Friday, March 21, 2014

Replace a Financial Dimension in Default Dimensions–Condensed in ax 2012

// Replace a Financial Dimension in Default Dimensions–Condensed [AX 2012]

static void replaceDefaultDimensionsCondense(Args _args)
{
    /*
     * In this job, we will replace the Business Unit Value from BU-001 to BU-002
     * and fill in the values for Department as Dep-001 and Worker as 114
     */
    CustTable                       custTable = CustTable::find(‘CUS-00004'); //Customer Record containing Financial Dimension
    Struct                          struct = new Struct(); //Structure to hold the dimension values to replace
    container                       defDimensionCon; //Container to prepare the required values and dimension attribute combination
    DimensionDefault                dimensionDefault; //Get the replaced dimension recid
    DimensionAttributeSetItem       dimAttrSetItem; //Table to get active dimensions for the legal entity
    DimensionAttribute              dimAttribute; //Table to get the Financial dimensions
    int i; //For looping

    //Loop for required dimensions
    while select Name, BackingEntityType from dimAttribute
        where dimAttribute.BackingEntityType == tableNum(DimAttributeOMBusinessUnit) ||
              dimAttribute.BackingEntityType == tableNum(DimAttributeOMDepartment) ||
              dimAttribute.BackingEntityType == tableNum(DimAttributeHcmWorker) &&
              dimAttribute.Type              != DimensionAttributeType::DynamicAccount
              join dimAttrSetItem
                where dimAttrSetItem.DimensionAttribute == dimAttribute.RecId &&
                      dimAttrSetItem.DimensionAttributeSet == DimensionCache::getDimensionAttributeSetForLedger()
    {
        //Add the Dimension name and display value to struct
        if (dimAttribute.BackingEntityType == tableNum(DimAttributeOMBusinessUnit))
        {
            struct.add(dimAttribute.Name, ‘BU-002');
        }
        else if (dimAttribute.BackingEntityType == tableNum(DimAttributeOMDepartment))
        {
            struct.add(dimAttribute.Name, ‘DEP-002');
        }
        else if (dimAttribute.BackingEntityType == tableNum(DimAttributeHcmWorker))
        {
            struct.add(dimAttribute.Name, ’114');
        }
    }

    //Prepare the container
    defDimensionCon += struct.fields();

    for (i = 1; i <= struct.fields(); i++)
    {
        defDimensionCon += struct.fieldName(i);
        defDimensionCon += struct.valueIndex(i);
    }

    //if there are fields in struct
    if (struct.fields())
    {
        //Get the DimensionAttributeValueSet table’s Record ID
        dimensionDefault = AxdDimensionUtil::getDimensionAttributeValueSetId(defDimensionCon);
     
        //Update to Customer
        ttsBegin;
        custTable.selectForUpdate(true);
        if (custTable.DefaultDimension)
        {
            custTable.DefaultDimension = DimensionDefaultingService::serviceMergeDefaultDimensions(dimensionDefault, custTable.DefaultDimension);
        }
        else
        {
            custTable.DefaultDimension = dimensionDefault;
        }
        custTable.doUpdate();
        ttsCommit;
    }
}

// Replace Finical Dimension:

static void replaceLedgerDimensions1(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, dimAttrRecId; //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
    DimAttributeHcmWorker           dimAttrWorker; //Backing entity view for Employee type dimension
    DimensionAttributeValue         dimAttrValue; // Contains used financial dimension values
    DimensionAttributeValueSet      dimAttrValueSet; //Contains default dimension records
    DimensionAttributeValueSetItem  dimAttrValueSetItem; //Contains individual records for default dimensions
    LedgerDimensionAccount          sourceDimension = 5637145829, targetDimension; //Record Id DimensionAttributeValueCombination table in which attribute value is to be replaced
    DimensionDefault                sourceDefDimension, targetDefDimension; //To hold the default dimension combination from a Ledger dimension
    LedgerDimensionDefaultAccount   defaultLedgerAccount;
    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);
    dimAttrRecId = new Map(Types::Integer, Types::Int64);

    //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();
    }
 
    // Get the default dimensions from Ledger dimensions
    sourceDefDimension      = DimensionStorage::getDefaultDimensionFromLedgerDimension(sourceDimension);
 
    //Get the default account from Ledger dimensions
    defaultLedgerAccount    = DimensionStorage::getLedgerDefaultAccountFromLedgerDim(sourceDimension);
 
    //Find the Dimension attribute record for the dimension to work on, in our case it is HcmWorker
    dimAttr.clear();
    select firstOnly dimAttr
        where dimAttr.BackingEntityType == emplBackEntityType
           && dimAttr.Type  != DimensionAttributeType::DynamicAccount;

    //Get the backing entity type for the dimension value to process
    select firstOnly dimAttrWorker
        where dimAttrWorker.Value == "51011";
 
    //Find the required Dimension Attribute Value record
    //Create if necessary
    dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimAttr.RecId, dimAttrWorker.RecId, false, true);
 
    //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();

        //Insert Employee dimension set item
        dimAttrValueSetItem.clear();
        dimAttrValueSetItem.DimensionAttributeValueSet = dimAttrValueSet.RecId;
        dimAttrValueSetItem.DimensionAttributeValue = dimAttrValue.RecId;
        dimAttrValueSetItem.DisplayValue = dimAttrWorker.Value;
        dimAttrValueSetItem.insert();

        ttscommit;
    }
 
    //Replace the value in default dimension
    targetDefDimension = DimensionDefaultingService::serviceReplaceAttributeValue(sourceDefDimension, dimAttrValueSet.RecId, dimAttr.RecId);
 
    //Combine the target default dimension, default ledger account to get the resultant ledger dimension
    targetDimension = DimensionDefaultingService::serviceCreateLedgerDimension(defaultLedgerAccount, targetDefDimension);
 
    info(strFmt("Before: %1", DimensionAttributeValueCombination::find(sourceDimension).DisplayValue));
    info(strFmt("Before: %1", DimensionAttributeValueCombination::find(targetDimension).DisplayValue));
}




//Remove a Financial Dimension Value

static void sgxRemoveWorkerDimension(Args _args)
{
    /*
     * We will Remove a worker dimension in this example
    */
    CustTable                       custTable = CustTable::find(‘CUS-00004'); //Customer Record containing Financial Dimension
    DimensionSHA1Hash               hash; //To store the calculated hash for DimensionAttributeValueSet
    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
    DimensionAttributeSetItem       dimAttrSetItem; // Contains the number of dimensions active for a account structure ledger

    HashKey     valueKeyHashArray[]; //To store the has key of dimension in question
    Map         dimAttrRecId, dimAttrStr; //To store the dimension attribute recid and dimension attribute value display value
    Set         dimAttrValueRecId;
    SetEnumerator   setEnum;
    int dimAttrCount, i;

 
    //Initialize the map to store the backing entity types
    dimAttrRecId = new Map(Types::Int64, Types::Integer);
    dimAttrValueRecId = new Set(Types::Int64);
    dimAttrStr = new Map(Types::Int64, Types::String);

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

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

    //Get individual dimension attribute records and display values except worker dimension
    //Store them in sets
    while select DisplayValue, DimensionAttributeValue from dimAttrValueSetItem
            where dimAttrValueSetItem.DimensionAttributeValueSet == custTable.DefaultDimension
            join DimensionAttribute, HashKey from dimAttrValue
                where dimAttrValue.RecId == dimAttrValueSetItem.DimensionAttributeValue
                join RecId from dimAttr
                    where dimAttr.RecId == dimAttrValue.DimensionAttribute
                       && dimAttr.BackingEntityType != tableNum(DimAttributeHcmWorker) //As we ignore worker dimension, its hash key remains blank
    {
        dimAttrValueRecId.add(dimAttrValueSetItem.DimensionAttributeValue);
        dimAttrStr.insert(dimAttrValueSetItem.DimensionAttributeValue, dimAttrValueSetItem.DisplayValue);
        valueKeyHashArray[dimAttrRecId.lookup(dimAttrValue.DimensionAttribute)] = 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 Dimensions”);
    }

    // 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();

        // Insert only specified set items use this
        setEnum = dimAttrValueRecId.getEnumerator();

        while (setEnum.moveNext())
        {
            dimAttrValueSetItem.clear();
            dimAttrValueSetItem.DimensionAttributeValueSet = dimAttrValueSet.RecId;
            dimAttrValueSetItem.DimensionAttributeValue = setEnum.current();
            dimAttrValueSetItem.DisplayValue = dimAttrStr.lookup(setEnum.current());
            dimAttrValueSetItem.insert();
        }
        ttscommit;
    }
 
    ttsBegin;
    custTable.selectForUpdate(true);
    custTable.DefaultDimension = dimAttrValueSet.RecId;
    custTable.doUpdate();
    ttsCommit;
}

No comments:

Post a Comment

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...