Say, we need to add a new field UniqueId to LedgerJournalTrans and then have it populated in GeneralJournalAccountEntry, once a General journal posted.
In other words the field value must be transferred from a general journal line to a related voucher transaction.
Generally speaking there are two different ways how GL transactions created in D365FO: via Source document framework and via LedgerVoucherObject. Moreover, one transaction may be a result of summarization of multiple documents. So, this approach works for this particular scenario, when GL transactions come from a general journal. The proposed solution covers Ledger, Customer, Vendor, and Bank types. You can elaborate it for Project, Fixed Asset, etc. Check their appropriate classes.
LedgerJournalCheckPost class creates one transaction per a line of Ledger type, two if the latter has an offset info.
When it comes to other transaction type, first, a transaction in CustTrans, VendTrans, BankTrans etc is created, and then based on the latter a new transaction is added.
So, we creates the following extensions.
Tables.
Classes.
Below, you can find code snippets for each of them.
BankVoucher_Extension
[ExtensionOf(classStr(BankVoucher))]
final class BankVoucher_Extension
{
public UniqueId UniqueId;
public UniqueId parmUniqueId(UniqueId _parm = uniqueId)
{
uniqueId = _parm;
return uniqueId;
}
protected LedgerVoucherTransObject initializeLedgerVoucherTransObjectForPosting(LedgerVoucherObject _ledgerVoucherObject, CurrencyExchangeHelper _exchangeRateHelper)
{
LedgerVoucherTransObject ledgerVoucherTransObject = next initializeLedgerVoucherTransObjectForPosting(_ledgerVoucherObject, _exchangeRateHelper);
if(ledgerVoucherTransObject)
{
ledgerVoucherTransObject.parmUniqueId(_ledgerVoucherObject.parmUniqueId());
}
return ledgerVoucherTransObject;
}
}
CustVendVoucher_Extension
[ExtensionOf(classStr(CustVendVoucher))]
final class CustVendVoucher_Extension
{
public UniqueId uniqueId;
public UniqueId parmUniqueId(UniqueId _parm = uniqueId)
{
uniqueId = _parm;
return uniqueId;
}
protected LedgerVoucherTransObject createLedgerVoucherTransObject(boolean _useSubLedger,
LedgerDimensionAccount _ledgerDimensionMerged,
LedgerJournalTrans _ledgerJournalTrans,
LedgerVoucher _ledgerPostingJournal,
CustVendTrans _custVendTrans)
{
LedgerVoucherTransObject ledgerVoucherTransObject = next createLedgerVoucherTransObject( _useSubLedger, _ledgerDimensionMerged, _ledgerJournalTrans, _ledgerPostingJournal, _custVendTrans);
if(ledgerVoucherTransObject)
{
ledgerVoucherTransObject.parmUniqueId(uniqueId);
}
return ledgerVoucherTransObject;
}
}
LedgerJournalCheckPost_Extension
[ExtensionOf(classStr(LedgerJournalCheckPost))]
final class LedgerJournalCheckPost_Extension
{
protected LedgerVoucherObject createPostingReference(LedgerJournalTrans _ledgerJournalTrans, SysModule _sysModule)
{
LedgerVoucherObject newVoucher = next createPostingReference(_ledgerJournalTrans, _sysModule);
if(newVoucher)
{
newVoucher.parmUniqueId(_ledgerJournalTrans.uniqueId);
}
return newVoucher;
}
protected LedgerVoucherObject updatePostingReference(LedgerVoucherObject _postingReference, LedgerJournalTrans _ledgerJournalTrans, SysModule _sysModule)
{
next updatePostingReference(_postingReference, _ledgerJournalTrans, _sysModule);
if(_postingReference)
{
_postingReference.parmUniqueId(_ledgerJournalTrans.uniqueId);
}
return _postingReference;
}
}
LedgerJournalTransUpdateBank_Extension
[ExtensionOf(classStr(LedgerJournalTransUpdateBank))]
final class LedgerJournalTransUpdateBank_Extension
{
protected BankVoucher initBankVoucher( LedgerJournalTrans _ledgerJournalTrans,
TaxAmount _taxAmount,
real _taxWithholdAmount,
DimensionDefault _defaultDimension,
LedgerJournalType _ledgerJournalType,
boolean _skipDimensionValidation)
{
BankVoucher bankVoucher = next initBankVoucher(_ledgerJournalTrans, _taxAmount, _taxWithholdAmount, _defaultDimension, _ledgerJournalType, _skipDimensionValidation);
if(bankVoucher)
{
bankVoucher.parmUniqueId(_ledgerJournalTrans.uniqueId);
}
return bankVoucher;
}
}
LedgerVoucherObject_Extension
[ExtensionOf(classStr(LedgerVoucherObject))]
final class LedgerVoucherObject_Extension
{
public UniqueId uniqueId;
public UniqueId parmUniqueId(UniqueId _parm = uniqueId)
{
uniqueId = _parm;
return uniqueId;
}
}
LedgerVoucherTransObject_Extension
[ExtensionOf(classStr(LedgerVoucherTransObject))]
final class LedgerVoucherTransObject_Extension
{
public UniqueId uniqueId;
public UniqueId parmUniqueId(UniqueId _parm = uniqueId)
{
generalJournalAccountEntry.UniqueId = _parm;
return generalJournalAccountEntry.UniqueId;
}
public static LedgerVoucherTransObject newTransLedgerJournal(
LedgerJournalTrans _ledgerJournalTrans,
TaxAmount _taxAmount,
boolean _bridging,
container _intercompanyRecIds,
boolean _reversalsMayExist,
boolean _forcedExchangeRate)
{
LedgerVoucherTransObject ledgerVoucherTransObject = next newTransLedgerJournal(_ledgerJournalTrans, _taxAmount, _bridging, _intercompanyRecIds, _reversalsMayExist, _forcedExchangeRate);
if(ledgerVoucherTransObject)
{
ledgerVoucherTransObject.parmUniqueId(_ledgerJournalTrans.UniqueId);
}
return ledgerVoucherTransObject;
}
public LedgerPostingTransactionTmp getLedgerPostingTransaction()
{
LedgerPostingTransactionTmp ledgerPostingTransaction = next getLedgerPostingTransaction();
ledgerPostingTransaction.UniqueId = generalJournalAccountEntry.UniqueId;
return ledgerPostingTransaction;
}
public void initFromLedgerPostingTransaction(LedgerPostingTransactionTmp _ledgerPostingTransaction,LedgerPostingTransactionProjectTmp _projectPostingTransaction)
{
next initFromLedgerPostingTransaction(_ledgerPostingTransaction,_projectPostingTransaction);
generalJournalAccountEntry.UniqueId = _ledgerPostingTransaction.UniqueId;
}
public static LedgerVoucherTransObject newTransactionAccountingAmountsDefault(
LedgerVoucherObject _defaultLedgerPostingReference,
LedgerPostingType _postingType,
RecId _ledgerDimensionId,
CurrencyCode _transactionCurrencyCode,
Money _transactionCurrencyAmount,
MoneyMST _accountingCurrencyAmount,
CurrencyExchangeHelper _currencyExchangeHelper)
{
LedgerVoucherTransObject postingTrans;
postingTrans = next newTransactionAccountingAmountsDefault(_defaultLedgerPostingReference, _postingType, _ledgerDimensionId, _transactionCurrencyCode, _transactionCurrencyAmount, _accountingCurrencyAmount, _currencyExchangeHelper);
if(postingTrans)
{
postingTrans.parmUniqueId(_defaultLedgerPostingReference.parmUniqueId());
}
return postingTrans;
}
}
I wish to credit the following articles I used:
http://axforum.info/forums/showthread.php?t=74038
https://allaboutdynamic.com/2018/06/25/d365-ax7-update-custom-fields-in-custtrans-vendtrans-from-ledgerjournaltrans-during-the-posting-of-journal/
http://axwiki.blogspot.com/2017/01/customize-field-in-ledgerjournaltabletr.html