Migrate Invoice PDF to pdf-compiler#931
Open
JustSamuel wants to merge 1 commit into
Open
Conversation
SudoSOS Coverage ReportCommit: 78ed1b7 Details (changed files)
The full per-file breakdown is omitted to stay under GitHub's 65,536-character comment limit. Download the |
There was a problem hiding this comment.
Pull request overview
This PR migrates Invoice PDF generation from the legacy LaTeX/pdf-generator-client flow to an HTML template compiled through pdf-compiler, introducing the new “F6c” invoice layout as part of the broader PDF migration tracker (#926).
Changes:
- Replaced the removed
InvoicePdfService(LaTeX) withInvoiceHtmlPdfService(HTML → pdf-compiler). - Added a new HTML invoice template (
src/html/invoice.html.ts) and centralized BAC letterhead/payment details. - Updated unit tests and removed unused legacy PDF helper functions.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/service/invoice-html-pdf-service.ts | Updates/extends tests to cover HTML-based invoice PDF parameter generation and HTML anchors. |
| src/service/pdf/invoice-pdf-service.ts | Removes the legacy LaTeX/pdf-generator-client invoice PDF service. |
| src/service/pdf/invoice-html-pdf-service.ts | Adds new HTML-to-PDF invoice service that computes totals, VAT breakdown, line items, and due date. |
| src/html/invoice.html.ts | Introduces the new two-page “F6c” invoice HTML template rendered to PDF via pdf-compiler. |
| src/helpers/pdf.ts | Removes now-unused legacy helpers (emptyIdentity, subTransactionRowToProduct) tied to the old invoice PDF implementation. |
| src/files/templates/bac-letterhead.ts | Adds a single source of truth for BAC letterhead/payment details used by the invoice template/service. |
| src/entity/invoices/invoice.ts | Switches the invoice entity to use InvoiceHtmlPdfService by default. |
Comments suppressed due to low confidence (2)
test/unit/service/invoice-html-pdf-service.ts:266
- This test restores
uploadPdfStubinside the test body, butafterEachalso restores the same stub. Restoring stubs mid-test makes teardown order-dependent and can lead to double-restore issues or accidental invocation of real implementations. Prefer keeping the stub in place and configuring its behavior for this test (or create a separate sandbox/service instance for tests that need the real method).
test/unit/service/invoice-html-pdf-service.ts:336 - These tests call
compileHtmlStub.restore()even thoughafterEachalways restores the stub, andcreateRaw()does not callcompileHtml()anyway. This extra restore is unnecessary and makes the test setup/teardown harder to reason about (and can become brittle if the stubbing strategy changes). Consider removing the manual restores and/or only stubbingcompileHtmlin tests that actually exercise PDF compilation.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
acc26bb to
26cad08
Compare
Replace InvoicePdfService (LaTeX via pdf-generator-client) with InvoiceHtmlPdfService (HTML via @gewis/pdf-compiler-ts). The new service extends HtmlPdfService, so getOrCreatePdf and the storage flow stay unchanged; getParameters now contains the per-row aggregation that previously lived only in the dev harness. The visual design is F6c, the variant picked during the design exploration: a two-page layout with a Factuur cover and a Line items spec page. Existing cached InvoicePdf rows regenerate on next access because the new parameter shape produces different hashes. emptyIdentity and subTransactionRowToProduct are removed from src/helpers/pdf.ts since only the deleted invoice service used them. The PDF_VAT_* constants and UNUSED_PARAM stay until the remaining six LaTeX PDFs migrate. Part of #926.
26cad08 to
78ed1b7
Compare
RubenLWF
requested changes
Jun 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
First of seven PDF migrations under #926. Replaces the LaTeX invoice service with an HTML one that goes through pdf-compiler instead of pdf-generator-client, and lands the F6c design as the new invoice layout.
Visual change
The PDF now renders as the two-page F6c design: a Factuur cover with the recipient, totals headline, BTW spec table and BAC letterhead, plus a line items page with one row per sub_transaction_row (ascending by row id). Cached invoices regenerate on next access because the new parameter shape produces different hashes, so getOrCreatePdf falls through to createPdf for any invoice with a stale PDF on disk.
The "Attn. " line ("t.a.v." in Dutch) renders between the addressee and the street when invoice.attention is set. The dev seed leaves attention empty so the smoke render looks identical to before, but invoices created via the API can have it set and will now show it.
Spillover for long invoices
Invoices with many distinct products spill onto multiple line item pages. The template puts spacer rows inside the items table thead and tfoot, so every continuation page gets ~80px above and ~60px below the rows instead of items butting up against the page edge. Chromium ignores @page :first and :nth() on continuation pages, so the spacers have to live inside the table for them to auto-repeat.
Tested at 30, 60 and 120 distinct line items.
Removed
Not removed yet
pdf-generator-client is still in package.json since six other PDFs use it. Removing it is the final PR in the series, per PLAN-invoice-pdf-migration.md section 3.
Related issues/external references
#926
Types of changes
PR Checklist
Additional Notes
Smoke tested end-to-end against a running backend with the abc.docker-registry.gewis.nl/eou/pdf-compiler:latest container running locally. The rendered PDF matches the F6c reference output.