---
title: In stock and arrivals
order: 3
updated: 2026-07-21
---

# In stock and arrivals

The *In Stock* screen is the inbound side of your warehouse: it tracks goods arriving from suppliers, from the purchase orders still awaiting delivery, through the arrivals waiting for a second person to approve, all the way to the full recorded history. Its page heading reads *In Stock* with the subtitle *Track arrivals, approvals, and stock movements*.

Everything on this page is re-checked on the server. A stock arrival never changes your on-hand counts by itself — it starts as *pending* and only moves stock once it is *approved*. That two-step design is deliberate: it keeps a forged or careless entry from silently corrupting the [Stock](/docs/inventory/stock-overview) snapshot.

## Open the screen

1. Open *Inventory* in the sidebar.
2. Click *In Stock*.

The page is deep-linkable. The active tab and every filter are written into the address bar (`?tab=…&supplier=…&cp=…&head=…&code=…`), so you can bookmark or share a pre-filtered view, and the browser back/forward buttons work correctly. The [Pending Transfer](/docs/inventory/transfer-stock) page, for instance, can link here already filtered.

## The three top tabs

A row of tabs sits directly under the heading. Which ones you see depends on your permissions (see [Who can see what](#who-can-see-what)).

### Pending Arrivals

Purchase orders that have been *sent* (or are *partially arrived*) and still have stock outstanding. The server lists only POs whose `currentStatus` is `sent` or `partiallyArrived` and that still have at least one line not fully received — once every line is covered, the PO flips to *arrived* and drops off this tab automatically.

Each row shows the *PO Number*, *Supplier*, *Supplier CP*, the *Products* still outstanding, an *Arrived* count, the *Total Qty* ordered, and the *PO Date* (the send date if present, otherwise the PO date). All dates here read as `dd mmm yyyy` (for example `24 Apr 2026`).

When a PO lists the **same product code on more than one line** — for example the same item under two different makes, prices, or quantities — each line is tracked independently. Only lines with a *remaining* quantity above zero are shown, and the *Arrived* figure is colour-coded: green when the line is fully received, amber when partially received, muted when nothing has arrived yet.

*View* opens the *Purchase Order Details* modal. From there, if you hold *Upload Stock Arrival From PO*, the top-right `⋮` menu carries an *Upload Arrival* action — see [Record an arrival against a PO](#record-an-arrival-against-a-po).

That same `⋮` menu also has *Toggle Columns*, which shows, hides and reorders the columns of the *Products* table below (*Head*, *Qty*, *Price / Unit*, *Discount*, *Tax*). *Code* always stays on, since it is what identifies each row. Your choice is remembered for next time, and *Reset* puts the columns back to their defaults.

### Pending Approvals

Arrivals that have been logged but are still waiting for an approver. This tab pins the sub-status to *Pending* and shows the same arrival list described below. Only users with *Approve Stock Arrival* see it.

### Arrival History

Every recorded arrival. A row of status sub-tabs sits above the list:

- *All* — always shown.
- *Pending (n)* — shown only when there are pending entries, with a live count. (On the *Arrival History* tab this sub-tab is hidden because pending entries live in their own top tab; it appears in the count logic but is filtered out of the History sub-tab row.)
- *Approved* — always shown.
- *Rejected (n)* — shown only when there are rejected entries, with a live count.

Each row carries the *Supplier* (with a *Return* chip on reverse entries), *Contact Person*, *Product* lines, *Qty*, *Invoice No.*, *Invoice Date*, *Status*, *Upload Date*, and a *View* button. Dates in this table read as `dd/mm/yy`. The list is paginated `20` rows per page.

## Who can see what

Tab and action visibility is gated by inventory permissions (a firm administrator always sees everything):

- *Pending Arrivals* — needs *View Pending Arrival POs* (`viewPendingArrivalPurchaseOrder`) **or** *Upload Stock Arrival From PO* (`uploadArrivalFromPO`).
- *Pending Approvals* — needs *Approve Stock Arrival* (`approveAddStockRequest`).
- *Arrival History* — the tab is always visible, but the arrival list only loads for users who hold *Create Stock Arrival Entry* (`generateAddStockRequest`) **or** *Approve Stock Arrival*. A user with neither sees the tab but an empty list.
- *Add Entry* (top right) — needs *Create Stock Arrival Entry*.
- *Send Arrival Receipts* (in the `⋮` menu) — needs *Send Arrival Receipt to Supplier* (`sendArrivalReceiptToSupplier`).
- *Deleted Arrival Logs* (in the `⋮` menu, History tab only) — firm admin, or *View Inventory Pages* (`viewInventory`).

**Generate-only gotcha:** a non-admin who can *create* arrivals but cannot *approve* them sees only **their own** entries in *Arrival History* — the server silently scopes the list to `generatedBy = you`. Approvers and admins see every user's entries.

## Filter the list

The *Arrival History* and *Pending Approvals* tabs share an always-visible row of four searchable filters. The *Pending Arrivals* tab has the same four, applied to pending POs.

### Supplier

Type to search suppliers by name. Clearing the supplier also clears the *Contact Person* below it (a contact person only makes sense within a supplier).

### Contact Person

Disabled until a supplier is picked, then scoped to that supplier's contact persons.

### Category (Product Head)

Type to search product categories (heads). Clearing it also clears the *Code* below it.

### Code (Product Code)

Disabled until a category is picked, then scoped to that category's codes. On *Arrival History* and *Pending Approvals*, filtering by code narrows to arrivals containing that exact code; filtering by category only (no code) narrows to arrivals containing any code under that head.

All four filters live in the URL, so they persist across a refresh and are shareable.

## Advanced filters (Arrival History and Pending Approvals)

Open the top-right `⋮` menu and choose *Advanced Filters*. A badge beside it shows how many are active, and a *Clear Advanced Filters* item appears alongside once any are set. These filters are not offered on the *Pending Arrivals* tab. The modal is titled *Advanced Filters* and adds what the inline row cannot express.

### Identifiers

- *PO Number contains* — keeps only arrivals whose linked purchase-order number contains your text (case-insensitive). Placeholder `e.g. PO-2026`.
- *Invoice Number contains* — keeps only arrivals whose supplier invoice number contains your text (case-insensitive). Placeholder `e.g. INV/042`.

Both are treated as user-supplied patterns but are length-capped at `100` characters and compile-checked on the server, so a malformed pattern returns a clean error rather than stalling the database.

### Date Ranges

Three independent from–to ranges, each a calendar range picker:

- *PO Date* — the linked purchase order's date.
- *Arrival (Invoice) Date* — the invoice/arrival date recorded on the entry.
- *Upload Date* — when the entry was logged in the system.

A *PO Date* range only matches arrivals linked to a purchase order — **direct (non-PO) entries are excluded while it is set**. The modal shows this warning inline once a PO Date range is active.

### Sort

- *Sort By* — `Upload Date`, `Arrival (Invoice) Date`, or `PO Date`.
- *Direction* — `Ascending` or `Descending` (disabled until a sort key is chosen; defaults to `Descending`).

When no sort is chosen, the default order is newest *Upload Date* first. Sorting by *PO Date* performs an inner join on the linked PO and therefore **hides direct (non-PO) arrivals** while active — the modal warns you of this too.

*Reset all* clears every advanced filter; *Apply filters* commits them and refetches from page 1.

## Show, hide, or reorder columns

The `⋮` menu holds a *Toggle Columns* submenu. Tick or untick a column name to show or hide it, and drag the grip handle beside a name to reorder it in the table. A *Reset* button restores the default set and order.

The choice is saved **per device** and each tab remembers its own layout: *Pending Arrivals* uses one column set and *Pending Approvals* / *Arrival History* share another. The *View* / *actions* column cannot be hidden. This is the same drag-to-reorder control used across the app's [common tables](/docs/getting-started/tables-and-actions).

## Hover tooltips

The `⋮` menu also has a *Tooltips* submenu that toggles the hover cards on this page. Two are available here — *Supplier* and *Product* — letting you switch off the on-hover detail popovers if you find them distracting. There is no customer tooltip on this inbound screen.

## Add a direct arrival

Use the *Add Entry* button (top right, needs *Create Stock Arrival Entry*) to record goods that arrived **without** an open purchase order — you pick the supplier, products, and locations yourself. This opens the full *Add Stock Entry* page. The complete field-by-field walkthrough lives on its own page: [Add a stock arrival](/docs/inventory/add-stock-arrival).

Direct arrivals carry no discount (it is always shown as `0%`) and their tax slab is whatever you set on the entry form — there is no PO to read those from.

## Record an arrival against a PO

When goods arrive against an open PO, record them from *Pending Arrivals* rather than *Add Entry* — the form is pre-scoped to that PO's outstanding lines, so nothing can be over-received by accident.

1. On *Pending Arrivals*, click *View* on the PO row to open *Purchase Order Details*.
2. From the top-right `⋮` menu choose *Upload Arrival* (shown only if you hold *Upload Stock Arrival From PO*).

The *Upload Stock Arrival* modal appears, headed with the PO number, supplier, and contact person. The same modal is also reached from the procurement-side Purchase Order page's *Arrival* menu.

### Invoice number and date

- *Invoice No.* — the supplier's invoice reference (optional). Placeholder `INV-001`.
- *Invoice Date* — defaults to today; the calendar will not let you pick a future date.

### Product rows

Each row is: *Product · Qty · Unit Price · Godown · Room · Rack · remove*, with an optional per-product *Remarks* line beneath.

- *Product* — a dropdown of the PO's still-pending lines. Because the same code can appear on several lines, each option is labelled with its make (for example *Bolt 10mm · Make X*) and shows how much is *left*. Hovering an option reveals a *PO Line* card with *Ordered*, *Arrived*, and *Remaining*, plus HSN and description. Picking a line already used in another row prompts an *Already in list* confirmation before it is re-added.
- *Qty* — pre-filled with the line's remaining quantity. On a fresh upload it is clamped between `1` and the line's remaining amount. If you split one line across several rows (arriving into different racks), the **sum across rows** for that line must not exceed its remaining — the modal blocks the total, not just each row.
- *Unit Price* — pre-filled from the PO line and **locked**. The arrival cannot drift from the price that was authorised on the PO; the tax slab is likewise frozen onto the arrival from the PO line.
- *Godown → Room → Rack* — the destination, chosen top-down. Room is disabled until a godown is chosen; rack until a room is chosen. If only one option is within your management scope at any level, it is auto-selected and the cascade continues. Each picker shows a **live stock hint**: how much of the selected product already sits in that location, with a hover breakdown down to the rack.
- *Remarks* — free text for that line (optional).

*Add Product* adds another row; the minus icon removes one (the last remaining row can't be removed).

### Additional Notes

A free-text area for header-level notes about the whole arrival. Notes are HTML-sanitised on the server.

### Additional charges

If the PO carries additional charges (freight, packing, and so on), an *Additional Charges* section lets you tick the ones this arrival should bill, each with an optional remark. A charge can be billed on only **one approved arrival**. See [Add a stock arrival](/docs/inventory/add-stock-arrival#recording-an-arrival-from-a-purchase-order) for the full rules. Direct arrivals and reverse entries never carry charges.

### Attachments

Drag-and-drop or browse to attach the supplier's delivery note, invoice, or other proof. Each file may be up to `50 MB`; files with a name already added are skipped. Whether an attachment is **required** depends on your firm's setting — if the owner has made attachments compulsory for stock arrivals, you cannot save without one (the server enforces this, not just the form). See [Firm customisation](/docs/settings/firm-customisation).

*Upload Arrival* submits the entry. It is saved as **pending** and shows up under *Pending Approvals* for a second user to confirm.

### What the server re-checks on upload

Every payload is re-validated, so a forged request cannot corrupt the system:

- You must hold *Create Stock Arrival Entry*; a PO-linked upload additionally needs *Upload Stock Arrival From PO*.
- The linked PO must exist, not be deleted, and be in `sent` or `partiallyArrived` status. Uploading against any other status is refused.
- Every product row must reference a real PO line by its internal line id, and the row's product code must match that line — a forged line id, or one pointing at a line for a different code, is rejected before anything is written.
- You must have manage scope over each destination godown/room/rack, and the rack must genuinely sit inside the room, which must sit inside the godown.
- `taxRateInPercentage` is clamped to `0`–`100`; `quantity` must be positive; `pricePerUnit` must be `0` or more.
- Notes, custom descriptions, and remarks are stripped of any script content; an attempted injection is logged as a security event.

## Open a row

Click *View* on any arrival row to open its detail modal, headed *Stock Arrival* (or *Reverse Arrival* for a return), with a status chip (*Pending* / *Approved* / *Rejected*).

### Cards

- *Supplier* — name, GST number, and address.
- *Invoice Info* — invoice number and date, status, *Approved On* / *Rejected On* when set, and the money roll-up (see below).
- *Contact Person* — name, phone, email, and post.
- *Notes* — the header notes, if any.
- *Uploaded By* — who logged it, when, and (once approved) who approved it.
- *Purchase Order* — for PO-linked arrivals only, showing the PO number and date. Direct (non-PO) arrivals do not show this card.

### Money roll-up (Invoice Info)

The *Invoice Info* card totals the products into *Subtotal (excl. tax)*, *Discount*, and *Total (incl. tax)*, all in `₹`. For a PO-linked arrival the discount is read **live from the linked PO** — change the PO's discount and the figures move the next time you open the arrival. For a direct (non-PO) arrival the discount is always `0`. Any additional charges attached from the PO fold into the *Subtotal* and *Total* (charge amount plus its own tax; charges carry no discount).

### Products table

Each line shows *Product*, *Make*, *Qty* (with unit), *Price/Unit*, *Disc %*, *Tax %*, *HSN*, and *Location* (Godown › Room › Rack). Expanding a row reveals the description — while pending it shows the *Default Description* and any *Custom Description* separately; once approved it shows the merged description saved at approval time — plus HSN, make, and remarks.

### Actions (the `⋮` menu in the modal)

Which actions appear depends on the entry's status and your permissions:

- *Open Purchase Order — {poNumber}* — for PO-linked arrivals, opens that PO's detail (view-only) so you can see where the stock came in against.
- *Invoice Documents* — always available; opens the attached files read-only.
- *Edit* — see below. Shown only to the person who uploaded it, and only while *pending* or *rejected*.
- *Delete* — removes a *pending* or *rejected* entry. Shown only to its uploader.
- *Approve* / *Reject* — shown to approvers while the entry is *pending*.
- *Delete Approved Entry* — see below.

### Editing an arrival

Only the person who uploaded an entry can edit it, and only while it is *pending* or *rejected* — an *approved* arrival is locked for everyone. How edit opens depends on the entry:

- **PO-linked** arrivals (normal or reverse) reopen the same fill modal, pre-filled. On edit the quantity caps are loose — you can adjust freely because the server re-validates against the PO at approval time. The invoice number, date, notes, per-line quantity/location/remarks, and attached charges can all be changed (sending an empty charge set clears them).
- **Direct (non-PO)** arrivals open the full edit page at `/inventory/in-stock/edit/{id}`, which carries the supplier and product pickers a PO arrival doesn't need.

### Approving an arrival

An approver picks *Approve* on a pending entry. Approval merges the description, stamps who approved it and when, adds the stock to the on-hand snapshot at each destination, and — for a PO-linked arrival — recomputes the PO status (which may flip it from *sent* to *partially arrived* or *arrived*).

**Over-arrival guard.** If approving would push the total received past the PO's ordered quantity — for instance because a second arrival for the same line was approved in the meantime — approval is blocked and a breakdown modal (*Cannot approve — PO total would be exceeded*) lists each offending product with *Ordered*, *Already arrived*, *This arrival*, and *Would total*. Edit the arrival down, or reject it.

**Charge conflict.** If an additional charge on this arrival was billed on another approved receipt since this one was drafted, approval is blocked with a note to edit the receipt and remove the conflicting charge first.

Rejecting simply sets the entry to *rejected*; it never touches stock.

### Deleting an approved entry

*Delete Approved Entry* permanently removes an approved arrival and **immediately reduces inventory** for its products. A strong confirmation warns that if any of that stock has already been consumed or transferred, deleting it may push counts negative. Who can do this:

- A firm administrator — always.
- For **manual (non-PO)** approved entries only — a user with *Delete Manual Arrival Entry* (`deleteManualArrivalEntry`).

PO-linked approved arrivals cannot be deleted by non-admins this way; undo them with a *reverse entry* instead (below).

## Reverse an entry (return to supplier)

Sometimes goods that already arrived have to go back — wrong item, damage, or over-supply. A *reverse entry* records that return. It is the inbound mirror of a sales return: a normal arrival *adds* stock, a reverse entry *removes* it and sends it back to the supplier.

A reverse entry exists **only for PO-linked arrivals**. To create one, open the **Purchase Order** and choose *Reverse Entry* from its top-right menu (alongside *Additional Charges*, *Universal Notes*, and the *Stock Arrival Ledger*). The modal is titled *Reverse Entry — Return to Supplier* and works exactly like recording an arrival, with these differences:

- The product dropdown lists the PO's **received** lines (net of anything already reversed); the cap per line is the *returnable* net-received quantity, not the remaining-to-arrive.
- You enter a normal **positive** quantity; the system stores it internally as a **negative** movement, so every stock figure nets out automatically.
- The date field is labelled *Return Date* and the reference is *Debit Note / Ref No.* (placeholder `DN-001`).
- The notes field is *Reason / Notes*.

Like a normal arrival it starts *pending*. A second user with *Approve Reverse Arrival* (`approveReturnArrivalRequest`) must approve it before stock actually moves, and approval re-checks that the return does not exceed the net quantity received (a *Cannot approve — exceeds quantity received* breakdown appears if it would).

Once approved:

- *On-hand stock* falls by the returned quantity at the location it left from. You can never return more than is physically on hand there.
- *The purchase order status* is recomputed on the **net** received (everything that arrived minus everything reversed). If a full return drops the net to zero, the PO falls back to *Sent* — and a *Sent* PO can be deleted again.

Reverse entries show a *Return* chip in *Arrival History* and a *Return to Supplier* badge in the detail modal (headed *Reverse Arrival*). They appear as a downward movement in the [Stock Ledger](/docs/inventory/stock-history) and are deliberately left out of purchase-rate reports and supplier receipts, because a return is not a purchase. Pending reverse entries are approved from the same *Pending Approvals* tab.

Two permissions gate the feature:

- *Create Reverse Arrival (Return to Supplier)* (`generateReturnArrivalRequest`) — to raise one from a PO.
- *Approve Reverse Arrival* (`approveReturnArrivalRequest`) — to approve and commit the movement.

## Deleted arrival logs

Nothing is ever truly lost. The moment any arrival is deleted — pending, rejected, or approved — a full snapshot is copied to a permanent audit log **before** it is removed. The snapshot records exactly what the arrival was (supplier, products, quantities, prices, locations) plus **who deleted it, when, and why**. Because it is a separate frozen copy, deleted entries vanish cleanly from your stock figures and ledger while the record survives for accountability.

To review them, open the `⋮` menu on the *Arrival History* tab and choose *Deleted Arrival Logs* (firm admin, or *View Inventory Pages*). The read-only window has four free-text search boxes across the top — *Supplier*, *Contact Person*, *Product Head*, and *Product Code* — and lists every deleted arrival with its *Deleted On* time, *Deleted By*, *Status* (with a *Reverse* chip where relevant), *Supplier*, *PO No*, *Products*, and *Reason*. The reason reads *Approved entry deleted* or *Pending/rejected deleted*. *View* opens the full deleted arrival exactly as it looked, marked with a banner showing who removed it. There are no actions here — it is purely a record.

## Common questions

### Why does an arrival need approval?

So one person's entry is confirmed by another before it touches your on-hand counts. A stock arrival starts *pending* and only adds stock when an approver clicks *Approve*. The *Pending Approvals* tab is where the approver works.

### I logged an arrival but the stock count hasn't changed — why?

Because it is still *pending*. Stock only moves on approval. Check *Pending Approvals*; someone with *Approve Stock Arrival* needs to confirm it.

### What if a supplier delivered less than the PO promised?

Record the arrival with the actual quantity received. The remaining quantity stays open against the PO and keeps appearing in *Pending Arrivals* until it is fulfilled or the PO is closed. See [Purchase order follow-up](/docs/procurement/purchase-order-follow-up).

### Can I split one PO line across two locations?

Yes — add the line to two rows with different *Godown / Room / Rack* selections. The combined quantity across those rows still cannot exceed the line's remaining amount.

### Why can't I see other people's arrivals in the history?

If you can create arrivals but not approve them, the history is scoped to your own entries by design. Ask for *Approve Stock Arrival* (or admin) to see everyone's.

### I made a mistake on an approved arrival — how do I fix it?

An approved arrival is locked. If it came from a PO, raise a *reverse entry* to send the stock back, or (as admin, or with *Delete Manual Arrival Entry* for non-PO entries) use *Delete Approved Entry*. For a direct correction after approval, an admin may delete and re-add. Pending or rejected entries can still be edited from their row.

### How do I email the supplier a receipt for what arrived?

From the `⋮` menu choose *Send Arrival Receipts*. See [Send arrival receipt to supplier](/docs/inventory/send-arrival-receipt).

### Where do reverse entries and approved arrivals show up as stock movements?

In the [Stock Ledger](/docs/inventory/stock-history) — approvals as inbound movements, reverse entries as outbound. The current on-hand totals live on the [Stock](/docs/inventory/stock-overview) snapshot.
