Skip to main content

Item lifecycle

Every item carries a State (a string on ItemMaster) that says where the item is in its physical life: sitting in stock, moving through an order, out on loan, consumed, or unaccounted for. The state controls which operations are allowed — whether the item can be counted in a stocktake, scanned onto an order, or deleted.

Transitions are enforced by a state machine: a disallowed transition is simply not applied, and the calling operation surfaces its own error. Every successful transition appends an ItemStateHistory row (state, tag, source type, agent, reason, comments, timestamp) — the audit trail behind GET api/items/getitemstatehistory.

States and transitions

Think of the states in two groups: the free pool (states where the item is available to stock operations) and the order-owned states (the item is in flight on an order and locked to that workflow).

The diagram shows the typical flows; the table below is the authoritative transition matrix:

FromAllowed transitions to
Present, Missing, Moved, RestoredEverything except Dispatched, OnLoan, Restored
ClearedEverything except Dispatched, OnLoan, Restored — and cannot re-enter Cleared
AllocatedDispatched, Present only
ReservedOnLoan, Present only
DispatchedReceived, Missing only
OnLoanReturned, Missing only
Received, ReturnedEverything except Restored
ConsumedRestored only

Two rules fall out of the matrix: Dispatched and OnLoan are only reachable through an order's dispatch step (never directly), and Restored is only reachable from Consumed — it is the single exit from the consumed state.

What sets each state

StateSet by
PresentItem creation; stocktake/cycle-count confirmation at the expected place; order cancel/revert cascades. See Stocktakes.
MovedEvery physical movement: moveitems, updateitemplaceexternal, updategeocoordinates, portal reads, and cycle-count relocations.
MissingStocktake "missing sweep" — expected but not scanned (see Stocktakes); also order cancel cascades on dispatched items.
Clearedclearselecteditemstate (recorded with SourceType.CycleCount).
Consumedconsumeitems, plus order flows that consume items.
Restoredrestoreitems, or a Return order's receiving scan — see Order lifecycle.
Allocated / Reserved / Dispatched / OnLoan / Received / ReturnedOrder workflow cascades — allocating scans, dispatch, and receiving scans. The full mapping (including the Loan variants) is on the Order lifecycle page.

Snapshot eligibility

Whether an item is counted when a scan snapshot is resolved depends on its state. For inventory and cycle-count Add snapshots:

States
CountedPresent, Moved, Missing, Cleared, Received, Returned, Restored
ExcludedAllocated, Reserved, Consumed, Dispatched, OnLoan

Excluded items are not silently dropped — they surface in the snapshot result's Notifications list, which is why in-flight order items appear as notifications in a stocktake instead of being counted (see Stocktakes).

The order-owned states still allow order-phase snapshots: Allocated and Reserved allow an order Remove snapshot; Dispatched and OnLoan allow an order-receive Add or any Remove; Consumed allows an order-receive Add (the return-order restore path) or an order Remove.

Deletion gates

DeletableNot deletable
Present, Missing, Moved, Cleared, Consumed, Received, ReturnedAllocated, Reserved, Dispatched, OnLoan — the item is on an active order. Restored — see below.
Restored is not deletable

An item in Restored cannot be deleted, even though the neighbouring free-pool states can. This is a known quirk (owner review pending). Workaround: transition the item to any deletable state (e.g. a place move → Moved) first.

Interaction with the SKU lifecycle

Item creation is gated by the item's SKU: when the SKU's lifecycle state is non-operational (Draft or Discontinued), single item create returns 400, bulk create fails per row, and auto-create on tag scan is silently skipped. See the SKU operational lock.

Retail vs Asset

ItemMaster.UnitCost — per-item cost — is asset-management-only. Asset tenants track cost and depreciation on each individual item. Retail tenants do not populate it: retail pricing (UnitCost, RetailPrice, SalePrice) lives on the SKU — see SKU lifecycle.

  • Order lifecycle — the order-side state machine that drives Allocated/Reserved/Dispatched/OnLoan/Received/Returned, and its cancel/revert cascades back into the free pool.
  • Stocktakes — the Missing/Present sweeps and how snapshot resolution touches item states.
  • Errors & response conventions — some workflow operations return 200 despite a failed transition; check the body, not just the status code.