Skip to main content

Commit Movement

POST 

/api/v2/inventory/movements/composer

Atomic commit of a composed movement: creates inventory adjustments, persists lot/serial detail, and triggers allocation release or demotion — all inside one DB transaction. When an outbound demotion consumes hard-allocated stock, each confirmed shipping label is voided in the same transaction (the fulfillment's inventory is reversed back to on-hand, its FulfillmentOrder budget reopened, and the shipment marked canceled).

Named route: v2.inventory.movements.composer

Request fields:

  • direction (required) — one of: receive, ship, adjust_up, adjust_down
  • warehouse_id (required) — must exist in warehouses
  • movement_date (required) — ISO date
  • against_type (optional) — purchase_order, transfer, or none
  • against_id (optional) — ID of the source doc when against_type is set
  • reason (optional, max 1000 chars)
  • lines[] (required, min 1):
    • product_id (required)
    • quantity (required, non-zero — positive for inbound, negative for outbound)
    • unit_cost (optional, >= 0)
    • serials[] (optional, each max 100 chars)
    • lot (optional): lot_number, expires_at, manufactured_at
    • override_reason (optional, max 500 chars)
  • void_confirmations[] (required when preview-demotion returned requires_void_confirmation=true):
    • fulfillment_id (required)
    • attempt_void (required bool)
    • reason (optional, max 500 chars)

Response shape (200):

{
"data": {
"adjustment_ids": [101, 102],
"voided_fulfillment_ids": [9001],
"skipped_fulfillments": []
},
"message": "Receipt committed — 1 line(s)."
}

voided_fulfillment_ids lists the fulfillments whose labels were voided. skipped_fulfillments lists any confirmed fulfillment that could not be voided (already voided, or part of a multi-shipment merge group) as { fulfillment_id, kind, reason } — these are skipped, not fatal.

Error (422): Returned when hard-allocated fulfillments are missing from void_confirmations or any other \InvalidArgumentException is thrown by the manager.

{ "error": "Hard-allocated fulfillment #9001 requires an explicit void confirmation before committing." }

release_backorders (boolean, inbound only, default true): when true, the received stock is applied to any waiting back-orders (promoting them to allocated); when false, the stock is received as free inventory and the back-orders keep waiting.

release_sales_order_ids (array of ints, inbound only, optional): granular release. Omit or null to release ALL waiting back-orders; pass a list of sales order ids to release only those orders' back-orders. Requires release_backorders = true.

Request

Responses

Successful response