# CreateGoodsReceipt

## Permission Scope

goodsReceipt

## Overview

CreateGoodsReceipt creates a draft goods receipt for a company and supplier with one or more receipt lines. Each line optionally references a purchase-order line — PO-unlinked lines are permitted for blind receipts, non-PO purchases, and consignment scenarios. A single receipt may span lines from multiple purchase orders, and may mix PO-linked and PO-unlinked lines.

## Business Rules

- Receipt header requires company and supplier
- At least one receipt line is required
- Receipt lines optionally reference a purchase-order line (`purchaseOrderLineId` is nullable)
- When a PO reference is present, the referenced purchase-order line must exist and have open quantity
- When a PO reference is present, the parent purchase order must not be cancelled or closed
- When a PO reference is present, the parent purchase order must belong to the same company and supplier as the receipt header
- Each receipt line must record a received quantity greater than zero
- Each 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
- Goods receipts are created in `DRAFT` status

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{At least one line?}
    B -->|No| C[Return EMPTY_RECEIPT_LINES]
    B -->|Yes| D{For each PO-linked line: references a valid PO line?}
    D -->|No| E[Return line validation error]
    D -->|Yes| F{PO-linked lines: same company and supplier as header?}
    F -->|No| G[Return COMPANY_OR_SUPPLIER_MISMATCH]
    F -->|Yes| H{PO-linked lines: all referenced POs receivable?}
    H -->|No| I[Return PURCHASE_ORDER_NOT_RECEIVABLE]
    H -->|Yes| J{Each line has qty > 0 and PO-linked lines within open qty?}
    J -->|No| K[Return quantity validation error]
    J -->|Yes| L[Insert goods receipt in DRAFT]
    L --> M[Return created receipt]
```

## External Dependencies

- None

## Error Scenarios

- **EMPTY_RECEIPT_LINES**: No goods-receipt lines were provided
- **PURCHASE_ORDER_LINE_NOT_FOUND**: Referenced purchase-order line does not exist
- **PURCHASE_ORDER_NOT_RECEIVABLE**: Referenced purchase order is cancelled, closed, or otherwise unavailable for receipt
- **COMPANY_OR_SUPPLIER_MISMATCH**: A referenced purchase-order line belongs to a purchase order with a different company or supplier than the receipt header
- **NO_OPEN_RECEIPT_QUANTITY**: Purchase-order line has no remaining open quantity to receive
- **INVALID_RECEIVED_QUANTITY**: Received quantity is zero or negative

## Test Cases

- creates a draft goods receipt with lines from a single ordered purchase order
- creates a draft goods receipt with lines from multiple purchase orders of the same supplier (consolidated shipment)
- creates a draft goods receipt with PO-unlinked lines (blind receipt)
- creates a draft goods receipt with a mix of PO-linked and PO-unlinked lines
- creates a draft goods receipt against a partially received purchase order
- returns error when no receipt lines are provided
- returns error when a purchase-order line does not exist
- returns error when a referenced purchase order is cancelled or closed
- returns error when a receipt line references a purchase order with a different company
- returns error when a receipt line references a purchase order with a different supplier
- returns error when received quantity is zero or negative
- returns error when a receipt line has no open quantity
- returns error when PO-unlinked line has zero or negative quantity
- returns error when PO is not found for a PO-linked line
- uses PO line defaults for itemId, unitId, requiresInventoryHandoff, and destinationSite
- falls back to PO header receivingSiteId when line receivingSiteId is null
