Here we have to understand some terminology before implementing the solution in your project.
1. Before creating a default dimension with a set of dimension values in D365, you need to know the your accounting structure. For this go to
https://usnconeboxax1aos.cloud.onebox.dynamics.com/?cmp=igil&mi=DimensionConfigureAccountStructure
Before creating financial dimension you should know your dimension value combination sequence from accounting structure you have define for the journal.
2. create a container, which is used as a parameter for function contains dimension values in sequence of accounting structure.
3. AccountId = conPeek(_conData,1);
mainAccount = MainAccount::findByMainAccountId(AccountId);
The above lines are responsible for getting the main account buffer from accountid set on the first index of _conData which holds account id and dimension values.
4. recordvalue = DimensionHierarchy::getAccountStructure(mainAccount.RecId,Ledger::current());
The recordvalue holds the accounting structure buffer which has been define on main account you mention in _conData, which is helpful while creating default dimensions in ledger journal.
5. hierarchyCount = DimensionHierarchy::getLevelCount(recordvalue);
DimensionSet = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);
DimensionHierarchy::getLevelCount return the total count of financial dimension used in accounting structure which has been define on main account including main account value.
DimensionHierarchyLevel::getDimensionHierarchyLevelNames returns the sequence names of financial dimension used in accounting structure which has been define on main account including main account value.
Example: HierarchyCount = 3
HierarchyName = ['Main Account', 'Business Unit', 'Department']
DimensionSet = ["1135205","Centre","ATK"]
6. DimensionAttribute::findByLocalizedName(DimensionSet[hierarchyIdx],
false,
"en-us");
The dimension value set in container used to get dimension attribute buffer, which is helpful in finding dimension attribute value buffer.
Note: In some case we are responsible to also create financial dimension values through code in D365, for which dimension attribute value is not initializes/recorded. If dimension attribute value is not set for some dimension we have to set create if necessary parameter as true to create record in dimensionAttributeValue table.
Like this:
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
conPeek(_conData,hierarchyIdx),
false,
true);
Run the below code for creating financial dimension values:
dimensionAttribute = DimensionAttribute::findByName(DimensionName);
if(dimensionAttribute.RecId)
{
financialTag.initValue();
financialTag.Description = "Description";
financialTag.Value = "42051";
financialTag.FinancialTagCategory = dimensionAttribute.financialTagCategory();
if(financialTag.validateWrite())
{
financialTag.insert();
}
}
Now see below code for reference.
Run the below job with your specific set of dimension values and get the default dimension(Recid) for that combination:
/// <summary>
/// The method used to create a dimension dynamic account according to the financial dimesnion accounting structure
/// </summary>
/// <param name = "_conData">container constains all group record financial dimension in accouting structure sequences</param>
/// <returns></returns>
private DimensionDynamicAccount generateLedgerDimension(container _conData)
{
//Finanical Dimension Attribute.
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
DimensionSetSegmentName DimensionSet;
DimensionStorage dimStorage;
DimensionAttributeValueContract ValueContract;
dimensionAttributeValueCombination dimensionAttributeValueCombination;
//Main Account details
MainAccount mainAccount;
//table ref recid
LedgerRecId ledgerRecId;
RefRecId recordvalue;
//index count
int hierarchyCount;
int hierarchyIdx;
//Main Account
Str AccountId;
//Account Contract.
LedgerAccountContract LedgerAccountContract = new LedgerAccountContract();
List valueContracts = new List(Types::Class);
AccountId = conPeek(_conData,1);
mainAccount = MainAccount::findByMainAccountId(AccountId);
recordvalue = DimensionHierarchy::getAccountStructure(mainAccount.RecId,Ledger::current());
hierarchyCount = DimensionHierarchy::getLevelCount(recordvalue);
DimensionSet = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);
for(hierarchyIdx = 1;hierarchyIdx<=hierarchyCount;hierarchyIdx++)
{
dimensionAttribute = DimensionAttribute::findByLocalizedName(DimensionSet[hierarchyIdx],
false,
"en-us");
if(dimensionAttribute)
{
if(hierarchyIdx <= conLen(_conData))
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
conPeek(_conData,hierarchyIdx),
false,
true);
}
else
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
conPeek(_conData,hierarchyIdx));
}
if(dimensionAttributeValue)
{
ValueContract = new DimensionAttributeValueContract();
ValueContract.parmName(dimensionAttribute.Name) ;
ValueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);
valueContracts.addEnd(ValueContract);
}
}
}
LedgerAccountContract.parmMainAccount(AccountId);
LedgerAccountContract.parmValues(valueContracts);
dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);
dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());
ledgerRecId = dimensionAttributeValueCombination.RecId;
return ledgerRecId;
}