# Purchase Order Lifecycle

## Overview

Purchase Order Lifecycle governs how a supplier commitment is created, reviewed, placed, fulfilled, and closed. A `PurchaseOrder` records the commercial agreement with a supplier for one or more items, including ordered quantity, expected delivery, unit price, currency, payment-term reference, and receiving site. The order is the primary document that downstream receipts and supplier bills match against.

The lifecycle tracks both document control and fulfillment progress. A purchase order begins in draft, may be submitted for approval, can be explicitly rejected back to draft with a reason, becomes ordered when released to the supplier, then moves through partial or full receipt and partial or full billing states as execution proceeds. This gives procurement teams a single source of truth for what is still open with each supplier.

## Business Purpose

- Create a formal, auditable supplier commitment before goods or services are received
- Freeze negotiated commercial terms at the time an order is placed, even if future price lists change
- Capture the company and receiving-site context needed for receipt routing and supplier traceability
- Track open quantity, received quantity, billed quantity, and remaining commitment per line
- Provide the reference document required for receipt matching and supplier bill matching
- Support partial fulfillment without losing visibility into remaining supplier obligations
- Prevent inactive suppliers, inactive items, or incomplete orders from entering downstream execution

## Process Flow

```mermaid
flowchart TD
    A[Create Purchase Order] --> B[DRAFT]
    B --> C[Add supplier, lines, prices, terms]
    C --> D{Submit?}
    D -->|No| C
    D -->|Yes| E[SUBMITTED]
    E --> F{Approve?}
    F -->|Reject| R[REJECTED]
    R --> B
    F -->|Approve and send| G[ORDERED]
    G --> H{Receipt posted?}
    H -->|Partial| I[PARTIALLY RECEIVED]
    H -->|Full| J[RECEIVED]
    I --> K{Supplier bill matched?}
    J --> K
    K -->|Partial| L[PARTIALLY BILLED]
    K -->|Full| M[BILLED]
    I --> N{Close remaining?}
    J --> N
    L --> N
    M --> N
    N -->|Close| O[CLOSED]
    B --> P[CANCELLED]
    E --> P
    G --> P
```

## Scenario Patterns

- **Standard stock purchase**: A buyer creates an order for replenishment items, applies supplier pricing and payment terms, submits it, and sends it to the supplier once approved
- **Rejected for revision**: An approver rejects a submitted order because the receiving site or supplier quote is wrong, and the order returns to draft with the rejection reason preserved for audit
- **Split delivery**: A supplier confirms the order but ships in two batches. The purchase order remains open after the first receipt and closes only when all ordered quantity is received or explicitly closed out
- **Price override before release**: A buyer starts from an automatically suggested supplier price rule but overrides one line before approval due to a one-time negotiated exception
- **Service or non-stock procurement**: A purchase order is created for a supplier-provided service or consumable item that may still require bill matching even if no warehouse stock is updated
- **Order cancellation before fulfillment**: An order is cancelled after submission because demand disappears and no receipt or bill has yet been matched
- **Close remaining balance**: A supplier underdelivers the final 2 units and the buyer chooses to close the remaining open quantity instead of keeping the order indefinitely open
- **Multi-line mixed fulfillment**: Some lines on the same order are fully received while others remain open, and line-level progress rolls up to the document status
- **Supplier change control**: A buyer duplicates and revises a draft order rather than changing the supplier on an already ordered document, preserving traceability

## Test Cases

- Creating a purchase order with a valid ACTIVE supplier, company, and at least one line should succeed
- A purchase order line must require an ACTIVE item, quantity greater than zero, and a non-negative unit price
- Purchase orders can only be created in `DRAFT` status
- A `DRAFT` order can be revised freely, but `ORDERED` commercial fields must not change without an explicit revision workflow
- Submitting a purchase order without any lines should fail
- Submitting a purchase order without a receiving site when the line requires physical receipt should fail
- Submitting a purchase order for a partner that does not carry the SUPPLIER role should fail
- Approving or ordering a purchase order whose supplier is INACTIVE should fail
- Rejecting a submitted purchase order should record the rejection reason and return the document to `DRAFT`
- Cancelling a purchase order after a posted receipt or matched supplier bill exists should be prevented
- Posting a partial receipt should update line received quantities and move the order to a partial receipt status
- Matching a supplier bill should update line billed quantities independently of receipt quantities
- Closing a purchase order should be allowed only when all remaining open quantities are fulfilled, cancelled, or explicitly written off
- Purchase order totals and open balances must be isolated per company
- The applied unit price on a purchase order line must remain unchanged even if the underlying supplier price rule is later edited
- A purchase order must preserve its assigned payment term snapshot for downstream bill due-date calculation
- Each purchase order line should expose remaining quantity to receive and remaining quantity to bill
- Duplicate external supplier order references should be rejected or flagged according to company policy
- Only authorized procurement users should be able to submit, approve, cancel, or close purchase orders

## Reference Links

- [Odoo Purchase documentation](https://www.odoo.com/documentation/19.0/applications/inventory_and_mrp/purchase.html)
- [Oracle Fusion Cloud Procurement guide](https://docs.oracle.com/en/cloud/saas/procurement/index.html)
- [SAP procurement overview](https://help.sap.com/docs/SAP_S4HANA_CLOUD)
