Stock Adjustments
Taking stock out for wastage, spoilage and shrinkage, the reason codes that feed the Shrinkage report, correcting a wrong figure, and who is allowed to do it.
7 min read · Updated 28 Sep 2026
On this page
An adjustment is how you tell Kassly that stock left without a sale — it went in the bin, it broke, it walked, or the number was wrong to begin with. It is free on every plan and it lives on the same form as receiving: Inventory → Stock Levels → Stock Adjustment.
The three types, and which one you want
| Adjustment Type | What it does |
|---|---|
| Stock In (add inventory) | Adds to the current figure |
| Remove stock (waste, damage, theft) | Subtracts from the current figure |
| Physical Count (set absolute quantity) | Replaces the current figure with the number you type |
Adjustment only ever removes. Whatever you enter is taken off, so there is no way to add stock with an Adjustment. To add, use Stock In. To land on an exact figure without working out the difference, use Physical Count.
Physical Count here is the blunt version: it sets one item at one branch to one number, immediately, with no review. The governed version — count a list of items, get a variance report, have a manager approve anything unexpected — is Stock counts.
Pick a reason
Every removal and count carries a reason, picked from a fixed list, so waste, damage and theft can be added up instead of read out of free text.
| Reason | Use it for |
|---|---|
| Damaged | Broken, crushed, torn: it can't be sold |
| Expired | Past its use-by or best-before date |
| Spoiled | Went bad before its date: left out, fridge failed, pests |
| Theft | Taken without being paid for, or a count that's short and can only be theft |
| Sampling | Tastings, demo units, staff trials |
| Correction | The figure was wrong to begin with (a miskeyed receipt, the wrong unit) |
| Other | Anything else. You must say what in the note |
On a Remove stock the reason is required. On a Physical Count it is optional, because a count usually corrects the number rather than explains a loss. Stock In has no reason.
The Notes field is still there, next to the reason, for the detail the code can't carry: "Dropped a case unloading the van". A note is required when the reason is Other, and on a Physical Count that has no reason. Otherwise it is optional. Up to 500 characters.
Reasons and notes appear in Stock Movement History on the product page and in the export, next to the quantity and the person who made the change. The reasons are totalled in the Shrinkage report.
Older app versions don't send a reason. A removal recorded from a phone or desktop app that hasn't been updated still works: it saves with its note and no reason. It shows as Not specified in the Shrinkage report. So do removals recorded before reasons existed.
Filling in the form
| Field | Required | Notes |
|---|---|---|
| Branch (or Location) | Yes | Adjustments are per branch. With the Warehouse Management add-on and View Warehouses, the field is called Location and also lists your warehouses; see Warehouses. |
| Product | Yes | |
| Adjustment Type | Yes | |
| Variant | Only if the item has variants | |
| Quantity | Yes | For Remove stock, the amount to remove. For Physical Count, the figure to land on. |
| Unit | — | Packaging units are offered if the item has them; the figure is converted to the item's stock unit. |
| Cost per unit | No | Per the unit picked; converted to the item's stock unit. See Receiving stock. |
| Reason | Yes for Remove stock; optional for Physical Count | See Pick a reason. |
| Notes | Only when the reason is Other, or a Physical Count has no reason | Up to 500 characters. |
Batch and expiry fields are not offered on an Adjustment — they only appear for Stock In. You do not need them to write off an expired batch: a removal comes out of the batches earliest expiry first, so expired batches are emptied first. See Batch & expiry.
For a serial-tracked product, a Stock In takes one serial per unit and a removal can name the serials that went. See Serial & IMEI tracking.
An adjustment cannot go below zero
If the removal would take the branch below zero, Kassly refuses it and tells you what it has: Insufficient stock. Current: 4, requested: 10.
That is a guard rail, not a bug to work around. A branch showing 4 when the shelf holds 10 means an earlier delivery was never recorded — fix that with a Stock In or a Physical Count rather than shaving the write-off down until it fits.
Sales are different: a sale always takes its full quantity, so an item can be below zero already (see When stock goes below zero). You can't remove more from an oversold item. Record a Physical Count with what is really on the shelf, or a Stock In for the delivery that was missed.
Nothing is ever edited
Every adjustment writes one Adjustment movement — an immutable row carrying the quantity, the branch, the note, the time and your name. Movements cannot be edited or deleted, by anyone, including support.
The practical consequence: you correct a mistake by making a second movement, not by fixing the first. Removed 100 when you meant 10? Stock In the 90 back with a note saying so. Both rows stay in the history, which is exactly what you want when someone asks what happened.
Who is allowed to adjust
| Where | Who |
|---|---|
| Web | Owner and Manager |
| App | Owner and Manager. Lower roles see Requires manager approval. and a manager PIN prompt. |
The custom-role permission for this work is Stock In / Adjust Inventory
(stock.manage) — see Custom roles.
Granting that permission to a cashier does not currently work for adjustments. The server still requires the signed-in account to be an Owner or Manager, so a cashier holding the permission passes the app's PIN prompt and is then refused. Until that changes, adjustments have to be made from a manager's account.
Everything is attributed either way: the movement records the account that made it, and adjustments also appear in the audit trail. See Audit logs.
Recipe waste is a different thing
If you run recipes, you will meet a waste percentage on each ingredient line. That is not an adjustment and it is not wastage you record after the fact — it is the trim, peel and spillage built into the recipe, applied automatically on every sale. It is explained in Ingredients & recipes.
Use an adjustment for the wastage nobody planned. Use the recipe's waste percentage for the wastage that happens every single time you cook the dish.
Seeing what you wrote off
Reports → Shrinkage totals what you wrote off, by reason, by product and by branch, with the cost value lost for anyone allowed to see cost prices. Count shortfalls from Stock counts are in there too. See Inventory reports.
Removals reach your books too. From the day this update reached your store, each removal posts to the general ledger and shows on the Profit & Loss under Stock written off or found, at the item's cost at the time (or the cost you typed). The reason picks the account: spoiled and expired to Inventory Spoilage & Expiry, damaged to Inventory Damage, sampling to Samples & Internal Use, anything else to Inventory Shrinkage. A quick count that comes in higher posts to Inventory Count Gains. Earlier removals are not posted, so closed months do not change. Stock-ins never post here. See Chart of accounts.
Removals are outflows, so they also show up in the Stock Consumption panel alongside sales and transfers. That panel answers "what did we get through" rather than "what did we lose". See Stock levels for how to read it and what it costs beyond today.
Where to go next
- Stock counts — the reviewed way to correct figures
- Stock levels — the ledger and its movement types
- Inventory reports — the Shrinkage report
- Receiving stock — the other direction