CluPilotCloud/app
nexxo c1896e70fc
tests / pest (push) Failing after 7m9s Details
tests / assets (push) Successful in 24s Details
tests / release (push) Has been skipped Details
Render an invoice, with the arithmetic held to integer cents
TCPDF 6, deliberately, after installing 7 and finding out what it is. Version 7
is not a newer TCPDF; it is a compatibility shim over tc-lib-pdf whose own
mapping table lists 115 of 293 methods as stubs, and whose font package ships
no font files at all — the first render died on a missing helvetica.json. The
6.x line carries a hundred and sixty-five fonts, a working writeHTML and real
header and footer hooks, and is what everybody means by TCPDF.

The body is a Blade template handed to writeHTML rather than a hundred Cell()
calls with millimetre coordinates, because this table has to be adjusted the
first time somebody sees it on paper, and nobody adjusts the second kind.

InvoiceMath is integer cents end to end, and rounds once. A percentage applied
line by line and rounded each time drifts from the same percentage applied to
the sum — three lines at 3,33 € less 10 % is 99 cents that way and 100 cents
the honest way, and the customer's calculator is what finds it. Gross is always
derived from net and never the reverse: taking VAT back out of a gross figure
returns a different number often enough to matter. A discount and a surcharge
are one operation with opposite signs, so nothing has to remember which of two
flags means which.

Quantities are thousandths, because hours, gigabytes and part-months are all
real, and are printed with the trailing zeroes stripped — "12,000 Std." reads
as a defect.

Every line shows quantity, unit price net, total net AND total gross: this goes
to businesses and to consumers, and each reads a different column first.

Verifying it took two goes and both failures were mine. `strings` over a PDF set
in a Unicode font finds nothing, because the text is stored as subset glyph ids
— the check has to render in a core font to be a check at all. And two of the
strings I then declared missing were simply expectations I had got wrong.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 01:41:46 +02:00
..
Actions Put every mail in one design, and confirm an order when the money arrives 2026-07-29 00:14:04 +02:00
Console Move host DNS names off the public zone into vpn-dns's internal hostsdir 2026-07-28 23:44:31 +02:00
Exceptions Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
Http Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
Listeners Recognise the devices an account signs in from, and warn about a new one 2026-07-28 23:28:34 +02:00
Livewire Answer on every name for the website, and send them all to one 2026-07-29 01:29:33 +02:00
Mail Put every mail in one design, and confirm an order when the money arrives 2026-07-29 00:14:04 +02:00
Models Lay the foundation for self-issued invoices: series, numbers, frozen documents 2026-07-29 00:57:06 +02:00
Notifications Add the SSH identity to the vault, and give deployment config a console page 2026-07-29 00:52:44 +02:00
Policies Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
Providers Move host DNS names off the public zone into vpn-dns's internal hostsdir 2026-07-28 23:44:31 +02:00
Provisioning Add the SSH identity to the vault, and give deployment config a console page 2026-07-29 00:52:44 +02:00
Services Render an invoice, with the arithmetic held to integer cents 2026-07-29 01:41:46 +02:00
Support Give the console a Finance tab: company details, VAT rate, invoice series 2026-07-29 01:18:43 +02:00