Skip to content

feat(templates): carry a monogram, a ship-to, per-line tax and a payee on the structured invoice - #622

Merged
DemchaAV merged 1 commit into
feature/template-promotionfrom
feat/structured-invoice-luma-fields
Aug 31, 2026
Merged

DemchaAV merged 1 commit into
feature/template-promotionfrom
feat/structured-invoice-luma-fields

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

The structured invoice model landed in #611 with one consumer, ConsultingInvoice. A model shaped around one document is a model nobody has tested, and the next published invoice — a UK studio's, with a drawn monogram, a delivery address and VAT per line — found six things it could not say.

Each of them is general rather than one design's whim, which is the test this change had to pass before touching a public record.

What changed

  • InvoiceBrand.monogramTop / monogramBottom — a lockup drawn as two lines of initials rather than an image. hasMonogram() answers it the way hasLogo() already answers the other.
  • InvoiceContactBlock.taxRegistrationLabel / taxRegistrationNumber — a second labelled registration. A UK sender prints both a company number and a VAT number; the model had room for one, and the labels are content because they differ by jurisdiction.
  • StructuredInvoiceData.shipTo — the delivery address beside the billing one. It normalises to the empty recipient rather than null, like every other block, so preset code reads it without a check.
  • InvoiceServiceLines.Line.vatRate and Columns.vat — the tax rate printed per line and the column heading it sits under. It is a String, not a number, because what a sheet prints is 20% in one jurisdiction and something else in another, and the model should not decide the wording.
  • InvoicePaymentBlock.accountHolder / signOff — who the money is paid to, set above the fields, and the closing line beside the due notice.

Every addition is blank when absent. Every constructor that predates one is kept explicitly.

Verification

Full reactor gate → BUILD SUCCESS; the invoice suites 27/27.

The compatibility promise is pinned twice over. StructuredInvoiceCompatibilityTest exercises each old constructor and asserts the new field comes back blank, plus that an absent shipTo normalises to the empty recipient rather than null. And ConsultingInvoice — the model's existing consumer — passes its exact layout snapshot and its pixel baseline untouched, which is the stronger proof: had any of this been more than additive, those two would have moved.

Notes

  • No preset reads the new fields yet. The one that does arrives next: the published luma-co-studio-invoice, whose entrypoint had to be reconstructed before it could be ported at all.
  • The obvious alternative — a third invoice model — was rejected. Two models already carry a cost of explanation; a third for one sheet would be worse than five additive fields on the one designed for exactly this shape.

Lane: canonical (templates.data.invoice + qa) — no engine changes, no preset changes.

@DemchaAV
DemchaAV merged commit 80cc372 into feature/template-promotion Aug 31, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the feat/structured-invoice-luma-fields branch August 31, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant