Accessing the financial dimension framework

Financial dimensions provide the ability to add structured analysis codes to source documents that are posted to the general ledger for later analysis. These appear as fields on forms such as the customer details form, but they are constructed from data. We can decide which analysis fields should display and whether they should be linked to custom lists or real tables in AX, such as the customer group table.

From the AOT, open (right-click and choose Open) the CustTable form and expand the Financial dimensions fast tab.

The fields that appear on the customer details form actually result in a single field on CustTable, named DefaultDimension. This is a foreign key to a set of records called a dimension attribute value set.

The fields displayed are built by looking up a record in DimensionAttributeValueSet and building the controls from the related records in DimensionAttributeValueSetItem. The field names are taken from the DimensionAttribute table.

From this perspective, the tables involved are as follows:

Table

Relation

Purpose

DimensionAttributeValueSet

 

The foreign key found on the main table, such as CustTable.

DefaultDimension

DimensionAttributeValueSetItem

DimensionAttributeValueSet ==

DimensionAttributeValueSet.RecId

A record for each value (a business unit), which is indirectly related to the type of value, (BusinesUnit)

DimensionAttributeValue

AttributeValueSet ==

DimensionAttributeValueSetItem.RecId

Relates the set item, with some other information, to the attribute.

DimensionAttribute

DimensionAttribute ==

DimensionAttribute.RecId

The attribute, such as BusinessUnit.

There are many more tables, and this structure looks particularly complicated, where many tables in the data structure hold only foreign keys. The table browser is virtually unusable for investigating the data behind the scenes.

Although it may seem discomforting that looking at the physical tables doesn't really help us understand what is going on, we don't have to. The data structure wasn't designed to be modified or extended, and there shouldn't be a case where we would want to. There are tasks that are sometimes required, which require further explanation.

The most common tasks we may want to do are as follows:

  • Add a dimension attribute entity to a record, such as Business unit
  • Access a specific dimension from a dimension value set held against an entity, such as CustTable
  • Merge two dimension sets

The first point is to be able to identify, in code, the attribute we want.

We do this by simply adding a primary key relation to the DimensionAttribute table, and we can then add the resulting field to a form as a ReferenceGroup control.

This is something we have done many times, and a good example is the InventParameters table, which has a SiteDimensionAttribute relation. The resulting foreign key field is presented in the InventSiteDimensionLink form.

This first part holds nothing new to us, so we can use it to demonstrate the second part. You can test your knowledge and add such a field to a suitable parameter table, but for demonstration purposes, we will use InventParameters.SiteDimensionAttribute.

To get and set the BusinessUnit dimension on the customer record, follow these steps:

  1. In the InventSiteDimensionLink form, set the dimension attribute to BusinessUnit.
  2. For the first customer, expand the Financial dimensions fast tab and set the BusinessUnit dimension to 001. If you are not using Contoso data (USMF), set this to a specific value and note down another value.
  3. Using the relations defined earlier, write a job to get the BusinessUnit from a customer. Use the following lines of code as an example:
    static void ConFMSCustTabeGetBusinessUnit(Args _args)
    {
        CustTable custTable;
        DimensionAttributeValueSetItem attrItem;
        DimensionAttributeValue attributeValue;
    
        RefRecId attributeRecId = 
               InventParameters::find().SiteDimensionAttribute;
    
        custTable = CustTable::find("DE-001", true);
    
        select firstOnly attrItem
            where attrItem.DimensionAttributeValueSet == 
                                    custTable.DefaultDimension
            join attributeValue 
            where attributeValue.RecId == 
                            attrItem.DimensionAttributeValue &&
                  attributeValue.DimensionAttribute == 
                            attributeRecId;
    
        info(attrItem.DisplayValue);
    }
  4. The code required to set the same attribute value to a new one is as follows:
    static void ConFMSCustTableSetBusinessUnit(Args _args)
    {
        DimensionAttributeValueSetStorage storage;
        DimensionAttributeValue attrValue;
        DimensionAttribute      attribute;
        CustTable               custTable;
        RefRecId                attributeRecId;
        DimensionDisplayValue   businessUnit;
        boolean                 updateRequired;
    
        custTable = CustTable::find("DE-001");
    
        // the new value to set
        businessUnit = "002";
    
        // get the attribute for the business unit
        attributeRecId = InventParameters::
                               find().SiteDimensionAttribute;
    
        // this is required in order to get the value record
        attribute = DimensionAttribute::find(attributeRecId);
    
        // this will find or create the
        // value record for the business unit
        attrValue = DimensionAttributeValue::
                findByDimensionAttributeAndValue(attribute,
                                                 businessUnit,
                                                 false, true);
        // construct the dimension value set
        // storage handler from the customer dimension
        storage = DimensionAttributeValueSetStorage::
                             find(custTable.DefaultDimension);
        storage.addItem(attrValue);
    
        ttsBegin;
        custTable.selectForUpdate(true);
        // this will trigger the class to persist the
        // new data structures to the database and return
        // the new DimensionAttributeValueSet RecId
        custTable.DefaultDimension = storage.save();
        custTable.update();
        ttsCommit;
    }

The key commands here are described next:

attrValue = DimensionAttributeValue::
            findByDimensionAttributeAndValue(attribute,
                                             businessUnit,
                                             false, true);

The storage class needs a DimensionAttributeValue record, which needs to be found or created for the new business unit value:

storage.addItem(attrValue);

After the storage is constructed, we can update the data stored in the class. The preceding line will add the item or replace it if it exists.

The final key command is the following line, which writes the internal structures to the database and returns the new record ID:

custTable.DefaultDimension = storage.save();

References

Refer to What's new: Financial dimensions framework [AX 2012] at http://technet.microsoft.com/en-us/library/dn527192.aspx. This also contains a link to the white paper, and provides some great technical background information.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.218.45