Below is the code to create general journals in D365 using X++. In this implementation, we utilize the LedgerJournalEngine, which can handle both single- and multi-voucher journal creation scenarios. This approach increases the likelihood that the resulting lines will match those created manually.
public class CreateGeneralJournalService { ledgerJournalTable ledgerJournalTable; ProjParameters projParameters; LedgerJournalEngine ledgerJournalEngine; /// <summary> /// Method Used to create the Journal Header /// </summary> /// <returns>ledgerJournalTable</returns> public ledgerJournalTable createGeneralJournalHeader() { projParameters = ProjParameters::find(); ledgerJournalTable.clear(); ledgerJournalTable.initValue(); ledgerJournalTable.initFromLedgerJournalName(projParameters.DaxJournalNameId); ledgerJournalTable.JournalNum = JournalTableData::newTable(ledgerJournalTable).nextJournalId(); ledgerJournalTable.insert(); ledgerJournalEngine = LedgerJournalEngine::construct(ledgerJournalTable.JournalType); ledgerJournalEngine.newJournalActive(ledgerJournalTable); return ledgerJournalTable; } /// <summary> ///Method Used to create the journal Lines /// </summary> /// <param name = "_StagingTrans"></param> public void createGeneralJournalLine(DaxStagingTrans _StagingTrans) { ledgerJournalTrans ledgerJournalTrans; // DeptCC-ProfitCenter-PRODGRP-UnifiedProductID-Customer-Vendor container conAttribute = CreateGeneralJournalService::getFDFromParameters(); container convalue = [_StagingTrans.Costcenter, projParameters.DaxProfitCenter]; RecId defaultDimensionRecId = CreateGeneralJournalService::createDefaultDimension(conAttribute, convalue); ledgerJournalTrans.clear(); ledgerJournalTrans.initValue(); ledgerJournalEngine.initValue(ledgerJournalTrans); ledgerJournalTrans.JournalNum = ledgerJournalTable.JournalNum; ledgerJournalTrans.TransDate = _StagingTrans.JournalDate; ledgerJournalTrans.AccountType = LedgerJournalACType::Ledger; ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, AccountType)); ledgerJournalTrans.LedgerDimension = LedgerDimensionFacade::serviceCreateLedgerDimension(this.getDefaultAccount(_StagingTrans.Expensecategory), defaultDimensionRecId);; ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, LedgerDimension)); ledgerJournalEngine.accountModified(LedgerJournalTrans); ledgerJournalTrans.OffsetAccountType = LedgerJournalACType::Ledger; ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, OffsetAccountType)); ledgerJournalTrans.OffsetLedgerDimension = LedgerDimensionFacade::serviceCreateLedgerDimension(projParameters.DaxReimbursableEmpExpensePayAccount, defaultDimensionRecId); ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, OffsetLedgerDimension)); ledgerJournalEngine.offsetAccountModified(ledgerJournalTrans); ledgerJournalTrans.CurrencyCode = _StagingTrans.Currency; ledgerJournalEngine.currencyModified(LedgerJournalTrans); ledgerJournalTrans.AmountCurDebit = _StagingTrans.Costamount; ledgerJournalTrans.DaxTransID = _StagingTrans.TransID; ledgerJournalTrans.DaxOrderItemID = _StagingTrans.OrderItemId; ledgerJournalTrans.DaxExpenseCategory = _StagingTrans.Expensecategory; ledgerJournalTrans.Approved = NoYes::Yes; ledgerJournalTrans.SkipBlockedForManualEntryCheck = true; ledgerJournalTrans.defaultRow(); ledgerJournalTrans.TaxItemGroup = nullValueFromType(Types::String); ledgerJournalTrans.TaxGroup = nullValueFromType(Types::String); if (ledgerJournalTrans.validateWrite()) { ledgerJournalTrans.insert(); ledgerJournalEngine.write(ledgerJournalTrans); } } /// <summary> /// A construct method to Create an object /// </summary> /// <returns></returns> public static CreateGeneralJournalService construct() { return new CreateGeneralJournalService(); } /// <summary> /// Gets the default dimension from Proj posting setup /// </summary> /// <param name = "_categoryRelation">Str</param> /// <returns>LedgerDimensionDefaultAccount</returns> public LedgerDimensionDefaultAccount getDefaultAccount(str _categoryRelation) { ProjPosting projPosting; select firstonly projPosting where projPosting.ProjAccountType == ProjAccountType::CostAccount && projPosting.ProjCategoryRelation == _categoryRelation; return projPosting.LedgerDimension; } /// <summary> /// It will returns the format of finanicaial dimensions /// </summary> /// <returns>container</returns> public static container getFDFromParameters() { DimensionHierarchy dimensionHierarchy; DimensionHierarchyIntegration dimensionHierarchyIntegration; select firstonly DisplayString from dimensionHierarchyIntegration exists join dimensionHierarchy where dimensionHierarchy.RecId == dimensionHierarchyIntegration.DimensionHierarchy && dimensionHierarchy.StructureType == DimensionHierarchyType::DataEntityDefaultDimensionFormat && dimensionHierarchyIntegration.IsDefault == true; return str2con(dimensionHierarchyIntegration.DisplayString, DimensionParameters::getDimensionSegmentDelimiter()); } /// <summary> /// Method Used to create the default Dimension /// </summary> /// <param name = "conAttribute"></param> /// <param name = "convalue"></param> /// <returns></returns> public static DimensionDefault createDefaultDimension(container conAttribute , container convalue) { DimensionAttributeValueSetStorage valueSetStorage = new DimensionAttributeValueSetStorage(); DimensionAttribute dimensionAttribute; DimensionAttributeValue dimensionAttributeValue; str dimValue; for (int i = 1; i <= conLen(conAttribute); i++) { dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttribute,i)); if (dimensionAttribute.RecId == 0) { continue; } dimValue = conPeek(convalue,i); if (dimValue != "") { dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, dimValue, false, true); valueSetStorage.addItem(dimensionAttributeValue); } } return valueSetStorage.save(); } }
Additionally, to post the above created Journals we can use LedgerJournalcheckpost class as below
LedgerJournalCheckPost ledgerjournalcheckpost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes);
if (ledgerjournalcheckpost.validate())
{
ledgerjournalcheckpost.run();
}
Thanks !!
No comments:
Post a Comment