Table and Class CustomizationBy default, Dynamics AX 4.0 supports up to eight inventory dimensions. (Additional inventory dimensions can be defined by the user.) Dimensions describe the characteristics of items or item lots. Item dimensions might include characteristics such as configuration, model, and size. Item lots might have storage dimensions, such as warehouse, location, or pallet, or they might be identified by a serial number and batch number. The following customization scenario describes how to customize tables and classes used by the inventory dimension feature to implement two new item dimensions that describe a specific bicycle configuration: frame size and wheel size. This description is not an exhaustive list of elements that must be changed; instead, it offers guidelines on how to find the elements necessary to customize the full implementation of a new inventory dimension. Creating New Dimension TypesWhen implementing new inventory dimensions, your first task is to create extended data types for each of the dimensions. Doing so provides the following benefits:
This scenario defines a table in which a field of the specific type is part of the primary key. You can define the relationship to this table on the extended data type and subsequently instruct the application runtime to provide lookups and Go To The Main Table Form support. In this example, you enter the Data Dictionary in the Application Object Tree (AOT) and create a BikeFrameSize extended data type and a BikeWheelSize extended data type. Table 6-1 lists the property settings that deviate from the default settings.
Figure 6-1 shows the property sheet for the BikeFrameSize extended data type, accessible by clicking Properties on the context menu for the type. Figure 6-1. The BikeFrameSize extended data type property sheet.
Best Practices Next, create two tables, named BikeFrameSizeTable and BikeWheelSizeTable, in which the frame and wheel sizes for each item can be stored. In addition to the specific inventory dimension types, the tables also contain an ItemId field and a Name field. The ItemId and dimension in each table constitute the table's primary index. Table 6-2 lists the BikeFrameSizeTable property settings that deviate from the default settings. (The property settings for BikeWheelSizeTable are identical except for the BikeWheelSize field and its extended property type.)
Create a unique index on both tables. For BikeFrameSizeTable, name the index FrameIdx and make it contain the ItemId field and the BikeFrameSize field. For BikeWheelSizeTable, name the index WheelIdx and make it contain the ItemId field and the BikeWheelSize field. Declare the indexes as the PrimaryIndex on the respective tables. In the AOT, the fields and the index appear as shown in Figure 6-2. Figure 6-2. The BikeFrameSizeTable definition.
In addition to the fields and index shown in Figure 6-2, you should also set properties in the tables for caching, form references, and so on, and the table should contain field groups and methods for checking the validity of the fields. However, it is beyond the scope of this chapter to describe these enhancements. The Microsoft Dynamics AX SDK contains guidelines and best practices for creating tables. After you define the tables, you should update the extended data types to reflect their relationship to the individual tables, as shown in Figure 6-3. Figure 6-3. The BikeFrameSize extended data type relation.
This relationship instructs the Dynamics AX runtime to provide lookup and Go To The Main Table Form functionality when fields of these types appear on forms. The application runtime uses the related table as the data source for the lookup form and also to find the main table form from the FormRef property on the table. You must therefore create forms for the BikeFrameSizeTable and BikeWheelSizeTable tables and menu items to open the forms. These menu items are added to the FormRef properties on the corresponding tables. You could design the forms to mirror the form shown in Figure 6-4, but this is also beyond the scope of this chapter. Figure 6-4. The Frame Sizes form.
Adding New Dimensions to a TableTo store transactions with the new inventory dimensions, the dimensions must be added to the InventDim table. You do this by creating two new fields, BikeFrameSize and BikeWheelSize, of the corresponding type on the InventDim table. You should also add these fields to the unique DimIdx index, because any combination of inventory dimensions may exist only once in the InventDim table. The display of inventory dimensions in almost any form in the Dynamics AX application is based on field groups and where the content of the field group in the form is built at run time. The forms runtime in Dynamics AX builds the group from the list of fields in the associated field group defined on the InventDim table. Therefore, by adding the new fields to the InventoryDimensions field group on the InventDim table, you make the two new fields available in almost any form that displays inventory dimensions. Position the fields in the field group based on where you want them to appear relative to the other dimensions, as shown in Figure 6-5. Figure 6-5. The InventDim table with customized InventoryDimensions field group.
Figure 6-5 shows "usr" flags on the AutoReport and ItemDimensions field groups, indicating that the custom fields have been added to these groups as well. The AutoReport group is modified so that it will print the new dimensions if you create an auto-report by clicking Print on a form; the ItemDimensions group is modified because the new dimensions are considered to be item dimensions. Although the inventory dimensions are now available in any form because of the interpretation of the field groups by the Dynamics AX forms runtime, the fields are still not visible or editable, because they are not enabled in any inventory dimension group. Moreover, the two new inventory dimensions automatically appear in the Dimension Groups form, because the inventory dimension feature also interprets the InventoryDimensions field group on the InventDim table to find all the currently available inventory dimensions. To make the form work with the new dimensions, you merely state whether the new dimensions are item dimensions. You do this by adding the new dimensions to the isFieldItemDim method on the InventDim table, as shown in the following X++ code. The added lines are shown in bold. The new dimensions will be available for setup in the Dimension Groups form, which is reached through the Navigation Pane under Inventory Management\Setup\Dimensions\Dimension Groups. The dimensions are located in the Item Dimensions grid, as shown in Figure 6-6. Figure 6-6. The Dimension Groups form with new item dimensions.
Important
Enabling New Dimensions in FormsThe new dimensions can be enabled by setting up dimension groups, but the dimensions are not yet visible in the forms. The inventory dimension feature uses a temporary table called InventDimParm to carry certain information, such as whether a dimension:
This is done by reflecting each inventory dimension as a Boolean flag field on the InventDimParm table and then matching the corresponding fields in the X++ code. For example, when a dimension group is queried to determine which dimensions are active, an InventDimParm record is returned where the corresponding flag field is set to true for the active dimensions. The remaining flags are set to false. You must therefore add a frame-size flag and a wheel-size flag to the InventDimParm table, as shown in Table 6-3.
The new fields should also be added to the FixedView and View field groups defined on the InventDimParm table, because they are used in forms from which it is possible to specify whether a dimension should be visible. When you add fields to the table and field groups, the new fields on the InventDim table must be mapped to the corresponding fields on the InventDimParm table in the X++ code. To do this, you modify the dim2DimParm method on the InventDim table, as shown in the following X++ code. The added mappings of BikeFrameSize and BikeWheelSize appear in bold. The same modification must be made to the dimParm2Dim method on the same table to map InventDimParm fields to InventDim fields. Customizing Other TablesThe customizations made so far allow the new dimensions to be enabled on dimension groups and presented in forms. However, you should also consider customizing the following additional tables by adding inventory dimensions to them:
Whether and how these tables should be customized depends on the functionality you are implementing. You should therefore examine how the inventory dimensions are implemented and used for each of the tables. Adding Dimensions to QueriesBecause of the generic implementation of the inventory dimension concept using the InventDim and InventDimParm tables, a substantial number of queries written in X++ use just a few patterns to select, join, and filter the inventory dimensions. So that you do not have to repeatedly copy and paste the same X++ code, these patterns exist as macros that you can apply in your code. To modify these queries, you simply customize the macros, and then recompile the entire application to update the X++ code with the new dimensions. You should customize the following macros:
The bold text in the following X++ code shows the changes that you must make to the InventDimExistsJoin macro to enable the two new dimensions for all exists joins written as statements involving the InventDim table. The three remaining macros are just as easy to modify. Just remember to recompile the entire application after you make your changes. Adding Lookup, Validation, and Defaulting X++ CodeIn addition to macro customizations and the customizations to the previously mentioned methods on the InventDim table, you must also implement and customize lookup, validation, and defaulting methods. These include methods such as the InventDim::findDim lookup method, the InventDim.validateWriteItemDim validation method, and the InventDim.initFrom-InventDimCombination defaulting method. The necessary changes in the InventDim::findDim lookup method for the new inventory dimensions are shown in bold in the following X++ code. Notice the use of the inventDimDevelop macro in the preceding method. The inventDimDevelop macro is merely a macro that contains the following comment. Performing a global search for use of the inventDimDevelop macro should be sufficient to find all the X++ code that must be considered when implementing a new dimension. This search returns all the methods that require further investigation. Figure 6-7 shows results of a search for the use of the macro on all tables. Figure 6-7. Search results for the inventDimDevelop macro.
Best Practices
Most of the methods you will find when searching for the macro will be lookup, validation, and defaulting methods, but you will also see other methods that do not fall under these categories. Such methods would include those that modify the Query object, such as the InventDim::queryAddHintFromCaller method, and methods that describe dimensions, such as the InventDimParm.isFlagSelective method. You should also review these methods when investigating the X++ code. Tip
|