I am planning to use WeasyPrint to “generate PDF” from the same HTML
that the user view, but it seems that it does not support flex’s gap
and some other properties that i had to change to work in both user
agents.
I also moved the invoice’s “footer” inside the last product’s body
because i do not want the footer to be a “widow”.
Had to group name and description rows in tbody because i do not want
to break them on pagination.
I also could not use tfoot for subtotal, taxes, and total because then
they appear on every page.
The disclaimer should appear only at the very bottom of the last page,
but i do not know how to do that; using position fixed shows it on
every page.
The design calls for rendering all amounts with their currency symbol,
but golang.org/x/text’s currency package always render the symbol in
front, which is wrong in Catalan and Spanish, and a lot of other
languages.
Consulting the Internet, the most popular package for that is
accounting[0], which is almost as useless because they confuse locale
with the currency’s country of origin’s “usual locale” (e.g., en-US for
USD), which is also wrong: in Catalan i need to write USD prices as
"1.234,56 $" regardless of what Americans do.
With accounting i have the recourse of initializing the struct that
holds all the “locale” information, which is also wrong because i have
to define the decimal and thousands separators, something that depends
only on the locale, next to the currency’s precision, that is
locale-independent. But, since all CLDR data from golang.org/x/text
is inside an internal package, i can not access it and would need to
define all that information myself, which defeats the purpose of using
an external package.
Since for now i only need the format pattern for currency, i just saved
it into the database of available languages, that i do not expect to
grow too much.
[0]: https://github.com/leekchan/accounting
They are not functions because i need to join them with the main
invoice relation, and although possible is a bit more awkward with
functions.
The taxes have their own relation because i will need them grouped by
their name in the PDF, so it will probably be a select for that
relation.
They are to complete the invoice, so it can be in an invalid date, but
we do not want to force people to finish all required inputs before they
can add products or update quantities, do we?
Now had to add the empty option label for customer in all cases, because
it could be empty, although that should be done regardless in case
someone has a browser that does not validate fields.