# Shipment Fulfillment

## Overview

Shipment Fulfillment records what quantity from a sales order has actually been committed to outbound delivery. A `Shipment` references one sales order and one or more sales order lines, captures ship dates, shipment quantities, delivery addresses, and external tracking context, and updates each line's shipped progress. The shipment document is the sales-side confirmation that the customer commitment moved into physical fulfillment.

This feature deliberately separates **commercial shipment control** from **warehouse stock execution**. Sales owns the shipment document, backorder logic, customer-facing shipment status, and matching rules against the order; inventory remains the owner of reservation ledgers, stock issue execution, lot or serial state, and on-hand updates. The named handoff contract from sales to inventory is `OutboundShipmentHandoff`, whose minimum payload is sales order reference, sales order line reference, shipment reference, shipped quantity, unit of measure, source fulfillment site, and ship date.

## Business Purpose

- Confirm outbound fulfillment against the original customer commitment
- Support partial shipments and backorders without losing order-level visibility
- Provide the shipment basis required for shipment-gated billing policies
- Trigger downstream stock issue and warehouse execution processes without moving warehouse logic into sales
- Preserve customer-facing shipment traceability with shipment references and dates
- Maintain an auditable record of what was shipped, when, from where, and against which sales commitment

## Process Flow

```mermaid
flowchart TD
    A[Sales Order in CONFIRMED status] --> B[Create Shipment]
    B --> C[Select open order lines]
    C --> D[Enter shipment quantities, ship-from site, and dates]
    D --> E{Within open quantity?}
    E -->|No| F[Block or require controlled override]
    E -->|Yes| G[Post Shipment]
    G --> H[Update order line shipped quantities]
    G --> I[Emit outbound shipment handoff to inventory]
    H --> J{All quantities shipped?}
    J -->|No| K[Order remains PARTIALLY SHIPPED]
    J -->|Yes| L[Order becomes SHIPPED]
    G --> M[Shipment eligible for invoice generation when policy requires shipment evidence]
```

## Scenario Patterns

- **Full shipment**: Every ordered line is shipped in one outbound document and a single posted shipment completes the fulfillment side of the order
- **Partial shipment with backorder**: Only part of the demand ships now. The shipment posts successfully, open quantity remains on the order, and another shipment can be recorded later
- **Multi-line mixed fulfillment**: One line on the order ships fully while another remains open, and the shipment captures both outcomes in the same document
- **Channel SLA shipment**: A channel-originated order must be shipped within a short service window, and the shipment document preserves the promised ship date and actual ship date for compliance analysis
- **Service line exclusion**: A service line on the same sales order is invoiced without a physical shipment, while stock items still require shipment evidence
- **Tracking update before posting**: A fulfillment user notices the wrong carrier or tracking reference while the shipment is still draft and corrects it before posting
- **Ship-from-site distinction**: An order is fulfilled from a different site than originally planned, and the shipment records the actual ship-from context for auditability
- **Future shipment reversal**: A posted shipment is later found to be incorrect. A future reversal workflow will preserve the original posted shipment, emit a compensating correction, and keep the audit trail intact rather than mutating history
- **Cross-channel status update**: After shipment posts, a later sync job can push shipped status back to the originating channel without the sales module embedding channel API logic in the shipment itself

## Test Cases

- Creating a shipment against a `CONFIRMED` sales order with open shippable quantity should succeed
- A shipment line must reference a valid sales order line and a shipped quantity greater than zero
- A cancelled or closed sales order must not accept new shipments
- Posting a shipment must increase the referenced sales order line's cumulative shipped quantity
- Partial shipments must leave the remaining open quantity available for future shipment
- Shipping more than the remaining ordered quantity should fail or require an explicit override policy
- A shipment posted for a stock item should emit or call the downstream inventory handoff contract exactly once
- The `OutboundShipmentHandoff` payload must include sales order reference, sales order line reference, shipment reference, shipped quantity, UoM, source site, and ship date at minimum
- A shipment posted for a non-stock or service line must not require inventory stock execution
- Only posted shipments should count toward shipment-gated billing policies
- Shipment posting must be isolated by company and must not update sales orders belonging to another company
- If a shipment is reversed or corrected through a future workflow, the sales order shipped quantity must remain auditable rather than silently overwritten
- Sales order status should move to a partial or full shipment state based on aggregate posted shipment quantities
- Shipment posting should snapshot the customer shipping address used for fulfillment
- Only authorized fulfillment or sales users should be able to post shipments
- A shipment should preserve the customer, order, and line references needed for audit and customer support traceability

## Reference Links

- [Odoo delivery orders documentation](https://www.odoo.com/documentation/19.0/applications/inventory_and_mrp/inventory/shipping_receiving/picking_methods.html)
- [Oracle Shipping Execution documentation](https://docs.oracle.com/en/cloud/saas/supply-chain-and-manufacturing/index.html)
- [SAP outbound delivery overview](https://help.sap.com/docs/SAP_S4HANA_CLOUD)
