Core Concepts
Six ideas explain almost everything surprising about this module. Learn them once here and the twenty-two applet pages stop being a list of screens.
1. The balance is a running total, not a stored number you can edit
There is no screen anywhere in BigLedger where you type a stock balance. The balance is the tip of a signed stock ledger — one row per item per movement — that the server appends to when a document is finalised. The Stock Balance applet is the enquiry over that total and nothing more.
flowchart TD
F["Document set to FINAL"] --> P1["Generic-document primary processor<br/>fans out to its subscribed jobs"]
P1 --> P2["Inventory transaction line processor<br/>one signed ledger line per item line<br/>with a non-zero quantity signum"]
P2 --> P3["Ledger line → current stock balance processor<br/>upserts the location row and the company row,<br/>updates the cost bases, then serial / batch / bin"]
P3 --> B["Stock balance<br/>item × company × location"]
F -.->|"VOID"| V["Void processor<br/>writes a <b>negated copy</b> of every line<br/>— nothing is deleted"]
V --> B
Four consequences:
- If a number is wrong, the fix is a document, never the screen. Usually a Stock Adjustment.
- FINAL is not instant. The work happens in background processors. On a busy day the balance can lag the document by moments. A page that says “real time” is overstating it.
- VOID does not delete history. It writes a negated copy of every ledger line, marked as a void. The movement and its reversal both stay.
- A backdated document is inserted mid-chain and the balance is re-projected from there, which is why backdating is expensive and why the FIFO chain is rebuilt after one.
Where a movement lands
The location on a ledger line is the first of these that is set: the line’s delivery location, then the line’s store, then the header’s store, then the branch’s default location. Most “the stock went to the wrong place” cases are a line with no location falling through to a branch default nobody had looked at.
2. The quantity signum decides everything
Two numbers on a document type decide its effect: the quantity signum (does stock move, and which way) and the amount signum (does money move). A zero means nothing happens. They are fixed in the backend for each document type — not settings, not per tenant, and the applet’s own copy is overwritten by the server on every save.
| Moves stock in (+1) | Moves stock out (−1) | Moves nothing (0) |
|---|---|---|
| Purchase Invoice | Sales Invoice | Sales Order, Purchase Order, Quotation |
| Purchase GRN Stock In | Cash Bill | plain Purchase GRN, plain Sales GIN |
| Sales Return | Sales GIN Stock Out | Invoice No Stock In / No Stock Out |
| Sales Refund Note | Purchase Return | Credit Note, Debit Note |
| Transfer In | Purchase Refund Note | Stock Requisition |
| Consignment GRN | Transfer Out | Delivery Order, Goods Delivery Note |
| Consignment GIN | Packing Order, Jobsheet, Job Order |
Stock Adjustment takes its direction from the line (adjust-in or adjust-out). Stock Conversion takes it from the tab the line was entered on.
The same trap exists on the sales side: a plain Sales GIN and a plain Sales GRN are inert, and the document types that really issue and receive stock — GIN Stock Out, GRN Stock In — are different documents.
3. Balance and availability are different numbers, and availability can exceed balance
Balance is what the ledger says you physically hold.
Availability is what you can still promise. It is not balance minus reservations. It is the balance plus a signed adjustment for open documents:
flowchart LR
SB["Stock balance<br/>ledger quantity at this company and location"]
SO["Open sales orders<br/>not yet invoiced · signum −1"]
GRN["Goods received notes<br/>not yet invoiced · signum +1"]
ADJ["Adj Qty<br/>signed sum"]
AV["Available Qty<br/>balance + Adj Qty"]
SO --> ADJ
GRN --> ADJ
SB --> AV
ADJ --> AV
So “50 on the shelf, 0 available” means open sales orders, and “10 on the shelf, 35 available” means goods received and not yet invoiced. Both are correct. The Details screen in Stock Availability lists the documents behind the adjustment by type, so the difference is always traceable to specific documents rather than to a mystery.
Reservation is a third, separate thing. A reservation adds to the reserved column on the balance row, which the availability screens subtract. It moves no stock and posts nothing. It is opt-in — an action somebody takes in the Stock Reservation applet, or one that the Sales Order, Job Order and Packing Order applets take on a document’s behalf. There is no “hard” and “soft” allocation, and a plain FINAL sales order does not lock anything.
4. Counting measures the gap; adjusting closes it
These are two applets and two documents, and conflating them is the commonest misunderstanding in the module.
| Stock Take | Stock Adjustment | |
|---|---|---|
| What it is | A counting session for one location, with devices attached and records captured by scan or by hand | A document with lines, saved as a draft and finalised |
| What it produces | A report: counted against system, a tolerance band for movements during the count, missing and unexpected serials, and the cost of the difference | A ledger line per item and a journal |
| Effect on the balance | None. It never changes a balance | Changes it |
| Effect on the ledger | None | One signed line per item |
There is no “post the variance” button. Somebody reads the count report and raises an adjustment.
5. One document in this module posts a journal
Stock Adjustment. That is the list.
| Adjustment direction | Debit | Credit |
|---|---|---|
| Adjust-Out (quantity down) | Stock adjustment expense (STOCK_ADJUSTMENT, or the line’s own GL code) | Stock (STOCK_BALANCE) |
| Adjust-In (quantity up) | Stock (STOCK_BALANCE) | Stock adjustment (STOCK_ADJUSTMENT, or the line’s own GL code) |
A consignment GRN posts through the consignment handler — CONSIGNMENT_LIABILITY against
CONSIGNMENT_STOCK — because the stock is not yours until it sells. The consignment GIN that sends it
back does not: it has no consignment mapping of its own and posts through the ordinary purchase
mapping, so it reaches your ordinary supplier (CREDITOR) and purchase (PURCHASE) accounts. Check
those accounts, not the consignment ones, when a returned consignment does not seem to have left the
books.
Everything else in the module posts nothing. Stock transfers carry quantity only: value stays on the balance sheet wherever the goods physically are, and the company’s unit cost is untouched by construction — the transfer types are excluded from the moving-average calculation, so the transfer is a cost-neutral relieve. The per-location cost is a different number and it does not follow the goods: the location calculator seeds from the previous line at the receiving location, so a location that has never held the item seeds at zero and values the arrival at zero. Read the company figure for valuation; see Stock Transfer for the three cases. Stock conversions post no journal either. On 2026-10-01 they post no stock at all: nothing is connected to the conversion’s posting run, so a FINAL conversion leaves the balance where it was (§6).
The cost of goods sold on a sale is posted by the sales journal handler, from the sales document. No document in this module posts cost of sales.
6. Four cost bases are kept at once, and moving average is the one that bites
Every balance row carries moving-average, weighted-average, FIFO and LIFO amounts and prices, plus last purchase cost and landed cost. They are columns maintained side by side, not a costing mode you select. Each screen decides which one to show.
Moving average is what most screens use, and three things distort it or leave it short:
- A stock conversion moves no cost between items. Once its posting chain is connected (it is not, on 2026-10-01), the kit comes in at its own last price at that location — zero for a new item — and the components leave at their running average. Each item’s average holds; the kit never carries its components’ cost.
- A trade-in unit is not inventory stock at all. Trade-ins live in their own tables with their own cost, appear in Stock Availability because that screen unions the two, and never appear in the historical balance report.
- A backdated document re-projects the chain, which moves every average computed after it.
Reset Moving Average, in the Stock Adjustment applet, is the correction. It changes inventory value on the balance sheet and cost of sales on the income statement, so it belongs to finance and to nobody else.
7. Nothing in this module is approved
BigLedger’s document-approval engine covers three document types — Purchase Order, Purchase Requisition and Stock Requisition — is off until a tenant configures it, and causes FINAL rather than gating it. No transfer, adjustment, conversion or count consults it.
And the one inventory document the engine nominally covers is a dead end today: the Stock Requisition applet shows an Approval Settings screen but has no approval tab on the document, no request screen and no history screen, so a setting created there cannot be used from that applet.
Your control over who may write stock off, move it between branches or reset a cost is the permission set, and nothing else. Say so during implementation rather than after the first write-off nobody expected.