Relevant menu items:
Warehouse management / Setup / Location directives
Warehouse management / Setup / Warehouse / Fixed locations / Product variant
Warehouse management / Setup / Warehouse / Location stocking limits
Warehouse management / Work / Work creation history log
The Work creation history log should be enabled in Warehouse management / Setup / Warehouse management parameters / General / Work / Enable work creation history log.
Work creation process - Movement by template (WHSWorkCreationProcess::MovementByTemplate) can be used to test the Location directives process. WhsWorkExecuteDisplayMovementByTemplate class.
The initial task is to specify not only a fixed product variant location but also an "overspill" location if the primary fixed product variant location is already full.
The main loop, which goes through all suitable location directives is in
WhsLocationDirective.findLocation()
The most appropriate place to modify the location directive query is in
WhsLocationDirective.buildLocDirTableQuery()
The method is called with WhsLocationDirectiveTableQueryParameters class as a parameter containing useful context information. However, the information is not full. It does not contain the inventory dimensions of the item. Inventory dimensions can be taken from initialInventDimId class variable. Which unfortunately is private (version 10.0.41, extension requested and by the time you read this article might have been implemented by Microsoft), however, you can still access it using the
reflection.
For example, you may want to use in a location directive query data sources, which depend on product variants. As per standard, you can only use the information specified on the item.
Call stack:
WhsLocationDirective.findPickPutLocation
WhsLocationDirective.findLocation()
WhsLocationDirective.hasLocDirMatches()
WhsLocationDirective.buildLocDirTableQuery()
Location directive Query example:
SELECT *
FROM InventTable(InventTable_1)
WHERE ((ItemId = N'VK075'))
JOIN * FROM WHSInventTable(WHSInventTable)
ON InventTable.ItemId = WHSInventTable.ItemId
WHERE ((InventTable(InventTable_1).))
EXISTS JOIN * FROM WHSProductVariantFixedLocation(WHSProductVariantFixedLocation_1)
WHERE InventTable.ItemId = WHSProductVariantFixedLocation.ItemId AND ((WMSLocationId LIKE N'301*'))}
A user added the WHSProductVariantFixedLocation data source to the location directive query. However, the WHSProductVariantFixedLocation table contains records per each product variant. To achieve what was initially intended by the user (directive should be triggered for a specific fixed product variant location, which is tied with the correct product variant) we can modify the query in WhsLocationDirective.buildLocDirTableQuery() method using CoC and if the query contains WHSProductVariantFixedLocation datasource add additional range to it on ProductVariantInventDimId field.
Alternative solution, which will require less setup might be:
1. Modify Fixed locations Product variants (WHSProductVariantFixedLocation ) table to add an additional "Overspill" location fiel
2. Modify Location Directive Action table Fixed location usage field (WHSLocDirAction.UseInventFixedLocation, enum: WHSUseFixedLocations) to add additional enum value: Only fixed locations for product variant overspill
And use it as a second Sequence number:
3. Make code changes to apply additional changes to the Location Directive Action query.
- Modify WhsLocationDirective.isLocationDirectiveActionApplicable() to add additional enum value processing similar to WHSUseFixedLocations::ProductVariantFixed. The same method this.isProductApplicableForProductVariantFixedLocDirAction() might be used in our case to verify that product variant fixed location record exists for our product variant.
- Modify WhsLocationDirectiveActionQuery.addFixedInventLocationQueryRange() to add a data source and ranges in the same way as it is done for the WHSUseFixedLocations::ProductVariantFixed option, however, the location field should be different, the one, which we have created previously.
Location Directive Action query call stack:
WhsLocationDirective.loopLocDirLines()
WhsLocationDirective.isLocationDirectiveActionApplicable() !!
WhsLocationDirective.isProductApplicableForProductVariantFixedLocDirAction()
WhsLocationDirective.createActionQuery()
WhsLocationDirectiveActionQuery
WhsLocationDirectiveActionQuery.buildQueryRun()
WhsLocationDirectiveActionQuery.modifyPutLocDirActionQuery()
WhsLocationDirectiveActionQuery.addFixedInventLocationQueryRange() !!
Location Directive Action Query example (Only fixed locations for the product variant):
SELECT inventLocationId, LocProfileId, wMSLocationId
FROM WMSLocation(WMSLocation)
WHERE ((inventLocationId = N'10'))
EXISTS JOIN * FROM WHSProductVariantFixedLocation(WHSProductVariantFixedLocation_1)
WHERE WMSLocation.inventLocationId = WHSProductVariantFixedLocation.InventLocationId AND
WMSLocation.wMSLocationId = WHSProductVariantFixedLocation.WMSLocationId AND
((ItemId = N'VK075')) AND ((ProductVariantInventDimId = N'#000000015000061C'))}