# SalesOrder

## Description

SalesOrder is the primary commercial commitment between one company and one customer. It captures customer, channel, billing, shipping, payment-term, and pricing context before downstream fulfillment or invoicing occurs, and it preserves the commercial baseline that shipment, invoice, and credit-note records must reference later. The aggregate includes one or more SalesOrderLine children that track ordered, shipped, invoiced, and remaining quantities per sellable item.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createSalesOrder
    Draft --> Submitted: submitSalesOrder
    Submitted --> Draft: rejectSalesOrder
    Submitted --> Confirmed: confirmSalesOrder
    Confirmed --> CreditHold: placeSalesOrderOnCreditHold
    PartiallyShipped --> CreditHold: placeSalesOrderOnCreditHold
    Shipped --> CreditHold: placeSalesOrderOnCreditHold
    PartiallyInvoiced --> CreditHold: placeSalesOrderOnCreditHold
    Invoiced --> CreditHold: placeSalesOrderOnCreditHold
    CreditHold --> Confirmed: releaseSalesOrderCreditHold
    CreditHold --> PartiallyShipped: releaseSalesOrderCreditHold
    CreditHold --> Shipped: releaseSalesOrderCreditHold
    CreditHold --> PartiallyInvoiced: releaseSalesOrderCreditHold
    CreditHold --> Invoiced: releaseSalesOrderCreditHold
    Confirmed --> PartiallyShipped: postShipment
    PartiallyShipped --> Shipped: postShipment
    Confirmed --> PartiallyInvoiced: issueSalesInvoice
    PartiallyShipped --> PartiallyInvoiced: issueSalesInvoice
    Shipped --> PartiallyInvoiced: issueSalesInvoice
    PartiallyInvoiced --> Invoiced: issueSalesInvoice
    Confirmed --> Cancelled: cancelSalesOrder
    CreditHold --> Cancelled: cancelSalesOrder
    Draft --> Cancelled: cancelSalesOrder
    Submitted --> Cancelled: cancelSalesOrder
    Confirmed --> Closed: closeSalesOrder
    Shipped --> Closed: closeSalesOrder
    Invoiced --> Closed: closeSalesOrder
    PartiallyShipped --> Closed: closeSalesOrder
    PartiallyInvoiced --> Closed: closeSalesOrder
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| submit | DRAFT | SUBMITTED | [submitSalesOrder](../commands/SubmitSalesOrder.md) |
| reject | SUBMITTED | DRAFT | [rejectSalesOrder](../commands/RejectSalesOrder.md) |
| confirm | SUBMITTED | CONFIRMED | [confirmSalesOrder](../commands/ConfirmSalesOrder.md) |
| placeCreditHold | CONFIRMED, PARTIALLY_SHIPPED, PARTIALLY_INVOICED, SHIPPED, INVOICED | CREDIT_HOLD | [placeSalesOrderOnCreditHold](../commands/PlaceSalesOrderOnCreditHold.md) |
| releaseCreditHold | CREDIT_HOLD | CONFIRMED | [releaseSalesOrderCreditHold](../commands/ReleaseSalesOrderCreditHold.md) |
| partialShip | CONFIRMED | PARTIALLY_SHIPPED | [postShipment](../commands/PostShipment.md) |
| completeShip | PARTIALLY_SHIPPED | SHIPPED | [postShipment](../commands/PostShipment.md) |
| partialInvoice | CONFIRMED, PARTIALLY_SHIPPED, SHIPPED | PARTIALLY_INVOICED | [issueSalesInvoice](../commands/IssueSalesInvoice.md) |
| completeInvoice | PARTIALLY_INVOICED | INVOICED | [issueSalesInvoice](../commands/IssueSalesInvoice.md) |
| cancel | CONFIRMED, CREDIT_HOLD, DRAFT, SUBMITTED | CANCELLED | [cancelSalesOrder](../commands/CancelSalesOrder.md) |
| close | CONFIRMED, PARTIALLY_SHIPPED, SHIPPED, PARTIALLY_INVOICED, INVOICED | CLOSED | [closeSalesOrder](../commands/CloseSalesOrder.md) |

### Command Definitions

- [createSalesOrder](../commands/CreateSalesOrder.md) - Create a new draft sales order with initial line-level commercial context.
- [updateSalesOrder](../commands/UpdateSalesOrder.md) - Revise mutable draft fields and line details before submission or explicit revision flow.
- [submitSalesOrder](../commands/SubmitSalesOrder.md) - Move a draft order into review-ready submitted status.
- [rejectSalesOrder](../commands/RejectSalesOrder.md) - Return a submitted order to draft with a preserved rejection reason.
- [confirmSalesOrder](../commands/ConfirmSalesOrder.md) - Freeze commercial terms and make the order executable.
- [placeSalesOrderOnCreditHold](../commands/PlaceSalesOrderOnCreditHold.md) - Suspend further shipment or invoice release with an explicit commercial hold reason.
- [releaseSalesOrderCreditHold](../commands/ReleaseSalesOrderCreditHold.md) - Restore an order from credit hold to the executable confirmed lifecycle.
- [cancelSalesOrder](../commands/CancelSalesOrder.md) - Cancel an order that has not progressed into an irreversible downstream state.
- [closeSalesOrder](../commands/CloseSalesOrder.md) - Close the remaining open balance when execution is complete or written off by policy.

### Query Definitions

- [getSalesOrder](../queries/GetSalesOrder.md) - Retrieve one sales order with customer, status, line, and progress details.
- [listSalesOrders](../queries/ListSalesOrders.md) - List sales orders for operational work queues and sales monitoring.

### Models

- SalesOrder
- SalesOrderLine

### Invariants

- Every sales order belongs to exactly one company and one customer, and all child lines stay within that same company scope.
- A sales order always contains at least one sales order line before it can leave DRAFT.
- Only ACTIVE business partners carrying the CUSTOMER role can be used as the customer on a new or confirmed sales order.
- Each line preserves the applied unit price, currency, matched price-rule reference, and payment-term snapshot so later master-data edits do not rewrite the confirmed commercial baseline.
- When the order is in CREDIT_HOLD, no new shipment posting or invoice issuance may proceed until the hold is released.
- When credit hold is released, the order returns to the state that matches its preserved line progress at the time of hold — CONFIRMED, PARTIALLY_SHIPPED, SHIPPED, PARTIALLY_INVOICED, or INVOICED — so prior fulfillment and billing evidence are never lost.
- The cumulative shipped quantity and cumulative invoiced quantity for each line can never exceed the ordered quantity unless a documented override flow is introduced later.
- An order can move to CLOSED only when every remaining obligation is fulfilled, cancelled, or explicitly written off by policy.

### Relationships

- **Owns SalesOrderLine**: SalesOrder is the aggregate root for one or more SalesOrderLine children.
- **References BusinessPartner (cross-module)**: `customerId`, billing address snapshot, shipping address snapshot, and customer tax identifiers come from business-partner.
- **References SalesPaymentTerm**: `paymentTermId` and a normalized payment-term snapshot drive downstream invoice due schedules.
- **References Channel**: `channelId` is optional and links internally entered or channel-originated demand to its commercial channel context.
- **Referenced By Shipment**: Shipment records consume open sales-order quantities for fulfillment evidence.
- **Referenced By SalesInvoice and SalesCreditNote**: Billing documents must point back to the originating commercial commitment.
- **Referenced By ChannelOrder**: Converted channel orders store the internal sales-order linkage after normalization succeeds.
