M11 Invoices — draft to paid
The most-used screen in the firm after Tasks. Auto-numbered, auto-drafted on job completion, branded navy PDF, live balance recompute as payments allocate, advance pre-application, dunning automation. The state machine + lifecycle stamps make every transition forensic.
Invoice header — the anatomy
| Description | Qty | Rate | VAT | Total |
|---|---|---|---|---|
| Annual Audit FY 2025 | 1.000 | 5,000.000 | 250.000 | 5,250.000 |
| Out-of-pocket — site visits | 1.000 | 300.000 | 15.000 | 315.000 |
| Subtotal | 5,300.000 | |||
| VAT (5%) | 265.000 | |||
| Grand Total | OMR 5,565.000 | |||
| Less: prior advance applied | (1,000.000) | |||
| Balance Due | OMR 4,565.000 | |||
Header fields
Atomic counter. Tax invoices share invoice sequence; proforma + CN + DN have their own sequences.
tax_invoice (default) · proforma · credit_note · debit_note · receipt. Drives behaviour throughout.
Bill-to. Inherits VAT TRN, address, payment terms, T&Cs override (if any).
If linked, M07 Job → Invoices tab shows this invoice.
If converted from quote, points to the source.
For CN/DN/proforma-converted: points to parent. NULL for primary tax invoices.
Issue defaults today. Due defaults issue + 30 days (configurable per client/firm).
draft · sent · partially_paid · paid · overdue · cancelled · written_off · converted
OMR default. Non-OMR captures FX rate at issuance + computes OMR-equivalent for reporting.
grand_total − allocated payments. Auto-recomputes on every payment allocation change.
From client.invoice_terms_override OR firm default (Settings → Company Profile → Invoice defaults).
Never on the PDF. Pricing rationale, partner approvals, internal context.
Lifecycle stamp columns
| Column | Stamped on |
|---|---|
| created_at + by | Insert |
| approved_at + by | draft → sent (or first approve) |
| sent_at + by | Status flips to sent |
| paid_in_full_at | Last allocation closes balance to 0 |
| cancelled_at + by + reason | Mandatory reason |
| written_off_at + by + reason | Mandatory reason; super_admin/partner only |
| converted_at + by | Proforma → tax invoice conversion |
| overdue_flagged_at | Cron auto-flips sent → overdue |
Step-by-step — manually create a tax invoice
Open Invoices → New invoice
Or from a job → Invoices tab → New from this job. Or from a client → Invoices tab → New for this client.
Header
Doc type defaults to tax_invoice. Client + job pre-filled if launched from those modules. Issue date = today. Due date = today + 30. T&Cs pre-filled.
Add line items
Description (datalist autocomplete) · qty · unit_price · discount · VAT category. Header rolls up live.
Save as draft
Auto-numbered
INV/{YYYY}/{NNNN}. Status=draft. PDF generated to cache.Approve
Manager/partner clicks Approve.
approved_at+ by stamped. Now ready to send.Send
Click Send. M17 queues email with template
invoice.sent+ branded PDF attached. Status flips draft → sent.sent_at+ by stamped.Apply prior advances (auto)
If client has unallocated advance balance, system silently allocates against the new invoice up to min(advance, total). Flash message shows the auto-allocated amount.
Wait for payment
Or set up dunning auto-reminder (chapter 10).
Editing — what's allowed when
| Status | Edit lines? | Edit header? |
|---|---|---|
| draft | ✓ | ✓ |
| sent | ✗ (cancel + reissue) | Limited (notes only) |
| partially_paid / paid / overdue | ✗ | Notes only |
| cancelled / written_off / converted | Read-only | Read-only |
RBAC matrix
| Role | view | create | approve | send | cancel | write_off |
|---|---|---|---|---|---|---|
| super_admin | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| partner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| admin_staff | ✓ | ✓ | — | ✓ | — | — |
| accountant | ✓ | ✓ | ✓ | ✓ | — | — |
| manager | ✓ (dept) | — | — | — | — | — |
| senior / staff | ✓ (assigned) | — | — | — | — | — |
| read_only | ✓ | — | — | — | — | — |
Open any open job → Invoices tab → New invoice from this job. Watch the line description's datalist suggest task names from the job + recent invoice descriptions. Add 2 lines, save draft, approve, send. End-to-end in under 90 seconds.
Don't write-off an invoice without a real reason. The system enforces a min 50-character reason captured in written_off_reason column. Audit log keeps both the action + the reason permanently. Write-offs are a finance event with tax implications — never use them as a shortcut to "make the AR list cleaner".
The line description field pulls from 4 sources: job title, template description's first sentence, task names of the linked job, firm-wide recent invoice lines. Use this — typing "Annu..." surfaces "Annual Audit FY 2025" instantly + auto-prefills unit_price from prior similar invoices.