Customer told us that they are used to a view of the booking status of
each campsite in the form of a grid: each campsite is a row, and each
day a column; bookings are show as boxes from the first day to the last
day on the corresponding campsite’s row.
I do not yet show the booking boxes, but at least now i have the grid
and date selector form in place.
In the form i would need a couple of input[type=month], but this is not
yet supported in Firefox and Safari. According to MDN, one common way
to bypass that problem is to have two fields, one for the month and the
other for the year; i just did that, but had to create a new input type
in the `form` package just for this.
It turns out that, **this time**, at least, the way to compute the
discount is not by “the more expensive”, but “the more expensive _in a
given group_”.
However, there are a couple of options, such as motorhome, that can be
in different groups but only must be used once.
Customer wants this because the booking is not automatically created,
thus it is possible to overbook. They want to accept the payment of
those that they can actually book.
Since this address is used to send notifications when a new payment is
received, is quite important not to use the same address as in
production, or there is a non-trivial chance of confusion.
I swear i believe sometime before we said that the number of dogs is not
important and should be used only as a boolean, but apparently it is
wrong: it should be number_dogs * cost_per_pet.
After months of keeping what does the ACSI checkbox mean, now customer
told us that we should add a discount based on a series of
arbitrary conditions that, and need to be done NOW!
There is no UI to edit the conditions due to lack of time.
I always intended to delete draft payments after some time. I follow
WooCommerce’s default times: 1 day for draft and 1 hour for pending. No
other reason than we are used to it.
I added a cron job, rather than a systemd timer, because i want email
notifications, and because i do not yet know how to add many service
files in a Debian package.
We have some clients that are on slow connections that have trouble
uploading large images due to timeout, and receive a “Guru Meditation”
from Varnish that it could not fetch.
Redsys are a bunch of … something: they **only** recognize HTTP 200
as success; HTTP 204 apparently is an error for they, and don’t get
me started in not understanding what to do with an HTP 301.
Let’s just give in, and relax.
This is specially for the departure date: Firefox triggers a change each
time the user writes something, but since the date may be outside the
allowed range while the user is typing, the form replaces the input with
the “corrected” one. The idiomorph thing is to keep the focus in the
“same” field, from the point of view of the user.
It still happens if one is slow enough, but i guess people that want to
write instead of picking the date are usually fast typist. Let’s hope.
This is required by law.
I do not know why i have this value and the tax amount in the database,
but the payment percent and the number of days are hardcoded. I guess i
am such an inconsistent mess.
Apparently, the bank has to validate the fucking thing on the actual
domain, because of reasons, so we have to replace the current web in
production with this version in test mode, meaning that users **will**
believe they have paid, when in fact they have not.
The warning is for these few people that actually read such notices.
This is the mode they want to work with, but i could not test it because
they do not have it enabled in Redsys. For now, just add the status and
the code to handle the responses.
Now i store all responses, if they are for a valid payment, just in case
i fucked something up. I also needed it because an authorization hold
needs at least two responses: one to accept the hold, and another for
the settlement.
Had to do a couple of changes to the database: add the currency_code to
the payment relation, to format the price according to the payment’s
currency instead of the company’s; and the reference SQL function, to
replace the equivalent golang function, so that i can use it to index
payments.
The rest is mostly the same as any other page, except that the
individual payment’s page is not a form, but a regular info dump.
I also moved the payment settings as a sub-route of payments, as i
believe this makes more sense than an additional user menu item.
Customer wants to require a down payment of 30 % for bookings made
one week or more before the actual date, and to make the full payment
otherwise.
This would require yet another relation to keep these values. Fuck it;
i added them to the function, as they are very unlikely to change.
That forced me to change the test for draft_payment to use relative
dates, otherwise there is no way i can have stable results in the
future.
This is easier to read and requires less unit tests, but i only used
them in the new relations and fields for HEAD, because i do not see any
point on creating migrations just for that.
This can happen when the customer reaches the payment page, but then
returns back to the booking form via the back button: the browser
remembers the URI with the cart slug, trying to make it ready, and then
it fails because it is already pending.
I did not like the idea of modifying a payment that is already not
a draft, because it seems to me that can lead to errors if we receive
Redsys notifications of payments that are being changed back to draft.
In fact, i believe that draft payments maybe should go to a different
relation altogether, so that i can prevent UPDATE on payment by guests,
but maybe i am going overboard now.
This way i can use the function in the from clause of the query that
i already had to do to get the totals formatted with to_price. In this
case, i believe it is better to leave out Go’s function because it would
force me to perform two queries.
Instead of binding a nullable string pointer with the payment’s slug,
i wanted to use pgtype’s zeronull.Text type, but it can not work in this
case because it encodes the value as a text, while the parameters is
uuid. I can not use zero.UUID, because it is a [16]byte array, while i
have it in a string.
Thus, had to create my own ZeroNullUUID type that use a string as a base
but encodes it as a UUID.
Otherwise, it reloads the form while customers are writing their
details, removing the focus from the form; **very** annoying.
On the plus side, there is nothing to compute when entering these
fields, thus no redundant work is done now.
To send the actual mail with sendmail, i have stolen the code from
go-mail[0] and removed everything i did not need. This is because there
is no Go package to send email in Debian 12, and this was easier than
to build the DEB for go-mail.
Once i have the time….
[0]: https://go-mail.dev/
I have to basically do the reverse of signing the request to verify that
the notification comes from them. Lots of code just for that.
I return the changed status from the PL/pgSQL function because i will
need to email customers when a payment is completed, and i need to know
when.