Inventory Transfers
An inventory transfer moves stock from one location to another. Because inventory is always tracked per location, a transfer is how you record goods physically relocating, and it accounts for the time they spend in transit between the two.
Transfers are their own module, built to do one thing: move units between locations. One transfer carries a list of items, and each line picks its own target, a raw material on the materials ledger or a finished good on the finished-goods ledger, so a real shipment of several things is one document rather than one per item, even when it mixes the two. The document holds the where and when of the move, the lines hold the what and how much; the ledgers stay the source of truth for stock, because every transfer projects each line's movement into the matching ledger as it progresses.
What it does
- Track the move. At its core a transfer is a record of one relocation: the items and their quantities, the source and destination locations, and the dates it moved through each stage. That record stands on its own, with editable dates.
- Move inventory between locations. A transfer takes stock out of the source when it ships and puts it into the destination when it arrives, writing each line to whichever ledger its item belongs to: the materials ledger for a raw material, the finished-goods ledger for a product. A transfer that carries both writes to both. While it travels, the stock belongs to neither location's on-hand.
How it works
A transfer is always in exactly one status, and it steps forward through three of them as the goods travel: it is planned, then shipped, and finally received. Every move is manual, because a transfer has no receipts of its own; you advance it as each stage happens.
The statuses
| Status | What it means |
|---|---|
| Planning | Draft. You are preparing the move; nothing is committed and inventory is untouched. |
| In Transit | The goods have left the source. On-hand at the source drops now, and the stock is in transit, belonging to neither location. |
| Completed | The goods have arrived at the destination. On-hand there rises and the move is done. |
A richer lifecycle (cancellation, reversing a completed move) is a planned improvement on this same document model.
Moving between them
- Forward, stage by stage. Advance Planning to In Transit to Completed as the move progresses. You pick a source and destination location and one or more items with their quantities when you create it, and it opens in Planning under an auto-assigned code.
- Back, to fix a mistake. Step a transfer back and its inventory effect steps back with it: dropping out of In Transit removes the source entries, dropping out of Completed removes the destination entries. Every line moves together, so the record always reflects only what is true right now.
Effect on inventory
| What happens | Ledger effect |
|---|---|
| Reach In Transit | writes a CONSUME entry per line at the source; on-hand there drops |
| Reach Completed | writes a RECEIVE entry per line at the destination; on-hand there rises |
| Step back or delete | removes the matching entries; on-hand recomputes as if it never happened |
Every entry is an ordinary single-location movement: shipping consumes from the source,
arriving receives at the destination, so nothing in the ledger has to span two places.
Planning does not touch inventory: the stock only leaves the source once the transfer goes
In Transit. All of them carry the transfer's code as their reference (TFR-001,
TFR-002, and so on) and a source of "transfer", so a shipment's entries are easy to find
together and a consume is never mistaken for one from production. Within a transfer each
entry is told apart by its item, which is why one transfer may carry a given item only
once: to move more of it, raise that line's quantity. Transfers recorded before the module
existed keep their original TFR-MI-xxx (materials) and TFR-FG-xxx (finished goods)
series on both the document and its ledger entries.
What travels with the stock
A transfer moves more than units. Each line's arrival at the destination inherits exactly what that line drew at the source: each lot, its expiration, and its cost, layer by layer. Ship 100 units that came from two deliveries and the destination holds those same two batches, each still knowing its own expiration and cost, so FEFO and valuation at the new location behave as if the goods had always been there. Lines are independent here: each one traces its own item's history, so a mixed shipment is simply several such traces under one code. In the ledger view, a move that spans several lots shows as one line per lot at both ends; see Lots & Expirations for how that split works.
None of it is frozen on the transfer. Cost, lot, and expiration are all derived on read from the source history, valued as of the moment the goods left, so they stay correct even when earlier history is corrected, and later activity at the source can never reach back into a move that already departed. The items and the locations can be changed freely while the transfer is still in Planning, because nothing has moved yet; once it goes In Transit they are locked, so to correct them step the transfer back to Planning, or delete it and create the correct one.
Dates
Every status stamps its own date as the transfer reaches it, and each stays editable afterwards so you can correct it: a planning, in-transit, and completed date.
The ledger entries take their business date from the matching status: the CONSUMEs from the in-transit date, the RECEIVEs from the completed date. Editing a date moves every entry it dates with it, so the stock history always reads in true business-date order, which is what positions and the cost model sort by. The record-of-entry timestamp never moves.
See also
Create, advance, update, and delete transfers through the REST API or the MCP server.