# CreatePurchaseBill

## Permission Scope

purchaseBill

## Overview

CreatePurchaseBill creates a supplier bill in `DRAFT` status with invoice identity, line quantities, tax snapshot inputs, and the payment-term snapshot that will later drive payable scheduling. Bill lines optionally reference a purchase-order line — PO-unlinked lines are permitted for invoices without a corresponding purchase order (spot purchases, expense-type invoices).

## Business Rules

- Company, supplier, invoice number, invoice date, and at least one line are required
- Duplicate supplier invoice numbers are rejected within the same supplier and company
- Bill lines optionally reference a purchase-order line (`purchaseOrderLineId` is nullable)
- When a PO reference is present, the referenced purchase-order line must exist
- When a PO reference is present, the parent purchase order must not be cancelled
- Each line must record billed quantity greater than zero
- Each bill 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
- Assigned payment term snapshot and supplier tax identification must be captured at create time
- Item ACTIVE status is not checked — billing is a post-order flow that settles an already-committed purchase order, so inactive items must still be billable to avoid blocking in-progress fulfillment
- New purchase bills are created in `DRAFT` status

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Supplier and company valid?}
    B -->|No| C[Return supplier or company error]
    B -->|Yes| D{Duplicate invoice number?}
    D -->|Yes| E[Return DUPLICATE_SUPPLIER_INVOICE_NUMBER]
    D -->|No| F{At least one valid bill line?}
    F -->|No| G[Return line validation error]
    F -->|Yes| H[Snapshot payment term and supplier tax identity]
    H --> I[Insert purchase bill in DRAFT]
    I --> J[Return created bill]
```

## External Dependencies

- [business-partner::GetPartner](../../../business-partner/docs/queries/GetPartner.md) - Validate supplier identity and status
- [business-partner::ListPartnerIdentificationsByPartner](../../../business-partner/docs/queries/ListPartnerIdentificationsByPartner.md) - Source supplier tax identification snapshot

## Error Scenarios

- **SUPPLIER_NOT_FOUND**: Referenced supplier partner does not exist
- **DUPLICATE_SUPPLIER_INVOICE_NUMBER**: Supplier invoice number already exists in the same company and supplier scope
- **EMPTY_BILL_LINES**: No purchase-bill lines were provided
- **PURCHASE_ORDER_LINE_NOT_FOUND**: Referenced purchase-order line does not exist
- **INVALID_BILLED_QUANTITY**: Billed quantity is zero or negative
- **PURCHASE_ORDER_CANCELLED**: Referenced purchase order is cancelled
- **PAYMENT_TERM_SNAPSHOT_MISSING**: No valid payment-term snapshot is available for the bill
- **SUPPLIER_TAX_IDENTIFICATION_MISSING**: Required supplier tax identification cannot be snapshotted

## Test Cases

- creates a draft purchase bill with valid line references
- creates a draft purchase bill with PO-unlinked lines
- snapshots payment-term data at create time
- snapshots supplier tax identification at create time
- returns error when supplier does not exist
- returns error when invoice number is duplicated
- returns error when no bill lines are provided
- returns error when a purchase-order line does not exist
- returns error when billed quantity is zero or negative
- returns error when referenced purchase order is cancelled
- returns error when no payment-term snapshot is available
- returns error when supplier tax identification cannot be snapshotted
- returns error when PO-unlinked bill line has zero or negative quantity
- returns error when PO is not found for a PO-linked bill line
- uses PO line unitPrice as default billedUnitPrice when not provided
- creates PO-unlinked bill line with provided optional fields
