Editing an inventory item
Every row in the inventory list opens here. The detail page is where the kitchen and the books agree on what one thing in the pantry actually is: what it’s called, what supplier brought it in, what one unit of it costs right now, how much of it is on the shelf, how much should be. One row, one set of numbers, edited from one place.
This page is for two readers. If you’re the owner, “Why this page exists” is for you — start there. If you’re the head chef, jump to “What you can edit” and skim down to “Worked example”.
Why this page exists
The inventory list is a map. The detail page is the legend. The list tells you, at a glance, what the kitchen has and what’s running thin — but it doesn’t tell you why the cost of the tagliatelle al ragù moved from 32% to 37% last Friday. The detail page does: open the row, look at the cost history, see the supplier change, see when it happened. The reason lives here, on the item.
The other reason this page exists is leverage. Most numbers in the system are derived from numbers on these rows. The cost-per-portion of a dish is built from the cost-per-unit of its ingredients. The food-cost percentage on the dashboard is built from the cost-per-portion. The reorder shortlist is built from the par level. Change a number here and four screens elsewhere reconcile in seconds. The detail page is small; what it controls isn’t.
The rule
The item is the only place a number lives once. You change the supplier, the par, the unit, the cost here — and inventory, recipes, dashboards, and the till all reconcile from this single edit. Two rows holding the same number is a bug, not redundancy.
What you can edit
The form is grouped into a handful of themes. Most days you’ll only touch one or two fields; the rest stays as it was when the row was first set up.
Identity. The Name is the canonical label every other screen refers to. The Type chip — L1 raw materials you buy, L2 preps the kitchen makes, L3 finished items the till sells — drives where the row shows up in the recipe-output picker and the inventory grouping. The Category is the catalogue the list groups by. On items you buy from a supplier you’ll also see a Brand and a Supplier code (the supplier’s own product code, used by the receiving scanner to match deliveries back to this row). On a generic ingredient — a row that wraps multiple supplier products under one canonical name — Brand and Supplier code are hidden, because those values live on the supplier products underneath, not on the wrapper.
Stock and sourcing. The Preferred supplier points at the supplier the kitchen normally orders from. Changing this field re-runs the cost roll-up using the new supplier’s last price and pack data — every recipe that uses this item picks up the new cost on its next read, without anyone editing a recipe. The Current stock is what’s actually on the shelf, in stock units (bottles, jars, sacks — the thing you pick up). The Par level is the target the kitchen wants to always have on hand; rows that fall below par show on the daily reorder shortlist. The Storage location drives the storage-filter chip on the list, drawn from the catalogue at storage locations.
The Stock unit and the Recipe unit are two different ways of counting the same thing — bottle and ml for wine, tin and g for tomatoes, each and g for eggs. The Conversion between them (1 bottle = 750 ml, 1 tin = 400 g, 1 egg = 60 g) is what lets the kitchen count in bottles and the recipes consume in millilitres without anyone doing the maths twice. Most of the time the defaults are right and you leave them alone; the advanced section lets you override when how you count differs from how you store.
Cost. The Last purchase price is what you actually paid most recently, promotion included. The system uses this plus the pack chain (pieces per purchase unit, net weight per piece) to compute the cost per recipe unit — the small number on the right of the price field, the one recipes consume. A separate Regular list price records the non-promo price; when it sits higher than the purchase price the row counts as promo-active until Promo ends. The Yield percentage is the fraction usable after trim and cook loss — a beef shoulder might be 94% usable, and the system multiplies it into the recipe cost so the trim isn’t free. When the supplier prices an item by weight rather than by the pack — most cheese, cured meat, fish and deli — a small Priced per switch above the price lets you type the figure exactly as the invoice reads it; the next section walks through it.
Recipe link (read-only). For L2 preps and L3 finished items, the row is produced by a recipe. The link shows in the detail header as a chip you can tap to jump to the recipe; the field is read-only on the edit form because the recipe owns the relationship. To re-point — change which inventory row a recipe produces, or absorb a duplicate — use re-pointing inventory links.
Lifecycle. A row can be Active or Archived. Archiving hides the row from the inventory list and the recipe pickers and unlinks every approved supplier product underneath, sending them back to draft. The toggle is reversible — flip it back on and the row reappears, though you’ll need to re-link the suppliers. When the row is a duplicate of another live one, use Merge instead: it moves every live pointer (recipes, supplier products, menu items, modifiers, decomposition children, stock) from the duplicate to the survivor, then archives the duplicate, atomically, with an audit entry on both sides.
Custom fields. Each inventory category can declare extra fields the row carries — grape variety on wines, milk type on cheeses, origin region on olive oils. They show up only when the category has a schema attached, and they’re the extension point for category-specific information the rest of the system reads later (allergen badges, AI menu copy, sourcing reports).
Priced per kilo, sold by the pack
A whole class of ingredients is billed by weight but delivered in packs. Your buffalo mozzarella arrives as a 250 g packet — two 125 g balls — but the invoice doesn’t say “฿171.56 per packet”, it says ฿686.25 per kilo. Fresh-cut cheese, prosciutto, salmon sides, olives from the deli counter: the price list quotes a per-kilo figure, and the pack you actually receive weighs whatever it weighs.
The first instinct is to look for “kg” in Physical form — and it isn’t there, for a good reason. Per kilo isn’t a shape you pick up off the shelf; it’s only how the price is written. The thing you hold is still a packet. So the form keeps those two facts apart: you describe the packet once (a packet, 250 g inside), and you tell it the price the way the invoice reads it.
The rule. Per kilo is a price, not a package. Describe the real pack — what it is, what’s inside — then flip Priced per to match the invoice. Never reshape the pack to make the price fit.
That switch sits just above the price field and only shows up when the item is weighed (it stays hidden for things you count, like eggs). It has two settings:
| Priced per | When to use it | What you type |
|---|---|---|
| per packet (or per box, per case…) | One fixed price for the whole thing you pick up — a €4 jar, a €30 case | The price of one of those |
| per kg (or per L) | The invoice quotes a weight — most cheese, cured meat, fish, deli, loose produce | The per-kilo figure, straight off the invoice |
Flip it to per kg and the system does the arithmetic you used to do in your head: it reads the net weight you already entered, works out what one packet costs, and shows it back to you on the line underneath — = ฿171.56 per packet. The cost-per-gram it feeds to recipes is identical either way; the difference is that your stock now counts packets correctly instead of believing each one weighs a kilo.
Worked example
Marco sets up the buffalo mozzarella. Physical form: packet. Net weight per packet: 250 g (the two balls together). Recipe unit: g, because the kitchen weighs it onto the caprese. Then the price. The invoice says ฿915/kg list, ฿686.25/kg on this week’s promotion — so he flips Priced per to kg and types those two numbers exactly as they’re printed. The card updates live: ฿686.25 per kg, and below it = ฿171.56 per packet, and below that → ฿0.686 per g — the number every recipe pulls. The packaging line reads 1 packet › 250 g › 250 g total. Count eight packets in the walk-in and the stock value reads two kilos, not eight. Next month the promotion ends; Marco opens the row, sees ฿686.25 per kg waiting exactly as he left it, and changes the one number — no multiplying, no guessing which figure was which.
How to use it
Tap a row in the inventory list and the detail page opens. The top shows the basics — name, type chip, category, current stock, par, cost per recipe unit — alongside a row of tabs: Overview, 🚛 Suppliers, Recipes, Production, Analytics, Procurement, Waste, Stock counts, AI, Media, History. The Overview tab is where you land; the others are read-only slices of the row’s life (cost history, deliveries, waste events, every recipe that consumes this item).
To change something, tap Edit at the top right and the form opens. Every field with a non-obvious meaning has a small ⓘ icon next to its label — tap for a plain-English explanation. Make the change, tap Save; tap Cancel to discard.
A typical edit — the kitchen wants to switch the preferred supplier on the San Marzano tomatoes row because the regular supplier ran out — runs like this. Open the row, open the 🚛 Suppliers tab, find the alternative in the list of approved products, tap Set as preferred. The detail header refreshes with the new cost, every recipe that consumes the row recomputes, and the dashboard’s food-cost figure on the affected dishes settles to the new number, usually before the next breath. If the alternative isn’t in the list yet, tap + Link a supplier product to pull in a draft, confirm the pack data, and approve.
The other common path — raising a Par level because demand jumped — is even simpler. Edit → bump the number → Save. The next list refresh re-evaluates the row against the new par; if it’s now below, it appears on the Below par shortlist and the daily reorder message.
What happens behind the scenes
Save writes only the fields you changed. The system checks whether any of them feed the cost roll-up — purchase price, pack chain, recipe unit, supplier — and if so, recomputes the cost per recipe unit on this row in the same save.
From there a cascade fires. The system walks every recipe that uses this item as an ingredient, recomputes its total cost and cost-per-portion against the new value, writes both back. For preps (L2 items produced by batched recipes) the cascade keeps going: the prep’s new cost-per-unit means every recipe that consumes that prep recomputes too, and so on, until the chain runs out. Menu items that point at any of these recipes pick up the fresh food-cost percentage on the next dashboard load. None of the downstream rows are hand-edited; they all pull from the chain.
Editing Stock behaves differently — it doesn’t ripple, because stock is a count of physical reality, not a derived number. It does update the Below par flag and the stock-value figure on the row. Editing Par level is the same shape: instant on the list, no cascade. Editing the Unit of an existing row is the most delicate change: past stock numbers don’t auto-rescale, so set the unit at creation and leave it alone unless you’re actively reconciling.
Every meaningful change writes an entry to the History tab — old value, new value, who, when. The history is both a debugging tool (“the carbonara food cost jumped on Tuesday — why?”) and the audit trail when a number on a dashboard surprises you.
Worked example
Sara runs the kitchen at your venue. It’s Monday morning. The new price list from her main cheese supplier just landed and her stomach drops: Pecorino Romano DOP has gone from €18/kg to €23/kg — a 28% jump on one of the load-bearing ingredients of the menu’s most-ordered dish, Mezze Maniche Cacio e Pepe.
She opens /admin/inventory, types pecorino into the search, taps the row. The detail page tells her what she needs in one glance. Cost per recipe unit: €0.018/g, sourced from the current preferred supplier at €18/kg. Linked recipes: Mezze Maniche Cacio e Pepe (40 g per portion), Tonnarelli Cacio e Pepe (35 g), Spaghetti alla Gricia (15 g as a finish). One portion of the mezze maniche dish costs €0.72 in pecorino today; the dish costs €1.33 in total and sells at €18, food cost around 7.4%.
Sara taps Edit, types the new price into Last purchase price — €23/kg — and saves. The header refreshes: cost per recipe unit now reads €0.023/g. She switches to the Recipes tab and watches the Mezze Maniche Cacio e Pepe line settle to a new portion cost of €1.53 (40 g × €0.023 = €0.92 of pecorino per portion, up from €0.72; pasta and pepper didn’t move). Food cost on the dish climbs to 8.5%. Small in absolute terms because the dish is high-margin, but on ~40 portions a week the kitchen plates, that’s €8 of margin a week, ~€416 a year, on this dish alone.
She doesn’t accept the new price yet. She opens the 🚛 Suppliers tab on the same row and finds the secondary supplier she approved last quarter — a smaller dairy carrying Pecorino Romano DOP from a different producer at €19/kg. She taps Set as preferred. The cost re-derives from the secondary supplier’s pack data: €0.019/g. The Mezze Maniche Cacio e Pepe portion recomputes to €1.37; food cost lands at 7.6%, a hair above where it was Friday. Sara orders the next batch from the secondary supplier, tastes it on Tuesday’s service, and decides whether to stay or switch back. The History tab on the row remembers exactly what happened — supplier change, price change, recipe ripple, dashboard ripple — in order.
One row edited, four places reconciled.
Related features
- Inventory — overview — the entry point the list this page is reached from
- Recipes — how the kitchen turns ingredients into a costed output — the recipes that consume this row, and where the cost flows next
- Inventory categories — the catalogue the Category field picks from, and the source of custom fields for things like wine grape or cheese milk type
- Storage locations — the catalogue the Storage location field picks from
- Re-pointing inventory links — the two surgical operations: re-pointing which inventory row a recipe produces, and merging two duplicate rows into one
- Stock counts — the periodic audit that resets the Current stock field when reality and the row drift apart
- Waste log — taking stock down without a sale (spoilage, breakage), recorded against this row
- Separations — when one row splits into several children (whole egg → yolk + white), configured on the parent row’s decomposition rule
- Product samples — the parallel ledger for free or paid samples a supplier sends, kept apart from live stock until you decide to convert one into a row here
- What shows up in the inventory list — the rule that decides which rows the list shows (linked to a supplier, produced by a recipe, or a child of a separation)
- Adding photos to inventory items — the Media tab on each item; the starred photo becomes the row thumbnail across the list, the header, and hover previews
- Beverage Margins and Food Margins — where this row’s cost shows up alongside the POS sell price; one screen for the monthly cost pass
- Where your information lives — the five rooms of the system; this page edits a row in the pantry
- Prices, costs, and margins — the broader rule about how the cost number you set here cascades through three different prices