Skip to content

Warehouses & Stock Management

Stoa supports multi-warehouse inventory management. Products can have stock distributed across multiple physical locations, and stock is automatically deducted when orders are created.

Key Concepts

Warehouses

A warehouse represents a physical storage location. Each warehouse has:

  • Name and Code — human-readable identifier and unique machine code
  • Priority — determines which warehouse stock is deducted from first (lower = higher priority)
  • Address — optional physical address fields
  • Active flag — inactive warehouses are excluded from stock calculations

Warehouse Stock

Stock is tracked per product (or product variant) per warehouse. The warehouse_stock table links a product to a warehouse with a quantity. A product can have stock in multiple warehouses simultaneously.

Denormalized Stock

The stock field on products and product_variants tables is kept as a denormalized aggregate. It always reflects the sum of all active warehouse stock entries. This means existing queries and cart validations continue to work without changes.

Stock Movements

Every stock change is recorded as a stock_movement entry with a type:

TypeDescription
saleStock deducted when an order is created
restockStock added back (e.g. new shipment received)
adjustmentManual stock correction via admin
returnStock restored when an order is cancelled or refunded

Stock Deduction

Stock is deducted at order creation time, not at payment confirmation. This prevents overselling for asynchronous payment methods.

Priority-Based Warehouse Selection

When an order is created, Stoa deducts stock from warehouses in priority order:

  1. All warehouse stock entries for the product are loaded, ordered by warehouse priority (ascending)
  2. Stock is deducted from the highest-priority warehouse first
  3. If that warehouse doesn't have enough, the remainder cascades to the next warehouse
  4. If total stock across all warehouses is insufficient, the order is cancelled

Example

Warehouse A (priority 0) has 3 units, Warehouse B (priority 1) has 10 units. An order for 5 units deducts 3 from A and 2 from B.

Row-Level Locking

The deduction process uses SELECT ... FOR UPDATE row-level locking within a single transaction. This prevents race conditions when multiple orders are placed simultaneously.

Stock Restoration

When an order transitions to cancelled or refunded, the stock is automatically restored to the original warehouses. Return movements are recorded for the audit trail.

Default Warehouse

When you first run the warehouse migration, a default warehouse (DEFAULT) is created automatically. All existing product stock values are migrated to this warehouse, ensuring backward compatibility.

Admin Panel

The admin panel includes warehouse management pages:

  • Warehouse list — view, create, edit, and delete warehouses
  • Warehouse detail — edit warehouse properties and view/edit stock entries
  • Product stock — the product detail page shows a stock breakdown per warehouse

Navigate to Warehouses in the admin sidebar to manage your inventory locations.

Plugin Hooks

Plugins can react to warehouse and stock events:

HookTimingCan cancel?
warehouse.before_createBefore warehouse creationYes
warehouse.after_createAfter warehouse creationNo
warehouse.before_updateBefore warehouse updateYes
warehouse.after_updateAfter warehouse updateNo
warehouse.before_deleteBefore warehouse deletionYes
warehouse.after_deleteAfter warehouse deletionNo
warehouse.before_stock_updateBefore manual stock changeYes
warehouse.after_stock_updateAfter manual stock changeNo
warehouse.after_stock_deductAfter order stock deductionNo

Next Steps

Released under the APACHE 2.0 License.