Short intro of Inventory Dimensions.
If we look at the InventDim table, the fields can be split up in 3 groups:
- Product Dimensions
- Tracking Dimensions
- Storage Dimensions
Apart those three groups are also 12 unassigned generic dimensions: InventDimension1 to InventDimension12.



In the tracking dimensions group, fields InventProfileId_RU and InventOwnerId_RU are specified for Russian localization. those can be turned off with the configuration key “Invent tracking dimensions – GTD, inventory profile, owner.”
How to create new Inventory Dimension
- First step is to create a extension of InventDim table (InventDim.Extension) and add our new field called “InventDimension1 ” inside field group that this dimension belongs (in our case Tracking Dimension).
- Create a new relation in InventDim.Extension from the InventDimension1 to your new lookup table.
- Create an extension of InventDimParm table (InventDimParm.Extension) and add InventDimension1Flag to the field group that belongs (in our case Tracking Dimension).
- Create EDT Extension of InventDimension1 and InventDimension1Flag to correct labels on.
- The next step is creating extension of next three tables using chain of comand and the final step is creating the new extended class from InventTrackingDimension.
[ExtensionOf(tableStr(InventDim))]
final class InventDimXXDim1_Extension
{
public DlvTermId parmInventFlavorId(DlvTermId _XXTable = this.getValueForDimension(classStr(XXInventTrackingDimensionDim1)))
{
if (!prmIsDefault(_XXTable))
{
this.setValueForDimension(classStr(XXInventTrackingDimensionDim1), _XXTable);
}
return _XXTable;
}
public static FieldID fieldIdFlavor()
{
return InventDim::fieldIdForDimension(classStr(XXInventTrackingDimensionDim1));
}
}
[ExtensionOf(tableStr(InventDimParm))]
final class InventDimParmXXDim1_Extension
{
public NoYes parmInventFlavorFlag(NoYes _flavorFlag = this.getValueForDimension(classStr(XXInventTrackingDimensionDim1)))
{
this.setValueForDimension(classStr(XXInventTrackingDimensionDim1), _flavorFlag);
return _flavorFlag;
}
public static FieldID fieldIdFlavor()
{
return InventDimParm::fieldIdForDimension(classStr(XXInventTrackingDimensionDim1));
}
}
[ExtensionOf(tableStr(InventDimFieldBinding))]
public final class InventDimFieldBindingXXDim1_Extension
{
protected static FieldName className2FieldName(ClassName _className)
{
var fieldName = next className2FieldName(_className);
if (_className == classStr(XXInventTrackingDimensionDim1))
{
return fieldStr(InventDim, InventDimension1);
}
return fieldName;
}
}
final class XXInventTrackingDimensionDim1 extends InventTrackingDimension
{
public IndexId indexHintForTable(TableId _tableId)
{
switch (_tableId)
{
case tableNum(InventDim):
return IndexNum(InventDim, InventDimension1Idx);
}
return 0;
}
public static XXInventTrackingDimensionDim1 getInstance()
{
return InventDimension::singletonFromInventDimFieldId(fieldNum(InventDim, InventDimension1)) as XXInventTrackingDimensionDim1;
}
public boolean isAffectingPrice()
{
return true;
}
///Override next lines incase behavior should change
public boolean checkExistsValueForItem(InventTable _inventTable, anytype _value)
public boolean isSelective()
public boolean isTransferReceiptMergeable()
public boolean isTransferTransitReceiptMergeable()
}
The results
And of course, do not forget to turn on the configuration key for InventDimension1, testing would be impossible with out . The next screen dumps show the look and feel.

