Monday, May 28, 2012

Enabling a new inventory dimension and the AllBlank dimension Id

I recently explored the idea of enabling a new inventory dimension to track a new type of inventory in Dynamics AX. There were a few goals that I wanted to stick to.
  1. Use one of the existing inventory dimensions rather than adding a new dimension. InventColor, InventSizeId, InventBatchId, and InventSerialId were all candidates.
  2. While technically we would allow blank values, I wanted to have two explicit values to use rather than assuming blank was a meaningful value.
  3. Due to #2, update all existing transactions in the system to be one of the explicit values.
The steps necessary to complete this are straight forward, but there are some words of caution I want to add along the way which I discovered in my investigation.

The first step is to choose which existing inventory dimension to enable. Adding a new dimension is also an option, but as on of my previous colleagues points out this requires a good amount of code changes to do correctly. For this example I will choose InventColor.

The next step is to create a new Dimension Group (Inventory Management > Setup > Dimensions > Dimension groups). Use the form to mimic the existing dimension group or groups and then enable the addition dimension.

Once this is done you need to assign the new dimension group to items. I suggest writing a simple job to perform the update and to be explicit to replace an existing dimension group with your new group. I have seen some set ups where "special" items are created with unique dimension groups. Some analysis should reveal if you need to worry about this case.

Now comes the tricky part: updating existing inventory transactions. Of course, inventory dimensions are stored on the InventDim table, with a unique inventDimId assigned to each new combination of dimensions and used as a foreign key throughout AX. Updating all existing transactions to a single new value is relatively safe, but trying to update existing transactions to multiple values is recipe for complications.

To update all transactions to a new single value, there is only one thing to take note of. There is a special record in the InventDim table with an InventDimID of 'AllBlank' (versions of AX prior to 2009 used 'Axapta' as the InventDimID). This record should NOT be updated. If it is updated the system will very likely create a new record in the InventDim table with an Id of 'AllBlank2' and you will end up with a lot of records that should be pointing to the blank buffer which are actually not pointing to a blank buffer. Other than this special record, all other InventDim records can be updated to the same value of the new dimension without issue.

To update existing transactions to multiple values of the new record has one major obstacle. It's quite possible and even likely that you may want to update an existing inventDim record to both values, but of course you cannot without creating a new record with a new inventDimId. Now if you knew confidently which other records in the system needed to be updated to point to the new Id this wouldn't a such a problem, however I have found that weeding out all of these references and determining which should be updated to which Id is not a trivial exercise, so I recommend against this approach. If you can in any way live with only one value in the past and the new value going forward, I strongly recommend doing so.

One other side note: I have seen some interesting uses of inventDim records which I wanted to call out. Sometimes the business rules are such that only a subset of the dimensions are important. In these cases I have seen InventDim records where the important dimensions are populated and the non-important dimensions are forced to be blank, and the resulting inventDimId is used as a reference. I don't recommend this approach, it would be much better to simply reference the individual important dimensions directly even at the expense of size. In this situation it is entirely possible that adding a new dimension could break some assumption in the code as to whether the new dimension is important or not. If you think you have this situation in your code base you should examine the parts of code that deal with this.

In Summary, adding a new dimension to an existing system is not a big or scary of a task as it may seem at first as long at you can make the assumption that all existing data is either not converted or is converted to a single value. In my experience so far, outside of the 'AllBlank' dimension Id issue, I have not seen any adverse effect of updating all existing transactions to a single value.

1 comment:

  1. I wanted to post a quick follow up on this post. Above I strongly recommend against trying to update existing transaction to more than one value of the new dimension. After having some more time to experiment with this, I want to re-iterate this point. Due to the way inventory transactions are summarized to determine the on hand quantities and other quantities the risk here is to incorrectly mark some inventory transactions or miss some inventory transactions that would need to be marked and cause the on hand quantities to be incorrect (i.e. positive for some combinations and negative for other combinations). This could cause the unfortunate circumstance of consuming inventory that does not really exist.