Appearance
Universal Invoice Builder — manual QA sign-off
Use this checklist after migration Backend/migrations/20260929_invoice_builder.sql and a backend restart. Mark each row Pass / Fail / N/A with date and tester initials.
Preconditions
- [ ] Admin and Backend running against a DB with migration applied
- [ ] At least one inventory invoice exists (legacy data unchanged)
- [ ] Test user has
billing.create,billing.update, portal/pay enabled if testing those paths
Inventory mode (regression)
| # | Scenario | Expected | Result |
|---|---|---|---|
| 1 | Create new invoice (default inventory) | Saves; line items, HSN, tax summary, totals unchanged | |
| 2 | Edit existing pre-migration invoice | Opens inventory UI; save does not set invoice_mode: custom | |
| 3 | PDF download (detail) | Standard tax invoice layout | |
| 4 | Email send | Inventory line table in HTML | |
| 5 | Customer portal | Inventory columns | |
| 6 | Pay link page | Inventory table | |
| 7 | Duplicate invoice | New draft with copied inventory lines | |
| 8 | Export CSV | Mode inventory; line summary as before | |
| 9 | Import | Notice references builder; imported rows stay inventory |
Custom mode — create & edit
| # | Scenario | Expected | Result |
|---|---|---|---|
| 10 | Toggle Custom on new invoice | Accordions: columns (2–10), PDF settings, labels; sticky Summary; Templates load/update | |
| 11 | Save custom invoice | invoice_mode: custom, layout_config persisted | |
| 12 | Currency column + totals | Subtotal from designated currency column + shipping − advance | |
| 13 | Re-open for edit | Layout and rows restored | |
| 14 | Switch custom → inventory (if allowed) | Validation rejects invalid rows or clears custom rows per product rules | |
| 15 | Save builder template | Appears in template list; apply loads layout |
Custom mode — read paths
| # | Scenario | Expected | Result |
|---|---|---|---|
| 16 | Invoice detail preview | Dynamic column table + summary block | |
| 17 | PDF download (detail) | Custom table matches layout labels; matches email PDF when server route succeeds | |
| 18 | Server PDF (if used) | Matches Admin preview (sync InvoicePdfCustomTable) | |
| 19 | Custom HTML table | ||
| 20 | Portal (UI + GenX) | custom_table rendering | |
| 21 | Pay page | Dynamic columns | |
| 22 | Customer ledger | Custom badge; Custom chip filter | |
| 22b | Main Invoices customer folders | Custom layout / N custom hint when custom_invoice_count > 0 | |
| 22c | Main Invoices Custom layouts chip | Lists only customers with ≥1 custom invoice | |
| 23 | List PDF (Bad debt / quotes bulk path) | Custom table when full invoice payload includes items + layout_config |
Quotes, proforma, credit notes, recurring
| # | Scenario | Expected | Result |
|---|---|---|---|
| 24 | Quote / proforma | Remain inventory-style (v1) | |
| 25 | Credit note | Inventory layout | |
| 26 | Recurring schedule | Unchanged; no custom builder on recurring v1 |
API & data integrity
| # | Scenario | Expected | Result |
|---|---|---|---|
| 27 | GET /newinvoice/singleinvoice/:id | Returns invoice_mode, layout_config for custom | |
| 27b | GET /newinvoice/singleinvoice/:id/pdf | PDF buffer (inventory + custom); Admin detail uses this first | |
| 28 | GET .../customer-list/:id | Includes invoice_mode; excludes heavy items | |
| 29 | Invalid layout (API) | 4xx with validation message | |
| 30 | RBAC on builder templates | Matches permissionRouteMap |
Automated tests (local)
powershell
cd d:\Client\Beentara\Backend
npm run test:invoice-builderpowershell
npm run invoice-builder:smoke --prefix d:\Client\Beentara\qa-tests- [ ] All listed unit tests pass
- [ ] Smoke script passes (optional; needs Admin + Backend + DB)
Known limitations (v1)
- Custom mode not combined with quotes/recurring document types
- Client PDF fallback lives in lazy
InvoiceDetailClientPdf.jsx(server PDF is canonical) - List PDF fallback (
invoiceListPdfDocument.jsx) is simplified vs server template
Sign-off
| Role | Name | Date | Notes |
|---|---|---|---|
| Dev | |||
| QA / Owner |