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
5.2 KiB
Phase 3 — Accounts Payable: Manual Test Checklist
Mirrors Accounts Receivable exactly, but for money owed to suppliers instead of money owed by
customers: Suppliers, Supplier Invoices (Bills), Debit Notes, and Payments with allocation —
same Draft → Post workflow, same shared PostingService, same Tax Codes. Backend correctness
is already covered by tests/integration/ap.posting.spec.ts (7 tests, passing alongside AR's
7 and GL's 9) and was additionally verified over the real HTTP API by hand (create supplier →
create/post invoice → create/post payment → allocate → invoice balance hit zero). This
checklist is for the parts only a human can judge.
Start the same four dev servers as before and sign in through the Manager.
0. New nav items
- Sidebar shows a new Purchasing section (between Sales and General Ledger): Suppliers, Bills, Payments
1. Suppliers
- "New Supplier" requires a branch selection; creating one without a branch shows an error
- A created supplier appears in the Suppliers grid
- Branch switcher filters the Suppliers grid the same way it does Customers
- Clicking a supplier opens their detail page (the AP equivalent of Customer 360)
2. Supplier detail page
- Header shows the supplier's name and an Active/Closed status pill
- Three summary tiles: Outstanding Balance, Overdue (30+ days), Payment Terms
- A brand-new supplier with no invoices shows R0.00 everywhere
- Contact Details card shows code/email/phone/tax number (or "—" for anything empty)
- Three tabs — Invoices / Payments / Debit Notes — each show "No … yet." until you create one
- "New Invoice" and "Make Payment" buttons only appear if you have the AP permissions
3. Creating and posting a supplier invoice (Bill)
- From the supplier's page, "New Invoice" opens the form with that supplier pre-selected
- Due date auto-fills from invoice date + the supplier's payment terms and is read-only
- Adding a line, picking an expense account (only EXPENSE-type accounts for that supplier'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
- "Save Draft" creates the invoice with status DRAFT and does not create a GL entry
- "Post Invoice" posts it — status flips to POSTED, and a new balanced entry appears in
General Ledger under journal
PURCHASES - Opening that entry shows: debit line(s) to the expense account(s) for the subtotal, a debit line to Input Tax Receivable for the tax (if any), and a credit line to Accounts Payable Control for the total
- A draft invoice can be Voided; a posted invoice has no Void option — only a debit note can reverse it
- The invoice appears in the supplier's Invoices tab and in the global Bills list
4. Making a payment
- From the supplier's page, "Make Payment" opens the form with the supplier pre-selected
- "Paid from" only offers accounts marked as a Bank control account
- Posting a payment for the invoice's exact total creates a balanced GL entry: debit to
Accounts Payable Control, credit to Bank, journal
CASH_PAYMENT - The posted payment's detail page shows an "Allocate Against Invoices" panel listing the supplier's open (posted, balance > 0) invoices
- "Full" fills in the invoice's exact remaining balance, capped at what's still unallocated on the payment
- Applying the allocation reduces both the invoice's balance and the payment's unallocated amount — reload both pages and confirm the numbers persist
- Over-allocating (more than the payment'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 on the supplier's Invoices tab
5. Debit notes
- Create a debit note for the same supplier, one line mirroring a posted invoice line
- Posting it creates the mirror-image GL entry: debit to Accounts Payable Control, credit to the expense account (+ credit to Input Tax if taxed) — and is balanced
- The debit note's detail page shows the same allocation panel; allocating it against the open invoice reduces both the invoice's balance and the debit note's remaining balance
- A draft debit note can be voided; a posted one cannot
6. Cross-cutting checks
- Every invoice/payment/debit-note number follows its own series (
APINV-2026-######,APPMT-2026-######,APDN-2026-######) and never repeats or skips oddly - The Dashboard's "Posted Movement by Account Type" bars now also reflect AP activity (LIABILITY bar grows from AP Control movement, EXPENSE bar grows from bills)
- Switching to a specific branch shows only that branch's suppliers/invoices/payments
- No console errors in the browser dev tools while working through this checklist
Once this is ticked, the plan's next step is Tax reporting (VAT/output-input reconciliation), then Stock Control + Procurement Matching (GRV/PPV, incorporating the Posting Ledger reference already reviewed).