How stock is counted
Read this before trusting any stock number in Orbit.
Orbit Inventory holds two independent stock figures that are never reconciled. Almost every confusing thing about the module follows from that one fact.
1. The two numbers
| The ledger | current_stock | |
|---|---|---|
| What it is | An append-only journal of movements | A single number stored on the row |
| Lives on | organization_inventory_transactions | The variation, and the raw material |
| Balance is | SUM(quantity) — computed | Read directly |
| Shown on | Inventory Ledger | Catalogue Stock column · Raw Materials Stock Status · storefront "Sold out" · Cockpit tiles |
| History | Complete | None — no record of who changed it or when |
Both claim to answer "how much do we have". They are computed from disjoint sets of events.
2. Who writes which
| Writer | Ledger | current_stock |
|---|---|---|
| Goods receipt | ✅ | ❌ |
| Production completion | ✅ | ❌ |
| Direct sale | ✅ | ❌ |
| Adjustment / wastage | ✅ | ❌ |
| Product editor Stock field | ❌ | ✅ |
| CSV import | ❌ | ✅ |
| Raw material edit | ❌ | ✅ |
| Storefront order placed | ❌ | ✅ decrement |
| Storefront cancel / refund | ❌ | ✅ restock |
No writer appears in both columns. That is the whole problem.
3. What this means in practice
A goods receipt does not raise the stock figure
You receive 60 KG of rice. The ledger gains a PURCHASE row for +60. The Raw Materials screen still
reads whatever it read before — usually 0, usually flagged LOW STOCK.
A completed production run does not consume anything visible
Six CONSUMPTION_OUT rows appear in the ledger. Every material's Stock Status is unchanged.
A storefront sale is invisible to the ledger
The variation's current_stock drops by 2. The ledger gains nothing. A stock-take reconciled
against the ledger will be short by every storefront sale ever made.
An adjustment does not adjust the number you were looking at
The screen exists to "keep system stock honest with what's on the shelf". It writes a ledger row. The system stock on the catalogue is untouched.
The Cockpit values the wrong number
Stock-value and low-stock tiles are computed from current_stock × price. A tenant recording
everything correctly through Inventory operations shows a stock value of zero.
4. Which number does what
| If you care about | Use | Because |
|---|---|---|
| Whether the storefront will sell it | current_stock | It drives the "Sold out" gate |
| What physically moved, and when | The ledger | It is the only audit trail |
| Cost and valuation | The ledger | unit_cost is captured per movement |
| Cockpit and low-stock alerts | current_stock | That is what they read |
| Explaining a discrepancy to an auditor | The ledger | current_stock has no history |
5. How to work with it
Pick one as authoritative and keep the other deliberately in step. Three workable postures:
A · Ledger-authoritative
Record everything through the operations screens. Accept that the Stock column, the "Sold out" gate
and the Cockpit tiles are decorative, and periodically set current_stock by hand from the ledger
balance.
- Good for: manufacturers who need cost and audit
- Cost: the storefront cannot be trusted to stop selling what you do not have
B · current_stock-authoritative
Maintain the stock field by hand or via import. Use the ledger only as a cost record.
- Good for: storefront-first sellers
- Cost: no audit trail for anything but purchases
C · Both, reconciled on a schedule
Operate normally, and on a fixed cadence compare the ledger balance to current_stock, then correct
current_stock in the editor.
- Good for: anyone who needs both
- Cost: a recurring manual job, and it is genuinely manual — nothing in the product assists
Nothing in the current code path bridges them. The gap is structural, not a missing job. Design your process around it.
6. Reconciling by hand
For one variation:
- Filter the ledger to that SKU
- Sum the Movement column — signs included
- Add every storefront sale, which is not in the ledger, from Storefront orders
- Compare to the Stock field in the editor
- Correct the editor field
Step 3 is what makes this hard: the storefront's contribution has to be gathered from a different module entirely.
The ledger's Export Data button does nothing — no handler, no endpoint. Bulk reconciliation means
the external API with inventory:stock:read, or direct database access.
7. Quick answers
| Question | Answer |
|---|---|
| I received stock and nothing changed | Correct. Receipts write the ledger only |
| Storefront says "Sold out" but the ledger is positive | The gate reads current_stock |
| Cockpit stock value is ₹0 | It reads current_stock, which operations never write |
| Every raw material says LOW STOCK | current_stock is 0 and reorder_level is above it |
| The ledger balance is negative | Nothing blocks over-consumption; it surfaces rather than hides |
| Which is "right"? | Neither. They measure different event sets |