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.
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.
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 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.
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.
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.
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.