需求:
在普通日记账行上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 }