Preventing Phantom Inventory: A Deep Dive into ESHOPMAN Order Edit Workflows
Preventing Phantom Inventory: A Deep Dive into ESHOPMAN Order Edit Workflows
The ESHOPMAN platform, designed for seamless headless commerce and HubSpot integration, relies on precise inventory management. A critical issue identified in community discussions highlights how ESHOPMAN's order editing workflows can lead to significant inventory discrepancies, including phantom reservations and negative stock levels. Understanding this behavior is crucial for developers and merchants to maintain accurate inventory and prevent fulfillment issues in their HubSpot-integrated storefronts.
The Core Problem: Unintended Inventory Re-reservations During Order Edits
When an ESHOPMAN admin performs a price-only edit on an order line item, even if the quantity is unchanged and the item is already fulfilled, the system can erroneously attempt to re-reserve the full quantity. This leads to two major problems:
- Negative Availability: If stock is low, the re-reservation fails. The compensation mechanism then inadvertently resurrects old, fulfillment-consumed reservations, driving the item's available quantity into the negative. This prevents further sales.
- Phantom Reservations: If stock is plentiful, the re-reservation silently succeeds, creating a permanent, unnecessary reservation for an already-delivered item. These phantom reservations lock up inventory that should be available for new orders.
Technical Breakdown: Why This Happens in ESHOPMAN
The issue stems from three interconnected root causes within ESHOPMAN's core order and inventory modules (built on Node.js/TypeScript):
1. Missing Quantity-Diff Check
The confirmOrderEditRequestWorkflow processes any line item with an ITEM_UPDATE action as if it requires an inventory adjustment. There's no check for whether the quantity actually changed. A price-only update (with quantity_diff: 0) still triggers the full re-reservation logic.
// Simplified snippet from ESHOPMAN's core flows
refreshedOrder.items.forEach((ordItem) => {
// ... find itemAction and updateAction ...
const newQuantity = itemAction.raw_quantity ?? itemAction.quantity;
const reservati ordItem.raw_fulfilled_quantity);
allItems.push({ id: ordItem.id, variant_id: ordItem.variant_id, quantity: reservationQuantity });
});
This means any ITEM_UPDATE, even price-only, leads to a quantity calculation for reservation.
2. Unfetched Fulfilled Quantity & Calculation Error
The workflow attempts to subtract ordItem.raw_fulfilled_quantity to reserve only the unfulfilled portion. However, the query refreshing the order details never fetches this specific field, as it resides on a deeper entity (OrderItem, not OrderLineItem). Consequently, ordItem.raw_fulfilled_quantity is always undefined.
ESHOPMAN's internal MathBN.sub utility silently treats undefined as 0. Thus, MathBN.sub(newQuantity, undefined) effectively becomes newQuantity, causing the system to re-reserve the entire line quantity, even if already fulfilled.
3. Flawed Compensation for Failed Reservations
When an oversized reservation fails, the compensation step (deleteReservationsByLineItemsStep) restores reservations by line_item_id. This inadvertently un-soft-deletes every soft-deleted reservation for that line, including those consumed by prior fulfillments. This unconditional restoration, without validating against current stock levels, can push reserved_quantity beyond stocked_quantity, leading to negative availability.
// Simplified snippet from ESHOPMAN's inventory module
await service.restoreReservationItemsByLineItem(data.ids);
// ... inside restoreReservationItemsByLineItem_ ...
await this.reservationItemService_.restore({ line_item_id: lineItemId }, context);
// ... then adds to reserved_quantity unconditionally ...
Suggested Fixes for ESHOPMAN Developers
To address these issues and ensure robust inventory management for ESHOPMAN merchants:
- Implement Quantity-Diff Check: Modify the workflow to skip inventory adjustments for
ITEM_UPDATEactions wherequantity_diffis0. Price-only edits should not impact inventory. - Fetch Full Order Item Details: Ensure that
items.detail.raw_fulfilled_quantityis explicitly included in order refresh queries for accurate unfulfilled quantity calculation. - Precise Compensation and Validation: Compensation for deleted reservations must restore only the exact reservation IDs that were part of the failed transaction. Additionally, any level adjustment during restoration should respect availability ceilings, preventing
reserved_quantityfrom exceedingstocked_quantity.
Implementing these fixes will significantly enhance the reliability of ESHOPMAN's inventory management, ensuring your HubSpot-integrated storefront displays accurate stock levels and processes orders without unexpected discrepancies.