---
title: Transfer stock
order: 6
updated: 2026-07-12
---

# Transfer stock

A transfer moves stock of one product from one place inside your firm to another — between godowns, rooms, or racks. Use a transfer when goods physically shift location without being sold, returned, or consumed. Nothing about the total on-hand quantity changes; the stock simply leaves the source rack and lands at the destination rack.

A transfer is **instant and needs no approval** — the moment you click *Transfer* the movement is recorded and both racks reflect it. It is one of the three instant, permission-gated stock movements alongside [Physical stock entry](/docs/inventory/physical-stock-entry) and [Convert stock](/docs/inventory/convert-stock). It differs from an arrival or a delivery, which start pending and must be approved.

## Open the transfer

1. Open *Inventory* in the sidebar and click *Stock*.
2. Click the actions menu (the vertical-dots button) at the top right of the *Stock* screen.
3. Open the *Transfer* submenu and pick *Transfer Stock*. The *Transfer Stock* modal opens.

The whole *Transfer* submenu — both *Transfer Stock* and *Transfer History* — only appears if you are a firm administrator or hold the *Transfer Stock* permission (`inventory.transferStock`). If you cannot see it, ask an administrator to grant that permission.

## Record a transfer

The *Transfer Stock* modal is laid out top to bottom: first the product and quantity, then the *From* and *To* locations, then optional notes and attachments.

1. Pick the *Product Head* from *Select head…*.
2. Pick the *Product Code* from *Select code…* — disabled until a head is chosen, then scoped to that head.
3. If the code's in-stock goods carry brand makes, pick the *Make*. If exactly one make exists it is filled in for you.
4. Enter the *Quantity* to move.
5. Choose the *Unit*. If the product allows only one unit it is filled in and locked.
6. Pick the source: *From Godown*, then *From Room*, then *From Rack*. Each option shows how much of the selected code sits there, and single-option or single-in-stock levels auto-fill.
7. Pick the destination: *To Godown*, then *To Room*, then *To Rack*. The destination rack cannot be the same rack you are moving out of.
8. Optionally add a note in *Any notes about this transfer…*.
9. Optionally drag and drop or browse for attachments (PDF, images, Word — up to `50 MB` each).
10. Click *Transfer*.

The transfer reduces the quantity at the source rack and adds the same quantity at the destination rack. It shows up in *Transfer History*, and — when a location filter is applied — as paired transfer-out / transfer-in rows in the stock ledger (see [Stock history](/docs/inventory/stock-history)).

## Product and quantity

### Product Head

A searchable dropdown (*Select head…*) listing every product head. Picking a head unlocks the *Product Code* field and scopes it to that head. Changing the head clears the code, unit, and make below it.

### Product Code

A searchable dropdown (*Select code…*), **disabled until a head is picked**. Only codes belonging to the selected head appear. Choosing a code drives everything below: it loads the code's allowed units, the makes currently in stock for it, and the per-location stock breakdown that powers the quantity hints and auto-fill.

### Make

A dropdown listing the makes (brands) that currently have stock for the selected code. Its behaviour:

- The list is built from the code's stock movement history, so it shows only makes that have actually been stocked.
- The legacy *Unspecified* bucket (stock recorded with no make) is **not** offered here — that stock has no make to carry through a transfer.
- If exactly one real make is found, it is selected automatically.
- Placeholder text reflects the state: `Loading…` while it fetches, `Pick code first` before a code is chosen, `No makes in stock` when the code has no make-tagged stock, and `Select make` when a choice is needed.

**Gotcha (make is conditionally required):** if the code has one or more makes in stock you *must* pick one before the transfer will submit. If the code has no makes at all (only *Unspecified* stock), the make field stays empty and the transfer proceeds without one — the source-stock check then looks at all stock at the rack regardless of make. The server re-checks the make: it must be a valid, existing make, and the available-quantity check at the source is make-aware when a make is supplied.

### Quantity

A number field (placeholder `0`) accepting fractional amounts (step `any`, minimum `0.01` on screen). The transfer will not submit with a blank, zero, or negative quantity.

**Server re-validation:** the backend requires the quantity to be a positive number and, crucially, **no greater than the stock available at the source rack** (make-aware if a make was picked). If you request more than is on hand it is refused with an "Insufficient stock at source" message showing the available and requested amounts. There is no fixed upper limit other than what is physically in that rack.

### Unit

A dropdown of the units allowed for the selected code. If the code defines an allowed-unit list, only those units appear; otherwise every unit is offered. If exactly one unit is possible it is filled in and the field is disabled. The placeholder reads `Loading…` while units load, then `Select unit`.

## From and To locations

Both sides are a three-level cascade — *Godown → Room → Rack*. The room list loads once a godown is chosen; the rack list loads once a room is chosen. Every option in every dropdown shows the quantity of the selected code held at that location, so you can see at a glance where the stock actually is.

### Auto-fill behaviour

To save clicks, the modal fills in what it can:

- **One godown in the firm** — both *From Godown* and *To Godown* are set to it automatically.
- **Two godowns** — once you pick the *From Godown*, the *To Godown* is set to the other one.
- **One room / one rack under a chosen parent** — it is selected automatically.
- **Stock-aware source fill** — after the *From* rooms (or racks) load, if only a single room (or rack) actually holds stock of this code, that one is selected even when several exist. This lands the *From* side on the rack where the goods really sit.

You can override any auto-filled value by opening the dropdown and choosing another.

### From Godown / From Room / From Rack

Where the stock is moving out of. *From Room* is disabled until a godown is picked, and *From Rack* until a room is picked. The quantity shown against each option is the on-hand amount of the selected code there.

### To Godown / To Room / To Rack

Where the stock is moving to. Two guards keep the destination valid:

- The *To Godown* list **hides the source godown** when that godown has no room to spare — specifically, when the source godown has only one room and one rack, so there is nowhere else inside it to move to.
- The *To Rack* list **excludes the exact source rack** when the *To* godown and room match the *From* godown and room. This is what enforces "the destination cannot be the same rack as the source." If a previously chosen destination rack becomes the source rack, the selection is cleared.

**Note:** this same-rack block is applied in the screen. The server validates that every location ID is real and that each rack belongs to its stated room and each room to its stated godown, but it does not itself reject a transfer whose source and destination rack are identical — the modal is what prevents that combination from being submitted.

## Notes

An optional free-text area (*Any notes about this transfer…*) for anything worth recording — reason for the move, batch number, a supervisor's approval reference. It is stored with the transfer and shown on its detail view. There is no enforced length limit.

## Attachments

Optional supporting files — a signed movement slip, a photo, a gate pass. Drag and drop onto the drop zone or click *browse*.

- Accepted: **PDF, images, and Word** documents, up to `50 MB` per file. A file over the limit is skipped with a message; the server also rejects any single file above `50 MB`.
- Files with a name already in the list are skipped as duplicates.
- You can add several files; each is uploaded when you click *Transfer*.

Attachments are viewable later from the transfer's detail view (read-only there — see [Review past transfers](#review-past-transfers)).

## Submit

Click *Transfer*. Before sending, the modal checks that a code is chosen, the quantity is valid, a unit is set, a make is set when the code has makes, and that both the *From* and *To* locations are complete down to the rack. On success you get a *Stock transferred successfully* toast and the modal closes.

### What the server re-checks

Because every request is re-verified server-side, a hand-crafted or tampered request is caught. On top of the field-shape checks (all IDs must be valid, quantity must be positive, unit must be present) the backend enforces:

- **Permission** — you must be an administrator or hold `inventory.transferStock`, or the request is refused.
- **Manage scope on both ends** — a non-admin must have manage scope covering the *From* location **and** manage scope covering the *To* location. Scope is satisfied by a matching godown, room, or rack entry in your inventory manage scopes. A transfer out of, or into, a location you do not manage is refused. See [Storage locations](/docs/inventory/storage-locations) for how scope is assigned.
- **Product code exists** — an unknown code is a `404`.
- **Location hierarchy** — each rack must genuinely belong to its room, and each room to its godown, on both sides. A rack ID smuggled under the wrong room is rejected.
- **Make exists** — if a make is supplied it must be a real make on record.
- **Sufficient source stock** — the requested quantity must not exceed what is on hand at the source rack (make-aware when a make is given).

These checks exist so that a forged payload cannot crash the stock pipeline or move stock a user has no right to touch.

## Review past transfers

From the same *Transfer* submenu on *Stock*, pick *Transfer History*. The *Transfer History* modal lists every transfer, newest first, `10` per page.

### Filters

- *Product Head* (*All heads…*) — limit to one head. Choosing a head resets the code filter.
- *Product Code* (*Pick head first* until a head is chosen, then *All codes…*) — narrow to one code.
- *From Date* and *To Date* — limit the range. Each has a clear (×) button.

### Columns

Each row shows the *Date* (`dd/mm/yy`), *Product Code*, *Qty* with its short unit, the *From* location as `Godown › Room › Rack`, an arrow, the *To* location the same way, and *By* — who performed it. Click *View* on a row to open its detail.

**Who sees which rows:** a non-administrator only sees transfers whose **source** location falls within their manage scope (or, if they have no scope arrays at all, only the transfers they performed themselves). Administrators and users with an "all" scope see everything.

### Transfer detail

*View* opens the *Transfer Details* modal: the transfer's ID, the date and time (`dd/mm/yy HH:mm`), who performed it, the product code and quantity with full unit label, the *From → To* movement drawn as location breadcrumbs, the notes, and — if any files were attached — an *Attachment(s)* button. That button opens the attachments in **read-only** mode; you can view and download them but not add or remove files after the fact.

## Common questions

### Where is the "Transfer Stock" option — I can't find it?

It lives on the *Stock* screen (under *Inventory → Stock*), in the actions menu at the top right, inside the *Transfer* submenu. The whole submenu is hidden unless you are an administrator or hold the *Transfer Stock* permission.

### Can a transfer be undone?

There is no delete or reverse button on a transfer. To move the stock back, record a second transfer in the opposite direction. The original entry stays in *Transfer History* for the audit trail.

### Why won't it let me pick the same rack as source and destination?

A transfer to the same rack would net to nothing, so the *To Rack* list drops the source rack whenever the *To* godown and room match the *From* side. Pick a different rack, room, or godown for the destination.

### It says "Insufficient stock at source" — why?

The quantity you asked to move is more than the source rack actually holds for that code (and that make, if you picked one). The location dropdowns show the on-hand figure against each rack — check there, lower the quantity, or pick the rack that really has the stock. If the snapshot itself looks wrong, investigate before transferring; a genuine count discrepancy is corrected with a [Physical stock entry](/docs/inventory/physical-stock-entry), not a transfer.

### Why do I have to choose a make?

Because the selected code has stock recorded under one or more brand makes, and a transfer has to move a specific make's stock. If the code only has make-less (*Unspecified*) stock, no make is asked for and the transfer moves that stock directly.

### I can open Transfer Stock but Transfer History gives an error — why?

Viewing history is a separate permission (*View Transfer History*, `inventory.viewStockTransferHistory`). The menu shows both entries together under the *Transfer* permission, but the history list is refused server-side unless you also hold the view permission (administrators always may). Ask an administrator to add it.

### Does a transfer affect stock value or cost?

No. A transfer only relocates existing stock, so the total on-hand quantity, the weighted-average cost, and the stock value are unchanged. Only the per-location breakdown moves. To add or write off stock (which does affect value), use a [Physical stock entry](/docs/inventory/physical-stock-entry); to turn one product into another, use [Convert stock](/docs/inventory/convert-stock).

### Where do transfers show up besides Transfer History?

In the per-location stock breakdown on the *Stock* screen (the source rack drops, the destination rises), and in the stock ledger as paired transfer-out and transfer-in rows once you filter the ledger to a location. They are deliberately kept out of *Stock In* and *Stock Out*, which track arrivals and deliveries. See [Stock overview](/docs/inventory/stock-overview) and [Stock history](/docs/inventory/stock-history).
