Context for managing goods receipts (goods arrival onto the warehouse).
A goods receipt registers the arrival of goods from a supplier order and INCREASES warehouse stock when posted. There is NO repost — posting a goods receipt is an additive delta operation. Correction after posting is limited to note and storage_folder only.
Summary
Functions
Manually attaches a traceability reference to a goods receipt.
Corrects the note and/or storage_folder_uuid of a goods receipt without changing status or lines. Works on documents in any status. Lines are immutable once posted.
Creates a draft goods receipt from a posted supplier order.
Creates a new draft goods receipt.
Returns {:ok, receipt} or {:error, :not_found}.
Returns the goods receipt or raises.
Imports lines from a list of posted supplier orders into an existing draft goods receipt.
Lists non-deleted goods receipts ordered by number descending (newest first).
Posts a goods receipt in an Ecto.Multi transaction. INCREASES warehouse stock.
Detaches a traceability reference from a goods receipt. No-op when the
{type, uuid} pair isn't present.
Sets the storage_folder_uuid on a goods receipt.
Works on documents in any status.
Soft-deletes a draft goods receipt. Returns {:error, :not_draft} for posted documents.
Updates a draft goods receipt. Returns {:error, :not_draft} when not in
draft status.
Functions
Manually attaches a traceability reference to a goods receipt.
"internal_order" and "supplier_order" are always valid (intra-module).
Any other type must be a kind registered via PhoenixKitWarehouse.SourceKinds.
Pure metadata — does not touch lines and is not gated to draft status.
A duplicate {type, uuid} pair is a no-op.
Corrects the note and/or storage_folder_uuid of a goods receipt without changing status or lines. Works on documents in any status. Lines are immutable once posted.
Creates a draft goods receipt from a posted supplier order.
Lines are copied from the supplier order with:
ordered_quantity= the supplier order's ordered_quantity (snapshot)received_quantity= 0 (default; keeper edits actual received)
Sets supplier_order_uuid, supplier_uuid, and location_uuid from the source order.
Creates a new draft goods receipt.
location_uuid defaults to the configured default warehouse when not given.
created_by_uuid is set programmatically — not via cast.
Returns {:ok, receipt} or {:error, :not_found}.
Returns the goods receipt or raises.
Imports lines from a list of posted supplier orders into an existing draft goods receipt.
Lines are merged by item_uuid (ordered_quantity summed across all SOs). supplier_uuid and supplier_order_uuid are taken from the first selected SO (primary SO). source_refs are enriched with the full traceability chain — each selected supplier order, the internal order(s) that fed it, and the customer order(s)/sub-order(s) that fed those — and saved via update_draft.
Returns {:ok, updated_receipt} or {:error, reason}.
Lists non-deleted goods receipts ordered by number descending (newest first).
Posts a goods receipt in an Ecto.Multi transaction. INCREASES warehouse stock.
- Locks the row FOR UPDATE and re-checks status == "draft" (prevents double-posting).
- Deduplicates lines by item_uuid.
- For each line with received_quantity > 0:
- Captures
previous_quantity= current on-hand for audit. - Calls
StockLedger.receive_quantity/3(additive stock delta).
- Captures
- Lines with received_quantity == 0 contribute no stock change.
- Merges
previous_quantityinto the persisted lines (audit trail). - Flips status → "posted", sets posted_at and performed_by_uuid.
Returns {:error, :not_draft} for non-draft receipts.
Detaches a traceability reference from a goods receipt. No-op when the
{type, uuid} pair isn't present.
Sets the storage_folder_uuid on a goods receipt.
Works on documents in any status.
Soft-deletes a draft goods receipt. Returns {:error, :not_draft} for posted documents.
Updates a draft goods receipt. Returns {:error, :not_draft} when not in
draft status.
Locks the row FOR UPDATE and re-checks status == "draft" in the DB (not just the in-memory struct) so a stale tab cannot overwrite a receipt that was posted concurrently by another tab/user.