# 05 — Receivables & Billing

Where the money actually gets collected. Everything here follows from one rule stated in
doc 04: **a sale is either settled now or becomes a receivable.**

---

## 1. The document chain

```
Order (on_account)
   └──▶ Charge ─────────────┐
                            │  billing run at cycle close
                            ▼
                        Invoice ──────────▶ Payment (receipt)
                            │                    │
                            │                    └──▶ Allocation (payment → invoice)
                            ├──▶ Credit Note (refund / goodwill)
                            └──▶ Write-off (uncollectible)
```

Every document is **immutable once issued**. Corrections are new opposing documents.
This is non-negotiable: an editable invoice makes every historical report unreliable and
removes the audit trail that credit selling depends on.

---

## 2. Charge

Created the instant an order settles `on_account`.

| Field | Notes |
|---|---|
| `id`, `account_id`, `branch_id`, `order_id` | |
| `business_day`, `created_at` | |
| `amount`, `currency` | Snapshotted from the order |
| `authorized_person_id?` | Who took it — required for restricted accounts |
| `signature_ref?` | If the account requires signature capture |
| `status` | `unbilled` / `billed` / `voided` |
| `invoice_id?` | Set when a billing run picks it up |
| `credit_check` | `passed` / `override` / `provisional` (created offline) |

**Rules**
- A charge is voided only by voiding its order.
- A charge already on an issued invoice **cannot be voided**; issue a **credit note** instead.
- Charges are never edited. Amount corrections are credit notes.

---

## 3. Billing run

The scheduled process that converts `unbilled` charges into invoices.

```
for each active account with mode ≠ IMMEDIATE:
    period = current_open_period(account.billing_terms, today)
    if period.close_date <= today:
        charges = unbilled charges of this account with business_day within period
        if charges is empty and not account.issue_zero_invoices:
            close the period without an invoice
        else:
            issue Invoice(period, charges)
            mark charges billed
            advance the period grid
```

| Aspect | Decision |
|---|---|
| **Where it runs** | Centrally, not on a branch terminal. Requires the full charge set, including charges from other branches for cross-branch accounts. |
| **When** | Automatically after the business-day cutoff; manually re-runnable by Accountant/Owner. |
| **Idempotency** | Keyed on `(account_id, period_start, period_end)`. Re-running the same period never produces a second invoice. |
| **Late-arriving charges** | A charge that syncs *after* its period was invoiced is **not** back-dated into it. It rolls into the next period, flagged `late_arrival` on the invoice and listed on the Sync Exceptions report. Reopening a closed period is worse than a one-period delay. |
| **Zero-activity periods** | No invoice by default. Configurable per account for tenants that require a monthly document regardless. |
| **Partial-period on terms change** | The open period completes under the old terms; new terms apply from the next period. |
| **Owner-declared closures** | The period grid runs on **calendar days and is unaffected by closures** ([10 §3.1](10-cross-cutting-rules.md)). A closed day contributes no charges; a `DAILY` account simply gets no invoice that day. Shifting cycle dates because the cafe shut for a day makes invoicing unpredictable for tenants. |
| **Employee caps** | Only the **covered** portion of a split order is invoiced to the company (doc 03 §6.4). The personally-paid portion never reaches the invoice. |

### Period grid examples

| Terms | Periods |
|---|---|
| `DAILY` | Each business day is its own period |
| `EVERY_N_DAYS n=7, start 1 Aug` | 1–7, 8–14, 15–21, 22–28, 29–4 Sep … the grid never drifts |
| `MONTHLY, anchor EOM` | 1–31 Aug, 1–30 Sep … |
| `MONTHLY, anchor 25` | 25 Jul–24 Aug, 25 Aug–24 Sep … |

---

## 4. Invoice / Statement

| Field | Notes |
|---|---|
| `invoice_number` | Sequential per organization, gapless, never reused |
| `account_id` | |
| `period_start`, `period_end`, `issue_date`, `due_date` | `due_date = issue_date + due_days` |
| `lines[]` | One line per charge, or grouped by day / by person / by item — configurable per account |
| `subtotal`, `discount`, `tax`, `total`, `currency` | |
| `amount_paid`, `amount_credited`, `amount_written_off`, `balance_due` | Derived from allocations |
| `status` | `issued` / `partially_paid` / `paid` / `overdue` / `written_off` / `cancelled` |
| `branch_breakdown[]` | Totals per branch for cross-branch accounts |
| `delivery` | `print` / `whatsapp` / `email` / `collected`, with sent timestamp |

### Statement presentation

Tenants dispute invoices they cannot verify. Support three groupings, chosen per account:

| Grouping | Best for |
|---|---|
| **By day** | "5 Aug — 12 items — 46,000 IQD" — compact, for high-trust accounts |
| **By person** | "Ahmed — 14 items — 52,000 IQD" — the most common tenant request |
| **Full detail** | Every order, every line — for disputes and first invoices |

Always available regardless of grouping: a drill-down to individual orders with timestamps
and the authorized person, plus signature images where captured. This one feature removes
most collection friction.

### Cap summary on the statement

For accounts with `CAPPED_PER_EMPLOYEE` funding (doc 03 §6), the statement carries a cap
block — it is the document the tenant's HR or finance person actually checks:

```
Employee          Cap        Covered by you   Paid personally   Unused
Ahmed Kareem      50,000          50,000            18,500          0
Sara Jassim       50,000          31,200                 0     18,800
Mustafa Ali       50,000          50,000             4,000          0   (2 overage approvals)
                              ─────────────
Invoiced to company              131,200
```

Only the "Covered by you" column sums to the invoice total. Showing the other columns
pre-empts the two questions every capped tenant asks: *did anyone exceed their allowance,
and did we pay for it?*

### Rules

1. Invoice numbers are **gapless**. A cancelled invoice keeps its number with status
   `cancelled`; it is never deleted or reused.
2. An issued invoice is **immutable**. Cancellation is allowed only while
   `amount_paid = 0`, requires Owner approval and a reason, and returns its charges to
   `unbilled`.
3. Invoices are issued in the **account's currency** with the FX rate recorded if underlying
   charges were in another currency.

---

## 5. Payments (receipts)

| Field | Notes |
|---|---|
| `receipt_number` | Sequential per branch |
| `account_id`, `branch_id`, `received_by_user_id`, `shift_id?` | |
| `amount`, `currency`, `fx_rate?` | |
| `method` | `cash` / `card` / `wallet` / `bank_transfer` / `cheque` |
| `reference` | Transfer/wallet reference, cheque number |
| `received_at`, `business_day` | |
| `allocations[]` | `{ invoice_id, amount }` |
| `unapplied_amount` | Credit sitting on the account |
| `note` | |

**Rules**
1. **A payment can be collected at any branch** for any account, if the account allows it.
   Recorded against the collecting branch's shift so branch cash reconciles.
2. **Default allocation is oldest-invoice-first**; the Accountant may reallocate manually.
3. **Overpayment becomes unapplied credit**, applied automatically to the next invoice.
4. **A cash payment collected at the POS enters the shift's cash count** — this is a
   frequent source of unexplained cash variance if forgotten. It must be a first-class POS
   action ("Receive account payment"), not a back-office-only screen.
5. Payments are **immutable**. A mistake is corrected by reversing the payment (audited,
   Accountant/Owner only), not by editing it.

---

## 6. Credit notes and write-offs

| Document | When | Effect |
|---|---|---|
| **Credit note** | Refund of an invoiced charge; goodwill; billing error | Reduces `balance_due` on a specific invoice, or sits as an account credit |
| **Write-off** | Debt accepted as uncollectible (tenant left the building, dispute settled) | Closes the balance; recognised as a loss in reporting |

**Rules**
- Both require a reason code and approval: credit notes by Accountant, write-offs by Owner.
- Write-offs appear on their own report. A rising write-off number is the earliest signal
  that credit control has stopped working.
- Neither ever alters the original invoice or charge.

---

## 7. Aging & collections

### Aging buckets (per account, per branch, consolidated)

```
Current  |  1–30 days  |  31–60 days  |  61–90 days  |  90+ days
```

Computed from `due_date`, not issue date.

### Automatic actions

| Trigger | Action |
|---|---|
| `due_date` reached | Invoice → `overdue`; reminder queued to the billing contact |
| `due_date + grace_days` | If `auto_hold_when_overdue`, the account moves to `on_hold`; new charges are blocked at the POS |
| Balance ≥ `credit_limit` | New charges blocked; alert to Manager and Accountant |
| Payment received clearing the balance | Hold released automatically |

### Collections workflow

Lightweight and deliberate:

```
Invoice overdue
   → reminder 1 (automatic, on due date)
   → reminder 2 (automatic, due + grace)
   → account on hold + branch manager notified
   → escalate to building operator contact
   → owner decision: settlement plan | write-off | legal
```

Each step logs an activity note against the account so the history is visible when the
tenant calls.

---

## 8. Reports owned by this module

| Report | Answers |
|---|---|
| **AR Aging Summary / Detail** | Who owes us what, and how late |
| **Account Statement** | The document the tenant receives |
| **Unbilled Charges** | Exposure not yet invoiced — real risk, invisible on an aging report |
| **Collections / Cash Received** | What came in, by branch, by method, by day |
| **Credit Exceptions** | Overrides, provisional offline charges, over-limit approvals |
| **Cap Utilization** | Per person: cap, consumed, remaining, % used — mid-cycle, before anyone is surprised |
| **Cap Exceptions** | Overage approvals (`ALLOW_WITH_APPROVAL`), who approved, and the amount the company will be billed above policy |
| **Write-offs & Credit Notes** | Losses and adjustments, by account and by approver |
| **Days Sales Outstanding (DSO)** | Average days from charge to cash, per account and overall |
| **Top Accounts by Revenue / by Risk** | Where the concentration is |

---

## 9. Worked example

```
Tenant: "Al-Rafidain Tech" — office 305, Baghdad Main
Terms:  MONTHLY, anchor EOM, due_days 10, grace_days 5, credit_limit 1,500,000 IQD

3 Aug   Ahmed (authorized) charges 3 lattes            13,500 IQD  → unbilled
7 Aug   Sara  (authorized) charges office order        46,000 IQD  → unbilled
...
28 Aug  balance reaches 1,480,000 → warning to manager (credit_limit − balance < 5%)
30 Aug  Ahmed attempts 25,000 charge → BLOCKED, over limit
        Manager overrides with PIN + reason "invoice in hand, payment Thursday" → audited
31 Aug  Billing run closes 1–31 Aug
        Invoice INV-2026-000412 issued, total 1,505,000 IQD, due 10 Sep
        Statement grouped BY PERSON at the tenant's request
 6 Sep  Payment 1,000,000 IQD cash received at the counter
        → enters that shift's cash count, allocated to INV-2026-000412
        → balance_due 505,000, status partially_paid
11 Sep  Overdue. Reminder 2 sent.
16 Sep  due + grace passed → account auto-held, new charges blocked
18 Sep  Payment 505,000 by bank transfer → invoice paid, hold released automatically
```
