“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.
This commit is contained in:
jordi fita mas 2024-04-24 20:12:29 +02:00
parent 3aa53cf1a9
commit fdf9502c8b
28 changed files with 1442 additions and 319 deletions

View File

@ -0,0 +1,108 @@
-- Deploy camper:add_booking_from_payment to pg
-- requires: roles
-- requires: schema_camper
-- requires: booking
-- requires: booking__payment_fields
-- requires: booking__stay
-- requires: booking_option
-- requires: payment
-- requires: payment__acsi_card
-- requires: payment_customer
-- requires: payment_option
begin;
set search_path to camper, public;
create or replace function add_booking_from_payment(payment_slug uuid) returns integer as
$$
declare
bid integer;
begin
insert into booking
( company_id
, campsite_type_id
, stay
, subtotal_nights
, number_adults
, subtotal_adults
, number_teenagers
, subtotal_teenagers
, number_children
, subtotal_children
, number_dogs
, subtotal_dogs
, subtotal_tourist_tax
, total
, currency_code
, zone_preferences
, acsi_card
, holder_name
, address
, postal_code
, city
, country_code
, email
, phone
, lang_tag
)
select company_id
, campsite_type_id
, daterange(arrival_date, departure_date)
, subtotal_nights
, number_adults
, subtotal_adults
, number_teenagers
, subtotal_teenagers
, number_children
, subtotal_children
, number_dogs
, subtotal_dogs
, subtotal_tourist_tax
, total
, currency_code
, zone_preferences
, acsi_card
, coalesce(full_name, 'Unknown')
, address
, postal_code
, city
, country_code
, email
, phone
, coalesce(lang_tag, 'und')
from payment
left join payment_customer using (payment_id)
where payment.slug = payment_slug
returning booking_id into bid;
if bid is null then
raise invalid_parameter_value using message = payment_slug || ' is not a valid payment.';
end if;
insert into booking_option
( booking_id
, campsite_type_option_id
, units
, subtotal
)
select bid
, campsite_type_option_id
, units
, subtotal
from payment_option
join payment using (payment_id)
where payment.slug = payment_slug
;
return bid;
end
$$
language plpgsql
;
revoke execute on function add_booking_from_payment(uuid) from public;
grant execute on function add_booking_from_payment(uuid) to employee;
grant execute on function add_booking_from_payment(uuid) to admin;
commit;

View File

@ -0,0 +1,48 @@
-- Deploy camper:booking__payment_fields to pg
-- requires: booking
-- requires: positive_integer
-- requires: nonnegative_integer
begin;
set search_path to camper, public;
alter table booking
add column address text
, add column postal_code text
, add column city text
, add column country_code country_code references country
, add column email email
, add column phone packed_phone_number
, add lang_tag text not null default 'und' references language
, add zone_preferences text not null default ''
, add subtotal_nights nonnegative_integer not null default 0
, add number_adults positive_integer not null default 1
, add subtotal_adults nonnegative_integer not null default 0
, add number_teenagers nonnegative_integer not null default 0
, add subtotal_teenagers nonnegative_integer not null default 0
, add number_children nonnegative_integer not null default 0
, add subtotal_children nonnegative_integer not null default 0
, alter column number_dogs type nonnegative_integer
, add subtotal_dogs nonnegative_integer not null default 0
, add subtotal_tourist_tax nonnegative_integer not null default 0
, add total nonnegative_integer not null default 0
, add currency_code currency_code not null default 'EUR' references currency
;
alter table booking
alter column zone_preferences drop default
, alter column subtotal_nights drop default
, alter column number_adults drop default
, alter column subtotal_adults drop default
, alter column number_teenagers drop default
, alter column subtotal_teenagers drop default
, alter column number_children drop default
, alter column subtotal_children drop default
, alter column subtotal_dogs drop default
, alter column subtotal_tourist_tax drop default
, alter column total drop default
, alter column currency_code drop default
;
commit;

24
deploy/booking_option.sql Normal file
View File

@ -0,0 +1,24 @@
-- Deploy camper:booking_option to pg
-- requires: roles
-- requires: schema_camper
-- requires: booking
-- requires: campsite_type_option
-- requires: positive_integer
-- requires: nonnegative_integer
begin;
set search_path to camper, public;
create table booking_option (
booking_id integer not null references booking,
campsite_type_option_id integer not null references campsite_type_option,
units positive_integer not null,
subtotal nonnegative_integer not null,
primary key (booking_id, campsite_type_option_id)
);
grant select, insert, update, delete on table booking_option to employee;
grant select, insert, update, delete on table booking_option to admin;
commit;

48
deploy/edit_booking.sql Normal file
View File

@ -0,0 +1,48 @@
-- Deploy camper:edit_booking to pg
-- requires: roles
-- requires: schema_camper
-- requires: booking
-- requires: booking__payment_fields
-- requires: booking__stay
-- requires: booking_campsite
begin;
set search_path to camper, public;
create or replace function edit_booking(bid integer, customer_name text, customer_address text, customer_post_code text, customer_city text, customer_country_code text, customer_email email, customer_phone text, customer_lang_tag text, booking_status text, campsite_ids integer[]) returns void as
$$
begin
update booking
set holder_name = customer_name
, address = customer_address
, postal_code = customer_post_code
, city = customer_city
, country_code = customer_country_code
, email = customer_email
, phone = case when customer_phone is null then null else parse_packed_phone_number(customer_phone, coalesce(customer_country_code, 'ES')) end
, lang_tag = coalesce(customer_lang_tag, 'und')
, booking_status = edit_booking.booking_status
where booking_id = bid
;
delete from booking_campsite
where booking_id = bid;
insert into booking_campsite
select bid
, campsite_id
, stay
from booking, unnest(campsite_ids) as campsite(campsite_id)
where booking_id = bid
;
end
$$
language plpgsql
;
revoke execute on function edit_booking(integer, text, text, text, text, text, email, text, text, text, integer[]) from public;
grant execute on function edit_booking(integer, text, text, text, text, text, email, text, text, text, integer[]) to employee;
grant execute on function edit_booking(integer, text, text, text, text, text, email, text, text, text, integer[]) to admin;
commit;

View File

@ -7,7 +7,9 @@ package booking
import (
"context"
"errors"
"net/http"
"strconv"
"strings"
"time"
@ -15,6 +17,7 @@ import (
"dev.tandem.ws/tandem/camper/pkg/auth"
"dev.tandem.ws/tandem/camper/pkg/database"
"dev.tandem.ws/tandem/camper/pkg/form"
httplib "dev.tandem.ws/tandem/camper/pkg/http"
"dev.tandem.ws/tandem/camper/pkg/locale"
"dev.tandem.ws/tandem/camper/pkg/template"
@ -37,8 +40,10 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
switch r.Method {
case http.MethodGet:
serveBookingIndex(w, r, user, company, conn)
case http.MethodPost:
addBooking(w, r, user, company, conn)
default:
httplib.MethodNotAllowed(w, r, http.MethodGet)
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPost)
}
case "new":
switch r.Method {
@ -146,33 +151,47 @@ type adminBookingForm struct {
*bookingForm
ID int
Campsites []*CampsiteEntry
selected []int
Months []*Month
Error error
}
func newAdminBookingForm(r *http.Request, conn *database.Conn, company *auth.Company, l *locale.Locale) (*adminBookingForm, error) {
form, err := newBookingForm(r, company, conn, l)
inner, err := newBookingForm(r, company, conn, l)
if err != nil {
return nil, err
}
if form.Options != nil {
for _, option := range form.Options.Options {
option.Subtotal = findSubtotal(option.ID, form.Cart)
if inner.Options != nil {
for _, option := range inner.Options.Options {
option.Subtotal = findSubtotal(option.ID, inner.Cart)
}
}
f := &adminBookingForm{
bookingForm: form,
bookingForm: inner,
}
// Dates and Campsite are valid
if form.Guests != nil {
arrivalDate, _ := time.Parse(database.ISODateFormat, form.Dates.ArrivalDate.Val)
if inner.Guests != nil {
arrivalDate, _ := time.Parse(database.ISODateFormat, inner.Dates.ArrivalDate.Val)
from := arrivalDate.AddDate(0, 0, -1)
departureDate, _ := time.Parse(database.ISODateFormat, form.Dates.DepartureDate.Val)
departureDate, _ := time.Parse(database.ISODateFormat, inner.Dates.DepartureDate.Val)
to := departureDate.AddDate(0, 0, 2)
f.Months = CollectMonths(from, to)
f.Campsites, err = CollectCampsiteEntries(r.Context(), company, conn, from, to, form.CampsiteType.String())
f.Campsites, err = CollectCampsiteEntries(r.Context(), company, conn, from, to, inner.CampsiteType.String())
if err != nil {
return nil, err
}
selected := r.Form["campsite"]
for _, s := range selected {
ID, _ := strconv.Atoi(s)
for _, c := range f.Campsites {
if c.ID == ID {
f.selected = append(f.selected, c.ID)
c.Selected = true
break
}
}
}
}
return f, nil
}
@ -197,3 +216,128 @@ func (f *adminBookingForm) MustRender(w http.ResponseWriter, r *http.Request, us
template.MustRenderAdminFiles(w, r, user, company, f, "booking/form.gohtml", "booking/fields.gohtml", "booking/grid.gohtml")
}
}
func addBooking(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
f, err := newAdminBookingForm(r, conn, company, user.Locale)
if err != nil {
panic(err)
}
if err := user.VerifyCSRFToken(r); err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return
}
if ok, err := f.Valid(r.Context(), conn, user.Locale); err != nil {
panic(err)
} else if !ok {
if !httplib.IsHTMxRequest(r) {
w.WriteHeader(http.StatusUnprocessableEntity)
}
f.MustRender(w, r, user, company)
return
}
tx := conn.MustBegin(r.Context())
if err := performAddBooking(r.Context(), tx, f); err == nil {
if err := tx.Commit(r.Context()); err != nil {
panic(err)
}
} else {
if err := tx.Rollback(r.Context()); err != nil {
panic(err)
}
panic(err)
}
httplib.Redirect(w, r, "/admin/bookings", http.StatusSeeOther)
}
func performAddBooking(ctx context.Context, tx *database.Tx, f *adminBookingForm) error {
var bookingID int
var err error
bookingID, err = tx.AddBookingFromPayment(ctx, f.PaymentSlug.Val)
if err != nil {
return err
}
return tx.EditBooking(
ctx,
bookingID,
f.Customer.FullName.Val,
f.Customer.Address.Val,
f.Customer.PostalCode.Val,
f.Customer.City.Val,
f.Customer.Country.String(),
f.Customer.Email.Val,
f.Customer.Phone.Val,
language.Make("und"),
"confirmed",
f.selected,
)
}
func (f *adminBookingForm) Valid(ctx context.Context, conn *database.Conn, l *locale.Locale) (bool, error) {
v := form.NewValidator(l)
if f.Dates == nil {
return false, errors.New("no booking date fields")
}
if f.Guests == nil {
return false, errors.New("no guests fields")
}
if f.Customer == nil {
return false, errors.New("no customer fields")
}
if f.Cart == nil {
return false, errors.New("no booking cart")
}
v.CheckSelectedOptions(f.CampsiteType, l.GettextNoop("Selected campsite type is not valid."))
f.Dates.Valid(v, l)
f.Guests.Valid(v, l)
if f.Options != nil {
f.Options.Valid(v, l)
}
var country string
if f.Customer.Country.ValidOptionsSelected() {
country = f.Customer.Country.Selected[0]
}
if v.CheckRequired(f.Customer.FullName, l.GettextNoop("Full name can not be empty.")) {
v.CheckMinLength(f.Customer.FullName, 1, l.GettextNoop("Full name must have at least one letter."))
}
if f.Customer.PostalCode.Val != "" {
if country == "" {
v.Check(f.Customer.PostalCode, false, l.GettextNoop("Country can not be empty to validate the postcode."))
} else if _, err := v.CheckValidPostalCode(ctx, conn, f.Customer.PostalCode, country, l.GettextNoop("This postcode is not valid.")); err != nil {
return false, err
}
}
if f.Customer.Email.Val != "" {
v.CheckValidEmail(f.Customer.Email, l.GettextNoop("This email is not valid. It should be like name@domain.com."))
}
if f.Customer.Phone.Val != "" {
if country == "" {
v.Check(f.Customer.Phone, false, l.GettextNoop("Country can not be empty to validate the phone."))
} else if _, err := v.CheckValidPhone(ctx, conn, f.Customer.Phone, country, l.GettextNoop("This phone number is not valid.")); err != nil {
return false, err
}
}
if len(f.selected) == 0 {
f.Error = errors.New(l.Gettext("You must select at least one accommodation."))
v.AllOK = false
} else if f.Dates.ArrivalDate.Error == nil && f.Dates.DepartureDate.Error == nil {
if available, err := datesAvailable(ctx, conn, f.Dates, f.selected); err != nil {
return false, err
} else if !available {
f.Error = errors.New(l.Gettext("The selected accommodations have no available openings in the requested dates."))
v.AllOK = false
}
}
return v.AllOK, nil
}
func datesAvailable(ctx context.Context, conn *database.Conn, dates *DateFields, selectedCampsites []int) (bool, error) {
return conn.GetBool(ctx, "select not exists (select 1 from camper.booking_campsite where campsite_id = any ($3) and stay && daterange($1::date, $2::date))", dates.ArrivalDate, dates.DepartureDate, selectedCampsites)
}

View File

@ -68,9 +68,11 @@ func CollectMonths(from time.Time, to time.Time) []*Month {
}
type CampsiteEntry struct {
ID int
Label string
Type string
Active bool
Selected bool
Bookings map[time.Time]*CampsiteBooking
}
@ -84,7 +86,8 @@ type CampsiteBooking struct {
func CollectCampsiteEntries(ctx context.Context, company *auth.Company, conn *database.Conn, from time.Time, to time.Time, campsiteType string) ([]*CampsiteEntry, error) {
rows, err := conn.Query(ctx, `
select campsite.label
select campsite_id
, campsite.label
, campsite_type.name
, campsite.active
from campsite
@ -101,7 +104,7 @@ func CollectCampsiteEntries(ctx context.Context, company *auth.Company, conn *da
var campsites []*CampsiteEntry
for rows.Next() {
entry := &CampsiteEntry{}
if err = rows.Scan(&entry.Label, &entry.Type, &entry.Active); err != nil {
if err = rows.Scan(&entry.ID, &entry.Label, &entry.Type, &entry.Active); err != nil {
return nil, err
}
campsites = append(campsites, entry)

View File

@ -7,6 +7,7 @@ package database
import (
"context"
"github.com/jackc/pgtype/zeronull"
"golang.org/x/text/language"
)
@ -351,3 +352,12 @@ func (tx *Tx) TranslateHome(ctx context.Context, companyID int, langTag language
func (c *Conn) ReadyPayment(ctx context.Context, paymentSlug string, customerName string, customerAddress string, customerPostCode string, customerCity string, customerCountryCode string, customerEmail string, customerPhone string, customerLangTag language.Tag) (int, error) {
return c.GetInt(ctx, "select ready_payment($1, $2, $3, $4, $5, $6, $7, $8, $9)", paymentSlug, customerName, customerAddress, customerPostCode, customerCity, customerCountryCode, customerEmail, customerPhone, customerLangTag)
}
func (tx *Tx) AddBookingFromPayment(ctx context.Context, paymentSlug string) (int, error) {
return tx.GetInt(ctx, "select add_booking_from_payment($1)", paymentSlug)
}
func (tx *Tx) EditBooking(ctx context.Context, bookingID int, customerName string, customerAddress string, customerPostCode string, customerCity string, customerCountryCode string, customerEmail string, customerPhone string, customerLangTag language.Tag, bookingStatus string, campsiteIDs []int) error {
_, err := tx.Exec(ctx, "select edit_booking($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", bookingID, customerName, zeronull.Text(customerAddress), zeronull.Text(customerPostCode), zeronull.Text(customerCity), zeronull.Text(customerCountryCode), zeronull.Text(customerEmail), zeronull.Text(customerPhone), customerLangTag, bookingStatus, campsiteIDs)
return err
}

267
po/ca.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-04-19 20:53+0200\n"
"POT-Creation-Date: 2024-04-24 19:59+0200\n"
"PO-Revision-Date: 2024-02-06 10:04+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n"
@ -116,6 +116,7 @@ msgstr "Reserva"
#: web/templates/mail/payment/details.gotxt:16
#: web/templates/public/booking/fields.gohtml:14
#: web/templates/admin/payment/details.gohtml:74
#: web/templates/admin/booking/fields.gohtml:12
msgctxt "title"
msgid "Accommodation"
msgstr "Allotjament"
@ -154,6 +155,7 @@ msgstr "No"
#: web/templates/public/campsite/dates.gohtml:4
#: web/templates/public/booking/fields.gohtml:30
#: web/templates/admin/payment/details.gohtml:86
#: web/templates/admin/booking/fields.gohtml:31
msgctxt "input"
msgid "Arrival date"
msgstr "Data darribada"
@ -162,6 +164,7 @@ msgstr "Data darribada"
#: web/templates/public/campsite/dates.gohtml:15
#: web/templates/public/booking/fields.gohtml:41
#: web/templates/admin/payment/details.gohtml:90
#: web/templates/admin/booking/fields.gohtml:42
msgctxt "input"
msgid "Departure date"
msgstr "Data de sortida"
@ -175,6 +178,7 @@ msgstr "Nits"
#: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98
#: web/templates/admin/booking/fields.gohtml:92
msgctxt "input"
msgid "Adults aged 17 or older"
msgstr "Adults de 17 anys o més"
@ -182,6 +186,7 @@ msgstr "Adults de 17 anys o més"
#: web/templates/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102
#: web/templates/admin/booking/fields.gohtml:108
msgctxt "input"
msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescents dentre 11 i 16 anys"
@ -189,6 +194,7 @@ msgstr "Adolescents dentre 11 i 16 anys"
#: web/templates/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106
#: web/templates/admin/booking/fields.gohtml:124
msgctxt "input"
msgid "Children from 2 to 10 years old"
msgstr "Nens dentre 2 i 10 anys"
@ -196,24 +202,26 @@ msgstr "Nens dentre 2 i 10 anys"
#: web/templates/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110
#: web/templates/admin/booking/fields.gohtml:139
msgctxt "input"
msgid "Dogs"
msgstr "Gossos"
#: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 pkg/booking/cart.go:197
#: web/templates/admin/payment/details.gohtml:114
#: web/templates/admin/booking/fields.gohtml:166 pkg/booking/cart.go:244
msgctxt "cart"
msgid "Tourist tax"
msgstr "Impost turístic"
#: web/templates/mail/payment/details.gotxt:27
#: web/templates/public/booking/fields.gohtml:225
#: web/templates/public/booking/fields.gohtml:230
msgctxt "cart"
msgid "Total"
msgstr "Total"
#: web/templates/mail/payment/details.gotxt:28
#: web/templates/public/booking/fields.gohtml:230
#: web/templates/public/booking/fields.gohtml:235
#: web/templates/admin/payment/details.gohtml:118
msgctxt "cart"
msgid "Down payment"
@ -231,6 +239,7 @@ msgstr "Opcions del tipus dallotjament"
#: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140
#: web/templates/admin/booking/fields.gohtml:187
msgctxt "title"
msgid "Customer Details"
msgstr "Detalls del client"
@ -238,6 +247,7 @@ msgstr "Detalls del client"
#: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143
#: web/templates/admin/booking/fields.gohtml:190
msgctxt "input"
msgid "Full name"
msgstr "Nom i cognoms"
@ -266,7 +276,7 @@ msgid "City"
msgstr "Població"
#: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:185
#: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159
#: web/templates/admin/taxDetails.gohtml:101
msgctxt "input"
@ -274,7 +284,7 @@ msgid "Country"
msgstr "País"
#: web/templates/mail/payment/details.gotxt:46
#: web/templates/public/booking/fields.gohtml:196
#: web/templates/public/booking/fields.gohtml:201
#: web/templates/admin/payment/details.gohtml:163
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
#: web/templates/admin/taxDetails.gohtml:53
@ -283,7 +293,7 @@ msgid "Email"
msgstr "Correu-e"
#: web/templates/mail/payment/details.gotxt:47
#: web/templates/public/booking/fields.gohtml:205
#: web/templates/public/booking/fields.gohtml:210
#: web/templates/admin/payment/details.gohtml:167
#: web/templates/admin/taxDetails.gohtml:45
msgctxt "input"
@ -570,7 +580,7 @@ msgid "Year"
msgstr "Any"
#: web/templates/public/campsite/type.gohtml:49
#: web/templates/public/booking/fields.gohtml:273
#: web/templates/public/booking/fields.gohtml:278
msgctxt "action"
msgid "Book"
msgstr "Reserva"
@ -818,7 +828,7 @@ msgstr " Camp desports"
#: web/templates/public/campground.gohtml:39
msgctxt "title"
msgid "Accomodations"
msgid "Accommodations"
msgstr "Allotjaments"
#: web/templates/public/campground.gohtml:41
@ -920,6 +930,7 @@ msgstr "Menú"
#: web/templates/admin/campsite/type/option/index.gohtml:10
#: web/templates/admin/campsite/type/index.gohtml:10
#: web/templates/admin/layout.gohtml:46 web/templates/admin/layout.gohtml:95
#: web/templates/admin/booking/fields.gohtml:265
msgctxt "title"
msgid "Campsites"
msgstr "Allotjaments"
@ -972,19 +983,22 @@ msgid "Guests"
msgstr "Hostes"
#: web/templates/public/booking/fields.gohtml:92
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgid "Note: Due to guest capacity, we have added more accommodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgstr "Nota: Shan afegit més allotjaments a la reserva degut a la capacitat de cadascuna, però <strong>no</strong> es garanteix que estiguin de costat."
#: web/templates/public/booking/fields.gohtml:109
#: web/templates/admin/booking/fields.gohtml:178
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
msgstr "Nota: A aquest allotjament <strong>no</strong> shi permeten gossos."
#: web/templates/public/booking/fields.gohtml:121
#: web/templates/admin/booking/fields.gohtml:55
msgctxt "input"
msgid "Area preferences (optional)"
msgstr "Preferències dàrea (opcional)"
#: web/templates/public/booking/fields.gohtml:123
#: web/templates/admin/booking/fields.gohtml:59
msgid "Campground map"
msgstr "Mapa del càmping"
@ -993,29 +1007,31 @@ msgctxt "input"
msgid "Town or village"
msgstr "Població"
#: web/templates/public/booking/fields.gohtml:188
#: web/templates/public/booking/fields.gohtml:193
#: web/templates/admin/booking/fields.gohtml:203
msgid "Choose a country"
msgstr "Esculli un país"
#: web/templates/public/booking/fields.gohtml:242
#: web/templates/public/booking/fields.gohtml:247
#: web/templates/admin/booking/fields.gohtml:258
msgctxt "input"
msgid "ACSI card? (optional)"
msgstr "Targeta ACSI? (opcional)"
#: web/templates/public/booking/fields.gohtml:250
#: web/templates/public/booking/fields.gohtml:255
msgctxt "input"
msgid "I have read and I accept %[1]sthe reservation conditions%[2]s"
msgstr "He llegit i accepto %[1]sles condicions de reserves%[2]s"
#: web/templates/public/booking/fields.gohtml:258
#: web/templates/public/booking/fields.gohtml:263
msgid "By down paying the %d %% of the total, you are pre-booking your preferences. We will respond within 24 hours and this percentage will be charged if accepted."
msgstr "En tramitar el %d %% del total esteu realitzant la prereserva de les vostres preferències. Us respondrem en un termini de 24 hores i us cobrarem aquest percentatge en cas que sigui acceptada."
#: web/templates/public/booking/fields.gohtml:260
#: web/templates/public/booking/fields.gohtml:265
msgid "By paying the total you are pre-booking your preferences. We will respond within 24 hours and this amount will be charged if accepted."
msgstr "En tramitar el pagament del total esteu realitzant la prereserva de les vostres preferències. Us respondrem en un termini de 24 hores i us cobrarem aquesta quantitat en cas que sigui acceptada."
#: web/templates/public/booking/fields.gohtml:264
#: web/templates/public/booking/fields.gohtml:269
msgid "See <%s>our conditions</%s> for more information."
msgstr "Consulteu <%s>les nostres condicions</%s> per a més informació."
@ -1082,6 +1098,8 @@ msgid "Down payment"
msgstr "A compte"
#: web/templates/admin/payment/index.gohtml:24
#: web/templates/admin/booking/fields.gohtml:74
#: web/templates/admin/booking/fields.gohtml:172
msgctxt "header"
msgid "Total"
msgstr "Total"
@ -1176,6 +1194,7 @@ msgstr "Contingut"
#: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/fields.gohtml:272
msgctxt "action"
msgid "Update"
msgstr "Actualitza"
@ -1195,6 +1214,7 @@ msgstr "Actualitza"
#: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/fields.gohtml:274
msgctxt "action"
msgid "Add"
msgstr "Afegeix"
@ -1467,26 +1487,20 @@ msgctxt "action"
msgid "Add Campsite"
msgstr "Afegeix allotjament"
#: web/templates/admin/campsite/index.gohtml:32
#: web/templates/admin/amenity/index.gohtml:20
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:78
#: web/templates/admin/campsite/index.gohtml:25
msgid "From Date"
msgstr "De la data"
#: web/templates/admin/campsite/index.gohtml:85
#: web/templates/admin/campsite/index.gohtml:32
msgid "To Date"
msgstr "A la data"
#: web/templates/admin/campsite/index.gohtml:92
#: web/templates/admin/campsite/index.gohtml:39
msgctxt "action"
msgid "Show"
msgstr "Mostra"
#: web/templates/admin/campsite/index.gohtml:96
#: web/templates/admin/campsite/index.gohtml:43
msgid "No campsites added yet."
msgstr "No sha afegit cap allotjament encara."
@ -2146,6 +2160,12 @@ msgctxt "action"
msgid "Add Amenity"
msgstr "Afegeix instaŀlació"
#: web/templates/admin/amenity/index.gohtml:20
#: web/templates/admin/booking/grid.gohtml:13
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/amenity/index.gohtml:29
msgid "Are you sure you wish to delete this amenity?"
msgstr "Esteu segur de voler esborrar aquesta instaŀlació?"
@ -2184,6 +2204,7 @@ msgid "Logout"
msgstr "Surt"
#: web/templates/admin/layout.gohtml:92
#: web/templates/admin/booking/form.gohtml:15
#: web/templates/admin/booking/index.gohtml:6
#: web/templates/admin/booking/index.gohtml:16
msgctxt "title"
@ -2291,6 +2312,65 @@ msgctxt "title"
msgid "Upload Media"
msgstr "Pujada de mèdia"
#: web/templates/admin/booking/fields.gohtml:18
msgid "Choose an accommodation"
msgstr "Esculliu un allotjament"
#: web/templates/admin/booking/fields.gohtml:72
msgctxt "header"
msgid "Units"
msgstr "Unitats"
#: web/templates/admin/booking/fields.gohtml:73
msgctxt "header"
msgid "Decription"
msgstr "Descripció"
#: web/templates/admin/booking/fields.gohtml:80 pkg/booking/cart.go:234
msgctxt "cart"
msgid "Night"
msgstr "Nit"
#: web/templates/admin/booking/fields.gohtml:199
msgctxt "input"
msgid "Country (optional)"
msgstr "País (opcional)"
#: web/templates/admin/booking/fields.gohtml:211
msgctxt "input"
msgid "Address (optional)"
msgstr "Adreça (opcional)"
#: web/templates/admin/booking/fields.gohtml:220
msgctxt "input"
msgid "Postcode (optional)"
msgstr "Codi postal (opcional)"
#: web/templates/admin/booking/fields.gohtml:229
msgctxt "input"
msgid "Town or village (optional)"
msgstr "Població (opcional)"
#: web/templates/admin/booking/fields.gohtml:238
msgctxt "input"
msgid "Email (optional)"
msgstr "Correu-e (opcional)"
#: web/templates/admin/booking/fields.gohtml:247
msgctxt "input"
msgid "Phone (optional)"
msgstr "Telèfon (opcional)"
#: web/templates/admin/booking/form.gohtml:8
msgctxt "title"
msgid "Edit Booking"
msgstr "Edició de la reserva"
#: web/templates/admin/booking/form.gohtml:10
msgctxt "title"
msgid "New Booking"
msgstr "Nova reserva"
#: web/templates/admin/booking/index.gohtml:14
msgctxt "action"
msgid "Add Booking"
@ -2421,12 +2501,12 @@ msgid "Slide image must be an image media type."
msgstr "La imatge de la diapositiva ha de ser un mèdia de tipus imatge."
#: pkg/app/login.go:56 pkg/app/user.go:246 pkg/company/admin.go:224
#: pkg/booking/public.go:544
#: pkg/booking/public.go:545
msgid "Email can not be empty."
msgstr "No podeu deixar el correu-e en blanc."
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/company/admin.go:225
#: pkg/booking/public.go:545
#: pkg/booking/admin.go:316 pkg/booking/public.go:546
msgid "This email is not valid. It should be like name@domain.com."
msgstr "Aquest correu-e no és vàlid. Hauria de ser similar a nom@domini.com."
@ -2637,12 +2717,12 @@ msgctxt "header"
msgid "Children (aged 2 to 10)"
msgstr "Mainada (entre 2 i 10 anys)"
#: pkg/campsite/admin.go:419 pkg/booking/public.go:172
#: pkg/booking/public.go:227
#: pkg/campsite/admin.go:280 pkg/booking/admin.go:292 pkg/booking/public.go:173
#: pkg/booking/public.go:228
msgid "Selected campsite type is not valid."
msgstr "El tipus dallotjament escollit no és vàlid."
#: pkg/campsite/admin.go:420 pkg/amenity/admin.go:282
#: pkg/campsite/admin.go:281 pkg/amenity/admin.go:282
msgid "Label can not be empty."
msgstr "No podeu deixar letiqueta en blanc."
@ -2734,7 +2814,7 @@ msgstr "No podeu deixar ladreça de lenllaç en blanc."
msgid "This web address is not valid. It should be like https://domain.com/."
msgstr "Aquesta adreça web no és vàlida. Hauria de ser similar a https://domini.com/."
#: pkg/company/admin.go:207 pkg/booking/public.go:529
#: pkg/company/admin.go:207 pkg/booking/public.go:530
msgid "Selected country is not valid."
msgstr "El país escollit no és vàlid."
@ -2754,15 +2834,15 @@ msgstr "No podeu deixar el NIF en blanc."
msgid "This VAT number is not valid."
msgstr "Aquest NIF no és vàlid."
#: pkg/company/admin.go:219 pkg/booking/public.go:547
#: pkg/company/admin.go:219 pkg/booking/public.go:548
msgid "Phone can not be empty."
msgstr "No podeu deixar el telèfon en blanc."
#: pkg/company/admin.go:220 pkg/booking/public.go:548
#: pkg/company/admin.go:220 pkg/booking/admin.go:321 pkg/booking/public.go:549
msgid "This phone number is not valid."
msgstr "Aquest número de telèfon no és vàlid."
#: pkg/company/admin.go:230 pkg/booking/public.go:537
#: pkg/company/admin.go:230 pkg/booking/public.go:538
msgid "Address can not be empty."
msgstr "No podeu deixar ladreça en blanc."
@ -2774,11 +2854,11 @@ msgstr "No podeu deixar la població en blanc."
msgid "Province can not be empty."
msgstr "No podeu deixar la província en blanc."
#: pkg/company/admin.go:233 pkg/booking/public.go:539
#: pkg/company/admin.go:233 pkg/booking/public.go:540
msgid "Postcode can not be empty."
msgstr "No podeu deixar el codi postal en blanc."
#: pkg/company/admin.go:234 pkg/booking/public.go:540
#: pkg/company/admin.go:234 pkg/booking/admin.go:311 pkg/booking/public.go:541
msgid "This postcode is not valid."
msgstr "Aquest codi postal no és vàlid."
@ -2830,161 +2910,176 @@ msgstr "No podeu deixar el fitxer del mèdia en blanc."
msgid "Filename can not be empty."
msgstr "No podeu deixar el nom del fitxer en blanc."
#: pkg/booking/cart.go:159
msgctxt "cart"
msgid "Night"
msgstr "Nit"
#: pkg/booking/cart.go:160
#: pkg/booking/cart.go:235
msgctxt "cart"
msgid "Adult"
msgstr "Adult"
#: pkg/booking/cart.go:161
#: pkg/booking/cart.go:236
msgctxt "cart"
msgid "Teenager"
msgstr "Adolescent"
#: pkg/booking/cart.go:162
#: pkg/booking/cart.go:237
msgctxt "cart"
msgid "Child"
msgstr "Nen"
#: pkg/booking/cart.go:163
#: pkg/booking/cart.go:238
msgctxt "cart"
msgid "Dog"
msgstr "Gos"
#: pkg/booking/admin.go:126
#: pkg/booking/admin.go:144
msgctxt "filename"
msgid "bookings.ods"
msgstr "reserves.ods"
#: pkg/booking/public.go:276 pkg/booking/public.go:305
#: pkg/booking/admin.go:304 pkg/booking/public.go:534
msgid "Full name can not be empty."
msgstr "No podeu deixar el nom i els cognoms en blanc."
#: pkg/booking/admin.go:305 pkg/booking/public.go:535
msgid "Full name must have at least one letter."
msgstr "El nom i els cognoms han de tenir com a mínim una lletra."
#: pkg/booking/admin.go:310
msgid "Country can not be empty to validate the postcode."
msgstr "No podeu deixar el país en blanc per validar el codi postal."
#: pkg/booking/admin.go:320
msgid "Country can not be empty to validate the phone."
msgstr "No podeu deixar el país en blanc per validar el telèfon."
#: pkg/booking/admin.go:327
msgid "You must select at least one accommodation."
msgstr "Heu descollir com a mínim un allotjament."
#: pkg/booking/admin.go:333
msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Els allotjaments escollits no estan disponibles a les dates demanades."
#: pkg/booking/public.go:277 pkg/booking/public.go:306
msgid "Arrival date must be a valid date."
msgstr "La data darribada ha de ser una data vàlida."
#: pkg/booking/public.go:290 pkg/booking/public.go:312
#: pkg/booking/public.go:291 pkg/booking/public.go:313
msgid "Departure date must be a valid date."
msgstr "La data de sortida ha de ser una data vàlida."
#: pkg/booking/public.go:304
#: pkg/booking/public.go:305
msgid "Arrival date can not be empty"
msgstr "No podeu deixar la data darribada en blanc."
#: pkg/booking/public.go:306
#: pkg/booking/public.go:307
#, c-format
msgid "Arrival date must be %s or after."
msgstr "La data darribada ha de ser igual o posterior a %s."
#: pkg/booking/public.go:307
#: pkg/booking/public.go:308
#, c-format
msgid "Arrival date must be %s or before."
msgstr "La data darribada ha de ser anterior o igual a %s."
#: pkg/booking/public.go:311
#: pkg/booking/public.go:312
msgid "Departure date can not be empty"
msgstr "No podeu deixar la data de sortida en blanc."
#: pkg/booking/public.go:313
#: pkg/booking/public.go:314
#, c-format
msgid "Departure date must be %s or after."
msgstr "La data de sortida ha de ser igual o posterior a %s."
#: pkg/booking/public.go:314
#: pkg/booking/public.go:315
#, c-format
msgid "Departure date must be %s or before."
msgstr "La data de sortida ha de ser anterior o igual a %s."
#: pkg/booking/public.go:368
#: pkg/booking/public.go:369
#, c-format
msgid "There can be at most %d guests in this accommodation."
msgstr "Hi poden haver com a màxim %d convidats a aquest allotjament."
#: pkg/booking/public.go:388
#: pkg/booking/public.go:389
msgid "Number of adults can not be empty"
msgstr "No podeu deixar el número dadults en blanc."
#: pkg/booking/public.go:389
#: pkg/booking/public.go:390
msgid "Number of adults must be an integer."
msgstr "El número dadults ha de ser enter."
#: pkg/booking/public.go:390
#: pkg/booking/public.go:391
msgid "There must be at least one adult."
msgstr "Hi ha dhaver com a mínim un adult."
#: pkg/booking/public.go:393
#: pkg/booking/public.go:394
msgid "Number of teenagers can not be empty"
msgstr "No podeu deixar el número dadolescents en blanc."
#: pkg/booking/public.go:394
#: pkg/booking/public.go:395
msgid "Number of teenagers must be an integer."
msgstr "El número dadolescents ha de ser enter."
#: pkg/booking/public.go:395
#: pkg/booking/public.go:396
msgid "Number of teenagers can not be negative."
msgstr "El número dadolescents no pot ser negatiu."
#: pkg/booking/public.go:398
#: pkg/booking/public.go:399
msgid "Number of children can not be empty"
msgstr "No podeu deixar el número de nens en blanc."
#: pkg/booking/public.go:399
#: pkg/booking/public.go:400
msgid "Number of children must be an integer."
msgstr "El número de nens ha de ser enter."
#: pkg/booking/public.go:400
#: pkg/booking/public.go:401
msgid "Number of children can not be negative."
msgstr "El número de nens no pot ser negatiu."
#: pkg/booking/public.go:403
#: pkg/booking/public.go:404
msgid "Number of dogs can not be empty"
msgstr "No podeu deixar el número de gossos en blanc."
#: pkg/booking/public.go:404
#: pkg/booking/public.go:405
msgid "Number of dogs must be an integer."
msgstr "El número de gossos ha de ser enter."
#: pkg/booking/public.go:405
#: pkg/booking/public.go:406
msgid "Number of dogs can not be negative."
msgstr "El número de gossos no pot ser negatiu."
#: pkg/booking/public.go:476
#: pkg/booking/public.go:477
#, c-format
msgid "%s can not be empty"
msgstr "No podeu deixar %s en blanc."
#: pkg/booking/public.go:477
#: pkg/booking/public.go:478
#, c-format
msgid "%s must be an integer."
msgstr "%s ha de ser un número enter."
#: pkg/booking/public.go:478
#: pkg/booking/public.go:479
#, c-format
msgid "%s must be %d or greater."
msgstr "El valor de %s ha de ser com a mínim %d."
#: pkg/booking/public.go:479
#: pkg/booking/public.go:480
#, c-format
msgid "%s must be at most %d."
msgstr "El valor de %s ha de ser com a màxim %d."
#: pkg/booking/public.go:533
msgid "Full name can not be empty."
msgstr "No podeu deixar el nom i els cognoms en blanc."
#: pkg/booking/public.go:534
msgid "Full name must have at least one letter."
msgstr "El nom i els cognoms han de tenir com a mínim una lletra."
#: pkg/booking/public.go:538
#: pkg/booking/public.go:539
msgid "Town or village can not be empty."
msgstr "No podeu deixar la població en blanc."
#: pkg/booking/public.go:553
#: pkg/booking/public.go:554
msgid "It is mandatory to agree to the reservation conditions."
msgstr "És obligatori acceptar les condicions de reserves."
#~ msgctxt "title"
#~ msgid "Accomodations"
#~ msgstr "Allotjaments"
#~ msgctxt "header"
#~ msgid "Type"
#~ msgstr "Tipus"
@ -2995,14 +3090,6 @@ msgstr "És obligatori acceptar les condicions de reserves."
#~ msgid "This postal code is not valid."
#~ msgstr "Aquest codi postal no és vàlid."
#~ msgctxt "input"
#~ msgid "Address (optional)"
#~ msgstr "Adreça (opcional)"
#~ msgctxt "input"
#~ msgid "Postcode (optional)"
#~ msgstr "Codi postal (opcional)"
#~ msgctxt "action"
#~ msgid "Pay"
#~ msgstr "Paga"

269
po/es.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-04-19 20:53+0200\n"
"POT-Creation-Date: 2024-04-24 19:59+0200\n"
"PO-Revision-Date: 2024-02-06 10:04+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
@ -116,6 +116,7 @@ msgstr "Reserva"
#: web/templates/mail/payment/details.gotxt:16
#: web/templates/public/booking/fields.gohtml:14
#: web/templates/admin/payment/details.gohtml:74
#: web/templates/admin/booking/fields.gohtml:12
msgctxt "title"
msgid "Accommodation"
msgstr "Alojamientos"
@ -154,6 +155,7 @@ msgstr "No"
#: web/templates/public/campsite/dates.gohtml:4
#: web/templates/public/booking/fields.gohtml:30
#: web/templates/admin/payment/details.gohtml:86
#: web/templates/admin/booking/fields.gohtml:31
msgctxt "input"
msgid "Arrival date"
msgstr "Fecha de llegada"
@ -162,6 +164,7 @@ msgstr "Fecha de llegada"
#: web/templates/public/campsite/dates.gohtml:15
#: web/templates/public/booking/fields.gohtml:41
#: web/templates/admin/payment/details.gohtml:90
#: web/templates/admin/booking/fields.gohtml:42
msgctxt "input"
msgid "Departure date"
msgstr "Fecha de salida"
@ -175,6 +178,7 @@ msgstr "Noches"
#: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98
#: web/templates/admin/booking/fields.gohtml:92
msgctxt "input"
msgid "Adults aged 17 or older"
msgstr "Adultos de 17 años o más"
@ -182,6 +186,7 @@ msgstr "Adultos de 17 años o más"
#: web/templates/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102
#: web/templates/admin/booking/fields.gohtml:108
msgctxt "input"
msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescentes de 11 a 16 años"
@ -189,6 +194,7 @@ msgstr "Adolescentes de 11 a 16 años"
#: web/templates/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106
#: web/templates/admin/booking/fields.gohtml:124
msgctxt "input"
msgid "Children from 2 to 10 years old"
msgstr "Niños de 2 a 10 años"
@ -196,24 +202,26 @@ msgstr "Niños de 2 a 10 años"
#: web/templates/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110
#: web/templates/admin/booking/fields.gohtml:139
msgctxt "input"
msgid "Dogs"
msgstr "Perros"
#: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 pkg/booking/cart.go:197
#: web/templates/admin/payment/details.gohtml:114
#: web/templates/admin/booking/fields.gohtml:166 pkg/booking/cart.go:244
msgctxt "cart"
msgid "Tourist tax"
msgstr "Impuesto turístico"
#: web/templates/mail/payment/details.gotxt:27
#: web/templates/public/booking/fields.gohtml:225
#: web/templates/public/booking/fields.gohtml:230
msgctxt "cart"
msgid "Total"
msgstr "Total"
#: web/templates/mail/payment/details.gotxt:28
#: web/templates/public/booking/fields.gohtml:230
#: web/templates/public/booking/fields.gohtml:235
#: web/templates/admin/payment/details.gohtml:118
msgctxt "cart"
msgid "Down payment"
@ -231,6 +239,7 @@ msgstr "Opciones del tipo de alojamiento"
#: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140
#: web/templates/admin/booking/fields.gohtml:187
msgctxt "title"
msgid "Customer Details"
msgstr "Detalles del cliente"
@ -238,6 +247,7 @@ msgstr "Detalles del cliente"
#: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143
#: web/templates/admin/booking/fields.gohtml:190
msgctxt "input"
msgid "Full name"
msgstr "Nombre y apellidos"
@ -266,7 +276,7 @@ msgid "City"
msgstr "Población"
#: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:185
#: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159
#: web/templates/admin/taxDetails.gohtml:101
msgctxt "input"
@ -274,7 +284,7 @@ msgid "Country"
msgstr "País"
#: web/templates/mail/payment/details.gotxt:46
#: web/templates/public/booking/fields.gohtml:196
#: web/templates/public/booking/fields.gohtml:201
#: web/templates/admin/payment/details.gohtml:163
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
#: web/templates/admin/taxDetails.gohtml:53
@ -283,7 +293,7 @@ msgid "Email"
msgstr "Correo-e"
#: web/templates/mail/payment/details.gotxt:47
#: web/templates/public/booking/fields.gohtml:205
#: web/templates/public/booking/fields.gohtml:210
#: web/templates/admin/payment/details.gohtml:167
#: web/templates/admin/taxDetails.gohtml:45
msgctxt "input"
@ -570,7 +580,7 @@ msgid "Year"
msgstr "Año"
#: web/templates/public/campsite/type.gohtml:49
#: web/templates/public/booking/fields.gohtml:273
#: web/templates/public/booking/fields.gohtml:278
msgctxt "action"
msgid "Book"
msgstr "Reservar"
@ -818,7 +828,7 @@ msgstr "Campo de deportes"
#: web/templates/public/campground.gohtml:39
msgctxt "title"
msgid "Accomodations"
msgid "Accommodations"
msgstr "Alojamientos"
#: web/templates/public/campground.gohtml:41
@ -920,6 +930,7 @@ msgstr "Menú"
#: web/templates/admin/campsite/type/option/index.gohtml:10
#: web/templates/admin/campsite/type/index.gohtml:10
#: web/templates/admin/layout.gohtml:46 web/templates/admin/layout.gohtml:95
#: web/templates/admin/booking/fields.gohtml:265
msgctxt "title"
msgid "Campsites"
msgstr "Alojamientos"
@ -972,19 +983,22 @@ msgid "Guests"
msgstr "Huéspedes"
#: web/templates/public/booking/fields.gohtml:92
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgid "Note: Due to guest capacity, we have added more accommodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgstr "Nota: Se han añadido alojamientos a la reserva debido a la capacidad de cada una, pero <strong>no</strong> se garantiza que estén de lado."
#: web/templates/public/booking/fields.gohtml:109
#: web/templates/admin/booking/fields.gohtml:178
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
msgstr "Nota: En este alojamiento <strong>no</strong> se permiten perros."
#: web/templates/public/booking/fields.gohtml:121
#: web/templates/admin/booking/fields.gohtml:55
msgctxt "input"
msgid "Area preferences (optional)"
msgstr "Preferencias de área (opcional)"
#: web/templates/public/booking/fields.gohtml:123
#: web/templates/admin/booking/fields.gohtml:59
msgid "Campground map"
msgstr "Mapa del camping"
@ -993,29 +1007,31 @@ msgctxt "input"
msgid "Town or village"
msgstr "Población"
#: web/templates/public/booking/fields.gohtml:188
#: web/templates/public/booking/fields.gohtml:193
#: web/templates/admin/booking/fields.gohtml:203
msgid "Choose a country"
msgstr "Escoja un país"
#: web/templates/public/booking/fields.gohtml:242
#: web/templates/public/booking/fields.gohtml:247
#: web/templates/admin/booking/fields.gohtml:258
msgctxt "input"
msgid "ACSI card? (optional)"
msgstr "¿Tarjeta ACSI? (opcional)"
#: web/templates/public/booking/fields.gohtml:250
#: web/templates/public/booking/fields.gohtml:255
msgctxt "input"
msgid "I have read and I accept %[1]sthe reservation conditions%[2]s"
msgstr "He leído y acepto %[1]slas condiciones de reserva%[2]s"
#: web/templates/public/booking/fields.gohtml:258
#: web/templates/public/booking/fields.gohtml:263
msgid "By down paying the %d %% of the total, you are pre-booking your preferences. We will respond within 24 hours and this percentage will be charged if accepted."
msgstr "En tramitar el %d %% del total estáis realizando la prerreserva de vuestras preferencias. Os responderemos en un término de 24 horas y os cobraremos este porcentaje en caso que sea aceptada."
#: web/templates/public/booking/fields.gohtml:260
#: web/templates/public/booking/fields.gohtml:265
msgid "By paying the total you are pre-booking your preferences. We will respond within 24 hours and this amount will be charged if accepted."
msgstr "En tramitar el pago del total estáis realizando la prerreserva de vuestras preferencias. Os responderemos en un término de 24 horas y os cobraremos esta cantidad en caso que sea aceptada."
#: web/templates/public/booking/fields.gohtml:264
#: web/templates/public/booking/fields.gohtml:269
msgid "See <%s>our conditions</%s> for more information."
msgstr "Consultad <%s>nuestras condiciones</%s> para más información."
@ -1082,6 +1098,8 @@ msgid "Down payment"
msgstr "A cuenta"
#: web/templates/admin/payment/index.gohtml:24
#: web/templates/admin/booking/fields.gohtml:74
#: web/templates/admin/booking/fields.gohtml:172
msgctxt "header"
msgid "Total"
msgstr "Total"
@ -1176,6 +1194,7 @@ msgstr "Contenido"
#: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/fields.gohtml:272
msgctxt "action"
msgid "Update"
msgstr "Actualizar"
@ -1195,6 +1214,7 @@ msgstr "Actualizar"
#: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/fields.gohtml:274
msgctxt "action"
msgid "Add"
msgstr "Añadir"
@ -1467,26 +1487,20 @@ msgctxt "action"
msgid "Add Campsite"
msgstr "Añadir alojamiento"
#: web/templates/admin/campsite/index.gohtml:32
#: web/templates/admin/amenity/index.gohtml:20
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:78
#: web/templates/admin/campsite/index.gohtml:25
msgid "From Date"
msgstr "De la fecha"
#: web/templates/admin/campsite/index.gohtml:85
#: web/templates/admin/campsite/index.gohtml:32
msgid "To Date"
msgstr "A la fecha"
#: web/templates/admin/campsite/index.gohtml:92
#: web/templates/admin/campsite/index.gohtml:39
msgctxt "action"
msgid "Show"
msgstr "Mostrar"
#: web/templates/admin/campsite/index.gohtml:96
#: web/templates/admin/campsite/index.gohtml:43
msgid "No campsites added yet."
msgstr "No se ha añadido ningún alojamiento todavía."
@ -2146,6 +2160,12 @@ msgctxt "action"
msgid "Add Amenity"
msgstr "Añadir instalación"
#: web/templates/admin/amenity/index.gohtml:20
#: web/templates/admin/booking/grid.gohtml:13
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/amenity/index.gohtml:29
msgid "Are you sure you wish to delete this amenity?"
msgstr "¿Estáis seguro de querer borrar esta instalación?"
@ -2184,6 +2204,7 @@ msgid "Logout"
msgstr "Salir"
#: web/templates/admin/layout.gohtml:92
#: web/templates/admin/booking/form.gohtml:15
#: web/templates/admin/booking/index.gohtml:6
#: web/templates/admin/booking/index.gohtml:16
msgctxt "title"
@ -2291,6 +2312,65 @@ msgctxt "title"
msgid "Upload Media"
msgstr "Subida de medio"
#: web/templates/admin/booking/fields.gohtml:18
msgid "Choose an accommodation"
msgstr "Escoja un alojamiento"
#: web/templates/admin/booking/fields.gohtml:72
msgctxt "header"
msgid "Units"
msgstr "Unidades"
#: web/templates/admin/booking/fields.gohtml:73
msgctxt "header"
msgid "Decription"
msgstr "Descripción"
#: web/templates/admin/booking/fields.gohtml:80 pkg/booking/cart.go:234
msgctxt "cart"
msgid "Night"
msgstr "Noche"
#: web/templates/admin/booking/fields.gohtml:199
msgctxt "input"
msgid "Country (optional)"
msgstr "País (opcional)"
#: web/templates/admin/booking/fields.gohtml:211
msgctxt "input"
msgid "Address (optional)"
msgstr "Dirección (opcional)"
#: web/templates/admin/booking/fields.gohtml:220
msgctxt "input"
msgid "Postcode (optional)"
msgstr "Código postal (opcional)"
#: web/templates/admin/booking/fields.gohtml:229
msgctxt "input"
msgid "Town or village (optional)"
msgstr "Población (opcional)"
#: web/templates/admin/booking/fields.gohtml:238
msgctxt "input"
msgid "Email (optional)"
msgstr "Correo-e (opcional)"
#: web/templates/admin/booking/fields.gohtml:247
msgctxt "input"
msgid "Phone (optional)"
msgstr "Teléfono (opcional)"
#: web/templates/admin/booking/form.gohtml:8
msgctxt "title"
msgid "Edit Booking"
msgstr "Edición de la reserva"
#: web/templates/admin/booking/form.gohtml:10
msgctxt "title"
msgid "New Booking"
msgstr "Nueva reserva"
#: web/templates/admin/booking/index.gohtml:14
msgctxt "action"
msgid "Add Booking"
@ -2299,7 +2379,7 @@ msgstr "Añadir reserva"
#: web/templates/admin/booking/index.gohtml:15
msgctxt "action"
msgid "Export Bookings"
msgstr "Exportar eservas"
msgstr "Exportar reservas"
#: web/templates/admin/booking/index.gohtml:22
msgctxt "header"
@ -2421,12 +2501,12 @@ msgid "Slide image must be an image media type."
msgstr "La imagen de la diapositiva tiene que ser un medio de tipo imagen."
#: pkg/app/login.go:56 pkg/app/user.go:246 pkg/company/admin.go:224
#: pkg/booking/public.go:544
#: pkg/booking/public.go:545
msgid "Email can not be empty."
msgstr "No podéis dejar el correo-e en blanco."
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/company/admin.go:225
#: pkg/booking/public.go:545
#: pkg/booking/admin.go:316 pkg/booking/public.go:546
msgid "This email is not valid. It should be like name@domain.com."
msgstr "Este correo-e no es válido. Tiene que ser parecido a nombre@dominio.com."
@ -2637,12 +2717,12 @@ msgctxt "header"
msgid "Children (aged 2 to 10)"
msgstr "Niños (de 2 a 10 años)"
#: pkg/campsite/admin.go:419 pkg/booking/public.go:172
#: pkg/booking/public.go:227
#: pkg/campsite/admin.go:280 pkg/booking/admin.go:292 pkg/booking/public.go:173
#: pkg/booking/public.go:228
msgid "Selected campsite type is not valid."
msgstr "El tipo de alojamiento escogido no es válido."
#: pkg/campsite/admin.go:420 pkg/amenity/admin.go:282
#: pkg/campsite/admin.go:281 pkg/amenity/admin.go:282
msgid "Label can not be empty."
msgstr "No podéis dejar la etiqueta en blanco."
@ -2734,7 +2814,7 @@ msgstr "No podéis dejar la dirección del enlace en blanco."
msgid "This web address is not valid. It should be like https://domain.com/."
msgstr "Esta dirección web no es válida. Tiene que ser parecido a https://dominio.com/."
#: pkg/company/admin.go:207 pkg/booking/public.go:529
#: pkg/company/admin.go:207 pkg/booking/public.go:530
msgid "Selected country is not valid."
msgstr "El país escogido no es válido."
@ -2754,15 +2834,15 @@ msgstr "No podéis dejar el NIF en blanco."
msgid "This VAT number is not valid."
msgstr "Este NIF no es válido."
#: pkg/company/admin.go:219 pkg/booking/public.go:547
#: pkg/company/admin.go:219 pkg/booking/public.go:548
msgid "Phone can not be empty."
msgstr "No podéis dejar el teléfono en blanco."
#: pkg/company/admin.go:220 pkg/booking/public.go:548
#: pkg/company/admin.go:220 pkg/booking/admin.go:321 pkg/booking/public.go:549
msgid "This phone number is not valid."
msgstr "Este teléfono no es válido."
#: pkg/company/admin.go:230 pkg/booking/public.go:537
#: pkg/company/admin.go:230 pkg/booking/public.go:538
msgid "Address can not be empty."
msgstr "No podéis dejar la dirección en blanco."
@ -2774,11 +2854,11 @@ msgstr "No podéis dejar la población en blanco."
msgid "Province can not be empty."
msgstr "No podéis dejar la provincia en blanco."
#: pkg/company/admin.go:233 pkg/booking/public.go:539
#: pkg/company/admin.go:233 pkg/booking/public.go:540
msgid "Postcode can not be empty."
msgstr "No podéis dejar el código postal en blanco."
#: pkg/company/admin.go:234 pkg/booking/public.go:540
#: pkg/company/admin.go:234 pkg/booking/admin.go:311 pkg/booking/public.go:541
msgid "This postcode is not valid."
msgstr "Este código postal no es válido."
@ -2830,161 +2910,176 @@ msgstr "No podéis dejar el archivo del medio en blanco."
msgid "Filename can not be empty."
msgstr "No podéis dejar el nombre del archivo en blanco."
#: pkg/booking/cart.go:159
msgctxt "cart"
msgid "Night"
msgstr "Noche"
#: pkg/booking/cart.go:160
#: pkg/booking/cart.go:235
msgctxt "cart"
msgid "Adult"
msgstr "Adulto"
#: pkg/booking/cart.go:161
#: pkg/booking/cart.go:236
msgctxt "cart"
msgid "Teenager"
msgstr "Adolescente"
#: pkg/booking/cart.go:162
#: pkg/booking/cart.go:237
msgctxt "cart"
msgid "Child"
msgstr "Niño"
#: pkg/booking/cart.go:163
#: pkg/booking/cart.go:238
msgctxt "cart"
msgid "Dog"
msgstr "Perro"
#: pkg/booking/admin.go:126
#: pkg/booking/admin.go:144
msgctxt "filename"
msgid "bookings.ods"
msgstr "reservas.ods"
#: pkg/booking/public.go:276 pkg/booking/public.go:305
#: pkg/booking/admin.go:304 pkg/booking/public.go:534
msgid "Full name can not be empty."
msgstr "No podéis dejar el nombre y los apellidos en blanco."
#: pkg/booking/admin.go:305 pkg/booking/public.go:535
msgid "Full name must have at least one letter."
msgstr "El nombre y los apellidos tienen que tener como mínimo una letra."
#: pkg/booking/admin.go:310
msgid "Country can not be empty to validate the postcode."
msgstr "No podéis dejar el país en blanco para validar el código postal."
#: pkg/booking/admin.go:320
msgid "Country can not be empty to validate the phone."
msgstr "No podéis dejar el país en blanco para validar el teléfono."
#: pkg/booking/admin.go:327
msgid "You must select at least one accommodation."
msgstr "Tenéis que seleccionar como mínimo un alojamiento."
#: pkg/booking/admin.go:333
msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Los alojamientos seleccionados no tienen disponibilidad en las fechas pedidas."
#: pkg/booking/public.go:277 pkg/booking/public.go:306
msgid "Arrival date must be a valid date."
msgstr "La fecha de llegada tiene que ser una fecha válida."
#: pkg/booking/public.go:290 pkg/booking/public.go:312
#: pkg/booking/public.go:291 pkg/booking/public.go:313
msgid "Departure date must be a valid date."
msgstr "La fecha de partida tiene que ser una fecha válida."
#: pkg/booking/public.go:304
#: pkg/booking/public.go:305
msgid "Arrival date can not be empty"
msgstr "No podéis dejar la fecha de llegada en blanco."
#: pkg/booking/public.go:306
#: pkg/booking/public.go:307
#, c-format
msgid "Arrival date must be %s or after."
msgstr "La fecha de llegada tiene que ser igual o posterior a %s."
#: pkg/booking/public.go:307
#: pkg/booking/public.go:308
#, c-format
msgid "Arrival date must be %s or before."
msgstr "La fecha de llegada tiene que ser anterior o igual a %s."
#: pkg/booking/public.go:311
#: pkg/booking/public.go:312
msgid "Departure date can not be empty"
msgstr "No podéis dejar la fecha de partida en blanco."
#: pkg/booking/public.go:313
#: pkg/booking/public.go:314
#, c-format
msgid "Departure date must be %s or after."
msgstr "La fecha de partida tiene que igual o posterior a %s."
#: pkg/booking/public.go:314
#: pkg/booking/public.go:315
#, c-format
msgid "Departure date must be %s or before."
msgstr "La fecha de partida tiene que ser anterior o igual a %s."
#: pkg/booking/public.go:368
#: pkg/booking/public.go:369
#, c-format
msgid "There can be at most %d guests in this accommodation."
msgstr "Solo puede haber como máximo %d invitados en este alojamiento."
#: pkg/booking/public.go:388
#: pkg/booking/public.go:389
msgid "Number of adults can not be empty"
msgstr "No podéis dejar el número de adultos blanco."
#: pkg/booking/public.go:389
#: pkg/booking/public.go:390
msgid "Number of adults must be an integer."
msgstr "El número de adultos tiene que ser entero."
#: pkg/booking/public.go:390
#: pkg/booking/public.go:391
msgid "There must be at least one adult."
msgstr "Tiene que haber como mínimo un adulto."
#: pkg/booking/public.go:393
#: pkg/booking/public.go:394
msgid "Number of teenagers can not be empty"
msgstr "No podéis dejar el número de adolescentes en blanco."
#: pkg/booking/public.go:394
#: pkg/booking/public.go:395
msgid "Number of teenagers must be an integer."
msgstr "El número de adolescentes tiene que ser entero."
#: pkg/booking/public.go:395
#: pkg/booking/public.go:396
msgid "Number of teenagers can not be negative."
msgstr "El número de adolescentes no puede ser negativo."
#: pkg/booking/public.go:398
#: pkg/booking/public.go:399
msgid "Number of children can not be empty"
msgstr "No podéis dejar el número de niños en blanco."
#: pkg/booking/public.go:399
#: pkg/booking/public.go:400
msgid "Number of children must be an integer."
msgstr "El número de niños tiene que ser entero."
#: pkg/booking/public.go:400
#: pkg/booking/public.go:401
msgid "Number of children can not be negative."
msgstr "El número de niños no puede ser negativo."
#: pkg/booking/public.go:403
#: pkg/booking/public.go:404
msgid "Number of dogs can not be empty"
msgstr "No podéis dejar el número de perros en blanco."
#: pkg/booking/public.go:404
#: pkg/booking/public.go:405
msgid "Number of dogs must be an integer."
msgstr "El número de perros tiene que ser entero."
#: pkg/booking/public.go:405
#: pkg/booking/public.go:406
msgid "Number of dogs can not be negative."
msgstr "El número de perros no puede ser negativo."
#: pkg/booking/public.go:476
#: pkg/booking/public.go:477
#, c-format
msgid "%s can not be empty"
msgstr "No podéis dejar %s en blanco."
#: pkg/booking/public.go:477
#: pkg/booking/public.go:478
#, c-format
msgid "%s must be an integer."
msgstr "%s tiene que ser un número entero."
#: pkg/booking/public.go:478
#: pkg/booking/public.go:479
#, c-format
msgid "%s must be %d or greater."
msgstr "%s tiene que ser como mínimo %d."
#: pkg/booking/public.go:479
#: pkg/booking/public.go:480
#, c-format
msgid "%s must be at most %d."
msgstr "%s tiene que ser como máximo %d"
#: pkg/booking/public.go:533
msgid "Full name can not be empty."
msgstr "No podéis dejar el nombre y los apellidos en blanco."
#: pkg/booking/public.go:534
msgid "Full name must have at least one letter."
msgstr "El nombre y los apellidos tienen que tener como mínimo una letra."
#: pkg/booking/public.go:538
#: pkg/booking/public.go:539
msgid "Town or village can not be empty."
msgstr "No podéis dejar la población en blanco."
#: pkg/booking/public.go:553
#: pkg/booking/public.go:554
msgid "It is mandatory to agree to the reservation conditions."
msgstr "Es obligatorio aceptar las condiciones de reserva."
#~ msgctxt "title"
#~ msgid "Accomodations"
#~ msgstr "Alojamientos"
#~ msgctxt "header"
#~ msgid "Type"
#~ msgstr "Tipo"
@ -2995,14 +3090,6 @@ msgstr "Es obligatorio aceptar las condiciones de reserva."
#~ msgid "This postal code is not valid."
#~ msgstr "Este código postal no es válido."
#~ msgctxt "input"
#~ msgid "Address (optional)"
#~ msgstr "Dirección (opcional)"
#~ msgctxt "input"
#~ msgid "Postcode (optional)"
#~ msgstr "Código postal (opcional)"
#~ msgctxt "action"
#~ msgid "Pay"
#~ msgstr "Pagar"

271
po/fr.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-04-19 20:53+0200\n"
"POT-Creation-Date: 2024-04-24 19:59+0200\n"
"PO-Revision-Date: 2024-02-06 10:05+0100\n"
"Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n"
"Language-Team: French <traduc@traduc.org>\n"
@ -116,6 +116,7 @@ msgstr "Réservation"
#: web/templates/mail/payment/details.gotxt:16
#: web/templates/public/booking/fields.gohtml:14
#: web/templates/admin/payment/details.gohtml:74
#: web/templates/admin/booking/fields.gohtml:12
msgctxt "title"
msgid "Accommodation"
msgstr "Hébergement"
@ -154,6 +155,7 @@ msgstr "Non"
#: web/templates/public/campsite/dates.gohtml:4
#: web/templates/public/booking/fields.gohtml:30
#: web/templates/admin/payment/details.gohtml:86
#: web/templates/admin/booking/fields.gohtml:31
msgctxt "input"
msgid "Arrival date"
msgstr "Date darrivée"
@ -162,6 +164,7 @@ msgstr "Date darrivée"
#: web/templates/public/campsite/dates.gohtml:15
#: web/templates/public/booking/fields.gohtml:41
#: web/templates/admin/payment/details.gohtml:90
#: web/templates/admin/booking/fields.gohtml:42
msgctxt "input"
msgid "Departure date"
msgstr "Date de depart"
@ -175,6 +178,7 @@ msgstr "Nuits"
#: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98
#: web/templates/admin/booking/fields.gohtml:92
msgctxt "input"
msgid "Adults aged 17 or older"
msgstr "Adultes âgés 17 ans ou plus"
@ -182,6 +186,7 @@ msgstr "Adultes âgés 17 ans ou plus"
#: web/templates/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102
#: web/templates/admin/booking/fields.gohtml:108
msgctxt "input"
msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescents de 11 à 16 ans"
@ -189,6 +194,7 @@ msgstr "Adolescents de 11 à 16 ans"
#: web/templates/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106
#: web/templates/admin/booking/fields.gohtml:124
msgctxt "input"
msgid "Children from 2 to 10 years old"
msgstr "Enfants de 2 à 10 ans"
@ -196,24 +202,26 @@ msgstr "Enfants de 2 à 10 ans"
#: web/templates/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110
#: web/templates/admin/booking/fields.gohtml:139
msgctxt "input"
msgid "Dogs"
msgstr "Chiens"
#: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 pkg/booking/cart.go:197
#: web/templates/admin/payment/details.gohtml:114
#: web/templates/admin/booking/fields.gohtml:166 pkg/booking/cart.go:244
msgctxt "cart"
msgid "Tourist tax"
msgstr "Taxe touristique"
#: web/templates/mail/payment/details.gotxt:27
#: web/templates/public/booking/fields.gohtml:225
#: web/templates/public/booking/fields.gohtml:230
msgctxt "cart"
msgid "Total"
msgstr "Totale"
#: web/templates/mail/payment/details.gotxt:28
#: web/templates/public/booking/fields.gohtml:230
#: web/templates/public/booking/fields.gohtml:235
#: web/templates/admin/payment/details.gohtml:118
msgctxt "cart"
msgid "Down payment"
@ -231,6 +239,7 @@ msgstr "Options de type demplacement de camping"
#: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140
#: web/templates/admin/booking/fields.gohtml:187
msgctxt "title"
msgid "Customer Details"
msgstr "Détails du client"
@ -238,6 +247,7 @@ msgstr "Détails du client"
#: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143
#: web/templates/admin/booking/fields.gohtml:190
msgctxt "input"
msgid "Full name"
msgstr "Nom et prénom"
@ -266,7 +276,7 @@ msgid "City"
msgstr "Ville"
#: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:185
#: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159
#: web/templates/admin/taxDetails.gohtml:101
msgctxt "input"
@ -274,7 +284,7 @@ msgid "Country"
msgstr "Pays"
#: web/templates/mail/payment/details.gotxt:46
#: web/templates/public/booking/fields.gohtml:196
#: web/templates/public/booking/fields.gohtml:201
#: web/templates/admin/payment/details.gohtml:163
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
#: web/templates/admin/taxDetails.gohtml:53
@ -283,7 +293,7 @@ msgid "Email"
msgstr "E-mail"
#: web/templates/mail/payment/details.gotxt:47
#: web/templates/public/booking/fields.gohtml:205
#: web/templates/public/booking/fields.gohtml:210
#: web/templates/admin/payment/details.gohtml:167
#: web/templates/admin/taxDetails.gohtml:45
msgctxt "input"
@ -570,7 +580,7 @@ msgid "Year"
msgstr "Année"
#: web/templates/public/campsite/type.gohtml:49
#: web/templates/public/booking/fields.gohtml:273
#: web/templates/public/booking/fields.gohtml:278
msgctxt "action"
msgid "Book"
msgstr "Réserver"
@ -818,8 +828,8 @@ msgstr "Terrain de sport"
#: web/templates/public/campground.gohtml:39
msgctxt "title"
msgid "Accomodations"
msgstr "Hébergement"
msgid "Accommodations"
msgstr "Hébergements"
#: web/templates/public/campground.gohtml:41
msgctxt "legend"
@ -920,6 +930,7 @@ msgstr "Menu"
#: web/templates/admin/campsite/type/option/index.gohtml:10
#: web/templates/admin/campsite/type/index.gohtml:10
#: web/templates/admin/layout.gohtml:46 web/templates/admin/layout.gohtml:95
#: web/templates/admin/booking/fields.gohtml:265
msgctxt "title"
msgid "Campsites"
msgstr "Locatifs"
@ -972,19 +983,22 @@ msgid "Guests"
msgstr "Personnes logeant"
#: web/templates/public/booking/fields.gohtml:92
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgid "Note: Due to guest capacity, we have added more accommodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
msgstr "Remarque : En raison de la capacité daccueils, nous avons ajouté dautres hébergements à la réservation, mais nous <strong>ne pouvons</strong> garantir quils seront côte à côte."
#: web/templates/public/booking/fields.gohtml:109
#: web/templates/admin/booking/fields.gohtml:178
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
msgstr "Remarque : Dans cet hébergement les chiens <strong>ne</strong> sont pas acceptés."
#: web/templates/public/booking/fields.gohtml:121
#: web/templates/admin/booking/fields.gohtml:55
msgctxt "input"
msgid "Area preferences (optional)"
msgstr "Préférences de zone (facultatif)"
#: web/templates/public/booking/fields.gohtml:123
#: web/templates/admin/booking/fields.gohtml:59
msgid "Campground map"
msgstr "Plan du camping"
@ -993,29 +1007,31 @@ msgctxt "input"
msgid "Town or village"
msgstr "Ville"
#: web/templates/public/booking/fields.gohtml:188
#: web/templates/public/booking/fields.gohtml:193
#: web/templates/admin/booking/fields.gohtml:203
msgid "Choose a country"
msgstr "Choisissez un pays"
#: web/templates/public/booking/fields.gohtml:242
#: web/templates/public/booking/fields.gohtml:247
#: web/templates/admin/booking/fields.gohtml:258
msgctxt "input"
msgid "ACSI card? (optional)"
msgstr "Carte ACSI ? (Facultatif)"
msgstr "Carte ACSI ? (facultatif)"
#: web/templates/public/booking/fields.gohtml:250
#: web/templates/public/booking/fields.gohtml:255
msgctxt "input"
msgid "I have read and I accept %[1]sthe reservation conditions%[2]s"
msgstr "Jai lu et jaccepte %[1]sles conditions de réservation%[2]s"
#: web/templates/public/booking/fields.gohtml:258
#: web/templates/public/booking/fields.gohtml:263
msgid "By down paying the %d %% of the total, you are pre-booking your preferences. We will respond within 24 hours and this percentage will be charged if accepted."
msgstr "En En effectuant le paiement de %d %% du total vous pré-réservez vos préférences. Nous vous répondrons dans les 24 heures et ce pourcentage sera facturé en cas dacceptation."
#: web/templates/public/booking/fields.gohtml:260
#: web/templates/public/booking/fields.gohtml:265
msgid "By paying the total you are pre-booking your preferences. We will respond within 24 hours and this amount will be charged if accepted."
msgstr "En procédant au paiement du montant total vous pré-réservez vos préférences. Nous vous répondrons dans les 24 heures et ce montant sera facturé en cas dacceptation."
#: web/templates/public/booking/fields.gohtml:264
#: web/templates/public/booking/fields.gohtml:269
msgid "See <%s>our conditions</%s> for more information."
msgstr "Consultez <%s>nos conditions</%s> pour plus dinformations."
@ -1082,6 +1098,8 @@ msgid "Down payment"
msgstr "Acompte"
#: web/templates/admin/payment/index.gohtml:24
#: web/templates/admin/booking/fields.gohtml:74
#: web/templates/admin/booking/fields.gohtml:172
msgctxt "header"
msgid "Total"
msgstr "Totale"
@ -1176,6 +1194,7 @@ msgstr "Contenu"
#: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/fields.gohtml:272
msgctxt "action"
msgid "Update"
msgstr "Mettre à jour"
@ -1195,6 +1214,7 @@ msgstr "Mettre à jour"
#: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/fields.gohtml:274
msgctxt "action"
msgid "Add"
msgstr "Ajouter"
@ -1467,26 +1487,20 @@ msgctxt "action"
msgid "Add Campsite"
msgstr "Ajouter un camping"
#: web/templates/admin/campsite/index.gohtml:32
#: web/templates/admin/amenity/index.gohtml:20
msgctxt "header"
msgid "Label"
msgstr "Label"
#: web/templates/admin/campsite/index.gohtml:78
#: web/templates/admin/campsite/index.gohtml:25
msgid "From Date"
msgstr "Partir de la date"
#: web/templates/admin/campsite/index.gohtml:85
#: web/templates/admin/campsite/index.gohtml:32
msgid "To Date"
msgstr "À la date"
#: web/templates/admin/campsite/index.gohtml:92
#: web/templates/admin/campsite/index.gohtml:39
msgctxt "action"
msgid "Show"
msgstr "Montrer"
#: web/templates/admin/campsite/index.gohtml:96
#: web/templates/admin/campsite/index.gohtml:43
msgid "No campsites added yet."
msgstr "Aucun camping na encore été ajouté."
@ -2146,6 +2160,12 @@ msgctxt "action"
msgid "Add Amenity"
msgstr "Ajouter un installation"
#: web/templates/admin/amenity/index.gohtml:20
#: web/templates/admin/booking/grid.gohtml:13
msgctxt "header"
msgid "Label"
msgstr "Label"
#: web/templates/admin/amenity/index.gohtml:29
msgid "Are you sure you wish to delete this amenity?"
msgstr "Êtes-vous sûr de vouloir supprimer ce installation ?"
@ -2184,6 +2204,7 @@ msgid "Logout"
msgstr "Déconnexion"
#: web/templates/admin/layout.gohtml:92
#: web/templates/admin/booking/form.gohtml:15
#: web/templates/admin/booking/index.gohtml:6
#: web/templates/admin/booking/index.gohtml:16
msgctxt "title"
@ -2291,6 +2312,65 @@ msgctxt "title"
msgid "Upload Media"
msgstr "Envoyer un fichier"
#: web/templates/admin/booking/fields.gohtml:18
msgid "Choose an accommodation"
msgstr "Choisissez un hébergement"
#: web/templates/admin/booking/fields.gohtml:72
msgctxt "header"
msgid "Units"
msgstr "Unités"
#: web/templates/admin/booking/fields.gohtml:73
msgctxt "header"
msgid "Decription"
msgstr "Description"
#: web/templates/admin/booking/fields.gohtml:80 pkg/booking/cart.go:234
msgctxt "cart"
msgid "Night"
msgstr "Nuit"
#: web/templates/admin/booking/fields.gohtml:199
msgctxt "input"
msgid "Country (optional)"
msgstr "Pays (facultatif)"
#: web/templates/admin/booking/fields.gohtml:211
msgctxt "input"
msgid "Address (optional)"
msgstr "Adresse (facultatif)"
#: web/templates/admin/booking/fields.gohtml:220
msgctxt "input"
msgid "Postcode (optional)"
msgstr "Code postal (facultatif)"
#: web/templates/admin/booking/fields.gohtml:229
msgctxt "input"
msgid "Town or village (optional)"
msgstr "Ville (facultatif)"
#: web/templates/admin/booking/fields.gohtml:238
msgctxt "input"
msgid "Email (optional)"
msgstr "E-mail (facultatif)"
#: web/templates/admin/booking/fields.gohtml:247
msgctxt "input"
msgid "Phone (optional)"
msgstr "Téléphone (facultatif)"
#: web/templates/admin/booking/form.gohtml:8
msgctxt "title"
msgid "Edit Booking"
msgstr "Ajouter une réservation"
#: web/templates/admin/booking/form.gohtml:10
msgctxt "title"
msgid "New Booking"
msgstr "Nouvelle réservation"
#: web/templates/admin/booking/index.gohtml:14
msgctxt "action"
msgid "Add Booking"
@ -2421,12 +2501,12 @@ msgid "Slide image must be an image media type."
msgstr "Limage de la diapositive doit être de type média dimage."
#: pkg/app/login.go:56 pkg/app/user.go:246 pkg/company/admin.go:224
#: pkg/booking/public.go:544
#: pkg/booking/public.go:545
msgid "Email can not be empty."
msgstr "Le-mail ne peut pas être vide."
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/company/admin.go:225
#: pkg/booking/public.go:545
#: pkg/booking/admin.go:316 pkg/booking/public.go:546
msgid "This email is not valid. It should be like name@domain.com."
msgstr "Cette adresse e-mail nest pas valide. Il devrait en être name@domain.com."
@ -2637,12 +2717,12 @@ msgctxt "header"
msgid "Children (aged 2 to 10)"
msgstr "Enfants (de 2 à 10 anys)"
#: pkg/campsite/admin.go:419 pkg/booking/public.go:172
#: pkg/booking/public.go:227
#: pkg/campsite/admin.go:280 pkg/booking/admin.go:292 pkg/booking/public.go:173
#: pkg/booking/public.go:228
msgid "Selected campsite type is not valid."
msgstr "Le type demplacement sélectionné nest pas valide."
#: pkg/campsite/admin.go:420 pkg/amenity/admin.go:282
#: pkg/campsite/admin.go:281 pkg/amenity/admin.go:282
msgid "Label can not be empty."
msgstr "L'étiquette ne peut pas être vide."
@ -2734,7 +2814,7 @@ msgstr "Laddresse du lien ne peut pas être vide."
msgid "This web address is not valid. It should be like https://domain.com/."
msgstr "Cette adresse web nest pas valide. Il devrait en être https://domain.com/."
#: pkg/company/admin.go:207 pkg/booking/public.go:529
#: pkg/company/admin.go:207 pkg/booking/public.go:530
msgid "Selected country is not valid."
msgstr "Le pays sélectionné nest pas valide."
@ -2754,15 +2834,15 @@ msgstr "Le numéro de TVA ne peut pas être vide."
msgid "This VAT number is not valid."
msgstr "Ce numéro de TVA nest pas valide."
#: pkg/company/admin.go:219 pkg/booking/public.go:547
#: pkg/company/admin.go:219 pkg/booking/public.go:548
msgid "Phone can not be empty."
msgstr "Le téléphone ne peut pas être vide."
#: pkg/company/admin.go:220 pkg/booking/public.go:548
#: pkg/company/admin.go:220 pkg/booking/admin.go:321 pkg/booking/public.go:549
msgid "This phone number is not valid."
msgstr "Ce numéro de téléphone nest pas valide."
#: pkg/company/admin.go:230 pkg/booking/public.go:537
#: pkg/company/admin.go:230 pkg/booking/public.go:538
msgid "Address can not be empty."
msgstr "Ladresse ne peut pas être vide."
@ -2774,11 +2854,11 @@ msgstr "La ville ne peut pas être vide."
msgid "Province can not be empty."
msgstr "La province ne peut pas être vide."
#: pkg/company/admin.go:233 pkg/booking/public.go:539
#: pkg/company/admin.go:233 pkg/booking/public.go:540
msgid "Postcode can not be empty."
msgstr "Le code postal ne peut pas être vide."
#: pkg/company/admin.go:234 pkg/booking/public.go:540
#: pkg/company/admin.go:234 pkg/booking/admin.go:311 pkg/booking/public.go:541
msgid "This postcode is not valid."
msgstr "Ce code postal nest pas valide."
@ -2830,161 +2910,176 @@ msgstr "Le fichier téléchargé ne peut pas être vide."
msgid "Filename can not be empty."
msgstr "Le nom de fichier ne peut pas être vide."
#: pkg/booking/cart.go:159
msgctxt "cart"
msgid "Night"
msgstr "Nuit"
#: pkg/booking/cart.go:160
#: pkg/booking/cart.go:235
msgctxt "cart"
msgid "Adult"
msgstr "Adulte"
#: pkg/booking/cart.go:161
#: pkg/booking/cart.go:236
msgctxt "cart"
msgid "Teenager"
msgstr "Adolescent"
#: pkg/booking/cart.go:162
#: pkg/booking/cart.go:237
msgctxt "cart"
msgid "Child"
msgstr "Enfant"
#: pkg/booking/cart.go:163
#: pkg/booking/cart.go:238
msgctxt "cart"
msgid "Dog"
msgstr "Chien"
#: pkg/booking/admin.go:126
#: pkg/booking/admin.go:144
msgctxt "filename"
msgid "bookings.ods"
msgstr "reservations.ods"
#: pkg/booking/public.go:276 pkg/booking/public.go:305
#: pkg/booking/admin.go:304 pkg/booking/public.go:534
msgid "Full name can not be empty."
msgstr "Le nom complet ne peut pas être vide."
#: pkg/booking/admin.go:305 pkg/booking/public.go:535
msgid "Full name must have at least one letter."
msgstr "Le nom complet doit comporter au moins une lettre."
#: pkg/booking/admin.go:310
msgid "Country can not be empty to validate the postcode."
msgstr "Le pays ne peut pas être vide pour valider le code postal."
#: pkg/booking/admin.go:320
msgid "Country can not be empty to validate the phone."
msgstr "Le pays ne peut pas être vide pour valider le téléphone."
#: pkg/booking/admin.go:327
msgid "You must select at least one accommodation."
msgstr "Vous devez sélectionner au moins un hébergement."
#: pkg/booking/admin.go:333
msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Les hébergements sélectionnés nont pas de disponibilités aux dates demandées."
#: pkg/booking/public.go:277 pkg/booking/public.go:306
msgid "Arrival date must be a valid date."
msgstr "La date darrivée doit être une date valide."
#: pkg/booking/public.go:290 pkg/booking/public.go:312
#: pkg/booking/public.go:291 pkg/booking/public.go:313
msgid "Departure date must be a valid date."
msgstr "La date de départ doit être une date valide."
#: pkg/booking/public.go:304
#: pkg/booking/public.go:305
msgid "Arrival date can not be empty"
msgstr "La date darrivée ne peut pas être vide"
#: pkg/booking/public.go:306
#: pkg/booking/public.go:307
#, c-format
msgid "Arrival date must be %s or after."
msgstr "La date darrivée doit être égale ou postérieure à %s."
#: pkg/booking/public.go:307
#: pkg/booking/public.go:308
#, c-format
msgid "Arrival date must be %s or before."
msgstr "La date darrivée doit être antérieure ou égale à %s."
#: pkg/booking/public.go:311
#: pkg/booking/public.go:312
msgid "Departure date can not be empty"
msgstr "La date de départ ne peut pas être vide"
#: pkg/booking/public.go:313
#: pkg/booking/public.go:314
#, c-format
msgid "Departure date must be %s or after."
msgstr "La date de départ doit être égale ou postérieure à %s."
#: pkg/booking/public.go:314
#: pkg/booking/public.go:315
#, c-format
msgid "Departure date must be %s or before."
msgstr "La date de départ doit être antérieure ou égale à %s."
#: pkg/booking/public.go:368
#: pkg/booking/public.go:369
#, c-format
msgid "There can be at most %d guests in this accommodation."
msgstr "Il peut y avoir au plus %d invités dans cet hébergement."
#: pkg/booking/public.go:388
#: pkg/booking/public.go:389
msgid "Number of adults can not be empty"
msgstr "Le nombre dadultes ne peut pas être vide."
#: pkg/booking/public.go:389
#: pkg/booking/public.go:390
msgid "Number of adults must be an integer."
msgstr "Le nombre dadultes doit être un entier."
#: pkg/booking/public.go:390
#: pkg/booking/public.go:391
msgid "There must be at least one adult."
msgstr "Il doit y avoir au moins un adulte."
#: pkg/booking/public.go:393
#: pkg/booking/public.go:394
msgid "Number of teenagers can not be empty"
msgstr "Le nombre dadolescents ne peut pas être vide."
#: pkg/booking/public.go:394
#: pkg/booking/public.go:395
msgid "Number of teenagers must be an integer."
msgstr "Le nombre dadolescents doit être un entier."
#: pkg/booking/public.go:395
#: pkg/booking/public.go:396
msgid "Number of teenagers can not be negative."
msgstr "Le nombre dadolescents ne peut pas être négatif."
#: pkg/booking/public.go:398
#: pkg/booking/public.go:399
msgid "Number of children can not be empty"
msgstr "Le nombre denfants ne peut pas être vide."
#: pkg/booking/public.go:399
#: pkg/booking/public.go:400
msgid "Number of children must be an integer."
msgstr "Le nombre denfants doit être un entier."
#: pkg/booking/public.go:400
#: pkg/booking/public.go:401
msgid "Number of children can not be negative."
msgstr "Le nombre denfants ne peut pas être négatif."
#: pkg/booking/public.go:403
#: pkg/booking/public.go:404
msgid "Number of dogs can not be empty"
msgstr "Le nombre de chiens ne peut pas être vide."
#: pkg/booking/public.go:404
#: pkg/booking/public.go:405
msgid "Number of dogs must be an integer."
msgstr "Le nombre de chiens nuits être un entier."
#: pkg/booking/public.go:405
#: pkg/booking/public.go:406
msgid "Number of dogs can not be negative."
msgstr "Le nombre de chiens ne peut pas être négatif."
#: pkg/booking/public.go:476
#: pkg/booking/public.go:477
#, c-format
msgid "%s can not be empty"
msgstr "%s ne peut pas être vide"
#: pkg/booking/public.go:477
#: pkg/booking/public.go:478
#, c-format
msgid "%s must be an integer."
msgstr "%s doit être un entier."
#: pkg/booking/public.go:478
#: pkg/booking/public.go:479
#, c-format
msgid "%s must be %d or greater."
msgstr "%s doit être %d ou plus."
#: pkg/booking/public.go:479
#: pkg/booking/public.go:480
#, c-format
msgid "%s must be at most %d."
msgstr "%s doit être tout au plus %d."
#: pkg/booking/public.go:533
msgid "Full name can not be empty."
msgstr "Le nom complet ne peut pas être vide."
#: pkg/booking/public.go:534
msgid "Full name must have at least one letter."
msgstr "Le nom complet doit comporter au moins une lettre."
#: pkg/booking/public.go:538
#: pkg/booking/public.go:539
msgid "Town or village can not be empty."
msgstr "La ville ne peut pas être vide."
#: pkg/booking/public.go:553
#: pkg/booking/public.go:554
msgid "It is mandatory to agree to the reservation conditions."
msgstr "Il est obligatoire daccepter les conditions de réservation."
#~ msgctxt "title"
#~ msgid "Accomodations"
#~ msgstr "Hébergement"
#~ msgctxt "header"
#~ msgid "Type"
#~ msgstr "Type"
@ -2995,14 +3090,6 @@ msgstr "Il est obligatoire daccepter les conditions de réservation."
#~ msgid "This postal code is not valid."
#~ msgstr "Ce code postal nest pas valide."
#~ msgctxt "input"
#~ msgid "Address (optional)"
#~ msgstr "Adresse (Facultatif)"
#~ msgctxt "input"
#~ msgid "Postcode (optional)"
#~ msgstr "Code postal (Facultatif)"
#~ msgctxt "action"
#~ msgid "Pay"
#~ msgstr "Payer"

View File

@ -0,0 +1,7 @@
-- Revert camper:add_booking_from_payment from pg
begin;
drop function if exists camper.add_booking_from_payment(uuid);
commit;

View File

@ -0,0 +1,27 @@
-- Revert camper:booking__payment_fields from pg
begin;
alter table camper.booking
drop column if exists address
, drop column if exists postal_code
, drop column if exists city
, drop column if exists country_code
, drop column if exists email
, drop column if exists phone
, drop column if exists lang_tag
, drop column if exists zone_preferences
, drop column if exists subtotal_nights
, drop column if exists number_adults
, drop column if exists subtotal_adults
, drop column if exists number_teenagers
, drop column if exists subtotal_teenagers
, drop column if exists number_children
, drop column if exists subtotal_children
, drop column if exists subtotal_dogs
, drop column if exists subtotal_tourist_tax
, drop column if exists total
, drop column if exists currency_code
;
commit;

View File

@ -0,0 +1,7 @@
-- Revert camper:booking_option from pg
begin;
drop table if exists camper.booking_option;
commit;

9
revert/edit_booking.sql Normal file
View File

@ -0,0 +1,9 @@
-- Revert camper:edit_booking from pg
begin;
set search_path to camper, public;
drop function if exists camper.edit_booking(integer, text, text, text, text, text, email, text, text, text, integer[]);
commit;

View File

@ -285,3 +285,7 @@ draft_payment [draft_payment@v7 acsi_option__option_group] 2024-04-03T08:15:40Z
booking__stay [booking] 2024-04-19T16:02:11Z jordi fita mas <jordi@tandem.blog> # Replace booking arrival and departure dates with a daterange
booking_campsite [roles schema_camper booking campsite extension_btree_gist] 2024-04-21T18:27:20Z jordi fita mas <jordi@tandem.blog> # Add relation of campsite booking
booking__payment_fields [booking positive_integer nonnegative_integer] 2024-04-24T10:20:21Z jordi fita mas <jordi@tandem.blog> # Add “the rest” of the fields from payment to booking
booking_option [roles schema_camper booking campsite_type_option positive_integer nonnegative_integer] 2024-04-24T11:14:03Z jordi fita mas <jordi@tandem.blog> # Add booking campsite option relation
add_booking_from_payment [roles schema_camper booking booking__payment_fields booking__stay booking_option payment payment__acsi_card payment_customer payment_option] 2024-04-24T11:23:22Z jordi fita mas <jordi@tandem.blog> # Add function to create a pre-booking from a payment
edit_booking [roles schema_camper booking booking__payment_fields booking__stay booking_campsite] 2024-04-24T16:27:10Z jordi fita mas <jordi@tandem.blog> # Add function to update a booking

View File

@ -0,0 +1,121 @@
-- Test add_booking_from_payment
set client_min_messages to warning;
create extension if not exists pgtap;
reset client_min_messages;
begin;
select plan(15);
set search_path to camper, public;
select has_function('camper', 'add_booking_from_payment', array['uuid']);
select function_lang_is('camper', 'add_booking_from_payment', array['uuid'], 'plpgsql');
select function_returns('camper', 'add_booking_from_payment', array['uuid'], 'integer');
select isnt_definer('camper', 'add_booking_from_payment', array['uuid']);
select volatility_is('camper', 'add_booking_from_payment', array['uuid'], 'volatile');
select function_privs_are('camper', 'add_booking_from_payment', array ['uuid'], 'guest', array[]::text[]);
select function_privs_are('camper', 'add_booking_from_payment', array ['uuid'], 'employee', array['EXECUTE']);
select function_privs_are('camper', 'add_booking_from_payment', array ['uuid'], 'admin', array['EXECUTE']);
select function_privs_are('camper', 'add_booking_from_payment', array ['uuid'], 'authenticator', array[]::text[]);
set client_min_messages to warning;
truncate booking_option cascade;
truncate booking cascade;
truncate payment_option cascade;
truncate payment_customer cascade;
truncate payment cascade;
truncate campsite_type_option cascade;
truncate campsite_type cascade;
truncate media cascade;
truncate media_content cascade;
truncate company cascade;
reset client_min_messages;
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, tourist_tax, tourist_tax_max_days, country_code, currency_code, default_lang_tag)
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 60, 7, 'ES', 'EUR', 'ca')
;
insert into media_content (media_type, bytes)
values ('image/x-xpixmap', 'static char *s[]={"1 1 1 1","a c #ffffff","a"};')
;
insert into media (media_id, company_id, original_filename, content_hash)
values (6, 2, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};'))
;
insert into campsite_type (campsite_type_id, company_id, name, media_id, max_campers, bookable_nights)
values (12, 2, 'Wooden lodge', 6, 7, '[1, 7]')
, (14, 2, 'Bungalow', 6, 7, '[1, 7]')
, (16, 2, 'Plot', 6, 7, '[1, 7]')
;
insert into campsite_type_option (campsite_type_option_id, campsite_type_id, name, range, per_night)
values (18, 12, 'Big tent', '[0, 4)', true)
, (20, 12, 'Small tent', '[0, 4)', true)
, (22, 14, 'Electricity', '[0, 5)', false)
, (24, 14, 'Car', '[0, 4)', true)
, (26, 16, 'Autocaravan', '[0, 4)', true)
;
insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, zone_preferences, acsi_card, payment_status)
values (28, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'EUR', 'pref I before E', true, 'draft')
, (30, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 14, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', false, 'draft')
, (32, '7cae7d1c-d626-41e0-b1c5-48359e515579', 2, 16, '2024-08-30', '2024-09-02', 74000, 3, 122, 1, 333, 2, 444, 3, 555, 666, 777, 'USD', 'None', false, 'preauth')
;
insert into payment_customer (payment_id, full_name, address, postal_code, city, country_code, email, phone, lang_tag)
values (30, 'First', 'Fake St., 123', '17800', 'Girona', 'ES', 'customer@example.com', '+34 977 977 977', 'ca')
, (32, 'Second', 'None', '555', 'Paris', 'FR', 'customer@example.fr', '+33 123 123 123', 'fr')
;
insert into payment_option (payment_id, campsite_type_option_id, units, subtotal)
values (28, 18, 1, 1500)
, (30, 22, 2, 111)
, (30, 24, 3, 2222)
;
select lives_ok(
$$ select add_booking_from_payment('4ef35e2f-ef98-42d6-a724-913bd761ca8c') $$,
'Should be able to create a booking from a payment without customer data'
);
select lives_ok(
$$ select add_booking_from_payment('6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693') $$,
'Should be able to create a booking from a payment with all data'
);
select lives_ok(
$$ select add_booking_from_payment('7cae7d1c-d626-41e0-b1c5-48359e515579') $$,
'Should be able to create a booking from a payment without options'
);
select throws_ok(
$$ select add_booking_from_payment('ef603c62-cf35-4192-8642-2ab6bd71dc26') $$,
'22023', 'ef603c62-cf35-4192-8642-2ab6bd71dc26 is not a valid payment.',
'Should not be possible to create a booking from a non-existing payment'
);
select bag_eq(
$$ select company_id, campsite_type_id, stay, holder_name, address, postal_code, city, country_code::text, email::text, phone::text, lang_tag, zone_preferences, subtotal_nights::integer, number_adults::integer, subtotal_adults::integer, number_teenagers::integer, subtotal_teenagers::integer, number_children::integer, subtotal_children::integer, number_dogs::integer, subtotal_dogs::integer, subtotal_tourist_tax::integer, total::integer, acsi_card, currency_code::text, booking_status from booking $$,
$$ values (2, 12, daterange('2024-08-28', '2024-09-04'), 'Unknown', null, null, null, null, null, null, 'und', 'pref I before E', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, true, 'EUR', 'created')
, (2, 14, daterange('2024-08-29', '2024-09-03'), 'First', 'Fake St., 123', '17800', 'Girona', 'ES', 'customer@example.com', '+34 977 97 79 77', 'ca', '', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, false, 'EUR', 'created')
, (2, 16, daterange('2024-08-30', '2024-09-02'), 'Second', 'None', '555', 'Paris', 'FR', 'customer@example.fr', '+33 1 23 12 31 23', 'fr', 'None', 74000, 3, 122, 1, 333, 2, 444, 3, 555, 666, 777, false, 'USD', 'created')
$$,
'Should have created the new bookings'
);
select bag_eq (
$$ select campsite_type_id, campsite_type_option_id, units, subtotal from booking_option join booking using (booking_id) $$,
$$ values (12, 18, 1, 1500)
, (14, 22, 2, 111)
, (14, 24, 3, 2222)
$$ ,
'Should have added the booking options too'
);
select *
from finish();
rollback;

View File

@ -5,7 +5,7 @@ reset client_min_messages;
begin;
select plan(74);
select plan(156);
set search_path to camper, public;
@ -54,7 +54,7 @@ select col_not_null('booking', 'stay');
select col_hasnt_default('booking', 'stay');
select has_column('booking', 'number_dogs');
select col_type_is('booking', 'number_dogs', 'integer');
select col_type_is('booking', 'number_dogs', 'nonnegative_integer');
select col_not_null('booking', 'number_dogs');
select col_hasnt_default('booking', 'number_dogs');
@ -77,6 +77,108 @@ select col_not_null('booking', 'created_at');
select col_has_default('booking', 'created_at');
select col_default_is('booking', 'created_at', 'CURRENT_TIMESTAMP');
select has_column('booking', 'zone_preferences');
select col_type_is('booking', 'zone_preferences', 'text');
select col_not_null('booking', 'zone_preferences');
select col_hasnt_default('booking', 'zone_preferences');
select has_column('booking', 'address');
select col_type_is('booking', 'address', 'text');
select col_is_null('booking', 'address');
select col_hasnt_default('booking', 'address');
select has_column('booking', 'postal_code');
select col_type_is('booking', 'postal_code', 'text');
select col_is_null('booking', 'postal_code');
select col_hasnt_default('booking', 'postal_code');
select has_column('booking', 'city');
select col_type_is('booking', 'city', 'text');
select col_is_null('booking', 'city');
select col_hasnt_default('booking', 'city');
select has_column('booking', 'country_code');
select col_is_fk('booking', 'country_code');
select fk_ok('booking', 'country_code', 'country', 'country_code');
select col_type_is('booking', 'country_code', 'country_code');
select col_is_null('booking', 'country_code');
select col_hasnt_default('booking', 'country_code');
select has_column('booking', 'email');
select col_type_is('booking', 'email', 'email');
select col_is_null('booking', 'email');
select col_hasnt_default('booking', 'email');
select has_column('booking', 'phone');
select col_type_is('booking', 'phone', 'packed_phone_number');
select col_is_null('booking', 'phone');
select col_hasnt_default('booking', 'phone');
select has_column('booking', 'lang_tag');
select col_is_fk('booking', 'lang_tag');
select fk_ok('booking', 'lang_tag', 'language', 'lang_tag');
select col_type_is('booking', 'lang_tag', 'text');
select col_not_null('booking', 'lang_tag');
select col_has_default('booking', 'lang_tag');
select col_default_is('booking', 'lang_tag', 'und');
select has_column('booking', 'subtotal_nights');
select col_type_is('booking', 'subtotal_nights', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_nights');
select col_hasnt_default('booking', 'subtotal_nights');
select has_column('booking', 'number_adults');
select col_type_is('booking', 'number_adults', 'positive_integer');
select col_not_null('booking', 'number_adults');
select col_hasnt_default('booking', 'number_adults');
select has_column('booking', 'subtotal_adults');
select col_type_is('booking', 'subtotal_adults', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_adults');
select col_hasnt_default('booking', 'subtotal_adults');
select has_column('booking', 'number_teenagers');
select col_type_is('booking', 'number_teenagers', 'nonnegative_integer');
select col_not_null('booking', 'number_teenagers');
select col_hasnt_default('booking', 'number_teenagers');
select has_column('booking', 'subtotal_teenagers');
select col_type_is('booking', 'subtotal_teenagers', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_teenagers');
select col_hasnt_default('booking', 'subtotal_teenagers');
select has_column('booking', 'number_children');
select col_type_is('booking', 'number_children', 'nonnegative_integer');
select col_not_null('booking', 'number_children');
select col_hasnt_default('booking', 'number_children');
select has_column('booking', 'subtotal_children');
select col_type_is('booking', 'subtotal_children', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_children');
select col_hasnt_default('booking', 'subtotal_children');
select has_column('booking', 'subtotal_dogs');
select col_type_is('booking', 'subtotal_dogs', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_dogs');
select col_hasnt_default('booking', 'subtotal_dogs');
select has_column('booking', 'subtotal_tourist_tax');
select col_type_is('booking', 'subtotal_tourist_tax', 'nonnegative_integer');
select col_not_null('booking', 'subtotal_tourist_tax');
select col_hasnt_default('booking', 'subtotal_tourist_tax');
select has_column('booking', 'total');
select col_type_is('booking', 'total', 'nonnegative_integer');
select col_not_null('booking', 'total');
select col_hasnt_default('booking', 'total');
select has_column('booking', 'currency_code');
select col_is_fk('booking', 'currency_code');
select fk_ok('booking', 'currency_code', 'currency', 'currency_code');
select col_type_is('booking', 'currency_code', 'currency_code');
select col_not_null('booking', 'currency_code');
select col_hasnt_default('booking', 'currency_code');
set client_min_messages to warning;
truncate booking cascade;
@ -125,9 +227,9 @@ values (10, 2, 'Wooden lodge', 6, 7, '[1, 7]')
, (12, 4, 'Bungalow', 8, 6, '[2, 6]')
;
insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card)
values (2, 10, 'Holder 2', daterange('2024-01-18', '2024-01-19'), 0, false)
, (4, 12, 'Holder 4', daterange('2024-01-18', '2024-01-19'), 0, false)
insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total)
values (2, 10, 'Holder 2', daterange('2024-01-18', '2024-01-19'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
, (4, 12, 'Holder 4', daterange('2024-01-18', '2024-01-19'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
;
prepare booking_data as
@ -157,7 +259,7 @@ select bag_eq(
);
select lives_ok(
$$ insert into booking(company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card) values (2, 10, 'New Holder', daterange('2024-01-18', '2024-01-19'), 0, false) $$,
$$ insert into booking(company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total) values (2, 10, 'New Holder', daterange('2024-01-18', '2024-01-19'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0) $$,
'Users from company 2 should be able to insert a new booking type to their company.'
);
@ -183,7 +285,7 @@ select bag_eq(
);
select throws_ok(
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card) values (4, 12, 'Another holder', daterange('2024-01-18', '2024-01-19'), 0, false) $$,
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total) values (4, 12, 'Another holder', daterange('2024-01-18', '2024-01-19'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0) $$,
'42501', 'new row violates row-level security policy for table "booking"',
'Users from company 2 should NOT be able to insert new bookings to company 4.'
);
@ -240,23 +342,17 @@ select bag_eq(
);
select throws_ok(
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card) values (2, 10, ' ', daterange('2024-01-18', '2024-01-19'), 0, false) $$,
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total) values (2, 10, ' ', daterange('2024-01-18', '2024-01-19'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0) $$,
'23514', 'new row for relation "booking" violates check constraint "holder_name_not_empty"',
'Should not be able to add bookings with a blank holder name.'
);
select throws_ok(
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card) values (2, 10, 'Holder', daterange('2024-01-18', '2024-01-18'), 0, false) $$,
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total) values (2, 10, 'Holder', daterange('2024-01-18', '2024-01-18'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0) $$,
'23514', 'new row for relation "booking" violates check constraint "stay_not_empty"',
'Should not be able to add bookings with an empty stay.'
);
select throws_ok(
$$ insert into booking (company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card) values (2, 10, 'Holder', daterange('2024-01-18', '2024-01-19'), -1, false) $$,
'23514', 'new row for relation "booking" violates check constraint "number_dogs_nonnegative"',
'Should not be able to add bookings owing dogs to holder.'
);
select *

View File

@ -67,9 +67,9 @@ values (12, 2, 'A', 10)
, (16, 2, 'C', 10)
;
insert into booking (booking_id, company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card)
values (18, 2, 10, 'Holder 2', daterange('2024-01-18', '2024-01-29'), 0, false)
, (20, 2, 10, 'Holder 4', daterange('2024-01-28', '2024-01-29'), 0, false)
insert into booking (booking_id, company_id, campsite_type_id, holder_name, stay, number_dogs, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, subtotal_dogs, subtotal_tourist_tax, total)
values (18, 2, 10, 'Holder 2', daterange('2024-01-18', '2024-01-29'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
, (20, 2, 10, 'Holder 4', daterange('2024-01-28', '2024-01-29'), 0, false, 'EUR', '', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
;
insert into booking_campsite (booking_id, campsite_id, stay)

49
test/booking_option.sql Normal file
View File

@ -0,0 +1,49 @@
-- Test booking_option
set client_min_messages to warning;
create extension if not exists pgtap;
reset client_min_messages;
begin;
select plan(27);
set search_path to camper, public;
select has_table('booking_option');
select has_pk('booking_option');
select col_is_pk('booking_option', array['booking_id', 'campsite_type_option_id']);
select table_privs_are('booking_option', 'guest', array[]::text[]);
select table_privs_are('booking_option', 'employee', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
select table_privs_are('booking_option', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
select table_privs_are('booking_option', 'authenticator', array[]::text[]);
select has_column('booking_option', 'booking_id');
select col_is_fk('booking_option', 'booking_id');
select fk_ok('booking_option', 'booking_id', 'booking', 'booking_id');
select col_type_is('booking_option', 'booking_id', 'integer');
select col_not_null('booking_option', 'booking_id');
select col_hasnt_default('booking_option', 'booking_id');
select has_column('booking_option', 'campsite_type_option_id');
select col_is_fk('booking_option', 'campsite_type_option_id');
select fk_ok('booking_option', 'campsite_type_option_id', 'campsite_type_option', 'campsite_type_option_id');
select col_type_is('booking_option', 'campsite_type_option_id', 'integer');
select col_not_null('booking_option', 'campsite_type_option_id');
select col_hasnt_default('booking_option', 'campsite_type_option_id');
select has_column('booking_option', 'units');
select col_type_is('booking_option', 'units', 'positive_integer');
select col_not_null('booking_option', 'units');
select col_hasnt_default('booking_option', 'units');
select has_column('booking_option', 'subtotal');
select col_type_is('booking_option', 'subtotal', 'nonnegative_integer');
select col_not_null('booking_option', 'subtotal');
select col_hasnt_default('booking_option', 'subtotal');
select *
from finish();
rollback;

95
test/edit_booking.sql Normal file
View File

@ -0,0 +1,95 @@
-- Test edit_booking
set client_min_messages to warning;
create extension if not exists pgtap;
reset client_min_messages;
begin;
select plan(13);
set search_path to camper, public;
select has_function('camper', 'edit_booking', array['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]']);
select function_lang_is('camper', 'edit_booking', array['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'plpgsql');
select function_returns('camper', 'edit_booking', array['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'void');
select isnt_definer('camper', 'edit_booking', array['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]']);
select volatility_is('camper', 'edit_booking', array['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'volatile');
select function_privs_are('camper', 'edit_booking', array ['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'guest', array[]::text[]);
select function_privs_are('camper', 'edit_booking', array ['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'employee', array['EXECUTE']);
select function_privs_are('camper', 'edit_booking', array ['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'admin', array['EXECUTE']);
select function_privs_are('camper', 'edit_booking', array ['integer', 'text', 'text', 'text', 'text', 'text', 'email', 'text', 'text', 'text', 'integer[]'], 'authenticator', array[]::text[]);
set client_min_messages to warning;
truncate booking_campsite cascade;
truncate booking cascade;
truncate campsite_type cascade;
truncate media cascade;
truncate media_content cascade;
truncate company cascade;
reset client_min_messages;
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, tourist_tax, tourist_tax_max_days, country_code, currency_code, default_lang_tag)
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 60, 7, 'ES', 'EUR', 'ca')
;
insert into media_content (media_type, bytes)
values ('image/x-xpixmap', 'static char *s[]={"1 1 1 1","a c #ffffff","a"};')
;
insert into media (media_id, company_id, original_filename, content_hash)
values (6, 2, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};'))
;
insert into campsite_type (campsite_type_id, company_id, name, media_id, max_campers, bookable_nights)
values (10, 2, 'Wooden lodge', 6, 7, '[1, 7]')
;
insert into campsite (campsite_id, company_id, label, campsite_type_id)
values (12, 2, 'A', 10)
, (14, 2, 'B', 10)
, (16, 2, 'C', 10)
;
insert into booking (booking_id, company_id, campsite_type_id, holder_name, stay, acsi_card, currency_code, zone_preferences, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total)
values (18, 2, 10, 'Holder 2', daterange('2024-01-18', '2024-01-29'), false, 'EUR', '', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
, (20, 2, 10, 'Holder 4', daterange('2024-01-28', '2024-01-29'), true, 'USD', 'None', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
;
insert into booking_campsite (booking_id, campsite_id, stay)
values (18, 12, daterange('2024-01-18', '2024-01-29'))
;
select lives_ok(
$$ select edit_booking(18, 'First', 'Fake St., 123', '17800', 'Girona', 'ES', 'customer@example.com', '+34 977 97 79 77', 'ca', 'confirmed', array[14]) $$,
'Should be able to edit the first booking'
);
select lives_ok(
$$ select edit_booking(20, 'Second', 'None', '555', 'Paris', 'FR', 'customer@example.fr', '+33 1 23 12 31 23', 'fr', 'invoiced', array[12, 16]) $$,
'Should be able to edit the second booking'
);
select bag_eq(
$$ select booking_id, company_id, campsite_type_id, stay, holder_name, address, postal_code, city, country_code::text, email::text, phone::text, lang_tag, zone_preferences, subtotal_nights::integer, number_adults::integer, subtotal_adults::integer, number_teenagers::integer, subtotal_teenagers::integer, number_children::integer, subtotal_children::integer, number_dogs::integer, subtotal_dogs::integer, subtotal_tourist_tax::integer, total::integer, acsi_card, currency_code::text, booking_status from booking $$,
$$ values (18, 2, 10, daterange('2024-01-18', '2024-01-29'), 'First', 'Fake St., 123', '17800', 'Girona', 'ES', 'customer@example.com', '+34 977 97 79 77', 'ca', '', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, false, 'EUR', 'confirmed')
, (20, 2, 10, daterange('2024-01-28', '2024-01-29'), 'Second', 'None', '555', 'Paris', 'FR', 'customer@example.fr', '+33 1 23 12 31 23', 'fr', 'None', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, true, 'USD', 'invoiced')
$$,
'Should have updated the bookings'
);
select bag_eq (
$$ select booking_id, campsite_id, stay from booking_campsite $$,
$$ values (18, 14, daterange('2024-01-18', '2024-01-29'))
, (20, 12, daterange('2024-01-28', '2024-01-29'))
, (20, 16, daterange('2024-01-28', '2024-01-29'))
$$ ,
'Should have updated the booking campsites too'
);
select *
from finish();
rollback;

View File

@ -0,0 +1,7 @@
-- Verify camper:add_booking_from_payment on pg
begin;
select has_function_privilege('camper.add_booking_from_payment(uuid)', 'execute');
rollback;

View File

@ -0,0 +1,27 @@
-- Verify camper:booking__payment_fields on pg
begin;
select address
, postal_code
, city
, country_code
, email
, phone
, lang_tag
, zone_preferences
, subtotal_nights
, number_adults
, subtotal_adults
, number_teenagers
, subtotal_teenagers
, number_children
, subtotal_children
, subtotal_dogs
, subtotal_tourist_tax
, total
, currency_code
from camper.booking
where false;
rollback;

12
verify/booking_option.sql Normal file
View File

@ -0,0 +1,12 @@
-- Verify camper:booking_option on pg
begin;
select booking_id
, campsite_type_option_id
, units
, subtotal
from camper.booking_option
where false;
rollback;

9
verify/edit_booking.sql Normal file
View File

@ -0,0 +1,9 @@
-- Verify camper:edit_booking on pg
begin;
set search_path to camper, public;
select has_function_privilege('camper.edit_booking(integer, text, text, text, text, text, email, text, text, text, integer[])', 'execute');
rollback;

View File

@ -15,7 +15,7 @@
data-hx-get="/admin/bookings/new" data-hx-trigger="change"
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Choose an accomodation" )}}</option>
<option value="">{{( gettext "Choose an accommodation" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
@ -196,9 +196,8 @@
{{- end }}
{{ with .Country -}}
<label>
{{( pgettext "Country" "input" )}}<br>
{{( pgettext "Country (optional)" "input" )}}<br>
<select name="{{ .Name }}"
required
{{ template "error-attrs" . }}
>
<option>{{( gettext "Choose a country" )}}</option>
@ -209,8 +208,8 @@
{{- end }}
{{ with .Address -}}
<label class="colspan">
{{( pgettext "Address" "input" )}}<br>
<input type="text" required
{{( pgettext "Address (optional)" "input" )}}<br>
<input type="text"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
@ -218,8 +217,8 @@
{{- end }}
{{ with .PostalCode -}}
<label>
{{( pgettext "Postcode" "input" )}}<br>
<input type="text" required
{{( pgettext "Postcode (optional)" "input" )}}<br>
<input type="text"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
@ -227,9 +226,8 @@
{{- end }}
{{ with .City -}}
<label>
{{( pgettext "Town or village" "input" )}}<br>
{{( pgettext "Town or village (optional)" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
@ -237,8 +235,8 @@
{{- end }}
{{ with .Email -}}
<label>
{{( pgettext "Email" "input" )}}<br>
<input type="email" required
{{( pgettext "Email (optional)" "input" )}}<br>
<input type="email"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
@ -246,8 +244,8 @@
{{- end }}
{{ with .Phone -}}
<label>
{{( pgettext "Phone" "input" )}}<br>
<input type="tel" required
{{( pgettext "Phone (optional)" "input" )}}<br>
<input type="tel"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
@ -279,5 +277,11 @@
</footer>
{{ define "campsite-heading" -}}
<label><input type="checkbox"> {{ .Label }}</label>
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/booking.CampsiteEntry*/ -}}
<label>
<input type="checkbox"
name="campsite"
value="{{ .ID }}"
{{- if .Selected }} checked="checked"{{ end -}}
> {{ .Label }}</label>
{{- end }}

View File

@ -18,6 +18,9 @@
{{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/booking.adminBookingForm*/ -}}
<h2>{{ template "title" .}}</h2>
{{ if .Error -}}
<p class="error">{{ .Error }}</p>
{{- end }}
<form id="booking-form"
data-hx-ext="morph"
data-hx-swap="morph:innerHTML"

View File

@ -89,7 +89,7 @@
</label>
{{- end }}
{{ if .Overflow -}}
<small>{{( gettext "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other." ) | raw}}</small>
<small>{{( gettext "Note: Due to guest capacity, we have added more accommodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other." ) | raw}}</small>
{{- end }}
{{ if .Error -}}
<p class="error">{{ .Error }}</p>

View File

@ -36,7 +36,7 @@
<li><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M32 192V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V88c0 4.4 3.6 8 8 8h32c4.4 0 8-3.6 8-8V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V88c0 4.4 3.6 8 8 8h32c4.4 0 8-3.6 8-8V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V192c0 10.1-4.7 19.6-12.8 25.6L352 256l16 144H80L96 256 44.8 217.6C36.7 211.6 32 202.1 32 192zm176 96h32c8.8 0 16-7.2 16-16V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v48c0 8.8 7.2 16 16 16zM22.6 473.4L64 432H384l41.4 41.4c4.2 4.2 6.6 10 6.6 16c0 12.5-10.1 22.6-22.6 22.6H38.6C26.1 512 16 501.9 16 489.4c0-6 2.4-11.8 6.6-16z"/></svg> {{( pgettext "Playground" "legend" )}}</li>
<li><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M320 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM125.7 175.5c9.9-9.9 23.4-15.5 37.5-15.5c1.9 0 3.8 .1 5.6 .3L137.6 254c-9.3 28 1.7 58.8 26.8 74.5l86.2 53.9-25.4 88.8c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l28.7-100.4c5.9-20.6-2.6-42.6-20.7-53.9L238 299l30.9-82.4 5.1 12.3C289 264.7 323.9 288 362.7 288H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H362.7c-12.9 0-24.6-7.8-29.5-19.7l-6.3-15c-14.6-35.1-44.1-61.9-80.5-73.1l-48.7-15c-11.1-3.4-22.7-5.2-34.4-5.2c-31 0-60.8 12.3-82.7 34.3L57.4 153.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l23.1-23.1zM91.2 352H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h69.6c19 0 36.2-11.2 43.9-28.5L157 361.6l-9.5-6c-17.5-10.9-30.5-26.8-37.9-44.9L91.2 352z"/></svg> {{( pgettext "Sports field" "legend" )}}</li>
</ul>
<h4>{{( pgettext "Accomodations" "title" )}}</h4>
<h4>{{( pgettext "Accommodations" "title" )}}</h4>
<ul>
<li><svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 0 533 512"><path d="M237 -33q19 -12 38 0l109 78v0v-20v0q0 -14 9 -23t23 -9h32v0q14 0 23 9t9 23v89v0l19 13v0q17 14 12 36q-8 21 -31 22h-32h-416q-22 -1 -30 -22q-6 -22 11 -36l224 -160v0zM32 241q2 -22 24 -24h112v0q22 2 24 24v16v0q-2 22 -24 24h-112v0q-22 -2 -24 -24v-16v0z M56 313h112h-112h112q22 2 24 24v16v0q-2 22 -24 24h-112v0q-22 -2 -24 -24v-16v0q2 -22 24 -24v0zM56 409h112h-112h112q22 2 24 24v16v0q-2 22 -24 24h-112v0q-22 -2 -24 -24v-16v0q2 -22 24 -24v0zM320 241q2 -22 24 -24h112v0q22 2 24 24v16v0q-2 22 -24 24h-112v0 q-22 -2 -24 -24v-16v0zM344 409h112h-112h112q22 2 24 24v16v0q-2 22 -24 24h-112v0q-22 -2 -24 -24v-16v0q2 -22 24 -24v0zM320 337q2 -22 24 -24h112v0q22 2 24 24v16v0q-2 22 -24 24h-112v0q-22 -2 -24 -24v-16v0zM256 121q14 0 23 -9v0v0q9 -9 9 -23t-9 -23t-23 -9 t-23 9t-9 23t9 23t23 9v0z" /></svg> {{( pgettext "Wooden lodge" "legend" )}}</li>
<li><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M36.8 192H603.2c20.3 0 36.8-16.5 36.8-36.8c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM64 224V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V384 224H320V384H128V224H64zm448 0V480c0 17.7 14.3 32 32 32s32-14.3 32-32V224H512z"/></svg> {{( pgettext "Bungalow" "legend" )}}</li>