Just needed to save some code I have been working on in my blog.
This code is used for basically deconstructing ledger dimensions and default dimensions to be able to merge / overwrite dimension attribute values in the ledger dimension.
My scenario is that during the processing of a ledger allocation, I have an "original" transaction that is being allocated. My destination transaction (the transaction that allocates the original transaction to a new ledger dimension) will inherit all the ledger dimensions of the original transaction BUT will have some of it's dimension attribute values overwritten, by a default dimension set up on the ledger allocation rule destination.
Basically I deconstruct the ledger dimension of the original transaction and put all the found dimensions into a map.
I the deconstruct the default dimension of the ledger allocation rule destination, and find the matching entries in my map, to replace them.
When my "merged" map is complete, I prepare a list of DimensionAttributeValueContract objects that is fed in to a LEdgerAccountContract object.
This is then used when calling DimensionsServiceProvider::BuildDimensionStorageForLedgerAccount to create a DimensionAttributeValueCombination record that can be attached on my LedgerJournalTrans record in the LedgerDimension field.
///
/// Finds or creates a DimensionAttributeValueCombination record
///
///
/// GeneralJournalAccountEntry record
///
///
/// LedgerAllocationRuleDestination
///
///
/// Recid of DimensionAttributeValueCombination record
///
///
/// Used to ensure that the correct main account / dimension combination for allocation ledgerJournalTrans are available
/// The combination is constructed using dimensions inherited from the "original" generealAccountJournalEntry record that is being allocated
/// and the default dimension of the ledgerallocationruleDestination. The dimensions from the ledgerAllocationRuleDestination overrides the
/// dimensions of the original generealAccountJournalEntry if set.
///
private recId findOrCreateDimAttrValueCombination(LedgerJournalTrans _sourceTrans,LedgerAllocationRuleDestination _ledAllocationRuleDest)
{
// These objects are used for constructing a ledgerdimension
LedgerAccountContract ledAccountContract;
DimensionAttributeValueContract dimAttrValueContract;
List dimAttrValueObjects;
Map commonAttributeMap;
MapIterator commonAttributeMapInterator;
DimensionStorage dimStorage;
// Deconstruction variables ledgerdimension
int hierachyCount,hierachyIndex;
int segmentCount,segmentIndex;
DimensionStorageSegment dimStorageSegment;
DimensionAttribute orgTransDimAttribute;
DimensionAttributeValue orgTransDimAttributeValue;
// Deconstruction variables defaultdimension for ledgerallocationruledestination
DimensionAttributeValueSetStorage dimAttrValueSetStorage;
int ruleDestCount,ruleDestIndex;
// Common attribute map object
commonAttributeMap = new Map(Types::Int64,Types::Int64);
// Construct dimensions storage object for desconstructing dimension values of original trans
dimStorage = DimensionStorage::findById(_sourceTrans.LedgerDimension);
hierachyCount = dimStorage.hierarchyCount();
// Deconstruction original trans and constructing a List of dimAttrValueContract objects that can be used for finding/creating a
// DimensionAttributeValueCombination record
for(hierachyIndex=1;hierachyIndex<=hierachyCount;hierachyIndex++)
{
segmentCount = dimStorage.segmentCountForHierarchy(hierachyIndex);
for(segmentIndex=1;segmentIndex<=segmentCount;segmentIndex++)
{
// Get segment
dimStorageSegment = dimStorage.getSegmentForHierarchy(hierachyIndex,segmentIndex);
if (dimStorageSegment.parmDimensionAttributeValueId() != 0)
{
orgTransDimAttribute = DimensionAttribute::find(DimensionAttributeValue::find(dimStorageSegment.parmDimensionAttributeValueId()).DimensionAttribute);
orgTransDimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(orgTransDimAttribute,dimStorageSegment.parmDisplayValue());
commonAttributeMap.insert(orgTransDimAttribute.RecId,orgTransDimAttributeValue.RecId);
}
}
}
// Deconstruction ledger allocation rule destination and overriding dimensionattribute values for original transaction dimension with the default dimension
// from the allocation rule destination
// Construct DimensionAttributeValueSetStorage object for deconstructing dimension values of ledgerAllocationRuleDestination
dimAttrValueSetStorage = DimensionAttributeValueSetStorage::find(_ledAllocationRuleDest.ToDefaultDimension);
ruleDestCount = dimAttrValueSetStorage.elements();
// Traverse DimensionAttributeValueSet and "override" values in common attribute map
for(ruleDestIndex=1;ruleDestIndex<=ruleDestCount;ruleDestIndex++)
{
if (commonAttributeMap.exists(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex)))
{
// Remove dimension already gathered
commonAttributeMap.remove(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex));
// Insert overridden dimension
commonAttributeMap.insert(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex),dimAttrValueSetStorage.getValueByIndex(ruleDestIndex));
}
else
commonAttributeMap.insert(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex),dimAttrValueSetStorage.getValueByIndex(ruleDestIndex));
}
// Build list of DimensionAttributeValueContract objects
// Initialize list of DimensionAttributeValueContract objects
dimAttrValueObjects = new List(Types::Class);
commonAttributeMapInterator = new MapIterator(commonAttributeMap);
// Traverse "common set" of attributes for main account
while (commonAttributeMapInterator.more())
{
// Prepare DimensionAttributeValueContract objects for DimensionServiceProvider object
dimAttrValueContract = new DimensionAttributeValueContract();
orgTransDimAttribute = DimensionAttribute::find(commonAttributeMapInterator.key());
orgTransDimAttributeValue = DimensionAttributeValue::find(commonAttributeMapInterator.value());
// Inherit dimension from original transaction
dimAttrValueContract.parmName(orgTransDimAttribute.Name);
dimAttrValueContract.parmValue(orgTransDimAttributeValue.getValue());
dimAttrValueObjects.addEnd(dimAttrValueContract);
commonAttributeMapInterator.next();
}
// Initialize LedgerAccountContract
ledAccountContract = new LedgerAccountContract();
ledAccountContract.parmMainAccount(DimensionStorage::getMainAccountFromLedgerDimension(_sourceTrans.LedgerDimension).MainAccountId);
ledAccountContract.parmValues(dimAttrValueObjects);
return DimensionServiceProvider::buildDimensionStorageForLedgerAccount(ledAccountContract).save();
}
As always - If you use this code, you do so at your own risk.
This code is used for basically deconstructing ledger dimensions and default dimensions to be able to merge / overwrite dimension attribute values in the ledger dimension.
My scenario is that during the processing of a ledger allocation, I have an "original" transaction that is being allocated. My destination transaction (the transaction that allocates the original transaction to a new ledger dimension) will inherit all the ledger dimensions of the original transaction BUT will have some of it's dimension attribute values overwritten, by a default dimension set up on the ledger allocation rule destination.
Basically I deconstruct the ledger dimension of the original transaction and put all the found dimensions into a map.
I the deconstruct the default dimension of the ledger allocation rule destination, and find the matching entries in my map, to replace them.
When my "merged" map is complete, I prepare a list of DimensionAttributeValueContract objects that is fed in to a LEdgerAccountContract object.
This is then used when calling DimensionsServiceProvider::BuildDimensionStorageForLedgerAccount to create a DimensionAttributeValueCombination record that can be attached on my LedgerJournalTrans record in the LedgerDimension field.
///
/// Finds or creates a DimensionAttributeValueCombination record
///
///
/// GeneralJournalAccountEntry record
///
///
/// LedgerAllocationRuleDestination
///
///
/// Recid of DimensionAttributeValueCombination record
///
///
/// Used to ensure that the correct main account / dimension combination for allocation ledgerJournalTrans are available
/// The combination is constructed using dimensions inherited from the "original" generealAccountJournalEntry record that is being allocated
/// and the default dimension of the ledgerallocationruleDestination. The dimensions from the ledgerAllocationRuleDestination overrides the
/// dimensions of the original generealAccountJournalEntry if set.
///
private recId findOrCreateDimAttrValueCombination(LedgerJournalTrans _sourceTrans,LedgerAllocationRuleDestination _ledAllocationRuleDest)
{
// These objects are used for constructing a ledgerdimension
LedgerAccountContract ledAccountContract;
DimensionAttributeValueContract dimAttrValueContract;
List dimAttrValueObjects;
Map commonAttributeMap;
MapIterator commonAttributeMapInterator;
DimensionStorage dimStorage;
// Deconstruction variables ledgerdimension
int hierachyCount,hierachyIndex;
int segmentCount,segmentIndex;
DimensionStorageSegment dimStorageSegment;
DimensionAttribute orgTransDimAttribute;
DimensionAttributeValue orgTransDimAttributeValue;
// Deconstruction variables defaultdimension for ledgerallocationruledestination
DimensionAttributeValueSetStorage dimAttrValueSetStorage;
int ruleDestCount,ruleDestIndex;
// Common attribute map object
commonAttributeMap = new Map(Types::Int64,Types::Int64);
// Construct dimensions storage object for desconstructing dimension values of original trans
dimStorage = DimensionStorage::findById(_sourceTrans.LedgerDimension);
hierachyCount = dimStorage.hierarchyCount();
// Deconstruction original trans and constructing a List of dimAttrValueContract objects that can be used for finding/creating a
// DimensionAttributeValueCombination record
for(hierachyIndex=1;hierachyIndex<=hierachyCount;hierachyIndex++)
{
segmentCount = dimStorage.segmentCountForHierarchy(hierachyIndex);
for(segmentIndex=1;segmentIndex<=segmentCount;segmentIndex++)
{
// Get segment
dimStorageSegment = dimStorage.getSegmentForHierarchy(hierachyIndex,segmentIndex);
if (dimStorageSegment.parmDimensionAttributeValueId() != 0)
{
orgTransDimAttribute = DimensionAttribute::find(DimensionAttributeValue::find(dimStorageSegment.parmDimensionAttributeValueId()).DimensionAttribute);
orgTransDimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(orgTransDimAttribute,dimStorageSegment.parmDisplayValue());
commonAttributeMap.insert(orgTransDimAttribute.RecId,orgTransDimAttributeValue.RecId);
}
}
}
// Deconstruction ledger allocation rule destination and overriding dimensionattribute values for original transaction dimension with the default dimension
// from the allocation rule destination
// Construct DimensionAttributeValueSetStorage object for deconstructing dimension values of ledgerAllocationRuleDestination
dimAttrValueSetStorage = DimensionAttributeValueSetStorage::find(_ledAllocationRuleDest.ToDefaultDimension);
ruleDestCount = dimAttrValueSetStorage.elements();
// Traverse DimensionAttributeValueSet and "override" values in common attribute map
for(ruleDestIndex=1;ruleDestIndex<=ruleDestCount;ruleDestIndex++)
{
if (commonAttributeMap.exists(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex)))
{
// Remove dimension already gathered
commonAttributeMap.remove(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex));
// Insert overridden dimension
commonAttributeMap.insert(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex),dimAttrValueSetStorage.getValueByIndex(ruleDestIndex));
}
else
commonAttributeMap.insert(dimAttrValueSetStorage.getAttributeByIndex(ruleDestIndex),dimAttrValueSetStorage.getValueByIndex(ruleDestIndex));
}
// Build list of DimensionAttributeValueContract objects
// Initialize list of DimensionAttributeValueContract objects
dimAttrValueObjects = new List(Types::Class);
commonAttributeMapInterator = new MapIterator(commonAttributeMap);
// Traverse "common set" of attributes for main account
while (commonAttributeMapInterator.more())
{
// Prepare DimensionAttributeValueContract objects for DimensionServiceProvider object
dimAttrValueContract = new DimensionAttributeValueContract();
orgTransDimAttribute = DimensionAttribute::find(commonAttributeMapInterator.key());
orgTransDimAttributeValue = DimensionAttributeValue::find(commonAttributeMapInterator.value());
// Inherit dimension from original transaction
dimAttrValueContract.parmName(orgTransDimAttribute.Name);
dimAttrValueContract.parmValue(orgTransDimAttributeValue.getValue());
dimAttrValueObjects.addEnd(dimAttrValueContract);
commonAttributeMapInterator.next();
}
// Initialize LedgerAccountContract
ledAccountContract = new LedgerAccountContract();
ledAccountContract.parmMainAccount(DimensionStorage::getMainAccountFromLedgerDimension(_sourceTrans.LedgerDimension).MainAccountId);
ledAccountContract.parmValues(dimAttrValueObjects);
return DimensionServiceProvider::buildDimensionStorageForLedgerAccount(ledAccountContract).save();
}
As always - If you use this code, you do so at your own risk.
Comments
Post a Comment