---
title: Physical stock entry
order: 6
updated: 2026-07-12
---

# Physical stock entry

A *Physical Stock Entry* is a plain `±N` movement at one rack on one date — it adds or removes stock without going through the purchase-order arrival flow or the delivery flow. Use it when:

- Stock is found during a physical count that was never recorded as arriving.
- Stock is missing after a count and has to be written off.
- Goods came in through a channel that bypassed the purchase order (a hand-carry, a sample kept, an opening balance).

Every entry is recorded as an ordinary movement in the stock ledger — nothing earlier is rewritten or absorbed. An *add* increases on-hand at the chosen rack; a *remove* decreases it. Once saved, the change is live immediately (there is no approval step, unlike a [stock arrival](/docs/inventory/add-stock-arrival)).

Internally each entry is a *stock adjustment*, so you may see that word in the ledger and in reports.

## Open the entry form

1. Open *Inventory* in the sidebar, then the *Stock* screen — see [Stock overview](/docs/inventory/stock-overview).
2. Open the actions menu at the top right and expand the *Adjustment* submenu.
3. Choose *Physical Stock Entry* to record a new one, or *Stock Entry History* to review past entries.

The whole *Adjustment* submenu — both the entry form and the history — only appears if you hold the *Physical Stock Entry* permission (`inventory.physicalAdjustment`), or you are a firm administrator. That permission itself depends on *Open Inventory Pages* (`inventory.viewInventory`). Without it the submenu is hidden and the server rejects the underlying requests with `403` even if the call is forged.

## Record an entry

The form is titled *Physical Stock Entry* with the sub-line "Add or remove stock at a rack as a plain ±N movement." It is the same form whether you are on web or the desktop app.

### Direction (Add / Remove)

Two buttons at the top of the form:

- *Add Stock* — the entry increases on-hand at the rack. This is the **default**. The button is highlighted in the primary colour when active.
- *Remove Stock* — the entry decreases on-hand. The button turns red when active.

The direction decides the sign of the movement: the quantity you type is always a plain positive number, and the app stores it as `+qty` for an add or `−qty` for a remove. It also controls whether the value fields (*Price Per Unit*, *Tax Rate*) are shown — they appear only when adding. Switching to *Remove* hides them, and on save the server clears any price/tax that was set.

### Date

The date the movement is recorded against. Defaults to **today**. You **cannot pick a future date** — the picker is capped at today. Backdating to an earlier day is allowed.

The date is the entry's effective date in the dated views: the [Stock Ledger](/docs/inventory/stock-history) and any date-windowed report place the movement on this day. Your current on-hand total is a straight sum of every non-deleted movement, so backdating does not retroactively rewrite an earlier balance — it only changes where the entry sits on the timeline. The time is fixed to midday local time so the entry never slips across a day boundary due to time zones.

### Product Head and Product Code

Two searchable pickers, both required:

- *Product Head* — pick the head first. Type to search.
- *Product Code* — the specific code under that head. It stays disabled until a head is chosen (placeholder *Pick head first*), then lets you search codes within that head.

Picking a code pulls that product's defaults and drives three conveniences:

- The *Tax Rate* is pre-set to the product's default tax rate.
- If the product is flagged as always taxed at one rate, the *Tax Rate* dropdown is locked to that rate.
- The *Unit* picker is limited to the product's allowed units; if the product has exactly one allowed unit it is filled in and locked.

Picking a code also triggers **location auto-fill** (see *Godown / Room / Rack* below).

### Godown / Room / Rack

The warehouse location the adjustment applies to. All three are required and cascade:

- *Godown* — the warehouse.
- *Room* — enabled once a godown is picked (placeholder *Pick godown first*); the room list loads for that godown.
- *Rack* — enabled once a room is picked (placeholder *Pick room first*); the rack list loads for that room.

Each list is filtered to the locations you are allowed to manage. A firm administrator, or a user whose scope is set to `all`, sees every location; otherwise only godowns in your *Godown Stock Scope* (`inventory.manageGodownScope`), rooms in your *Room Stock Scope* (`inventory.manageRoomScope`), and racks in your *Rack Stock Scope* (`inventory.manageRackScope`) appear. If a level has exactly one allowed option it is auto-selected and the next level loads automatically.

Each option in the dropdown shows a **live stock hint** — how much of the selected product that godown / room / rack currently holds — so you can see at a glance where the stock already sits.

**Auto-fill.** When you pick a product code, the form tries to pre-select a sensible destination from that product's existing stock spread (within your scope): the rack most in deficit (most negative) first, then the rack holding the most stock, then a location that already appears in the product's history with zero. It never invents an unrelated rack — if the product has no in-scope history the location is left blank for you to choose. You can always override the auto-filled location.

The server re-checks the hierarchy on save: the rack must belong to the chosen room, the room must belong to the chosen godown, and (for non-admins) you must hold manage scope on at least one of the target godown, room, or rack. A forged location that fails any of these is rejected.

### Quantity and Unit

- *Quantity* — a positive number. It must be **greater than zero** (the server rejects zero or negative). The direction toggle, not the sign you type, decides add vs remove.
- *Unit* — required. Limited to the product's allowed units (see *Product Code*). Locked when the product has a single allowed unit.

### Make

Optional. The manufacturer or brand for this stock. Disabled until a product head is chosen (the make list is scoped to the head). Leave blank if it does not apply. The server verifies the make exists before saving.

### Price Per Unit — add only

Shown only when the direction is *Add Stock*, and then **required**: it must be greater than `0`. The field formats to two decimal places.

The cost is what lets the app value the added stock. When you add priced stock it is folded into the product's **weighted-average cost**, exactly like a purchase arrival — the dashboard stock value and inventory reports then include this stock at the recorded cost. Adding stock with no cost would leave the valuation blind, which is why it is mandatory.

When removing stock this field is hidden; a removal does not change the weighted-average cost, it just reduces the quantity at whatever average cost the product already carries.

### Tax Rate (%) — add only

Shown only when adding. A dropdown of the standard GST slabs: `0`, `5`, `12`, `18`, `28`. It defaults to the product code's own default tax rate, and is **locked** if that product is flagged to always use the same rate. Together with *Price Per Unit* it is used to compute the tax-inclusive value of the added stock. The server clamps the stored rate to the `0`–`100` range and only keeps it for additions.

### Notes

Optional free text — a reason, a count reference, any context. It is sanitised on the server (any script/HTML injection is stripped and logged as a security event), and it is shown as formatted text in the entry's detail view.

### Attachments

Optional supporting files — count sheets, adjustment forms, photos. Drag and drop onto the drop zone, or click to browse. Multiple files are allowed. Limits and behaviour:

- **Maximum `50 MB` per file.** Anything larger is skipped with a warning.
- Duplicate file names (already added in this form) are skipped with a warning.
- The hint reads "PDF, images, Word — up to 50 MB each"; other common document types upload too.

Each file must finish uploading (reach a *ready* state) before the entry will save — the server refuses an entry whose attachments are still processing.

### Save

Press *Save Entry*. The form validates that the date, product head, product code, godown, room, rack, quantity, and unit are all present, that the quantity is above zero, and (for an add) that the price is above zero. On success a toast confirms the recorded change, e.g. `Stock entry recorded (+10 NOS)`, and the stock figures on the Stock screen refresh. The server re-validates every one of these rules independently, so a hand-crafted request that skips the form cannot slip a bad entry through.

## Stock Entry History

*Stock Entry History* (same *Adjustment* submenu) opens the *Physical Stock Entries* list — every non-deleted entry you are allowed to see, newest first, `10` per page. The header shows the total record count.

### Filters

A row of four filters above the list, all optional and combinable:

- *Product Head* — limit to one head. Clearing it also clears the code filter.
- *Product Code* — limit to one code; disabled until a head is chosen (*Pick head first*).
- *From Date* / *To Date* — a date range on the entry's recorded date. Neither can be a future date.

### What you can see

Which entries appear depends on your scope:

- A firm administrator, or anyone whose godown/room/rack scope is `all`, sees every entry.
- A scoped user sees entries whose target godown, room, or rack falls inside their manage scope.
- A user with the *Physical Stock Entry* permission but **no** location scope at all sees only the entries they performed themselves.

### Columns

- *Date* — the entry date (`dd/mm/yy`).
- *Product* — code name, with the head name beneath it.
- *Location* — `Godown › Room › Rack`.
- *Change* — the signed movement with the short unit, colour-coded: green for an add (`+`), red for a remove (`−`).
- *Make* — hidden by default; enable it from the table's column control.
- *By* — who performed the entry.
- *Notes* — the note text (HTML stripped), truncated with the full text on hover.
- Row actions — *View* always; the pencil (*Edit*) and trash (*Delete*) icons appear only if you hold the *Physical Stock Entry* permission.

### View an entry

*View* opens a read-only detail with the date, when it was created, product, location, make, who performed it, the big signed *Change* figure, the formatted notes, and the attachments. Each attachment has a download button. A deleted entry is marked with a `(deleted)` tag. (Viewing requires *Open Inventory Pages*.)

## Edit an entry

From *Stock Entry History*, click the pencil icon on a row. The same *Physical Stock Entry* form opens, pre-filled, but some fields are **locked**:

- *Product Head*, *Product Code*, *Godown*, *Room*, and *Rack* are read-only. They cannot be changed on an edit — the location and product of an entry are fixed. To move the movement to a different product or rack, delete this entry and record a fresh one.
- Everything else is editable: the direction, date, quantity, unit, make, notes, and — when adding — the price and tax.

You can also manage attachments: add new files (same `50 MB` per-file limit), and remove existing ones with *Remove* (toggle back with *Undo* before saving).

If you flip an edited entry from *Add* to *Remove*, the price and tax fields disappear and the server clears them, since they are meaningless for a removal. Flipping back to *Add* requires a valid price again. Editing is gated by the same *Physical Stock Entry* permission; note that an edit re-checks that permission but does not re-run the location manage-scope check, because the location itself is locked.

## Delete an entry

Click the trash icon on a history row and confirm *Delete this entry?*. The entry is **soft-deleted**: it is flagged deleted (with who deleted it and when kept for audit) and stops counting toward stock immediately, but the record is not physically erased. There is no separate "deleted entries" browser for physical entries — a deleted one simply drops out of the history and the stock figures. Deleting is gated by the *Physical Stock Entry* permission.

## How an entry affects stock and value

### On-hand quantity

An entry's signed quantity is added straight into the on-hand calculation for that product code at that rack, alongside arrivals, deliveries, transfers, and conversions. A `+` entry raises on-hand; a `−` entry lowers it. Deleted entries are excluded.

### Stock value

- **Adding priced stock** contributes its `quantity × price` (and the tax-inclusive equivalent) to the product's weighted-average cost, merged with purchase arrivals. The dashboard and inventory value figures then reflect it. This is why a price is required on every add — see [Stock overview](/docs/inventory/stock-overview) for where those value columns appear (they need the value-columns permission).
- **Removing stock** reduces the on-hand quantity only; it uses the product's existing weighted-average cost and does not change it.

## Common questions

### Why is Price Per Unit required when adding stock?

Without a cost the app cannot value the added stock, so the dashboard and inventory screens would show an inaccurate total. An add therefore always needs a price above zero. Removals need no price — they reuse the product's existing average cost.

### Is the Tax Rate a free number or a fixed list?

It is a dropdown of the standard slabs `0`, `5`, `12`, `18`, `28`. It defaults to the product code's own default rate and is locked if that product always uses one rate. It only appears when adding stock.

### Does an entry need approval before it affects stock?

No. Unlike a [stock arrival](/docs/inventory/add-stock-arrival), a physical entry has no approval step — it is live the moment you save it.

### Can I change the product or location after saving?

No — those are locked on edit. Delete the entry and record a new one at the correct product or rack. You can still change the quantity, direction, date, unit, make, notes, price, and tax on an edit.

### Who can see and manage entries?

Recording, editing, and deleting all need the *Physical Stock Entry* permission (`inventory.physicalAdjustment`) or firm-administrator rights. What you see in history is further limited by your godown/room/rack manage scope; a user with the permission but no scope sees only their own entries.

### Why is a warehouse, room, or rack missing from the pickers?

The lists only show locations inside your manage scope. If a location is missing, either it does not exist yet — add it from the warehouse screens, see [Storage locations](/docs/inventory/storage-locations), [Warehouses](/docs/records/warehouses), and [Warehouse rooms](/docs/records/warehouse-rooms) — or it falls outside your scope and an administrator must grant it.

### How is this different from a transfer or a conversion?

A physical entry is a one-sided `±N` correction at a single rack. A [stock transfer](/docs/inventory/transfer-stock) moves stock between two racks (net zero overall), and a [stock conversion](/docs/inventory/convert-stock) turns one product code into another. Use a physical entry only when stock genuinely appears or disappears with no counterpart movement.
