AAuditPro Suite· Finance manual
Finance manual Advances

What makes a payment an "advance"?

The is_advance column is computed at insert + on every allocation change. It's TRUE when:

  1. Zero allocations — payment recorded but not yet matched to any invoice
  2. Only proforma allocations — payment is against PI/{...}, which is informational only — actual revenue is recognised on tax invoice conversion
  3. Partial tax allocation with leftover — payment exceeds the tax invoice's balance; the unallocated remainder is the advance portion

5 worked scenarios

ScenarioPaymentAllocationsis_advance
Full settlementOMR 5,565INV/0042 — 5,565 (full)0
Partial settlementOMR 3,000INV/0042 — 3,000 (partial)0
Cross-invoice settlementOMR 12,500INV/0040 — 5,000 · INV/0041 — 5,000 · INV/0042 — 2,500 (Σ = 12,500)0
Pure advanceOMR 5,000(none)1
Proforma + leftoverOMR 6,000PI/0010 — 5,250 (informational)1 (5,250 + 750 leftover)

Advance balance computation

Payment::advanceBalanceForClient($clientId) returns the current unallocated credit:

SELECT
  SUM(p.amount) - SUM(COALESCE(allocated_to_tax.amt, 0)) AS advance_balance
FROM payments p
LEFT JOIN (
  SELECT pa.payment_id, SUM(pa.amount_allocated) AS amt
  FROM payment_allocations pa
  JOIN invoices i ON pa.invoice_id = i.id AND i.doc_type = 'tax_invoice'
  GROUP BY pa.payment_id
) allocated_to_tax ON allocated_to_tax.payment_id = p.id
WHERE p.client_id = ? AND p.deleted_at IS NULL

Proforma allocations don't reduce advance balance — only tax-invoice allocations do.

Where advance balance surfaces

Auto-allocation on new invoice

When a new tax invoice is created for a client with positive advance balance, the system silently:

  1. Computes min(advance_balance, invoice.grand_total)
  2. Picks the oldest payment with unallocated capacity
  3. Inserts a payment_allocations row of that amount against the new invoice
  4. Recomputes invoice balance_due
  5. If balance_due reaches 0, invoice flips draft → sent → paid in one shot
  6. Flash message shows the auto-allocated amount

Behaviour can be disabled per-firm via m11.auto_apply_advances=0. Default ON.

Post-hoc allocation form

Sometimes an advance came in long before the invoice was issued. Click into the payment → Allocate button. Form:

Useful for: retainer applied to first work performed, year-end clean-up, applying old advances before write-off review.

Step-by-step — handling a retainer

  1. Client sends OMR 5,000 retainer

    "Apply when fieldwork starts." Bank transfer hits the firm account.

  2. Record payment (no allocation)

    M11 → Payments → New. client = X, amount = 5,000, method = bank_transfer, reference = bank ref. Save without allocations. is_advance=1 auto-set. Receipt PDF generated showing "Advance — un-allocated".

  3. Send receipt to client

    Email the receipt PDF. M17 template payment.received.

  4. Fieldwork happens · invoice raised

    Job completes → tax invoice INV/2026/0050 auto-drafts for OMR 6,000.

  5. Auto-allocate on draft

    System sees client has 5,000 advance, auto-allocates against the new invoice. Invoice balance_due = 1,000. Status moves draft → sent → partially_paid.

  6. Client pays remainder

    OMR 1,000 received. Allocate to invoice. Status → paid. Done.

Reporting on advances

The Reports module exposes:

Try this

Record a OMR 3,000 advance for a client with no open invoices. Check the client → Billing card — orange "Advance balance: OMR 3,000" tile appears. Now create a tax invoice for OMR 5,000 from that client. The auto-allocation triggers + the new invoice's balance_due becomes OMR 2,000. Flash message confirms.

Watch out

Aged un-allocated advances (> 90 days) are an audit-finding waiting to happen — clients have paid for services not yet delivered. Either deliver or refund. Reports → Aged Advance highlights these. Best-practice firms keep advance balance < 1 month of revenue.

Tip — proforma vs straight advance

If you want to send the client a "this is what your money is going toward" doc upfront, issue a proforma. If they pay in trust (no specific invoice), record as a straight advance and apply later. Both are valid; proforma adds documentation discipline.