Requirement:
In D365 Finance and operations, if the warehouse which is set on the store is enabled for “Use warehouse management process”, inventory lookup matrix for product master will not show on-hand quantities.
Solution:
Out of the box D365 Finance and operations does not support inventory lookup of product master which has warehouse process enabled.
For that we did a customization using the extension of class “RetailTransactionServiceInventory” method “GetProductAvailabilityByDimensions”.
Make sure to have the proper inventory status and other related configuration of warehouse management.
For the customization it will check if the warehouse is enabled for “Use warehouse management process” and after that it will take the “Default inventory status ID” and “Default receipt location” for the specific warehouse because of the minimum required dimension of the “Reservation Hierarchy” levels defined on the item.
If the item is not enabled for “Use warehouse management process”, it will use out of the box inventory lookup.

Below is the code to achieve the result,
using TS = Microsoft.Dynamics.Commerce.Runtime.TransactionService.Serialization;
[ExtensionOf(classStr(RetailTransactionServiceInventory))]
final class RetailTransactionServiceInventory_POS_Extension
{
public static container GetProductAvailabilityByDimensions(str _itemAvailabilityLookupParamXmlStr)
{
int infoLogIndex;
container output = [false, ''];
container GetProductAvailabilityByDimensions = [false, ''];
GetProductAvailabilityByDimensions = next GetProductAvailabilityByDimensions(_itemAvailabilityLookupParamXmlStr);
try
{
infoLogIndex = Global::infologLine();
RetailRTSItemAvailabilityParameter itemAvailabilityParameter = RetailRTSItemAvailabilityParameter::fromXML(_itemAvailabilityLookupParamXmlStr);
InventTable inventTable = InventTable::find(itemAvailabilityParameter.parmItemId());
InventDimParm inventDimParm = InventDimParm::activeDimFlag(InventDimGroupSetup::newInventTable(inventTable));
if (inventDimParm.WMSLocationIdFlag && WHSInventEnabled::exist(itemAvailabilityParameter.parmItemId()))
{
str dimensionType, dimensionValue;
System.Collections.ArrayList resultList = new System.Collections.ArrayList();
ListEnumerator inventLocationIdEnum = itemAvailabilityParameter.parmInventLocationIdEnum();
while (inventLocationIdEnum.moveNext())
{
InventLocation inventLocation;
select inventLocation where inventLocation.InventLocationId == inventLocationIdEnum.current();
if (inventLocation.WHSEnabled)
{
ListEnumerator productDimensionCombinationEnumerator = itemAvailabilityParameter.parmProductDimensionCombinationEnum();
while (productDimensionCombinationEnumerator.moveNext())
{
EcoResItemSizeName inventSizeId;
EcoResItemColorName inventColorId;
EcoResItemStyleName inventStyleId;
EcoResItemVersionName inventVersionId;
EcoResItemConfigurationName configId;
List productDimensionCombination = productDimensionCombinationEnumerator.current();
ListEnumerator productDimensionEnumerator = productDimensionCombination.getEnumerator();
while (productDimensionEnumerator.moveNext())
{
[dimensionType, dimensionValue] = productDimensionEnumerator.current();
switch (dimensionType)
{
case 'Size':
inventSizeId = dimensionValue;
break;
case 'Color':
inventColorId = dimensionValue;
break;
case 'Style':
inventStyleId = dimensionValue;
break;
case 'Version':
inventVersionId = dimensionValue;
break;
case 'Configuration':
configId = dimensionValue;
break;
}
}
TS.InventoryInfo variantInventoryInfo = RetailTransactionServiceInventory::getOnHandInfo(
itemAvailabilityParameter.parmItemId(),
inventSizeId,
inventColorId,
inventLocation,
itemAvailabilityParameter.parmIsSizeActive(),
itemAvailabilityParameter.parmIsColorActive());
resultList.Add(variantInventoryInfo);
}
System.Type[] typeArray = new System.Type[1]();
TS.InventoryInfo inventoryInfo = new TS.InventoryInfo();
typeArray.SetValue(inventoryInfo.GetType(), 0);
output = [true, '', RetailTransactionServiceInventory::SerializeToJson(resultList, typeArray)];
}
else
{
return GetProductAvailabilityByDimensions;
}
}
}
else
{
return GetProductAvailabilityByDimensions;
}
}
catch(Exception::Error)
{
str error = strFmt("@RET2382" + RetailTransactionServiceUtilities::getInfologMessages(infoLogIndex));
str axCallStack = con2Str(xSession::xppCallStack());
output = [false, error, ''];
}
return output;
}
private static TS.InventoryInfo getOnHandInfo(
ItemId _itemId,
EcoResItemSizeName _inventSizeId,
EcoResItemColorName _inventColorId,
InventLocation _location,
boolean _isSizeActive,
boolean _isColorActive
)
{
InventQty availPhysical,orderedQty,reservPhysical;
InventOnhand inventOnhand;
TS.InventoryInfo inventoryInfo;
InventSum inventSum;
InventDim inventDimBuffer;
if (_isSizeActive && _isColorActive )
{
inventoryInfo = new TS.InventoryInfo();
while select inventSum
join inventDimBuffer
where inventSum.Closed == NoYes::No && inventSum.ItemId == _itemId && inventSum.InventDimId == inventDimBuffer.inventDimId
&& inventDimBuffer.InventSizeId == _inventSizeId && inventDimBuffer.InventColorId == _inventColorId &&
inventDimBuffer.InventSiteId == _location.InventSiteId && inventDimBuffer.InventLocationId == _location.InventLocationId &&
inventDimBuffer.WMSLOCATIONID == _location.WMSLocationIdDefaultReceipt && inventDimBuffer.InventStatusId == _location.DefaultStatusId
{
availPhysical += inventSum.AvailPhysical;
orderedQty += inventSum.Ordered;
reservPhysical += inventSum.ReservPhysical;
}
inventoryInfo.ItemId = _itemId;
inventoryInfo.InventoryLocationId = _location.InventLocationId;
inventoryInfo.InventoryAvailable = num2Str(availPhysical, 0, 16, 1, 0);
inventoryInfo.OrderedSum = num2Str(orderedQty, 0, 16, 1, 0);
inventoryInfo.PhysicalReserved = num2Str(reservPhysical, 0, 16, 1, 0);
}
else
{
inventoryInfo = null;
}
return inventoryInfo;
}
private static str SerializeToJson(System.Object _objectToSerialize, System.Type[] _typeArray)
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(
_objectToSerialize.GetType(),
_typeArray);
System.String result;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
serializer.WriteObject(ms, _objectToSerialize);
result = System.Text.Encoding::UTF8.GetString(ms.ToArray());
}
return result;
}
}
After the above customization,
Below is the product master with enabled warehouse process,

Inventory lookup in POS:


Thanks,
Happy Daxing with Rizz 😉
