User guide › Apps › Stock & warehouse
Stock is part of Point of Sale
There is no separate stock app to install. Warehouses, stock levels, counts, transfers and the movement history are all screens of the Point of Sale app, and they live under the POS menu in the sidebar. Install POS and you have them.
What varies is who can open which one. Each screen is unlocked by its own permission, granted per role under Settings → Module Access, so a stockroom colleague can count and receive without being able to sell, and a cashier can sell without being able to rewrite stock figures.
| Screen | What it does | Permission needed |
|---|---|---|
| Stock overview | Read-only: every product against every warehouse. | Access to POS |
| Count / Adjust | Set the on-hand figure for chosen products. | Count / adjust |
| Stocktake | Guided physical count of a whole warehouse. | Count / adjust |
| Import stock | Load opening balances from a spreadsheet. | Count / adjust |
| Transfer | Move stock from one warehouse to another. | Transfer stock |
| Receive | Book in a delivery. See Purchasing. | Receive stock |
Where the numbers live
Five tables sit under the POS menu and hold the raw data. You'll mostly work through the screens above, but it helps to know what's underneath.
| Table | Holds |
|---|---|
| Products | The catalog: name, SKU, barcode, price, cost, category, unit, tax rate — and the tracking switches. |
| Warehouses | Your locations: shops, stockrooms, vans. Name and code. |
| Stock | One row per product-and-warehouse pair, holding On hand, its Reorder point and when it was Last counted. |
| Stock movements | The history. One row for every change ever made, with a reason and a signed quantity. Nothing is edited in place. |
| Stock lots / Serial units | Batch and serial detail, for products where you've turned that on. |
When a figure looks wrong, open Stock movements and filter to that product. Every sale, refund, delivery, adjustment and transfer is there with a timestamp. The on-hand number is only ever the running total of those rows.
POS → Stock overview is the "where do I stand" screen: products down the side, warehouses across the top, on-hand quantity in each cell, then a Total and a Value column. A banner above the grid gives Total inventory value (at cost) for everything.
- Search by name or SKU and the category dropdown narrow the list.
- Low stock only keeps just the products sitting at or under their reorder point somewhere. Low cells are flagged in red with a warning triangle.
- A cell only counts as low if that stock row has a reorder point above zero. Leave reorder points at zero and nothing will ever be flagged.
- The page updates itself as sales and receipts happen — no refreshing.
- Open Count / Adjust in the header jumps straight to correcting something. It only appears if you have the count permission.
If the page says No warehouses configured yet, add one under POS → Warehouses first — stock has to live somewhere.
Setting your opening stock
The first thing most workspaces need: get today's real inventory in, once, without typing it product by product. POS → Import stock takes a spreadsheet.
- Pick the warehouse One file, one warehouse. Importing several locations means one file each.
- Paste or upload the CSV
Three columns —
sku,qty,notes— with notes optional. A first row containing the word "sku" is treated as a header and skipped. - Read the preview As you type or paste, the page counts valid row(s) and invalid row(s) and says exactly what's wrong with each bad one — missing SKU, a quantity that isn't a non-negative number, or no product matching that SKU or name.
- Label the batch Reference (optional) — something like "Opening 2026-01-01" — is stored against the movements so you can find this import again later.
- Import The button reads Import n row(s) and only submits the valid ones. It reports how many landed and how many were skipped.
Each row sets the on-hand figure for that product in that warehouse. A row saying 12 means "there are 12", not "add 12". Running the same file twice is harmless; running a file of deliveries against existing stock will wipe out what was already there.
Invalid rows are never submitted, so a file with mistakes in it partially imports the good rows. Fix the bad ones and paste them again — the re-import simply sets those products to the right figure.
Correcting a few products
POS → Count / Adjust is for the small, targeted correction: breakage, a miscount, a sample given away.
- Pick a warehouse and a reason Adjustment (correction) for routine fixes, Stock count (walkthrough) when you've physically counted, or Opening balance when you're establishing a starting figure.
- Add the products Search by name or SKU and click to add. Each line shows the Current figure so you can see what you're changing from.
- Type the new figure The New column is what there actually is — not the difference. Under Opening balance each line also takes a Unit cost, so the starting stock is valued properly.
- Note what this was Reference (optional) — an audit batch, a count sheet number.
- Apply Apply n adjustment(s). The difference between old and new is written to the movement history, so the trail survives even though you typed an absolute figure.
Lines where nothing changed are skipped rather than logged, so the history doesn't fill up with no-ops.
Running a stocktake
POS → Stocktake is the whole-warehouse version: count the shelves, type what you found, look at the variances, post them.
- Choose the warehouse and load the sheet Load count sheet builds a line for every active product with the system's expected figure pre-filled.
- Decide whether to count blind Blind count on hides the Expected and Variance columns while you're counting, so nobody is nudged toward the number the system already believes. Turn it off afterwards to review.
- Enter what you counted Filter products… jumps to a line without scrolling. Lines that differ from expected are highlighted, and the Variance column shows the gap — positive in green, negative in red.
- Review before posting The footer counts n line(s) with a variance. That's exactly what will be posted; anything you didn't change is untouched.
- Post Post n variance(s) writes the corrections and reloads the sheet so it now reflects the counted figures.
The sheet snapshots what the system expects at the moment you load it. If sales keep ringing on that warehouse while you count, a variance you post may be correcting a figure that moved underneath you. Count outside trading hours, or reload the sheet immediately before posting.
Posted variances aren't free — they land in the ledger as an inventory write-off or gain if you're running perpetual accounting. See Accounting.
Moving stock between locations
POS → Transfer shifts stock from one warehouse to another. Pick From and To — they have to differ — then add products.
- Each line shows what's Available at the source and takes the quantity to Transfer.
- Ask for more than there is and the page warns you up front: the transfer would be refused, so lower the quantity or split it into two transfers.
- Reference and Notes are there for the transfer order number, the driver, the vehicle.
- Transfer n line(s) commits it. Each line produces two entries in the history: out of the source, into the destination.
A transfer is checked in full before any of it happens. If one line is short, the whole transfer is refused — you never end up with stock that left one warehouse and never arrived at the other.
What moves the numbers
Every stock figure is the sum of its movement history. These are the reasons you'll see there, and what causes each one.
| Reason | Written when | Direction |
|---|---|---|
| Sale | A sale is completed at the register, or a restaurant tab is settled. | Out |
| Return | A receipt is refunded, line by line. | In |
| Receipt | A delivery is received — see Purchasing. | In |
| Adjustment | Count / Adjust, a posted stocktake variance, or a stock import. | Either |
| Transfer | A transfer between warehouses — one row out, one row in. | Both |
| Void/Refund | A sale is reversed in full. | In |
Manufacturing moves stock too — components are issued out and finished goods received in as work orders progress. See Manufacturing, and Stock lifecycle for how the whole chain fits together.
Why is my stock count wrong?
Start with Stock movements filtered to the product — nine times in ten the answer is sitting in the list. If it isn't, work through these.
| Symptom | Likely cause |
|---|---|
| Sales aren't reducing stock at all | The product has no stock row for that warehouse, so it's treated as untracked — it sells fine and is logged for audit, but there's no balance to reduce. Give it a stock row (Count / Adjust or an import) and tracking starts working immediately. This is deliberate: services and made-to-order items shouldn't be forced into stock tracking. |
| Right product, wrong location | Stock is per warehouse, and a register only ever touches the warehouse it's bound to. A sale on the shop till can't reduce the stockroom. Check the register's Warehouse, and use the overview's per-warehouse columns rather than the Total. |
| On hand has gone negative | That register has Allow overselling switched on, which lets a sale go through below the available quantity. Useful for backorders; misleading if nobody meant to enable it. |
| An import halved / doubled everything | Import and Count / Adjust set the absolute figure. A file of delivered quantities imported over live stock replaces it rather than adding to it. Post the delivery through receiving instead. |
| Some rows in a file didn't import | They were listed as invalid and skipped — unknown SKU, blank SKU, or a quantity that isn't a number. The preview names each one. |
| Products the store sells aren't in the count sheet | Products with Active in POS switched off are left out of the stocktake sheet — and out of Count / Adjust. Switch the product back on, or set its figure through Import stock, which does include inactive products. |
| The counted figure was right, then drifted | Sales kept happening during the count. Last counted on the stock row tells you when the figure was last established. |
| Two people corrected it at once | Absolute-quantity edits are last-one-wins by design. Whoever pressed Apply second set the figure. The history shows both. |
Typing over a quantity in the Stock table changes the number without explaining it. Use Count / Adjust or Stocktake — they set the same figure but leave a dated, reasoned entry in the history, which is what you'll want the next time someone asks.
Lots, expiry and serial numbers
Two optional switches on a product turn on deeper tracking:
- Track by lot/expiry — receiving captures a lot or batch number and an expiry date, and sales relieve the earliest-expiring batch first. The batches are listed under POS → Stock lots.
- Track by serial — receiving registers individual serial numbers and sales mark them sold. They're listed under POS → Serial units.
Both are off by default and only worth turning on where they earn their keep — pharmacy, food, warranty-tracked equipment. The aggregate on-hand figure keeps working exactly as before either way.
Products can also be bought in one unit and sold in another: set a Purchase unit and Units per purchase unit and receiving in cases converts to singles automatically, cost included.
What stock is worth
The overview's Value column and the total banner value your inventory at cost. How that cost is worked out is a workspace-wide choice under Accounting → Settings → Inventory method:
| Costing method | How it behaves |
|---|---|
| Weighted average | The default. Every delivery blends into one moving cost per product, and each sale relieves stock at that average. Nothing to reconcile per batch. |
| FIFO / batch layers | Stock is held in dated cost layers and each sale relieves the oldest first — or the earliest-expiring batch for lot-tracked goods — at what that batch actually cost. For distribution, wholesale and pharma, where "what did this batch cost" matters. |
On FIFO, the stock overview grows a Batch cost layers (FIFO) panel listing each open layer with its received date, lot, expiry, quantity left and unit cost, plus a layer total that reconciles to the Inventory account. Average workspaces don't see the panel at all.
Switching to FIFO seeds opening cost layers from your current on-hand stock at each product's current average cost, so nothing is left un-costed — the app tells you how many it created. You can switch back. The same settings section also controls whether sales post cost of goods sold to the ledger as they happen (Perpetual) or not (None / periodic).
Being told before you run out
Set a Reorder point on a stock row and two things follow: the cell is flagged in the stock overview, and once a day admins get a notification saying how many products are at or below their reorder point, linking straight to the overview.
If you use lot tracking, a second daily notification flags batches that are expired or expiring within 30 days and links to Stock lots. Both are summaries — one message covering everything, not one per product.
Restocking
Putting stock in is the purchasing side of the same app: raise a purchase order, receive the delivery against it, store the goods receipt, and return anything faulty to the supplier. Receiving is what writes the Receipt movements you see in the history, and it's also where landed costs — freight, duty — get spread across the goods.
All of it is covered in Purchasing & suppliers.