Warehouse & supply
Follow stock movements, calculate requirements and cover shortages.
Purpose
The Warehouse menu group covers the entire material loop: how much of what is on the warehouse and exactly where (batches, storage cells), material movement in/out/between storage locations (arrivals, issues, transfers, stocktaking, waste write-off), purchasing from suppliers (requisition → order → arrival), and the calculation screens that say what is missing and how much needs to be bought/made (MRP, Supply availability). Separately, limit-and-issue cards (repeated material issue to the shop within a limit, without a separate document for every issue).
Five menu items in the group: MRP, Supply availability, Warehouse (itself 10 nested tabs), Limit cards, Arrivals.
Who uses it (roles)
- Storekeeper — the main user of the whole phase: MRP, Supply availability, Warehouse (all tabs), Limit cards, Arrivals.
- Procurement officer — the purchasing part: Supply availability,
Arrivals, plus viewing Orders (production orders, not to be confused
with supplier orders — those live on the Warehouse tab under the same
provision.viewpermission as Supply availability). - Area foreman and Dispatcher — see and use Supply availability (view + manage) to check whether there is enough material for their own orders and to create a request/order from a shortage.
- Administrator — all permissions, plus two spots in this phase where
a plain section permission is not enough:
- Direct balance correction ("Warehouse journal," reason
"Correction") — available only to
operator.is_admin(checked by flag, not permission slug) and requires a mandatory reason. A storekeeper without administrator rights uses the "Stocktaking" tab for the same purpose. - Production waste and write-off — the only screen in the
application gated by either of two permissions:
warehouse.viewORqc.write. An area foreman/storekeeper writes off ordinary production waste under the first permission, a QC inspector writes off defects/rework under the second; no single role covers both cases on its own.
- Direct balance correction ("Warehouse journal," reason
"Correction") — available only to
Key concepts
| Term | Meaning |
|---|---|
| Stock movement (StockMovement) | An immutable log entry: the part, the sign and size of the change (delta), the reason (arrival/issue/correction/return/transfer), the date, the basis, and optionally a cell/batch/price. The source of truth for a balance; Part.stock_qty is a materialized cache on top of it |
| Batch | A lot of material, created only when an arrival document is posted: number, quantity, price, arrival date, certificate, ownership group. A batch's balance is always recomputed on the fly as the sum of movements with that batch_id |
| Issue method (FIFO / LIFO / SELECT) | A warehouse-wide setting for how an issue picks a batch: FIFO — oldest batches first, LIFO — newest batches first, SELECT ("manual batch") — the operator picks the batch for each line. Configured on the "Issues" tab |
| Storage cell | A tree of physical locations (warehouse → rack → shelf → cell). Not a separate balance register — just a filter/grouping over the same movement log (cell_id) |
| Arrival / issue document | A "draft → lines → Post" document: the lines are plain data, and actual stock movements (and, for arrivals, batches) are created only on posting |
| Purchase requisition / Supplier order | A two-stage purchase: a requisition (draft → approved → "Create order…") turns into a supplier order; a supplier order can also be created directly, bypassing the requisition — for routine purchases with no approval step |
| Arrival notice | The fact that "material has physically arrived" separate from the fact that "the balance has been received": "Receive" creates an arrival stock movement |
| Limit-and-issue card (limit card) | A document for repeated issue of one part to one department within a limit over a period; the issued quantity is the sum of movements with ref = the card id |
| Supply availability | Matches net requirement (the same BOM math as MRP) against balance, production, orders, minimum reserve, and loss factor; balance = availability − requirement×loss factor − minimum reserve |
| Ownership group (StockOwnershipGroup) | A tag on a batch/movement for tracking identical stock separately by contract/project within one warehouse — implemented at the API level, with no screen in the interface yet (see "Notes" below) |
Warehouse
Section /warehouse, permission warehouse.view. Technically not one
page but a nested dockview with 10 independently draggable panels that all
open at once on first entry: Warehouse journal, Supplier orders,
Purchase requisitions, Addressing, Arrivals, Issues,
Transfer, Turnover, Stocktaking, Production waste. Any
panel can be dragged into its own window, closed, and reopened — just like
top-level windows (see Getting started).
Unlike legacy VOGBIT (support/4158), this version does not print ready-made document forms (arrival order, issue document, etc.) — only Excel export, where it exists at all (the "Turnover" tab, the "Supply availability" screen).
Warehouse journal
What you see
A single table of all stock movements: Date / Part / Type / Change / Unit price / Amount / Basis, with a column filter. Issue rows younger than the return period get a "Return" button. Below is a quick movement-entry form: part, type (Arrival / Issue / "Correction (admin)" — the last option is visible only to an administrator), quantity, unit price (arrivals only), basis.
Typical scenarios
- A storekeeper quickly records an arrival or issue without filling out a full document — for example, minor office supplies or a one-off operation.
- Returning an erroneously issued item: the "Return" button only appears on issue movements no older than the return period (3 days by default, configured on the "Issues" tab); the entered quantity cannot exceed the not-yet-returned remainder of that movement.
- An administrator manually corrects a discrepancy with a mandatory reason — the only route for a direct correction with no source document.
Notes and limitations
- A direct correction (
reason=adjustment) requiresoperator.is_adminand a non-empty reason — otherwise the server rejects the request (403/422). - An arrival's price, if not entered manually, is auto-filled from the
part's current effective price (
PriceRecord— the same price list maintained in the Price list, Cost & prices). - A return inherits the cell/batch/price of the original issue movement — they cannot be overridden.
- The list shows the last 200 movements with no pagination; for a period summary, use the "Turnover" tab.
Arrivals
What you see
On the left, a list of arrival documents (Document / Supplier / Date / Status). On the right, the selected document's lines: Part / Qty / Unit / Qty (base unit) / Unit price / Cell / Batch, with line deletion while the document is a draft. Document creation form: Supplier, Document #, Date. Line form (draft only): part, quantity, unit (empty = the part's base unit), unit price, cell, batch number, certificate. The "Post" button is available only for a draft with at least one line.
Typical scenarios
- A storekeeper enters a document for a batch received from a supplier, fills in the lines row by row with price, certificate, and batch number, and posts it — each line creates a batch (Batch) and an arrival stock movement.
- An erroneous line can be deleted while the document is a draft; after posting, the document and its lines are immutable.
Notes and limitations
- Posting is irreversible in the interface — there is no undo/reversal button for a posted document.
- If a line specifies a unit other than the base one, and no conversion coefficient (Reference data → Coefficients, Reference data & access) is set up for that unit pair, posting fails with an error; the line needs to be fixed.
- The batch number, if not specified, is generated automatically (the first 8 characters of the line's id).
Issues
What you see
The header has two settings shared by the whole warehouse (not just this tab): issue method (FIFO / LIFO / "Manual batch (SELECT)") and the return period in days. Below, a list of issue documents (Basis / Department / Status) and the selected one's lines: Part / Requested / Unit / To issue (base unit) / To issue (an editable field, while the document is a draft) / Cell / Batch. New document form: Basis (requisition/work order), Department. Line form: part, quantity, unit, cell, batch (required, and appears only if the issue method is SELECT).
Typical scenarios
- A storekeeper creates an issue document against a shop requisition or work order, enters the requested quantity, adjusts "To issue" to the actual amount to be issued if needed (a partial issue is an edit to this field before posting, not a series of separate partial postings), and posts it.
- Under the SELECT method, the operator explicitly picks the batch for each line; under FIFO/LIFO, the system allocates the issue across open batches itself, splitting across several if needed.
Notes and limitations
- "To issue" defaults to "Requested" and is editable only in the draft.
- The issue method and return period, changed here, take effect immediately on the "Warehouse journal," the quick-issue dialog ("Addressing"), and "Transfer" as well.
Transfer
What you see
A list of transfers (From / To / Status; for "In transit" status, an "Accept" button). Lines: Part / Qty / Unit / Qty (base unit) / Batch. Creation form: pick the "From" and "To" cells, a comment. Line form — same as "Issues" (plus batch under the SELECT method). Two posting buttons: "Transfer" and "Issue."
Typical scenarios
- A transfer within an area controlled by one storekeeper — "Transfer"
posts both sides at once (
draft → completed). - A transfer between departments/warehouses with different owners —
"Issue" posts only the outbound side (
draft → pending); the receiving side later clicks "Accept" in the shared list (pending → accepted).
Notes and limitations
There is no separate "receiving warehouse"/"sending warehouse" entity on this screen — "from"/"to" are always storage cells, not whole warehouses.
Turnover
What you see
A "From" / "To" period (defaults to the start of the month through today), a "Show" button, an "Export to Excel" button (active once the report is built). A per-part table: Opening balance / Arrivals / Issues / Returns / Transfers / Corrections / Closing balance / Closing amount.
Typical scenarios
Period-end reconciliation: a storekeeper or accountant builds a monthly report, checks opening/closing balances, and exports it to Excel for the archive or accounting department.
Notes and limitations
The report is computed on the fly from the movement log on every "Show" — there is no separate stored turnover table; speed depends on the size of the entire movement log across all time (the log is read in full, then filtered by date).
Addressing
What you see
On the left, a tree of storage cells (Code / Name / Parent) and a form to add a cell (Code, Name, Parent). On the right, after selecting a cell — its balances: checkboxes + Part / Qty, an "Issue (N)" button for the checked rows, and a quick-transfer form (part + quantity signed "+arrival / −issue," a "Transfer" button).
Typical scenarios
- A storekeeper builds out the storage-location hierarchy: warehouse → rack → shelf → cell.
- A quick issue right from a shelf: checks several items, "Issue (N)" opens the quick-issue dialog (see below).
- A manual "+arrival / −issue" on a specific cell — an ordinary stock
movement with that
cell_id.
Notes and limitations
- A cell's balances are not a separate register but a breakdown of the
movement log by
cell_id— "what's on the shelf" is always recomputed fresh, never read from a ready-made table. - At the API level there is a separate "Warehouse" entity (
Warehouse) with a tree of cells linked to it by a dedicated relation (not through ordinary cell-in-cell nesting) — but the cell-creation form on this tab provides no way to pick/create aWarehouse. All cells created from here remain unlinked to any container warehouse; this is a transitional migration state.
Quick-issue dialog
Appears via the "Issue (N)" button: a table of the checked items (quantity — no more than the cell's balance; batch — SELECT method only), Recipient (department), Worker, Link type, Comment fields, an "Issue" button. Under FIFO/LIFO the batch for posting is chosen automatically; the dialog creates and immediately posts an issue document in one call — with no intermediate draft.
Supplier orders
What you see
An orders table: Part (1st line) / Qty (1st line) / Supplier / Expected / Status, a "Lines" button (opens a modal with the order's full line list) and status-transition buttons ("→ Received," "→ Canceled"). Creation form: part, quantity, expected date, supplier (picked from the reference list, or "+ new supplier…" with a name field right in the form).
Typical scenarios
- A storekeeper or procurement officer creates an order directly to a supplier for a routine purchase, bypassing approval through a requisition.
- On actually receiving the goods, they move the status to "Received": for each order line, the system posts a real arrival document (with its own batches), not just a single stock movement.
Notes and limitations
The "Part/Qty (1st line)" columns show only the order's first line — the header duplicates the first line's data for historical reasons (an order used to always be single-line). For a multi-line order (for example, one converted from a requisition with several items), the remaining lines are visible only via "Lines."
Purchase requisitions
What you see
A list of requisitions (Basis / Status, transition buttons "→ Approved," "→ Rejected," "→ Canceled"; for approved ones, "Create order…"). The selected requisition's lines: Part / Qty / Needed by. A requisition creation form (Basis) and a line-add form (part, quantity, "Needed by" date).
Typical scenarios
- A requisition is created as a draft, filled with lines, and approved.
- An approved requisition is converted into a supplier order via the "Create order…" dialog (pick an existing supplier or enter a new one) — the requisition moves to "Ordered" status, and a real supplier order is created with all the requisition's lines.
Notes and limitations
A direct transition of a requisition to "Ordered" status is blocked at the
API level — only via the "Create order…" action (/convert), so a
requisition cannot be marked ordered without actually creating a supplier
order.
Stocktaking
What you see
A list of stocktakings (Comment / Created / Status; for a draft, "Post" and "Cancel" buttons). Lines: Part / Cell / Counted / Per journal / Deviation. Line form: part, batch (or "Not found (new batch)"), cell, counted quantity.
Typical scenarios
A storekeeper physically recounts the balance and enters the actual quantity for each item — "Per journal" and "Deviation" are computed and shown immediately, even before posting (a preview, nothing is saved yet). "Post" writes a compensating stock movement for each line, bringing the system balance in line with the count.
Notes and limitations
After posting, a line's "Deviation" naturally shows a value close to zero — the correction has already been applied and the system balance matches the counted one; this is expected behavior, not a bug.
Production waste and write-off
What you see
A table (Waste part / Kind / Source / Qty / Reason / Status; posted entries get a "Cancel" button). Form: source type ("Order operation" / "Rework order") with a text field for the source ID, the source part and batch, the waste part, kind ("Receive (production waste)" / "Write off permanently"), quantity, reason.
Typical scenarios
- Receiving production waste (for example, material cutoffs) — an arrival document for the waste part is created and immediately posted (a new batch), the source batch's balance is unchanged.
- Permanently writing off defects/losses — an issue document from the source batch is created and immediately posted.
Notes and limitations
- The only screen in the application gated by either of two permissions
(
warehouse.viewORqc.write) — see "Who uses it" above. - The "Operation ID"/"Rework order ID" field is plain text with no dropdown search: there is no ready-made picker for these objects yet, the id must be known beforehand (for example, copied from an already open card).
- Creation and posting are one step, there is no draft; only an already-posted entry can be canceled, and only as a whole.
Ownership groups (contract-level accounting — API only, for now)
The mechanism for separately accounting identical stock by different
contracts/projects within one warehouse is fully implemented in the code
(StockOwnershipGroup — a group reference, StockOwnershipTransfer — a
transfer of quantity from one batch to a new one under a different group,
with the ability to cancel): a batch and a stock movement both have an
ownership_group_id field, and an arrival fills in the default group on
posting if the line did not specify one. But no Warehouse screen has a
list of ownership groups or a transfer form — this is API-only
functionality (support/724 in the legacy version is a full screen with a
"virtual fence" formed around part of a balance and transfers between
groups) with no interface of its own in Vyrab as of this phase's
writing.
MRP (Requirements calculation)
Section /mrp, permission mrp.view.
What you see
A part and quantity picker, a "Calculate" button. After calculating — a table: Part / Kind / Unit / OwnerQty / K1 / Requirement / Substitute. The "Substitute" column is a dropdown of available alternates for the item (if substitutes are set up in the reference for this spot in the product composition); once one or more substitutes are chosen, a "⇄ Recalculate with substitutes" button appears.
Typical scenarios
A process engineer or storekeeper checks what and how much is needed for a hypothetical quantity of a product before creating a real order — a pure BOM calculation with no regard for the warehouse balance, current production, or open orders (unlike "Supply availability" below, which takes this exact same math and adds the warehouse to it).
Notes and limitations
- Walks the product composition (BOM) recursively, up to 20 levels deep.
- K1 comes from the conversion-coefficient reference (Reference data →
Coefficients, Reference data & access) for the specific part/unit pair, and if no record
is found, from the part card's
default_k1. - K2 and standard labor intensity are accounted for only if the tenant has
per-operation consumption norms enabled (the
vgb_norm_type_enabledsetting); otherwise the formula reduces to "OwnerQty × K1" — the most common VOGBIT case. - Managing the norms themselves (
norm_rulerules — a formula or a table, K1/K2/K3) is a separate administrative screen in Reference data (Reference data & access); this page only applies them, it does not edit them.
Supply availability
Section /provision, permission provision.view.
What you see
Three tab-modes: Whole plan, By order, By part. Below them, a run form (for "By part" — part and quantity, for "By order" — pick a production order from a list), a "Calculate" button. After calculating — filters (All / Shortage only / Surplus only; All kinds / Manufactured / Purchased), an "Export to Excel" button, a table: Part / Unit / Requested / Issued / Balance / Min. reserve / Loss factor / In production / Ordered / Balance (colored: red — shortage, blue — surplus). Row actions: an "eye" icon — details (links to related production orders and supplier orders); on a shortage, a "Production order" button (for manufactured items) or "Purchase requisition" button (for purchased items); a "book" icon — open the part in the reference catalog.
Typical scenarios
- The "Whole plan" mode is computed automatically as soon as the screen opens — an overall picture across all active production orders.
- A dispatcher checks the supply availability of a specific order before launching it into production ("By order" mode).
- For a shortage on a purchased item — "Purchase requisition": a dialog with a quantity (defaults to the shortage amount) and a date, creates a draft requisition with one line; approval and conversion into a real supplier order happen separately, on the "Purchase requisitions" tab of the "Warehouse" section.
- For a shortage on a manufactured item — "Production order": a dialog with an order number (auto-generated), a quantity, and a date — creates a real production order directly, with no intermediate approval.
Notes and limitations
- Balance = (Balance + In production + Ordered) − Requested×Loss factor − Min. reserve. The minimum reserve and loss factor are edited on the part's card (Products & orders), not on this screen.
- The "Purchase requisition" path from a shortage creates a
PurchaseRequisition(draft) — this decision was revised on 2026-08-25; previously a shortage created a supplier order directly. Direct creation of a supplier order is still available separately, on the "Supplier orders" tab of the "Warehouse" section, for routine purchases with no formal approval. - "In production" is the sum of quantities on schedule items (
WorkOrder) not yet in done/canceled status; this is not "how much is actually left to finish across routing steps," but a simplified metric for this screen. - "Issued" is the total issue quantity for the part across the entire stock-movement log, not tied to a specific requirement or order: the system has no separate "material requisition" document that would link the two.
Limit cards
Section /limit-cards, permission limit-cards.view.
What you see
A cards table: Card # / Part / Department / Limit / Issued / Limit remaining / Effective from / To / a status badge ("Open" / "Closed"); for open cards, "Issue" and "Close" buttons. Creation form: card number, part, department, limit, effective start and end dates.
Typical scenarios
A storekeeper sets up a card for a department against a specific part with a limit for a period. As the shop makes requests, they click "Issue" — the dialog shows the limit remaining, they enter the quantity being issued — and so on until the limit is exhausted, with no separate document for every issue. Once the work is done, the card is "Closed."
Notes and limitations
- A card is set up entirely by hand — the operator enters the number, part, limit, and dates. This differs from legacy VOGBIT (support/395), where limit cards are generated automatically from an order's composition and routing, and automatically split by department/storage location; Vyrab has no such auto-generation.
- "Issued" is always recomputed as the sum of stock movements with
ref= the card id; an issue beyond the limit remaining is rejected by the server. - Creating a card also reserves the entire limit as a soft reservation
(
StockReservation) on that part; closing the card releases the reservation in the same action. Partial issues do not reduce the reservation itself — it is a coarse "reserved for this card" marker, not an exact reservation remainder.
Arrivals
Section /arrivals, permission arrivals.view.
What you see
A notices table: Date / Part / Qty / Note / Status ("Pending" / "Received"); for pending ones, a "Receive" button. Creation form: part, quantity, date, note.
Typical scenarios
A procurement officer records that material has physically arrived at the warehouse — before the storekeeper has even received it on paper. Once the storekeeper verifies it, they click "Receive": an arrival stock movement is created, and the status changes to "Received."
Notes and limitations
- At the API level, a notice can be linked to a specific supplier order
(
purchase_order_id), but the creation form on this screen does not show that field — the link is de facto unused through the interface. - "Receive" can be done only once (an idempotency key based on the notice's id) and is irreversible in the interface — there is no undo button.
Related sections
- Getting started — roles and permissions, windows and navigation; used here without re-explaining them.
- Dashboard & analytics — the "Arrivals not yet received," "Limit cards running out," and "Purchasing needs attention" dashboard widgets pull their data from here (Arrivals, Limit cards, Purchase requisitions/supplier orders).
- Production & planning — "Flow management": the "Material shortage" widget/summary uses the same Supply availability math.
- Products & orders — the parts card stores
min_reserve_qty/safety_factor/default_k1, used by MRP and Supply availability; component substitutes (has_substitute) are set up there too. The production orders that "Supply availability"'s "By order" mode refers to are also from there. - Cost & prices — an arrival's default price is filled in from the part's current price, maintained by the Price list.
- Reference data & access — unit conversion
coefficients (K1/K2/K3) and consumption-norm rules (
norm_rule) are administered there; here they are only applied when posting documents and in MRP/Supply availability calculations.