Batches, expiry & serial numbers

Overview
For goods requiring proof, stock alone is not enough — what counts is which item went where. This module keeps batches, best-before dates and serial numbers and turns them into a usage record.
The serious case it is built for: a supplier reports a faulty batch. The question is then not "do we still have any of it" but "who did it go to" — and only the usage record answers that.
Core tasks
See the proof requirement per item. Not every item needs traceability. Which items demand one is shown here; the requirement itself is set through the interface (see "Fields in detail").
See batch stock. Stock per batch, with shelf life.
Produce a usage record. Where a batch or serial number went.
Block a batch. A blocked batch is no longer available for sale and dispatch. That is the fastest move in a recall — faster than searching every order individually.
Cost price per unit. On goods receipt every serial unit and every batch takes over the cost price of the order line. It is the basis of the margin scheme (section 25a German VAT Act): the margin of exactly this unit is taxed, not an average. A return keeps the cost price of the purchase; an unknown cost price stays unknown and is never assumed to be 0.
Fields in detail
The What it does column answers what changes in the system. The grey name behind it is the API field: the same thing runs under that name through automation, import and AI tools.
This page has exactly one input form: blocking a batch. Batches and serial numbers themselves arise from goods receipts and cannot be created by hand — a hand-made batch would be stock without a movement, and that is precisely the gap an audit looks for.
Block a batch
| Field | Required | Values / format | What it does |
|---|---|---|---|
Reason for blocking reason | yes | text, at most 200 characters | Why the batch is taken out of circulation. Without a reason the block is rejected: a block that halts selling has to be traceable afterwards. The reason then appears in the status column of the batch list. |
Lifting the block needs no field — it is a separate action with the same permission.
Proof requirement per item — interface and automation only
The page shows the proof requirement per item; it is created and changed through the interface (POST/PATCH on /v1/batch-serial/product-tracking). Switching it over is only possible while no units without proof are in stock — otherwise the next issue would be goods without a batch.
| Field | Values / format | What it does |
|---|---|---|
productId | an existing article (required when creating) | Which article the requirement applies to. |
mode | none · batch · serial | Which proof is demanded: none, a batch (a quantity) or a serial number (exactly one piece). |
expiryRequired | yes/no | Whether a best-before date is demanded as well. Requires batch management — the date hangs off the batch, not off the article. |
minShelfLifeDays | 0 to 3650 days | Minimum remaining shelf life on dispatch. Goods below it are no longer offered by the FEFO suggestion; 0 means no rule. |
What the batch list shows
| Column | Field | What it shows |
|---|---|---|
| Batch | batchNumber | The batch identifier. It accompanies the goods from receipt to the customer. |
| Article | productId | What the batch belongs to. |
| Remaining | remainingQty | What is left of the quantity originally received (receivedQty). |
| Best before | expiresAt | The best-before date; empty for non-perishable goods. Picking takes the shortest remaining shelf life (shelfLifeDays) first — otherwise goods expire on the shelf while fresher ones go out. |
| Status | blocked, blockReason | Blocked or free, with the reason for the block. Whether a batch may go out at all today is in deliverable — it combines block, remaining quantity and remaining shelf life. |
The usage record above the list is not a form but a search: a batch or serial number, answered from the movement journal — not from remaining stock. That is why it also finds goods that left the building long ago.
Settings & permissions
- Module
module.batchserial. batchserial.tracking.view/.managefor traceability,batchserial.batch.blockfor
blocking — a distinct permission, because a block halts selling.
- Labels carrying batch details are printed by the print module.
- Without the proof requirement on the item no traceability arises — not retrospectively either.
FAQ & troubleshooting
An item has no batches. Then it is not set as requiring proof. That cannot be established retrospectively.
A blocked batch still appears. Check whether goods already dispatched are affected — the block acts on stock, not on what has left the building. The usage record is for that.
The best-before date is not considered. It hangs off the batch. Without batch management there is no best-before date.
I cannot block. Then batchserial.batch.block is missing.