Skip to main content

Get account Structure ranges set in AX Ledger

How to pass Account Structure ranges set in AX Ledger to an external system.


Recently I have got a requirement where I have to populate same set of main account and financial dimension values to an external system using integration off course, which I have set in AX Ledger.
The difficulty in this scenario was, how to get the valid set of main account and financial dimension values from AX. 
Because AX gives us 'Segmented Entry Controls' where we just have to use the field as a segmented entry control and valid values will populate according to the Account Structure set in Ledger.

 I have created a service class which extends "DimensionValueService"

public class CMCDimensionValueService extends DimensionValueService
{
    // Insert list of valid main accounts to 'DimensionValueContract'
    private void insertMainAccountValueLocalList(List                       _dimensionValueList,
                                                 DimensionAttribute         _dimensionAttribute,
                                                 DimensionAttributeValue    _dimensionAttributeValue,
                                                 DimAttributeMainAccount    _common)
    {
        DimensionValueContract dimensionValueContract;

        dimensionValueContract = new DimensionValueContract();
        dimensionValueContract.parmDimensionAttribute(_dimensionAttribute.Name);
        dimensionValueContract.parmBackingEntityType(_dimensionAttribute.BackingEntityType);
        dimensionValueContract.parmValue(_common.Value);
        dimensionValueContract.parmDescription(_common.Name);
        dimensionValueContract.parmActiveFrom(_dimensionAttributeValue.ActiveFrom);
        dimensionValueContract.parmActiveTo(_dimensionAttributeValue.ActiveTo);

        dimensionValueContract.parmPersonnelNumber(HcmWorker::find
                                                            (_dimensionAttributeValue.Owner).PersonnelNumber);

        dimensionValueContract.parmGroupDimension(_dimensionAttributeValue.GroupDimension);
         dimensionValueContract.parmIsBlockedForManualEntry(
                                                                      _dimensionAttributeValue.IsBlockedForManualEntry);
        dimensionValueContract.parmIsSuspended(_dimensionAttributeValue.IsSuspended);
        _dimensionValueList.addEnd(dimensionValueContract);
    }

    // Insert list of valid financial dimensions to 'DimensionValueContract'
    private void insertDimensionValueLocalList(List _dimensionValueList,
                        DimensionAttribute _dimensionAttribute,
                        DimensionAttributeValue _dimensionAttributeValue,
                        Common _common)
    {
        DimensionValueContract dimensionValueContract;

        dimensionValueContract = new DimensionValueContract();
        dimensionValueContract.parmDimensionAttribute(_dimensionAttribute.Name);
        dimensionValueContract.parmBackingEntityType(_dimensionAttribute.BackingEntityType);
        dimensionValueContract.parmValue(_common.(_dimensionAttribute.ValueAttribute));
        dimensionValueContract.parmDescription(_common.(_dimensionAttribute.NameAttribute));
        dimensionValueContract.parmActiveFrom(_dimensionAttributeValue.ActiveFrom);
        dimensionValueContract.parmActiveTo(_dimensionAttributeValue.ActiveTo);
        dimensionValueContract.parmPersonnelNumber(HcmWorker::find
                                                                (_dimensionAttributeValue.Owner).PersonnelNumber);
        dimensionValueContract.parmGroupDimension(_dimensionAttributeValue.GroupDimension);
        dimensionValueContract.parmIsBlockedForManualEntry(
                                                               _dimensionAttributeValue.IsBlockedForManualEntry);
        dimensionValueContract.parmIsSuspended(_dimensionAttributeValue.IsSuspended);
        _dimensionValueList.addEnd(dimensionValueContract);
    }

    [AifCollectionTypeAttribute('return', Types::Class, classStr(DimensionValueContract))]
    public List getValidDimensionValues(DimensionContract _dimensionContract, Name _name)
    {
        DimensionAttribute  dimensionAttribute;
        List                dimensionValueContractList;

        if (!_dimensionContract)
        {
            throw AifFault::faultList("@SYS323958", #DimensionContractIsNotInitialized);
        }

        if (!_dimensionContract.parmDimensionName())
        {
            throw  AifFault::faultList("@SYS323957", #DimensionContractIsNotInitialized);
        }

        changecompany(curext())
        {
            select firstonly dimensionAttribute where dimensionAttribute.Name == 
                                                                      _dimensionContract.parmDimensionName();
            if(dimensionAttribute)
            {
                dimensionValueContractList =  this.getValidDimensionValueList(dimensionAttribute,
                                                                                                       _name, _dimensionContract);
            }
            else
            {
                throw AifFault::faultList("@SYS323856", #DimensionAttributeDoesNotExist);
            }
        }
        return dimensionValueContractList;
    }

    // Get the list of valid dimension Values
    private List getValidDimensionValueList(DimensionAttribute _dimensionAttribute, Name _name,
                                                                       DimensionContract _dimensionContract)
    {
        List                                dimensionValueList;
        DimensionAttributeValue             dimensionAttributeValue;
        FinancialTagCategory                financialTagCategory;
        DimensionAttributeDirCategory       dimensionAttributeDirCategory;
        int                                 categoryFieldNum;
        DimensionHierarchyLevel             dimHierarchyLevel;
        DimensionConstraintNodeView         dimConstraintNodeView;
        LedgerStructure                     ledgerStructure;
        DimensionHierarchy                  dimHierarchy;
        Common                              common;
        DictTable                           dictTable;
        LedgerChartOfAccounts               ledgerChartOfAccounts;
        LedgerChartOfAccounts               ledgerCOA;
        Ledger                              ledger;
        DimAttributeMainAccount             mainAccount;

        dimensionValueList = new List(Types::Class);

        dictTable = new DictTable(_dimensionAttribute.BackingEntityType);

        ledgerChartOfAccounts = LedgerChartOfAccounts::find(Ledger::findByLegalEntity
                                                 (CompanyInfo::findDataArea(curExt()).RecId).ChartOfAccounts);

        if (!ledgerChartOfAccounts)
        {
            throw AifFault::fault(strFmt("@CMC521", curExt()), "Chart of Account doesn't exist.");
        }

        select firstonly RecId from ledger 
                         where Ledger.ChartOfAccounts == ledgerChartOfAccounts.RecId
                                   && Ledger.PrimaryForLegalEntity == CompanyInfo::current();

        if (dictTable && dictTable.fieldObject(_dimensionAttribute.NameAttribute)
             && dictTable.fieldObject(_dimensionAttribute.ValueAttribute))
        {
            common = dictTable.makeRecord();

            // Creates a contract of Custom financial dimension
            if (_dimensionAttribute.Type == DimensionAttributeType::CustomList)
            {
                categoryFieldNum = fieldNum(DimensionFinancialTag, FinancialTagCategory);

                while select common
                    outer join DimensionAttribute, ActiveFrom, ActiveTo, Owner, GroupDimension, 
                                    IsBlockedForManualEntry, IsSuspended from dimensionAttributeValue
                        where dimensionAttributeValue.EntityInstance == 
                                                          common.(_dimensionAttribute.KeyAttribute)
                           && dimensionAttributeValue.DimensionAttribute    == _dimensionAttribute.RecId
                    exists join financialTagCategory
                        where  financialTagCategory.RecId == common.(categoryFieldNum)
                    exists join dimensionAttributeDirCategory
                        where (financialTagCategory.RecId == dimensionAttributeDirCategory.DirCategory)
                        && (_dimensionAttribute.RecId == 
                                                                 dimensionAttributeDirCategory.DimensionAttribute)
                    join dimConstraintNodeView where
                                (common.(_dimensionAttribute.ValueAttribute) like 
                                                        dimConstraintNodeView.WildCardString ||
                                    ((dimConstraintNodeView.WildCardString == " ") &&
                                        (((dimConstraintNodeView.RangeFrom == " ") ||
                                          ((dimConstraintNodeView.IsFromOpen == 0) && (dimConstraintNodeView.RangeFrom <= common.(_dimensionAttribute.ValueAttribute))) ||
                                          ((dimConstraintNodeView.IsFromOpen == 1) && (dimConstraintNodeView.RangeFrom < common.(_dimensionAttribute.ValueAttribute)))) &&
                                         ((dimConstraintNodeView.RangeTo == " ") ||
                                          ((dimConstraintNodeView.IsToOpen == 0) && 
(common.(_dimensionAttribute.ValueAttribute) <= dimConstraintNodeView.RangeTo)) ||
                                          ((dimConstraintNodeView.IsToOpen == 1) && (common.(_dimensionAttribute.ValueAttribute) < dimConstraintNodeView.RangeTo))))))
                     join dimHierarchyLevel
                        order by
                        dimHierarchyLevel.Level,
                        dimHierarchyLevel.DimensionHierarchy
                            where dimHierarchyLevel.DimensionHierarchy == 
                                                                dimConstraintNodeView.DimensionHierarchy &&
                                    dimHierarchyLevel.Level == dimConstraintNodeView.Level &&
                                    dimHierarchyLevel.DimensionAttribute == _dimensionAttribute.RecId
                    join dimHierarchy
                        where dimHierarchy.RecId == dimHierarchyLevel.DimensionHierarchy &&
                             dimHierarchy.Name == _name &&
                             dimHierarchy.StructureType == DimensionHierarchyType::AccountStructure &&
                             dimHierarchy.IsDraft == false &&
                             dimHierarchy.IsSystemGenerated == false
                {
                    this.insertDimensionValueLocalList(dimensionValueList, _dimensionAttribute, 
                                                                 dimensionAttributeValue, common);
                }
            }
            // Creates a contract of valid main accounts
            else if (_dimensionAttribute.Type == DimensionAttributeType::MainAccount)
            {
                while select mainAccount 
                    where MainAccount.Category == ledgerChartOfAccounts.RecId
                    join ledgerCOA where
                        ledgerCOA.RecId == mainAccount.Category 
                        && ledgerCOA.Name == ledgerChartOfAccounts.Name
                    join dimConstraintNodeView
                            where (mainAccount.Value like dimConstraintNodeView.WildCardString ||
                                    ((dimConstraintNodeView.WildCardString == " ") &&
                                        (((dimConstraintNodeView.RangeFrom == " ") ||
                                          ((dimConstraintNodeView.IsFromOpen == 0) && 
                                            (dimConstraintNodeView.RangeFrom <= mainAccount.Value)) ||
                                          ((dimConstraintNodeView.IsFromOpen == 1) && 
                                         (dimConstraintNodeView.RangeFrom < mainAccount.Value))) &&
                                         ((dimConstraintNodeView.RangeTo == " ") ||
                                          ((dimConstraintNodeView.IsToOpen == 0) && 
                                          (mainAccount.Value <= dimConstraintNodeView.RangeTo)) ||
                                          ((dimConstraintNodeView.IsToOpen == 1) && 
                                           (mainAccount.Value < dimConstraintNodeView.RangeTo))))))
                    join dimHierarchyLevel
                         where dimHierarchyLevel.DimensionHierarchy ==
                         dimConstraintNodeView.DimensionHierarchy &&
                              dimHierarchyLevel.Level == dimConstraintNodeView.Level &&
                              dimHierarchyLevel.DimensionAttribute == _dimensionAttribute.RecId
                    join dimHierarchy
                        where dimHierarchy.RecId == dimHierarchyLevel.DimensionHierarchy &&
                             dimHierarchy.Name == _name &&
                             dimHierarchy.StructureType == DimensionHierarchyType::AccountStructure &&
                             dimHierarchy.IsDraft == false &&
                             dimHierarchy.IsSystemGenerated == false
                {
                    this.insertMainAccountValueLocalList(dimensionValueList, _dimensionAttribute, 
                                                         dimensionAttributeValue, mainAccount);
                }
            }
            // Creates a contract of other existing financial dimension
            else
            {
                while select common
                    outer join DimensionAttribute, ActiveFrom, ActiveTo, Owner, GroupDimension,
                                   IsBlockedForManualEntry, IsSuspended from dimensionAttributeValue
                        where dimensionAttributeValue.EntityInstance == 
                                                                      common.(_dimensionAttribute.KeyAttribute)
                           && dimensionAttributeValue.DimensionAttribute    == _dimensionAttribute.RecId
                   join dimConstraintNodeView where
                                (common.(_dimensionAttribute.ValueAttribute) like
                                                 dimConstraintNodeView.WildCardString ||
                                    ((dimConstraintNodeView.WildCardString == " ") &&
                                        (((dimConstraintNodeView.RangeFrom == " ") ||
                                          ((dimConstraintNodeView.IsFromOpen == 0) && (dimConstraintNodeView.RangeFrom <= common.(_dimensionAttribute.ValueAttribute))) ||
                                          ((dimConstraintNodeView.IsFromOpen == 1) && (dimConstraintNodeView.RangeFrom < common.(_dimensionAttribute.ValueAttribute)))) &&
                                         ((dimConstraintNodeView.RangeTo == " ") ||
                                          ((dimConstraintNodeView.IsToOpen == 0) && (common.(_dimensionAttribute.ValueAttribute) <= dimConstraintNodeView.RangeTo)) ||
                                          ((dimConstraintNodeView.IsToOpen == 1) && (common.(_dimensionAttribute.ValueAttribute) < dimConstraintNodeView.RangeTo))))))
                     join dimHierarchyLevel
                        order by
                        dimHierarchyLevel.Level,
                        dimHierarchyLevel.DimensionHierarchy
                            where dimHierarchyLevel.DimensionHierarchy == dimConstraintNodeView.DimensionHierarchy &&
                                    dimHierarchyLevel.Level == dimConstraintNodeView.Level &&
                                    dimHierarchyLevel.DimensionAttribute == _dimensionAttribute.RecId
                    join dimHierarchy
                        where dimHierarchy.RecId == dimHierarchyLevel.DimensionHierarchy &&
                             dimHierarchy.Name == _name &&
                             dimHierarchy.StructureType == DimensionHierarchyType::AccountStructure &&
                             dimHierarchy.IsDraft == false &&
                             dimHierarchy.IsSystemGenerated == false
                {
                    this.insertDimensionValueLocalList(dimensionValueList, _dimensionAttribute, dimensionAttributeValue, common);
                }
            }
        }
        return dimensionValueList;
    }

}


getValidDimensionValueList() method of the service class returns a list of all valid dimensions according to the account structure set in Ledger. This method takes dimension attribute, Name of the dimension attribute (Business unit, main account etc.) and dimension contract as parameters. And based on these parameters it returns list of valid dimension values.

This list of dimension you can pass to any external system.

Thanks!
Nishant Srivastava
AX Technical Consultant| Campus Management Corp.
Bangalore, Karnataka

Comments

  1. will this code will also provide the combinations of business unit and cost center etc ?

    ReplyDelete

Post a Comment

Popular posts from this blog

Mass cheque printing in AX7/Dynamics 365 for finance & operation

AX7/Dynamics 365 for finance & operation: How to avoid user interaction while printing multiple cheques(Mass cheque printing) You all might be aware of the ‘Generate Payment’ functionality available in Dynamics AX. This function we use to generate/print cheques. The process is to create one payment journal, add few transactions with mode of payment as ‘Cheque’ then go for ‘Generate Payment’ option available in the drop down of ‘Function’ menu item button. Process is specific to print one cheque at a time for a single journal. Recently I came across a requirement where I had a customized form which contains multiple journal records and I have to add the ‘Generate Payment’ button on the form to allow user to print the checks for journals, and also allow user to select multiple journal records at the same time to print cheques and avoid user interaction with the system for each cheque. The major challenge here was, how to handle user interactions everytime to print multiple

Hierarchy conflicts in AX 7 during migration from other AX versions and it's resolution - Delegates and Handlers

Delegates and Handlers in AX 7(Hierarchy conflicts resolution) Hi, We recently did a migration of our AX 2012 solution to AX 7, and while doing so one of the major challenge that we have faced are hierarchy conflicts. I'll be discussing here on the same. First of all we need to know that what is a hierarchy conflict. Coming to the AX 7 architecture, Application stack is divide into three basic packages. These are- 1: Application Platform 2: Application Foundation  3: Application Suite As shown in the above image, Application platform is the base package which contains Runtime and data access , work flow and services etc. and on top of it we have application foundation which contains organisation model, number sequence and GAB etc. and at the top we have Application Suite and Fleet Management. To understand the concept of these packages in depth you can follow the below link- Architecture changes in AX 7 All three models follows a hierarchy. Application p