Sales & Consumption — how a sale turns into stock leaving the warehouse¶
What this covers. When a restaurant sells something, the ingredients behind it have to leave inventory — at a real cost, charged to the right restaurant's bottom line. This explains how a sale that happened somewhere else (a till, the app, a delivery platform, a spreadsheet, or a manager typing it in) becomes that stock depletion: the one-way line between "selling" and "stock," the single front door every sale comes through, the two kinds of thing you can sell (a dish vs. a raw item), where the cost is drawn from and who it's charged to, why it's recorded the instant it happens, how a comped plate is still a sale while a staff meal or a recipe test is a separate recorded event of its own, and what happens when a sale is corrected, arrives late, or names something the system doesn't recognize.
1. A sale is two different events¶
The same sale means two completely different things to two parts of the business.
To the selling side — the till, the app, the delivery platform — a sale is a transaction with a customer: a price, a discount, a tip, a tax collected, a payment. That's the money coming in.
To the stock side — the warehouse and the books — the same sale is a depletion: real ingredients physically left the building, and they had a cost. A sold plate of carbonara means spaghetti, guanciale, egg, and cheese are no longer in stock. That's the cost going out.
This document is only about the second event. It does not care what the customer paid; it cares what left and what it cost. Keeping those two apart is the foundation everything else here rests on.
2. The boundary is one-way (and why that matters)¶
The selling side tells the stock side "this was sold." The stock side never talks back, and it never reaches into the customer transaction.
The selling system produces sales facts; the stock system consumes them. Stock doesn't know the menu price; the till doesn't know the recipe or what a kilogram of flour is worth.
Why draw the line so firmly? Because the two sides change for different reasons. The restaurant's food-cost math must not wobble because someone ran a promotion or edited a menu price. The till must not need to understand recipes or average costs to ring up a sandwich. A one-way boundary means the stock side has exactly one thing to get right — turning "X was sold" into "these ingredients left, at this cost, charged here" — and it does that identically whether the sale came from the app, a delivery platform, a spreadsheet, or a manager's keyboard. (What the customer paid, and the tax collected on the sale, stay on the selling side — out of scope here.)
3. One front door for every sale¶
No matter where a sale is born, it enters the stock side through a single front door — one kind of record we'll call a sales ticket. The app feed, a delivery platform, a spreadsheet of last month's sales, a hand-typed sale: all of them become sales tickets, and from that point on they're handled identically. There is one path to get right, not four.
A good front door has to guard against two specific ways the books get corrupted. They're worth understanding, because the whole design of the door exists to prevent them.
Trap 1 — counting the same sale twice. Tills and delivery platforms retry. The same order can arrive twice (a re-sent message, a re-imported spreadsheet, a manager who clicks "import" again). If the second arrival removes stock a second time, the warehouse's flour silently goes negative and food cost looks too high. The fix: a sale's identity is the restaurant plus the document's own id — the serial the till printed on the check, the ticket id a platform assigned. A free-text label (a till's nickname, a source name someone types) never joins the identity: labels drift from day to day, ids don't. The door recognizes a repeat by that identity and ignores it, so the same order, delivered twice, depletes stock exactly once — and when the world provides no id at all (a walk-in sale typed from memory), the system mints one, so each such entry counts once as its own sale.
Trap 2 — landing on the wrong day. A delivery order placed at 23:55 and handed over at 00:10 straddles midnight; a platform's timestamp may be in a different timezone than the restaurant. If the depletion is recorded on the wrong calendar day, it falls into the wrong accounting month and throws off the month-end count. The fix: the moment a sale comes through the door it is stamped — once, permanently — with a business date in the restaurant's own local clock, not the raw timestamp and not "the day we happened to import it."
Both traps are boundary problems — they happen at the instant a foreign sale crosses into the books — so both are solved right there at the door, not patched downstream.
4. Two kinds of thing you can sell¶
A sale line points at one of two things, and the only real difference is whether there's a recipe to unpack.
(a) A dish — unpack the recipe¶
The usual case. The line says "12 Carbonara." A dish doesn't deplete stock by itself — its recipe does. So the system unpacks the recipe (the textbook name for this is exploding a bill of materials): it looks up the recipe that was in force on the sale's business date, walks it down to the actual raw ingredients, and multiplies by how many were sold. The result is the list of ingredients that left stock.
Worked example. 12 Carbonaras sold. The recipe, per portion, is 110 g spaghetti, 45 g guanciale, 1 egg, 18 g pecorino. Twelve portions deplete 1.32 kg spaghetti, 540 g guanciale, 12 eggs, 216 g pecorino — each removed from stock at what that ingredient is currently worth.
One subtlety: if the recipe contains something the restaurant makes and stocks in advance — a batch of dough, a base sauce (a prep item — formally, a semi-finished good) — the unpacking stops there and depletes the prepped item itself, instead of re-deriving it down to flour and water. The dough was already made and costed when it was produced; counting its ingredients again would double-count. (See the recipes doc.)
(b) A raw item — sell it as-is¶
Sometimes you sell stock directly, with no recipe at all: a bottle of wine sold by the bottle, a case of surplus tomatoes sold to a neighbor, a can of Coke pulled from the cooler. The line names the item, and that exact item leaves stock at its own cost. No recipe, no unpacking.
There is deliberately no "is this sellable?" setting on an item. Whether something belongs on the menu is the selling side's business, not stock's. Stock's only question is the honest one: is there any of it on hand to remove? Two things therefore can't be sold this way — fixed assets (an oven isn't sold like a case of tomatoes; disposing of it is handled in the fixed-asset sub-ledger) and expensed supplies like salt or oil (they were written off when received and aren't tracked as on-hand, so there's nothing to deplete).
5. Where the cost comes from, and who it's charged to¶
Every depletion answers two questions: which stock did it come out of, and whose profit-and-loss does the cost land on. These are different questions with different answers, and keeping them apart is what lets one shared warehouse serve several restaurants honestly.
- Which stock — the warehouse. Ingredients are drawn from a specific warehouse and priced at that warehouse's average cost. The warehouse is where value lives.
- Whose P&L — the restaurant. The cost is charged to the restaurant that made the sale — its profit-and-loss, its food-cost number. The restaurant is who the margin belongs to.
A single sold dish can even draw from more than one place, so each ingredient is routed to the right warehouse:
Worked example. A Negroni sold at Restaurant A. It's a bar drink, so by default its ingredients come from Restaurant A's bar store (a warehouse) — gin, Campari, and vermouth all deplete there. But the orange-peel garnish is always pulled from the kitchen store (a second of Restaurant A's warehouses), so that one ingredient routes there instead. Every depletion is charged to Restaurant A's P&L (the restaurant is the same for the whole sale); only the warehouse differs.
The routing follows a three-level fallback, and every level stays within the selling restaurant's own consumption warehouses — the stores it actually draws from:
- A per-ingredient override. A specific ingredient can opt out of the station's store — the orange peel above always routes to the kitchen store.
- The dish's station, mapped by the restaurant. A station is a tag on the dish — kitchen, bar — naming which part of the operation produces it; each restaurant maps each station to one of its own stores (stations and the mapping are defined fully in Scope & locations). The same Negroni sold at two restaurants depletes each restaurant's own bar store.
- The restaurant's default store. Every restaurant designates one mandatory default consumption warehouse that catches anything the first two levels didn't decide — so a sale is never left with nowhere to draw from.
One consequence worth stating plainly: a sale never depletes a warehouse the goods have already left. Stock that a commissary preps for a restaurant reaches that restaurant's own stores by an explicit transfer before it is ever consumed (see Scope & locations).
6. Record it now, not at month-end¶
The instant a sale comes through the door, the stock is depleted — immediately, not deferred to a month-end batch.
This is what makes the inventory count live: on-hand is correct the moment a sale happens, the food-cost number is real all month, and the reorder math works from the truth rather than a guess. It also means a problem with one sale (say, a dish the system doesn't recognize — §8) surfaces right then, against that one sale, instead of as an avalanche at month-end. The close then becomes a calm reconciliation of what was already recorded against a physical count — not a frantic from-scratch calculation.
7. A sale expects money; everything else is internal consumption¶
A sales ticket records exactly one kind of event: a guest transaction. Money is expected — but expected is not received, and zero is a legal amount. A price can also be simply unknown — a day sheet photographed off a till, a spreadsheet column nobody filled in — and an unknown price is never confused with a zero one: the food was made either way, so the sale still depletes stock; it just doesn't claim the guest paid nothing. A comped dessert for an unhappy guest, a giveaway plate, a marketing tasting served to a customer: the guest transaction happened, so it is a sale at €0 — no revenue, but the ingredients deplete and the cost lands exactly as if the guest had paid. The €0 price is the comp; there is no separate kind of event for it. Every sale, paid or comped, leaves to the customer side of the books (the virtual destination consumption departs to; see Stock ledger) — a guest consumed the food.
What a ticket must never carry is consumption that was never guest-facing. "Maria ate a burger before her shift," "we burned two batches testing the new mole recipe" — no guest, no transaction, no money expected. These are live events in their own right, and each is recorded as its own document: an internal consumption. It says what was consumed (a dish, unpacked through its recipe exactly like a sale line, or a raw item depleted as-is) and a free note ("testing the new mole recipe"). The routing and the costing are the same machinery every consumption uses — only the door is different.
Every internal consumption carries exactly one consumption category — an entry in a small vocabulary the company owns, not a fixed list built into the system. A category does two jobs:
- It names the consumption in reports. Every company starts with Staff meal and R&D, and reshapes the list to its own reality — a caterer adds "tasting/samples," another adds "donation" or "owner's draw," a taqueria with no R&D archives that entry. Renaming and archiving are safe: history keeps pointing at the category it was recorded under.
- It says where the food went. Each category is created pointing at one of two destinations, and that choice is permanent for the category's life: eaten — a person consumed the food, so it leaves to the customer side like any meal (a staff meal); or used up — consumed by the process, nobody fed, so it leaves to scrap, the same destination recorded waste goes to (a recipe test). A destination that could be edited would silently re-route every future posting, so a category whose destination was wrong is archived and replaced, never bent.
To stock, all of it is the same primitive — ingredients left a warehouse, at a cost, charged to a restaurant. The split carries the meaning: a sale (even at €0) belongs to the guest-facing story and the food-cost-of-sales number; internal consumption is the company feeding itself or its process, reported under the company's own names for it.
8. When things change, arrive late, or don't add up¶
Three things go wrong often enough that the domain handles each on purpose, rather than hoping they don't happen.
A sale is corrected. A platform amends an order from 12 to 10; a manager fixes a mis-typed sale. The books are never edited in place — you don't reach back and change history. Instead you reverse the original depletion (put the ingredients back, on today's terms) and re-record the corrected version. The original and its reversal both stay visible, so anyone auditing later sees exactly what happened and when.
Worked example. "Carbonara ×12" was recorded, then amended to ×10. The system returns the 2-portion overage of each ingredient and nothing more is owed — net effect ×10 — while the original ×12 and its reversal both remain in the record.
A sale arrives after its month is closed. A delivery platform back-reports a straggler; a spreadsheet covers a month that's already closed. The closed month is not reopened — that would undo a finished reconciliation. Instead the depletion is recorded in the next open month as a prior-period adjustment, while still noting its true business date for the record.
A sale cannot be mapped or costed. A platform sells "Spag Bol" but the menu calls it "Spaghetti Bolognese"; or a brand-new menu item is selling before its recipe exists. The system cannot guess what left stock — so it does not silently record zero. It quarantines the sale: holds it, unrecorded, and flags it for someone to map the unknown name to a real dish or a stocked item, or activate a recipe covering the sale date, after which it records normally.
Mapping a name also teaches. The confirmed answer — "Spag Bol" means Spaghetti Bolognese — joins the restaurant's sold-name vocabulary; a till prints the same few dozen names every day, so one answer is enough, and tomorrow's report records that name without asking again. Only a person's confirmation teaches; a machine's guess never does, because a wrong remembered mapping would quietly miscost every future sale of that name — the same invisible wrongness quarantine exists to prevent.
Resolving is not forcing. Mapping the name answers what sold, but the line still has to post like any other depletion — and if something else blocks it at that moment (say, the books show too little stock to cover it), the line stays held with its mapping saved. Nothing is lost and nothing is faked: fix the blocking cause, retry, and it records. A held line therefore always shows why it waits — an unknown name still to map, a recipe missing for its sale date, or a resolved target whose posting failed and wants a retry.
Why never just record zero. A sale costed at zero would quietly understate food cost and corrupt the month-end variance — and do it invisibly, which is the worst kind of wrong. Quarantine makes the gap loud and fixable instead of a silent hole in the books. (A dish that is recognized but has no recipe on its sale date is caught the same way at ingest — a sold dish must never cost nothing.)
9. End to end, in one pass¶
The life of a sold "Carbonara ×12" delivery order:
- The platform reports the sale on the one-way feed. Stock doesn't know or care what the customer paid.
- It comes through the front door as one sales ticket, carrying the platform's own order id (so a re-send is ignored) and stamped with the restaurant-local business date.
- It's recorded immediately. The dish is unpacked against the recipe in force on that date into its four raw ingredients, each removed from stock at current cost.
- Each ingredient is routed to the right warehouse — one of the selling restaurant's own stores — and charged to that restaurant's P&L.
- It's now a fact: on-hand for spaghetti, guanciale, egg, and pecorino is down; the live food-cost number reflects it; the reorder math sees the real number.
- If something's off — the platform amends it (reverse + re-record), the month already closed (record in the next one), or the name didn't match a dish or stocked item (quarantine + flag for mapping).
At month-end none of this is recalculated — it was recorded as it happened. The close simply reconciles what was recorded against the physical count.
See also¶
- Recipes & production — how a dish is unpacked into its ingredients, and how a stocked prep item stops the unpacking.
- Stock ledger — the journal every depletion is recorded in; why entries are reversed, never edited.
- Scope & locations — warehouse (where value lives) vs restaurant (whose P&L it is), stations and the per-restaurant station mapping, and the transfers that move commissary stock into a restaurant's stores.
- Costing & valuation — the average cost each depletion is priced at.
- Period close — the month-end close that reconciles these recorded depletions against the physical count.
- Financial boundary — the conceptual accounts these depletions roll up into (cost of goods sold, split into food and packaging) for export to the operator's accounting system.