10 September 2020

How to extend the DynaRent Dimensions Framework for Customizations?

Coding

When implementing DynaRent, To-Increase’s equipment rental solution suite, we’ve seen that customizations are required in most cases to meet customer requirements. This means besides creating a set of new functions and minor adjustments, it might also be that the dimensions a customer is already using are different from those that come out of the box with DynaRent.

Also, we’ve had some customers come to us with a requirement to implement dimensions on another table where it is not yet implemented. Since DynaRent made an extension on the standard AX dimensions, it will be a challenge to make full use of this extended dimensions framework.

This blog will guide your developers through the steps that will enable them to utilize the DynaRent Dimensions Framework completely for your customization.

The steps 

Step 1. Object adjustments 

You will need to make some adjustments, such as changes in tables, forms, and classes, and the next sections will guide you through each of them.

Table adjustments 

As first step, you need to identify the table that requires the dimensions, and then do the following:  

  • Make sure that the field DefaultDimension is available on the table (either with or without a prefix).
          If it is
    not, then create a new field of type Int64 and:
    • Set the ExtendedDataType property to DimensionDefault.
  • Create a relation to the DimensionAttributeValueSet and set the relation between the new dimension field and
          the
    RecId field of the DimensionAttributeValueSet table.
  • Next, the main form for the table needs to be adjusted, and if the form does not have a financial dimensions
          tab
    , then you need to create it as follows: 
    • Add a new tab to the form and name it FinancialDimensions (prefix it if required) and set the Caption
            to
      @SYS101181. 
    • Apply the “Dimension Entry Control” pattern. 
    • Now a new element of type “Dimension entry” needs to be added with the following properties: 
      • Auto Declaration: Yes 
      • Controller class: LedgerDefaultDimensionEntryController 
      • Caption Test: @SYS138487 
      • Data Source: <table on which you have added the DefaultDimension field> 
      • Value Data Field: <the actual dimension field on the data source> 
  • The final adjustment on the form (when it exists in the current model) or on the extension class
          (when the form’s origin is in another model) is to add the following piece of code to the
    init method after the
          super() call: FINDimValueController::setEditableDimensionSet (tableNum(<Table name>), <Dimension entry control
          name
    >).  

Step 2. Class adjustments 

Now that the table and form are adjusted, you’ll also need to create some code adjustmentsFirst of all, it is good to mention there are a couple of classes that act as the core of the DynaRent Dimensions Framework, and these are DNREventGenericFINDimValueController, and FINDimValueResult. 

  • DNREventGeneric is a DynaRent class, meaning that if it needs to be customized, it must be done through extension. So, firstly, you need to create a new EventHandler class and events to this class. 
  • FINDimValueController is also a DynaRent class and needs to be extended specifically for the table for which you want to enable the dimensions framework. 
  • FINDimValueResult: Since a dimension value can be either a simple alphanumeric value or a reference to another value, this class is introducedInstances of this class are passed around rather than the actual values or record and table references. This is also a DynaRent class, and it does not need to be extended. 
  • DNRCrossCompanySynchronizer is a DynaRent class that manages the synchronization between companies and is consumed by the DNREventGeneric class. 

DNREventGeneric 

Lets start with the first one, DNREventGeneric. Since this is a DynaRent class, it cannot be adjusted, and therefore an EventHandler class needs to be created. If you would make a class that acts as an extension of (using the ExtensionOf attribute), then it would violate a best-practice check. Once this EventHandler class is created (using the customer’s suggested naming convention), you should create a couple of data event handler methods, and here are few essential ones: 

  • Inserted/Inserting 
  • Updated/Updating
  • Deleted/Deleting

Which event handler to use is decided based on whether the dimensions should be determined during or after the record modification. When it needs to happen while the record is modified, then you should use the event handler ending with “ing,” and if it is after the record modification, then the event handler ending with “ed” should be used. 

Depending on the action, one of the following static methods on the FINDIMValueController class need to be called: 

  • eventInsert 
  • eventUpdate 
  • eventDelete 

These methods require only one parameter of type Common which is the current record of the table for which the dimensions are implemented. Below a screenshot of the methods mentioned for the PurchReqLine table. 

the methods mentioned for the PurchReqLine table
 
When it needs to be synchronized across companies, then the doSync method (also static) on the DNRCrossCompanySynchronizer needs to be called. 

The doSync method requires the following 2 parameters:  

(a) The current record and a DataEventType to specify whether the record is inserted, updated, or deleted. When, for example, the Inserted data event handler is being used, then the method calling the doSync should look like the screenshot below. 

The doSync method requirement 1

(b) Then there is also the static ValidatedWrite event handler to validate the values. This is not required, but it is good practice to have this event handler for your table as well. This method also requires only the table buffer as parameter. 

The doSync method requirement 2

FINDimValueController  

The next class is FINDimValueController. When implementing the dimensions for a new tablethis class needs to be extended like so: <customer specific prefix>_FINDimValueController_<table name>.  

It needs to have at least the following 3 methods: 

  • getDescriptionto return a descriptive value of the record 
  • getDimensionFieldIdto return the field number of the dimension field on the consumed table 
  • new: this method has one parameter which is the record that is currently being processed and stores it in a global variable

Below is a screenshot of the implementation on a table called EBCTransactionType: 

the implementation on a table called EBCTransactionType

There are two more types of methods that can be implemented to retrieve the correct values used in the dimension field: 

  • ref* methods: With this type of method, dimension reference is copied from one record to the current method. For examplethe location from the InventTable to the SalesLine 
  • find* methods: This type of method is used to copy the value and place it in one of the dimension attributes. For example, the ItemId of the InventTable on the SalesLine’s ItemId dimension (if available). 

Besides this table-specific class, two new classes also need to be created, so the new table that supports dimensions is processed correctly. They are: 

  • An extension class of the FINDimValueController class which has the [ExtensionOf(classStr(FINDimValueController))] attribute. This new extension class requires the getDimensionableTableIds method to be implemented. By using CoC, a set of tables can be retrieved by the next call, and the newly supported table(s) can then be added to this set, like the screenshot below: 

An extension class of the FINDimValueController class

  • An event handler class for the FINDimValueController class. In this class, a new event handler method needs to be created for the contructDelegate method. An example can be found in the screenshot below 

DNRCrossCompanySynchronizer 

Finally, the DNRCrossCompanySynchronizer class needs to be extended because intercompany synchronization needs to be applied, followed by adding at least the following two methods to the extension class: 

  • getFieldIds2Sync: In this method, all fields that need to be synchronized across companies are added to a set 
    Here’s an example of the InventSite table: 

Example of getFieldIds2Sync

  • getFieldIds2Identify: In this method, the fields to identify the record are added to a setHere’s an example of the InventSite table 

Example of getFieldIds2Identify

Furthermore, it is also possible to add an eventDeleted and eventInserted method to create logic specifically created for the currently consumed record. 

The setup 

Once all code and objects are created and adjusted, it is time to complete the setup. Assuming the correct dimensions are already available, it is just a matter of pointing the correct methods to the dimension field on the correct table. Below are two examples of dimensions that can be setup on the SalesLine table.  

First example of the setup on the SalesLine table

Second example of the setup on the SalesLine table

The first example has a Reference method filled with a ref method (refEBCLot), meaning that it will create a reference to the dimension found in the refEBCLot method. The second example used a find method to retrieve a certain value to store as dimension value. 

If you’ve added the dimension field to a new table and made all of the adjustments in code and objects, then it is possible to add this new table to the setup as well. This is how this is done: 

  1. Create a new record in the Dimension attribute setup 
  2. In the Reference table name field, select the new table 
  3. In Financial dimension, field select the dimension that needs to be filled 
  4. Use the Reference field or Reference method field to select how the value for the dimension needs to be retrieved 
  5. Then there are 3 fields which are also good to mention:
    • Autocreatewhen this is set to Yes and there is not a value found in the Custom list financial dimension (DimensionFinancialTag) then a record will be created in that table
    • Allow edit: if set to Yes then the user is allowed to adjust the dimension value 
    • Force value: if set to Yes then a value will be stored for the dimension instead of reference

Curious to find out what DynaRent Solutions Suite, our end-to-end equipment rental solution, has to offer?

DynaRent-Solutions-Suite
Gerard Doornenbal,
Gerard Doornenbal,
Senior Software Engineer

Also interesting