🧾 Supplier invoice — booking only what the supplier billed differently
Updated
A supplier invoice is the supplier's paper, entered as a document of its own. It exists because the receipt and the invoice are two different events: goods arrive at the price the order carried, and the invoice arrives later, sometimes with a different price.
Why it does not book the whole invoice#
The receipt already recognised the debt. When a PurchaseOrder moves to Received, GoodsReceiptPayableTx adds the net line amounts to Payable, and the purchase tax seam adds the input VAT on top. By the time the supplier's paper arrives, the supplier is already owed the ordered amount.
So the supplier invoice posts only the difference between what the supplier billed and what the receipts already accrued. Booking the invoice in full would make the business owe the same money twice.
| What happened | What Payable holds |
|---|---|
| Receipt of 4 bolts at 25, VAT 15% | 115.00 |
| Supplier invoices the same 4 at 25 | 115.00 — the invoice posts nothing |
| Supplier invoices 4 at 30 | 138.00 — the invoice posts the 20 difference plus 3 VAT |
| Supplier invoices 4 at 20 | 92.00 — the invoice reverses 20 plus 3 VAT |
How the process works#
Open Purchasing → Documents → Supplier invoices. The document is SupplierInvoice.
The usual path starts on a received order. Enter supplier invoice on a PurchaseOrder in Received creates a draft supplier invoice, copies supplier, date, payment term, due date and the order lines that are not invoiced yet, and links the two documents. The link is a document-family edge, not a field: one invoice can cover several receipts.
On the draft, type the supplier's own number into Supplier's number and correct the prices to what the paper says. Then press Register.
Register is the only way out of Draft. It asks the matching service for the accrued and invoiced totals, stamps Matched amount and Difference into the header so the number is visible before it is posted, and only then moves the document to Registered.
An invoice can also be entered standalone, with no order behind it — a service or an expense nobody received into a store. Then nothing was accrued, the difference equals the whole invoice, and the whole invoice becomes debt.
Settings#
| Required setup | Why it matters |
|---|---|
PurchasingSettings.InvoiceMatchTolerance |
The largest difference Register will accept. Zero means no limit — any difference registers |
| Default tax code with a rate effective on the invoice date | Without it Applied tax rate stays zero and the difference is booked net of VAT |
| Buying legal entity | Taken from the order's receiving cell, otherwise from the order header. The GL entry needs it to find the fiscal period |
AccountingSettings.PurchasePriceVarianceAccount |
The profit-and-loss leaf the difference is booked to. Empty means the ledger leg is skipped; Payable still moves |
Supplier's number is deliberately not a required field on the card. A draft is created from the order before the supplier's paper exists. The requirement is enforced by Register, which is the only door into the posted state.
Boundaries and edge cases#
- Selecting the subtype on the card is not the user path; after the first save it is frozen.
- Register refuses: no supplier, a blank supplier number, no lines, a line with quantity at or below zero, a supplier that disagrees with the linked order, and a difference beyond the tolerance.
- A difference beyond the tolerance leaves the invoice in
Draftand posts nothing. RaisingInvoiceMatchToleranceand pressing Register again lets it through. - The difference does not correct the cost of stock already received. A price correction that must reach inventory valuation is a
StockAdjustment, not this document. - Only orders in
Receivedcount towards the accrued amount. A linked order still inOrderedaccrued nothing yet. - A receipt can be invoiced in parts, but not twice. Each invoice line is matched against the receipt price of the same quantity, so an invoice for 3 of 4 received units is matched at the price of 3 and the fourth stays accrued for the next invoice. Enter supplier invoice drafts exactly what is not invoiced yet; when nothing is left, it opens the invoice already there. Register refuses an invoice that, together with the
Registeredinvoices on the same receipts, bills more of an item than was received, and names those invoices. The check also catches a link made by hand or by an import. Example: 4 received at 25; invoice 1 bills 3 at 25 (matched 75, difference 0); Enter supplier invoice again drafts 1; registering it leaves payables at 115, as the receipt accrued.
What is posted#
On Registered:
SupplierInvoicePayableTxadds the gross difference — the difference plus tax at Applied tax rate — toPayablefor the supplier. A zero difference posts nothing at all.SupplierInvoiceGLTxbooks the absolute difference as a purchase price variance — a result of the period, not a correction of the inventory account. A positive difference debits the variance account and credits payables; a negative one swaps the two, because the general ledger service refuses a non-positive amount. An emptyAccountingSettings.PurchasePriceVarianceAccountmeans "this leg is not configured": the invoice still registers andPayablestill moves, and nothing is written to the ledger.- The document event creates a
TaxCalculationin the input direction for a positive difference, or a reversal for a negative one, and links it to the invoice.
The purchase tax seam that adds input VAT to Payable only fires when it can resolve a PurchaseOrder behind the calculation, so it does not double the invoice's own tax.
Why the difference is a variance, not a stock correction#
The receipt valued the goods at the order price in two places at once: the InventoryValue register and the cost layers in ItemCostFifo. Both are what CostingIssueTotalDriver writes off when the goods later leave the store, and it writes off exactly the amount the costing engine removed from the layers. That lock-step is the reason the ledger and the subledger cannot drift apart whatever costing method the settings name.
A supplier invoice arriving later cannot reopen those layers. A layer is addressed by the engine's own lot number, which no script ever sees, and a movement with zero quantity is worse than useless: plain FIFO hands its whole amount to the next issue however small, and the average-cost branch gives such a layer a zero share and then drops it, so the money never leaves stock at all.
So the policy is stated rather than implied, and it is the one standard-costing shops use: stock keeps the price the receipt recognised, and the gap with the supplier's sheet is a result of the period. Payable still ends at what the supplier billed, which is what a payment settles.
4 bolts received at 25, invoiced at 30, VAT 15%:
| Before the invoice | After Register | |
|---|---|---|
InventoryValue for the item |
100.00 | 100.00 — unchanged |
ItemCostFifo layers for the item |
100.00 | 100.00 — unchanged |
| Inventory account in the ledger | 100.00 Dr | 100.00 Dr — still equal to the subledger |
| Purchase price variance account | — | 20.00 Dr |
| Payables account | 115.00 Cr | 138.00 Cr (20 difference + 3 VAT) |
Payable for the supplier |
115.00 | 138.00 |
Invoiced at 20 instead, the same rows read 20.00 Cr on the variance account and 92.00 Cr on payables; inventory does not move either way.
Correcting the cost of goods already sitting in a cell stays a StockAdjustment — deliberately, as a decision somebody takes rather than a side effect of a supplier's paperwork.
What's not there yet#
- There is no three-way match against a separate goods-received-not-invoiced account. The difference lands on the purchase price variance account.
- The difference does not re-cost received stock — that is the policy, not a missing form. See Why the difference is a variance.
- There is no approval step between
DraftandRegisteredbeyond the tolerance check.
Same topic for other readers: User