From fdf9502c8b658013762fbcef10336115de1f4d2d Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Wed, 24 Apr 2024 20:12:29 +0200 Subject: [PATCH] =?UTF-8?q?=E2=80=9CFinish=E2=80=9D=20the=20new=20booking?= =?UTF-8?q?=20form?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- deploy/add_booking_from_payment.sql | 108 ++++++++ deploy/booking__payment_fields.sql | 48 ++++ deploy/booking_option.sql | 24 ++ deploy/edit_booking.sql | 48 ++++ pkg/booking/admin.go | 164 ++++++++++++- pkg/booking/campsite.go | 7 +- pkg/database/funcs.go | 10 + po/ca.po | 267 +++++++++++++------- po/es.po | 269 +++++++++++++------- po/fr.po | 271 ++++++++++++++------- revert/add_booking_from_payment.sql | 7 + revert/booking__payment_fields.sql | 27 ++ revert/booking_option.sql | 7 + revert/edit_booking.sql | 9 + sqitch.plan | 4 + test/add_booking_from_payment.sql | 121 +++++++++ test/booking.sql | 126 ++++++++-- test/booking_campsite.sql | 6 +- test/booking_option.sql | 49 ++++ test/edit_booking.sql | 95 ++++++++ verify/add_booking_from_payment.sql | 7 + verify/booking__payment_fields.sql | 27 ++ verify/booking_option.sql | 12 + verify/edit_booking.sql | 9 + web/templates/admin/booking/fields.gohtml | 32 +-- web/templates/admin/booking/form.gohtml | 3 + web/templates/public/booking/fields.gohtml | 2 +- web/templates/public/campground.gohtml | 2 +- 28 files changed, 1442 insertions(+), 319 deletions(-) create mode 100644 deploy/add_booking_from_payment.sql create mode 100644 deploy/booking__payment_fields.sql create mode 100644 deploy/booking_option.sql create mode 100644 deploy/edit_booking.sql create mode 100644 revert/add_booking_from_payment.sql create mode 100644 revert/booking__payment_fields.sql create mode 100644 revert/booking_option.sql create mode 100644 revert/edit_booking.sql create mode 100644 test/add_booking_from_payment.sql create mode 100644 test/booking_option.sql create mode 100644 test/edit_booking.sql create mode 100644 verify/add_booking_from_payment.sql create mode 100644 verify/booking__payment_fields.sql create mode 100644 verify/booking_option.sql create mode 100644 verify/edit_booking.sql diff --git a/deploy/add_booking_from_payment.sql b/deploy/add_booking_from_payment.sql new file mode 100644 index 0000000..80f6a57 --- /dev/null +++ b/deploy/add_booking_from_payment.sql @@ -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; diff --git a/deploy/booking__payment_fields.sql b/deploy/booking__payment_fields.sql new file mode 100644 index 0000000..cbe9677 --- /dev/null +++ b/deploy/booking__payment_fields.sql @@ -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; diff --git a/deploy/booking_option.sql b/deploy/booking_option.sql new file mode 100644 index 0000000..8cb4503 --- /dev/null +++ b/deploy/booking_option.sql @@ -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; diff --git a/deploy/edit_booking.sql b/deploy/edit_booking.sql new file mode 100644 index 0000000..18d21d7 --- /dev/null +++ b/deploy/edit_booking.sql @@ -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; diff --git a/pkg/booking/admin.go b/pkg/booking/admin.go index ced2d89..e404cd1 100644 --- a/pkg/booking/admin.go +++ b/pkg/booking/admin.go @@ -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) +} diff --git a/pkg/booking/campsite.go b/pkg/booking/campsite.go index 8a0d490..8acc07a 100644 --- a/pkg/booking/campsite.go +++ b/pkg/booking/campsite.go @@ -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) diff --git a/pkg/database/funcs.go b/pkg/database/funcs.go index 8846585..2769110 100644 --- a/pkg/database/funcs.go +++ b/pkg/database/funcs.go @@ -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 +} diff --git a/po/ca.po b/po/ca.po index 008d2ae..1a6aebb 100644 --- a/po/ca.po +++ b/po/ca.po @@ -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 \n" "Language-Team: Catalan \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 d’arribada" @@ -162,6 +164,7 @@ msgstr "Data d’arribada" #: 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 d’entre 11 i 16 anys" @@ -189,6 +194,7 @@ msgstr "Adolescents d’entre 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 d’entre 2 i 10 anys" @@ -196,24 +202,26 @@ msgstr "Nens d’entre 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 d’allotjament" #: 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 d’esports" #: 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 cannot 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 cannot guarantee that they will be next to each other." msgstr "Nota: S’han afegit més allotjaments a la reserva degut a la capacitat de cadascuna, però no 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 not allow dogs." msgstr "Nota: A aquest allotjament no s’hi 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 for more information." msgstr "Consulteu <%s>les nostres condicions 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 s’ha 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 d’allotjament 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 l’etiqueta en blanc." @@ -2734,7 +2814,7 @@ msgstr "No podeu deixar l’adreça de l’enllaç 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 l’adreç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 d’escollir 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 d’arribada 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 d’arribada 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 d’arribada 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 d’arribada 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 d’adults en blanc." -#: pkg/booking/public.go:389 +#: pkg/booking/public.go:390 msgid "Number of adults must be an integer." msgstr "El número d’adults 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 d’haver 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 d’adolescents en blanc." -#: pkg/booking/public.go:394 +#: pkg/booking/public.go:395 msgid "Number of teenagers must be an integer." msgstr "El número d’adolescents 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 d’adolescents 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" diff --git a/po/es.po b/po/es.po index 5f619ea..77ad1b1 100644 --- a/po/es.po +++ b/po/es.po @@ -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 \n" "Language-Team: Spanish \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 cannot 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 cannot 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 no 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 not allow dogs." msgstr "Nota: En este alojamiento no 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 for more information." msgstr "Consultad <%s>nuestras condiciones 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" diff --git a/po/fr.po b/po/fr.po index 60f9d74..7ea0168 100644 --- a/po/fr.po +++ b/po/fr.po @@ -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 \n" "Language-Team: French \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 d’arrivée" @@ -162,6 +164,7 @@ msgstr "Date d’arrivé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 d’emplacement 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 cannot 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 cannot guarantee that they will be next to each other." msgstr "Remarque : En raison de la capacité d’accueils, nous avons ajouté d’autres hébergements à la réservation, mais nous ne pouvons garantir qu’ils seront côte à côte." #: web/templates/public/booking/fields.gohtml:109 +#: web/templates/admin/booking/fields.gohtml:178 msgid "Note: This accommodation does not allow dogs." msgstr "Remarque : Dans cet hébergement les chiens ne 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 "J’ai lu et j’accepte %[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 d’acceptation." -#: 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 d’acceptation." -#: web/templates/public/booking/fields.gohtml:264 +#: web/templates/public/booking/fields.gohtml:269 msgid "See <%s>our conditions for more information." msgstr "Consultez <%s>nos conditions pour plus d’informations." @@ -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 n’a 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 "L’image de la diapositive doit être de type média d’image." #: 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 "L’e-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 n’est 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 d’emplacement sélectionné n’est 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 "L’addresse 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 n’est 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é n’est 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 n’est 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 n’est 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 "L’adresse 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 n’est 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 n’ont 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 d’arrivé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 d’arrivé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 d’arrivé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 d’arrivé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 d’adultes 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 d’adultes 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 d’adolescents 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 d’adolescents 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 d’adolescents 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 d’enfants 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 d’enfants 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 d’enfants 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 d’accepter 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 d’accepter les conditions de réservation." #~ msgid "This postal code is not valid." #~ msgstr "Ce code postal n’est 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" diff --git a/revert/add_booking_from_payment.sql b/revert/add_booking_from_payment.sql new file mode 100644 index 0000000..b06fd33 --- /dev/null +++ b/revert/add_booking_from_payment.sql @@ -0,0 +1,7 @@ +-- Revert camper:add_booking_from_payment from pg + +begin; + +drop function if exists camper.add_booking_from_payment(uuid); + +commit; diff --git a/revert/booking__payment_fields.sql b/revert/booking__payment_fields.sql new file mode 100644 index 0000000..556b719 --- /dev/null +++ b/revert/booking__payment_fields.sql @@ -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; diff --git a/revert/booking_option.sql b/revert/booking_option.sql new file mode 100644 index 0000000..d199fa0 --- /dev/null +++ b/revert/booking_option.sql @@ -0,0 +1,7 @@ +-- Revert camper:booking_option from pg + +begin; + +drop table if exists camper.booking_option; + +commit; diff --git a/revert/edit_booking.sql b/revert/edit_booking.sql new file mode 100644 index 0000000..14836e1 --- /dev/null +++ b/revert/edit_booking.sql @@ -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; diff --git a/sqitch.plan b/sqitch.plan index 0144c10..682a3fc 100644 --- a/sqitch.plan +++ b/sqitch.plan @@ -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 # 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 # Add relation of campsite booking +booking__payment_fields [booking positive_integer nonnegative_integer] 2024-04-24T10:20:21Z jordi fita mas # 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 # 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 # 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 # Add function to update a booking diff --git a/test/add_booking_from_payment.sql b/test/add_booking_from_payment.sql new file mode 100644 index 0000000..4a1af3b --- /dev/null +++ b/test/add_booking_from_payment.sql @@ -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; diff --git a/test/booking.sql b/test/booking.sql index 0690632..16b74f7 100644 --- a/test/booking.sql +++ b/test/booking.sql @@ -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 * diff --git a/test/booking_campsite.sql b/test/booking_campsite.sql index bd629e7..c35ecbc 100644 --- a/test/booking_campsite.sql +++ b/test/booking_campsite.sql @@ -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) diff --git a/test/booking_option.sql b/test/booking_option.sql new file mode 100644 index 0000000..66f9312 --- /dev/null +++ b/test/booking_option.sql @@ -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; + diff --git a/test/edit_booking.sql b/test/edit_booking.sql new file mode 100644 index 0000000..37d7807 --- /dev/null +++ b/test/edit_booking.sql @@ -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; diff --git a/verify/add_booking_from_payment.sql b/verify/add_booking_from_payment.sql new file mode 100644 index 0000000..d95260d --- /dev/null +++ b/verify/add_booking_from_payment.sql @@ -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; diff --git a/verify/booking__payment_fields.sql b/verify/booking__payment_fields.sql new file mode 100644 index 0000000..6f538db --- /dev/null +++ b/verify/booking__payment_fields.sql @@ -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; diff --git a/verify/booking_option.sql b/verify/booking_option.sql new file mode 100644 index 0000000..717bb48 --- /dev/null +++ b/verify/booking_option.sql @@ -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; diff --git a/verify/edit_booking.sql b/verify/edit_booking.sql new file mode 100644 index 0000000..7283111 --- /dev/null +++ b/verify/edit_booking.sql @@ -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; diff --git a/web/templates/admin/booking/fields.gohtml b/web/templates/admin/booking/fields.gohtml index e6f4d2c..388aa03 100644 --- a/web/templates/admin/booking/fields.gohtml +++ b/web/templates/admin/booking/fields.gohtml @@ -15,7 +15,7 @@ data-hx-get="/admin/bookings/new" data-hx-trigger="change" {{ template "error-attrs" . }} > - + {{ template "list-options" . }}
{{ template "error-message" . }} @@ -196,9 +196,8 @@ {{- end }} {{ with .Country -}}