# TANRAIL ONE — Phase 3.2.4 Procurement Workflows

## 1. Commercial Workflow (Approval)
1. **Creation:** User creates `PurchaseOrder` (status `DRAFT`).
2. **Line Management:** User adds/removes `PurchaseOrderLine` items. Totals dynamically recalculate.
3. **Submission:** User submits PO. Status becomes `SUBMITTED`. Lines are locked (no changes).
4. **Approval:** Manager approves PO. Status becomes `APPROVED`. It is now a binding commercial document.

## 2. Goods Receiving Workflow (Physical)
1. **Initiation:** Delivery arrives. Warehouse user creates a `PurchaseReceipt` against an `APPROVED` or `PARTIAL_RECEIVED` Purchase Order.
2. **Line Entry:** User specifies which `PurchaseOrderLine` items arrived and the `quantity`.
3. **Validation:** 
   - `quantity > 0`
   - `(previously_received + new_quantity) <= ordered_quantity` (Over-receiving strictly rejected by Core).
4. **Confirmation:** The receipt is saved. 
   - The `PurchaseOrderLine.received_quantity` is incremented.
   - The PO status updates to `PARTIAL_RECEIVED` or `RECEIVED` based on aggregate totals.
   - Event `PurchaseReceiptConfirmed` is dispatched.

## 3. Inventory Integration
The `InventoryService` listens for `PurchaseReceiptConfirmed`. 
For each `PurchaseReceiptLine`, it executes:
`InventoryService::receive(Item, Location, Quantity, 'purchase', Receipt_ID)`
This strictly maintains the single-source-of-truth for stock mutations.

## 4. Cancellation
- If `DRAFT` or `SUBMITTED`, can be easily `CANCELLED`.
- If `APPROVED` but nothing received, can be `CANCELLED`.
- If `PARTIAL_RECEIVED` or `RECEIVED`, CANNOT be arbitrarily cancelled without an explicit Return-to-Vendor workflow (out of scope for base 3.2.4; strictly blocked).
