lundi 27 février 2012

Defaulting Financial Dimensions [AX 2012]

Next in the series of posts on Ledger dimensions and Financial dimensions is defaulting or setting the financial dimensions for any record. Suppose you have a requirement wherein you need to create a customer via code and default specific dimension (say Employee) to this record.
In AX 2012 dimensions are not directly attached but the combination Record Id is stored. The name generally is DefaultDimension.
This field points to a record in DimensionAttributeValueSet table. This table holds the combination of financial dimensions that a particular record is attached to. The combination is stored in DimensionAttributeValueSetItem table.
The job below will help you in defaulting a dimension: I have put in enough comments to make the job self explanatory. This job will help you find / create a dimension combination record and get the record id to set.
static void setDefaultFinancialDimension(Args _args)
{
    #LedgerSHA1Hash
    DimensionSHA1Hash               hash; //To store the calculated hash for DimensionAttributeValueSet
    HashKey                         valueKeyHashArray[]; //To store the has key of dimension in question
    Map                             dimAttrIdx; //to store the dimension index and backing entity type
    DimensionAttributeSetItem       dimAttrSetItem; // Contains the number of dimensions active for a account structure ledger
    DimensionAttribute              dimAttr; // Contains the financial dimensions records
    DimensionAttributeValue         dimAttrValue; // Contains used financial dimension values
    DimensionAttributeValueSet      dimAttrValueSet; //Contains default dimension records
    DimensionAttributeValueSetItem  dimAttrValueSetItem; //Contains individual records for default dimensions
    DimAttributeHcmWorker           dimAttrWorker; //Backing entity view for Employee type dimension
    DimensionEnumeration            dimensionSetId; //Record id for table that contains active dimensions for current ledger

    int dimAttrCount, i;
    int emplBackEntityType; //Stores the backing entity type for Employee type dimension

    ;

    //The employee backing entity will be the view DimAttributeHcmWorker
    emplBackEntityType = tableNum(DimAttributeHcmWorker);

    //Initialize the map to store the backing entity types
    dimAttrIdx = new Map(Types::Integer, Types::Integer);

    //Get the record Id (dimension set id) for current ledger to find active dimensions
    dimensionSetId = DimensionCache::getDimensionAttributeSetForLedger();

    //Find all the active dimensions for current ledger except main account and store there
    //backing entity type in the map
    while select * from dimAttr
        order by Name
            where dimAttr.Type != DimensionAttributeType::MainAccount
        join RecId from dimAttrSetItem
            where dimAttrSetItem.DimensionAttribute == dimAttr.RecId &&
                dimAttrSetItem.DimensionAttributeSet == dimensionSetId
    {
        dimAttrCount++;
        dimAttrIdx.insert(dimAttr.BackingEntityType, dimAttrCount);
    }

    //initialize hash key array to null
    for (i = 1; i<= dimAttrCount; i++)
        valueKeyHashArray[i] = emptyGuid();

    //Find the Dimension attribute record for the dimension to work on
    dimAttr.clear();
    select firstonly dimAttr
        where dimAttr.BackingEntityType == emplBackEntityType;

    //Get the backing entity type for the dimension value to process
    select firstOnly dimAttrWorker
        where dimAttrWorker.Value == ’000038′;

    //Find the required Dimension Attribute Value record
    //Create if necessary
    dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimAttr.RecId, dimAttrWorker.RecId, falsetrue);

    //Store the required combination hash keys
    valueKeyHashArray[dimAttrIdx.lookup(emplBackEntityType)] = dimAttrValue.HashKey;

    //Calculate the hash for the current values
    hash = DimensionAttributeValueSetStorage::getHashFromArray(valueKeyHashArray, dimAttrCount);

    //Null hash indicates no values exist, which may occur if the user entered an invalid value for one dimension attribute
    if (hash == conNull())
    {
        throw error("Wrong value for Employee Dimension");
    }

    // Search for existing value set
    dimAttrValueSet = DimensionAttributeValueSet::findByHash(hash);

    // This value set does not exist, so it must be persisted
    if (!dimAttrValueSet)
    {
        ttsbegin;

        // Insert the value set with appropriate hash
        dimAttrValueSet.Hash = hash;
        dimAttrValueSet.insert();

        /*
         * This Piece of code is only meant for better understanding hence commented
         * Use this code in case you have to handle more than one dimension
         * For our example we have only employee type dimension hence we will not use this for loop
         * Value key array would be the array of different dimension values
         */
        // Insert only specified set items use this
        /*for (i = 1; i <= dimAttrCount; i++)
        {
            if (valueKeyArray[i] != 0)
            {
                dimAttrValueSetItem.clear();
                dimAttrValueSetItem.DimensionAttributeValueSet = valueSet.RecId;
                dimAttrValueSetItem.DimensionAttributeValue = valueKeyArray[i];
                dimAttrValueSetItem.DisplayValue = valueStrArray[i];
                dimAttrValueSetItem.insert();
            }
        }*/
        //Insert Employee dimension set item
        dimAttrValueSetItem.clear();
        dimAttrValueSetItem.DimensionAttributeValueSet = dimAttrValueSet.RecId;
        dimAttrValueSetItem.DimensionAttributeValue = dimAttrValue.RecId;
        dimAttrValueSetItem.DisplayValue = dimAttrWorker.Value;
        dimAttrValueSetItem.insert();

        ttscommit;
    }
    info(strFmt("%1", dimAttrValueSet.RecId));
}

Aucun commentaire:

Enregistrer un commentaire