How destroyed stock is written off, why a big write-off waits for a second person, and what rejecting a note actually does to the ledger.
Why waste gets its own document
Most things a phone can capture post straight to the ledger. Waste doesn't always, and the reason is arithmetic. The variance report works out actual usage as the opening count, plus purchases, plus transfers in, minus transfers out, minus waste, minus the closing count. Waste is a term in that equation. Fifty bottles written off as breakage cancel fifty bottles that walked out the back door exactly, and the loss leaves the report relabelled as explained. Waste is the one paper channel a loss can hide in, so it carries a closed list of reasons, a threshold in shillings, and a second person above it.
The Waste page under Inventory needs one of record_waste, approve_waste or view_inventory. Recording needs record_waste, which the Storekeeper, Chef, Bar Manager and Outlet Manager roles hold by default. Deciding needs approve_waste, which among the seeded roles only the Outlet Manager and Admin hold. See Roles & Permissions.
Recording a write-off
Record waste opens a form: an outlet, one storage location, then lines. One location per note, like a count, because the value is worked out at that location's average cost and variance is reported per location. Each line names an item, a quantity in the item's stock unit, a reason and an optional note. One reason per line, so a single bin-run across three causes is one note with three lines, not three notes.
The reason list is fixed, with eight entries: Spoilage, Expired, Breakage, Spillage, Preparation error, Fridge / power failure, Pest damage, and Other (note required). What's missing is the point. There is no theft, because theft is what variance exists to expose. No staff meals, because those are zero-value sales lines. No over-portioning, because over-portioning is the variance. "Other" exists so a closed list never forces a lie, and it costs a note; the server refuses a bare one with 'A line recorded as "other" must say what happened.'
What the form and the server check:
- Quantities are magnitudes and must be above zero. There's no way to type a negative line, because a negative waste line would be a way to add stock through a write-off screen. The server puts the sign on the movement.
- A discontinuing item can still be written off. Clearing the last of a line you stopped stocking is exactly what happens after you stop stocking it, and it is one of the ways a run-down finishes. See Replacing & Retiring Items.
- Items that aren't stock-tracked are refused, since there's no balance to reduce.
- A note can't be dated more than a day ahead: "Stock cannot be written off in the future."
Below the lines there's a note for the reviewer and a photograph field. Attaching a photo from the browser needs manage_files; if your role lacks it the form says so and points you at a device that can, because the rule can't be skipped from the form.
The threshold
Every line is valued at the weighted-average cost prevailing at that location when the stock was destroyed, and the note's total is measured against the company's Approval threshold (KES), set on the Inventory Policy tab of Company settings. The default is KES 5,000, pitched so a crate of beer gets a second look and a broken glass doesn't. The capture form shows the figure at the top before you type anything.
Two paths from there:
Below the threshold, the movements post in the same transaction as the capture. The stock is already in the bin; holding the posting would leave the books carrying product that isn't there. The note lands as Posted and the toast reads "WST-000031 captured and posted".
At or above it, nothing posts. The note lands as Awaiting approval, the stock is gone from the shelf but still on the books, and it stays that way until somebody other than the recorder accepts it. Set the threshold to zero and every note waits.
There's a third route into the queue: a note whose value can't be computed. If any line's item has never been valued at that location, that line's cost is unknown, so the total is unknown, and the note goes for approval whatever its size. The list shows a dash in the Value column for these, never a zero, because "we can't say what this was worth" deserves more scrutiny rather than less.
The value and the threshold in force are both snapshotted on the note. The detail page shows "Threshold when captured", so "why did this one need approval" stays answerable a year later, after the setting has moved.
The photo rule
Require a photograph on every waste note is a checkbox on the same settings tab, off by default. When it's on, a note without a photo is refused: "This company requires a photograph on every waste note." The setting's own hint warns you before you tick it: uploads don't ride the offline outbox, so switching it on makes waste capture from the web need a working connection. On the phone the photo queues beside the note and goes up when signal returns.
The detail page shows "Photograph on record" when one is attached. There's no link to view it yet; the API has no route that turns a stored file id back into an image, and the page won't guess at one.
The list
Four tabs, with the tab and filters in the URL: Awaiting approval (oldest first, because every day a note sits there is a day the books knowingly overstate the shelf), Posted, Rejected and All. An outlet picker appears when you have more than one outlet, alongside From and To dates. Export downloads the tab you're on, value column included, which is the column that file exists for.
Deciding a pending note
Open a pending note and the amber banner says it plainly: nothing has posted, and the books won't say so until somebody other than the recorder accepts the write-off. If the value couldn't be computed, the banner says that too.
Holders of approve_waste get Approve and Reject:
- Approve posts the movements dated at the time the stock was destroyed, moving the loss into the explained column of the Variance report.
- Reject posts nothing and needs a reason: "A rejected waste note must say what was wrong with it." The loss stays where an unaccepted explanation belongs, in variance at the next count.
The person who recorded the note can't decide it, whatever their role: "You recorded this waste, so somebody else has to accept it. A write-off its own author can approve is not evidence of anything." That refusal renders next to the buttons rather than in a toast.
Rejecting a note after it posted
A below-threshold note is Posted the moment it's captured, and an approve_waste holder who didn't record it can still reject it. Rejection reverses each line's movement: a new opposing row in the ledger pointing back at the original, with the reason recorded as "Waste note WST-000031 rejected:" followed by what you wrote, and the note marked Rejected. Nothing is erased. Both rows stay in the ledger forever, which is how every correction in this product works; see Stock on Hand.
Two refusals guard this route. Approving a note already in the ledger gets "This note was under the approval threshold and has already posted." And once a person has accepted a note, it's final: "This note has already been accepted. Reverse its movements instead." Undoing an accepted write-off is a ledger reversal by whoever holds reverse_stock_movement, done from the Movements screen.
Prefer rejecting through the note over reversing its movements directly. The Movements screen's own reversal dialog says as much: rejection through the note keeps the document and the ledger agreeing.
On the phone
The mobile Record waste screen (behind record_waste) works offline. Pick the location, add items with a reason chip each, attach a photo if your company requires one, and save. The note queues in the outbox and syncs when there's signal, carrying its own operation id so a double sync posts once. The screen shows your company's threshold beside the save button. Deciding a pending note is in the phone's Approvals hub under Waste notes, for approve_waste holders.
FAQ
A fridge died overnight and we lost KES 38,000 of meat. Is there a special workflow? No, and deliberately not. That event is a waste note: many lines, one location, the "Fridge / power failure" reason, a photograph, and a value that will certainly cross the threshold and wait for a second person. A dedicated screen would only add a sheet pre-filled with what the ledger thinks is in the fridge, which is a write-off by button press.
Can I split a KES 9,000 write-off into two notes to stay under KES 5,000? The system won't stop you; the control here is the second person, not a spend limit. But the two notes sit side by side in the Posted pile, same location, minutes apart, and anyone reading the list can see it. Splitting tends to get noticed in exactly the review you were avoiding.
Why is my note waiting for approval when it's only a few hundred shillings? Because its value couldn't be computed. At least one line's item has never been valued at that location, so the total is unknown rather than small. Receive the item on a priced GRN or cash purchase at that location and future notes will value normally.
We threw out staff meals. Which reason do I pick? None. Staff meals are authorised consumption, not destroyed product; through waste they'd overstate waste and misstate food cost. They belong in the sales import as zero-value lines so theoretical usage accounts for them.
I approved a note by mistake. Can I reject it now?
Not through the note; an accepted note is final. Ask whoever holds reverse_stock_movement to reverse its movements from the Movements screen, with a reason written for whoever reads the ledger later.