# TANRAIL ONE — Phase 3.2.4 Procurement Architecture

## 1. Objective
Build a fully generic, business-agnostic Procurement Engine for TANRAIL ONE. This engine handles the purchasing lifecycle from Supplier to Goods Receipt, entirely unaware of whether it is procuring meat for a Restaurant, bottles for Water Distribution, or spare parts for Transport.

## 2. Supplier Boundary
Suppliers are fundamentally `Organization`-scoped (Phase 3.1 Data Foundation). However, Procurement Transactions (`PurchaseOrder`, `PurchaseReceipt`) are strictly `BusinessUnit`-scoped and `Branch`-scoped. A Business Unit can procure from any Supplier within its Organization, but the transaction itself is isolated to that Business Unit.

## 3. Transaction Model
The Procurement process is split into commercial intent and physical receipt:
- **Commercial Intent:** `PurchaseOrder` and `PurchaseOrderLine`. Defines what we want to buy and at what price.
- **Physical Receipt:** `PurchaseReceipt` and `PurchaseReceiptLine`. Defines what actually arrived at the dock.

## 4. Inventory Integration
Procurement does NOT directly manipulate `StockBalance`.
When a `PurchaseReceipt` is completed, it triggers a domain event (`PurchaseReceiptConfirmed`). The existing `InventoryService` listens to this event and issues a `StockMovement` of type `RECEIVE`, guaranteeing single-source-of-truth for inventory logic.

## 5. Financial Boundary (Payables)
Procurement calculates order totals and tracking payments against the `PurchaseOrder`. Like Sales, it uses a simple `Payment` ledger against the Order, tracking what has been paid to the Supplier versus the total value of received goods. It avoids General Ledger complexity.

## 6. Immutability & Concurrency
- `PurchaseOrder` lines become immutable once `APPROVED`.
- Receiving utilizes database-level pessimistic locking (`lockForUpdate`) on the `PurchaseOrder` to safely calculate partial receiving aggregates without race conditions.
