Omnix
All docs
Core

Receiving stock

Manual receive vs PO-receive vs reverse-GRN. How batches get created, when stock_qty updates, what each path means for your books.

Receiving stock is the single most-used flow after the till. There are three paths, and they all create the same downstream effect: a new `batches` row, a stock_movement record, and an updated supplier balance. Where they differ is the audit trail and what happens to the related PO.

1. Manual receive (no PO)

Use this for petty replenishment — e.g. you bought a box of chewing gum from the kiosk next door for the till. Open Inventory → Products → Receive Stock, search for the product, set quantity + unit cost + batch number + expiry. Click Save. Omnix inserts a batch and increments the on-hand count.

There is no PO, no GRN, no three-way match — just a stock movement of type `purchase` with reference_type `manual_receive`. Use sparingly; for anything bigger than a single SKU you want a PO.

2. Receive against a PO

The standard flow. Open Purchases → the PO → Receive. The dialog pre-fills line items from the PO, lets you edit received quantity per line (so partial receipts work), records the supplier invoice number for three-way match, and creates the GRN.

What gets written: - A `goods_receipts` row with a sequential GRN number (GRN-XXXXX) - One `goods_receipt_items` per received line - One new `batches` row per product (so you can FIFO out of it later) - One `stock_movement` per batch - Updated `received_quantity` on each PO line — the PO status flips to `partial` or `received` based on cumulative coverage - Supplier `balance_owed` increments by the GRN total

3. Receive from product detail (#42)

A shortcut: from any product detail page click the Receive stock button at the top right. The same dialog opens but with the product pre-loaded in the line list. This is the fastest path when you know exactly what you're receiving and don't want to hunt through the supplier's PO.

This path always adds to existing stock (it inserts a batch). It never overwrites the on-hand quantity — that's a deliberate guarantee, because overwriting would silently destroy older batches.

Reverse-GRN

If you discover a receiving error (wrong supplier, double-counted line, expiry typed wrong), use Purchases → GRN list → the GRN → Reverse. Omnix:

1. Refuses if any of the originally-received batches have been partially sold or transferred. Those goods are out of the warehouse — you need a stock adjustment, not a reverse-GRN. 2. Deletes the `batches` rows and corresponding `stock_movements`. 3. Resets `received_quantity` on each PO line item. 4. Recomputes PO status (likely back to `partial` or `sent`). 5. Decrements the supplier's `balance_owed`. 6. Stamps the GRN with `reversed_at` + `reversed_by` so the original record stays in the audit log.

What ends up in your books

Every receive path writes the unit cost into `batches.buying_price`. Every COGS calculation downstream — P&L, day book, top products, dead stock — reads from there. Get the unit cost right at receive time and your reports will be right forever.

Was this helpful?

If something is wrong or missing, WhatsApp the owner. We update the docs every time a real question comes in.

Receiving stock — docs · Omnix