# TechTitans POS — Invoice Final Visual QA (logo, column alignment, classification, digital fulfillment)

**Date:** 2026-11-12 · **Branch:** `techtitans/integration` · Local commit only (no push/deploy).
NH POS / legacy portal untouched; no legacy PHP executed; sandbox (offline) dev payments only; invoice amounts,
taxes, payment ledger, customer data, tenant isolation and historical PDF bytes all preserved.

## The document the user was seeing — PF-2026-0015 (frozen historical)

Traced through the DB + stored bytes + the real `GET /orders/{id}/invoice` route:

| Field | Value |
|---|---|
| `document_type` | `proforma` |
| `payment_status_snapshot` | `PENDING` |
| `issued_at` | **2026-11-12 06:28:30** |
| stored PDF has image/logo | **no** |
| linked order | `status=DRAFT`, `order_number=NULL`, `order_source=SYSTEM`, `order_type=PICKUP` |

**Root causes of what the user saw on PF-2026-0015 (all because it is a frozen pre-fix document):**
- **Missing logo** — issued **before** the tenant logo became effective (cutover ~2026-11-12 **07:02**) *and* before the
  branded template; its frozen bytes are the old monochrome layout.
- **Column misalignment** — the old template had a minimal **4-column** table (Description/Qty/Unit/Amount), not the
  branded 6-column table.
- **PRO FORMA heading + watermark** — issued before the classification fix, and its order is a genuine unpaid `DRAFT`.
- **Crowded totals / irrelevant PICKUP / "Order: (Draft)"** — old template + the IPTV order's placeholder `PICKUP`
  type + no order number.

A stored invoice PDF is immutable (legal/audit), so PF-2026-0015 was **not** regenerated, relabelled or overwritten.
The fixes below apply to **newly issued** invoices. (See `screenshots/invoice-final-qa/before-PF-2026-0015-*.png`.)

## What was changed (template + metadata only; no financial logic)

1. **Stable 6-column table (Task 3)** — `resources/views/invoices/pdf.blade.php` now declares an explicit
   `<colgroup>` with proportions summing to 100% (Description 42% · Qty 7% · Unit price 14% · Discount 11% · Tax 12% ·
   Line total 14%). DomPDF does **not** honour `table-layout: fixed`, so widths live on the columns, which DomPDF
   respects as stable preferred widths in its auto layout. Description is left-aligned and wraps
   (`overflow-wrap: anywhere`); **Qty is centred**; all currency columns are right-aligned and `nowrap`; header and body
   cells line up on every row and every page (verified on a 5-page invoice).
2. **Digital-service fulfillment (Task 6)** — `InvoiceService::buildMetadata()` adds `fulfillment.physical`
   (`order_source !== 'SYSTEM'`). The template suppresses the Fulfillment block for digital services (IPTV renewals),
   so no misleading **PICKUP** appears; the service description + duration remain on the line
   ("IPTV renewal — N months"). Physical retail/online orders still show Fulfillment (e.g. "Online Delivery · Courier").
   `physical` defaults to `true` for legacy metadata, so nothing changes for already-issued documents.
3. **Classification / heading (Task 4)** — already delivered in the prior commit (`0a8e61e`): a formally-issued
   (committed) order is a **TAX INVOICE** with the payment pill shown separately (PAYMENT PENDING / PARTIALLY PAID /
   PAID); PRO FORMA is reserved for a genuinely preliminary unpaid DRAFT; the PRO FORMA watermark only renders for
   proformas. No watermark on issued invoices.
4. **Header spacing / totals (Tasks 5 & 7)** — unchanged from the prior refinement: ~20/20/20/22 mm margins, logo +
   business block left, title/number/date/terms/status right, and the Subtotal · Discount · Tax · Grand total · Amount
   paid · Balance due block right-aligned within the margins. Confirmed visually (below).

## Visual testing — actual rasterized PDFs (not unit tests alone)

Rendered through the live DomPDF pipeline with the **real TechTitans tenant logo** via `TenantLogoService`, and the
newest invoice opened through the **actual IPTV account → Invoices → View Invoice** route in Playwright.
Screenshots in `docs/techtitans/screenshots/invoice-final-qa/`:

| # | Scenario | Result |
|---|---|---|
| 1 | New TechTitans invoice **with uploaded logo** | ✅ logo top-left (`after-realroute-INV-2026-0028.png`) |
| 2 | IPTV **paid** invoice | ✅ TAX INVOICE + PAID, no PICKUP |
| 3 | IPTV **unpaid** invoice | ✅ TAX INVOICE + PAYMENT PENDING |
| 4 | **Partially paid** | ✅ TAX INVOICE + PARTIALLY PAID (INV-2026-0028, paid 7.00 / due 15.60) |
| 5 | **Discount + tax** | ✅ Discount (−CAD) and Tax (amount + 13%) columns aligned |
| 6 | **Long description** | ✅ wraps inside Description, no collision (`after-multipage-p1-longdesc.png`) |
| 7 | **Multi-page** | ✅ 5 pages, header repeats, stable columns, "Page X of Y" (`after-multipage-p2-*`) |
| 8 | **Retail with physical fulfillment** | ✅ "Online Delivery · Courier" shown (`after-physical-retail-fulfillment.png`) |
| 9 | **Tenant without logo** | ✅ clean text-only header, no broken image (`after-nologo-tenant.png`) |
| 10 | **Historical PF-2026-0015** | ✅ unchanged frozen bytes (`before-PF-2026-0015-*.png`) |

**Acceptance check — real route, newly issued:** a fresh IPTV renewal was issued and opened via the actual **View
Invoice** button (`GET /orders/{id}/invoice` → 200). The returned PDF (**INV-2026-0028**) visibly shows the TechTitans
logo, the professionally aligned 6-column table (Qty centred, currency right-aligned), the **TAX INVOICE** heading with
a separate **PARTIALLY PAID** pill, **no PICKUP**, and right-aligned totals within the margins. The live invoice list
shows the new INV- numbers alongside the untouched historical PF- documents (`after-ui-invoices-list.png`).

## Tests & static analysis

- `tests/Feature/Orders` + `tests/Feature/Iptv` → **281 passed (1349 assertions)**, including new
  `test_digital_system_order_suppresses_physical_fulfillment` and
  `test_physical_order_shows_fulfillment_and_all_six_columns`.
- **Pint**: passed. **PHPStan** (`app/Invoices`): **No errors.**
- Full backend suite was green on the prior classification commit; this change is template + one metadata field.

## Files changed

| File | Change |
|---|---|
| `resources/views/invoices/pdf.blade.php` | `<colgroup>` 6-column widths; Qty centred; wrap rules; Fulfillment gated on `physical` + prettified; removed unsupported `table-layout:fixed`. |
| `app/Invoices/InvoiceService.php` | `buildMetadata()` adds `fulfillment.physical` (digital vs physical). |
| `tests/Feature/Orders/InvoicePdfTest.php` | +2 regression tests (digital fulfillment suppression; physical fulfillment + six columns). |
| `docs/techtitans/INVOICE-FINAL-VISUAL-QA.md` + `screenshots/invoice-final-qa/` | This report + before/after PDFs. |

## Safety

No change to invoice amounts, taxes, payment ledger, customer data, tenant isolation, invoice numbering, or any
historical issued PDF. The digital-fulfillment and column changes are presentation-only. Not pushed or deployed.

## Commit (on `techtitans/integration`, no push)

- **Backend:** `1b6ce38` — template + metadata fix, regression tests, this report and before/after screenshots.
  (Document classification/heading fix is the prior commit `0a8e61e`.)
