By Isaac Muthui, CEO, Tamalaki Business Network Ltd. Originally published at factoraerp.com.
In food manufacturing ERPs, dispatch is often modelled as "create delivery note → reduce stock." That model fails the moment a held pallet looks identical to a released one, or FEFO loses to "whatever was nearest the door." The operational risk is not forgetting to print a DN. It is letting a status machine lie: WarehouseHold stock riding out on a DispatchOrder that should only allocate Released lots.
This piece is for builders modelling warehouse status, pick allocation and outbound gates. The factory-floor checklist behind it lives on the FactoraERP blog (canonical link above).
The domain objects you need
At minimum:
- FinishedGoodsLot — batch/lot identity, expiry / best-before, quantity, location.
-
WarehouseStatus — at least
hold|quarantine|released|rejected(names vary; the invariant matters). - SalesOrder / DeliveryNote — customer, lines (SKU, qty), optional lot constraints.
- PickList — allocated lot lines for a delivery (SKU, lot_id, qty).
- FEFOPolicy — allocation rule: earliest expiry among released lots that meet remaining-life rules.
- DispatchOrder — vehicle, load lines (must equal pick), destination drops, documents.
- DispatchSignOff — named user, timestamp, vehicle registration, sample counts / pallet IDs.
Sketch:
FinishedGoodsLot.status ∈ {hold, quarantine, released, rejected}
SalesOrder 1---* DeliveryNoteLine
PickList allocates only lots where status == released
FEFOPolicy orders candidate lots by expiry ASC (+ remaining-life filter)
DispatchOrder 1---* LoadLine (lot_id, qty) ⊆ PickList
DispatchOrder 1---0..1 DispatchSignOff (required before ship_state = departed)
Rule: held lots cannot ship
Encode the gate checklist as preconditions, not as a PDF:
- Every
LoadLine.lot.status == releasedat allocation and again at sign-off (status can flip after pick). -
sum(LoadLine.qty)per SKU matchesDeliveryNote(short picks require an amended DN before depart). - Allocation ran through FEFO (or recorded exception with reason + approver).
- Pack condition / cold-chain checks are checklist events on
DispatchOrderwhen product type requires them. - Document snapshot (DN + customer PO refs) matches load lines at sign-off time.
- Customer / drop identity on load zones matches DN destinations (no silent multi-customer mash).
-
DispatchSignOffexists beforedispatch_statemay leavestaged→departed.
If any gate fails, the API should refuse mark_departed, not show a warning toast warehouse staff click through while the gate opens.
Status machine vs physical bay
The hard bug is drift: UI says released, pallet still has a faded hold tag; or system says hold, picker already staged it. Two mitigations:
- Re-validate status at sign-off, not only at allocate.
-
Location constraints: hold/quarantine locations are not valid sources for
PickListcreation.
allocate(lot) → require lot.status == released && lot.location.pickable
sign_off(load) → for each line: reload lot; require still released
depart(load) → require sign_off_id != null
FEFO as allocation, not a report
A "FEFO report" operators ignore is not FEFO. Put earliest-expiry selection inside create_pick_list:
- Candidate set = released lots for SKU with qty available and remaining life ≥ customer/contract minimum (if any).
- Sort by expiry ascending, then allocate.
- Persist
allocation_method = fefo | exceptionon the pick; exceptions needapproved_by.
That is what later powers honest recall queries: which outbound shipments contain lot X? If dispatch allowed a silent substitution, your graph is fiction.
Vehicle load and cold chain as optional extensions
Do not overbuild day one. For chilled/frozen SKUs, attach a ColdChainCheck (pre-cool yes/no, temperature reading, checked_by) required before sign-off. Ambient SKUs skip the entity. Same pattern as allergen checks on changeovers: required when the product type says so.
What not to overbuild
You do not need a full WMS on day one. You do need:
- A real status enum shipping cannot ignore
- Pick allocation that refuses non-released lots
- FEFO (or explicit exception) at allocate time
- Re-check status + named sign-off before departed
Paper checklists work for tiny plants. Software earns its keep when lot count, holds mid-shift and multi-drop trucks outgrow the notebook—and when "the customer is waiting" keeps defeating your SOPs.
Isaac Muthui, CEO, Tamalaki Business Network Ltd
Top comments (0)