Updating Default dimensions -- the best possible way

 

Ever come across a situation, where you needed to update the default financial dimensions, runtime? Suppose you have sales lines, and they dimensions like [Costcenter-purpose-department-Employee]. There is a requirement, that asks you to update: depending on certain situations, the dimension code on 'Purpose' needs to be changed. This sorta requirement is quite common, and I bet you have confronted several situations like this, before.

Even a few versions of D365FO this, was damn easy. There was this function, which can let you change twitch between any Fin. dimension values:

 ledgerDimensionDefaultFacade::serviceReplaceAttributeValue(SalesLine.DefaultDimension, InventTable.DefaultDimension, DimensionAttribute::findByName("ProdLine").RecId);

But this method has changed and it looks like the following:

dimension = LedgerDimensionDefaultFacade::serviceReplaceAttributeValue(

                        _defaultDimension,

                        _dimensionDefaultMap.DefaultDimension,

                        dimensionAttributeRecId);

Whereby you have to generate a new dimension and then assign it to the original dimension.

Oh Rama....there could be sheer chances of again the structure of this method getting changed and we have to refurbish our code again.

Here is a pretty easy-to-use code, that can help you anytime to replace any dimension value with a new one -- regardless of whatever changes happen to any of these underlying Dimension classes.

private DimensionDefault updateDefaultDimension(SalesLine   _salesLine, InventLocationId  _newLocationVal)

    {

        DimensionDefault        fromDimensionDefault = _salesLine.DefaultDimension, 

                                toDimensionDefault;

        DefaultDimensionView    defaultDimensionView;

        Map                     mapDimvalues = new Map(Types::String, Types::String);

        Counter                 repeats = 1;

        

        while select DisplayValue, Name from defaultDimensionView

            order by RecId asc

                where defaultDimensionView.DefaultDimension == fromDimensionDefault

        {

            if (repeats == 1)

            {

                mapDimvalues.insert(defaultDimensionView.Name, _newLocationVal);

            }

            else

            {

                mapDimvalues.insert(defaultDimensionView.Name, defaultDimensionView.DisplayValue);

            }   

            repeats ++;

        }


        DimensionAttributeValueSetStorage   valueSetStorage = new DimensionAttributeValueSetStorage();        

        MapEnumerator                       dimValEnum = mapDimvalues.getEnumerator();

       

        DimensionAttributeValue             dimensionAttributeValue;


        while (dimValEnum.moveNext())

        {

            DimensionAttribute  dimensionAttribute = dimensionAttribute::findByName(dimValEnum.currentKey());

            if (dimensionAttribute.RecId == 0)

            {

                continue;

            }

            DimensionValue dimValue = dimValEnum.currentValue();

            if (dimValue != "")

            {

                dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, dimValue, false, true);

                valueSetStorage.addItem(dimensionAttributeValue);

            }

        }

    

        toDimensionDefault = valueSetStorage.save();


        return toDimensionDefault;

    }

Here, as per our business need, I needed to change the first dimension (i.e.: cost-center from CostCenter-Purpose-Department-Employee-Region combination) with a new code. That's what the 'if (repeats == 1)' check is doing. You can change it to any value you want, depending on the which dimension value you want to update (3rd/4th/5th and so on). The all-time favorite 'DefaultDimensionView ' holds all the records of any given dimension combination (field DefaultDimension) which we can loop through as per our requirement. 


Comments

Popular posts from this blog

X++ : mistakes which developers commit the most

Make your menu items visible on main menu, conditionally,, using this cool feature of D365FO

Speed up your execution performance by using SysGlobalCaches