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