Wastage and spoilage
Route: /org/inventory/maintenance — the same screen as
Stock adjustments, in a different mode
1. What wastage is
Stock that existed and is now unusable: spoiled, expired, broken, dropped.
| Adjustment | Wastage | |
|---|---|---|
| Answers | The count is wrong | The stock is gone |
| Direction | Either way | Down only |
| Ledger type | ADJUSTMENT | WASTAGE |
| Card badge | — | − |
| Implies | A counting error | A real loss |
Both modes share the entry grid, the reason field and the batch behaviour. The difference is the sign and the transaction type — and, more importantly, what the entry asserts. An adjustment says your records were wrong. A wastage says your records were right and the stock has been destroyed.
Using the wrong one produces the same net stock effect and a misleading audit trail.
2. Recording wastage
Choose Wastage / Spoilage → Raw Materials or Finished Goods on the chooser, then enter the wasted quantity per line.
| Field | Required | Notes |
|---|---|---|
| Wasted quantity | per line | Recorded as a negative delta |
| Reference | — | e.g. WST-2607-14 |
| Reason | ✅ | Free text — the picker is always empty |
| Remarks | — | Where the real explanation goes |
Validation — exact strings
| Condition | Message |
|---|---|
| Nothing entered | Enter at least one wasted quantity |
| No reason | Pick or type a reason for this entry |
| Success | Wastage / Spoilage posted • N items |
3. Reason wording matters more here
Because the reason master list is empty and cannot be populated, wastage reasons are whatever people type. On the reference tenant they read:
Spoilage — cold chain break, remarks "Chiller failure overnight; batch discarded"Expired stock, remarks "Past shelf life at morning check"
There is no reason taxonomy, no report that groups by reason, and no validation. If you want to know how much you lost to refrigeration failures this quarter, the only path is exporting the ledger and grouping the free text yourself — and the ledger's Export button does nothing.
Agree a fixed set of reason strings before people start typing.
4. What wastage writes
One WASTAGE ledger row per line, quantity negative, sharing a batch_id, remarks encoded as
[REASON:…] <notes>.
maintenance.waste is never checkedThe permission exists and can be granted. No route and no component reads it — wastage is gated by
maintenance.adjust, the same permission as a counting correction.
You cannot give someone the ability to correct a count without also giving them the ability to write stock off. See Permissions.
Like every other operation on this screen, wastage does not change current_stock.
5. Troubleshooting
| Symptom | Cause |
|---|---|
| Cannot enter a positive number | Correct — wastage is decrement-only |
The entry posted as ADJUSTMENT | The adjustment mode was chosen on the chooser |
Someone with only maintenance.waste cannot post | That permission is not enforced; they need maintenance.adjust |
| Reasons are inconsistent across the team | The picker is empty by design failure — see §3 |
| Stock level unchanged | Wastage writes the ledger only |