# IssueSalesInvoice

## Permission Scope

salesBilling

## Overview

IssueSalesInvoice validates billing policy and freezes the invoice as customer-facing commercial evidence. It snapshots due schedule, payment-term, tax, and pricing context for downstream receivable processing.

## Business Rules

- Only DRAFT invoices may be issued.
- Shipment-gated invoices must not exceed posted shipment quantity unless policy explicitly allows pre-shipment billing.
- Order-based invoices must not exceed ordered quantity or diverge from the order price snapshot.
- Issueing the invoice must compute and store the invoice due schedule.

## Process Flow

```mermaid
flowchart TD
    A[Receive issue request] --> B[Load draft invoice]
    B --> C[Validate billing policy and line quantities]
    C --> D[Calculate due schedule and snapshot commercial context]
    D --> E[Set status to ISSUED]
    E --> F[Return issued invoice]
```

## External Dependencies

- [getSalesInvoice](../queries/GetSalesInvoice.md) - Load invoice and line context.
- [calculateInvoiceDueSchedule](../queries/CalculateInvoiceDueSchedule.md) - Compute receivable due schedule from invoice date and payment term.
- [getShipment](../queries/GetShipment.md) - Validate posted shipment evidence for shipment-gated billing.

## Error Scenarios

- **SALES_INVOICE_NOT_FOUND**: Referenced sales invoice does not exist
- **INVALID_INVOICE_STATUS**: Invoice status does not allow this operation
- **BILLING_POLICY_VIOLATION**: Invoice quantity exceeds allowed order-based or shipment-based quantity.
- **DUE_SCHEDULE_NOT_COMPUTABLE**: The assigned payment term cannot produce a due schedule.

## Test Cases

- issues an order-based invoice when quantities and prices are valid
- issues a shipment-gated invoice when posted shipment evidence exists
- throws when draft invoice exceeds allowed billed quantity
- throws when due schedule cannot be computed
