# CreatePurchaseOrder

## Permission Scope

purchaseOrder

## Overview

CreatePurchaseOrder creates a new purchase order in `DRAFT` status with supplier, company, receiving context, payment-term snapshot seed, and one or more commercial lines.

## Business Rules

- Company, supplier, and at least one line are required
- Supplier must exist, be active, and carry the `SUPPLIER` role
- Each line must reference an active item, have quantity greater than zero, and have a non-negative unit price — ACTIVE is required because this is a new transaction entry point; inactive items should not start new procurement (contrast with post-order flows like PostGoodsReceipt where inactive items are accepted to avoid blocking in-progress fulfillment)
- Lines that require physical receipt must identify a valid receiving site
- If a default purchase payment term is inherited from the supplier profile, it must be active at creation time
- Order is always created with `orderStatus` = `DRAFT`; `receiptStatus` and `billingStatus` are not set at creation

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Supplier valid and active?}
    B -->|No| C[Return supplier error]
    B -->|Yes| D{At least one line?}
    D -->|No| E[Return EMPTY_PURCHASE_ORDER_LINES]
    D -->|Yes| F{Validate each line item, quantity, price, site}
    F -->|No| G[Return line validation error]
    F -->|Yes| H{Resolve default payment term if needed}
    H -->|Invalid| I[Return payment term error]
    H -->|Valid| J[Insert order and lines in DRAFT]
    J --> K[Return created order]
```

## External Dependencies

- [business-partner::GetPartner](../../../business-partner/docs/queries/GetPartner.md) - Validate supplier identity, status, and supplier role
- [item-management::GetItem](../../../item-management/docs/queries/GetItem.md) - Validate each referenced item and item status
- [organization::GetSite](../../../organization/docs/queries/GetSite.md) - Validate receiving site references

## Error Scenarios

- **SUPPLIER_NOT_FOUND**: Referenced supplier does not exist
- **SUPPLIER_NOT_ACTIVE**: Referenced supplier is inactive
- **PARTNER_NOT_SUPPLIER**: Referenced partner does not carry the `SUPPLIER` role
- **EMPTY_PURCHASE_ORDER_LINES**: No purchase-order lines were provided
- **ITEM_NOT_FOUND**: Referenced item does not exist
- **ITEM_NOT_ACTIVE**: Referenced item is inactive
- **INVALID_QUANTITY**: Ordered quantity is zero or negative
- **INVALID_UNIT_PRICE**: Unit price is negative
- **RECEIVING_SITE_NOT_FOUND**: Referenced receiving site does not exist
- **RECEIVING_SITE_REQUIRED**: A physical-receipt line has no receiving site
- **PAYMENT_TERM_INACTIVE**: Inherited default payment term is inactive

## Test Cases

- creates a draft purchase order with valid supplier and lines
- inherits default payment term from supplier profile when present
- returns error when supplier does not exist
- returns error when supplier is inactive
- returns error when partner is not a supplier
- returns error when no lines are provided
- returns error when an item does not exist
- returns error when an item is inactive
- returns error when quantity is zero or negative
- returns error when unit price is negative
- returns error when receiving site is missing for a physical line
- returns error when receiving site does not exist
- returns error when inherited payment term is inactive
- creates a purchase order with lines that skip physical receipt when requiresPhysicalReceipt is false
- creates a purchase order with optional line fields defaulting to null
- falls back to documentReceivingSiteId when line receivingSiteId is not set
