Commit Graph

436 Commits

Author SHA1 Message Date
jordi fita mas 7edf3a3ed1 Pre-fill all guests with the holder’s address
Most will be families living at the same address.  And, if they are not,
it is far easier to replace the incorrect address with the actual,
rather than write the same address to all family members under the same
household.
2024-04-29 17:49:38 +02:00
jordi fita mas f71ad2cc65 Redirect to invoice after create, not booking 2024-04-28 22:50:56 +02:00
jordi fita mas 90d8247c0f Fix null problems 2024-04-28 22:49:04 +02:00
jordi fita mas 2299f2325e Allow to create the customer to invoice “in flight”
That way i can get the data from the booking or the actual customer.
2024-04-28 22:36:21 +02:00
jordi fita mas ff9f33dfba Add invoicing of bookings
It is a bit user-hostile because you have to create a new customer prior
to create the invoice, but that’s what it is for now.
2024-04-28 21:56:51 +02:00
jordi fita mas 205d1f1e99 Include weasyprint as dependency of camper package 2024-04-28 21:47:44 +02:00
jordi fita mas d0f6c9734a Confirm a created booking if admin saves it 2024-04-28 21:00:15 +02:00
jordi fita mas 17f7520876 Add customer and invoices sections
Copied as much as i could from Numerus, and made as few modifications as
i could to adapt to this code base; it is, quite frankly, a piece of
shit.

We need to be able to create invoices from scratch “just in case”,
apparently, but it is not yet possible to create an invoice from a
booking.
2024-04-28 20:28:45 +02:00
jordi fita mas 3559ff311b Chose the actual campsite when double-clicking on the accommodation grid 2024-04-26 17:31:39 +02:00
jordi fita mas 846ca0bc5c Add an empty value to the “choose country” option in booking form
Otherwise, the value is the same as the label
2024-04-26 17:31:13 +02:00
jordi fita mas f2b24a83a3 Add check-in form
I based the form from the documentation given by the Mossos
d’Esquadra[0], required by law.

https://registreviatgers.mossos.gencat.cat/mossos_hotels/AppJava/fitxaviatger.do?reqCode=create
2024-04-26 17:09:36 +02:00
jordi fita mas c9e8165f83 Allow updating bookings
I need to retrieve the values from the database and put them in the
form, like all other forms, but in this case the processing is done as
if it were a new form, because everything comes from the query string
and there is no need to do any extra work then.

Had to move the <footer> from the fields.gohtml to form.gohtml because
then it could not know that it was editing an existing booking.  Had to
move the <fieldset> out too, in order to give it an ID and make it
htmx’s target, or it would replace the form, causing even more problems
—the button would disappear then—.  The target **must** be in <form>
because it is needed for tis children’s hx-get and for its own hx-put.
2024-04-25 20:27:08 +02:00
jordi fita mas 30e87c309e Remove useless fields from paymentDraft
At first i thought i would need to keep the second query of draftPayment
in newBookingCart, its caller, and i added these fields to pass back
the parsed or retrieved values, but when i could move that query within
draftPayment i forgot to remove them.
2024-04-25 13:17:07 +02:00
jordi fita mas 9eb6483cb9 Allow opening a booking or creating a new from the booking grid
I wanted to use a regular <a>, but apparently rendering that many
anchors is too resource-intensive for Firefox, and it is noticeably
slower.  It was even worse, in fact, because i had to have different
content for the main grid and the grid show in the new booking form,
as i did not want to have these links there, and had call a template for
each cell: 3 months × ~30 days × ~100 campsites = 9000 calls!

Using JavaScript for that is shameful, but it does not add much to the
existing markup, and no need for template fuckery.

I am using double-click to follow these links, instead of single click,
because it would be too easy to misclik on the grid, but that forced me
to add `user-select: none` to prevent the selection of text when double-
clicking.
2024-04-25 12:29:43 +02:00
jordi fita mas 2d4055b653 Fix insert of booking in demo SQL file 2024-04-24 20:39:19 +02:00
jordi fita mas b7e7d79177 Add alter column back to integer for booking.number_dogs in reverse 2024-04-24 20:29:23 +02:00
jordi fita mas fdf9502c8b “Finish” the new booking form
Had to bring the same fields that i have for a payment to booking,
except that some of those should be nullable, because it is unreasonable
to ask front desk to gather all customer data when they have a booking
via phone, for instance.

Therefore, i can not take advantage of the validation for customer data
that i use in the public-facing form, but, fortunately, most of the
validations where in separated functions, thus only had to rewrite that
one for this case.

I already have to create a booking from a payment, when receiving a
payment from the public instance, thus i made that function and reused
it here.  Then i “overwrite” the newly created pre-booking with the
customer data from the form, and set is as confirmed, as we do not see
any point of allowing pre-bookings from employees.
2024-04-24 20:19:13 +02:00
jordi fita mas 3aa53cf1a9 “Mockup” for the new booking form
It does nothing but compute the total of a booking, much like it does
for guests.  In fact, i use the same payment relations to do the exact
same computation, otherwise i am afraid i will make a mistake in the
ACSI or such, now or in future version; better if both are exactly the
same.

The idea is that once the user creates the booking, i will delete that
payment, because it makes no sense to keep it in this case; nobody is
going to pay for it.

Had to reuse the grid showing the bookings of campsites because
employees need to select one or more campsites to book, and need to see
which are available.  In this case, i have to filter by campsite type
and use the arrival and departure dates to filter the months, now up to
the day, not just month.

Had to change max width of th and td in the grid to take into account
that now a month could have a single day, for instance, and the month
heading can not stretch the day or booking spans would not be in their
correct positions.

For that, i needed to access campsiteEntry, bookingEntry, and Month from
campsite package, but campsite imports campsite/types, and
campsite/types already imports booking for the BookingDates type.  To
break the cycle, had to move all that to booking and use from campsite;
it is mostly unchanged, except for the granularity of dates up to days
instead of just months.

The design of this form calls for a different way of showing the totals,
because here employees have to see the amount next to the input with
the units, instead of having a footer with the table.  I did not like
the idea of having to query the database for that, therefore i “lifter”
the payment draft into a struct that both public and admin forms use
to show they respective views of the cart.
2024-04-23 21:07:41 +02:00
jordi fita mas 598354e8b7 Add missing autocomplete attribute to town or village 2024-04-22 18:44:48 +02:00
jordi fita mas dab19bbc4d Fix attributes of country select in public booking page 2024-04-22 18:44:22 +02:00
jordi fita mas 0e22096447 Tag version 8 of the database
I will need to change draft_payment **again**, and possibly many times,
during the development of the booking admin section.  Many times.
2024-04-22 13:43:38 +02:00
jordi fita mas a26e9c6e12 Fix tests for booking and booking_campsite 2024-04-21 21:57:34 +02:00
jordi fita mas 7eb718dfd9 Allow many campsites for each reservation
This is actually only used for plots, but, of course, it means that
every booking now can potentially have many booked campsites, and have
to create a relation for it.

I now have a conundrum regarding stay dates: i need them to be in the
same table as the campsite_id, because constraints only work on a single
relation and without the dates i can not make sure that i am not
overbooking a given campsite; but, on the other hand, all campsites
under the same booking must be for the same dates.

Where does stay belong, then? In booking or booking_campsite? If in
booking then i can not have a constraint that most assuredly will bite
me in the back, but if in booking_campsite then each campsite could
potentially have different dates.

As far as i can see, i can not use a exclude constraint with <> for
dates in booking_campsite to ensure that all rows with the same
booking_id have the same stay (i.e., exclude those that have a different
stay for the same booking_id).

For now, the say is in **both** relations: in booking, because i need it
when it is a prebooking, at least, and in booking_campsite for the
aforementioned constraint requirements.

Will this come back and bite me? Yes, it will. But what can i do?
2024-04-21 21:28:41 +02:00
jordi fita mas cba892c4c0 Fix booking list to use stay instead of arrival_date and departure_date 2024-04-19 21:29:36 +02:00
jordi fita mas cdd91c815e Show booking on booking grid
I need the campsite_id in booking to know what row to show the booking
at. Besides the need of knowing which actual campsite has been booked,
of course.

This field is nullable because we can not now it until an employee has
confirmed the booking; until that point we only know the campsite type
customer requested.  I do not care much if the campsite_id is from a
different campsite_type, because maybe the customer requested the change
by phone or what have you, therefore the database can not be that
strict.  It must have a value if the booking is confirmed.

It helps me if the arrival_date and departure_date is a single
daterange, because then i can use `&&` and other range operators to work
with these dates.  For instance, i have to intersect it with the range
displayed on the screen in order to know which day i have to put it.
But then i have to know whether the booking begins and ends in the
display range, because i only have to show arrival and departure (i.e.,
the box half-way within the first or last boxes) on these days only.
2024-04-19 21:09:28 +02:00
jordi fita mas bc5fd61d5d Move the booking’s filter to the bottom
The first thing to show, the most important, is the grid; then users
can change the grid’s output.
2024-04-19 17:39:44 +02:00
jordi fita mas 23d16fa162 Only show individual campsite and “Add campsite” links to admin
Regular users do not need, or can use, those links.
2024-04-19 17:37:28 +02:00
jordi fita mas e726bde025 Replace admin’s campsite map with a booking grid
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.
2024-04-19 11:29:52 +02:00
jordi fita mas 746aa013d3 Group ACSI options and allow for usage in different groups
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.
2024-04-03 12:56:52 +02:00
jordi fita mas b291ac34fc Tag database with version 7 2024-04-03 09:34:36 +02:00
jordi fita mas 6c18529317 Take only into account the more expensive option when computing ACSI
Apparently, this is how it is done, now.
2024-03-25 17:47:43 +01:00
jordi fita mas 75c94a95f5 Remove a paste error from camper.css 2024-03-25 16:43:58 +01:00
jordi fita mas 72f8a329d2 Use pre-authorization to accept payment, rather than charge
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.
2024-03-24 22:06:59 +01:00
jordi fita mas d71d974abd Change demo’s email address
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.
2024-03-24 20:28:48 +01:00
jordi fita mas 1b46f4224e Compute the subtotal of dogs using their number, not as a boolean
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.
2024-03-20 18:17:58 +01:00
jordi fita mas fc9ac321d5 Tag database with version 6 2024-03-20 18:10:49 +01:00
jordi fita mas dbbd06cf85 Change the verify for season_calendar_season_id_fkey
It failed in build.opensuse.org; possibly the view in information_scheme
is different.
2024-03-14 22:28:46 +01:00
jordi fita mas 0412ffca05 Compute ACSI discount
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.
2024-03-14 22:08:01 +01:00
jordi fita mas cc1b334639 Add missing foreign key between season_calendar and season 2024-03-14 18:38:58 +01:00
jordi fita mas cb1e3afb44 Tag database with v5 2024-03-13 20:55:58 +01:00
jordi fita mas 864286e52a Fix the scheme used in flush payments’ cronjob 2024-03-13 18:28:46 +01:00
jordi fita mas 5cf45dcd41 Add flush_payments to clean up draft and pending payments
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.
2024-03-13 14:54:30 +01:00
jordi fita mas 75e0d8e197 Increase HTTP timeout
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.
2024-03-05 12:05:00 +01:00
jordi fita mas 365fed55b1 Grant SELECT on payment_status to guest
It is necessary to send the details email from the notification handler.
2024-02-29 18:06:50 +01:00
jordi fita mas 0ba088e5e2 Remove an HTML tag from email’s body in plain text 2024-02-29 17:39:00 +01:00
jordi fita mas dc9e45dfde Send a notification email to the company too on successful payment 2024-02-29 16:59:30 +01:00
jordi fita mas 334904fc03 Actually log request to stdout to be captured by systemd 2024-02-29 16:12:08 +01:00
jordi fita mas 9dc4c4ef8d Remove a fmt.Println leftover from a debug session 2024-02-29 16:11:23 +01:00
jordi fita mas 4e2df3f3c3 Return HTTP 200 instead of HTTP 204 for payment notifications
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.
2024-02-28 13:42:12 +01:00
jordi fita mas 62d15970bf Reduce booking’s change delay to 500 ms 2024-02-28 13:36:14 +01:00