fix(pdf): wrap full product titles + invoice order number + base-currency VAT#431
Conversation
… VAT on invoices
Three invoice/PDF fixes (raised debugging staging order 163295):
1. Long product titles were single-line + ellipsised (and, on older builds, wrapped
into a fixed-height row and clipped). drawTable now supports a per-column `wrap`
flag: a wrap column shows its FULL value over as many lines as needed and the row
grows to fit (dynamic height); non-wrap columns keep the single-line + ellipsis
behaviour so MPNs/barcodes never split. Enabled `wrap` on the description/product/
component columns across every document generator (invoice, sales order, packing
slip, RFQ, manufacturing order, all previews, order-email PDFs).
2. The invoice header showed only the invoice number — added the sales order number
via a new drawHeader `secondaryReference` ("Order: <orderNumber>").
3. The base-currency equivalent on the invoice was hardcoded to GBP and only covered
the total. Now it uses the tenant's actual base currency (getBaseCurrencyDisplay)
and shows the VAT equivalent too, on one line, e.g.
"(GBP equivalent £80.73, 20% VAT £13.46)" — so a UK/GBP business billing in EUR
(or a DE/EUR business billing in USD) still states VAT in the base currency.
Tests: tests/pdf-table-wrap.test.ts (a wrap column grows the row for a long value;
a non-wrap column's height is unchanged). type-check, eslint, next build, full unit
suite (1889 pass / 0 fail) all green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a32002aa1c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const vatPct = so.taxRatePercent != null ? `${(Number(so.taxRatePercent) * 100).toFixed(0)}% ` : '' | ||
| equivParts.push(`${vatPct}VAT ${baseMoney(Number(so.taxBase))}`) |
There was a problem hiding this comment.
Only print a VAT rate when the invoice has one rate
For foreign-currency invoices that contain per-line tax overrides, taxRatePercent is only the order/shipping default while the tax rows above are built from each line's tax rate; using it here labels the aggregate taxBase as a single rate (for example 20% VAT) even when the amount includes 5%/0% lines. In that scenario the generated invoice states the wrong VAT rate for the base-currency total, so omit the percent or derive it only when all taxable lines share it.
Useful? React with 👍 / 👎.
| if (y + thisRowHeight > 780) { | ||
| doc.addPage() | ||
| y = 50 |
There was a problem hiding this comment.
Page-break wrapped rows before drawing the header
When a wrapped row is taller than the space remaining after the table header, this check runs after the header has already been drawn, so the row is moved to a new page while the column labels remain orphaned on the previous page. This can happen with long product descriptions after a long template note/address starts the table near the bottom; the new page then begins with data at y = 50 and no table header.
Useful? React with 👍 / 👎.
…k guard before totals (Codex review) - HIGH: lib/order-email.ts generateInvoicePdf is a separate invoice renderer that still hardcoded the GBP base equivalent (total-only). Apply the same fix: dynamic base currency via getBaseCurrencyDisplay + the combined "(<BASE> equivalent X, N% VAT Y)" line, and add the order number to its header. (taxBase added to SoForPdf.) - MEDIUM: a wrapped description column can leave the line-item table ending near the page bottom, pushing the totals block off-page. Add a page-break guard before the totals in BOTH the invoice route and the email generator. Verified: type-check, eslint, next build, full unit suite (1889 pass / 0 fail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three invoice/PDF fixes (from debugging staging order 163295)
drawTablegains a per-columnwrapflag. A wrap column shows its full value over as many lines as needed and the row grows to fit (dynamic height viaheightOfString); non-wrap columns keep single-line + ellipsis (so MPNs/barcodes never split mid-row). Enabled on the description/product/component columns across every PDF generator (invoice, sales order, packing slip, RFQ, manufacturing order, all previews, order-email PDFs).drawHeadergains asecondaryReference; the invoice now shows "Order: <orderNumber>" under the invoice ref.Verification
2 new unit tests (wrap grows the row; non-wrap height unchanged). type-check ✅, eslint ✅,
next build✅, full unit suite 1889 pass / 0 fail.🤖 Generated with Claude Code