As we know that Microsoft Dynamics AX 2012 has all new financial dimension framework and which is a really good enhancement in AX but for developers it is bit complex at the same time if you try handling it by your own code rather than using framework or utility classes. My intension is to let you guys now few important framework classes and few code sample to handle leger dimension is different scenarios.
Classes:
- DimensionDefaultingEngine
- AxdDimensionUtil
- DimensionStorage
Useful X++ code for ledger dimensions
Create Ledger Dimension through string values:
For this we needs to create a container with main account and all other required dimensions:
[‘1185’, ‘1185’, 2, ‘Department’, ‘101’ , ‘Product’, ‘909’]
i.e. I first specify the main account and then 2 is no. of dimensions and then the dimension name and its value. The positioning of dimension in container does not matter.
[‘1185’, ‘1185’, 2, ‘Product’, ‘909’ , ‘Department’, ‘101’]
will also create same ledger dimension.
[‘MainAccountId’, ‘MainAccountId’, no. of dimensions, ‘DimensionName’, ‘DimensionValue’ , …]
Static method “AxdDimensionUtil::getLedgerAccountId” takes container as parameter and creates and return ledger dimension.
Code:
container offsetAccount;
RefRecId ledgerDimension;
offsetAccount = [‘1185’, ‘1185’, 1, ‘Department’, ‘101’];
ledgerDimension = AxdDimensionUtil::getLedgerAccountId(offsetAccount);
Convert DefaultDimension into values:
The below code can be used to convert default dimension (Default dimensions are associated with Customers, Vendors etc. which can be combines with main account to create LedgerDimension) into values.
public static List getDefaultDimList(RefRecId _defaultDim)
{
Map dimensionSpecifiers;
MapEnumerator enumerator;
DimensionAttribute dimensionAttribute;
List dimList;
dimList = new List(Types::Container);
// DimensionDefaultingEngine::getDefaultDimensionSpecifiers takes DefaultDimension into values.
dimensionSpecifiers = DimensionDefaultingEngine::getDefaultDimensionSpecifiers(_defaultDim);
enumerator = dimensionSpecifiers.getEnumerator();
while (enumerator.moveNext())
{
dimensionAttribute = dimensionAttribute::find(enumerator.currentKey());
dimList.addEnd([dimensionAttribute.Name, enumerator.currentValue()]);
}
return dimList;
}
Converts string values to ledgerDimension after validating it against chart of account:
Below method can convert string values into LedgerDimension after validating it against chart of account. You can change the method parameters as per the dimensions setup in DAX.
Code:
public static RefRecId getLedgerAccountBasedonMainAccDims(str _mainAccount, str _department, str _product,
str _project, str _company)
{
container accountCon;
MainAccount mainAcc;
DimensionStorage dimensionStorage;
DimensionAttributeValueCombination dimCombination;
int hierarchyCount, hierarchyIndex, segmentCount, segmentIndex;
RefRecId recordvalue;
int dimCount;
DimensionStorageSegment segment;
DimensionHierarchyLevel hierarchyLevel;
DimensionAttribute dimAttribute;
accountCon = [_mainAccount, _mainAccount];
mainAcc = MainAccount::findByMainAccountId(_mainAccount);
recordvalue = DimensionHierarchy::getAccountStructure(mainAcc.RecId);
//If the ledgerDimension already created then we can find it in below table
select recid from dimCombination where dimCombination.MainAccount == mainAcc.RecId
&& dimCombination.AccountStructure == recordvalue;
if (!dimCombination)
{
accountCon = [_mainAccount, _mainAccount, 0];
if (_department)
{
accountCon += [“department”, _department];
dimCount++;
}
if (_company)
{
accountCon += [“company”, _company];
dimCount++;
}
if (_product)
{
accountCon += [“product”, _product];
dimCount++;
}
if (_project)
{
accountCon += [“project”, _project];
dimCount++;
}
accountCon = conPoke(accountCon, 3 , dimCount);
return accountCon;
}
//below code lines create ledgerdimension as per chart of account setup
dimensionStorage = DimensionStorage::findById(dimCombination.RecId);
if (dimensionStorage == null)
{
throw error(“No dimension Specified for the Main Account”);
}
hierarchyCount = dimensionStorage.hierarchyCount();
for(hierarchyIndex = 1; hierarchyIndex <= hierarchyCount; hierarchyIndex++)
{
segmentCount = dimensionStorage.segmentCountForHierarchy(hierarchyIndex);
accountCon += [0];
//Loop through segments and display required values
for (segmentIndex = 1; segmentIndex <= segmentCount; segmentIndex++)
{
segment = dimensionStorage.getSegmentForHierarchy(hierarchyIndex, segmentIndex);
hierarchyLevel = DimensionHierarchyLevel::findByDimensionHierarchyAndLevel(recordvalue, segmentIndex);
dimAttribute = DimensionAttribute::find(hierarchyLevel.DimensionAttribute);
switch (dimAttribute.Name)
{
case “department”:
if (_department)
{
accountCon += [“department”, _department];
accountCon = conPoke(accountCon, 3, conPeek(accountCon, 3) + 1);
}
break;
case “product” :
if(_product)
{
accountCon += [“product”, _product];
accountCon = conPoke(accountCon, 3, conPeek(accountCon, 3) + 1);
}
break;
case “project”:
if(_project)
{
accountCon += [“project”, _project];
accountCon = conPoke(accountCon, 3, conPeek(accountCon, 3) + 1);
}
break;
case “company”:
if(_company)
{
accountCon += [“company”, _company];
accountCon = conPoke(accountCon, 3, conPeek(accountCon, 3) + 1);
}
break;
}
}
}
return AxdDimensionUtil::getLedgerAccountId(accountCon);
}
Creates DefaultDimension from string values:
Below method will creates default dimension using string values. You can change the parameters as per the dimension setup in DAX.
Code:
public static RecId getDefaultDimension(str _department, str _product, str _project, str _company = ”)
{
container con;
int cnt = 0;
con = [0];
if (_company)
{
con += [“Company”, _company];
cnt++;
}
if (_department)
{
con += [“department”, _department];
cnt++;
}
if (_product)
{
con += [“product”, _product];
cnt++;
}
if (_project)
{
con += [“project”, _project];
cnt++;
}
con = conPoke(con, 1, cnt);
return AxdDimensionUtil::getDimensionAttributeValueSetId(con);
}
Convert LedgerDimension into string value:
Below code will convert ledger dimension into string value container.
Code:
container con;
int i;
String30 department, product;
con = AxdDimensionUtil::getLedgerAccountValue(_ledgerDimension);