Paper, not a layout
An invoice is read twice: once on a screen and once on a printer, often by someone’s
accounts department. So the whole set is built out of tables with stated column widths and
named paragraph styles — no text boxes, no floating logo, nothing anchored to a paragraph
that moves when you type. Add three line items and the total moves down with them; it does
not land on top of the bank details.
The margins suit A4 and US Letter alike, which is why the type column stops where it does
rather than running to the edge of the page.
No fields, on purpose
The usual trick for a total is a Word field — =SUM(ABOVE) in the cell. It is the one
thing we refuse to ship. Word shows the number it cached when the file was last saved;
LibreOffice Writer and Google Docs show 0. Which means the moment your client opens your
invoice in Google Docs, the total reads zero, and you find out when they ask.
Every number here is text in a cell. You type over the sample figures, and the figure you
see is the figure they see. The README spells out the three numbers to change on an invoice
and how VAT is rounded.
Four documents, one set of blocks
The quote, credit note and statement aren’t restyled copies of the invoice — they are the
same header, address and totals blocks with different words. A quote says valid until and
estimated total; a credit note says neither, because nothing is due, and it names the
invoice it reverses. The statement swaps the line items for a list of open invoices and
adds the ageing split, which is the only part of the set with arithmetic worth checking.
Checked by printing it
Every build converts all four files to PDF with LibreOffice and reads the pages back as
text. If a total, a label or a line item is missing from the printed page, the build fails
and the file never ships. That is also how the Word-field problem was caught: the document
looked right on screen and printed a column of zeros.
Need the numbers to add themselves up? Bill is the same invoice as a
spreadsheet with a register behind it, and the invoice generator
makes a one-off PDF in the browser without any file at all.