Skip to content

Procurement — getting stock in the door, before it hits the books

What this covers. Everything that happens before goods are physically in your warehouse: deciding what to buy, how much, and from whom — and then checking that what arrived, and what you were billed for, matches what you ordered, even when the bill shows up days after the truck. The central idea is that a purchase order is a promise, not a stock fact: flour you have ordered but not received is not on hand, cannot be cooked, and has no cost yet. This chapter explains the suppliers you buy from, the units goods come in, and the supplier articles that price them; the per-place minimum and maximum stock levels that decide when to reorder; the goods receipt and the supplier invoice that attaches to it — at the till for a walk-in buy, or days later for a delivery — and the lightest case of all, a no-supplier market run that posts stock from just an item, a quantity, and a cost; the three-way match between what was ordered, what was received, and what was invoiced; and the stock-aware plan that subtracts what you already have (and have already ordered) from what you need, so you never double-buy. Everything you buy rides this same path — ingredients, packaging, expensed supplies, even a €4,500 oven.


1. Buying is intent; the ledger is reality

A warehouse's stock ledger is an append-only record of what physically happened to stock — what was received, consumed, transferred, wasted, counted. (Perpetual inventory means the on-hand count is kept live, move by move, rather than discovered once a month at a stocktake.) Procurement sits in front of that ledger. It is the layer of intent: a decision to buy 20 kg of flour next Tuesday.

That decision is a commitment, not a stock movement. A stock movement is the ledger's unit of physical change — value moving from one place to another. A commitment changes nothing physical. Flour you have ordered but not received:

  • is not on hand — you can't cook with a promise,
  • has no cost in the books yet — its weighted-average cost (the running average price the warehouse paid, blended across deliveries) is unaffected,
  • and is not in the ledger at all — no movement, no entry.

So the single most important rule of this whole chapter is:

A purchase order never moves stock. It is a commitment document, full stop. Stock and value enter the books at exactly one moment — receipt, when goods physically arrive and a goods receipt is recorded. The order and the receipt are two different things, deliberately kept apart, and reconciled by the three-way match (§6).

Why keep them apart at all? Because they answer different questions and change for different reasons. The order is what we intend to spend; the receipt is what we actually got and what it actually cost. If you let the order touch the ledger, your on-hand count would inflate the instant you placed an order — long before the truck arrives, and even if it never does. The order's money is committed but not yet spent: it's the difference between "we have 5 kg of flour" and "we'll have 25 kg by Friday." Both numbers are true, and the plan in §8 needs both — but only one of them is stock.

This is the classic separation a large ERP draws between three roles: purchasing (the commitment), receiving (the goods actually showing up), and paying the supplier (the invoice). A big SAP-or-Odoo-style system keeps three separate documents wired together through a clearing account. For a small food-and-beverage operator that's ceremony with no payoff — so this domain keeps exactly one document, the goods receipt, and treats the supplier invoice as an attachment to it rather than a document of its own. The invoice can arrive in two rhythms:

  • At posting — the walk-in purchase. The chef pays at the cash-and-carry till and is handed the invoice with the goods. The receipt is recorded with the invoice already attached, complete in one step.
  • Later — the delivery pattern. Goods arrive with a delivery note — the paper that says what's on the truck, but not always what it costs. The supplier's invoice follows days later, sometimes consolidating a whole week of deliveries into one bill. The receipt posts from the delivery note right away — stock can't wait for paperwork — and the invoice attaches when it shows up, truing up the prices (§6).

Either way there is one receipt per delivery and no clearing account between receiving and paying. What survives, and what matters, is the match: did we get — and get billed for — what we ordered?

The market run: a goods receipt with no supplier at all

There is a third, even lighter rhythm, and it is first-class, not a workaround: the cash run to the market or the bazaar, where the cook buys a crate of tomatoes from a stall that issues no invoice and is no one's catalogued supplier. A goods receipt does not need a supplier or a supplier article to bring that stock in. The minimum to post a movement is genuinely small: an item, a quantity in a plain measure, a cost, a warehouse, and a date. That cost is all weighted-average costing needs; the stock lands and is valued exactly like any other receipt.

Everything supplier-shaped is optional on top of that floor. When a supplier is named, the three-way match (§6) and the price-history learning kick in; when one isn't, they simply don't apply — there is no order to match against and no article whose price to record, and that is fine. The market buy is the everyday reality a food operation runs on, so the receipt is built to accept it with no ceremony.

The lightweight prep document for that run is the shopping list — the casual jot of what to buy, carried to the market and booked against the till receipt as a walk-in goods receipt once the cook is back.


2. Who you buy from: suppliers and the article that prices an item

Procurement has to know what unit the goods come in, who sells it, and at what price, with what lead time. Two ideas carry this: a supplier (who you buy from) and a supplier article (how one supplier prices one item, in a chosen unit). There is no separate "bundle" record between them — the bundle a thing arrives in is just one of the item's units (a 25 kg sack, a case of 6 × 2 kg), exactly like kg or each, taught in Units of measure. You order in whatever unit you buy in ("2 sacks"); your stock is held in the base measure (grams, once it lands); the unit's ratio turns the one into the other without anyone doing the arithmetic twice.

The supplier

A supplier is a vendor you buy from: a name, a contact person, phone, email, address, and any attached paperwork (a signed contract, a price list). It is scoped to your company — your suppliers are yours. A supplier owns no prices itself. Price lives on the article, because the same vendor sells flour, sugar, and oil at three different prices in three different units.

The supplier article

A supplier article is one supplier's catalogue line for one item, bought in a chosen unit — how you buy this item from this vendor, and at what. It points at the item and the unit it is priced in: a per-item bundle (a 25 kg sack), or a plain measure (kg, for loose produce). The same item from two vendors is two articles; the same item priced two ways by one vendor — per sack and per pallet — is two articles too. Each carries the commercial terms and the recognition keys for that line:

  • the price in that unit — what this supplier charges per sack, per case, per kg,
  • the price per base measure — the same price expressed per kilogram or per liter, so you can compare two suppliers like-for-like even when one prices a 25 kg sack and the other a 10 kg bag,
  • the lead time — how many days from order to delivery, used to decide when to place the order so it lands in time (§8),
  • the minimum order quantity (MOQ) — the smallest amount the vendor will sell; you can't order half a sack,
  • the recorded price history — what this article has actually cost over its recent receipts, feeding the anomaly checks (§6). The history also yields the article's typical price: the middle value of its recent history, not the average, so one box misread as a single piece at ten times the price cannot poison the very figure used to catch that mistake,
  • and the codes and descriptions that let a delivery's invoice line be recognized as this article: the supplier's printed code (their article number), and the free-text line descriptions it has used before, learned over time — plus a shop link and photos of the goods and the supplier's label.

The article is optional, and entirely a purchasing-side concept: it exists to power purchase-order creation, the order↔invoice match, invoice auto-recognition, and price memory. Bringing stock in needs none of it — a goods receipt posts from an item, a unit, a quantity, and a price (the market run, §1). A catalogue line can even sit unresolved, naming a supplier and a code but no item or unit yet, until someone matches it — and that match is yours to change. Which item a supplier's line points at is a bookkeeping decision, not a fixed fact: re-aim it whenever you learn the line meant a different item, or fix one you mapped wrong. That never disturbs what you already received — every goods receipt froze its own item and unit the moment it posted — so a catalogue line only guides the next delivery, it never rewrites the last.

Worked example. Flour from "Baker's Supply": you buy it as a 25 kg sack (a per-item unit, ratio 25 000, since 25 kg = 25 000 g), and a supplier article prices that item-in-that-unit at €18.00 a sack, 2-day lead time, MOQ 1 sack. The price per base measure is 18.00 ÷ 25 000 = €0.00072 per gram, i.e. €0.72 per kg — the number you'd line up against a rival vendor's own article for the same flour. Order 2 sacks and that's 50 kg = 50 000 g feeding the plan's base-unit math; the committed cost is 2 × 18.00 = €36.00.

Variable-weight goods (catch-weight). Some goods are sold by a weight that isn't fixed per package — a side of beef, a wheel of cheese, loose fruit weighed at the counter. The supplier prices them per measure (per kilogram), and each delivery's actual weight is whatever the scale read that day. The unit for these is that measure — one kilogram, priced per kilogram — and the received line carries the weight that arrived (5.945 kg, not "1 case"). The ledger books exactly that weight: there is no fixed bundle to convert, because the weight is the quantity.


3. How much to keep: minimum and maximum per place

A par level answers a simple question: how much of this should I keep on hand here? It comes as a pair of numbers — a minimum and a maximum — set per item, per warehouse — a warehouse being one place the business actually holds stock.

  • Minimum (the reorder point). When the projected on-hand for this item at this warehouse falls to or below the minimum, it's time to reorder. This is the everyday, demand-agnostic trigger that keeps you from running out.
  • Maximum (the order-up-to level). The target you replenish back to. The baseline order quantity is simply maximum − projected on-hand, before any rounding for unit size or MOQ.

Why per-item-per-warehouse, and not just per item? Because the warehouse is the grain at which stock actually lives and is valued — on-hand and weighted-average cost are both warehouse-level facts (see Scope & locations and Costing & valuation). The bar and the dry store, run as two warehouses, hold what is, on paper, the same item, but they're different pools that run down at different rates and reorder on different cadences. A commissary warehouse that supplies three restaurants pars high; a single outlet's own warehouse pars low. A par level is a property of stock held at a place — exactly like on-hand and cost — so it belongs at the same grain.

Don't confuse the maximum with the supplier's MOQ (§2). They're different numbers from different sides of the table: MOQ is "the smallest the vendor will sell you"; the maximum is "the most you want to hold." Both feed the plan, and they're not interchangeable — a vendor might force a 1-sack minimum on an item you'd happily hold only 5 kg of.

Par only applies to stock you actually track

A par level only makes sense for an item the system perpetually tracks — one that is counted and valued, with a real on-hand number to compare against the minimum. This is the system's stocked gate: a single yes/no property that says whether an item is carried as perpetual inventory at all (see Item model & policies). The same gate governs counting, valuation, and the ledger — one consistent predicate, not a guess based on what category an item is filed under.

Everything, though, is orderable — any item can be a purchase-order line and a goods-receipt line. What the gate decides is only whether the plan can propose it automatically:

  • Tracked (stocked) items can be par'd, and the plan can propose orders automatically from their minimum and maximum.
  • Expense-on-receipt items — cooking oil, salt, a cleaning supply — are written off the moment they're received and never counted or valued. They have no on-hand quantity, so there is nothing for a minimum to watch and nothing for a maximum to refill toward. The operator can still put oil on an order by hand whenever they like, but the plan will not auto-propose it. Manual-add only.
  • Capitalized items — durable assets: an oven, a mixer, a walk-in fridge — are likewise orderable, manual-add only (nobody auto-reorders ovens off a par level). They ride a purchase order and a goods receipt like anything else; the difference shows at receiving, where a capitalized line creates an entry in the asset register instead of a stock movement (see Fixed assets) — and the line still participates in the three-way match. A €4,500 oven invoice is exactly the one worth matching.

4. The purchase list: capturing intent before it's resolved

Everything from here down assumes a buying decision is already resolved — you know the supplier, the unit, the price, the exact item. But that is rarely where buying actually starts. It starts with a scribble:

"I need 101 eggs, 5 kg of flour, and some cling film."

No supplier chosen. No unit chosen. Quantities in whatever unit is natural — and maybe not even a firm catalog item yet ("some cling film"). Forcing the operator to pick a supplier, a unit, and a price before they can even jot down "eggs" is exactly the kind of friction that stops a busy kitchen from starting at all. So the domain gives that scribble a home of its own: the purchase list.

A purchase list is loose buying intent, captured early — the everyday request that precedes the order. Like the order it is pure intent: it never moves stock and never touches the books. Unlike the order it is deliberately unresolved:

  • a line may be a real catalog item or just free text ("cling film") — it only has to name something;
  • the quantity, the unit, the needed-by date, and the warehouse are all optional — "some cling film" is a perfectly valid line;
  • there is no supplier and no price on it at all.

The kitchen adds to one list across the week; it can be printed and shopped; and when the buying decisions firm up, each line is resolved — bound to a catalog item (with a suggestion the operator applies, never an automatic guess) — and then fulfilled. The whole arc is capture → resolve → fulfill, and there are two ways to fulfill a list:

 capture            ┌─ Plan it ─▶ supplier + unit chosen, rounded to units ─▶ draft order(s) ─▶ receipt
 purchase list ─▶ per line          (your quantities at face value; optionally net out stock)
 (loose lines)      └─ Print ──▶ shop ─▶ keep the till check ─▶ scan the check ─▶ goods receipt

Plan it turns the list into actual orders. It does the same order-shaping the stock-aware plan does (§8): it resolves each line to a supplier and a unit, rounds the quantity up to whole units and the supplier's minimum, and groups the result one draft order per supplier. What it deliberately does not do by default is netting — subtracting what you already have. A hand-written list is an explicit statement of intent, so Plan it takes your quantities at face value: ask for 101 eggs and it orders enough whole units for 101 eggs, even if some are already in the fridge. Subtracting on-hand is offered as a deliberate opt-in: turn it on and a line is reduced by what's already on hand and already on order, and a line that's already fully covered is marked as such and ordered as nothing. (Contrast the automatic plan in §8, where netting is always on — that is the whole point of a reorder-point. The difference between the two is exactly the difference between "keep the stock topped up" and "I, a human, want these things.")

A line that can't be planned — no firm item, no quantity, a unit that can't be converted, or no warehouse to deliver to — is surfaced, not silently dropped; so is a plannable line with no supplier or unit to source it from ("pick a supplier"). The operator fixes it and plans again. Lines they decide they don't want are dropped. Whatever is left can simply be lived with: an unresolved "cling film" line may linger — that is the point of a low-friction front door — until the operator closes the list, or cancels it to abandon it.

The other path needs no orders at all. The operator prints the list, shops, keeps the till check, and records a goods receipt from that check — the same photo-to-receipt flow used for any walk-in purchase (§6). The list and the receipt aren't wired together; the list was just the shopping memo. When the trip is done, the operator closes the list.

Why a separate thing, and not just a loose order? Because an order carries invariants a loose list would break — above all one supplier per order, the very thing the three-way match (§6) reconciles against. A list that mixes eggs from one vendor and flour from another can't be a single order. Keeping the loose, multi-supplier, pre-resolution stage as its own artifact lets the order stay strict and matchable, and lets capture stay effortless. The purchase list is the third source of demand in this domain — the manual one — beside the two automatic feeders the plan already has (§8); it is the one a human authors by hand, and the only one that is stored, printed, and shopped.


5. The purchase order: a commitment to one supplier

A purchase order is a commitment to one supplier for specific items, at specific quantities, in chosen units, at agreed prices, expected by a date. It has:

  • a header — your company, the supplier, the target warehouse where the goods will land, the order date and the expected-by date, a status (§7), a note, any reference documents (a supplier quote, the emailed order confirmation, a signed copy of the order), and optionally a pointer back to the plan run that proposed it. These documents are filing-cabinet material — the supplier's invoice is never one of them; it rides on the goods receipt (§6);
  • lines — one per item ordered: the item, the unit ordered, the ordered quantity (in those units), the agreed price per unit, and a derived base-unit quantity and committed amount.

By construction the order is pre-ledger: no stock movement, no lot (a lot being a tracked batch of stock with its own arrival date and expiry), no effect on weighted-average cost. Its only money figure is a commitment — the sum of line price × quantity — and that number is used for two things only: forecasting how much you'll owe suppliers, and the three-way match (§6). It is never fed to valuation. What feeds cost is the receipt's actual net cost, not the order's promise (see Costing & valuation).

Why one supplier per order? Because an order is a thing you send to a vendor and then match against that vendor's one invoice. The plan in §8 may work out demand across many items sourced from many suppliers — but it then groups the result one order per supplier, so each order is a single thing you can send, receive, and reconcile against one bill.


6. The three-way match: ordered vs received vs invoiced

When goods arrive, the operator records a goods receipt — the document that brings stock into the books (what it does to stock and cost is covered in Stock ledger). The supplier invoice is not a separate document: it is an attachment on the receipt — present from the start for a walk-in purchase, attached later for a delivery (§1). The three-way match is the reconciliation that answers: did we receive — and get billed for — what we ordered?

The textbook three corners are the purchase order, the goods receipt, and the vendor invoice. Here the third corner rides on the second:

The classic three corners Here
Purchase order the purchase order (this chapter)
Goods receipt the goods receipt
Vendor invoice the invoice attached to the goods receipt — at posting, or later

So the "three-way" match is really purchase-order line(s) ↔ one goods receipt whose face carries the invoice. There is still exactly one document, so there is no separate clearing account sitting between receiving and paying.

When the invoice comes later: post now, true up the price

For the delivery pattern, the receipt posts from the delivery note at the ordered (or estimated) prices — the best figures available at the door. Stock is on hand, cookable, and costed from that moment. When the invoice attaches, the real prices replace the estimates, and the difference is settled honestly in two parts:

  • The portion still in stock is revalued — a value-only valuation entry (no quantity moves) brings the on-hand value up or down to the invoiced cost.
  • The portion already consumed can't be re-costed — those plates are sold and their cost is on the books — so its share of the difference is expensed as price drift, exactly the drift rule the costing chapter describes (see Costing & valuation).

The financial half of the match then runs against the attached invoice — the bill that actually exists, not the door-side estimate.

The connection from an order to a receipt is drawn line by line, and it is allowed to be absent. Two properties, both deliberate:

  1. Line-level, not document-level. One order can be received across several deliveries — the produce vendor ships what's fresh today and back-orders the rest; one sack is damaged and refused at the door. And one delivery can fulfill lines from more than one order. Matching at the item grain is the only way to support that fan-out honestly.
  2. Optional — walk-in receipts are first-class. A receipt line can point at no order at all, and that is completely normal: the chef drove to the market and bought tomatoes; a vendor dropped off a substitution nobody ordered. Food-and-beverage runs on these. The match never requires an order; an un-linked receipt line is the rule for spontaneous buys, not an error.

Sitting above those per-line links, a receipt also names — at its header — the set of orders it fulfills: a multiselect of one or more purchase orders the operator declares this delivery to be against. The submitted set is authoritative, and it stays in step with the line links automatically: linking any receipt line to an order's line auto-declares that order (the declared set is every order explicitly chosen plus every order a line points at), and dropping an order from the set detaches — unlinks — its lines. A declared order is checked two ways: it must belong to the same supplier as the receipt, and it must still be open to receive against — only an Ordered or Partially received order can be declared, never a finished (received/over-received) or cancelled one. Amending a receipt copies its declared-order set forward; re-scanning a draft re-derives the lines as unlinked, and if the supplier changed it clears the declared set (those orders belonged to a different vendor). The header set is the operator's statement of intent; the per-line links above remain optional and per-item beneath it.

Checking the money: gross amounts, within a small tolerance

The financial half of the match compares the gross amounts on each side — the order line's committed amount against the attached invoice's gross total for that line. "Gross" means the full invoice figure: the goods subtotal plus the share of freight/handling and any non-recoverable tax allocated to that line (the landed cost — the all-in cost of getting the goods into your warehouse). The comparison is gross precisely because the match is an invoice tie-out: it's checking "does the bill agree with the order," and the bill is gross. (The net cost — gross minus any recoverable tax — is what flows to valuation, a separate concern explained in Costing & valuation. The match doesn't use it.)

A small tolerance absorbs honest penny-drift — rounding on freight, a fractional cent here or there. The tolerance is a per-currency configuration default of 0.05, not a hard constant: what counts as penny-drift depends on the currency the company keeps its books in.

The match doesn't just answer matched-or-not; it classifies each order line with one verdict from a fixed, ordered set, and quantity is decided before price:

not-received   → nothing arrived against this line
short-received → less arrived than was ordered
over-received  → more arrived than was ordered
unpriced       → no expected price to compare against
price-mismatch → quantity is right, but the gross subtotal differs beyond tolerance
matched        → right quantity, right money

The quantity verdicts come first because a line that under- or over-delivered is a quantity story regardless of price; only once the quantity lines up does the gross subtotal get compared against the tolerance. This is exactly the per-line classification that makes the order's own status derivable — a line's over-received verdict is what lifts the whole order to over-received in §7. The same verdict rule serves a receipt-side preview too: before a draft is posted, the operator can see what posting this receipt would do to each declared order's lines and status, computed against a received baseline of the already-posted lines plus this receipt's own (other open drafts and amend-superseded originals don't count).

There is also a second, lighter reconciliation worth knowing about, separate from the order-versus-invoice match. When a receipt is built from a scanned supplier document, the grand total the document itself states is captured and kept as the receipt's scanned total. It is compared against the receipt's own computed gross — the sum of its lines — purely as an advisory check: if the typed-or-read lines don't add up to the invoice's stated total, that discrepancy is surfaced, but it never blocks posting. (For a manually keyed receipt there is no scanned total, so the check simply doesn't apply.) This catches a mis-keyed line; the order↔invoice match catches a mis-delivery or a price change. They are different questions asked of the same receipt.

Reading the invoice: from a photo to a draft receipt

Typing an invoice in by hand is the chore an operator most wants to skip, so a receipt can also be read straight off a photo or PDF of the supplier's invoice or delivery note. The reading produces a draft goods receipt, never a posted one — a starting point the operator reviews, corrects, and only then posts. Three things happen in that read, in order, and each is deliberately conservative: the system would rather leave a line for a human than guess wrong and quietly book the wrong stock.

  1. Identify the supplier. The vendor on the invoice is matched to one of your existing suppliers by name, across language and script — a bill that prints "Макро" is recognized as your "Makro." If no existing supplier is clearly the vendor, a new supplier is created from the name and contact details printed on the bill, so the draft always lands against a real supplier. Supplier identification is fully automatic; there is no separate "is this the right vendor?" step.
  2. Auto-fill the lines the system already knows. Every supplier article remembers the codes and descriptions that supplier has used for it on past invoices (the recognition keys of §2). A line whose printed code or description exactly matches one of those learned keys is bound straight to its item and unit and becomes a real, postable receipt line — and the match is learned, so this supplier's invoices get easier to read every time. Only an exact, deterministic match auto-fills; nothing is bound on a fuzzy resemblance.
  3. Set the rest aside for review. Every other line — a product the system can't confidently place, a line it has never seen from this supplier, a credit or return — is set aside as an extracted line awaiting review, not silently dropped and not guessed into a binding. Each carries what was read (the description, quantity, price, and which file and page it came from, so the operator can jump back to the source) plus, where the read was confident enough, a suggestion: "this looks like your existing Olive Oil 5L — confirm it," or "this looks new — create it as a new item." A suggestion is only ever a prompt for a human; it never binds the line on its own.

The operator then works the review list down. Applying a line turns it into a real receipt line (creating the item or unit first if it's genuinely new); dismissing a line drops it — a duplicate, a header row the reader mistook for a product. Either way the line leaves the review list. A line proposed as new is the operator's chance to tidy the inventory name, the unit name, and the unit's conversion ratio before committing — exactly the moment those are still editable.

Reading a line at the right grain. One printed line often states the same goods two ways — a coarse "1 box" alongside a finer "10 × 1 kg @ €0.99," or a weighed "5.945 kg @ €2.20/kg." The read takes the finest grain the bill actually prices, so the quantity that lands is the real one: ten kilograms from that box, the weighed kilograms from the scale — never "1" when the box holds ten. It only copies numbers the bill prints and checks they reconcile to the line's total; if the only price shown is per box, it reads one box and leaves the unit size to the item's known ratio. Rows that aren't goods at all — a delivery fee, an included tax or levy memo, a returnable-container deposit — are recognized by their role and kept out of the product lines, never read as stock.

A draft can't be posted while lines are still awaiting review. Posting brings stock and cost into the books, and a half-reviewed invoice would silently drop the stock on every un-applied line. So a receipt read from a document cannot post until every extracted line has been applied or dismissed — the review list must be empty. This is the one gate the photo path adds; it exists precisely so a readable-but-unplaced line can never vanish into a posted document.

Re-reading a draft from a fresh photo replaces its lines and its review list wholesale — a clean re-do, not a merge. And re-reading is the only repair: the read is a convenience that produces a draft for a human to finish, never an authority that posts on its own.

Worked example. - Order line: 2 sacks of flour @ €18.00 = €36.00 committed (gross). - Goods arrive: 2 sacks, supplier invoice line €36.03 gross (a 3-cent freight rounding). - Right quantity, difference = 0.03 ≤ 0.05 ⇒ matched, no operator action. - Counter-case: the invoice line reads €38.50 (the price went up). Right quantity, difference = 2.50 > 0.05 ⇒ price-mismatch, flagged for resolution. The receipt still records the goods at their real cost — the ledger always books what actually arrived — while the match is what surfaces the price drift so a human sees it.

Why the receipt, not the order, drives stock and cost. The order said €36.00; the truck might bring 1.9 sacks at a corrected price. The ledger and the weighted-average cost must reflect what physically arrived and what it actually cost — that's the receipt, valued at its net landed cost (and trued up if the invoice came later). The order is the expectation the actual is checked against; it is never the source of the stock fact. That, in one sentence, is the entire reason the two are separate documents.


7. The life of a purchase order

An order moves through six states:

Draft ──▶ Ordered ──▶ Partially received ──┬──▶ Received
  │           │                │            └──▶ Over-received
  └───────────┴────────────────┴───────────────▶ Cancelled
State What it means Effect on stock
Draft being assembled — by the operator, or proposed by the plan; freely editable; counts as an open order in the netting engine (§8) so a re-run while a proposal stands does not generate duplicates none
Ordered committed and sent to the supplier; counts as an open order in the plan (§8) none — still pre-ledger
Partially received some lines or quantities have arrived and been received; the rest is still outstanding the arrived portion enters the books via its goods receipt; the order itself, still none
Received fully fulfilled — every line arrived, each within tolerance of what was ordered none of its own (all stock effects belonged to the receipts)
Over-received fully fulfilled, but at least one line arrived above its ordered quantity (beyond tolerance) — the supplier sent more than the order called for none of its own (the surplus entered the books with its goods receipt)
Cancelled abandoned before or partway through fulfillment; stops counting as open none

Why "partially received" is a real state, not an edge case. In food-and-beverage, partial deliveries are normal: the produce vendor ships what's fresh and back-orders the rest; a damaged sack is rejected at the door. Modeling "partly here" as an explicit state — rather than forcing the operator to cancel and re-order, or to pretend the whole thing arrived — keeps the open-order math honest. The still-outstanding quantity is exactly what the plan must keep counting as on-order (§8).

Received, over-received, and the rule when lines disagree. An order is fully delivered once every line has arrived. If each line landed within tolerance of what was ordered, the order is received — a clean fulfillment. If nothing is short but at least one line came in above its order (beyond tolerance), it is over-received instead: a distinct outcome so the operator sees "the supplier sent more than we asked" at a glance, rather than having it hide inside a plain "received." One rule settles the mixed case — still-short always wins. If even one line is under-delivered, the order stays partially received no matter how far another line ran over, because that short line is genuinely still on-order and the plan must keep counting it (§8). Over-received is reached only when nothing is short and something is over. Reversing the over-delivery later — cancelling or amending the goods receipt that carried the surplus — rolls the order back to whatever its remaining receipts justify.

Who approves an order. There's no separate approval workflow. The human confirmation is the approval: when the plan proposes a draft order, an operator — often through the Dough agent — reviews it and confirms it into Ordered. The person is the gate. The agent proposes and explains; the operator decides; the deterministic path then does the work.


8. The stock-aware plan: what to buy, and when

The plan answers the operator's real question — "what do I actually need to buy, and when do I place the order?" — by combining demand (what we'll need) with coverage (what we already have or have already ordered). It draws demand from two automatic sources and runs them through one netting engine. (The third source of demand — the hand-authored purchase list of §4 — is manual: it reuses the shaping half of this engine but skips the netting by default, since a human typing "101 eggs" means 101, not "101 minus whatever's in the fridge.")

Two automatic sources of demand

  1. The reorder point (everyday). From the minimum/maximum par levels (§3): if projected on-hand has fallen to or below the minimum, top back up to the maximum. This is the demand-agnostic baseline that simply keeps you stocked.
  2. The forecast cascade (planning). A forward-looking, menu-driven chain: a weekly sales plan → a daily distribution → per-restaurant ingredient demand (obtained by exploding each dish's recipe — walking the bill of materials down to raw ingredients, the same explosion described in Recipes & production) → logistics dates → a prep plan → procurement demand. This is the source for "we expect to sell N of dish X next week, so we'll need M kg of ingredient Y by Tuesday."

Demand combines across restaurants on the way down. In a group fed by a central commissary, each restaurant's forecast explodes separately, and the demand for shared prep items lands together at the warehouse that makes them.

Worked example. Restaurant A's Tuesday plan needs 45 kg of dough; Restaurant B's needs 30 kg. The prep plan therefore calls for 75 kg of dough at the commissary by Tuesday — and because dough is a prep item, its recipe explodes onward: 75 kg of dough at a 60% flour ratio becomes 45 kg of flour demand at the commissary's store, dated early enough to produce. That single flour figure — not two restaurant-sized ones — is what enters the netting engine below, gets the commissary's on-hand and open orders subtracted, and lands on one supplier's draft order.

The netting engine, step by step

"Netting" just means subtracting what you already have from what you need, so you only buy the gap. In business terms the engine does this:

  1. Total up gross demand per item and demand-date, from the logistics plan plus the raw materials exploded out of each prep item line (a prep item — formally, a semi-finished good — is something you make in-house and stock: a batch of dough, a base sauce; its own recipe is exploded to find the raw materials it consumes). This total is "raw need, before subtracting anything we have."
  2. Keep only what can be sourced. Items with a known supplier article or default supplier proceed; an item with neither is skipped with a warning — surfaced for a human, never silently dropped. (Recall §3: par-driven auto-proposals are limited to stocked items; expensed and capitalized items can still ride along if added by hand.)
  3. Net against coverage — subtract what's already covered. This is the heart of a stock-aware plan. From gross demand, subtract:
  4. real on-hand — the live ledger quantity at the relevant warehouse (the running sum of stock movements; see Stock ledger), and
  5. open orders — the sum of max(ordered − received, 0) across the lines of every purchase order that is not yet finished: Draft, Ordered, or Partially received. Both Received and Over-received are finished and excluded — an over-received order has nothing still outstanding, so it contributes zero coverage, and the per-line max(… , 0) means an over-delivered line never subtracts more than was ordered. A draft proposal created in an earlier run of the netting engine is counted as coverage, so that a second run — before that draft is confirmed — does not generate duplicate orders for the same item.

There's also a within-this-run carry-forward: if rounding up to whole units on an earlier date over-buys, that surplus rolls forward and reduces a later date's need in the same run.

net need = gross demand − on-hand − open-order quantity − surplus carried forward

If net need comes out ≤ 0, order nothing and carry any surplus forward. 4. Round up for MOQ and unit size. Convert the net need (in base units) into whole units using the unit's ratio, take at least the article's MOQ, and round up — you cannot buy 1.3 sacks. 5. Back-date the order by the lead time. The recommended order date is the demand date minus the supplier's lead time, then snapped to the nearest valid ordering day on or before it. This is when to place the order so it arrives in time. 6. Group one order per supplier. Each line is resolved to its vendor (via the item's supplier article, or the item's default supplier), and the proposed lines are grouped one purchase order per supplier — one sendable, matchable document each.

The output is a set of draft purchase orders, one per supplier, each with lines carrying the supplier, item, order date, demand date, base-unit quantity, the unit, and the unit quantity.

One boundary worth stating: the engine buys from vendors — it does not move stock between your own warehouses, and it does not schedule production. In a group with a central commissary, "Restaurant B is low on dough" is answered by an explicit transfer from the commissary (see Scope & locations §5), not by a purchase order — and the netting engine does not propose those transfers. Likewise the prep plan stage of the forecast cascade (§8) tells the engine how much prep-item demand to explode into raw-material purchases, but the engine never emits "produce 60 kg of dough on Tuesday" — production runs record what the kitchen actually made; they are not proposed. Make-side and move-side suggestions are the same subtraction pointed at different sources and a natural later extension; today the commissary's production and dispatch rhythm is the operator's call.

Worked example (the subtraction that earns its keep)

Suppose next Tuesday's forecast needs 40 kg of flour at the dry store, the supplier's lead time is 2 days, the unit is a 25 kg sack, MOQ 1 sack, price €18.00 a sack.

  • Gross demand (Tue) = 40 kg.
  • On-hand now (the live ledger quantity at that warehouse) = 12 kg.
  • An open order, already Ordered, arriving Monday = 25 kg (1 sack).
  • Net need = 40 − 12 − 25 = 3 kg.
  • Units = ceil(3 ÷ 25) = ceil(0.12) → bumped up to the MOQ = 1 sack (25 kg).
  • Surplus carried forward = 25 − 3 = 22 kg (it'll trim any later demand in the same run).
  • Order date = Tuesday − 2 days = Sunday, snapped to the ordering calendar.
  • Committed amount = 1 × 18.00 = €18.00, grouped into the "Baker's Supply" draft order.

Without the on-hand-plus-open-order subtraction in step 3, the naïve plan would have ordered 2 sacks (ceil(40 ÷ 25)) and over-bought about 35 kg of flour you either already had or already had on the way. That subtraction is the whole point of a stock-aware plan.

The human stays in the loop

The plan never auto-sends. It produces draft orders and surfaces them to the operator — through the Dough agent — for review and confirm-to-Ordered. The agent proposes and explains its reasoning ("12 kg on hand, 25 more on order, so one extra sack covers Tuesday"); the operator approves; only then does the deterministic engine turn the draft into a sent order. Warnings — a missing supplier, a zero lead time — ride along as findings for the operator to see, rather than failing the whole run.


9. The whole flow, in one pass

  1. Optionally, a human jots a purchase list — loose, low-friction intent: items or free text, quantities maybe, no supplier or price. They resolve its lines to catalog items, then Plan it (order-shaping at face value, on-hand netting only if asked) into draft orders, or print it and shop, recording a goods receipt from the till check. This is the manual, third source of demand.
  2. Minimum/maximum par levels (per item, per warehouse, tracked items only) plus the forecast cascade produce demand automatically.
  3. The netting engine subtracts real on-hand and open orders, rounds up for MOQ and unit size, back-dates by the lead time, and groups one draft order per supplier.
  4. An operator (through the Dough agent) confirms a draft into Ordered — now an open commitment, still pre-ledger.
  5. Goods arrive → a goods receipt is recorded and posted — typed by hand or read from a photo of the invoice into a draft the operator reviews (§6) — with the invoice attached on the spot (a walk-in purchase), or from the delivery note at ordered/estimated prices (a delivery) — linked line by line to the order's lines, or left un-linked for a walk-in buy. A receipt read from a document can't post until every extracted line has been applied or dismissed. A capitalized line lands in the asset register instead of stock.
  6. If the invoice comes later, it attaches and the prices true up: the on-hand portion revalues; the consumed portion's difference is expensed as price drift.
  7. The three-way match compares the gross amounts against the attached invoice, within the configured tolerance (default 0.05, per currency): in tolerance is matched, out of tolerance is a discrepancy to resolve.
  8. The order advances Ordered → Partially received → Received — or to Over-received instead of Received, when a line arrived above its order — as its lines are fulfilled (§7); Received and Over-received are both finished outcomes. Throughout, only the goods receipt ever moves stock and cost — at the goods' actual net landed cost, which is what blends into weighted-average cost. The order itself moves nothing, ever.

See also

  • Stock ledger — the goods receipt that brings stock in: the landed-cost build-up, the batch (lot) it creates, and the gross-vs-net totals the match reads; plus the journal of stock movements whose running sum the plan subtracts as on-hand.
  • Period close — the goods receipt's draft → posted → amend/cancel lifecycle, and the month-end close where a match discrepancy ultimately surfaces.
  • Costing & valuation — weighted-average cost, the gross (invoice tie-out) vs net (valuation) split, why cost reads the net figure, and the drift rule the invoice true-up leans on.
  • Item model & policies — the stocked gate that par levels and the plan's filter rely on, and the four treatments (stocked, expensed-on-receipt, expensed-on-write-off, capitalized) a receipt line routes by.
  • Fixed assets — the asset register a capitalized receipt line lands in, and what happens to an asset after it's received.
  • Scope & locations — the warehouse as the stock and valuation grain that par levels are keyed to.
  • Units of measure — base measures, the units you buy in, and the ratio that converts a unit into a base-unit quantity.
  • Recipes & production — the recipe explosion that turns the menu forecast into ingredient demand, and the prep items whose own recipes the plan explodes.
  • Sales & consumption — the depletion side that draws stock down, against which reorder levels are set.
  • Financial boundary — the conceptual accounts this in-flow feeds for export to the operator's accounting system, including the price-difference expense the invoice true-up creates and the input-VAT receivable.
Last updated · History