PhoenixKitWarehouse.GoodsReceipts (PhoenixKitWarehouse v0.1.0)

Copy Markdown View Source

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

add_source_ref(receipt, type, uuid)

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.

correct_goods_receipt(receipt, attrs)

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.

create_from_supplier_order(supplier_order, actor_uuid)

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.

create_goods_receipt(attrs)

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.

get_goods_receipt(uuid)

Returns {:ok, receipt} or {:error, :not_found}.

get_goods_receipt!(uuid)

Returns the goods receipt or raises.

import_from_supplier_orders(receipt, so_uuids, actor_uuid)

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}.

list_goods_receipts(opts \\ [])

Lists non-deleted goods receipts ordered by number descending (newest first).

post_goods_receipt(receipt, performed_by_uuid)

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).
  • Lines with received_quantity == 0 contribute no stock change.
  • Merges previous_quantity into the persisted lines (audit trail).
  • Flips status → "posted", sets posted_at and performed_by_uuid.

Returns {:error, :not_draft} for non-draft receipts.

remove_source_ref(receipt, type, uuid)

Detaches a traceability reference from a goods receipt. No-op when the {type, uuid} pair isn't present.

set_storage_folder(receipt, storage_folder_uuid)

Sets the storage_folder_uuid on a goods receipt. Works on documents in any status.

soft_delete(receipt, actor_uuid)

Soft-deletes a draft goods receipt. Returns {:error, :not_draft} for posted documents.

update_draft(goods_receipt, attrs)

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.