Skip to main content

Movement types & fields reference

Every change to your owned stock is written to the inventory movement ledger as an inventory movement — a single, immutable + or line stamped with a type, a status, a source document, and (for stocked changes) a FIFO layer. This page is the field-level lookup for that record: the full type taxonomy, the two inventory statuses, the source link, and every field and list column, plus the three invariants that decide which movements can exist at all.

For how movements behave as an audit trail, read the concept The inventory movement ledger. To view and filter them in the app, see View & filter the inventory movement ledger. For how movements feed cost, see FIFO layers & how COGS is realized.

Movement type taxonomy

The Type records which part of the app created the movement and what it means. Each type is emitted by exactly one part of the app, so the type tells you where a stock change came from without opening the source document. The table below lists every type SKU.io writes as it appears in the Type column and filter, its typical sign, the part of the app that emits it, and its effect on FIFO layers.

TypeSignEmitted byFIFO effect
Inbound Receipt+Receiving an inbound shipmentCreates a new FIFO layer at the received cost
SaleShipping a sales order fulfillmentConsumes FIFO layers oldest-first; realizes COGS
Adjustment±An inventory adjustmentIncreases create a layer; decreases consume oldest-first
Stock Take±Finalizing a stock takeReconciliation delta; same layer behavior as an adjustment
Transfer±A warehouse transferUses paired in-transit and active movements; carries cost between warehouses
Reclassification±A location transfer within one warehousePaired active movements that move a layer between bins
Return+Receiving an RMAReturns stock to a layer
Purchase ReturnA vendor credit shipping stock back to a supplierConsumes layers
Manufacturing ConsumptionA manufacturing order consuming componentsConsumes component layers
Manufacturing Output+A manufacturing order producing finished goodsCreates a finished-good layer at rolled-up cost
Manufacturing ScrapA manufacturing order scrapping materialConsumes layers
Assembly±The legacy assembly flowLegacy; superseded by the manufacturing types
Assembly is legacy

The Assembly type is kept for historical rows only. New builds record the manufacturing consumption, output, and scrap types instead. Legacy assembly movements are grouped with manufacturing in the Source filter so they're not stranded, but their Source still opens the assembly rather than a manufacturing order that never existed.

Reclassification never crosses a warehouse

A Reclassification movement is emitted only by a location transfer — moving stock between bins inside one warehouse. A move between warehouses is a Transfer and uses the In Transit / Active status pair described below. See Move stock between bins (location transfers) and How warehouse transfers work.

Inventory status: Active vs In Transit

The inventory status has exactly two values. It's separate from the movement type: type says what happened, status says whether the stock is available to work with right now.

StatusChip colorWhat it means
ActiveGreen (success)Physically on hand in a warehouse. Counts toward availability and feeds the per-location on-hand figures.
In TransitBlue (info)Owned but on a warehouse-to-warehouse transfer. Counted in your owned totals and valuation, but not available to allocate or ship.

Both statuses are included in inventory valuation, because in-transit stock is still owned. The difference is availability: only active movements that carry a location contribute to the per-location figures, and only active stock feeds the in-warehouse availability figure. In-transit movements are excluded from availability but included in the owned total. This is the ledger-level version of the In Transit stock state.

There is no "reserved" status

Only Active and In Transit exist. There is no "Reserved" inventory status anywhere in the product. Allocation and holds are tracked separately from movement status — allocated stock and on-hold stock are their own states (the product list column for held stock is labelled On Hold, not "Reserved"). See Allocations & backorders and Place & manage stock holds.

Every movement is linked back to the exact document line that created it — a sales order line, an inbound shipment receipt line, a warehouse transfer shipment line, a stock-take item, an inventory adjustment, a return receipt line, a vendor credit line, a manufacturing output or component line, and more.

The Source column turns that link into a clickable reference to the document you'd actually want to open. Movements from a fulfillment or an inbound receipt link to that fulfillment or receipt; everything else links to the top-level document — the sales order behind a sales order line, the purchase order behind an inbound receipt line, the transfer behind a transfer shipment line, the stock take behind a stock-take item, the manufacturing order behind a component line.

Two behaviors are worth knowing:

  • The reference is captured at save time. Each movement stores a copy of its source document's reference (a PO or SO number, for example) rather than looking it up on every read. That's what keeps the ledger fast on large histories.
  • A movement outlives a broken link. If a movement's source can no longer be resolved, the movement, its type, and its stored reference still display — only the clickable link is dropped. Nothing disappears from the ledger.

What a movement records

Each movement in the ledger carries:

FieldWhat it holds
DateThe effective date and time of the stock change. This is what valuation uses — not when the row happened to be created.
ProductThe stocked product the movement is for.
QuantitySigned — positive adds stock, negative removes it.
TypeOne of the movement types.
StatusActive or In Transit.
WarehouseThe warehouse the change occurred in.
LocationThe bin within that warehouse.
FIFO layerThe layer this movement created or consumed, when it touches one. See FIFO layer fields, statuses & enums.
SourceThe document line that created the movement — see The Source link.
ReferenceThe source document's reference, such as a PO or SO number.
Batch number / Expiry dateLot and expiry, when the inbound was received against a batch.

Movements also carry a per-unit cost used for valuation. It isn't shown in the ledger — for cost and COGS, work from FIFO layers instead.

Movements list columns

The movement ledger list shows these columns. Some are sortable, some link elsewhere, and a few exist only in the export.

ColumnSortableNotes
IDYesThe movement's ID.
DateYesThe movement date, in your local timezone.
SKUYesThe product SKU.
Product NameYesThe product name.
TypeYesThe type label.
StatusYesActive (green) or In Transit (blue).
QuantityYesRight-aligned and colored by sign — green for positive, red for negative.
WarehouseNoThe warehouse name.
LocationNoThe bin within the warehouse.
LayerNoA purple FIFO Layer #N chip linking to that layer; empty when the movement has no layer. See Browse & manage FIFO layers.
SourceNoA link to the document that created the movement.
CreatedYesWhen the row was created.
UpdatedYesWhen the row was last updated.

The CSV/XLSX export adds a FIFO Layer ID column and expands Source into the source document's type and ID, so a spreadsheet keeps enough detail to trace any row back to its origin.

Guardrails: Which movements can exist

Three invariants are enforced whenever a movement is saved. They can't be worked around through the normal event-firing save path, and understanding them explains several "why can't I…" cases.

Bundle and matrix products carry no movements

A movement can only be recorded against a stockable product — a simple product or a variant. Saving a movement against a bundle or a matrix parent is rejected, because those are non-stocked abstractions rather than physical stock.

  • Selling a bundle expands to movements on its component products, never a single bundle movement.
  • A matrix parent never appears in the ledger; only its variants do.

Supplier warehouses carry no movements

A supplier (dropship/vendor) warehouse isn't an owned stock location, so no movement may post to it — the save is rejected. This guards against accidentally receiving or allocating owned stock into a supplier location.

Cross-product FIFO contamination is blocked

A movement can never point at a FIFO layer that belongs to a different product. If the layer's product doesn't match the movement's, the save is rejected — this is what keeps each product's costing correct.

High-volume paths check the same rule a different way

The cross-product check and the automatic cost snapshot run whenever a movement is written one at a time. High-volume bulk paths skip that per-row work for speed and instead set the unit cost and validate layer ownership up front, so the same rule holds either way — a movement can never end up on another product's FIFO layer.

These aren't movement guardrails, but they affect what you see in the ledger:

  • On Hand reconciles from the parts. On Hand = Available + Allocated + On Hold + Non-Sellable, which equals your owned total minus In Transit. Non-Sellable bin stock is a first-class column, not a hidden bucket. See Stock states & fields reference.
  • Empty FIFO layers can be archived. A fully consumed (zero-remaining) layer is archivable — its consuming movements stay in the ledger. See Browse & manage FIFO layers.
  • Channel-managed transfers are received by the channel. Manually receiving a transfer whose destination is an Amazon FBA/AWD/WFS-managed warehouse is rejected with a clear message and isn't offered in the UI — those movements are written when the channel confirms receipt. See Receive a transfer.

Next steps

Last verified: