Creating LedgerDimension from DefaultDimension in D365F&O
Its a very common requirement to create ledgerDimension, based on DefaultDimension. Generally we have a habit of hardcoding the dimension names, to get the resulting ledgerDimension value: ex --
dimensionMap.insert('CostCenter', '0033501_036'); dimensionMap.insert('Location', '2023GBG');
Where CostCenter, Location, Purpose, etc. are various financial dimensions.
But wouldn't it have been great, if we could generalize the code, so as to eliminate dimension names hardcodes, so that if tomorrow the client decides to include more dimensions, edit or remove some of them, we don't have to change our code?
This article can give you a very handy code to do the same. All you need to do is to call it correctly 😊
I have created a class separately: DimDimensionHelper.
The following method has been added:
public static Map getDimensionWiseDimensionValues_DefaultDimension(DimensionDefault _dimensionDefault){Map dimMap = new Map(Types::String, Types::String);DEFAULTDIMENSIONVIEW defaultDimensionView;while select Name, DisplayValue from defaultDimensionViewwhere defaultDimensionView.DefaultDimension == _dimensionDefault{dimMap.insert(defaultDimensionView.Name, defaultDimensionView.DisplayValue);}return dimMap;}
Here you are passing the DefaultDimension as a parameter, and then looping through the DefaultDimensionView view, and loading up the dimension name and displayValue as key-value pairs in a map.
Next we will pass on this Map along with the main account to create the segmented entry structure:
public static DimensionDynamicAccount getLedgerDimension(MainAccount _mainAccount, Map _conData){DimensionDynamicAccount ledgerRecId;DimensionAttribute dimensionAttribute;DimensionAttributeValue dimensionAttributeValue;DimensionSetSegmentName DimensionSet;DimensionStorage dimStorage;LedgerAccountContract ledgerAccountContract = new LedgerAccountContract();DimensionAttributeValueContract ValueContract;List valueContracts = new List(Types::Class);dimensionAttributeValueCombination dimensionAttributeValueCombination;MapEnumerator mapEnum = _conData.getEnumerator();while (mapEnum.moveNext()){dimensionAttribute = DimensionAttribute::findByLocalizedName(mapEnum.currentKey(),false, CompanyInfo::find().LanguageId);if(dimensionAttribute){dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, mapEnum.currentValue());if(dimensionAttributeValue){ValueContract = new DimensionAttributeValueContract();ValueContract.parmName(dimensionAttribute.Name) ;ValueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);valueContracts.addEnd(ValueContract);}}}ledgerAccountContract.parmMainAccount(_mainAccount.MainAccountId);ledgerAccountContract.parmValues(valueContracts);dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());ledgerRecId = dimensionAttributeValueCombination.RecId;return ledgerRecId;}
Here its essentially looping through the map's key-value pair, and getting each and every dimension name, searching in the hierarchy. If a match is found, its trying to search the associated value pair and then loading in a list called 'ValueContracts'. Rest is very simple -- as we all know -- using DimensionStorageProvider to create a the dimensionValueCombination recId, and then sending it back to calling code.
Summing it up, here is how, you can call the above methods:
Map dimension = DimDimensionHelper::getDimensionWiseDimensionValues_DefaultDimension(_dimensionDefault);ledgerDimaccount = DimDimensionHelper::getLedgerDimension(mainAccount, dimension);transJournal.LedgerDimension = ledgerDimaccount;
Hope it helps 😊
Comments
Post a Comment