Skip to content

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) ​

#ScenarioExpectedResult
1Create new invoice (default inventory)Saves; line items, HSN, tax summary, totals unchanged
2Edit existing pre-migration invoiceOpens inventory UI; save does not set invoice_mode: custom
3PDF download (detail)Standard tax invoice layout
4Email sendInventory line table in HTML
5Customer portalInventory columns
6Pay link pageInventory table
7Duplicate invoiceNew draft with copied inventory lines
8Export CSVMode inventory; line summary as before
9ImportNotice references builder; imported rows stay inventory

Custom mode — create & edit ​

#ScenarioExpectedResult
10Toggle Custom on new invoiceAccordions: columns (2–10), PDF settings, labels; sticky Summary; Templates load/update
11Save custom invoiceinvoice_mode: custom, layout_config persisted
12Currency column + totalsSubtotal from designated currency column + shipping − advance
13Re-open for editLayout and rows restored
14Switch custom → inventory (if allowed)Validation rejects invalid rows or clears custom rows per product rules
15Save builder templateAppears in template list; apply loads layout

Custom mode — read paths ​

#ScenarioExpectedResult
16Invoice detail previewDynamic column table + summary block
17PDF download (detail)Custom table matches layout labels; matches email PDF when server route succeeds
18Server PDF (if used)Matches Admin preview (sync InvoicePdfCustomTable)
19EmailCustom HTML table
20Portal (UI + GenX)custom_table rendering
21Pay pageDynamic columns
22Customer ledgerCustom badge; Custom chip filter
22bMain Invoices customer foldersCustom layout / N custom hint when custom_invoice_count > 0
22cMain Invoices Custom layouts chipLists only customers with ≥1 custom invoice
23List PDF (Bad debt / quotes bulk path)Custom table when full invoice payload includes items + layout_config

Quotes, proforma, credit notes, recurring ​

#ScenarioExpectedResult
24Quote / proformaRemain inventory-style (v1)
25Credit noteInventory layout
26Recurring scheduleUnchanged; no custom builder on recurring v1

API & data integrity ​

#ScenarioExpectedResult
27GET /newinvoice/singleinvoice/:idReturns invoice_mode, layout_config for custom
27bGET /newinvoice/singleinvoice/:id/pdfPDF buffer (inventory + custom); Admin detail uses this first
28GET .../customer-list/:idIncludes invoice_mode; excludes heavy items
29Invalid layout (API)4xx with validation message
30RBAC on builder templatesMatches permissionRouteMap

Automated tests (local) ​

powershell
cd d:\Client\Beentara\Backend
npm run test:invoice-builder
powershell
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 ​

RoleNameDateNotes
Dev
QA / Owner

Beentara — Business management made simple.