# TANRAIL ONE — Core Sales Data Model

## 1. Entities

### Order
Tracks the overall transaction intent.
- `id` (PK)
- `branch_id` (FK to branches -> inherently enforces BusinessUnit)
- `customer_id` (FK to customers - nullable for walk-ins)
- `status` (Enum: DRAFT, CONFIRMED, FULFILLED, COMPLETED, CANCELLED)
- `subtotal` (Decimal 14,4)
- `tax_total` (Decimal 14,4)
- `total` (Decimal 14,4)
- `created_by` (FK to users)
- `timestamps`

### OrderLine
Tracks the specific items purchased, locking in historical price.
- `id` (PK)
- `order_id` (FK to orders)
- `item_id` (FK to items)
- `quantity` (Decimal 14,4)
- `unit_price` (Decimal 14,4)
- `tax_amount` (Decimal 14,4)
- `subtotal` (Decimal 14,4)
- `total` (Decimal 14,4)

### Payment
Tracks funds received. (A minimal foundation for Core transactions).
- `id` (PK)
- `order_id` (FK to orders)
- `amount` (Decimal 14,4)
- `method` (Enum: CASH, CARD, TRANSFER, MOBILE_MONEY)
- `reference` (String, nullable)
- `created_by` (FK to users)
- `timestamps`

## 2. Constraints & Indexing
- `OrderLine` must enforce a foreign key to `Order` and `Item`.
- `Order` must enforce a foreign key to `Branch`.
- `business_unit_id` could be denormalized onto `Order` for indexing and global scoping, but strict application layer enforcement is required to ensure `Order->business_unit_id === Order->branch->business_unit_id`.

## 3. Immutability
- Once an `Order` transitions from `DRAFT` to `CONFIRMED`, `OrderLine` records become immutable.
- Payments are strictly append-only. To reverse a payment, a negative payment or refund record is appended. Delete is prohibited.
