Inventory · advanced

Move stock, trace everything.

Two workflows that pay off as soon as you have more than one branch — branch-to-branch transfers (HQ → outlet, rebalancing between stores), and the per-SKU lifetime history feed.

Why transfers matter

Most multi-branch optical chains run a central warehouse where supplier deliveries land first. The warehouse then dispatches sub-batches to each retail outlet. The retail manager confirms the boxes arrived, with any short-shipment edits — and the stock + cost basis carry across cleanly.

Doing this manually (spreadsheet of who sent what to whom) is the #1 source of inventory-vs-system mismatch in the chains we've talked to. The dedicated transfer flow eliminates it.

Dispatching from the source

  1. Sidebar → Transfers, then + New transfer.
  2. Pick source branch (where the stock is right now) and destination branch. Cross-org transfers (e.g. parent brand → franchisee) aren't allowed here — they need the inter-org accounting flow.
  3. Optional but recommended: type a reason(“new outlet opening”, “rebalance after spring sale”, “customer request”) and an expected delivery date so the destination team knows when to expect the boxes.
  4. Search and add SKUs. Search is bound to the source branch — you can only dispatch what's actually in stock there. Each line caps at the source's on-hand quantity.
  5. Hit Dispatch →. The source's stock decrements immediately. The transfer enters in_transit status. You get a transfer number (TRF-2026-NNNNN) for tracking.
The transfer-line snapshot includes the source's per-unit weighted-average cost. This is what gets used when the destination confirms — so the cost basis stays stable even if the source's average drifts before the confirm-received click.

Confirming receipt at the destination

The destination branch sees the inbound transfer on their /inventory/transfers list with status in_transit. Open it, verify the line items match what physically arrived (quantity adjustments come in a future release; for now you receive as-dispatched), and click Confirm received →.

On confirm:

  • Destination's branch_inventory.quantity_on_hand increments by the line quantity.
  • Destination's weighted-average cost recomputes using the snapshotted cost from dispatch.
  • Two inventory_movements rows are written — one transfer_out at source (on dispatch), one transfer_in at destination (on confirm).
  • Status flips to received. Audit columns capture who confirmed and when.

Cancelling a transfer

If a transfer was created in error and hasn't been received yet, the source branch manager can cancel it. This restores the dispatched units back to the source's on-hand count and writes a reversal movement. Once a transfer is received, it's closed — handle corrections via a new transfer in the other direction.

If you have only one branch

/inventory/transfers/new shows a friendly empty-state instead of a broken dropdown: “One branch, no transfers needed. Once you add a second branch this flow becomes available.” The list page (/inventory/transfers) still works — it just stays empty.

Per-SKU history

The where did this product come from, where did it go view. Open any SKU's detail card and click History →. Three sections, top to bottom:

1 · Stock by branch

Current quantity at every branch that has (or has ever had) this SKU. Columns: on-hand, reserved, last movement timestamp. Sorted by qty desc.

2 · Cost over time

Every receipt's unit cost as a small card with the date and a percent-delta from the prior receipt. Anything more than +10% colours red (supplier price hike — review your selling price); -10% or worse colours green (better deal, margin opportunity).

3 · Lifetime feed

Every event that ever touched this SKU, across every branch, reverse-chronological:

IconEventReference
📦Received from supplierReceipt number (clickable later)
🛒Sold to customerOrder number — clicks through to the order page
Transferred outTransfer number
Transferred inTransfer number
Returned by customerReturn number
Manual adjustmentAudit note

Each row shows quantity delta (+5, -1), branch name, the counterparty (supplier, customer, source/destination branch), and the per-unit price at the time of the event.

Use this page when a customer asks “how long has this frame been here?” or when the auditor asks “walk me through this SKU's movements last quarter.”

Next up

Reports

The owner / accountant view of everything operations is feeding into the system.