Skip to main content

Order lifecycle

Every order carries an OrderState (a string on OrderBase) that moves through an allocate leg (pick and dispatch) and/or a receive leg (scan in at the destination), depending on the order's type. Two further fields ride alongside the state:

  • OrderStatus (Ready / Processing / Errored) is a processing overlay, not part of the state machine. Processing is UI metadata only — the real mutex is a per-order SQL app lock. Errored means the order has unresolved error tags: it blocks Dispatch and Complete, but not the operations that can resolve the errors (AddSnapshot, AppendTags, Allocate, Receive, Cancel, manual fulfilment).
  • OrderType (Inbound, Replenishment, Outbound, Transfer, Return, Loan) selects which legs of the state machine the order uses.

Every transition writes an OrderTransactionHistory row — the audit trail behind GET api/orders/getordertransactions.

States and transitions

Completed and Cancelled are terminal. Cancel is allowed from every non-terminal state.

Allowed operations per state

StateAddSnapshotAppendTagsAllocateDispatchReceiveCompleteCancelRevert
Open✔ auto → Allocating (or Receiving for receive-only types)✔ same
Allocating✔ gate✖ (remove-snapshot ✔)
Allocated✔ → Dispatched→ Allocating
Dispatched✔ auto → Receiving✔ auto → Receiving✔ Outbound only → Completed
Receiving✔ gate✖ (remove-snapshot ✔)
Received✔ → Completed→ Receiving
Completed / Cancelledterminal — everything ✖

Reverts are explicit endpoints: reverttoallocating and reverttoreceiving. Removing a snapshot (allowed only in Allocating/Receiving) reverts each scanned item to the OldItemState/OldPlaceId captured at scan time.

The six order types

OrderTypeFlow
Inbound, Replenishment, ReturnOpen → Receiving → Received → Completed — receive leg only, no allocate/dispatch.
OutboundOpen → Allocating → Allocated → Dispatched → Completed — allocate leg only, no receive.
TransferFull chain: Open → Allocating → Allocated → Dispatched → Receiving → Received → Completed.
LoanFull chain, with the loan variants of the item states (Reserved/OnLoan/Returned) and reversed place moves.

Stage gates: Allocate and Receive

Allocate and Receive only succeed when:

  1. The order has at least one snapshot.
  2. Error tags are re-evaluated first — items that now pass are promoted.
  3. Every order line's quantity constraint is met (OrderQtyActionType: Exact ±0.01, OverOnly, UnderOnly, or All — measured in outer-SKU units), and no error tags remain.

A failed gate logs an AllocateFailed/ReceiveFailed transaction and leaves the state unchanged. On a successful Receive, allocated-but-unreceived items are swept to Missing.

200 despite failure

Dispatch, Receive and Complete return HTTP 200 even when the transition fails. Diff the returned OrderState against what you expected and inspect the order's error collections — see Errors & response conventions.

Item-state cascades

Order operations drive the order-owned item states — the other half of the Item lifecycle transition matrix:

Order operationStandard ordersLoan ordersReturn orders
Allocating scanAllocatedReserved
DispatchDispatchedOnLoan
Receiving scanReceivedReturnedRestored — the only exit from Consumed

Place moves ride along: an allocating scan moves the item to the order's FromPlace; dispatch moves items only for Loan orders (to the ToPlace); a receiving scan moves the item to the ToPlace (Loan: back to the FromPlace).

Cancel reverts items depending on where the order was: from Allocating/Allocated, items go back to Present; from Dispatched, to Missing; from Receiving/Received, received items go to Present and un-received items to Missing.

Asynchronous processing

AppendTags, AddSnapshot, Allocate, Dispatch, Receive and Complete accept NotifyOnceComplete plus a NotificationRecipientId. The recipient id must equal the caller's own user id — otherwise the request silently runs synchronously. The async response returns OrderOperationResultDto.BackgroundTaskId and auto-creates auto-delete event subscriptions for the completion callback. See Async operations for the full pattern.

AutoReceiptOrder (Transfer and Loan orders): dispatch automatically runs the entire receive leg in one go.