Commit Graph

414 Commits

Author SHA1 Message Date
jordi fita mas 3c14447ef9 Debian: add service and post installation script to create user and group 2023-06-13 14:48:43 +02:00
jordi fita mas d79ddc6731 Log the remote address, and only trust localhost proxies
I need the actual remote address to add fail2ban rules for it, but i
also to not want everyone to be able to fake X-Forward-For HTTP headers.
Which can contain multiple ip addresses, by the way, so i have to get
only the first one, as the others will be the proxies that the request
has been (re)forwarded to.
2023-06-13 14:21:54 +02:00
jordi fita mas ac28393398 Tag sqitch.plan with first version 2023-06-12 16:05:50 +02:00
jordi fita mas dde4395888 Add the most minimal home page design
This is so that Oriol can start working on it.
2023-06-11 22:24:25 +02:00
jordi fita mas 2d5a644c9d Add the “invoiced” quote status
This is for people to mark quotes that are already invoiced and filter
them out in the list.
2023-06-11 22:19:43 +02:00
jordi fita mas a16f696be5 Allow to create an invoice from the data of a quotation 2023-06-10 20:46:03 +02:00
jordi fita mas f43949dd43 Add quote number formatting and next number field to tax details
The same as for invoices: to allow people to have their own numbering
scheme, and for these that start using the program in the middle of the
current year.
2023-06-09 12:43:50 +02:00
jordi fita mas 6c3a3ff232 Allow empty contact and payment method for quotes
I have to use a value to be used as “none” for payment method and
contact.  In PL/pgSQL add_quote and edit_quote functions, that value is
NULL, while in forms it is the empty string.  I can not simply pass the
empty string for either of these fields because PL/pgSQL expects
(nullable) integers, and "" is not a valid integer and is not NULL
either.  A conversion is necessary.

Apparently, Go’s nil is not a valid representation for SQL’s NULL with
pgx, and had to use sql.NullString instead.

I also needed to coalesce contact’s VATIN and phone, because null values
can not be scanned to *string.  I did not do that before because
`coalesce(vatin, '')` throws an error that '' is not a valid VATIN and
just left as is, wrongly expecting that pgx would do the job of leaving
the string blank for me.  It does not.

Lastly, i can not blindly write Quotee’s tax details in the quote’s view
page, or we would see the (), characters for the empty address info.
2023-06-08 13:05:41 +02:00
jordi fita mas 5537a53834 Add margin between quotee and terms and conditions 2023-06-08 12:55:12 +02:00
jordi fita mas 9bb5bcd820 Use the same style for quoter and quotee than invoicer and invoicee 2023-06-08 12:52:40 +02:00
jordi fita mas 9fab65f108 Add terms and conditions to invoice’s view 2023-06-08 12:52:10 +02:00
jordi fita mas ba6f51ac5d Fix getting quote’s terms and conditions from form and database 2023-06-08 12:50:16 +02:00
jordi fita mas 9931796744 Add HTTP controller and view to add quotes
It still does not support quotes without contact or payment.
2023-06-07 16:35:31 +02:00
jordi fita mas efbb4da07f Added SQL views to compute computations amounts and edit them 2023-06-07 15:31:20 +02:00
jordi fita mas f54681de93 Require invoice_product_product for edit_invoice 2023-06-07 15:09:35 +02:00
jordi fita mas 86bf8765fc Use the correct integer literal for invoice_amount
PostgreSQL actually already casts the strings to integers, but best if
everything is as it should.
2023-06-07 14:54:29 +02:00
jordi fita mas a066726c2e Add function to create new quotes
I had to add the quote_number_format to company, similar to how we do
with invoices.
2023-06-07 14:14:48 +02:00
jordi fita mas aeca90256c Remove setting custom number invoice format from add_expense test
It is not necessary for this test and, since the column already has a
default value, setting it there seems like it might have any
consequence.
2023-06-07 13:27:49 +02:00
jordi fita mas 0e20eab46a Add test for invoice_number_counter counter_zero_or_positive constraint 2023-06-07 13:19:06 +02:00
jordi fita mas 775cdef097 Add foreign key constraint to invoice_number_counter.company_id 2023-06-07 13:11:29 +02:00
jordi fita mas 35b12f7ea4 Add relations for sales quotations and their products
They are mostly the same as invoices, but the contact and payment method
are optional, thus, like other optionals fields, i created relations to
link these that have payment method or contact, to avoid NULL columns in
quote.

Still missing functions to add and edit quotations, and views to compute
their tax and total amount.
2023-06-06 21:08:31 +02:00
jordi fita mas d7a256804f Move available_language.sql before user.sql in sqitch.plan
This is because when i create the demo users then i can no remove the
available languages before users, due the constrain, and i can no use
sqitch rebase or revert.
2023-06-06 19:09:48 +02:00
jordi fita mas 0ed0edeff6 Specify build_cookie dependency for login function 2023-06-04 22:59:25 +02:00
jordi fita mas 083d14e324 Allow to change the current year’s invoice number counter
This is for new users that do not start using the application from the
beginning of the current fiscal year and, therefore, need to create
invoices starting from a specific number.

I had to change the constraint on the currval to allow zero, otherwise
it would not be possible to set 1 as the next number, because users
can also not delete the row.
2023-05-31 20:01:00 +02:00
jordi fita mas 1855122d16 Update translations 2023-05-29 00:02:55 +02:00
jordi fita mas 8529da1615 Use HTMx to delete and restore invoice products
It is better that way because it works without JavaScript; if HTMx is
not available, it will just use regulars forms.

The problem is that most of the submit buttons where using formaction
to send the request to a different action, and only one button was the
“real” action.  Since i could not pass the formaction to
invoice-product-form template, i have changed the “default” action to
the one with “ancillary” functions.

I have to use a different action to remove for each product because i
can not pass the index to the backend without JavaScript: it only
depends on the button click, that already has a name for the action.
Thus, in a way, i have “merged” the action and the index in a single
name.
2023-05-29 00:01:11 +02:00
jordi fita mas 07a28639f2 There is no need for array_to_string() in tags 2023-05-27 21:36:10 +02:00
jordi fita mas 27a266097a Do not use pointer to point when retrieving tags to edit
It is the same with go 16, but with Debian’s go 15 it fails and
I believe, but i am not sure, this is the reason.
2023-05-27 20:51:36 +02:00
jordi fita mas 19f81128ec Keep the invoice number when requesting an update while editing 2023-05-26 14:02:39 +02:00
jordi fita mas d8812ba2f1 Add delete button to remove a product from the invoice form
With this button, it is no longer necessary to set the quantity to zero
to remove, at least not with JavaScript.  This is why i am using Alpine:
to use x-cloak and hide it from non-JavaScript users.

Although, i wonder if it would not be better to use HTMx for that?
2023-05-26 13:51:10 +02:00
jordi fita mas 689eab3a08 Use “Save” for all submit buttons of new/edit forms
Oriol says it is easier to understand for users.
2023-05-26 13:38:04 +02:00
jordi fita mas bec1305e8a Add an empty product to blank invoice form
There is no point in creating a new invoice without products, thus we
were forcing users to always use the “Add product” button for no reason
other than it was easier for me….

I wanted to add the product inside ServeInvoice, when the slug is “new”,
but then it tried to compute the invoice total without price or quantity
and it failed.  Thus, i add that product after it has done the
computation query.
2023-05-26 13:33:49 +02:00
jordi fita mas cbe868b6d6 Remove “shadow” variables inside invoices.ServeInvoice 2023-05-26 13:30:45 +02:00
jordi fita mas 992bbf32a9 Toggle filters forms
I tried this already when i started adding filters, but i tried to use
AlpineJS for that, and could not because it would reset the context each
time i submitted the filters, due to HTMx replacing the whole content.

I realized that the only thing i need is some “flag” to show and hide
the form with CSS.  I do not even need AlpineJS for that, but i used it
anyway because then i can use the x-cloak thing to hidde the toggle
button for users with JavaScript disabled.

Similarly, the body by default has that “flag” set in the markup, and is
removed when AlpineJS is initialized, thus if JavaScript is disabled the
filters form is shown nevertheless.
2023-05-24 12:13:09 +02:00
jordi fita mas 92edbdfc4d Reindent numerus.css with IntelliJ 2023-05-24 12:06:03 +02:00
jordi fita mas e68eb52578 Don’t show the “(optional)” label for filter inputs
It adds nothing, as all input fields for filters show be optional.
2023-05-24 11:41:48 +02:00
oriol carbonell pujolàs 79ec3ae4d6 Improve the CSS and general design 2023-05-23 23:13:21 +02:00
jordi fita mas bf2796190f Change the rows of the product description to 1 2023-05-23 15:25:55 +02:00
jordi fita mas d2a06dd1c0 Add class=filters to filters forms 2023-05-23 14:50:46 +02:00
jordi fita mas 9096cfe4f2 Wrap filter buttons with <noscript>
Since forms are already submitted on change, Oriol does not like the
idea of having a useless button around breaking the form grid.
2023-05-23 14:34:46 +02:00
jordi fita mas e974406870 Remove the “all” columns from products and contacts
That column was supposed to have a checkbox for batch operations, but
we do not have any operation that would like to perform to many products
or contacts at the same time.  For now, at least.
2023-05-23 14:21:04 +02:00
jordi fita mas 6c7762057c Change “Edit Invoice” button to just “Save” 2023-05-23 14:18:26 +02:00
jordi fita mas 65ee8a139c Use white-space: pre-line for invoice notes and payment instructions
I want the `white-space: pre` to preserve the newline characters that
users may have used, but this prevents line wrapping and long lines are
not confined within the page margins.

`pre-line` preserves the newlines, but collapses spaces and tabs, and
wraps long text, which is more what i want.
2023-05-22 11:23:19 +02:00
jordi fita mas 5cae0efe8f Fix validation of product ID for invoice products that have none
For some reason, i assumed that if the invoice product has and ID, that
is it comes from the database, it must also have a product ID, which is
incorrect, because we allow invoice lines with products not added to the
product relation.

I am using zero to mean “no product ID”, so now that validation has to
include the zero as well.
2023-05-22 11:16:21 +02:00
jordi fita mas bbabf5c733 Use a null as product ID when adding new products to invoices
Otherwise, pgx (rightfully) tries to convert a "" into a integer, as
this is the field’s type, cannot, and panics with an error.

Added a IntegerOrNull method to FormField because this is exactly the
same that happens with the invoiceProductId, and made no sense to have
to do the logic twice, or in a function inside form.
2023-05-22 11:06:06 +02:00
jordi fita mas 46b079cb0b Add tooltips to the SVG chart with date and amount 2023-05-21 19:22:46 +02:00
jordi fita mas 02a4fad443 Refactor a bit the code that draws SVG polylines in circles 2023-05-21 18:59:42 +02:00
jordi fita mas eb47988464 Add a background rectangle to the chart and fix NaN when max = 0 2023-05-21 00:14:48 +02:00
jordi fita mas 39b0b801b2 Add income and expenses chart in SVG 2023-05-20 15:53:59 +02:00
jordi fita mas d1b978054b Fix dashboard period ranges and add previous month and quarter options
Oriol told me what he actually wants: a way to see the current month,
quarter, and year for both double-check that the taxes form are filled
in correct and to see whether the business is doing well.  This is
specially important for the quarter period, as he has to fill taxes
each quarter.  Thus, the “last 90 days” thing i did was easier for me,
but completely useless for him.

We also decided to add previous month and previous quarter options
because it would be unfair to expect users check that data exactly the
last day or “lose access” to it.
2023-05-19 14:05:57 +02:00