D365 FO凭证信息客制化

需求:
在普通日记账行上LedgerJournalTrans增加字段,将新增的字段信息写入凭证相关表中。

从AX2012以后,凭证表的结构也发生了变化,AX2012之前的版本,凭证就一张表LedgerTrans,AX2012以后在,总账这边的表一分为二
GeneralJournalEntry 用来存放凭证的信息,凭证号,日记账号,凭证日期等信息。
GeneralJournalAccountEntry 用来存放凭证明细信息,过账的科目维度,金额等信息。
另外上述两个表各对应一个_W的表
GeneralJournalEntry_W
GeneralJournalAccountEntry_W
我感觉这两个表应该是放国家特性的字段,针对国家特性的客制化放在这两个表里,所以客制化的字段都写入到这两个表里。
GeneralJournalEntry_W和GeneralJournalAccountEntry_W这个表的国家特性的Country Region Codes加上中国CN

对于修改系统的现有功能,D365和AX2012最大的区别是,AX2012直接找到方法就可以改了,D365不能修改系统现有的代码,必须要找到合适的扩展方法用CoC修改。
对于日记账过账这个类,核心的方法是LedgerJournalCheckPost的postJournal方法,这个方法有300多行,用来处理日记账里的多个凭证过账。
CoC只能把自己的代码加到系统方法的前面或者后面,肯定不能直接用postJournal来扩展增加字段。
按照CoC的要求,只有protected或者public的方法能扩展,如果方法本身是final类型的,必须用属性[Wrappable(true)]指定才可以扩展。
说句题外话,个人觉得用final这个来定义是否可以扩展值得商榷,本来就很容易把扩展和继承的概念搞混淆,这个final关键字本身是用来定义在继承的时候是否可以覆盖父类方法的,这里又一字二用,有点不妥。
不过既然这么用了,就这么用吧。
将字段带入到凭证头的扩展点,我最后选择了下面这个方法:

 1 [Wrappable(true)]
 2     protected final LedgerVoucherObject createPostingReference(
 3         LedgerJournalTrans _ledgerJournalTrans,
 4         SysModule _sysModule)
 5     {
 6         return LedgerVoucherObject::newVoucher(
 7             _ledgerJournalTrans.Voucher,
 8             _ledgerJournalTrans.TransDate,
 9             _sysModule,
10             _ledgerJournalTrans.TransactionType,
11             _ledgerJournalTrans.correct(),
12             ledgerJournalTable.CurrentOperationsTax,
13             _ledgerJournalTrans.DocumentNum,
14             _ledgerJournalTrans.DocumentDate,
15             _ledgerJournalTrans.AcknowledgementDate);
16 
17     }

这个方法本身是final类型的,如果不加属性[Wrappable(true)]的话是不能扩展的,微软特意增加了这个这个属性可以让让其扩展,当然同时扩展一下updatePostingReference这个方法。
凭证头里加字段只需要扩展这两个方法就OK了。
凭证行上加字段就啰嗦一些。
扩展方法列表如下:
LedgerVoucherTransObject类的
newTransLedgerJournal
initFromLedgerPostingTransaction
getLedgerPostingTransaction
另外要把需要增加的字段添加到LedgerPostingTransactionTmp这个临时表里,因为生成凭证明细的时候通过这个表中转了一下。
另外要特别注意,还需要扩展表GeneralJournalAccountEntry_W的isLegalEntityInCountryRegion这个方法, 因为这个方法目前没有包含中国。
其实搞不懂为啥表里的Country Region Codes已经设置了,这里还要再检查一下。

 1 public static boolean isLegalEntityInCountryRegion()
 2     {
 3         boolean     retValue = true;
 4 
 5         #IsoCountryRegionCodes
 6 
 7         retValue =  next isLegalEntityInCountryRegion();
 8         retValue = SysCountryRegionCode::isLegalEntityInCountryRegion([#isoBR, #isoRU, #isoMX, #isoCN]);
 9 
10         return retValue;
11     }
原文地址:https://www.cnblogs.com/Farseer1215/p/12833012.html