Extensible Inventory Dimensions


Background

Adding new inventory dimensions is currently impossible without succumbing to overlayering. As you are reading my blog, you'll know we need an extensible alternative. This post outlines the solution we are proposing to enable extensible inventory dimensions.

There are several technical limitations influencing the design of the proposed solution. The most significant is the SQL statements throughout the application containing where-clauses on InventDim. Most of these are implemented using macros - but that doesn't change the fact that SQL statements are not extensible. Many of the SQL statements could be rewritten to use Query objects (which are extensible) - still many delete_from and update_recordset would remain. A viable solution cannot require changes to these SQL statements when adding new dimensions.

Another mention-worthy technical limitation is the amount of inventory dimensions we can support. Each adds a small overhead, and the InventDimFixed EDT sets an upper-limit on 32. This EDT contains a bit mask for each dimension, and as the EDT is an integer that limit is 32. Now, we could change it to an Int64 (or better still a container, or better still remove it) - and we might have to eventually. For now; we'll try to stay below the limit of 32.

Disclaimer

Before I describe the solution, let me emphasize, that this is work-in-progress and subject to change. The reason for sharing this draft is twofold, a) to get early feedback, and b) to describe a viable solution to this pretty hard problem.

Solution overview

The corner stone in the proposed solution is that multi-roles partake in the life-cycle of a solution. In this context, I'll be simplifying and generalizing, in real-life there is overlap between the roles, and sometimes it might even be the same person filling several roles.

Microsoft

Microsoft provides a finite set of unused dimension fields. In other words, Microsoft provides the physical schema.

The exact number is not settled yet, but 10 is our current working assumption. 8 will be string-based, 1 real-based and 1 utcdatetime based. This brings the total number of inventory dimensions in the standard application to 25. This still leaves room below the 32-limit for solutions not yet migrated, and future additions.

ISV-role

The ISV must be able to add new inventory dimensions. The solution must provide all the specific functionality for the dimension, it must be strongly-type, maintainable, testable and performant. Further, the solution must be agnostic to other ISV's solutions.

The ISV builds a solution that doesn't reference the physical schema directly, but goes through an indirection. With the new X++ extension capabilities, this can also be done seamlessly.

In other words, the ISV provides the logical implementation.

VAR-role

The VAR must be able to deliver a fully functional system to a customer. The system can contain solutions from multiple ISVs - each potentially containing new inventory dimensions. In total up-to 10 ISV dimension fields are supported.

The VAR provides the binding between the physical data model and logical implementation.

Details

The first half of the solution is straight forward. A new class hierarchy is introduced. Each new dimension must be implemented in a new class deriving from InventDimension. The InventProductDimension class hierarchy has already been released with the July-2017 update. The InventTrackingDimension is planned. As of right now we do not have plans for InventStorageDimension. With this, ISVs can introduce a new dimension without having to change any of the logic on the InventDim table.

 

To reference the new dimension in a strongly-typed fashion the ISV introduces a table extension class to the InventDim table. We already introduced similar extensions for Style, Color and Size, so they can be used as templates.

Now the dimensions can be referenced like this:

 

The ISV can now build logic including data model and user interface for maintaining the list of dimension values for the new inventory dimension.

 

The second half of the solution is the data model. The standard application will contain the following for each of the new dimension:

  • One Label file,
  • One Configuration key,
  • Two EDTs (for the field on InventDim and for the flag on InventDimParm),
  • One field on InventDim table,
  • One field on InventDimParm table,
  • One field on InventDimFieldMap map - and one field on each of the (~30) tables mapped.

 

The VAR's job is to wire the ISV solution(s) to the available dimension fields on InventDim for a given customer. We are aiming at minimizing this work, as of now it includes:

  • Implement the binding mapping.
    This is accomplished by extending the method InventDimFieldBinding.className2FieldName().
  • Enable the configuration key(s). Business as usual.
  • Extend the EDT(s) - to specify the right string size.
  • Extend the Label file(s) - i.e. copy the ISV provided labels into the right label file.
  • Extend the ProductDimensions or TrackingDimensions field groups on InventDim (and a few other tables) - depending on the type of dimension.
  • Extend relations and index as needed on InventDim.
  • <More to come>

 

Some obvious questions

When is this available?

This is still much subject to change. This will be a multi-release project. The first installment came in the July-2017 update (InventProductDimension class). Full support for product dimensions is targeted for the "Fall release 2017". Full support for tracking dimensions is targeted for the "Spring release 2018". As we haven't heard any demand for custom storage dimensions, we have no plans to enable these.

Can the VAR's steps be automated?

Yes, we are considering building some hand-rails to ensure VAR enables the dimensions correctly. At this point details are unknown.

Can I use product attributes instead of inventory dimensions?

Maybe! There are many cases where product attributes can be used instead of inventory dimension. Product attributes are much simpler in nature (configuration only), and do not require any code changes. Whenever possible you should use product attributes instead of inventory dimensions.

Where can I find more details?

There are many details not covered by this post, including how we will deal with data entities, table indices and relations. We will share more as the solution materializes.

I have a solution that will not fit this model - what should I do?

Please reach out to me directly using the contact button on my blog.

Why 10 custom dimensions?

Based on interviews with ISVs and telemetry it appears that 10 custom dimensions should be enough. This leaves a small room (7) for adding more later. This room can also be used by ISVs that haven't yet migrated their solution to be overlayer free.

How many of the 10 are product dimensions and tracking dimensions?

Each of the 10 fields can be used as either a product or tracking dimension. The type is determined for each system when the VAR adds the physical field to the right field group on InventDim and InventDimParm. Disclaimer: This is subject to change - if we discover a roadblock preventing this flexibility.

Why only string, real and utcdatetime fields?

It is our assumption that other types of fields can be implemented using these 3 types. Guid and Enum can be implemented using string. Integer and int64 can be implemented using real (or string). Date and Time can be implemented using utcdatetime. For storage string is enough; however, to support sorting the other 2 types will be supported too.

 

THIS POST IS PROVIDED AS-IS; AND CONFERS NO RIGHTS.


Comments (6)

  1. Victor Mauze says:

    Michael, thank you for sharing this information!
    I just reviewed compatibility of proposed solution with our current ISV project needs. And I want share some questions and notes with you. Probably it helps improve this new framework.
    1) 10 fixed dimensions looks not enough. Our ISV solution add exactly 10 dimensions and don’t leave rooms for any other which customer may want to install. You can say that InventDimFieldBinding allow customer dynamically configure environment and switch off one our dimension and use this free room for some other. But this ability adds much problems from technical side.
    2) We cannot really reference dimension by InventDim.(InventDim::fieldIdISVDim()) without previous validation, because it can be unmapped and cause error or unexpected behavior. As result all places where dimension was referenced by name must be reworked to if() blocks.
    3) How to use field groups, if we need put dimensions in one existing or add new group in some special order? Sure, we can extend InventDim and other tables, but we don’t know in advance what dimensions must be added in this group. Using edit methods is possible, but has one very significant limitation – we cannot filter and order by such fields. Moreover 2 our dimension must use type conversion, because we have no appropriate type among these 10 dimensions.
    4) The similar question – what about indexing when purpose of dimensions is unknown?
    5) What the main purpose of InventDimension hierarchy? It mostly used for enumeration purpose. Moreover, InventProductDimension enumerator use group from InventDim. Why not use reflection? Finally, we will have numerous classes with one validation function. And same number of extensions for base InventDimension, InventDim, InventDimParm… It can be avoided if use reflection and common parm-methods which allow get/set value for any dimensions in one line without external conversions and validations.

    The main question is, why not use approach like one implemented for financial dimensions in AX2012? Yes, too much rework for MS, understand. But it helps us solve the biggest AX7 problem how to extend non-extendable.

    1. Thanks Victor,
      Let me answer your questions:
      1) Yes, 10 is a limitation. It is worthwhile for us to understand how many solutions will fit under that limit. From our engagement with ISVs most ISVs add 0-2 dimensions, so 10 should accommodate for most installations. Perhaps some of your 10 dimensions can be converted to product attributes?
      2) The intention is not to allow ISV solutions to be partly enabled. If a solution is installed it is expected that all the dimensions are mapped.
      3a) Field groups are extensible. You can add fields to existing groups, and control the order of the fields you added.
      3b) What type do you have that doesn’t fit into string, real or datetime?
      4) For the VAR the purpose of the dimensions is known, so he can update index as needed. Further SQL is coming with new auto-indexing capabilities making this a moot point (eventually).
      5) The purpose of the InventDimension hierarchy is to encapsulate dimension specific functionality in one class – instead of having it spread out (as today). To enumerate, for example, product dimensions we use reflection of the ProductDimensions field group on InventDim. We might as well reflect on the class hierarchy – those two must be in-sync. It is a technical detail, if it has any implications, please enlighten me.
      Main question) Product Attributes are implemented using key/value pairs like Financial Dimensions. They are fully configurable (no code changes required). However; they also come with a number of limitations that we haven’t been able to resolve, and which are the reasons for having Inventory Dimensions side-by-side with the Product Attributes: a) Performance. We haven’t been able to achieve parity in performance in the on-hand checks using a key/value layout compared to a columnar layout. This is why Product Attributes are not considered when doing on-hand checks. b) API. Inventory dimensions usually require extensive X++ logic, forms and reports. Building a meaningful configuration-only dimension or abstraction-level on the configuration to allow for the code-level implementations as extensions is not trivial (to say the least) c) This would break our backward compatible promise. When the financial dimensions were introduced it was a major breaking change. We are now under the constraints that any AX7 solution must be able to upgrade seamlessly.

  2. Does this apply to the Storage Dimension as well?

    1. I assume that storage dimensions are not as likely to be amended… I see the reason for why it is not available. 🙂

  3. Tommy Skaue says:

    Will only ISVs be able to create and provide extensions supporting additional Product-/Tracking dimensions? Put another way, are there any “role restrains” on who can add additional custom dimensions through code?

    1. Hi Tommy – no constraints like that. A VAR can fill in both roles, and so can an ISV (how else can they test their solution?).
      Thanks for the good question!

Skip to main content