Stock is a ledger.
Not a number you edit.
Warehouse, shop floor, the 3PL, the van — each a location, each variant counted per location, and every change a movement with a reason. The number is the sum of its history.
Ninety seconds of stock control.
- 1
Checkout reserves on a real shelf.
An order checks availability across the summed stock and reserves on the location that has it. What the site sells is what a shelf holds.
- 2
Move it with a transfer.
Draft, send, receive — partial receipts allowed, over-receipt refused. Each side writes its own movement: transfer out here, transfer in there.
- 3
Count it without stopping sales.
Opening a count snapshots the expected quantities; applying it compares against the current on-hand, so a sale during the count is never reverted.
Every unit has a paper trail.
Sale, return, damage, theft, correction, transfer, receipt, count — nine movement reasons, each a row with an actor and a reference. Nothing in the codebase updates the level on its own; the level is the sum of the movements.
Locations are first-class.
Warehouses, stores, 3PLs and vans, plus org-wide shelves every brand can draw on. Each store keeps exactly one default location, so a checkout can never be blocked by a missing one — and the courier manifest consumes from where the order reserved.
Low stock is a threshold, not a surprise.
Per variant, per location: a reorder point and quantity on the level row. A saved filter lists what crossed it — with no threshold set, low means out — and the dashboard panel watches it for you.
A stock column vs a stock ledger.
| The old way | Raizn | |
|---|---|---|
| One number | Per store. Locations are a paid app. | Per store, variant and location — shared warehouses included. |
| Transfers | Export, edit, re-import, hope. | Draft, send, receive — partials tracked, over-receipt refused. |
| History | The current number. That's all. | Every movement, with reason, actor and reference. |