Extension Point: Inventory Flow
Basics
Parameter | Value |
---|---|
Extension Point Key | INVENTORY_FLOW |
Extension Point Name | Inventory Flow |
Extension Interface | InventoryFlow |
Supports Multiple Extensions? | No |
Selector Type | Store |
Available Since | 1.1.0 |
note
This extension point only supports a single extension, so if multiple are defined, the highest priority extension will be invoked.
Use Cases
Extensions implementing this Extension Point should track physical inventory for all product SKUs present in one or more warehouses.
There is an embedded extension named ElasticPathJournalingInventoryFlow
with priority 1050 that uses the Elastic Path database to track inventory.
note
This Extension Point supports inventory operations that happen as a result of shopper transactions. Administrative operations such as stock replenishment are not supported and should be addressed within the service that tracks inventory. Additionally, Commerce Manager administrative operations such as inventory adjustments and stock replenishment will only have an effect if the ElasticPathJournalingInventoryFlow
extension is in use.
Methods
getInventory
The getInventory
method is invoked whenever an Elastic Path service needs to determine inventory for a particular product SKU in a warehouse. The extension needs to return the following values in the XPFInventory
response object:
onHandQuantity
: The number of items currently in the warehouse.reservedQuantity
: The number of items being held back for sale in other channels or to prevent overselling.allocatedQuantity
: The number of items in the warehouse that have been purchased and are awaiting shipment.availableQuantity
: The number of items available for purchase.expectedRestockDate
: The next expected restock date.expectedRestockQuantity
: The number of items expected in the next restock.
getInventories
The getInventories
method is invoked whenever an Elastic Path service needs to determine inventory for a several product SKUs.
allocateInventory
The allocateInventory
method is invoked when a cart is purchased and indicates that the specified product SKU should be held for shipping to a customer.
deallocateInventory
The deallocateInventory
method is invoked when a purchase is cancelled and indicates that hte specified product SKU no longer needs to be held for shipping to a customer.
releaseInventory
The releaseInventory
method is invoked when the specified product SKU has been shipped to the customer, meaning the on hand quantity and allocated quantity should be decremented.
Extension Sample
@Extension
@XPFAssignment(extensionPoint = XPFExtensionPointEnum.INVENTORY_FLOW, priority = 10)
public class InMemoryInventoryFlow extends XPFExtensionPointImpl implements InventoryFlow {
private static final int DEFAULT_STARTING_INVENTORY = 10;
private final Map<String, XPFInventory> skuCodeToXPFInventoryMap = new ConcurrentHashMap<>();
@Override
public XPFInventory getInventory(final XPFInventoryKeyContext inventoryKeyContext) {
if (!skuCodeToXPFInventoryMap.containsKey(inventoryKeyContext.getProductSku().getCode())) {
XPFInventory xpfInventory = new XPFInventory(DEFAULT_STARTING_INVENTORY,
0,
0,
DEFAULT_STARTING_INVENTORY,
null,
0);
skuCodeToXPFInventoryMap.put(inventoryKeyContext.getProductSku().getCode(), xpfInventory);
}
return skuCodeToXPFInventoryMap.get(inventoryKeyContext.getProductSku().getCode());
}
@Override
public Map<XPFInventoryKeyContext, XPFInventory> getInventories(final Set<XPFInventoryKeyContext> inventoryKeyContexts) {
Map<XPFInventoryKeyContext, XPFInventory> map = new ConcurrentHashMap<>();
inventoryKeyContexts.forEach(context ->
map.put(context, getInventory(context)));
return map;
}
@Override
public XPFInventoryExecutionResult allocateInventory(final XPFUpdateSingleQuantityInventoryContext updateInventoryContext) {
XPFProductSku productSku = updateInventoryContext.getInventoryKey().getProductSku();
int quantity = updateInventoryContext.getQuantity();
XPFInventory xpfInventory = getInventory(updateInventoryContext.getInventoryKey());
XPFInventory updatedXpfInventory = new XPFInventory(
xpfInventory.getOnHandQuantity(),
xpfInventory.getReservedQuantity(),
xpfInventory.getAllocatedQuantity() + quantity,
xpfInventory.getAvailableQuantity() - quantity,
null,
0
);
skuCodeToXPFInventoryMap.put(productSku.getCode(), updatedXpfInventory);
return new XPFInventoryExecutionResult(updatedXpfInventory, quantity);
}
@Override
public XPFInventoryExecutionResult deallocateInventory(final XPFUpdateSingleQuantityInventoryContext updateInventoryContext) {
XPFProductSku productSku = updateInventoryContext.getInventoryKey().getProductSku();
int quantity = updateInventoryContext.getQuantity();
XPFInventory xpfInventory = getInventory(updateInventoryContext.getInventoryKey());
XPFInventory updatedXpfInventory = new XPFInventory(
xpfInventory.getOnHandQuantity(),
xpfInventory.getReservedQuantity(),
xpfInventory.getAllocatedQuantity() - quantity,
xpfInventory.getAvailableQuantity() + quantity,
null,
0
);
skuCodeToXPFInventoryMap.put(productSku.getCode(), updatedXpfInventory);
return new XPFInventoryExecutionResult(updatedXpfInventory, quantity);
}
@Override
public XPFInventoryExecutionResult releaseInventory(final XPFUpdateSingleQuantityInventoryContext updateInventoryContext) {
XPFProductSku productSku = updateInventoryContext.getInventoryKey().getProductSku();
int quantity = updateInventoryContext.getQuantity();
XPFInventory xpfInventory = skuCodeToXPFInventoryMap.get(productSku.getCode());
XPFInventory updatedXpfInventory = new XPFInventory(
xpfInventory.getOnHandQuantity() - quantity,
xpfInventory.getReservedQuantity(),
xpfInventory.getAllocatedQuantity() - quantity,
xpfInventory.getAvailableQuantity() - quantity,
null,
0
);
skuCodeToXPFInventoryMap.put(productSku.getCode(), updatedXpfInventory);
return new XPFInventoryExecutionResult(updatedXpfInventory, quantity);
}
}