# 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.