This is the same as a payment, but the user is the payee instead of the
payer.
I used a different relation than payment because i do not know any other
way to encode the constraint that only invoices can have a collection,
while expenses have only payments.
Besides the name and the fact that they are related to invoices, a
collection is pretty much the same as a payment.
With Oriol we agreed that to add new payments to expenses we should
direct users to a separate payments section, much like the general
payments but centered around the payments of the given expense.
In fact, the only thing i had to do is extract the expense from the
URL, and then adjust the base URI to keep things always within the
correct section; the rest of the code is shared with the general
section.
If there is no invoice number, then they can use the edit item from the
menu, but most expenses do have an invoice, thus this is easier for the
most usual case.
I was repeating myself a lot for this use case, because each one needed
a different URL and SQL query, however they were kind of structurally
similar and could be refactored into common functions.
I actually did not forget them, and i did not add them on purpose,
mistakenly believing that PostgreSQL’s row-level policies would project
only rows from the current company. That is actually how Camper works,
but that’s because we use the request’s domain name to select the
company; here we use the path, and the row-level policy would return
rows from all companies the user belongs to.
I needed to place the payment accounts section somewhere, and the most
logical place seemed to be that dialog, where users can set up company
parameters.
However, that dialog was already saturated with related, but ultimately
independent forms, and adding the account section would make things
even worse, specially given that we need to be able to edit those
accounts in a separate page.
We agreed to separate that dialog into tabs, which means separate pages.
When i had everything in a separated page, then i did not know how to
actually share the code for the tabs, and decided that, for now, these
“tabs” would be items from the profile menu. Same function, different
presentation.
Users are no longer expected to manually set the status of an expense
and, instead, have to add payments to such expense to mark it as partial
or paid.
That means that the PL/pgSQL functions must not accept a status
parameter, the edit and new forms should no longer have a field for
the status, and that the expense list should no longer have the “quick
edit” for their status. That’s why it no longer should have a pointer
cursor, unlike invoice or quote status.
I am using an htmx-infused button to remove the payment, but that
button can not have the CSRF token as value, thus i have to send it in a
header.
The removal of payments warrants a functions, instead of just DELETE
(and CASCADE) as i do for payment methods, because i have to adjust the
status of expenses too. Since i already have functions for everything,
it is not worth using triggers just for that.
This actually should be the “payments and receivables” section, however
this is quite a mouthful; a “receivable” is a payment made **to** you,
therefore “payments” is ok.
In fact, there is still no receivables in there, as they should be in
a separate relation, to constraint them to invoices instead of expenses.
It will be done in a separate commit.
Since this section will be, in a sense, sort of simplified accounting,
i needed to introduce the “payment account” concept. There is no way,
yet, for users to add them, because i have to revamp the “tax details”
section, but this commit started to grow too big already.
The same reasoning for the attachment payment slips as PDF to payment:
something i have to add, but not yet in this commit.
It is common to want to enumerate in a description, for instance when
adding specifications for a hosting, and that enumeration should be
formatted as the user wrote, otherwise it becomes useless.
Closes#94.
In the HTML tables i only compute the aggregated amount by tax class
(e.g., IVA, IRPF), but here we need the actual tax (e.g., IVA 4 %)
because this spreadsheet is intended for accountants.
I can easily extract the amounts from invoice_tax_amount and
expense_tax_amount, but i also need to add the columns to the
spreadsheet, and always with the same order—does not matter much which,
only the same—, that’s why i had to sort the tax IDs when exporting, as
Go does not guarantee an order for maps.
Closes#92
This is mostly to be able to sqitch rebase and restart with the demo
data during development, as it is very unlikely that i will need to
revert those at this point.
This is to help up “sell” the service: people can look around the demo
to see whether it fits them. Of course, everyone should have the same
username in the demo.
We talked about having the username and password displayed above the
form in the template, but i think it makes more sense to give users as
little work as necessary. Plus, that means i do not have to write them
down while developing.
Whether the database is demo or not is not something that directly
depends on the environment, but rather on which database we are
connected to, thus an environment variable would not make much sense—it
has to be something of the database.
PostgreSQL has no PRAGMA application_id or PRAGMA user_version as with
SQLite to include application-specific values to the database. The
equivalent would be customized options[0], intended for modules
configuration, but that would require me to execute an ALTER DATABASE
in demo.sql with an specific datbase name, or force the use of psql to
run script the script, because then i can use the :DBNAME placeholder.
I guess that the most “standard” way is to just create a function that
returns a know value if the database is demo. Sqitch does not add that
function, therefore it is unlikely to be there by change unless it is
the demo database.
https://www.postgresql.org/docs/15/runtime-config-custom.html
If there were contacts added with add_contact passing an empty string
to `web` parameter, contact_web would not have such row, and during the
revert the `web` parameter of contact would end up being NULL.
The legal stuff. Required by Spanish law when setting up a site intended
for pecuniary gain, directly or indirectly.
Now we have more pages to the “public web”, and moved the header and
footer from home to the common layout. I also took the opportunity to
change the element from <div> to the appropriate element based on their
use (i.e., <header> and <footer>).
I removed the <div> around the logo because i did not see any use for
it. I may be from a previous design iteration, but it had no style
applied nor any usage at all in JavaScript.
I mistakenly thought that <small> was de inverse of the deprecated <big>
element, but apparently it is for small-print text and such, thus suited
for this case.
This is mostly to reassure people that we are running the same version
as published on numerus.cat. Or at least, try.
Go 1.18 adds the info from git if the package is build from a git
repository, but this is not the case in OBS, so i instead relay on a
constant for the version number. This constant is “updated” by Debian’s
rules, mostly due to the discussion in [0].
[0]: https://github.com/golang/go/issues/22706