# GoodsReceipt

## Description

GoodsReceipt is the purchase-side confirmation that goods or services were received from the supplier. It records one receipt event with one or more receipt lines. Each line optionally references a purchase-order line — receipts can be created without a PO reference to support blind receipts, non-PO purchases (spot buys, samples, donations), and consignment scenarios. A single receipt may span lines from multiple purchase orders, supporting consolidated shipments where a supplier delivers against several orders in one delivery.

The receipt is a record of the physical fact that goods arrived. The matching of receipts against purchase orders and supplier bills is a separate, downstream step. Receipt lines that reference a purchase-order line update PO receiving progress when posted; PO-unlinked receipt lines are posted without affecting any purchase order. The PO reference can be assigned or changed on a draft receipt before posting.

Purchase owns the procurement confirmation and directly creates a DRAFT stock movement for stock-item lines. The inventory module owns the subsequent stock movement lifecycle (confirmation and execution). The receipt header carries company and supplier context; the relationship to purchase orders is expressed through receipt lines optionally referencing purchase-order lines, mirroring the same line-level referencing pattern used by PurchaseBill.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createGoodsReceipt
    Draft --> Draft: updateGoodsReceipt
    Draft --> Posted: postGoodsReceipt
    Draft --> Cancelled: cancelGoodsReceipt
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| post | DRAFT | POSTED | [postGoodsReceipt](../commands/PostGoodsReceipt.md) |
| cancel | DRAFT | CANCELLED | [cancelGoodsReceipt](../commands/CancelGoodsReceipt.md) |

### Command Definitions

- [createGoodsReceipt](../commands/CreateGoodsReceipt.md) - Create a draft receipt with lines optionally referencing purchase-order lines
- [updateGoodsReceipt](../commands/UpdateGoodsReceipt.md) - Correct draft receipt quantities, dates, or line composition before posting
- [postGoodsReceipt](../commands/PostGoodsReceipt.md) - Validate tolerance, post the receipt, update order progress, and create a DRAFT stock movement for stock-item lines
- [cancelGoodsReceipt](../commands/CancelGoodsReceipt.md) - Cancel a draft receipt before it affects purchase-order fulfillment

### Query Definitions

- [getGoodsReceipt](../queries/GetGoodsReceipt.md) - Retrieve a goods receipt with all receipt lines

### Models

- GoodsReceipt
- GoodsReceiptLine

### Invariants

- Every goods receipt belongs to exactly one company and one supplier
- Receipt lines that reference a purchase-order line must reference one that belongs to a purchase order with the same company and supplier as the receipt header
- Receipt lines may omit the purchase-order-line reference (PO-unlinked lines) for blind receipts, non-PO purchases, or consignment scenarios
- A single receipt may contain lines referencing purchase-order lines from different purchase orders (consolidated shipment), and may mix PO-linked and PO-unlinked lines
- Every receipt line records a received quantity greater than zero
- Only `POSTED` receipts contribute to purchase-order received quantities and 3-way bill matching
- A receipt line cannot post against a purchase-order line whose parent purchase order is cancelled or closed
- PO-unlinked receipt lines can be posted without affecting any purchase order
- Over-receipt beyond configured tolerance is invalid unless an explicit override path is recorded by policy
- Service or non-stock receipt lines do not require downstream warehouse execution even when the procurement receipt is posted
- Posted receipts are immutable; future corrections must use a compensating workflow instead of mutating receipt history in place
- Every goods receipt line belongs to exactly one goods receipt
- When a purchase-order-line reference is present, the parent purchase order must belong to the same company and supplier as the receipt
- Received quantity must be positive; when PO-linked, it must be within the tolerance of the open ordered quantity
- Every receipt line must carry a unit of measure; PO-linked lines inherit unitId from the purchase-order line when not explicitly provided, PO-unlinked lines must provide unitId explicitly
- Item defaults from the referenced purchase-order line when not explicitly provided; PO-unlinked lines should provide item explicitly

### Relationships

- **Belongs To BusinessPartner**: Each receipt references one supplier [BusinessPartner](../../../business-partner/docs/models/BusinessPartner.md)
- **Has Many GoodsReceiptLines**: Each receipt contains one or more line-level receipt confirmations
- **References PurchaseOrder (via lines)**: Receipt lines optionally reference one or more [PurchaseOrder](./PurchaseOrder.md) lines; the receipt header does not carry a direct purchase-order foreign key
- **References Item**: Receipt lines trace back to one [Item](../../../item-management/docs/models/Item.md) through the purchase-order line or directly via `itemId`
- **Triggers receiveStock**: Posted stock receipts call [receiveStock](../../../inventory/docs/commands/ReceiveStock.md) via the inventory module to immediately create InventoryLedger entries and update stock levels. The `toBlocked=true` parameter is used for items requiring inspection holds
- **Referenced By ThreeWayMatchEvent**: Receipt lines participate in [ThreeWayMatchEvent](./ThreeWayMatchEvent.md) records that capture the explicit matching relationship between bill lines and receipt lines
- **GoodsReceiptLine References PurchaseOrderLine (nullable)**: `purchaseOrderLineId` optionally identifies which order line this receipt covers; null for PO-unlinked receipts
- **GoodsReceiptLine References Item (cross-module)**: `itemId` optionally overrides the item from the purchase-order line; should be provided explicitly for PO-unlinked lines
