Files
Joshua OosthuizenandClaude Sonnet 5 4acbc03b35 Initial commit: multi-company financial management system
Root company app (src/, client/) — GL foundation, AR, and AP:
- Segmented Chart of Accounts (Sage 300-style), double-entry PostingService with
  three-layer balance enforcement (app validation, CHECK constraints, deferred
  DB trigger), gap-free document numbering, RBAC with branch restrictions.
- Accounts Receivable: Customers, Invoices, Credit Notes, Receipts with
  allocation, all posting through PostingService.
- Accounts Payable: Suppliers, Supplier Invoices, Debit Notes, Payments with
  allocation, mirroring AR's posting pattern.
- Tax Codes shared between AR and AP.
- Company-app login is a token handoff from the Account Manager (RS256,
  single-use, company-scoped) rather than a local password.
- Frontend reskinned to the approved mockup: navy sidebar, dashboard, tree-view
  Chart of Accounts, Customer/Supplier 360 pages.

Account Manager (manager/, manager/client/) — central login gateway:
- Password + TOTP 2FA + Google/Microsoft OAuth, company picker, and the RS256
  handoff token issuance that the company app verifies.

Covered by unit + integration tests against a real Postgres database (GL
balance invariants, AR/AP posting correctness and allocation limits, the full
handoff exchange including replay/cross-company/expiry/forgery rejection).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tq2DbEvzHzs13jDFhLaX44
2026-09-03 13:27:19 +02:00

114 lines
6.7 KiB
Markdown

# Phase 2 — Accounts Receivable: Manual Test Checklist
Adds Customers, Tax Codes, AR Invoices, Credit Notes, and Receipts with allocation — all
posting through the existing `PostingService`, so every one of these creates a real,
balanced GL entry you can trace from the Journal Entries screen. Backend correctness
(balanced postings, tax calc, allocation limits) is already covered by
`tests/integration/ar.posting.spec.ts` (7 tests, passing) and was additionally verified by
hand over the real HTTP API end-to-end. This checklist is for the parts only a human can
judge: does the UI make sense, does the data look right, does it match how the business
actually invoices customers.
Start the same four dev servers as Phase 1.5 (see `PHASE_1.5_TEST_PLAN.md` §0) and sign in
through the Manager.
## 0. New nav items
- [ ] Sidebar shows a new **Sales** section above General Ledger: Customers, Invoices, Receipts
- [ ] Administration section has a new **Tax Codes** item at the bottom
- [ ] Two tax codes are pre-seeded: STD (15%) and ZERO (0%) — visible at `/admin/tax-codes`
## 1. Tax Codes
- [ ] "New Tax Code" creates a code (e.g. `EXPORT`, `Zero-Rated Export`, `0`) and it appears in the grid
- [ ] Toggling a tax code's Active switch off, then back on, works
- [ ] A tax code is usable immediately on new invoice/credit note lines without a page refresh
## 2. Customers
- [ ] "New Customer" requires a branch selection; creating one without a branch shows an error
- [ ] A created customer appears in the Customers grid with the right code/name/credit limit/terms
- [ ] Switching the top-right Branch switcher to a single branch filters the Customers grid to
that branch only; switching back to Main shows all
- [ ] Clicking a customer row opens their Customer 360 page
## 3. Customer 360
- [ ] Header shows the customer's name and an Active/Closed status pill
- [ ] Four summary tiles: Outstanding Balance, Overdue (30+ days), Credit Limit, Payment Terms
- [ ] A brand-new customer with no invoices shows R0.00 everywhere, not blank or broken
- [ ] Contact Details card shows code/email/phone/tax number (or "—" for anything empty)
- [ ] Three tabs — Invoices / Payments / Credit Notes — each show "No … yet." until you create one
- [ ] "New Invoice" and "Receive Payment" buttons only appear if you have the AR permissions
(test with a restricted role, or trust the code path — both gate on `ar.invoice.manage` /
`ar.receipt.manage`)
## 4. Creating and posting an invoice
- [ ] From Customer 360, "New Invoice" opens the invoice form with that customer pre-selected
- [ ] Due date auto-fills from invoice date + the customer's payment terms and is read-only
- [ ] Adding a line, picking a revenue account (only INCOME-type accounts for that customer's
branch are offered) and a tax code updates that line's Amount live
- [ ] Applying the STD (15%) tax code to a R1,000 line shows R150 tax and R1,150 line total
- [ ] The footer Subtotal / Tax / Total roll up correctly across multiple lines with different
tax codes (including a line with no tax code — contributes 0 to tax)
- [ ] "Save Draft" creates the invoice with status DRAFT and does **not** create a GL entry —
confirm by checking General Ledger's entry count is unchanged
- [ ] From the draft's detail page, "Post Invoice" posts it — status flips to POSTED, and a new
entry appears in General Ledger (journal `SALES`) that is balanced (Debits = Credits)
- [ ] Opening that GL entry shows: one debit line to the AR Control account for the invoice
total, one or more credit lines to the revenue account(s) for the subtotal(s), and (if
tax was applied) a credit line to Output Tax Payable for the tax total
- [ ] "Post Invoice" directly from the form (skipping the separate detail-page click) also works
and lands you on the now-posted invoice
- [ ] A draft invoice can be **Voided** (status → VOID, no GL entry ever created); a posted
invoice has no Void option — only a credit note can reverse it
- [ ] The invoice now appears in the customer's Invoices tab and in the global Invoices list,
with the correct balance and status pill
## 5. Receiving a payment
- [ ] From Customer 360, "Receive Payment" opens the receipt form with the customer pre-selected
- [ ] "Deposited to" only offers accounts marked as a Bank control account
- [ ] Saving and posting a receipt for the invoice's exact total creates a balanced GL entry:
debit to Bank, credit to AR Control, journal `CASH_RECEIPT`
- [ ] The posted receipt's detail page shows an "Allocate Against Invoices" panel listing the
customer's open (posted, balance > 0) invoices
- [ ] Clicking "Full" next to an invoice fills in its exact remaining balance (capped at what's
still unallocated on the receipt)
- [ ] Applying the allocation reduces both the invoice's balance and the receipt's unallocated
amount by the applied amount — reload both pages and confirm the numbers persist
- [ ] Fully allocating a receipt makes the "Allocate" panel show "Fully allocated." instead of
the invoice table
- [ ] Attempting to allocate more than a receipt's unallocated amount, or more than an invoice's
balance, is rejected with a clear error and changes nothing
- [ ] A part-paid invoice shows the correct partial balance on its detail page and in the
Customer 360 Invoices tab
## 6. Credit notes
- [ ] Create a credit note for the same customer, one line mirroring a posted invoice line
(same account, same tax code, same amount)
- [ ] Posting it creates a GL entry that is the mirror image of the invoice's: debit to the
revenue account (+ debit to Output Tax if taxed), credit to AR Control — and is balanced
- [ ] The credit note's detail page shows the same "Allocate Against Invoices" panel; allocating
it against the open invoice reduces both the invoice's balance and the credit note's
remaining balance
- [ ] A draft credit note can be voided; a posted one cannot
## 7. Cross-cutting checks
- [ ] Every invoice/receipt/credit note number follows its own series (`ARINV-2026-######`,
`ARRCT-2026-######`, `ARCN-2026-######`) and never repeats or skips oddly between runs
- [ ] The Dashboard's "Posted Movement by Account Type" bars now reflect AR activity (ASSET bar
grows from AR Control + Bank movement, INCOME bar grows from Sales)
- [ ] Switching to a specific branch (not Main) on any AR screen shows only that branch's
customers/invoices/receipts
- [ ] No console errors in the browser dev tools while working through this checklist
---
Once this is ticked (or you've flagged issues), the plan's next step is Accounts Payable —
Suppliers, Supplier Invoices, Debit Notes, Payments — built the same way, followed by Tax
reporting and then Stock Control.