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