Add payment relation and use it to compute the booking’s cart
I had to add the payment concept separate from the booking, unlike other eCommerce solutions that subsume the two into a single “order”, like WooCommerce, because bookings should be done in a separate Camper instance that will sync to the public instance, but the payment is done by the public instance. There will be a queue or something between the public and the private instance to pass along the booking information once the payment is complete, but the public instance still needs to keep track of payments without creating bookings. To compute the total for that payment i had to do the same as was doing until now for the cart. To prevent duplications, or having functions with complex return types, i now create a “draft” payment while the user is filling in the form, and compute the cart there; from Go i only have to retrieve the data from the relation, that simplifies the work, actually. Since the payment is computed way before customers enter their details, i can not have that data in the same payment relation, unless i allow NULL values. Allowing NULL values means that i can create a payment without customer, thus i moved all customer details to a separate relation. It still allows payment without customer, but at least there are no NULL values. Draft payments should be removed after a time, but i believe this needs to be done in a cronjob or similar, not in the Go application. To update the same payment while filling the same booking form, i now have a hidden field with the payment slug. A competent developer would have used a cookie or something like that; i am not competent.
This commit is contained in:
parent
d22fe39c80
commit
e4636592c5
|
@ -0,0 +1,33 @@
|
|||
-- Deploy camper:available_payment_status to pg
|
||||
-- requires: payment_status
|
||||
-- requires: payment_status_i18n
|
||||
|
||||
begin;
|
||||
|
||||
insert into camper.payment_status (payment_status, name)
|
||||
values ('draft', 'Draft')
|
||||
, ('pending', 'Pending')
|
||||
, ('failed', 'Failed')
|
||||
, ('completed', 'Completed')
|
||||
, ('refunded', 'Refunded')
|
||||
;
|
||||
|
||||
insert into camper.payment_status_i18n (payment_status, lang_tag, name)
|
||||
values ('draft', 'ca', 'Esborrany')
|
||||
, ('pending', 'ca', 'Pendent')
|
||||
, ('failed', 'ca', 'No realitzat')
|
||||
, ('completed', 'ca', 'Completat')
|
||||
, ('refunded', 'ca', 'Reemborsat')
|
||||
, ('draft', 'es', 'Borrador')
|
||||
, ('pending', 'es', 'Pendiente')
|
||||
, ('failed', 'es', 'Fallido')
|
||||
, ('completed', 'es', 'Completado')
|
||||
, ('refunded', 'es', 'Reembolsado')
|
||||
, ('draft', 'fr', 'Brouillon')
|
||||
, ('pending', 'fr', 'En attente')
|
||||
, ('failed', 'fr', 'Échouée')
|
||||
, ('completed', 'fr', 'Terminée')
|
||||
, ('refunded', 'fr', 'Remboursée')
|
||||
;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,158 @@
|
|||
-- Deploy camper:draft_payment to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: season_calendar
|
||||
-- requires: season
|
||||
-- requires: campsite_type
|
||||
-- requires: campsite_type_pet_cost
|
||||
-- requires: campsite_type_cost
|
||||
-- requires: campsite_type_option_cost
|
||||
-- requires: campsite_type_option
|
||||
-- requires: payment
|
||||
-- requires: payment_option
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create type option_units as (option_id integer, units integer);
|
||||
|
||||
create or replace function draft_payment(payment_slug uuid, arrival_date date, departure_date date, campsite_type_slug uuid, num_adults integer, num_teenagers integer, num_children integer, num_dogs integer, zone_preferences text, options option_units[]) returns uuid as
|
||||
$$
|
||||
declare
|
||||
pid integer;
|
||||
begin
|
||||
insert into payment (
|
||||
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
|
||||
, zone_preferences
|
||||
)
|
||||
select coalesce(payment_slug, gen_random_uuid())
|
||||
, company_id
|
||||
, campsite_type_id
|
||||
, arrival_date
|
||||
, departure_date
|
||||
, sum(cost.cost_per_night * ceiling((num_adults::numeric + num_teenagers::numeric + num_children::numeric) / max_campers::numeric)::integer)::integer
|
||||
, num_adults
|
||||
, sum(cost_per_adult * num_adults)::integer
|
||||
, num_teenagers
|
||||
, sum(cost_per_teenager * num_teenagers)::integer
|
||||
, num_children
|
||||
, sum(cost_per_child * num_children)::integer
|
||||
, num_dogs
|
||||
, sum(case when num_dogs > 0 then coalesce(pet.cost_per_night, 0) else 0 end)::integer
|
||||
, sum(tourist_tax * num_adults)::integer
|
||||
, 0
|
||||
, coalesce(zone_preferences, '')
|
||||
from generate_series(arrival_date, departure_date - 1, interval '1 day') as date(day)
|
||||
left join season_calendar on season_range @> date.day::date
|
||||
left join season using (season_id)
|
||||
left join campsite_type using (company_id)
|
||||
left join campsite_type_pet_cost as pet using (campsite_type_id)
|
||||
left join campsite_type_cost as cost using (campsite_type_id, season_id)
|
||||
left join company using (company_id)
|
||||
where campsite_type.slug = campsite_type_slug
|
||||
group by company_id
|
||||
, campsite_type_id
|
||||
on conflict (slug) do update
|
||||
set company_id = excluded.company_id
|
||||
, campsite_type_id = excluded.campsite_type_id
|
||||
, arrival_date = excluded.arrival_date
|
||||
, departure_date = excluded.departure_date
|
||||
, subtotal_nights = excluded.subtotal_nights
|
||||
, number_adults = excluded.number_adults
|
||||
, subtotal_adults = excluded.subtotal_adults
|
||||
, number_teenagers = excluded.number_teenagers
|
||||
, subtotal_teenagers = excluded.subtotal_teenagers
|
||||
, number_children = excluded.number_children
|
||||
, subtotal_children = excluded.subtotal_children
|
||||
, number_dogs = excluded.number_dogs
|
||||
, subtotal_dogs = excluded.subtotal_dogs
|
||||
, subtotal_tourist_tax = excluded.subtotal_tourist_tax
|
||||
, total = excluded.total
|
||||
, zone_preferences = excluded.zone_preferences
|
||||
, updated_at = current_timestamp
|
||||
returning payment_id, payment.slug
|
||||
into pid, payment_slug
|
||||
;
|
||||
|
||||
if array_length(coalesce(options, array[]::option_units[]), 1) > 0 then
|
||||
delete
|
||||
from payment_option
|
||||
where payment_id = pid
|
||||
and campsite_type_option_id not in (
|
||||
select campsite_type_option_id
|
||||
from unnest(options) as option(campsite_type_option_id, units)
|
||||
);
|
||||
|
||||
insert into payment_option (
|
||||
payment_id
|
||||
, campsite_type_option_id
|
||||
, units
|
||||
, subtotal
|
||||
)
|
||||
select pid
|
||||
, campsite_type_option_id
|
||||
, units
|
||||
, case when per_night then sum(cost * units)::integer else max(cost * units)::integer end
|
||||
from generate_series(arrival_date, departure_date - 1, interval '1 day') as date(day)
|
||||
join season_calendar on season_range @> date.day::date
|
||||
join campsite_type_option_cost using (season_id)
|
||||
join campsite_type_option using (campsite_type_option_id)
|
||||
join unnest(options) as option(campsite_type_option_id, units) using (campsite_type_option_id)
|
||||
group by campsite_type_option_id
|
||||
, units
|
||||
, per_night
|
||||
on conflict (payment_id, campsite_type_option_id) do update
|
||||
set units = excluded.units
|
||||
, subtotal = excluded.subtotal
|
||||
;
|
||||
|
||||
with option as (
|
||||
select sum(subtotal)::integer as subtotal
|
||||
from payment_option
|
||||
where payment_id = pid
|
||||
)
|
||||
update payment
|
||||
set total = subtotal_nights + subtotal_adults + subtotal_teenagers + subtotal_children + subtotal_dogs + subtotal_tourist_tax + coalesce(option.subtotal, 0)
|
||||
from option
|
||||
where payment_id = pid
|
||||
;
|
||||
else
|
||||
delete
|
||||
from payment_option
|
||||
where payment_id = pid;
|
||||
|
||||
update payment
|
||||
set total = subtotal_nights + subtotal_adults + subtotal_teenagers + subtotal_children + subtotal_dogs + subtotal_tourist_tax
|
||||
where payment_id = pid
|
||||
;
|
||||
end if;
|
||||
|
||||
|
||||
return payment_slug;
|
||||
end;
|
||||
$$
|
||||
language plpgsql
|
||||
;
|
||||
|
||||
revoke execute on function draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, option_units[]) from public;
|
||||
grant execute on function draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, option_units[]) to guest;
|
||||
grant execute on function draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, option_units[]) to employee;
|
||||
grant execute on function draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, option_units[]) to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,40 @@
|
|||
-- Deploy camper:payment to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: company
|
||||
-- requires: campsite_type
|
||||
-- requires: payment_status
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table payment (
|
||||
payment_id integer generated by default as identity primary key,
|
||||
company_id integer not null references company,
|
||||
slug uuid not null unique default gen_random_uuid(),
|
||||
campsite_type_id integer not null references campsite_type,
|
||||
arrival_date date not null,
|
||||
departure_date date not null constraint departure_after_arrival check (departure_date > arrival_date),
|
||||
subtotal_nights integer not null constraint subtotal_nights_not_negative check (subtotal_nights >= 0),
|
||||
number_adults integer not null constraint number_adults_positive check (number_adults > 0),
|
||||
subtotal_adults integer not null constraint subtotal_adults_not_negative check (subtotal_adults >= 0),
|
||||
number_teenagers integer not null constraint number_teenagers_not_negative check (number_teenagers >= 0),
|
||||
subtotal_teenagers integer not null constraint subtotal_teenagers_not_negative check (subtotal_teenagers >= 0),
|
||||
number_children integer not null constraint number_children_not_negative check (number_children >= 0),
|
||||
subtotal_children integer not null constraint subtotal_children_not_negative check (subtotal_children >= 0),
|
||||
number_dogs integer not null constraint number_dogs_not_negative check (number_dogs >= 0),
|
||||
subtotal_dogs integer not null constraint subtotal_dogs_not_negative check (subtotal_dogs >= 0),
|
||||
subtotal_tourist_tax integer not null constraint subtotal_tourist_tax_not_negative check (subtotal_tourist_tax >= 0),
|
||||
total integer not null constraint total_not_negative check (total >= 0),
|
||||
zone_preferences text not null,
|
||||
payment_status text not null default 'draft' references payment_status,
|
||||
created_at timestamp with time zone not null default current_timestamp,
|
||||
updated_at timestamp with time zone not null default current_timestamp
|
||||
);
|
||||
|
||||
grant select, insert, update on table payment to guest;
|
||||
grant select, insert, update on table payment to employee;
|
||||
grant select, insert, update, delete on table payment to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,29 @@
|
|||
-- Deploy camper:payment_customer to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: payment
|
||||
-- requires: country
|
||||
-- requires: country_code
|
||||
-- requires: extension_pg_libphonenumber
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table payment_customer (
|
||||
payment_id integer not null primary key references payment,
|
||||
full_name text not null,
|
||||
address text not null,
|
||||
postal_code text not null,
|
||||
city text not null,
|
||||
country_code country_code not null references country,
|
||||
email email not null,
|
||||
phone packed_phone_number not null,
|
||||
acsi_card boolean not null
|
||||
);
|
||||
|
||||
grant select, insert on table payment_customer to guest;
|
||||
grant select, insert, update on table payment_customer to employee;
|
||||
grant select, insert, update, delete on table payment_customer to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,23 @@
|
|||
-- Deploy camper:payment_option to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: payment
|
||||
-- requires: campsite_type_option
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table payment_option (
|
||||
payment_id integer not null references payment,
|
||||
campsite_type_option_id integer not null references campsite_type_option,
|
||||
units integer not null constraint units_positive check (units > 0),
|
||||
subtotal integer not null constraint subtotal_not_negative check (subtotal >= 0),
|
||||
primary key (payment_id, campsite_type_option_id)
|
||||
);
|
||||
|
||||
grant select, insert, update, delete on table payment_option to guest;
|
||||
grant select, insert, update, delete on table payment_option to employee;
|
||||
grant select, insert, update, delete on table payment_option to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,17 @@
|
|||
-- Deploy camper:payment_status to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table payment_status (
|
||||
payment_status text not null primary key,
|
||||
name text not null
|
||||
);
|
||||
|
||||
grant select on table payment_status to employee;
|
||||
grant select on table payment_status to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,21 @@
|
|||
-- Deploy camper:payment_status_i18n to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: payment_status
|
||||
-- requires: language
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table payment_status_i18n (
|
||||
payment_status text not null references payment_status,
|
||||
lang_tag text not null references language,
|
||||
name text not null,
|
||||
primary key (payment_status, lang_tag)
|
||||
);
|
||||
|
||||
grant select on table payment_status_i18n to employee;
|
||||
grant select on table payment_status_i18n to admin;
|
||||
|
||||
commit;
|
|
@ -5,8 +5,6 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v4"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
)
|
||||
|
@ -61,75 +59,64 @@ func newBookingCart(ctx context.Context, conn *database.Conn, f *bookingForm, ca
|
|||
return cart, nil
|
||||
}
|
||||
}
|
||||
zonePreferences := ""
|
||||
if f.Options != nil && f.Options.ZonePreferences != nil {
|
||||
zonePreferences = f.Options.ZonePreferences.Val
|
||||
}
|
||||
|
||||
optionMap := make(map[int]*campsiteTypeOption)
|
||||
var typeOptions []*campsiteTypeOption
|
||||
if f.Options != nil {
|
||||
typeOptions = f.Options.Options
|
||||
}
|
||||
optionIDs := make([]int, 0, len(typeOptions))
|
||||
optionUnits := make([]int, 0, len(typeOptions))
|
||||
optionUnits := make([]*database.OptionUnits, 0, len(typeOptions))
|
||||
for _, option := range typeOptions {
|
||||
units, _ := strconv.Atoi(option.Input.Val)
|
||||
if units < 1 {
|
||||
continue
|
||||
}
|
||||
optionMap[option.ID] = option
|
||||
optionIDs = append(optionIDs, option.ID)
|
||||
optionUnits = append(optionUnits, units)
|
||||
optionUnits = append(optionUnits, &database.OptionUnits{
|
||||
OptionID: option.ID,
|
||||
Units: units,
|
||||
})
|
||||
}
|
||||
|
||||
row := conn.QueryRow(ctx, `
|
||||
with per_person as (
|
||||
select count(*) as num_nights
|
||||
, sum(cost.cost_per_night * ceiling(($4::numeric + $5::numeric + $6::numeric) / max_campers::numeric)::integer)::integer as nights
|
||||
, sum(cost_per_adult * $4)::integer as adults
|
||||
, sum(cost_per_teenager * $5)::integer as teenagers
|
||||
, sum(cost_per_child * $6)::integer as children
|
||||
, sum(case when $7 > 0 then coalesce(pet.cost_per_night, 0) else 0 end)::integer as dogs
|
||||
, sum(tourist_tax * $4)::integer as tourist_tax
|
||||
, max(decimal_digits) as decimal_digits
|
||||
from generate_series($1, $2, interval '1 day') as date(day)
|
||||
left join season_calendar on season_range @> date.day::date
|
||||
left join season using (season_id)
|
||||
left join campsite_type using (company_id)
|
||||
left join campsite_type_pet_cost as pet using (campsite_type_id)
|
||||
left join campsite_type_cost as cost using (campsite_type_id, season_id)
|
||||
left join company using (company_id)
|
||||
left join currency using (currency_code)
|
||||
where campsite_type.slug = $3
|
||||
), per_option as (
|
||||
select campsite_type_option_id
|
||||
, case when per_night then sum(cost * units)::integer else max(cost * units)::integer end as option_cost
|
||||
from generate_series($1, $2, interval '1 day') as date(day)
|
||||
join season_calendar on season_range @> date.day::date
|
||||
join campsite_type_option_cost using (season_id)
|
||||
join campsite_type_option using (campsite_type_option_id)
|
||||
join unnest($8::integer[], $9::integer[]) as option_units(campsite_type_option_id, units) using (campsite_type_option_id)
|
||||
group by campsite_type_option_id
|
||||
, per_night
|
||||
union all select -1, 0
|
||||
paymentSlug, err := conn.DraftPayment(
|
||||
ctx,
|
||||
f.PaymentSlug.Val,
|
||||
arrivalDate,
|
||||
departureDate,
|
||||
campsiteType,
|
||||
numAdults,
|
||||
numTeenagers,
|
||||
numChildren,
|
||||
numDogs,
|
||||
zonePreferences,
|
||||
optionUnits,
|
||||
)
|
||||
select num_nights
|
||||
, coalesce(to_price(nights, decimal_digits), '')
|
||||
, coalesce(to_price(adults, decimal_digits), '')
|
||||
, coalesce(to_price(teenagers, decimal_digits), '')
|
||||
, coalesce(to_price(children, decimal_digits), '')
|
||||
, coalesce(to_price(dogs, decimal_digits), '')
|
||||
, coalesce(to_price(tourist_tax, decimal_digits), '')
|
||||
, coalesce(to_price(nights + adults + teenagers + children + tourist_tax + sum(option_cost)::integer, decimal_digits), '')
|
||||
, array_agg((campsite_type_option_id, to_price(option_cost, decimal_digits)))
|
||||
from per_person, per_option
|
||||
group by num_nights
|
||||
, nights
|
||||
, adults
|
||||
, teenagers
|
||||
, children
|
||||
, dogs
|
||||
, tourist_tax
|
||||
, decimal_digits
|
||||
`, pgx.QueryResultFormats{pgx.BinaryFormatCode}, arrivalDate, departureDate.AddDate(0, 0, -1), campsiteType, numAdults, numTeenagers, numChildren, numDogs, optionIDs, optionUnits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.PaymentSlug.Val = paymentSlug
|
||||
|
||||
row := conn.QueryRow(ctx, `
|
||||
select payment_id
|
||||
, departure_date - arrival_date
|
||||
, to_price(subtotal_nights, decimal_digits)
|
||||
, to_price(subtotal_adults, decimal_digits)
|
||||
, to_price(subtotal_teenagers, decimal_digits)
|
||||
, to_price(subtotal_children, decimal_digits)
|
||||
, to_price(subtotal_dogs, decimal_digits)
|
||||
, to_price(subtotal_tourist_tax, decimal_digits)
|
||||
, to_price(total, decimal_digits)
|
||||
from payment
|
||||
join company using (company_id)
|
||||
join currency using (currency_code)
|
||||
where payment.slug = $1
|
||||
`, paymentSlug)
|
||||
|
||||
var paymentID int
|
||||
var numNights int
|
||||
var nights string
|
||||
var adults string
|
||||
|
@ -138,8 +125,7 @@ func newBookingCart(ctx context.Context, conn *database.Conn, f *bookingForm, ca
|
|||
var dogs string
|
||||
var touristTax string
|
||||
var total string
|
||||
var optionPrices database.RecordArray
|
||||
if err = row.Scan(&numNights, &nights, &adults, &teenagers, &children, &dogs, &touristTax, &total, &optionPrices); err != nil {
|
||||
if err = row.Scan(&paymentID, &numNights, &nights, &adults, &teenagers, &children, &dogs, &touristTax, &total); err != nil {
|
||||
if database.ErrorIsNotFound(err) {
|
||||
return cart, nil
|
||||
}
|
||||
|
@ -161,26 +147,42 @@ func newBookingCart(ctx context.Context, conn *database.Conn, f *bookingForm, ca
|
|||
maybeAddLine(numChildren, children, locale.PgettextNoop("Child", "cart"))
|
||||
maybeAddLine(numDogs, dogs, locale.PgettextNoop("Dog", "cart"))
|
||||
|
||||
for _, el := range optionPrices.Elements {
|
||||
optionID := el.Fields[0].Get()
|
||||
if optionID == nil {
|
||||
continue
|
||||
rows, err := conn.Query(ctx, `
|
||||
select campsite_type_option_id
|
||||
, units
|
||||
, to_price(subtotal, decimal_digits)
|
||||
from payment_option
|
||||
join payment using (payment_id)
|
||||
join company using (company_id)
|
||||
join currency using (currency_code)
|
||||
where payment_id = $1
|
||||
`, paymentID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
subtotal := el.Fields[1].Get()
|
||||
if subtotal == nil {
|
||||
continue
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var optionID int
|
||||
var units int
|
||||
var subtotal string
|
||||
err = rows.Scan(&optionID, &units, &subtotal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
option := optionMap[int(optionID.(int32))]
|
||||
option := optionMap[optionID]
|
||||
if option == nil {
|
||||
continue
|
||||
}
|
||||
units, _ := strconv.Atoi(option.Input.Val)
|
||||
maybeAddLine(units, subtotal.(string), option.Label)
|
||||
maybeAddLine(units, subtotal, option.Label)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
|
||||
maybeAddLine(numAdults, touristTax, locale.PgettextNoop("Tourist tax", "cart"))
|
||||
|
||||
if total != "" {
|
||||
if total != "0.0" {
|
||||
cart.Total = total
|
||||
cart.Enabled = f.Guests.Error == nil
|
||||
}
|
||||
|
|
|
@ -141,6 +141,7 @@ func (p *publicPage) MustRender(w http.ResponseWriter, r *http.Request, user *au
|
|||
|
||||
type bookingForm struct {
|
||||
CampsiteType *form.Select
|
||||
PaymentSlug *form.Input
|
||||
Dates *DateFields
|
||||
Guests *bookingGuestFields
|
||||
Options *bookingOptionFields
|
||||
|
@ -208,8 +209,12 @@ func newBookingForm(r *http.Request, company *auth.Company, conn *database.Conn,
|
|||
Name: "campsite_type",
|
||||
Options: form.MustGetOptions(r.Context(), conn, "select type.slug, coalesce(i18n.name, type.name) as l10n_name from campsite_type as type left join campsite_type_i18n as i18n on type.campsite_type_id = i18n.campsite_type_id and i18n.lang_tag = $1 where company_id = $2 and active order by position, l10n_name", l.Language, company.ID),
|
||||
},
|
||||
PaymentSlug: &form.Input{
|
||||
Name: "payment_slug",
|
||||
},
|
||||
}
|
||||
f.CampsiteType.FillValue(r)
|
||||
f.PaymentSlug.FillValue(r)
|
||||
campsiteType := f.CampsiteType.String()
|
||||
if campsiteType == "" {
|
||||
return f, nil
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
"github.com/jackc/pgtype"
|
||||
)
|
||||
|
||||
type OptionUnits struct {
|
||||
OptionID int
|
||||
Units int
|
||||
}
|
||||
|
||||
func (src OptionUnits) EncodeBinary(ci *pgtype.ConnInfo, dst []byte) ([]byte, error) {
|
||||
typeName := OptionUnitsTypeName
|
||||
dt, ok := ci.DataTypeForName(typeName)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
||||
}
|
||||
values := []interface{}{
|
||||
src.OptionID,
|
||||
src.Units,
|
||||
}
|
||||
ct := pgtype.NewValue(dt.Value).(*pgtype.CompositeType)
|
||||
if err := ct.Set(values); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ct.EncodeBinary(ci, dst)
|
||||
}
|
||||
|
||||
type OptionUnitsArray []*OptionUnits
|
||||
|
||||
func (src OptionUnitsArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
||||
typeName := OptionUnitsTypeName
|
||||
dt, ok := ci.DataTypeForName(typeName)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
||||
}
|
||||
|
||||
arrayHeader := pgtype.ArrayHeader{
|
||||
ElementOID: int32(dt.OID),
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: int32(len(src)), LowerBound: 1}},
|
||||
}
|
||||
buf = arrayHeader.EncodeBinary(ci, buf)
|
||||
for _, optionUnits := range src {
|
||||
sp := len(buf)
|
||||
buf = pgio.AppendInt32(buf, -1)
|
||||
|
||||
elemBuf, err := optionUnits.EncodeBinary(ci, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if elemBuf != nil {
|
||||
buf = elemBuf
|
||||
pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
|
||||
}
|
||||
}
|
||||
return buf, nil
|
||||
}
|
|
@ -7,6 +7,7 @@ package database
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
@ -348,3 +349,11 @@ func (tx *Tx) TranslateHome(ctx context.Context, companyID int, langTag language
|
|||
_, err := tx.Exec(ctx, "select translate_home($1, $2, $3)", companyID, langTag, slogan)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Conn) DraftPayment(ctx context.Context, paymentSlug string, arrivalDate time.Time, departureDate time.Time, campsiteTypeSlug string, numAdults int, numTeenagers int, numChildren int, numDogs int, zonePreferences string, options OptionUnitsArray) (string, error) {
|
||||
var paymentSlugParam *string
|
||||
if paymentSlug != "" {
|
||||
paymentSlugParam = &paymentSlug
|
||||
}
|
||||
return c.GetText(ctx, "select draft_payment($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", paymentSlugParam, arrivalDate, departureDate, campsiteTypeSlug, numAdults, numTeenagers, numChildren, numDogs, zonePreferences, options)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
const (
|
||||
RedsysRequestTypeName = "redsys_request"
|
||||
RedsysSignedRequestTypeName = "redsys_signed_request"
|
||||
OptionUnitsTypeName = "option_units"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -84,6 +85,21 @@ func registerConnectionTypes(ctx context.Context, conn *pgx.Conn) error {
|
|||
return err
|
||||
}
|
||||
|
||||
optionUnitsType, err := pgtype.NewCompositeType(
|
||||
OptionUnitsTypeName,
|
||||
[]pgtype.CompositeTypeField{
|
||||
{"option_id", pgtype.Int4OID},
|
||||
{"units", pgtype.Int4OID},
|
||||
},
|
||||
conn.ConnInfo(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = registerType(ctx, conn, optionUnitsType, optionUnitsType.TypeName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
138
po/ca.po
138
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-02-11 22:01+0100\n"
|
||||
"POT-Creation-Date: 2024-02-12 05:10+0100\n"
|
||||
"PO-Revision-Date: 2024-02-06 10:04+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||
|
@ -155,7 +155,7 @@ msgid "Discover"
|
|||
msgstr "Descobreix"
|
||||
|
||||
#: web/templates/public/campsite/type.gohtml:49
|
||||
#: web/templates/public/booking/fields.gohtml:243
|
||||
#: web/templates/public/booking/fields.gohtml:245
|
||||
msgctxt "action"
|
||||
msgid "Book"
|
||||
msgstr "Reserva"
|
||||
|
@ -278,13 +278,13 @@ msgid "Sun"
|
|||
msgstr "dg"
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:4
|
||||
#: web/templates/public/booking/fields.gohtml:26
|
||||
#: web/templates/public/booking/fields.gohtml:28
|
||||
msgctxt "input"
|
||||
msgid "Arrival date"
|
||||
msgstr "Data d’arribada"
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:15
|
||||
#: web/templates/public/booking/fields.gohtml:37
|
||||
#: web/templates/public/booking/fields.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "Departure date"
|
||||
msgstr "Data de sortida"
|
||||
|
@ -541,117 +541,117 @@ msgstr "Obertura"
|
|||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Número\">Núm.</abbr> <abbr title=\"Registre de Turisme de Catalunya\">RTC</abbr> %s"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:13
|
||||
#: web/templates/public/booking/fields.gohtml:15
|
||||
msgctxt "title"
|
||||
msgid "Accommodation"
|
||||
msgstr "Allotjaments"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:23
|
||||
#: web/templates/public/booking/fields.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Booking Period"
|
||||
msgstr "Període de reserva"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:50
|
||||
#: web/templates/public/booking/fields.gohtml:52
|
||||
msgctxt "title"
|
||||
msgid "Guests"
|
||||
msgstr "Hostes"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:54
|
||||
#: web/templates/public/booking/fields.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Adults aged 17 or older"
|
||||
msgstr "Adults de 17 anys o més"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:65
|
||||
#: web/templates/public/booking/fields.gohtml:67
|
||||
msgctxt "input"
|
||||
msgid "Teenagers from 11 to 16 years old"
|
||||
msgstr "Adolescents d’entre 11 i 16 anys"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:76
|
||||
#: web/templates/public/booking/fields.gohtml:78
|
||||
msgctxt "input"
|
||||
msgid "Children from 2 to 10 years old"
|
||||
msgstr "Nens d’entre 2 i 10 anys)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:86
|
||||
#: web/templates/public/booking/fields.gohtml:88
|
||||
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
|
||||
msgstr "Nota: S’han afegit més allotjaments a la reserva degut a la capacitat de cadascuna, però <strong>no</strong> es garanteix que estiguin de costat."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:94
|
||||
#: web/templates/public/booking/fields.gohtml:96
|
||||
msgctxt "input"
|
||||
msgid "Dogs"
|
||||
msgstr "Gossos"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:103
|
||||
#: web/templates/public/booking/fields.gohtml:105
|
||||
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
|
||||
msgstr "Nota: A aquest allotjament <strong>no</strong> s’hi permeten gossos."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:113
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
msgctxt "input"
|
||||
msgid "Area preferences (optional)"
|
||||
msgstr "Preferències d’àrea (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
#: web/templates/public/booking/fields.gohtml:117
|
||||
msgid "Campground map"
|
||||
msgstr "Mapa del càmping"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:138
|
||||
#: web/templates/public/booking/fields.gohtml:140
|
||||
msgctxt "title"
|
||||
msgid "Customer Details"
|
||||
msgstr "Detalls del client"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:141
|
||||
#: web/templates/public/booking/fields.gohtml:143
|
||||
msgctxt "input"
|
||||
msgid "Full name"
|
||||
msgstr "Nom i cognoms"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:150
|
||||
#: web/templates/public/booking/fields.gohtml:152
|
||||
msgctxt "input"
|
||||
msgid "Address (optional)"
|
||||
msgstr "Adreça (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:159
|
||||
#: web/templates/public/booking/fields.gohtml:161
|
||||
msgctxt "input"
|
||||
msgid "Postcode (optional)"
|
||||
msgstr "Codi postal (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:168
|
||||
#: web/templates/public/booking/fields.gohtml:170
|
||||
msgctxt "input"
|
||||
msgid "Town or village (optional)"
|
||||
msgstr "Població (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:177
|
||||
#: web/templates/public/booking/fields.gohtml:179
|
||||
#: web/templates/admin/taxDetails.gohtml:101
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:180
|
||||
#: web/templates/public/booking/fields.gohtml:182
|
||||
msgid "Choose a country"
|
||||
msgstr "Esculli un país"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:188
|
||||
#: web/templates/public/booking/fields.gohtml:190
|
||||
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
|
||||
#: web/templates/admin/taxDetails.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Email"
|
||||
msgstr "Correu-e"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:197
|
||||
#: web/templates/public/booking/fields.gohtml:199
|
||||
#: web/templates/admin/taxDetails.gohtml:45
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Telèfon"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:208
|
||||
#: web/templates/public/booking/fields.gohtml:210
|
||||
msgctxt "input"
|
||||
msgid "ACSI card? (optional)"
|
||||
msgstr "Targeta ACSI? (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:215
|
||||
#: web/templates/public/booking/fields.gohtml:217
|
||||
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:232
|
||||
#: web/templates/public/booking/fields.gohtml:234
|
||||
msgctxt "cart"
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
@ -1990,12 +1990,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:217
|
||||
#: pkg/booking/public.go:577
|
||||
#: pkg/booking/public.go:583
|
||||
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:218
|
||||
#: pkg/booking/public.go:578
|
||||
#: pkg/booking/public.go:584
|
||||
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."
|
||||
|
||||
|
@ -2206,8 +2206,8 @@ msgctxt "header"
|
|||
msgid "Children (aged 2 to 10)"
|
||||
msgstr "Mainada (entre 2 i 10 anys)"
|
||||
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:218
|
||||
#: pkg/booking/public.go:270
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:224
|
||||
#: pkg/booking/public.go:276
|
||||
msgid "Selected campsite type is not valid."
|
||||
msgstr "El tipus d’allotjament escollit no és vàlid."
|
||||
|
||||
|
@ -2363,7 +2363,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:200 pkg/booking/public.go:564
|
||||
#: pkg/company/admin.go:200 pkg/booking/public.go:570
|
||||
msgid "Selected country is not valid."
|
||||
msgstr "El país escollit no és vàlid."
|
||||
|
||||
|
@ -2383,11 +2383,11 @@ 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:212 pkg/booking/public.go:580
|
||||
#: pkg/company/admin.go:212 pkg/booking/public.go:586
|
||||
msgid "Phone can not be empty."
|
||||
msgstr "No podeu deixar el telèfon en blanc."
|
||||
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:581
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:587
|
||||
msgid "This phone number is not valid."
|
||||
msgstr "Aquest número de telèfon no és vàlid."
|
||||
|
||||
|
@ -2407,7 +2407,7 @@ msgstr "No podeu deixar la província en blanc."
|
|||
msgid "Postal code can not be empty."
|
||||
msgstr "No podeu deixar el codi postal en blanc."
|
||||
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:573
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:579
|
||||
msgid "This postal code is not valid."
|
||||
msgstr "Aquest codi postal no és vàlid."
|
||||
|
||||
|
@ -2447,32 +2447,32 @@ 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:158
|
||||
#: pkg/booking/cart.go:144
|
||||
msgctxt "cart"
|
||||
msgid "Night"
|
||||
msgstr "Nit"
|
||||
|
||||
#: pkg/booking/cart.go:159
|
||||
#: pkg/booking/cart.go:145
|
||||
msgctxt "cart"
|
||||
msgid "Adult"
|
||||
msgstr "Adult"
|
||||
|
||||
#: pkg/booking/cart.go:160
|
||||
#: pkg/booking/cart.go:146
|
||||
msgctxt "cart"
|
||||
msgid "Teenager"
|
||||
msgstr "Adolescent"
|
||||
|
||||
#: pkg/booking/cart.go:161
|
||||
#: pkg/booking/cart.go:147
|
||||
msgctxt "cart"
|
||||
msgid "Child"
|
||||
msgstr "Nen"
|
||||
|
||||
#: pkg/booking/cart.go:162
|
||||
#: pkg/booking/cart.go:148
|
||||
msgctxt "cart"
|
||||
msgid "Dog"
|
||||
msgstr "Gos"
|
||||
|
||||
#: pkg/booking/cart.go:181
|
||||
#: pkg/booking/cart.go:183
|
||||
msgctxt "cart"
|
||||
msgid "Tourist tax"
|
||||
msgstr "Impost turístic"
|
||||
|
@ -2534,124 +2534,124 @@ msgstr "La integració escollida no és vàlida."
|
|||
msgid "The merchant key is not valid."
|
||||
msgstr "Aquesta clau del comerç no és vàlid."
|
||||
|
||||
#: pkg/booking/public.go:319 pkg/booking/public.go:348
|
||||
#: pkg/booking/public.go:325 pkg/booking/public.go:354
|
||||
msgid "Arrival date must be a valid date."
|
||||
msgstr "La data d’arribada ha de ser una data vàlida."
|
||||
|
||||
#: pkg/booking/public.go:333 pkg/booking/public.go:355
|
||||
#: pkg/booking/public.go:339 pkg/booking/public.go:361
|
||||
msgid "Departure date must be a valid date."
|
||||
msgstr "La data de sortida ha de ser una data vàlida."
|
||||
|
||||
#: pkg/booking/public.go:347
|
||||
#: pkg/booking/public.go:353
|
||||
msgid "Arrival date can not be empty"
|
||||
msgstr "No podeu deixar la data d’arribada en blanc."
|
||||
|
||||
#: pkg/booking/public.go:349
|
||||
#: pkg/booking/public.go:355
|
||||
#, 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:350
|
||||
#: pkg/booking/public.go:356
|
||||
#, 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:354
|
||||
#: pkg/booking/public.go:360
|
||||
msgid "Departure date can not be empty"
|
||||
msgstr "No podeu deixar la data de sortida en blanc."
|
||||
|
||||
#: pkg/booking/public.go:356
|
||||
#: pkg/booking/public.go:362
|
||||
#, 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:357
|
||||
#: pkg/booking/public.go:363
|
||||
#, 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:399
|
||||
#: pkg/booking/public.go:405
|
||||
#, 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:419
|
||||
#: pkg/booking/public.go:425
|
||||
msgid "Number of adults can not be empty"
|
||||
msgstr "No podeu deixar el número d’adults en blanc."
|
||||
|
||||
#: pkg/booking/public.go:420
|
||||
#: pkg/booking/public.go:426
|
||||
msgid "Number of adults must be an integer."
|
||||
msgstr "El número d’adults ha de ser enter."
|
||||
|
||||
#: pkg/booking/public.go:421
|
||||
#: pkg/booking/public.go:427
|
||||
msgid "There must be at least one adult."
|
||||
msgstr "Hi ha d’haver com a mínim un adult."
|
||||
|
||||
#: pkg/booking/public.go:424
|
||||
#: pkg/booking/public.go:430
|
||||
msgid "Number of teenagers can not be empty"
|
||||
msgstr "No podeu deixar el número d’adolescents en blanc."
|
||||
|
||||
#: pkg/booking/public.go:425
|
||||
#: pkg/booking/public.go:431
|
||||
msgid "Number of teenagers must be an integer."
|
||||
msgstr "El número d’adolescents ha de ser enter."
|
||||
|
||||
#: pkg/booking/public.go:426
|
||||
#: pkg/booking/public.go:432
|
||||
msgid "Number of teenagers can not be negative."
|
||||
msgstr "El número d’adolescents no pot ser negatiu."
|
||||
|
||||
#: pkg/booking/public.go:429
|
||||
#: pkg/booking/public.go:435
|
||||
msgid "Number of children can not be empty"
|
||||
msgstr "No podeu deixar el número de nens en blanc."
|
||||
|
||||
#: pkg/booking/public.go:430
|
||||
#: pkg/booking/public.go:436
|
||||
msgid "Number of children must be an integer."
|
||||
msgstr "El número de nens ha de ser enter."
|
||||
|
||||
#: pkg/booking/public.go:431
|
||||
#: pkg/booking/public.go:437
|
||||
msgid "Number of children can not be negative."
|
||||
msgstr "El número de nens no pot ser negatiu."
|
||||
|
||||
#: pkg/booking/public.go:434
|
||||
#: pkg/booking/public.go:440
|
||||
msgid "Number of dogs can not be empty"
|
||||
msgstr "No podeu deixar el número de gossos en blanc."
|
||||
|
||||
#: pkg/booking/public.go:435
|
||||
#: pkg/booking/public.go:441
|
||||
msgid "Number of dogs must be an integer."
|
||||
msgstr "El número de gossos ha de ser enter."
|
||||
|
||||
#: pkg/booking/public.go:436
|
||||
#: pkg/booking/public.go:442
|
||||
msgid "Number of dogs can not be negative."
|
||||
msgstr "El número de gossos no pot ser negatiu."
|
||||
|
||||
#: pkg/booking/public.go:507
|
||||
#: pkg/booking/public.go:513
|
||||
#, c-format
|
||||
msgid "%s can not be empty"
|
||||
msgstr "No podeu deixar %s en blanc."
|
||||
|
||||
#: pkg/booking/public.go:508
|
||||
#: pkg/booking/public.go:514
|
||||
#, c-format
|
||||
msgid "%s must be an integer."
|
||||
msgstr "%s ha de ser un número enter."
|
||||
|
||||
#: pkg/booking/public.go:509
|
||||
#: pkg/booking/public.go:515
|
||||
#, 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:510
|
||||
#: pkg/booking/public.go:516
|
||||
#, 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:568
|
||||
#: pkg/booking/public.go:574
|
||||
msgid "Full name can not be empty."
|
||||
msgstr "No podeu deixar el nom i els cognoms en blanc."
|
||||
|
||||
#: pkg/booking/public.go:569
|
||||
#: pkg/booking/public.go:575
|
||||
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:586
|
||||
#: pkg/booking/public.go:592
|
||||
msgid "It is mandatory to agree to the reservation conditions."
|
||||
msgstr "És obligatori acceptar les condicions de reserves."
|
||||
|
||||
|
|
138
po/es.po
138
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-02-11 22:01+0100\n"
|
||||
"POT-Creation-Date: 2024-02-12 05:10+0100\n"
|
||||
"PO-Revision-Date: 2024-02-06 10:04+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||
|
@ -155,7 +155,7 @@ msgid "Discover"
|
|||
msgstr "Descubre"
|
||||
|
||||
#: web/templates/public/campsite/type.gohtml:49
|
||||
#: web/templates/public/booking/fields.gohtml:243
|
||||
#: web/templates/public/booking/fields.gohtml:245
|
||||
msgctxt "action"
|
||||
msgid "Book"
|
||||
msgstr "Reservar"
|
||||
|
@ -278,13 +278,13 @@ msgid "Sun"
|
|||
msgstr "do"
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:4
|
||||
#: web/templates/public/booking/fields.gohtml:26
|
||||
#: web/templates/public/booking/fields.gohtml:28
|
||||
msgctxt "input"
|
||||
msgid "Arrival date"
|
||||
msgstr "Fecha de llegada"
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:15
|
||||
#: web/templates/public/booking/fields.gohtml:37
|
||||
#: web/templates/public/booking/fields.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "Departure date"
|
||||
msgstr "Fecha de salida"
|
||||
|
@ -541,117 +541,117 @@ msgstr "Apertura"
|
|||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Número\">Nº</abbr> <abbr title=\"Registro de Turismo de Cataluña\">RTC</abbr> %s"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:13
|
||||
#: web/templates/public/booking/fields.gohtml:15
|
||||
msgctxt "title"
|
||||
msgid "Accommodation"
|
||||
msgstr "Alojamientos"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:23
|
||||
#: web/templates/public/booking/fields.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Booking Period"
|
||||
msgstr "Periodo de reserva"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:50
|
||||
#: web/templates/public/booking/fields.gohtml:52
|
||||
msgctxt "title"
|
||||
msgid "Guests"
|
||||
msgstr "Huéspedes"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:54
|
||||
#: web/templates/public/booking/fields.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Adults aged 17 or older"
|
||||
msgstr "Adultos de 17 años o más"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:65
|
||||
#: web/templates/public/booking/fields.gohtml:67
|
||||
msgctxt "input"
|
||||
msgid "Teenagers from 11 to 16 years old"
|
||||
msgstr "Adolescentes de 11 a 16 años"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:76
|
||||
#: web/templates/public/booking/fields.gohtml:78
|
||||
msgctxt "input"
|
||||
msgid "Children from 2 to 10 years old"
|
||||
msgstr "Niños de 2 a 10 años"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:86
|
||||
#: web/templates/public/booking/fields.gohtml:88
|
||||
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
|
||||
msgstr "Nota: Se han añadido alojamientos a la reserva debido a la capacidad de cada una, pero <strong>no</strong> se garantiza que estén de lado."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:94
|
||||
#: web/templates/public/booking/fields.gohtml:96
|
||||
msgctxt "input"
|
||||
msgid "Dogs"
|
||||
msgstr "Perros"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:103
|
||||
#: web/templates/public/booking/fields.gohtml:105
|
||||
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
|
||||
msgstr "Nota: En este alojamiento <strong>no</strong> se permiten perros."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:113
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
msgctxt "input"
|
||||
msgid "Area preferences (optional)"
|
||||
msgstr "Preferencias de área (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
#: web/templates/public/booking/fields.gohtml:117
|
||||
msgid "Campground map"
|
||||
msgstr "Mapa del camping"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:138
|
||||
#: web/templates/public/booking/fields.gohtml:140
|
||||
msgctxt "title"
|
||||
msgid "Customer Details"
|
||||
msgstr "Detalles del cliente"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:141
|
||||
#: web/templates/public/booking/fields.gohtml:143
|
||||
msgctxt "input"
|
||||
msgid "Full name"
|
||||
msgstr "Nombre y apellidos"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:150
|
||||
#: web/templates/public/booking/fields.gohtml:152
|
||||
msgctxt "input"
|
||||
msgid "Address (optional)"
|
||||
msgstr "Dirección (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:159
|
||||
#: web/templates/public/booking/fields.gohtml:161
|
||||
msgctxt "input"
|
||||
msgid "Postcode (optional)"
|
||||
msgstr "Código postal (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:168
|
||||
#: web/templates/public/booking/fields.gohtml:170
|
||||
msgctxt "input"
|
||||
msgid "Town or village (optional)"
|
||||
msgstr "Población (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:177
|
||||
#: web/templates/public/booking/fields.gohtml:179
|
||||
#: web/templates/admin/taxDetails.gohtml:101
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:180
|
||||
#: web/templates/public/booking/fields.gohtml:182
|
||||
msgid "Choose a country"
|
||||
msgstr "Escoja un país"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:188
|
||||
#: web/templates/public/booking/fields.gohtml:190
|
||||
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
|
||||
#: web/templates/admin/taxDetails.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Email"
|
||||
msgstr "Correo-e"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:197
|
||||
#: web/templates/public/booking/fields.gohtml:199
|
||||
#: web/templates/admin/taxDetails.gohtml:45
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Teléfono"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:208
|
||||
#: web/templates/public/booking/fields.gohtml:210
|
||||
msgctxt "input"
|
||||
msgid "ACSI card? (optional)"
|
||||
msgstr "¿Tarjeta ACSI? (opcional)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:215
|
||||
#: web/templates/public/booking/fields.gohtml:217
|
||||
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:232
|
||||
#: web/templates/public/booking/fields.gohtml:234
|
||||
msgctxt "cart"
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
@ -1990,12 +1990,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:217
|
||||
#: pkg/booking/public.go:577
|
||||
#: pkg/booking/public.go:583
|
||||
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:218
|
||||
#: pkg/booking/public.go:578
|
||||
#: pkg/booking/public.go:584
|
||||
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."
|
||||
|
||||
|
@ -2206,8 +2206,8 @@ msgctxt "header"
|
|||
msgid "Children (aged 2 to 10)"
|
||||
msgstr "Niños (de 2 a 10 años)"
|
||||
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:218
|
||||
#: pkg/booking/public.go:270
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:224
|
||||
#: pkg/booking/public.go:276
|
||||
msgid "Selected campsite type is not valid."
|
||||
msgstr "El tipo de alojamiento escogido no es válido."
|
||||
|
||||
|
@ -2363,7 +2363,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:200 pkg/booking/public.go:564
|
||||
#: pkg/company/admin.go:200 pkg/booking/public.go:570
|
||||
msgid "Selected country is not valid."
|
||||
msgstr "El país escogido no es válido."
|
||||
|
||||
|
@ -2383,11 +2383,11 @@ 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:212 pkg/booking/public.go:580
|
||||
#: pkg/company/admin.go:212 pkg/booking/public.go:586
|
||||
msgid "Phone can not be empty."
|
||||
msgstr "No podéis dejar el teléfono en blanco."
|
||||
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:581
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:587
|
||||
msgid "This phone number is not valid."
|
||||
msgstr "Este teléfono no es válido."
|
||||
|
||||
|
@ -2407,7 +2407,7 @@ msgstr "No podéis dejar la provincia en blanco."
|
|||
msgid "Postal code can not be empty."
|
||||
msgstr "No podéis dejar el código postal en blanco."
|
||||
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:573
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:579
|
||||
msgid "This postal code is not valid."
|
||||
msgstr "Este código postal no es válido."
|
||||
|
||||
|
@ -2447,32 +2447,32 @@ 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:158
|
||||
#: pkg/booking/cart.go:144
|
||||
msgctxt "cart"
|
||||
msgid "Night"
|
||||
msgstr "Noche"
|
||||
|
||||
#: pkg/booking/cart.go:159
|
||||
#: pkg/booking/cart.go:145
|
||||
msgctxt "cart"
|
||||
msgid "Adult"
|
||||
msgstr "Adulto"
|
||||
|
||||
#: pkg/booking/cart.go:160
|
||||
#: pkg/booking/cart.go:146
|
||||
msgctxt "cart"
|
||||
msgid "Teenager"
|
||||
msgstr "Adolescente"
|
||||
|
||||
#: pkg/booking/cart.go:161
|
||||
#: pkg/booking/cart.go:147
|
||||
msgctxt "cart"
|
||||
msgid "Child"
|
||||
msgstr "Niño"
|
||||
|
||||
#: pkg/booking/cart.go:162
|
||||
#: pkg/booking/cart.go:148
|
||||
msgctxt "cart"
|
||||
msgid "Dog"
|
||||
msgstr "Perro"
|
||||
|
||||
#: pkg/booking/cart.go:181
|
||||
#: pkg/booking/cart.go:183
|
||||
msgctxt "cart"
|
||||
msgid "Tourist tax"
|
||||
msgstr "Impuesto turístico"
|
||||
|
@ -2534,124 +2534,124 @@ msgstr "La integración escogida no es válida."
|
|||
msgid "The merchant key is not valid."
|
||||
msgstr "Esta clave del comercio no es válida."
|
||||
|
||||
#: pkg/booking/public.go:319 pkg/booking/public.go:348
|
||||
#: pkg/booking/public.go:325 pkg/booking/public.go:354
|
||||
msgid "Arrival date must be a valid date."
|
||||
msgstr "La fecha de llegada tiene que ser una fecha válida."
|
||||
|
||||
#: pkg/booking/public.go:333 pkg/booking/public.go:355
|
||||
#: pkg/booking/public.go:339 pkg/booking/public.go:361
|
||||
msgid "Departure date must be a valid date."
|
||||
msgstr "La fecha de partida tiene que ser una fecha válida."
|
||||
|
||||
#: pkg/booking/public.go:347
|
||||
#: pkg/booking/public.go:353
|
||||
msgid "Arrival date can not be empty"
|
||||
msgstr "No podéis dejar la fecha de llegada en blanco."
|
||||
|
||||
#: pkg/booking/public.go:349
|
||||
#: pkg/booking/public.go:355
|
||||
#, 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:350
|
||||
#: pkg/booking/public.go:356
|
||||
#, 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:354
|
||||
#: pkg/booking/public.go:360
|
||||
msgid "Departure date can not be empty"
|
||||
msgstr "No podéis dejar la fecha de partida en blanco."
|
||||
|
||||
#: pkg/booking/public.go:356
|
||||
#: pkg/booking/public.go:362
|
||||
#, 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:357
|
||||
#: pkg/booking/public.go:363
|
||||
#, 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:399
|
||||
#: pkg/booking/public.go:405
|
||||
#, 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:419
|
||||
#: pkg/booking/public.go:425
|
||||
msgid "Number of adults can not be empty"
|
||||
msgstr "No podéis dejar el número de adultos blanco."
|
||||
|
||||
#: pkg/booking/public.go:420
|
||||
#: pkg/booking/public.go:426
|
||||
msgid "Number of adults must be an integer."
|
||||
msgstr "El número de adultos tiene que ser entero."
|
||||
|
||||
#: pkg/booking/public.go:421
|
||||
#: pkg/booking/public.go:427
|
||||
msgid "There must be at least one adult."
|
||||
msgstr "Tiene que haber como mínimo un adulto."
|
||||
|
||||
#: pkg/booking/public.go:424
|
||||
#: pkg/booking/public.go:430
|
||||
msgid "Number of teenagers can not be empty"
|
||||
msgstr "No podéis dejar el número de adolescentes en blanco."
|
||||
|
||||
#: pkg/booking/public.go:425
|
||||
#: pkg/booking/public.go:431
|
||||
msgid "Number of teenagers must be an integer."
|
||||
msgstr "El número de adolescentes tiene que ser entero."
|
||||
|
||||
#: pkg/booking/public.go:426
|
||||
#: pkg/booking/public.go:432
|
||||
msgid "Number of teenagers can not be negative."
|
||||
msgstr "El número de adolescentes no puede ser negativo."
|
||||
|
||||
#: pkg/booking/public.go:429
|
||||
#: pkg/booking/public.go:435
|
||||
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:430
|
||||
#: pkg/booking/public.go:436
|
||||
msgid "Number of children must be an integer."
|
||||
msgstr "El número de niños tiene que ser entero."
|
||||
|
||||
#: pkg/booking/public.go:431
|
||||
#: pkg/booking/public.go:437
|
||||
msgid "Number of children can not be negative."
|
||||
msgstr "El número de niños no puede ser negativo."
|
||||
|
||||
#: pkg/booking/public.go:434
|
||||
#: pkg/booking/public.go:440
|
||||
msgid "Number of dogs can not be empty"
|
||||
msgstr "No podéis dejar el número de perros en blanco."
|
||||
|
||||
#: pkg/booking/public.go:435
|
||||
#: pkg/booking/public.go:441
|
||||
msgid "Number of dogs must be an integer."
|
||||
msgstr "El número de perros tiene que ser entero."
|
||||
|
||||
#: pkg/booking/public.go:436
|
||||
#: pkg/booking/public.go:442
|
||||
msgid "Number of dogs can not be negative."
|
||||
msgstr "El número de perros no puede ser negativo."
|
||||
|
||||
#: pkg/booking/public.go:507
|
||||
#: pkg/booking/public.go:513
|
||||
#, c-format
|
||||
msgid "%s can not be empty"
|
||||
msgstr "No podéis dejar %s en blanco."
|
||||
|
||||
#: pkg/booking/public.go:508
|
||||
#: pkg/booking/public.go:514
|
||||
#, c-format
|
||||
msgid "%s must be an integer."
|
||||
msgstr "%s tiene que ser un número entero."
|
||||
|
||||
#: pkg/booking/public.go:509
|
||||
#: pkg/booking/public.go:515
|
||||
#, c-format
|
||||
msgid "%s must be %d or greater."
|
||||
msgstr "%s tiene que ser como mínimo %d."
|
||||
|
||||
#: pkg/booking/public.go:510
|
||||
#: pkg/booking/public.go:516
|
||||
#, c-format
|
||||
msgid "%s must be at most %d."
|
||||
msgstr "%s tiene que ser como máximo %d"
|
||||
|
||||
#: pkg/booking/public.go:568
|
||||
#: pkg/booking/public.go:574
|
||||
msgid "Full name can not be empty."
|
||||
msgstr "No podéis dejar el nombre y los apellidos en blanco."
|
||||
|
||||
#: pkg/booking/public.go:569
|
||||
#: pkg/booking/public.go:575
|
||||
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:586
|
||||
#: pkg/booking/public.go:592
|
||||
msgid "It is mandatory to agree to the reservation conditions."
|
||||
msgstr "Es obligatorio aceptar las condiciones de reserva."
|
||||
|
||||
|
|
138
po/fr.po
138
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-02-11 22:01+0100\n"
|
||||
"POT-Creation-Date: 2024-02-12 05:10+0100\n"
|
||||
"PO-Revision-Date: 2024-02-06 10:05+0100\n"
|
||||
"Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n"
|
||||
"Language-Team: French <traduc@traduc.org>\n"
|
||||
|
@ -155,7 +155,7 @@ msgid "Discover"
|
|||
msgstr "Découvrir"
|
||||
|
||||
#: web/templates/public/campsite/type.gohtml:49
|
||||
#: web/templates/public/booking/fields.gohtml:243
|
||||
#: web/templates/public/booking/fields.gohtml:245
|
||||
msgctxt "action"
|
||||
msgid "Book"
|
||||
msgstr "Réserver"
|
||||
|
@ -278,13 +278,13 @@ msgid "Sun"
|
|||
msgstr "Dim."
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:4
|
||||
#: web/templates/public/booking/fields.gohtml:26
|
||||
#: web/templates/public/booking/fields.gohtml:28
|
||||
msgctxt "input"
|
||||
msgid "Arrival date"
|
||||
msgstr "Date d’arrivée"
|
||||
|
||||
#: web/templates/public/campsite/dates.gohtml:15
|
||||
#: web/templates/public/booking/fields.gohtml:37
|
||||
#: web/templates/public/booking/fields.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "Departure date"
|
||||
msgstr "Date de depart"
|
||||
|
@ -541,117 +541,117 @@ msgstr "Ouverture"
|
|||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Registre du tourisme de Catalogne\"># RTC</abbr> %s"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:13
|
||||
#: web/templates/public/booking/fields.gohtml:15
|
||||
msgctxt "title"
|
||||
msgid "Accommodation"
|
||||
msgstr "Hébergement"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:23
|
||||
#: web/templates/public/booking/fields.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Booking Period"
|
||||
msgstr "Période de réservation"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:50
|
||||
#: web/templates/public/booking/fields.gohtml:52
|
||||
msgctxt "title"
|
||||
msgid "Guests"
|
||||
msgstr "Personnes logeant"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:54
|
||||
#: web/templates/public/booking/fields.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Adults aged 17 or older"
|
||||
msgstr "Adultes âgés 17 ans ou plus"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:65
|
||||
#: web/templates/public/booking/fields.gohtml:67
|
||||
msgctxt "input"
|
||||
msgid "Teenagers from 11 to 16 years old"
|
||||
msgstr "Adolescents de 11 à 16 ans"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:76
|
||||
#: web/templates/public/booking/fields.gohtml:78
|
||||
msgctxt "input"
|
||||
msgid "Children from 2 to 10 years old"
|
||||
msgstr "Enfants de 2 à 10 ans"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:86
|
||||
#: web/templates/public/booking/fields.gohtml:88
|
||||
msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we <strong>cannot</strong> guarantee that they will be next to each other."
|
||||
msgstr "Remarque : En raison de la capacité d’accueils, nous avons ajouté d’autres hébergements à la réservation, mais nous <strong>ne pouvons</strong> garantir qu’ils seront côte à côte."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:94
|
||||
#: web/templates/public/booking/fields.gohtml:96
|
||||
msgctxt "input"
|
||||
msgid "Dogs"
|
||||
msgstr "Chiens"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:103
|
||||
#: web/templates/public/booking/fields.gohtml:105
|
||||
msgid "Note: This accommodation does <strong>not</strong> allow dogs."
|
||||
msgstr "Remarque : Dans cet hébergement les chiens <strong>ne</strong> sont pas acceptés."
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:113
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
msgctxt "input"
|
||||
msgid "Area preferences (optional)"
|
||||
msgstr "Préférences de zone (facultatif)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:115
|
||||
#: web/templates/public/booking/fields.gohtml:117
|
||||
msgid "Campground map"
|
||||
msgstr "Plan du camping"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:138
|
||||
#: web/templates/public/booking/fields.gohtml:140
|
||||
msgctxt "title"
|
||||
msgid "Customer Details"
|
||||
msgstr "Détails du client"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:141
|
||||
#: web/templates/public/booking/fields.gohtml:143
|
||||
msgctxt "input"
|
||||
msgid "Full name"
|
||||
msgstr "Nom et prénom"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:150
|
||||
#: web/templates/public/booking/fields.gohtml:152
|
||||
msgctxt "input"
|
||||
msgid "Address (optional)"
|
||||
msgstr "Adresse (Facultatif)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:159
|
||||
#: web/templates/public/booking/fields.gohtml:161
|
||||
msgctxt "input"
|
||||
msgid "Postcode (optional)"
|
||||
msgstr "Code postal (Facultatif)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:168
|
||||
#: web/templates/public/booking/fields.gohtml:170
|
||||
msgctxt "input"
|
||||
msgid "Town or village (optional)"
|
||||
msgstr "Ville (Facultatif)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:177
|
||||
#: web/templates/public/booking/fields.gohtml:179
|
||||
#: web/templates/admin/taxDetails.gohtml:101
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "Pays"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:180
|
||||
#: web/templates/public/booking/fields.gohtml:182
|
||||
msgid "Choose a country"
|
||||
msgstr "Choisissez un pays"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:188
|
||||
#: web/templates/public/booking/fields.gohtml:190
|
||||
#: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38
|
||||
#: web/templates/admin/taxDetails.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:197
|
||||
#: web/templates/public/booking/fields.gohtml:199
|
||||
#: web/templates/admin/taxDetails.gohtml:45
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Téléphone"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:208
|
||||
#: web/templates/public/booking/fields.gohtml:210
|
||||
msgctxt "input"
|
||||
msgid "ACSI card? (optional)"
|
||||
msgstr "Carte ACSI ? (Facultatif)"
|
||||
|
||||
#: web/templates/public/booking/fields.gohtml:215
|
||||
#: web/templates/public/booking/fields.gohtml:217
|
||||
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:232
|
||||
#: web/templates/public/booking/fields.gohtml:234
|
||||
msgctxt "cart"
|
||||
msgid "Total"
|
||||
msgstr "Totale"
|
||||
|
@ -1990,12 +1990,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:217
|
||||
#: pkg/booking/public.go:577
|
||||
#: pkg/booking/public.go:583
|
||||
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:218
|
||||
#: pkg/booking/public.go:578
|
||||
#: pkg/booking/public.go:584
|
||||
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."
|
||||
|
||||
|
@ -2206,8 +2206,8 @@ msgctxt "header"
|
|||
msgid "Children (aged 2 to 10)"
|
||||
msgstr "Enfants (de 2 à 10 anys)"
|
||||
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:218
|
||||
#: pkg/booking/public.go:270
|
||||
#: pkg/campsite/admin.go:275 pkg/booking/public.go:224
|
||||
#: pkg/booking/public.go:276
|
||||
msgid "Selected campsite type is not valid."
|
||||
msgstr "Le type d’emplacement sélectionné n’est pas valide."
|
||||
|
||||
|
@ -2363,7 +2363,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:200 pkg/booking/public.go:564
|
||||
#: pkg/company/admin.go:200 pkg/booking/public.go:570
|
||||
msgid "Selected country is not valid."
|
||||
msgstr "Le pays sélectionné n’est pas valide."
|
||||
|
||||
|
@ -2383,11 +2383,11 @@ 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:212 pkg/booking/public.go:580
|
||||
#: pkg/company/admin.go:212 pkg/booking/public.go:586
|
||||
msgid "Phone can not be empty."
|
||||
msgstr "Le téléphone ne peut pas être vide."
|
||||
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:581
|
||||
#: pkg/company/admin.go:213 pkg/booking/public.go:587
|
||||
msgid "This phone number is not valid."
|
||||
msgstr "Ce numéro de téléphone n’est pas valide."
|
||||
|
||||
|
@ -2407,7 +2407,7 @@ msgstr "La province ne peut pas être vide."
|
|||
msgid "Postal code can not be empty."
|
||||
msgstr "Le code postal ne peut pas être vide."
|
||||
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:573
|
||||
#: pkg/company/admin.go:227 pkg/booking/public.go:579
|
||||
msgid "This postal code is not valid."
|
||||
msgstr "Ce code postal n’est pas valide."
|
||||
|
||||
|
@ -2447,32 +2447,32 @@ 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:158
|
||||
#: pkg/booking/cart.go:144
|
||||
msgctxt "cart"
|
||||
msgid "Night"
|
||||
msgstr "Nuit"
|
||||
|
||||
#: pkg/booking/cart.go:159
|
||||
#: pkg/booking/cart.go:145
|
||||
msgctxt "cart"
|
||||
msgid "Adult"
|
||||
msgstr "Adulte"
|
||||
|
||||
#: pkg/booking/cart.go:160
|
||||
#: pkg/booking/cart.go:146
|
||||
msgctxt "cart"
|
||||
msgid "Teenager"
|
||||
msgstr "Adolescent"
|
||||
|
||||
#: pkg/booking/cart.go:161
|
||||
#: pkg/booking/cart.go:147
|
||||
msgctxt "cart"
|
||||
msgid "Child"
|
||||
msgstr "Enfant"
|
||||
|
||||
#: pkg/booking/cart.go:162
|
||||
#: pkg/booking/cart.go:148
|
||||
msgctxt "cart"
|
||||
msgid "Dog"
|
||||
msgstr "Chien"
|
||||
|
||||
#: pkg/booking/cart.go:181
|
||||
#: pkg/booking/cart.go:183
|
||||
msgctxt "cart"
|
||||
msgid "Tourist tax"
|
||||
msgstr "Taxe touristique"
|
||||
|
@ -2534,124 +2534,124 @@ msgstr "L’intégration sélectionnée n’est pas valide."
|
|||
msgid "The merchant key is not valid."
|
||||
msgstr "La clé marchand n’est pas valide."
|
||||
|
||||
#: pkg/booking/public.go:319 pkg/booking/public.go:348
|
||||
#: pkg/booking/public.go:325 pkg/booking/public.go:354
|
||||
msgid "Arrival date must be a valid date."
|
||||
msgstr "La date d’arrivée doit être une date valide."
|
||||
|
||||
#: pkg/booking/public.go:333 pkg/booking/public.go:355
|
||||
#: pkg/booking/public.go:339 pkg/booking/public.go:361
|
||||
msgid "Departure date must be a valid date."
|
||||
msgstr "La date de départ doit être une date valide."
|
||||
|
||||
#: pkg/booking/public.go:347
|
||||
#: pkg/booking/public.go:353
|
||||
msgid "Arrival date can not be empty"
|
||||
msgstr "La date d’arrivée ne peut pas être vide"
|
||||
|
||||
#: pkg/booking/public.go:349
|
||||
#: pkg/booking/public.go:355
|
||||
#, 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:350
|
||||
#: pkg/booking/public.go:356
|
||||
#, 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:354
|
||||
#: pkg/booking/public.go:360
|
||||
msgid "Departure date can not be empty"
|
||||
msgstr "La date de départ ne peut pas être vide"
|
||||
|
||||
#: pkg/booking/public.go:356
|
||||
#: pkg/booking/public.go:362
|
||||
#, 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:357
|
||||
#: pkg/booking/public.go:363
|
||||
#, 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:399
|
||||
#: pkg/booking/public.go:405
|
||||
#, 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:419
|
||||
#: pkg/booking/public.go:425
|
||||
msgid "Number of adults can not be empty"
|
||||
msgstr "Le nombre d’adultes ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/public.go:420
|
||||
#: pkg/booking/public.go:426
|
||||
msgid "Number of adults must be an integer."
|
||||
msgstr "Le nombre d’adultes doit être un entier."
|
||||
|
||||
#: pkg/booking/public.go:421
|
||||
#: pkg/booking/public.go:427
|
||||
msgid "There must be at least one adult."
|
||||
msgstr "Il doit y avoir au moins un adulte."
|
||||
|
||||
#: pkg/booking/public.go:424
|
||||
#: pkg/booking/public.go:430
|
||||
msgid "Number of teenagers can not be empty"
|
||||
msgstr "Le nombre d’adolescents ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/public.go:425
|
||||
#: pkg/booking/public.go:431
|
||||
msgid "Number of teenagers must be an integer."
|
||||
msgstr "Le nombre d’adolescents doit être un entier."
|
||||
|
||||
#: pkg/booking/public.go:426
|
||||
#: pkg/booking/public.go:432
|
||||
msgid "Number of teenagers can not be negative."
|
||||
msgstr "Le nombre d’adolescents ne peut pas être négatif."
|
||||
|
||||
#: pkg/booking/public.go:429
|
||||
#: pkg/booking/public.go:435
|
||||
msgid "Number of children can not be empty"
|
||||
msgstr "Le nombre d’enfants ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/public.go:430
|
||||
#: pkg/booking/public.go:436
|
||||
msgid "Number of children must be an integer."
|
||||
msgstr "Le nombre d’enfants doit être un entier."
|
||||
|
||||
#: pkg/booking/public.go:431
|
||||
#: pkg/booking/public.go:437
|
||||
msgid "Number of children can not be negative."
|
||||
msgstr "Le nombre d’enfants ne peut pas être négatif."
|
||||
|
||||
#: pkg/booking/public.go:434
|
||||
#: pkg/booking/public.go:440
|
||||
msgid "Number of dogs can not be empty"
|
||||
msgstr "Le nombre de chiens ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/public.go:435
|
||||
#: pkg/booking/public.go:441
|
||||
msgid "Number of dogs must be an integer."
|
||||
msgstr "Le nombre de chiens nuits être un entier."
|
||||
|
||||
#: pkg/booking/public.go:436
|
||||
#: pkg/booking/public.go:442
|
||||
msgid "Number of dogs can not be negative."
|
||||
msgstr "Le nombre de chiens ne peut pas être négatif."
|
||||
|
||||
#: pkg/booking/public.go:507
|
||||
#: pkg/booking/public.go:513
|
||||
#, c-format
|
||||
msgid "%s can not be empty"
|
||||
msgstr "%s ne peut pas être vide"
|
||||
|
||||
#: pkg/booking/public.go:508
|
||||
#: pkg/booking/public.go:514
|
||||
#, c-format
|
||||
msgid "%s must be an integer."
|
||||
msgstr "%s doit être un entier."
|
||||
|
||||
#: pkg/booking/public.go:509
|
||||
#: pkg/booking/public.go:515
|
||||
#, c-format
|
||||
msgid "%s must be %d or greater."
|
||||
msgstr "%s doit être %d ou plus."
|
||||
|
||||
#: pkg/booking/public.go:510
|
||||
#: pkg/booking/public.go:516
|
||||
#, c-format
|
||||
msgid "%s must be at most %d."
|
||||
msgstr "%s doit être tout au plus %d."
|
||||
|
||||
#: pkg/booking/public.go:568
|
||||
#: pkg/booking/public.go:574
|
||||
msgid "Full name can not be empty."
|
||||
msgstr "Le nom complet ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/public.go:569
|
||||
#: pkg/booking/public.go:575
|
||||
msgid "Full name must have at least one letter."
|
||||
msgstr "Le nom complet doit comporter au moins une lettre."
|
||||
|
||||
#: pkg/booking/public.go:586
|
||||
#: pkg/booking/public.go:592
|
||||
msgid "It is mandatory to agree to the reservation conditions."
|
||||
msgstr "Il est obligatoire d’accepter les conditions de réservation."
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
-- Revert camper:available_payment_status from pg
|
||||
|
||||
begin;
|
||||
|
||||
delete
|
||||
from camper.payment_status_i18n
|
||||
;
|
||||
|
||||
delete
|
||||
from camper.payment_status
|
||||
;
|
||||
|
||||
|
||||
commit;
|
|
@ -0,0 +1,9 @@
|
|||
-- Revert camper:draft_payment from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop function if exists camper.draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, camper.option_units[]);
|
||||
|
||||
drop type if exists camper.option_units;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:payment from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.payment;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:payment_customer from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.payment_customer;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:payment_option from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.payment_option;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:payment_status from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.payment_status;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:payment_status_i18n from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.payment_status_i18n;
|
||||
|
||||
commit;
|
|
@ -240,3 +240,10 @@ edit_campsite_type_option [edit_campsite_type_option@v3 campsite_type_option__pe
|
|||
campsite_type_option_cost__cost [campsite_type_option_cost] 2024-02-11T19:50:44Z jordi fita mas <jordi@tandem.blog> # Add cost field to campsite_type_option_cost
|
||||
set_campsite_type_option_cost [set_campsite_type_option_cost@v3 campsite_type_option_cost__cost] 2024-02-11T20:05:58Z jordi fita mas <jordi@tandem.blog> # Update cost instead of cost_per_night in set_campsite_type_option_cost
|
||||
campsite_type_option_cost__-cost_per_night [campsite_type_option_cost campsite_type_option_cost__cost] 2024-02-11T19:58:30Z jordi fita mas <jordi@tandem.blog> # Remove cost_per_night field from campsite_type_option_cost
|
||||
payment_status [roles schema_camper] 2024-02-11T21:13:32Z jordi fita mas <jordi@tandem.blog> # Add relation of payment statuses
|
||||
payment_status_i18n [roles schema_camper payment_status language] 2024-02-11T21:20:11Z jordi fita mas <jordi@tandem.blog> # Add relation for translation of payment status
|
||||
available_payment_status [payment_status payment_status_i18n] 2024-02-11T21:22:38Z jordi fita mas <jordi@tandem.blog> # Add available payment statuses
|
||||
payment [roles schema_camper company campsite_type payment_status] 2024-02-11T21:54:13Z jordi fita mas <jordi@tandem.blog> # Add relation for payments
|
||||
payment_customer [roles schema_camper payment country country_code extension_pg_libphonenumber] 2024-02-12T00:10:20Z jordi fita mas <jordi@tandem.blog> # Add relation of payment customer
|
||||
payment_option [roles schema_camper payment campsite_type_option] 2024-02-12T00:58:07Z jordi fita mas <jordi@tandem.blog> # Add relation of payment for campsite type options
|
||||
draft_payment [roles schema_camper season_calendar season campsite_type campsite_type_pet_cost campsite_type_cost campsite_type_option_cost campsite_type_option payment payment_option] 2024-02-12T01:31:52Z jordi fita mas <jordi@tandem.blog> # Add function to create a payment draft
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
-- Test draft_payment
|
||||
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', 'draft_payment', array['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]']);
|
||||
select function_lang_is('camper', 'draft_payment', array['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'plpgsql');
|
||||
select function_returns('camper', 'draft_payment', array['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'uuid');
|
||||
select isnt_definer('camper', 'draft_payment', array['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]']);
|
||||
select volatility_is('camper', 'draft_payment', array['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'volatile');
|
||||
select function_privs_are('camper', 'draft_payment', array ['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'guest', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'draft_payment', array ['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'employee', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'draft_payment', array ['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'admin', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'draft_payment', array ['uuid', 'date', 'date', 'uuid', 'integer', 'integer', 'integer', 'integer', 'text', 'option_units[]'], 'authenticator', array[]::text[]);
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate payment_option cascade;
|
||||
truncate payment cascade;
|
||||
truncate campsite_type_option_cost cascade;
|
||||
truncate campsite_type_option cascade;
|
||||
truncate campsite_type_pet_cost cascade;
|
||||
truncate campsite_type_cost cascade;
|
||||
truncate campsite_type cascade;
|
||||
truncate media cascade;
|
||||
truncate media_content cascade;
|
||||
truncate season_calendar cascade;
|
||||
truncate season 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, country_code, currency_code, default_lang_tag)
|
||||
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 350, 'ES', 'EUR', 'ca')
|
||||
;
|
||||
|
||||
insert into season (season_id, company_id, name)
|
||||
values (4, 2, 'High')
|
||||
, (6, 2, 'Shoulder')
|
||||
, (8, 2, 'Offseason')
|
||||
;
|
||||
|
||||
insert into season_calendar (season_id, season_range)
|
||||
values (4, '[2024-07-01,2024-08-30)')
|
||||
, (6, '[2024-08-30,2024-09-03)')
|
||||
, (8, '[2024-09-03,2024-09-08)')
|
||||
;
|
||||
|
||||
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 (10, 2, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};'))
|
||||
;
|
||||
|
||||
insert into campsite_type (campsite_type_id, slug, company_id, name, media_id, max_campers, bookable_nights, overflow_allowed)
|
||||
values (12, 'c1b6f4fc-32c1-4cd5-b796-0c5059152a52', 2, 'Plots', 10, 6, '[1, 7]', true)
|
||||
, (14, 'b065f4e3-2cc8-491d-a413-d015d7d00183', 2, 'Bungalow', 10, 6, '[1, 7]', false)
|
||||
;
|
||||
|
||||
insert into campsite_type_cost (campsite_type_id, season_id, cost_per_night, cost_per_adult, cost_per_teenager, cost_per_child)
|
||||
values (12, 4, 400, 795, 795, 640)
|
||||
, (12, 6, 200, 740, 740, 590)
|
||||
, (12, 8, 0, 660, 660, 540)
|
||||
, (14, 4, 17000, 0, 0, 0)
|
||||
, (14, 6, 13500, 0, 0, 0)
|
||||
, (14, 8, 10500, 0, 0, 0)
|
||||
;
|
||||
|
||||
insert into campsite_type_pet_cost (campsite_type_id, cost_per_night)
|
||||
values (12, 350)
|
||||
;
|
||||
|
||||
insert into campsite_type_option (campsite_type_option_id, campsite_type_id, name, range, per_night)
|
||||
values (16, 12, 'Big tent', '[0, 4)', true)
|
||||
, (18, 12, 'Car', '[0, 4)', true)
|
||||
, (20, 12, 'Electricity', '[0, 5)', false)
|
||||
;
|
||||
|
||||
insert into campsite_type_option_cost (campsite_type_option_id, season_id, cost)
|
||||
values (16, 4, 800)
|
||||
, (16, 6, 720)
|
||||
, (16, 8, 620)
|
||||
, (18, 4, 700)
|
||||
, (18, 6, 630)
|
||||
, (18, 8, 530)
|
||||
, (20, 4, 690)
|
||||
, (20, 6, 610)
|
||||
, (20, 8, 590)
|
||||
;
|
||||
|
||||
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, zone_preferences, created_at, updated_at)
|
||||
values (22, '7cccfe16-695e-486d-a6a5-1162fb85cafb', 2, 12, '2024-08-30', '2024-09-01', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '2024-01-01 01:01:01', '2024-01-01 01:01:01')
|
||||
;
|
||||
|
||||
insert into payment_option (payment_id, campsite_type_option_id, units, subtotal)
|
||||
values (22, 16, 1, 0)
|
||||
, (22, 18, 1, 0)
|
||||
;
|
||||
|
||||
select lives_ok(
|
||||
$$ select draft_payment(null, '2024-08-29', '2024-09-03', 'b065f4e3-2cc8-491d-a413-d015d7d00183', 1, 2, 3, 0, null, null) $$,
|
||||
'Should be able to create a new draft for Bungalows'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select draft_payment('7cccfe16-695e-486d-a6a5-1162fb85cafb', '2024-08-28', '2024-09-04', 'c1b6f4fc-32c1-4cd5-b796-0c5059152a52', 2, 4, 6, 3, 'pref I before E', array[(16, 2), (20, 3)]::option_units[]) $$,
|
||||
'Should be able to update the draft for Plots'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select company_id, campsite_type_id, arrival_date::text, departure_date::text, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, zone_preferences, created_at, updated_at from payment $$,
|
||||
$$ values (2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'pref I before E', '2024-01-01 01:01:01', current_timestamp)
|
||||
, (2, 14, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', current_timestamp, current_timestamp)
|
||||
$$,
|
||||
'Should have added and updated payments'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select payment_id, campsite_type_option_id, units, subtotal from payment_option $$,
|
||||
$$ values (22, 16, 2, 10200)
|
||||
, (22, 20, 3, 2070)
|
||||
$$,
|
||||
'Should have added, updated, and removed payment options'
|
||||
);
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,239 @@
|
|||
-- Test payment
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(114);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('payment');
|
||||
select has_pk('payment');
|
||||
select table_privs_are('payment', 'guest', array['SELECT', 'INSERT', 'UPDATE']);
|
||||
select table_privs_are('payment', 'employee', array['SELECT', 'INSERT', 'UPDATE']);
|
||||
select table_privs_are('payment', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('payment', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('payment', 'payment_id');
|
||||
select col_is_pk('payment', 'payment_id');
|
||||
select col_type_is('payment', 'payment_id', 'integer');
|
||||
select col_not_null('payment', 'payment_id');
|
||||
select col_hasnt_default('payment', 'payment_id');
|
||||
|
||||
select has_column('payment', 'company_id');
|
||||
select col_is_fk('payment', 'company_id');
|
||||
select fk_ok('payment', 'company_id', 'company', 'company_id');
|
||||
select col_type_is('payment', 'company_id', 'integer');
|
||||
select col_not_null('payment', 'company_id');
|
||||
select col_hasnt_default('payment', 'company_id');
|
||||
|
||||
select has_column('payment', 'slug');
|
||||
select col_is_unique('payment', 'slug');
|
||||
select col_type_is('payment', 'slug', 'uuid');
|
||||
select col_not_null('payment', 'slug');
|
||||
select col_has_default('payment', 'slug');
|
||||
select col_default_is('payment', 'slug', 'gen_random_uuid()');
|
||||
|
||||
select has_column('payment', 'campsite_type_id');
|
||||
select col_is_fk('payment', 'campsite_type_id');
|
||||
select fk_ok('payment', 'campsite_type_id', 'campsite_type', 'campsite_type_id');
|
||||
select col_type_is('payment', 'campsite_type_id', 'integer');
|
||||
select col_not_null('payment', 'campsite_type_id');
|
||||
select col_hasnt_default('payment', 'campsite_type_id');
|
||||
|
||||
select has_column('payment', 'arrival_date');
|
||||
select col_type_is('payment', 'arrival_date', 'date');
|
||||
select col_not_null('payment', 'arrival_date');
|
||||
select col_hasnt_default('payment', 'arrival_date');
|
||||
|
||||
select has_column('payment', 'departure_date');
|
||||
select col_type_is('payment', 'departure_date', 'date');
|
||||
select col_not_null('payment', 'departure_date');
|
||||
select col_hasnt_default('payment', 'departure_date');
|
||||
|
||||
select has_column('payment', 'subtotal_nights');
|
||||
select col_type_is('payment', 'subtotal_nights', 'integer');
|
||||
select col_not_null('payment', 'subtotal_nights');
|
||||
select col_hasnt_default('payment', 'subtotal_nights');
|
||||
|
||||
select has_column('payment', 'number_adults');
|
||||
select col_type_is('payment', 'number_adults', 'integer');
|
||||
select col_not_null('payment', 'number_adults');
|
||||
select col_hasnt_default('payment', 'number_adults');
|
||||
|
||||
select has_column('payment', 'subtotal_adults');
|
||||
select col_type_is('payment', 'subtotal_adults', 'integer');
|
||||
select col_not_null('payment', 'subtotal_adults');
|
||||
select col_hasnt_default('payment', 'subtotal_adults');
|
||||
|
||||
select has_column('payment', 'number_teenagers');
|
||||
select col_type_is('payment', 'number_teenagers', 'integer');
|
||||
select col_not_null('payment', 'number_teenagers');
|
||||
select col_hasnt_default('payment', 'number_teenagers');
|
||||
|
||||
select has_column('payment', 'subtotal_teenagers');
|
||||
select col_type_is('payment', 'subtotal_teenagers', 'integer');
|
||||
select col_not_null('payment', 'subtotal_teenagers');
|
||||
select col_hasnt_default('payment', 'subtotal_teenagers');
|
||||
|
||||
select has_column('payment', 'number_children');
|
||||
select col_type_is('payment', 'number_children', 'integer');
|
||||
select col_not_null('payment', 'number_children');
|
||||
select col_hasnt_default('payment', 'number_children');
|
||||
|
||||
select has_column('payment', 'subtotal_children');
|
||||
select col_type_is('payment', 'subtotal_children', 'integer');
|
||||
select col_not_null('payment', 'subtotal_children');
|
||||
select col_hasnt_default('payment', 'subtotal_children');
|
||||
|
||||
select has_column('payment', 'number_dogs');
|
||||
select col_type_is('payment', 'number_dogs', 'integer');
|
||||
select col_not_null('payment', 'number_dogs');
|
||||
select col_hasnt_default('payment', 'number_dogs');
|
||||
|
||||
select has_column('payment', 'subtotal_dogs');
|
||||
select col_type_is('payment', 'subtotal_dogs', 'integer');
|
||||
select col_not_null('payment', 'subtotal_dogs');
|
||||
select col_hasnt_default('payment', 'subtotal_dogs');
|
||||
|
||||
select has_column('payment', 'subtotal_tourist_tax');
|
||||
select col_type_is('payment', 'subtotal_tourist_tax', 'integer');
|
||||
select col_not_null('payment', 'subtotal_tourist_tax');
|
||||
select col_hasnt_default('payment', 'subtotal_tourist_tax');
|
||||
|
||||
select has_column('payment', 'total');
|
||||
select col_type_is('payment', 'total', 'integer');
|
||||
select col_not_null('payment', 'total');
|
||||
select col_hasnt_default('payment', 'total');
|
||||
|
||||
select has_column('payment', 'zone_preferences');
|
||||
select col_type_is('payment', 'zone_preferences', 'text');
|
||||
select col_not_null('payment', 'zone_preferences');
|
||||
select col_hasnt_default('payment', 'zone_preferences');
|
||||
|
||||
select has_column('payment', 'payment_status');
|
||||
select col_is_fk('payment', 'payment_status');
|
||||
select fk_ok('payment', 'payment_status', 'payment_status', 'payment_status');
|
||||
select col_type_is('payment', 'payment_status', 'text');
|
||||
select col_not_null('payment', 'payment_status');
|
||||
select col_has_default('payment', 'payment_status');
|
||||
select col_default_is('payment', 'payment_status', 'draft');
|
||||
|
||||
select has_column('payment', 'created_at');
|
||||
select col_type_is('payment', 'created_at', 'timestamp with time zone');
|
||||
select col_not_null('payment', 'created_at');
|
||||
select col_has_default('payment', 'created_at');
|
||||
select col_default_is('payment', 'created_at', 'CURRENT_TIMESTAMP');
|
||||
|
||||
select has_column('payment', 'updated_at');
|
||||
select col_type_is('payment', 'updated_at', 'timestamp with time zone');
|
||||
select col_not_null('payment', 'updated_at');
|
||||
select col_has_default('payment', 'updated_at');
|
||||
select col_default_is('payment', 'updated_at', 'CURRENT_TIMESTAMP');
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate payment 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, country_code, currency_code, default_lang_tag)
|
||||
values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 60, '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 (2, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};'))
|
||||
;
|
||||
|
||||
insert into campsite_type (campsite_type_id, company_id, media_id, name, description, max_campers, bookable_nights, active)
|
||||
values (10, 1, 2, 'Type A', '<p>A</p>', 5, '[1, 7]', true)
|
||||
;
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-07', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "departure_after_arrival"',
|
||||
'Should not be able to insert a payment with a departure date equal or before the arrival date (i.e., at least one night)'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_nights_not_negative"',
|
||||
'Should not be able to insert a payment with negative subtotal for nights'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "number_adults_positive"',
|
||||
'Should not be able to insert a payment with no adults'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_adults_not_negative"',
|
||||
'Should not be able to insert a payment with a negative subtotal for adults'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "number_teenagers_not_negative"',
|
||||
'Should not be able to insert a payment with a negative number of teenagers'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_teenagers_not_negative"',
|
||||
'Should not be able to insert a payment with a negative subtotal for teenagers'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "number_children_not_negative"',
|
||||
'Should not be able to insert a payment with a negative number of children'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_children_not_negative"',
|
||||
'Should not be able to insert a payment with a negative subtotal for children'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "number_dogs_not_negative"',
|
||||
'Should not be able to insert a payment with a negative number of dogs'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_dogs_not_negative"',
|
||||
'Should not be able to insert a payment with a negative subtotal for dogs'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "subtotal_tourist_tax_not_negative"',
|
||||
'Should not be able to insert a payment with a negative subtotal for tourist tax'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment (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, zone_preferences) values (1, 10, '2024-07-07', '2024-07-09', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, '') $$,
|
||||
'23514', 'new row for relation "payment" violates check constraint "total_not_negative"',
|
||||
'Should not be able to insert a payment with a negative total'
|
||||
);
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
-- Test payment_customer
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(47);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('payment_customer');
|
||||
select has_pk('payment_customer');
|
||||
select table_privs_are('payment_customer', 'guest', array['SELECT', 'INSERT']);
|
||||
select table_privs_are('payment_customer', 'employee', array['SELECT', 'INSERT', 'UPDATE']);
|
||||
select table_privs_are('payment_customer', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('payment_customer', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('payment_customer', 'payment_id');
|
||||
select col_is_pk('payment_customer', 'payment_id');
|
||||
select col_is_fk('payment_customer', 'payment_id');
|
||||
select fk_ok('payment_customer', 'payment_id', 'payment', 'payment_id');
|
||||
select col_type_is('payment_customer', 'payment_id', 'integer');
|
||||
select col_not_null('payment_customer', 'payment_id');
|
||||
select col_hasnt_default('payment_customer', 'payment_id');
|
||||
|
||||
select has_column('payment_customer', 'full_name');
|
||||
select col_type_is('payment_customer', 'full_name', 'text');
|
||||
select col_not_null('payment_customer', 'full_name');
|
||||
select col_hasnt_default('payment_customer', 'full_name');
|
||||
|
||||
select has_column('payment_customer', 'address');
|
||||
select col_type_is('payment_customer', 'address', 'text');
|
||||
select col_not_null('payment_customer', 'address');
|
||||
select col_hasnt_default('payment_customer', 'address');
|
||||
|
||||
select has_column('payment_customer', 'postal_code');
|
||||
select col_type_is('payment_customer', 'postal_code', 'text');
|
||||
select col_not_null('payment_customer', 'postal_code');
|
||||
select col_hasnt_default('payment_customer', 'postal_code');
|
||||
|
||||
select has_column('payment_customer', 'city');
|
||||
select col_type_is('payment_customer', 'city', 'text');
|
||||
select col_not_null('payment_customer', 'city');
|
||||
select col_hasnt_default('payment_customer', 'city');
|
||||
|
||||
select has_column('payment_customer', 'country_code');
|
||||
select col_is_fk('payment_customer', 'country_code');
|
||||
select fk_ok('payment_customer', 'country_code', 'country', 'country_code');
|
||||
select col_type_is('payment_customer', 'country_code', 'country_code');
|
||||
select col_not_null('payment_customer', 'country_code');
|
||||
select col_hasnt_default('payment_customer', 'country_code');
|
||||
|
||||
select has_column('payment_customer', 'email');
|
||||
select col_type_is('payment_customer', 'email', 'email');
|
||||
select col_not_null('payment_customer', 'email');
|
||||
select col_hasnt_default('payment_customer', 'email');
|
||||
|
||||
select has_column('payment_customer', 'phone');
|
||||
select col_type_is('payment_customer', 'phone', 'packed_phone_number');
|
||||
select col_not_null('payment_customer', 'phone');
|
||||
select col_hasnt_default('payment_customer', 'phone');
|
||||
|
||||
select has_column('payment_customer', 'acsi_card');
|
||||
select col_type_is('payment_customer', 'acsi_card', 'boolean');
|
||||
select col_not_null('payment_customer', 'acsi_card');
|
||||
select col_hasnt_default('payment_customer', 'acsi_card');
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
-- Test payment_option
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(29);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('payment_option');
|
||||
select has_pk('payment_option');
|
||||
select col_is_pk('payment_option', array['payment_id', 'campsite_type_option_id']);
|
||||
select table_privs_are('payment_option', 'guest', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('payment_option', 'employee', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('payment_option', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('payment_option', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('payment_option', 'payment_id');
|
||||
select col_is_fk('payment_option', 'payment_id');
|
||||
select fk_ok('payment_option', 'payment_id', 'payment', 'payment_id');
|
||||
select col_type_is('payment_option', 'payment_id', 'integer');
|
||||
select col_not_null('payment_option', 'payment_id');
|
||||
select col_hasnt_default('payment_option', 'payment_id');
|
||||
|
||||
select has_column('payment_option', 'campsite_type_option_id');
|
||||
select col_is_fk('payment_option', 'campsite_type_option_id');
|
||||
select fk_ok('payment_option', 'campsite_type_option_id', 'campsite_type_option', 'campsite_type_option_id');
|
||||
select col_type_is('payment_option', 'campsite_type_option_id', 'integer');
|
||||
select col_not_null('payment_option', 'campsite_type_option_id');
|
||||
select col_hasnt_default('payment_option', 'campsite_type_option_id');
|
||||
|
||||
select has_column('payment_option', 'units');
|
||||
select col_type_is('payment_option', 'units', 'integer');
|
||||
select col_not_null('payment_option', 'units');
|
||||
select col_hasnt_default('payment_option', 'units');
|
||||
|
||||
select has_column('payment_option', 'subtotal');
|
||||
select col_type_is('payment_option', 'subtotal', 'integer');
|
||||
select col_not_null('payment_option', 'subtotal');
|
||||
select col_hasnt_default('payment_option', 'subtotal');
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate payment_option 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, country_code, currency_code, default_lang_tag)
|
||||
values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 60, '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 (2, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};'))
|
||||
;
|
||||
|
||||
insert into campsite_type (campsite_type_id, company_id, media_id, name, description, max_campers, bookable_nights, active)
|
||||
values (10, 1, 2, 'Type A', '<p>A</p>', 5, '[1, 7]', true)
|
||||
;
|
||||
|
||||
insert into campsite_type_option (campsite_type_option_id, campsite_type_id, name, range, per_night)
|
||||
values (11, 10, 'Option 1', '[2, 2]', true)
|
||||
, (12, 10, 'Option 2', '[4, 8]', true)
|
||||
;
|
||||
|
||||
insert into payment (payment_id, 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, zone_preferences)
|
||||
values (15, 1, 10, '2024-07-07', '2024-07-08', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '')
|
||||
;
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment_option (payment_id, campsite_type_option_id, units, subtotal) values (15, 11, 0, 0) $$,
|
||||
'23514', 'new row for relation "payment_option" violates check constraint "units_positive"',
|
||||
'Should not be able to insert a payment option with zero units'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into payment_option (payment_id, campsite_type_option_id, units, subtotal) values (15, 12, 1, -1) $$,
|
||||
'23514', 'new row for relation "payment_option" violates check constraint "subtotal_not_negative"',
|
||||
'Should not be able to insert a payment option with a negative subtotal'
|
||||
);
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
-- Test payment_status
|
||||
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_table('payment_status');
|
||||
select has_pk('payment_status');
|
||||
select table_privs_are('payment_status', 'guest', array[]::text[]);
|
||||
select table_privs_are('payment_status', 'employee', array['SELECT']);
|
||||
select table_privs_are('payment_status', 'admin', array['SELECT']);
|
||||
select table_privs_are('payment_status', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('payment_status', 'payment_status');
|
||||
select col_is_pk('payment_status', 'payment_status');
|
||||
select col_type_is('payment_status', 'payment_status', 'text');
|
||||
select col_not_null('payment_status', 'payment_status');
|
||||
select col_hasnt_default('payment_status', 'payment_status');
|
||||
|
||||
select has_column('payment_status', 'name');
|
||||
select col_type_is('payment_status', 'name', 'text');
|
||||
select col_not_null('payment_status', 'name');
|
||||
select col_hasnt_default('payment_status', 'name');
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
-- Test payment_status_i18n
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(23);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('payment_status_i18n');
|
||||
select has_pk('payment_status_i18n');
|
||||
select col_is_pk('payment_status_i18n', array['payment_status', 'lang_tag']);
|
||||
select table_privs_are('payment_status_i18n', 'guest', array[]::text[]);
|
||||
select table_privs_are('payment_status_i18n', 'employee', array['SELECT']);
|
||||
select table_privs_are('payment_status_i18n', 'admin', array['SELECT']);
|
||||
select table_privs_are('payment_status_i18n', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('payment_status_i18n', 'payment_status');
|
||||
select col_is_fk('payment_status_i18n', 'payment_status');
|
||||
select fk_ok('payment_status_i18n', 'payment_status', 'payment_status', 'payment_status');
|
||||
select col_type_is('payment_status_i18n', 'payment_status', 'text');
|
||||
select col_not_null('payment_status_i18n', 'payment_status');
|
||||
select col_hasnt_default('payment_status_i18n', 'payment_status');
|
||||
|
||||
select has_column('payment_status_i18n', 'lang_tag');
|
||||
select col_is_fk('payment_status_i18n', 'lang_tag');
|
||||
select fk_ok('payment_status_i18n', 'lang_tag', 'language', 'lang_tag');
|
||||
select col_type_is('payment_status_i18n', 'lang_tag', 'text');
|
||||
select col_not_null('payment_status_i18n', 'lang_tag');
|
||||
select col_hasnt_default('payment_status_i18n', 'lang_tag');
|
||||
|
||||
select has_column('payment_status_i18n', 'name');
|
||||
select col_type_is('payment_status_i18n', 'name', 'text');
|
||||
select col_not_null('payment_status_i18n', 'name');
|
||||
select col_hasnt_default('payment_status_i18n', 'name');
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
-- Verify camper:available_payment_status on pg
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper;
|
||||
|
||||
select 1 / count(*) from payment_status where payment_status = 'draft' and name = 'Draft';
|
||||
select 1 / count(*) from payment_status where payment_status = 'pending' and name = 'Pending';
|
||||
select 1 / count(*) from payment_status where payment_status = 'failed' and name = 'Failed';
|
||||
select 1 / count(*) from payment_status where payment_status = 'completed' and name = 'Completed';
|
||||
select 1 / count(*) from payment_status where payment_status = 'refunded' and name = 'Refunded';
|
||||
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'draft' and lang_tag = 'ca' and name = 'Esborrany';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'pending' and lang_tag = 'ca' and name = 'Pendent';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'failed' and lang_tag = 'ca' and name = 'No realitzat';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'completed' and lang_tag = 'ca' and name = 'Completat';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'refunded' and lang_tag = 'ca' and name = 'Reemborsat';
|
||||
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'draft' and lang_tag = 'es' and name = 'Borrador';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'pending' and lang_tag = 'es' and name = 'Pendiente';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'failed' and lang_tag = 'es' and name = 'Fallido';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'completed' and lang_tag = 'es' and name = 'Completado';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'refunded' and lang_tag = 'es' and name = 'Reembolsado';
|
||||
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'draft' and lang_tag = 'fr' and name = 'Brouillon';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'failed' and lang_tag = 'fr' and name = 'Échouée';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'completed' and lang_tag = 'fr' and name = 'Terminée';
|
||||
select 1 / count(*) from payment_status_i18n where payment_status = 'refunded' and lang_tag = 'fr' and name = 'Remboursée';
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,7 @@
|
|||
-- Verify camper:draft_payment on pg
|
||||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('camper.draft_payment(uuid, date, date, uuid, integer, integer, integer, integer, text, camper.option_units[])', 'execute');
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,29 @@
|
|||
-- Verify camper:payment on pg
|
||||
|
||||
begin;
|
||||
|
||||
select payment_id
|
||||
, company_id
|
||||
, slug
|
||||
, 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
|
||||
, zone_preferences
|
||||
, payment_status
|
||||
, created_at
|
||||
, updated_at
|
||||
from camper.payment
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,17 @@
|
|||
-- Verify camper:payment_customer on pg
|
||||
|
||||
begin;
|
||||
|
||||
select payment_id
|
||||
, full_name
|
||||
, address
|
||||
, postal_code
|
||||
, city
|
||||
, country_code
|
||||
, email
|
||||
, phone
|
||||
, acsi_card
|
||||
from camper.payment_customer
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,12 @@
|
|||
-- Verify camper:payment_option on pg
|
||||
|
||||
begin;
|
||||
|
||||
select payment_id
|
||||
, campsite_type_option_id
|
||||
, units
|
||||
, subtotal
|
||||
from camper.payment_option
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,10 @@
|
|||
-- Verify camper:payment_status on pg
|
||||
|
||||
begin;
|
||||
|
||||
select payment_status
|
||||
, name
|
||||
from camper.payment_status
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,11 @@
|
|||
-- Verify camper:payment_status_i18n on pg
|
||||
|
||||
begin;
|
||||
|
||||
select payment_status
|
||||
, lang_tag
|
||||
, name
|
||||
from camper.payment_status_i18n
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -9,6 +9,8 @@
|
|||
data-hx-get="/{{ currentLocale }}/booking"
|
||||
data-hx-trigger="change"
|
||||
>
|
||||
<input type="hidden" name="{{ .PaymentSlug.Name }}" value="{{ .PaymentSlug.Val }}">
|
||||
|
||||
<fieldset class="accommodation">
|
||||
<legend>{{( pgettext "Accommodation" "title" )}}</legend>
|
||||
{{ range .CampsiteType.Options -}}
|
||||
|
|
Loading…
Reference in New Issue