diff --git a/deploy/draft_payment.sql b/deploy/draft_payment.sql index e88863c..d360fbc 100644 --- a/deploy/draft_payment.sql +++ b/deploy/draft_payment.sql @@ -42,6 +42,7 @@ begin , subtotal_dogs , subtotal_tourist_tax , total + , currency_code , down_payment_percent , zone_preferences ) @@ -61,6 +62,7 @@ begin , sum(case when num_dogs > 0 then coalesce(pet.cost_per_night, 0) else 0 end)::integer , sum(tourist_tax * num_adults)::integer , 0 + , currency_code , case when arrival_date - current_date >= 7 then 0.3 else 1.0 end , coalesce(zone_preferences, '') from generate_series(arrival_date, departure_date - 1, interval '1 day') as date(day) @@ -73,6 +75,7 @@ begin where campsite_type.slug = campsite_type_slug group by company_id , campsite_type_id + , currency_code on conflict (slug) do update set company_id = excluded.company_id , campsite_type_id = excluded.campsite_type_id @@ -89,6 +92,7 @@ begin , subtotal_dogs = excluded.subtotal_dogs , subtotal_tourist_tax = excluded.subtotal_tourist_tax , total = excluded.total + , currency_code = excluded.currency_code , down_payment_percent = excluded.down_payment_percent , zone_preferences = excluded.zone_preferences , updated_at = current_timestamp diff --git a/deploy/payment.sql b/deploy/payment.sql index 74ce0c5..618199c 100644 --- a/deploy/payment.sql +++ b/deploy/payment.sql @@ -7,6 +7,8 @@ -- requires: positive_integer -- requires: nonnegative_integer -- requires: percentage +-- requires: currency_code +-- requires: currency begin; @@ -30,6 +32,7 @@ create table payment ( subtotal_dogs nonnegative_integer not null, subtotal_tourist_tax nonnegative_integer not null, total nonnegative_integer not null, + currency_code currency_code not null references currency, down_payment_percent percentage not null default 1.0, zone_preferences text not null, payment_status text not null default 'draft' references payment_status, diff --git a/deploy/payment_reference.sql b/deploy/payment_reference.sql new file mode 100644 index 0000000..d06ac5e --- /dev/null +++ b/deploy/payment_reference.sql @@ -0,0 +1,23 @@ +-- Deploy camper:order_code to pg +-- requires: roles +-- requires: schema_camper +-- requires: payment + +begin; + +set search_path to camper, public; + +create or replace function reference(p payment) returns text as +$$ + select lpad(p.payment_id::text, 8, '0') || substring(p.slug::text from 1 for 4); +$$ + language sql + stable +; + +revoke execute on function reference(payment) from public; +grant execute on function reference(payment) to guest; +grant execute on function reference(payment) to employee; +grant execute on function reference(payment) to admin; + +commit; diff --git a/pkg/app/admin.go b/pkg/app/admin.go index 3bff2bd..1ecf211 100644 --- a/pkg/app/admin.go +++ b/pkg/app/admin.go @@ -19,6 +19,7 @@ import ( "dev.tandem.ws/tandem/camper/pkg/legal" "dev.tandem.ws/tandem/camper/pkg/location" "dev.tandem.ws/tandem/camper/pkg/media" + "dev.tandem.ws/tandem/camper/pkg/payment" "dev.tandem.ws/tandem/camper/pkg/season" "dev.tandem.ws/tandem/camper/pkg/services" "dev.tandem.ws/tandem/camper/pkg/surroundings" @@ -35,6 +36,7 @@ type adminHandler struct { legal *legal.AdminHandler location *location.AdminHandler media *media.AdminHandler + payment *payment.AdminHandler season *season.AdminHandler services *services.AdminHandler surroundings *surroundings.AdminHandler @@ -51,6 +53,7 @@ func newAdminHandler(mediaDir string) *adminHandler { legal: legal.NewAdminHandler(), location: location.NewAdminHandler(), media: media.NewAdminHandler(mediaDir), + payment: payment.NewAdminHandler(), season: season.NewAdminHandler(), services: services.NewAdminHandler(), surroundings: surroundings.NewAdminHandler(), @@ -90,6 +93,8 @@ func (h *adminHandler) Handle(user *auth.User, company *auth.Company, conn *data h.location.Handler(user, company, conn).ServeHTTP(w, r) case "media": h.media.Handler(user, company, conn).ServeHTTP(w, r) + case "payments": + h.payment.Handler(user, company, conn).ServeHTTP(w, r) case "seasons": h.season.Handler(user, company, conn).ServeHTTP(w, r) case "services": diff --git a/pkg/booking/admin.go b/pkg/booking/admin.go index 08621d1..d90d380 100644 --- a/pkg/booking/admin.go +++ b/pkg/booking/admin.go @@ -14,9 +14,7 @@ import ( "dev.tandem.ws/tandem/camper/pkg/auth" "dev.tandem.ws/tandem/camper/pkg/database" - "dev.tandem.ws/tandem/camper/pkg/form" httplib "dev.tandem.ws/tandem/camper/pkg/http" - "dev.tandem.ws/tandem/camper/pkg/locale" "dev.tandem.ws/tandem/camper/pkg/template" ) @@ -40,27 +38,6 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat default: httplib.MethodNotAllowed(w, r, http.MethodGet) } - case "payment": - head, r.URL.Path = httplib.ShiftPath(r.URL.Path) - switch head { - case "": - switch r.Method { - case http.MethodGet: - f := newPaymentForm(user.Locale) - if err := f.FillFromDatabase(r.Context(), company, conn); err != nil { - if !database.ErrorIsNotFound(err) { - panic(err) - } - } - f.MustRender(w, r, user, company) - case http.MethodPut: - updatePaymentSettings(w, r, user, company, conn) - default: - httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut) - } - default: - http.NotFound(w, r) - } default: http.NotFound(w, r) } @@ -151,124 +128,3 @@ func (page bookingIndex) MustRender(w http.ResponseWriter, r *http.Request, user template.MustRenderAdmin(w, r, user, company, "booking/index.gohtml", page) } } - -type paymentForm struct { - MerchantCode *form.Input - TerminalNumber *form.Input - Environment *form.Select - Integration *form.Select - EncryptKey *form.Input -} - -func newPaymentForm(l *locale.Locale) *paymentForm { - return &paymentForm{ - - MerchantCode: &form.Input{ - Name: "merchant_code", - }, - TerminalNumber: &form.Input{ - Name: "terminal_number", - }, - Environment: &form.Select{ - Name: "environment", - Options: []*form.Option{ - { - Value: "test", - Label: l.Pgettext("Test", "redsys environment"), - }, - { - Value: "live", - Label: l.Pgettext("Live", "redsys environment"), - }, - }, - }, - Integration: &form.Select{ - Name: "integration", - Options: []*form.Option{ - { - Value: "insite", - Label: l.Pgettext("InSite", "redsys integration"), - }, - { - Value: "redirect", - Label: l.Pgettext("Redirect", "redsys integration"), - }, - }, - }, - EncryptKey: &form.Input{ - Name: "encrypt_key", - }, - } -} - -func (f *paymentForm) FillFromDatabase(ctx context.Context, company *auth.Company, conn *database.Conn) error { - return conn.QueryRow(ctx, ` - select merchant_code - , terminal_number::text - , array[environment::text] - , array[integration::text] - from redsys - where company_id = $1`, company.ID).Scan( - &f.MerchantCode.Val, - &f.TerminalNumber.Val, - &f.Environment.Selected, - &f.Integration.Selected, - ) -} - -func (f *paymentForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { - template.MustRenderAdmin(w, r, user, company, "booking/payment.gohtml", f) -} - -func (f *paymentForm) Parse(r *http.Request) error { - if err := r.ParseForm(); err != nil { - return err - } - f.MerchantCode.FillValue(r) - f.TerminalNumber.FillValue(r) - f.Environment.FillValue(r) - f.Integration.FillValue(r) - f.EncryptKey.FillValue(r) - return nil -} - -func (f *paymentForm) Valid(l *locale.Locale) bool { - v := form.NewValidator(l) - - if v.CheckRequired(f.MerchantCode, l.GettextNoop("Merchant code can not be empty.")) { - if v.CheckExactLength(f.MerchantCode, 9, l.GettextNoop("Merchant code must be exactly nine digits long.")) { - v.CheckValidInteger(f.MerchantCode, l.GettextNoop("Merchant code must be a number.")) - } - } - - if v.CheckRequired(f.TerminalNumber, l.GettextNoop("Terminal number can not be empty.")) { - message := l.GettextNoop("Terminal number must be a number between 1 and 999.") - if v.CheckValidInteger(f.TerminalNumber, message) { - if v.CheckMinInteger(f.TerminalNumber, 1, message) { - v.CheckMaxInteger(f.TerminalNumber, 999, message) - } - } - } - - v.CheckSelectedOptions(f.Environment, l.GettextNoop("Selected environment is not valid.")) - v.CheckSelectedOptions(f.Integration, l.GettextNoop("Selected integration is not valid.")) - - if f.EncryptKey.Val != "" { - v.CheckValidBase64(f.EncryptKey, l.GettextNoop("The merchant key is not valid.")) - } - - return v.AllOK -} -func updatePaymentSettings(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { - f := newPaymentForm(user.Locale) - if ok, err := form.Handle(f, w, r, user); err != nil { - return - } else if !ok { - f.MustRender(w, r, user, company) - return - } - if err := conn.SetupRedsys(r.Context(), company.ID, f.MerchantCode.Val, f.TerminalNumber.Int(), f.Environment.Selected[0], f.Integration.Selected[0], f.EncryptKey.Val); err != nil { - panic(err) - } - httplib.Redirect(w, r, "/admin/booking/payment", http.StatusSeeOther) -} diff --git a/pkg/booking/cart.go b/pkg/booking/cart.go index 3ba9eb2..d2a27ca 100644 --- a/pkg/booking/cart.go +++ b/pkg/booking/cart.go @@ -96,7 +96,6 @@ func newBookingCart(ctx context.Context, conn *database.Conn, f *bookingForm, ca , to_price(total, decimal_digits) , to_price(payment.down_payment, decimal_digits) from draft_payment($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) as payment - join company using (company_id) join currency using (currency_code) `, database.ZeroNullUUID(f.PaymentSlug.Val), @@ -160,7 +159,6 @@ func newBookingCart(ctx context.Context, conn *database.Conn, f *bookingForm, ca , 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) diff --git a/pkg/payment/admin.go b/pkg/payment/admin.go new file mode 100644 index 0000000..de69dfb --- /dev/null +++ b/pkg/payment/admin.go @@ -0,0 +1,339 @@ +package payment + +import ( + "context" + "net/http" + "time" + + "dev.tandem.ws/tandem/camper/pkg/auth" + "dev.tandem.ws/tandem/camper/pkg/database" + httplib "dev.tandem.ws/tandem/camper/pkg/http" + "dev.tandem.ws/tandem/camper/pkg/locale" + "dev.tandem.ws/tandem/camper/pkg/template" + "dev.tandem.ws/tandem/camper/pkg/uuid" +) + +type AdminHandler struct { +} + +func NewAdminHandler() *AdminHandler { + return &AdminHandler{} +} + +func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var head string + head, r.URL.Path = httplib.ShiftPath(r.URL.Path) + + switch head { + case "": + switch r.Method { + case http.MethodGet: + servePaymentIndex(w, r, user, company, conn) + default: + httplib.MethodNotAllowed(w, r, http.MethodGet) + } + case "settings": + head, r.URL.Path = httplib.ShiftPath(r.URL.Path) + switch head { + case "": + switch r.Method { + case http.MethodGet: + f := newSettingsForm(user.Locale) + if err := f.FillFromDatabase(r.Context(), company, conn); err != nil { + if !database.ErrorIsNotFound(err) { + panic(err) + } + } + f.MustRender(w, r, user, company) + case http.MethodPut: + updatePaymentSettings(w, r, user, company, conn) + default: + httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut) + } + default: + http.NotFound(w, r) + } + default: + if !uuid.Valid(head) { + http.NotFound(w, r) + return + } + payment, err := fetchPaymentDetails(r.Context(), conn, head, user.Locale) + if err != nil { + if database.ErrorIsNotFound(err) { + http.NotFound(w, r) + return + } + panic(err) + } + h.paymentHandler(user, company, payment).ServeHTTP(w, r) + } + }) +} + +func (h *AdminHandler) paymentHandler(user *auth.User, company *auth.Company, payment *paymentDetails) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var head string + head, r.URL.Path = httplib.ShiftPath(r.URL.Path) + + switch head { + case "": + switch r.Method { + case http.MethodGet: + payment.MustRender(w, r, user, company) + default: + httplib.MethodNotAllowed(w, r, http.MethodGet) + } + default: + http.NotFound(w, r) + } + }) +} + +func servePaymentIndex(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { + payments, err := collectPaymentEntries(r.Context(), company, conn, user.Locale) + if err != nil { + panic(err) + } + page := &paymentIndex{ + Payments: payments, + } + page.MustRender(w, r, user, company) +} + +type paymentEntry struct { + URL string + Reference string + DownPayment string + Total string + Status string + StatusLabel string + CreatedAt time.Time +} + +func collectPaymentEntries(ctx context.Context, company *auth.Company, conn *database.Conn, locale *locale.Locale) ([]*paymentEntry, error) { + rows, err := conn.Query(ctx, ` + select '/admin/payments/' || payment.slug + , payment.reference + , to_price(payment.down_payment, decimal_digits) + , to_price(total, decimal_digits) + , payment.payment_status + , coalesce(payment_status_i18n.name, payment_status.name) + , created_at + from payment + join currency using (currency_code) + join payment_status using (payment_status) + left join payment_status_i18n on payment_status_i18n.payment_status = payment.payment_status + and payment_status_i18n.lang_tag = $2 + where company_id = $1 + order by created_at desc + `, company.ID, locale.Language) + if err != nil { + return nil, err + } + defer rows.Close() + + var payments []*paymentEntry + for rows.Next() { + entry := &paymentEntry{} + if err = rows.Scan( + &entry.URL, + &entry.Reference, + &entry.DownPayment, + &entry.Total, + &entry.Status, + &entry.StatusLabel, + &entry.CreatedAt, + ); err != nil { + return nil, err + } + payments = append(payments, entry) + } + + return payments, nil +} + +type paymentIndex struct { + Payments []*paymentEntry +} + +func (page *paymentIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { + template.MustRenderAdmin(w, r, user, company, "payment/index.gohtml", page) +} + +type paymentDetails struct { + ID int + Reference string + CampsiteType string + ArrivalDate time.Time + DepartureDate time.Time + NumNights int + NumAdults int + NumTeenagers int + NumChildren int + NumDogs int + SubtotalTouristTax string + Total string + DownPaymentPercent int + DownPayment string + ZonePreferences string + Status string + StatusLabel string + CreatedAt time.Time + UpdatedAt time.Time + Options []*paymentOption + Customer *paymentCustomer +} + +type paymentOption struct { + Label string + Units int +} + +type paymentCustomer struct { + FullName string + Address string + PostalCode string + City string + Country string + Email string + Phone string + Language string + ACSICard bool +} + +func fetchPaymentDetails(ctx context.Context, conn *database.Conn, slug string, locale *locale.Locale) (*paymentDetails, error) { + row := conn.QueryRow(ctx, ` + select payment_id + , payment.reference + , coalesce(campsite_type_i18n.name, campsite_type.name) + , arrival_date + , departure_date + , departure_date - arrival_date + , number_adults + , number_teenagers + , number_children + , number_dogs + , to_price(subtotal_tourist_tax, decimal_digits) + , to_price(total, decimal_digits) + , (down_payment_percent * 100)::integer + , to_price(payment.down_payment, decimal_digits) + , zone_preferences + , payment.payment_status + , coalesce(payment_status_i18n.name, payment_status.name) + , created_at + , updated_at + from payment + join currency using (currency_code) + join campsite_type using (campsite_type_id) + join payment_status using (payment_status) + left join payment_status_i18n on payment_status_i18n.payment_status = payment.payment_status + and payment_status_i18n.lang_tag = $2 + left join campsite_type_i18n on campsite_type_i18n.campsite_type_id = campsite_type.campsite_type_id + and campsite_type_i18n.lang_tag = $2 + where payment.slug = $1 + `, slug, locale.Language) + details := &paymentDetails{} + if err := row.Scan( + &details.ID, + &details.Reference, + &details.CampsiteType, + &details.ArrivalDate, + &details.DepartureDate, + &details.NumNights, + &details.NumAdults, + &details.NumTeenagers, + &details.NumChildren, + &details.NumDogs, + &details.SubtotalTouristTax, + &details.Total, + &details.DownPaymentPercent, + &details.DownPayment, + &details.ZonePreferences, + &details.Status, + &details.StatusLabel, + &details.CreatedAt, + &details.UpdatedAt, + ); err != nil { + return nil, err + } + + var err error + details.Options, err = fetchPaymentOptions(ctx, conn, details.ID, locale) + if err != nil && !database.ErrorIsNotFound(err) { + return nil, err + } + + details.Customer, err = fetchPaymentCustomer(ctx, conn, details.ID, locale) + if err != nil && !database.ErrorIsNotFound(err) { + return nil, err + } + + return details, nil +} + +func fetchPaymentOptions(ctx context.Context, conn *database.Conn, paymentID int, locale *locale.Locale) ([]*paymentOption, error) { + rows, err := conn.Query(ctx, ` + select coalesce(option_i18n.name, option.name) + , units + from payment_option + join campsite_type_option as option using (campsite_type_option_id) + left join campsite_type_option_i18n as option_i18n on option_i18n.campsite_type_option_id = option.campsite_type_option_id + and option_i18n.lang_tag = $2 + where payment_id = $1 +`, paymentID, locale.Language) + if err != nil { + return nil, err + } + defer rows.Close() + + var options []*paymentOption + for rows.Next() { + option := &paymentOption{} + if err = rows.Scan(&option.Label, &option.Units); err != nil { + return nil, err + } + options = append(options, option) + } + return options, nil +} + +func fetchPaymentCustomer(ctx context.Context, conn *database.Conn, paymentID int, locale *locale.Locale) (*paymentCustomer, error) { + row := conn.QueryRow(ctx, ` + select full_name + , address + , postal_code + , city + , coalesce(country_i18n.name, country.name) + , email + , phone::text + , language.endonym + , acsi_card + from payment_customer + join country using (country_code) + left join country_i18n on country.country_code = country_i18n.country_code + and country_i18n.lang_tag = $2 + join language on payment_customer.lang_tag = language.lang_tag + where payment_id = $1 +`, paymentID, locale.Language) + customer := &paymentCustomer{} + if err := row.Scan( + &customer.FullName, + &customer.Address, + &customer.PostalCode, + &customer.City, + &customer.Country, + &customer.Email, + &customer.Phone, + &customer.Language, + &customer.ACSICard, + ); err != nil { + return nil, err + } + return customer, nil +} + +func (f *paymentDetails) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { + template.MustRenderAdmin(w, r, user, company, "payment/details.gohtml", f) +} diff --git a/pkg/payment/public.go b/pkg/payment/public.go index fdd5bf9..a22dcbe 100644 --- a/pkg/payment/public.go +++ b/pkg/payment/public.go @@ -74,17 +74,17 @@ func fetchPayment(ctx context.Context, conn *database.Conn, paymentSlug string) row := conn.QueryRow(ctx, ` select payment_id , payment.slug::text + , payment.reference , payment.created_at , to_price(total, decimal_digits) , to_price(payment.down_payment, decimal_digits) from payment - join company using (company_id) join currency using (currency_code) where payment.slug = $1 and payment_status <> 'draft' `, paymentSlug) payment := &Payment{} - if err := row.Scan(&payment.ID, &payment.Slug, &payment.CreateTime, &payment.Total, &payment.DownPayment); err != nil { + if err := row.Scan(&payment.ID, &payment.Slug, &payment.Reference, &payment.CreateTime, &payment.Total, &payment.DownPayment); err != nil { return nil, err } return payment, nil @@ -93,6 +93,7 @@ func fetchPayment(ctx context.Context, conn *database.Conn, paymentSlug string) type Payment struct { ID int Slug string + Reference string Total string DownPayment string CreateTime time.Time @@ -105,7 +106,7 @@ func (payment *Payment) createRequest(r *http.Request, user *auth.User, company request := redsys.Request{ TransactionType: redsys.TransactionTypeCharge, Amount: payment.DownPayment, - OrderNumber: payment.OrderNumber(), + OrderNumber: payment.Reference, Product: user.Locale.Pgettext("Campsite Booking", "order product name"), SuccessURL: fmt.Sprintf("%s/success", baseURL), FailureURL: fmt.Sprintf("%s/failure", baseURL), @@ -115,10 +116,6 @@ func (payment *Payment) createRequest(r *http.Request, user *auth.User, company return request.Sign(r.Context(), conn, company) } -func (payment *Payment) OrderNumber() string { - return fmt.Sprintf("%08d%s", payment.ID, payment.Slug[:4]) -} - type paymentPage struct { *template.PublicPage Environment string @@ -240,7 +237,7 @@ func handleNotification(w http.ResponseWriter, r *http.Request, user *auth.User, http.Error(w, "Invalid response", http.StatusBadRequest) return } - if response.OrderNumber != payment.OrderNumber() { + if response.OrderNumber != payment.Reference { http.Error(w, "Response for a different payment", http.StatusBadRequest) return } @@ -287,7 +284,7 @@ type address struct { func sendEmail(ctx context.Context, conn *database.Conn, payment *Payment, company *auth.Company, locale *locale.Locale) error { email := &CompletedEmail{ CurrentLocale: locale.Language.String(), - PaymentReference: payment.OrderNumber(), + PaymentReference: payment.Reference, Total: template.FormatPrice(payment.Total, locale.Language, locale.CurrencyPattern, company.DecimalDigits, company.CurrencySymbol), DownPayment: template.FormatPrice(payment.DownPayment, locale.Language, locale.CurrencyPattern, company.DecimalDigits, company.CurrencySymbol), CompanyAddress: &address{}, diff --git a/pkg/payment/settings.go b/pkg/payment/settings.go new file mode 100644 index 0000000..07c5b40 --- /dev/null +++ b/pkg/payment/settings.go @@ -0,0 +1,135 @@ +package payment + +import ( + "context" + "net/http" + + "dev.tandem.ws/tandem/camper/pkg/auth" + "dev.tandem.ws/tandem/camper/pkg/database" + "dev.tandem.ws/tandem/camper/pkg/form" + httplib "dev.tandem.ws/tandem/camper/pkg/http" + "dev.tandem.ws/tandem/camper/pkg/locale" + "dev.tandem.ws/tandem/camper/pkg/template" +) + +type settingsForm struct { + MerchantCode *form.Input + TerminalNumber *form.Input + Environment *form.Select + Integration *form.Select + EncryptKey *form.Input +} + +func newSettingsForm(l *locale.Locale) *settingsForm { + return &settingsForm{ + + MerchantCode: &form.Input{ + Name: "merchant_code", + }, + TerminalNumber: &form.Input{ + Name: "terminal_number", + }, + Environment: &form.Select{ + Name: "environment", + Options: []*form.Option{ + { + Value: "test", + Label: l.Pgettext("Test", "redsys environment"), + }, + { + Value: "live", + Label: l.Pgettext("Live", "redsys environment"), + }, + }, + }, + Integration: &form.Select{ + Name: "integration", + Options: []*form.Option{ + { + Value: "insite", + Label: l.Pgettext("InSite", "redsys integration"), + }, + { + Value: "redirect", + Label: l.Pgettext("Redirect", "redsys integration"), + }, + }, + }, + EncryptKey: &form.Input{ + Name: "encrypt_key", + }, + } +} + +func (f *settingsForm) FillFromDatabase(ctx context.Context, company *auth.Company, conn *database.Conn) error { + return conn.QueryRow(ctx, ` + select merchant_code + , terminal_number::text + , array[environment::text] + , array[integration::text] + from redsys + where company_id = $1`, company.ID).Scan( + &f.MerchantCode.Val, + &f.TerminalNumber.Val, + &f.Environment.Selected, + &f.Integration.Selected, + ) +} + +func (f *settingsForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { + template.MustRenderAdmin(w, r, user, company, "payment/settings.gohtml", f) +} + +func (f *settingsForm) Parse(r *http.Request) error { + if err := r.ParseForm(); err != nil { + return err + } + f.MerchantCode.FillValue(r) + f.TerminalNumber.FillValue(r) + f.Environment.FillValue(r) + f.Integration.FillValue(r) + f.EncryptKey.FillValue(r) + return nil +} + +func (f *settingsForm) Valid(l *locale.Locale) bool { + v := form.NewValidator(l) + + if v.CheckRequired(f.MerchantCode, l.GettextNoop("Merchant code can not be empty.")) { + if v.CheckExactLength(f.MerchantCode, 9, l.GettextNoop("Merchant code must be exactly nine digits long.")) { + v.CheckValidInteger(f.MerchantCode, l.GettextNoop("Merchant code must be a number.")) + } + } + + if v.CheckRequired(f.TerminalNumber, l.GettextNoop("Terminal number can not be empty.")) { + message := l.GettextNoop("Terminal number must be a number between 1 and 999.") + if v.CheckValidInteger(f.TerminalNumber, message) { + if v.CheckMinInteger(f.TerminalNumber, 1, message) { + v.CheckMaxInteger(f.TerminalNumber, 999, message) + } + } + } + + v.CheckSelectedOptions(f.Environment, l.GettextNoop("Selected environment is not valid.")) + v.CheckSelectedOptions(f.Integration, l.GettextNoop("Selected integration is not valid.")) + + if f.EncryptKey.Val != "" { + v.CheckValidBase64(f.EncryptKey, l.GettextNoop("The merchant key is not valid.")) + } + + return v.AllOK +} + +func updatePaymentSettings(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { + f := newSettingsForm(user.Locale) + if ok, err := form.Handle(f, w, r, user); err != nil { + return + } else if !ok { + f.MustRender(w, r, user, company) + return + } + if err := conn.SetupRedsys(r.Context(), company.ID, f.MerchantCode.Val, f.TerminalNumber.Int(), f.Environment.Selected[0], f.Integration.Selected[0], f.EncryptKey.Val); err != nil { + panic(err) + } + httplib.Redirect(w, r, "/admin/payments", http.StatusSeeOther) +} diff --git a/pkg/template/render.go b/pkg/template/render.go index 34de752..79e791b 100644 --- a/pkg/template/render.go +++ b/pkg/template/render.go @@ -107,6 +107,9 @@ func mustRenderLayout(w io.Writer, user *auth.User, company *auth.Company, templ "formatDate": func(time time.Time) template.HTML { return template.HTML(`") }, + "formatDateTime": func(time time.Time) template.HTML { + return template.HTML(`") + }, "formatDateAttr": func(time time.Time) string { return time.Format(database.ISODateFormat) }, diff --git a/po/ca.po b/po/ca.po index 65fe5de..59dff74 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-02-13 23:38+0100\n" +"POT-Creation-Date: 2024-02-14 04:43+0100\n" "PO-Revision-Date: 2024-02-06 10:04+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -380,12 +380,14 @@ msgstr "dg" #: web/templates/public/campsite/dates.gohtml:4 #: web/templates/public/booking/fields.gohtml:29 +#: web/templates/admin/payment/details.gohtml:52 msgctxt "input" msgid "Arrival date" msgstr "Data d’arribada" #: web/templates/public/campsite/dates.gohtml:15 #: web/templates/public/booking/fields.gohtml:40 +#: web/templates/admin/payment/details.gohtml:56 msgctxt "input" msgid "Departure date" msgstr "Data de sortida" @@ -624,6 +626,7 @@ msgstr "Allotjaments" #: web/templates/public/layout.gohtml:70 #: web/templates/public/booking/page.gohtml:7 +#: web/templates/admin/payment/details.gohtml:41 msgctxt "title" msgid "Booking" msgstr "Reserva" @@ -643,9 +646,10 @@ msgid "RTC Núm. RTC %s" #: web/templates/public/booking/fields.gohtml:14 +#: web/templates/admin/payment/details.gohtml:44 msgctxt "title" msgid "Accommodation" -msgstr "Allotjaments" +msgstr "Allotjament" #: web/templates/public/booking/fields.gohtml:26 msgctxt "title" @@ -658,25 +662,29 @@ msgid "Guests" msgstr "Hostes" #: web/templates/public/booking/fields.gohtml:59 +#: web/templates/admin/payment/details.gohtml:64 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adults de 17 anys o més" #: web/templates/public/booking/fields.gohtml:70 +#: web/templates/admin/payment/details.gohtml:68 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescents d’entre 11 i 16 anys" #: web/templates/public/booking/fields.gohtml:81 +#: web/templates/admin/payment/details.gohtml:72 msgctxt "input" msgid "Children from 2 to 10 years old" -msgstr "Nens d’entre 2 i 10 anys)" +msgstr "Nens d’entre 2 i 10 anys" #: web/templates/public/booking/fields.gohtml:91 msgid "Note: Due to guest capacity, we have added more accomodations to the booking, but we cannot guarantee that they will be next to each other." msgstr "Nota: S’han afegit més allotjaments a la reserva degut a la capacitat de cadascuna, però no es garanteix que estiguin de costat." #: web/templates/public/booking/fields.gohtml:99 +#: web/templates/admin/payment/details.gohtml:76 msgctxt "input" msgid "Dogs" msgstr "Gossos" @@ -695,11 +703,13 @@ msgid "Campground map" msgstr "Mapa del càmping" #: web/templates/public/booking/fields.gohtml:145 +#: web/templates/admin/payment/details.gohtml:106 msgctxt "title" msgid "Customer Details" msgstr "Detalls del client" #: web/templates/public/booking/fields.gohtml:148 +#: web/templates/admin/payment/details.gohtml:109 msgctxt "input" msgid "Full name" msgstr "Nom i cognoms" @@ -720,6 +730,7 @@ msgid "Town or village (optional)" msgstr "Població (opcional)" #: web/templates/public/booking/fields.gohtml:184 +#: web/templates/admin/payment/details.gohtml:125 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -730,6 +741,7 @@ msgid "Choose a country" msgstr "Esculli un país" #: web/templates/public/booking/fields.gohtml:195 +#: web/templates/admin/payment/details.gohtml:129 #: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38 #: web/templates/admin/taxDetails.gohtml:53 msgctxt "input" @@ -737,6 +749,7 @@ msgid "Email" msgstr "Correu-e" #: web/templates/public/booking/fields.gohtml:204 +#: web/templates/admin/payment/details.gohtml:133 #: web/templates/admin/taxDetails.gohtml:45 msgctxt "input" msgid "Phone" @@ -758,10 +771,186 @@ msgid "Total" msgstr "Total" #: web/templates/public/booking/fields.gohtml:244 +#: web/templates/admin/payment/details.gohtml:84 msgctxt "cart" msgid "Down payment" msgstr "A compte" +#: web/templates/admin/payment/settings.gohtml:6 +#: web/templates/admin/payment/index.gohtml:14 +msgctxt "title" +msgid "Payment Settings" +msgstr "Paràmetres de pagament" + +#: web/templates/admin/payment/settings.gohtml:10 +#: web/templates/admin/payment/index.gohtml:6 +#: web/templates/admin/payment/details.gohtml:11 +#: web/templates/admin/layout.gohtml:40 +msgctxt "title" +msgid "Payments" +msgstr "Pagaments" + +#: web/templates/admin/payment/settings.gohtml:21 +msgctxt "input" +msgid "Merchant Code" +msgstr "Codi del comerç" + +#: web/templates/admin/payment/settings.gohtml:30 +msgctxt "input" +msgid "Terminal Number" +msgstr "Número de terminal" + +#: web/templates/admin/payment/settings.gohtml:40 +msgctxt "input" +msgid "Merchant Key (only if must change it)" +msgstr "Clau del comerç (només si s’ha de canviar)" + +#: web/templates/admin/payment/settings.gohtml:42 +msgctxt "input" +msgid "Merchant Key" +msgstr "Clau del comerç" + +#: web/templates/admin/payment/settings.gohtml:52 +msgctxt "title" +msgid "Environment" +msgstr "Entorn" + +#: web/templates/admin/payment/settings.gohtml:59 +msgctxt "title" +msgid "Integration" +msgstr "Integració" + +#: web/templates/admin/payment/settings.gohtml:66 +#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 +#: web/templates/admin/taxDetails.gohtml:170 +msgctxt "action" +msgid "Save changes" +msgstr "Desa els canvis" + +#: web/templates/admin/payment/index.gohtml:20 +#: web/templates/admin/user/login-attempts.gohtml:19 +msgctxt "header" +msgid "Date" +msgstr "Data" + +#: web/templates/admin/payment/index.gohtml:21 +#: web/templates/admin/payment/details.gohtml:22 +#: web/templates/admin/booking/index.gohtml:21 +msgctxt "header" +msgid "Reference" +msgstr "Referència" + +#: web/templates/admin/payment/index.gohtml:22 +#: web/templates/admin/payment/details.gohtml:26 +#: web/templates/admin/booking/index.gohtml:25 +msgctxt "header" +msgid "Status" +msgstr "Estat" + +#: web/templates/admin/payment/index.gohtml:23 +msgctxt "header" +msgid "Down payment" +msgstr "A compte" + +#: web/templates/admin/payment/index.gohtml:24 +msgctxt "header" +msgid "Total" +msgstr "Total" + +#: web/templates/admin/payment/index.gohtml:40 +msgid "No payments found." +msgstr "No s’ha trobat cap pagament." + +#: web/templates/admin/payment/details.gohtml:7 +msgctxt "title" +msgid "Payment %s" +msgstr "Pagament %s" + +#: web/templates/admin/payment/details.gohtml:19 +msgctxt "title" +msgid "Payment" +msgstr "Pagament" + +#: web/templates/admin/payment/details.gohtml:30 +msgctxt "payment header" +msgid "Created at" +msgstr "Creat el" + +#: web/templates/admin/payment/details.gohtml:34 +msgctxt "payment header" +msgid "Last updated at" +msgstr "Actualitzat per darrera vegada el" + +#: web/templates/admin/payment/details.gohtml:48 +msgctxt "header" +msgid "Area preferences" +msgstr "Preferències d’àrea" + +#: web/templates/admin/payment/details.gohtml:60 +msgctxt "cart" +msgid "Nights" +msgstr "Nits" + +#: web/templates/admin/payment/details.gohtml:80 pkg/booking/cart.go:188 +msgctxt "cart" +msgid "Tourist tax" +msgstr "Impost turístic" + +#: web/templates/admin/payment/details.gohtml:92 +#: web/templates/admin/campsite/type/option/form.gohtml:18 +#: web/templates/admin/campsite/type/option/index.gohtml:6 +#: web/templates/admin/campsite/type/option/index.gohtml:17 +msgctxt "title" +msgid "Campsite Type Options" +msgstr "Opcions del tipus d’allotjament" + +#: web/templates/admin/payment/details.gohtml:113 +#: web/templates/admin/taxDetails.gohtml:69 +msgctxt "input" +msgid "Address" +msgstr "Adreça" + +#: web/templates/admin/payment/details.gohtml:117 +#: web/templates/admin/taxDetails.gohtml:93 +msgctxt "input" +msgid "Postcode" +msgstr "Codi postal" + +#: web/templates/admin/payment/details.gohtml:121 +#: web/templates/admin/taxDetails.gohtml:77 +msgctxt "input" +msgid "City" +msgstr "Població" + +#: web/templates/admin/payment/details.gohtml:137 +#: web/templates/admin/profile.gohtml:68 +msgctxt "input" +msgid "Language" +msgstr "Idioma" + +#: web/templates/admin/payment/details.gohtml:141 +msgctxt "input" +msgid "ACSI card?" +msgstr "Targeta ACSI?" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "Yes" +msgstr "Sí" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "No" +msgstr "No" + #: web/templates/admin/legal/form.gohtml:8 #: web/templates/admin/legal/form.gohtml:29 msgctxt "title" @@ -911,13 +1100,6 @@ msgctxt "input" msgid "Map Embed" msgstr "Incrustació del mapa" -#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 -#: web/templates/admin/taxDetails.gohtml:170 -#: web/templates/admin/booking/payment.gohtml:65 -msgctxt "action" -msgid "Save changes" -msgstr "Desa els canvis" - #: web/templates/admin/campsite/feature/form.gohtml:8 msgctxt "title" msgid "Edit Campsite Feature" @@ -1145,22 +1327,6 @@ msgctxt "action" msgid "Edit Carousel" msgstr "Edita el carrusel" -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "Yes" -msgstr "Sí" - -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "No" -msgstr "No" - #: web/templates/admin/campsite/index.gohtml:47 msgid "No campsites added yet." msgstr "No s’ha afegit cap allotjament encara." @@ -1368,13 +1534,6 @@ msgctxt "title" msgid "New Campsite Type Option" msgstr "Nova opció del tipus d’allotjament" -#: web/templates/admin/campsite/type/option/form.gohtml:18 -#: web/templates/admin/campsite/type/option/index.gohtml:6 -#: web/templates/admin/campsite/type/option/index.gohtml:17 -msgctxt "title" -msgid "Campsite Type Options" -msgstr "Opcions del tipus d’allotjament" - #: web/templates/admin/campsite/type/option/form.gohtml:54 msgctxt "input" msgid "Minimum" @@ -1568,11 +1727,6 @@ msgctxt "input" msgid "Password Confirmation" msgstr "Confirmació de la contrasenya" -#: web/templates/admin/profile.gohtml:68 -msgctxt "input" -msgid "Language" -msgstr "Idioma" - #: web/templates/admin/user/login-attempts.gohtml:6 #: web/templates/admin/user/login-attempts.gohtml:15 msgctxt "title" @@ -1587,11 +1741,6 @@ msgctxt "title" msgid "Users" msgstr "Usuaris" -#: web/templates/admin/user/login-attempts.gohtml:19 -msgctxt "header" -msgid "Date" -msgstr "Data" - #: web/templates/admin/user/login-attempts.gohtml:20 #: web/templates/admin/user/index.gohtml:21 msgctxt "header" @@ -1649,26 +1798,11 @@ msgctxt "input" msgid "Trade Name" msgstr "Nom comercial" -#: web/templates/admin/taxDetails.gohtml:69 -msgctxt "input" -msgid "Address" -msgstr "Adreça" - -#: web/templates/admin/taxDetails.gohtml:77 -msgctxt "input" -msgid "City" -msgstr "Població" - #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Província" -#: web/templates/admin/taxDetails.gohtml:93 -msgctxt "input" -msgid "Postcode" -msgstr "Codi postal" - #: web/templates/admin/taxDetails.gohtml:111 msgctxt "input" msgid "Currency" @@ -1854,13 +1988,6 @@ msgctxt "title" msgid "Company Settings" msgstr "Paràmetres de l’empresa" -#: web/templates/admin/layout.gohtml:40 -#: web/templates/admin/booking/payment.gohtml:6 -#: web/templates/admin/booking/payment.gohtml:15 -msgctxt "title" -msgid "Payment Settings" -msgstr "Paràmetres de pagament" - #: web/templates/admin/layout.gohtml:55 #: web/templates/admin/media/form.gohtml:10 #: web/templates/admin/media/index.gohtml:6 @@ -1988,36 +2115,6 @@ msgctxt "title" msgid "Upload Media" msgstr "Pujada de mèdia" -#: web/templates/admin/booking/payment.gohtml:20 -msgctxt "input" -msgid "Merchant Code" -msgstr "Codi del comerç" - -#: web/templates/admin/booking/payment.gohtml:29 -msgctxt "input" -msgid "Terminal Number" -msgstr "Número de terminal" - -#: web/templates/admin/booking/payment.gohtml:39 -msgctxt "input" -msgid "Merchant Key (only if must change it)" -msgstr "Clau del comerç (només si s’ha de canviar)" - -#: web/templates/admin/booking/payment.gohtml:41 -msgctxt "input" -msgid "Merchant Key" -msgstr "Clau del comerç" - -#: web/templates/admin/booking/payment.gohtml:51 -msgctxt "title" -msgid "Environment" -msgstr "Entorn" - -#: web/templates/admin/booking/payment.gohtml:58 -msgctxt "title" -msgid "Integration" -msgstr "Integració" - #: web/templates/admin/booking/index.gohtml:14 msgctxt "action" msgid "Add Booking" @@ -2028,11 +2125,6 @@ msgctxt "action" msgid "Export Bookings" msgstr "Exporta reserves" -#: web/templates/admin/booking/index.gohtml:21 -msgctxt "header" -msgid "Reference" -msgstr "Referència" - #: web/templates/admin/booking/index.gohtml:22 msgctxt "header" msgid "Arrival Date" @@ -2048,21 +2140,68 @@ msgctxt "header" msgid "Holder Name" msgstr "Nom del titular" -#: web/templates/admin/booking/index.gohtml:25 -msgctxt "header" -msgid "Status" -msgstr "Estat" - #: web/templates/admin/booking/index.gohtml:41 msgid "No booking found." msgstr "No s’ha trobat cap reserva." -#: pkg/payment/public.go:109 +#: pkg/payment/settings.go:37 +msgctxt "redsys environment" +msgid "Test" +msgstr "Proves" + +#: pkg/payment/settings.go:41 +msgctxt "redsys environment" +msgid "Live" +msgstr "Real" + +#: pkg/payment/settings.go:50 +msgctxt "redsys integration" +msgid "InSite" +msgstr "InSite" + +#: pkg/payment/settings.go:54 +msgctxt "redsys integration" +msgid "Redirect" +msgstr "Redirecció" + +#: pkg/payment/settings.go:98 +msgid "Merchant code can not be empty." +msgstr "No podeu deixar el codi del comerç en blanc." + +#: pkg/payment/settings.go:99 +msgid "Merchant code must be exactly nine digits long." +msgstr "El codi del comerç ha de ser de nou dígits." + +#: pkg/payment/settings.go:100 +msgid "Merchant code must be a number." +msgstr "El codi del comerç." + +#: pkg/payment/settings.go:104 +msgid "Terminal number can not be empty." +msgstr "No podeu deixar el número del terminal en blanc." + +#: pkg/payment/settings.go:105 +msgid "Terminal number must be a number between 1 and 999." +msgstr "El número del terminal ha de ser entre 1 i 999" + +#: pkg/payment/settings.go:113 +msgid "Selected environment is not valid." +msgstr "L’entorn escollit no és vàlid." + +#: pkg/payment/settings.go:114 +msgid "Selected integration is not valid." +msgstr "La integració escollida no és vàlida." + +#: pkg/payment/settings.go:117 +msgid "The merchant key is not valid." +msgstr "Aquesta clau del comerç no és vàlid." + +#: pkg/payment/public.go:110 msgctxt "order product name" msgid "Campsite Booking" msgstr "Reserva de càmping" -#: pkg/payment/public.go:346 +#: pkg/payment/public.go:342 msgctxt "subject" msgid "Booking payment successfully received" msgstr "Rebut amb èxit el pagament de la reserva" @@ -2140,7 +2279,7 @@ msgstr "L’idioma escollit no és vàlid." msgid "File must be a valid PNG or JPEG image." msgstr "El fitxer has de ser una imatge PNG o JPEG vàlida." -#: pkg/app/admin.go:70 +#: pkg/app/admin.go:73 msgid "Access forbidden" msgstr "Accés prohibit" @@ -2563,93 +2702,36 @@ 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:151 +#: pkg/booking/cart.go:150 msgctxt "cart" msgid "Night" msgstr "Nit" -#: pkg/booking/cart.go:152 +#: pkg/booking/cart.go:151 msgctxt "cart" msgid "Adult" msgstr "Adult" -#: pkg/booking/cart.go:153 +#: pkg/booking/cart.go:152 msgctxt "cart" msgid "Teenager" msgstr "Adolescent" -#: pkg/booking/cart.go:154 +#: pkg/booking/cart.go:153 msgctxt "cart" msgid "Child" msgstr "Nen" -#: pkg/booking/cart.go:155 +#: pkg/booking/cart.go:154 msgctxt "cart" msgid "Dog" msgstr "Gos" -#: pkg/booking/cart.go:190 -msgctxt "cart" -msgid "Tourist tax" -msgstr "Impost turístic" - -#: pkg/booking/admin.go:149 +#: pkg/booking/admin.go:126 msgctxt "filename" msgid "bookings.ods" msgstr "reserves.ods" -#: pkg/booking/admin.go:177 -msgctxt "redsys environment" -msgid "Test" -msgstr "Proves" - -#: pkg/booking/admin.go:181 -msgctxt "redsys environment" -msgid "Live" -msgstr "Real" - -#: pkg/booking/admin.go:190 -msgctxt "redsys integration" -msgid "InSite" -msgstr "InSite" - -#: pkg/booking/admin.go:194 -msgctxt "redsys integration" -msgid "Redirect" -msgstr "Redirecció" - -#: pkg/booking/admin.go:238 -msgid "Merchant code can not be empty." -msgstr "No podeu deixar el codi del comerç en blanc." - -#: pkg/booking/admin.go:239 -msgid "Merchant code must be exactly nine digits long." -msgstr "El codi del comerç ha de ser de nou dígits." - -#: pkg/booking/admin.go:240 -msgid "Merchant code must be a number." -msgstr "El codi del comerç." - -#: pkg/booking/admin.go:244 -msgid "Terminal number can not be empty." -msgstr "No podeu deixar el número del terminal en blanc." - -#: pkg/booking/admin.go:245 -msgid "Terminal number must be a number between 1 and 999." -msgstr "El número del terminal ha de ser entre 1 i 999" - -#: pkg/booking/admin.go:253 -msgid "Selected environment is not valid." -msgstr "L’entorn escollit no és vàlid." - -#: pkg/booking/admin.go:254 -msgid "Selected integration is not valid." -msgstr "La integració escollida no és vàlida." - -#: pkg/booking/admin.go:257 -msgid "The merchant key is not valid." -msgstr "Aquesta clau del comerç no és vàlid." - #: pkg/booking/public.go:275 pkg/booking/public.go:304 msgid "Arrival date must be a valid date." msgstr "La data d’arribada ha de ser una data vàlida." @@ -2771,10 +2853,6 @@ msgstr "El nom i els cognoms han de tenir com a mínim una lletra." msgid "It is mandatory to agree to the reservation conditions." msgstr "És obligatori acceptar les condicions de reserves." -#~ msgctxt "title" -#~ msgid "Payment" -#~ msgstr "Pagament" - #~ msgctxt "action" #~ msgid "Pay" #~ msgstr "Paga" diff --git a/po/es.po b/po/es.po index c28cf2d..d6c3575 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-02-13 23:38+0100\n" +"POT-Creation-Date: 2024-02-14 04:47+0100\n" "PO-Revision-Date: 2024-02-06 10:04+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -380,12 +380,14 @@ msgstr "do" #: web/templates/public/campsite/dates.gohtml:4 #: web/templates/public/booking/fields.gohtml:29 +#: web/templates/admin/payment/details.gohtml:52 msgctxt "input" msgid "Arrival date" msgstr "Fecha de llegada" #: web/templates/public/campsite/dates.gohtml:15 #: web/templates/public/booking/fields.gohtml:40 +#: web/templates/admin/payment/details.gohtml:56 msgctxt "input" msgid "Departure date" msgstr "Fecha de salida" @@ -624,6 +626,7 @@ msgstr "Alojamientos" #: web/templates/public/layout.gohtml:70 #: web/templates/public/booking/page.gohtml:7 +#: web/templates/admin/payment/details.gohtml:41 msgctxt "title" msgid "Booking" msgstr "Reserva" @@ -643,6 +646,7 @@ msgid "RTC RTC %s" #: web/templates/public/booking/fields.gohtml:14 +#: web/templates/admin/payment/details.gohtml:44 msgctxt "title" msgid "Accommodation" msgstr "Alojamientos" @@ -658,16 +662,19 @@ msgid "Guests" msgstr "Huéspedes" #: web/templates/public/booking/fields.gohtml:59 +#: web/templates/admin/payment/details.gohtml:64 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adultos de 17 años o más" #: web/templates/public/booking/fields.gohtml:70 +#: web/templates/admin/payment/details.gohtml:68 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescentes de 11 a 16 años" #: web/templates/public/booking/fields.gohtml:81 +#: web/templates/admin/payment/details.gohtml:72 msgctxt "input" msgid "Children from 2 to 10 years old" msgstr "Niños de 2 a 10 años" @@ -677,6 +684,7 @@ msgid "Note: Due to guest capacity, we have added more accomodations to the book msgstr "Nota: Se han añadido alojamientos a la reserva debido a la capacidad de cada una, pero no se garantiza que estén de lado." #: web/templates/public/booking/fields.gohtml:99 +#: web/templates/admin/payment/details.gohtml:76 msgctxt "input" msgid "Dogs" msgstr "Perros" @@ -695,11 +703,13 @@ msgid "Campground map" msgstr "Mapa del camping" #: web/templates/public/booking/fields.gohtml:145 +#: web/templates/admin/payment/details.gohtml:106 msgctxt "title" msgid "Customer Details" msgstr "Detalles del cliente" #: web/templates/public/booking/fields.gohtml:148 +#: web/templates/admin/payment/details.gohtml:109 msgctxt "input" msgid "Full name" msgstr "Nombre y apellidos" @@ -720,6 +730,7 @@ msgid "Town or village (optional)" msgstr "Población (opcional)" #: web/templates/public/booking/fields.gohtml:184 +#: web/templates/admin/payment/details.gohtml:125 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -730,6 +741,7 @@ msgid "Choose a country" msgstr "Escoja un país" #: web/templates/public/booking/fields.gohtml:195 +#: web/templates/admin/payment/details.gohtml:129 #: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38 #: web/templates/admin/taxDetails.gohtml:53 msgctxt "input" @@ -737,6 +749,7 @@ msgid "Email" msgstr "Correo-e" #: web/templates/public/booking/fields.gohtml:204 +#: web/templates/admin/payment/details.gohtml:133 #: web/templates/admin/taxDetails.gohtml:45 msgctxt "input" msgid "Phone" @@ -758,10 +771,188 @@ msgid "Total" msgstr "Total" #: web/templates/public/booking/fields.gohtml:244 +#: web/templates/admin/payment/details.gohtml:84 msgctxt "cart" msgid "Down payment" msgstr "A cuenta" +#: web/templates/admin/payment/settings.gohtml:6 +#: web/templates/admin/payment/index.gohtml:14 +msgctxt "title" +msgid "Payment Settings" +msgstr "Parámetros de pago" + +#: web/templates/admin/payment/settings.gohtml:10 +#: web/templates/admin/payment/index.gohtml:6 +#: web/templates/admin/payment/details.gohtml:11 +#: web/templates/admin/layout.gohtml:40 +msgctxt "title" +msgid "Payments" +msgstr "Pagos" + +#: web/templates/admin/payment/settings.gohtml:21 +msgctxt "input" +msgid "Merchant Code" +msgstr "Código del comercio" + +#: web/templates/admin/payment/settings.gohtml:30 +msgctxt "input" +msgid "Terminal Number" +msgstr "Número de terminal" + +#: web/templates/admin/payment/settings.gohtml:40 +msgctxt "input" +msgid "Merchant Key (only if must change it)" +msgstr "Clave del comercio (sólo si se debe cambiar)" + +#: web/templates/admin/payment/settings.gohtml:42 +msgctxt "input" +msgid "Merchant Key" +msgstr "Clave del comercio" + +#: web/templates/admin/payment/settings.gohtml:52 +msgctxt "title" +msgid "Environment" +msgstr "Entorno" + +#: web/templates/admin/payment/settings.gohtml:59 +msgctxt "title" +msgid "Integration" +msgstr "Integración" + +#: web/templates/admin/payment/settings.gohtml:66 +#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 +#: web/templates/admin/taxDetails.gohtml:170 +msgctxt "action" +msgid "Save changes" +msgstr "Guardar los cambios" + +#: web/templates/admin/payment/index.gohtml:20 +#: web/templates/admin/user/login-attempts.gohtml:19 +msgctxt "header" +msgid "Date" +msgstr "Fecha" + +#: web/templates/admin/payment/index.gohtml:21 +#: web/templates/admin/payment/details.gohtml:22 +#: web/templates/admin/booking/index.gohtml:21 +msgctxt "header" +msgid "Reference" +msgstr "Referencia" + +#: web/templates/admin/payment/index.gohtml:22 +#: web/templates/admin/payment/details.gohtml:26 +#: web/templates/admin/booking/index.gohtml:25 +msgctxt "header" +msgid "Status" +msgstr "Estado" + +#: web/templates/admin/payment/index.gohtml:23 +msgctxt "header" +msgid "Down payment" +msgstr "A cuenta" + +#: web/templates/admin/payment/index.gohtml:24 +msgctxt "header" +msgid "Total" +msgstr "Total" + +#: web/templates/admin/payment/index.gohtml:40 +msgid "No payments found." +msgstr "No se ha encontrado ningún pago." + +#: web/templates/admin/payment/details.gohtml:7 +msgctxt "title" +msgid "Payment %s" +msgstr "Pago %s" + +#: web/templates/admin/payment/details.gohtml:19 +msgctxt "title" +msgid "Payment" +msgstr "Pago" + +#: web/templates/admin/payment/details.gohtml:30 +#, fuzzy +msgctxt "payment header" +msgid "Created at" +msgstr "Creado el" + +#: web/templates/admin/payment/details.gohtml:34 +#, fuzzy +msgctxt "payment header" +msgid "Last updated at" +msgstr "Actualizado por última vez el" + +#: web/templates/admin/payment/details.gohtml:48 +msgctxt "header" +msgid "Area preferences" +msgstr "Preferencias de área" + +#: web/templates/admin/payment/details.gohtml:60 +msgctxt "cart" +msgid "Nights" +msgstr "Noches" + +#: web/templates/admin/payment/details.gohtml:80 pkg/booking/cart.go:188 +msgctxt "cart" +msgid "Tourist tax" +msgstr "Impuesto turístico" + +#: web/templates/admin/payment/details.gohtml:92 +#: web/templates/admin/campsite/type/option/form.gohtml:18 +#: web/templates/admin/campsite/type/option/index.gohtml:6 +#: web/templates/admin/campsite/type/option/index.gohtml:17 +msgctxt "title" +msgid "Campsite Type Options" +msgstr "Opciones del tipo de alojamiento" + +#: web/templates/admin/payment/details.gohtml:113 +#: web/templates/admin/taxDetails.gohtml:69 +msgctxt "input" +msgid "Address" +msgstr "Dirección" + +#: web/templates/admin/payment/details.gohtml:117 +#: web/templates/admin/taxDetails.gohtml:93 +msgctxt "input" +msgid "Postcode" +msgstr "Código postal" + +#: web/templates/admin/payment/details.gohtml:121 +#: web/templates/admin/taxDetails.gohtml:77 +msgctxt "input" +msgid "City" +msgstr "Población" + +#: web/templates/admin/payment/details.gohtml:137 +#: web/templates/admin/profile.gohtml:68 +msgctxt "input" +msgid "Language" +msgstr "Idioma" + +#: web/templates/admin/payment/details.gohtml:141 +msgctxt "input" +msgid "ACSI card?" +msgstr "¿Tarjeta ACSI?" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "Yes" +msgstr "Sí" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "No" +msgstr "No" + #: web/templates/admin/legal/form.gohtml:8 #: web/templates/admin/legal/form.gohtml:29 msgctxt "title" @@ -911,13 +1102,6 @@ msgctxt "input" msgid "Map Embed" msgstr "Incrustación del mapa" -#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 -#: web/templates/admin/taxDetails.gohtml:170 -#: web/templates/admin/booking/payment.gohtml:65 -msgctxt "action" -msgid "Save changes" -msgstr "Guardar los cambios" - #: web/templates/admin/campsite/feature/form.gohtml:8 msgctxt "title" msgid "Edit Campsite Feature" @@ -1145,22 +1329,6 @@ msgctxt "action" msgid "Edit Carousel" msgstr "Editar el carrusel" -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "Yes" -msgstr "Sí" - -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "No" -msgstr "No" - #: web/templates/admin/campsite/index.gohtml:47 msgid "No campsites added yet." msgstr "No se ha añadido ningún alojamiento todavía." @@ -1368,13 +1536,6 @@ msgctxt "title" msgid "New Campsite Type Option" msgstr "Nueva opción del tipo de alojamiento" -#: web/templates/admin/campsite/type/option/form.gohtml:18 -#: web/templates/admin/campsite/type/option/index.gohtml:6 -#: web/templates/admin/campsite/type/option/index.gohtml:17 -msgctxt "title" -msgid "Campsite Type Options" -msgstr "Opciones del tipo de alojamiento" - #: web/templates/admin/campsite/type/option/form.gohtml:54 msgctxt "input" msgid "Minimum" @@ -1568,11 +1729,6 @@ msgctxt "input" msgid "Password Confirmation" msgstr "Confirmación de la contraseña" -#: web/templates/admin/profile.gohtml:68 -msgctxt "input" -msgid "Language" -msgstr "Idioma" - #: web/templates/admin/user/login-attempts.gohtml:6 #: web/templates/admin/user/login-attempts.gohtml:15 msgctxt "title" @@ -1587,11 +1743,6 @@ msgctxt "title" msgid "Users" msgstr "Usuarios" -#: web/templates/admin/user/login-attempts.gohtml:19 -msgctxt "header" -msgid "Date" -msgstr "Fecha" - #: web/templates/admin/user/login-attempts.gohtml:20 #: web/templates/admin/user/index.gohtml:21 msgctxt "header" @@ -1649,26 +1800,11 @@ msgctxt "input" msgid "Trade Name" msgstr "Nombre comercial" -#: web/templates/admin/taxDetails.gohtml:69 -msgctxt "input" -msgid "Address" -msgstr "Dirección" - -#: web/templates/admin/taxDetails.gohtml:77 -msgctxt "input" -msgid "City" -msgstr "Población" - #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Provincia" -#: web/templates/admin/taxDetails.gohtml:93 -msgctxt "input" -msgid "Postcode" -msgstr "Código postal" - #: web/templates/admin/taxDetails.gohtml:111 msgctxt "input" msgid "Currency" @@ -1854,13 +1990,6 @@ msgctxt "title" msgid "Company Settings" msgstr "Parámetros de la empresa" -#: web/templates/admin/layout.gohtml:40 -#: web/templates/admin/booking/payment.gohtml:6 -#: web/templates/admin/booking/payment.gohtml:15 -msgctxt "title" -msgid "Payment Settings" -msgstr "Parámetros de pago" - #: web/templates/admin/layout.gohtml:55 #: web/templates/admin/media/form.gohtml:10 #: web/templates/admin/media/index.gohtml:6 @@ -1988,36 +2117,6 @@ msgctxt "title" msgid "Upload Media" msgstr "Subida de medio" -#: web/templates/admin/booking/payment.gohtml:20 -msgctxt "input" -msgid "Merchant Code" -msgstr "Código del comercio" - -#: web/templates/admin/booking/payment.gohtml:29 -msgctxt "input" -msgid "Terminal Number" -msgstr "Número de terminal" - -#: web/templates/admin/booking/payment.gohtml:39 -msgctxt "input" -msgid "Merchant Key (only if must change it)" -msgstr "Clave del comercio (sólo si se debe cambiar)" - -#: web/templates/admin/booking/payment.gohtml:41 -msgctxt "input" -msgid "Merchant Key" -msgstr "Clave del comercio" - -#: web/templates/admin/booking/payment.gohtml:51 -msgctxt "title" -msgid "Environment" -msgstr "Entorno" - -#: web/templates/admin/booking/payment.gohtml:58 -msgctxt "title" -msgid "Integration" -msgstr "Integración" - #: web/templates/admin/booking/index.gohtml:14 msgctxt "action" msgid "Add Booking" @@ -2028,11 +2127,6 @@ msgctxt "action" msgid "Export Bookings" msgstr "Exportar eservas" -#: web/templates/admin/booking/index.gohtml:21 -msgctxt "header" -msgid "Reference" -msgstr "Referencia" - #: web/templates/admin/booking/index.gohtml:22 msgctxt "header" msgid "Arrival Date" @@ -2048,21 +2142,68 @@ msgctxt "header" msgid "Holder Name" msgstr "Nombre del titular" -#: web/templates/admin/booking/index.gohtml:25 -msgctxt "header" -msgid "Status" -msgstr "Estado" - #: web/templates/admin/booking/index.gohtml:41 msgid "No booking found." msgstr "No se ha encontrado ninguna reserva." -#: pkg/payment/public.go:109 +#: pkg/payment/settings.go:37 +msgctxt "redsys environment" +msgid "Test" +msgstr "Pruebas" + +#: pkg/payment/settings.go:41 +msgctxt "redsys environment" +msgid "Live" +msgstr "Real" + +#: pkg/payment/settings.go:50 +msgctxt "redsys integration" +msgid "InSite" +msgstr "InSite" + +#: pkg/payment/settings.go:54 +msgctxt "redsys integration" +msgid "Redirect" +msgstr "Redirección" + +#: pkg/payment/settings.go:98 +msgid "Merchant code can not be empty." +msgstr "No podéis dejar el código del comercio en blanco." + +#: pkg/payment/settings.go:99 +msgid "Merchant code must be exactly nine digits long." +msgstr "El código del comercio tiene que ser de nueve dígitos." + +#: pkg/payment/settings.go:100 +msgid "Merchant code must be a number." +msgstr "El código del comercio tiene que ser un número." + +#: pkg/payment/settings.go:104 +msgid "Terminal number can not be empty." +msgstr "No podéis dejar el número de terminal en blanco." + +#: pkg/payment/settings.go:105 +msgid "Terminal number must be a number between 1 and 999." +msgstr "El número de terminal tiene que ser entre 1 y 999." + +#: pkg/payment/settings.go:113 +msgid "Selected environment is not valid." +msgstr "El entorno escogido no es válido." + +#: pkg/payment/settings.go:114 +msgid "Selected integration is not valid." +msgstr "La integración escogida no es válida." + +#: pkg/payment/settings.go:117 +msgid "The merchant key is not valid." +msgstr "Esta clave del comercio no es válida." + +#: pkg/payment/public.go:110 msgctxt "order product name" msgid "Campsite Booking" msgstr "Reserva de camping" -#: pkg/payment/public.go:346 +#: pkg/payment/public.go:342 msgctxt "subject" msgid "Booking payment successfully received" msgstr "Se ha recibido correctamente el pago de la reserva" @@ -2140,7 +2281,7 @@ msgstr "El idioma escogido no es válido." msgid "File must be a valid PNG or JPEG image." msgstr "El archivo tiene que ser una imagen PNG o JPEG válida." -#: pkg/app/admin.go:70 +#: pkg/app/admin.go:73 msgid "Access forbidden" msgstr "Acceso prohibido" @@ -2563,93 +2704,36 @@ 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:151 +#: pkg/booking/cart.go:150 msgctxt "cart" msgid "Night" msgstr "Noche" -#: pkg/booking/cart.go:152 +#: pkg/booking/cart.go:151 msgctxt "cart" msgid "Adult" msgstr "Adulto" -#: pkg/booking/cart.go:153 +#: pkg/booking/cart.go:152 msgctxt "cart" msgid "Teenager" msgstr "Adolescente" -#: pkg/booking/cart.go:154 +#: pkg/booking/cart.go:153 msgctxt "cart" msgid "Child" msgstr "Niño" -#: pkg/booking/cart.go:155 +#: pkg/booking/cart.go:154 msgctxt "cart" msgid "Dog" msgstr "Perro" -#: pkg/booking/cart.go:190 -msgctxt "cart" -msgid "Tourist tax" -msgstr "Impuesto turístico" - -#: pkg/booking/admin.go:149 +#: pkg/booking/admin.go:126 msgctxt "filename" msgid "bookings.ods" msgstr "reservas.ods" -#: pkg/booking/admin.go:177 -msgctxt "redsys environment" -msgid "Test" -msgstr "Pruebas" - -#: pkg/booking/admin.go:181 -msgctxt "redsys environment" -msgid "Live" -msgstr "Real" - -#: pkg/booking/admin.go:190 -msgctxt "redsys integration" -msgid "InSite" -msgstr "InSite" - -#: pkg/booking/admin.go:194 -msgctxt "redsys integration" -msgid "Redirect" -msgstr "Redirección" - -#: pkg/booking/admin.go:238 -msgid "Merchant code can not be empty." -msgstr "No podéis dejar el código del comercio en blanco." - -#: pkg/booking/admin.go:239 -msgid "Merchant code must be exactly nine digits long." -msgstr "El código del comercio tiene que ser de nueve dígitos." - -#: pkg/booking/admin.go:240 -msgid "Merchant code must be a number." -msgstr "El código del comercio tiene que ser un número." - -#: pkg/booking/admin.go:244 -msgid "Terminal number can not be empty." -msgstr "No podéis dejar el número de terminal en blanco." - -#: pkg/booking/admin.go:245 -msgid "Terminal number must be a number between 1 and 999." -msgstr "El número de terminal tiene que ser entre 1 y 999." - -#: pkg/booking/admin.go:253 -msgid "Selected environment is not valid." -msgstr "El entorno escogido no es válido." - -#: pkg/booking/admin.go:254 -msgid "Selected integration is not valid." -msgstr "La integración escogida no es válida." - -#: pkg/booking/admin.go:257 -msgid "The merchant key is not valid." -msgstr "Esta clave del comercio no es válida." - #: pkg/booking/public.go:275 pkg/booking/public.go:304 msgid "Arrival date must be a valid date." msgstr "La fecha de llegada tiene que ser una fecha válida." @@ -2771,10 +2855,6 @@ msgstr "El nombre y los apellidos tienen que tener como mínimo una letra." msgid "It is mandatory to agree to the reservation conditions." msgstr "Es obligatorio aceptar las condiciones de reserva." -#~ msgctxt "title" -#~ msgid "Payment" -#~ msgstr "Pago" - #~ msgctxt "action" #~ msgid "Pay" #~ msgstr "Pagar" diff --git a/po/fr.po b/po/fr.po index 15e07b8..caae0a6 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-02-13 23:38+0100\n" +"POT-Creation-Date: 2024-02-14 04:47+0100\n" "PO-Revision-Date: 2024-02-06 10:05+0100\n" "Last-Translator: Oriol Carbonell \n" "Language-Team: French \n" @@ -380,12 +380,14 @@ msgstr "Dim." #: web/templates/public/campsite/dates.gohtml:4 #: web/templates/public/booking/fields.gohtml:29 +#: web/templates/admin/payment/details.gohtml:52 msgctxt "input" msgid "Arrival date" msgstr "Date d’arrivée" #: web/templates/public/campsite/dates.gohtml:15 #: web/templates/public/booking/fields.gohtml:40 +#: web/templates/admin/payment/details.gohtml:56 msgctxt "input" msgid "Departure date" msgstr "Date de depart" @@ -393,7 +395,7 @@ msgstr "Date de depart" #: web/templates/public/surroundings.gohtml:30 msgctxt "title" msgid "What to Do Outside the Campsite?" -msgstr "Que faire à l’extérieur du camping ?" +msgstr "Que faire à l’extérieur du camping ?" #: web/templates/public/surroundings.gohtml:50 msgctxt "title" @@ -624,6 +626,7 @@ msgstr "Locatifs" #: web/templates/public/layout.gohtml:70 #: web/templates/public/booking/page.gohtml:7 +#: web/templates/admin/payment/details.gohtml:41 msgctxt "title" msgid "Booking" msgstr "Réservation" @@ -643,6 +646,7 @@ msgid "RTC # RTC %s" #: web/templates/public/booking/fields.gohtml:14 +#: web/templates/admin/payment/details.gohtml:44 msgctxt "title" msgid "Accommodation" msgstr "Hébergement" @@ -658,16 +662,19 @@ msgid "Guests" msgstr "Personnes logeant" #: web/templates/public/booking/fields.gohtml:59 +#: web/templates/admin/payment/details.gohtml:64 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adultes âgés 17 ans ou plus" #: web/templates/public/booking/fields.gohtml:70 +#: web/templates/admin/payment/details.gohtml:68 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescents de 11 à 16 ans" #: web/templates/public/booking/fields.gohtml:81 +#: web/templates/admin/payment/details.gohtml:72 msgctxt "input" msgid "Children from 2 to 10 years old" msgstr "Enfants de 2 à 10 ans" @@ -677,6 +684,7 @@ msgid "Note: Due to guest capacity, we have added more accomodations to the book msgstr "Remarque : En raison de la capacité d’accueils, nous avons ajouté d’autres hébergements à la réservation, mais nous ne pouvons garantir qu’ils seront côte à côte." #: web/templates/public/booking/fields.gohtml:99 +#: web/templates/admin/payment/details.gohtml:76 msgctxt "input" msgid "Dogs" msgstr "Chiens" @@ -695,11 +703,13 @@ msgid "Campground map" msgstr "Plan du camping" #: web/templates/public/booking/fields.gohtml:145 +#: web/templates/admin/payment/details.gohtml:106 msgctxt "title" msgid "Customer Details" msgstr "Détails du client" #: web/templates/public/booking/fields.gohtml:148 +#: web/templates/admin/payment/details.gohtml:109 msgctxt "input" msgid "Full name" msgstr "Nom et prénom" @@ -720,6 +730,7 @@ msgid "Town or village (optional)" msgstr "Ville (Facultatif)" #: web/templates/public/booking/fields.gohtml:184 +#: web/templates/admin/payment/details.gohtml:125 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -730,6 +741,7 @@ msgid "Choose a country" msgstr "Choisissez un pays" #: web/templates/public/booking/fields.gohtml:195 +#: web/templates/admin/payment/details.gohtml:129 #: web/templates/admin/login.gohtml:27 web/templates/admin/profile.gohtml:38 #: web/templates/admin/taxDetails.gohtml:53 msgctxt "input" @@ -737,6 +749,7 @@ msgid "Email" msgstr "E-mail" #: web/templates/public/booking/fields.gohtml:204 +#: web/templates/admin/payment/details.gohtml:133 #: web/templates/admin/taxDetails.gohtml:45 msgctxt "input" msgid "Phone" @@ -745,7 +758,7 @@ msgstr "Téléphone" #: web/templates/public/booking/fields.gohtml:215 msgctxt "input" msgid "ACSI card? (optional)" -msgstr "Carte ACSI ? (Facultatif)" +msgstr "Carte ACSI ? (Facultatif)" #: web/templates/public/booking/fields.gohtml:222 msgctxt "input" @@ -758,10 +771,188 @@ msgid "Total" msgstr "Totale" #: web/templates/public/booking/fields.gohtml:244 +#: web/templates/admin/payment/details.gohtml:84 msgctxt "cart" msgid "Down payment" msgstr "Acompte" +#: web/templates/admin/payment/settings.gohtml:6 +#: web/templates/admin/payment/index.gohtml:14 +msgctxt "title" +msgid "Payment Settings" +msgstr "Paramètres de paiement" + +#: web/templates/admin/payment/settings.gohtml:10 +#: web/templates/admin/payment/index.gohtml:6 +#: web/templates/admin/payment/details.gohtml:11 +#: web/templates/admin/layout.gohtml:40 +msgctxt "title" +msgid "Payments" +msgstr "Paiements" + +#: web/templates/admin/payment/settings.gohtml:21 +msgctxt "input" +msgid "Merchant Code" +msgstr "Code Marchant" + +#: web/templates/admin/payment/settings.gohtml:30 +msgctxt "input" +msgid "Terminal Number" +msgstr "Numéro de terminal" + +#: web/templates/admin/payment/settings.gohtml:40 +msgctxt "input" +msgid "Merchant Key (only if must change it)" +msgstr "Clé marchande (uniquement si vous devez la changer)" + +#: web/templates/admin/payment/settings.gohtml:42 +msgctxt "input" +msgid "Merchant Key" +msgstr "Clé Marchant" + +#: web/templates/admin/payment/settings.gohtml:52 +msgctxt "title" +msgid "Environment" +msgstr "Environnement" + +#: web/templates/admin/payment/settings.gohtml:59 +msgctxt "title" +msgid "Integration" +msgstr "Intégration" + +#: web/templates/admin/payment/settings.gohtml:66 +#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 +#: web/templates/admin/taxDetails.gohtml:170 +msgctxt "action" +msgid "Save changes" +msgstr "Enregistrer les changements" + +#: web/templates/admin/payment/index.gohtml:20 +#: web/templates/admin/user/login-attempts.gohtml:19 +msgctxt "header" +msgid "Date" +msgstr "Date" + +#: web/templates/admin/payment/index.gohtml:21 +#: web/templates/admin/payment/details.gohtml:22 +#: web/templates/admin/booking/index.gohtml:21 +msgctxt "header" +msgid "Reference" +msgstr "Référence" + +#: web/templates/admin/payment/index.gohtml:22 +#: web/templates/admin/payment/details.gohtml:26 +#: web/templates/admin/booking/index.gohtml:25 +msgctxt "header" +msgid "Status" +msgstr "Statut" + +#: web/templates/admin/payment/index.gohtml:23 +msgctxt "header" +msgid "Down payment" +msgstr "Acompte" + +#: web/templates/admin/payment/index.gohtml:24 +msgctxt "header" +msgid "Total" +msgstr "Totale" + +#: web/templates/admin/payment/index.gohtml:40 +msgid "No payments found." +msgstr "Aucun paiement trouvée." + +#: web/templates/admin/payment/details.gohtml:7 +msgctxt "title" +msgid "Payment %s" +msgstr "Paiement %s" + +#: web/templates/admin/payment/details.gohtml:19 +msgctxt "title" +msgid "Payment" +msgstr "Paiement" + +#: web/templates/admin/payment/details.gohtml:30 +#, fuzzy +msgctxt "payment header" +msgid "Created at" +msgstr "Créé à" + +#: web/templates/admin/payment/details.gohtml:34 +#, fuzzy +msgctxt "payment header" +msgid "Last updated at" +msgstr "Dernière mise à jour à" + +#: web/templates/admin/payment/details.gohtml:48 +msgctxt "header" +msgid "Area preferences" +msgstr "Préférences de zone" + +#: web/templates/admin/payment/details.gohtml:60 +msgctxt "cart" +msgid "Nights" +msgstr "Nuits" + +#: web/templates/admin/payment/details.gohtml:80 pkg/booking/cart.go:188 +msgctxt "cart" +msgid "Tourist tax" +msgstr "Taxe touristique" + +#: web/templates/admin/payment/details.gohtml:92 +#: web/templates/admin/campsite/type/option/form.gohtml:18 +#: web/templates/admin/campsite/type/option/index.gohtml:6 +#: web/templates/admin/campsite/type/option/index.gohtml:17 +msgctxt "title" +msgid "Campsite Type Options" +msgstr "Options de type d’emplacement de camping" + +#: web/templates/admin/payment/details.gohtml:113 +#: web/templates/admin/taxDetails.gohtml:69 +msgctxt "input" +msgid "Address" +msgstr "Adresse" + +#: web/templates/admin/payment/details.gohtml:117 +#: web/templates/admin/taxDetails.gohtml:93 +msgctxt "input" +msgid "Postcode" +msgstr "Code Postal" + +#: web/templates/admin/payment/details.gohtml:121 +#: web/templates/admin/taxDetails.gohtml:77 +msgctxt "input" +msgid "City" +msgstr "Ville" + +#: web/templates/admin/payment/details.gohtml:137 +#: web/templates/admin/profile.gohtml:68 +msgctxt "input" +msgid "Language" +msgstr "Langue" + +#: web/templates/admin/payment/details.gohtml:141 +msgctxt "input" +msgid "ACSI card?" +msgstr "Carte ACSI ?" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "Yes" +msgstr "Oui" + +#: web/templates/admin/payment/details.gohtml:142 +#: web/templates/admin/campsite/index.gohtml:41 +#: web/templates/admin/campsite/type/index.gohtml:53 +#: web/templates/admin/season/index.gohtml:44 +#: web/templates/admin/user/login-attempts.gohtml:31 +#: web/templates/admin/amenity/index.gohtml:40 +msgid "No" +msgstr "Non" + #: web/templates/admin/legal/form.gohtml:8 #: web/templates/admin/legal/form.gohtml:29 msgctxt "title" @@ -911,13 +1102,6 @@ msgctxt "input" msgid "Map Embed" msgstr "Carte intégrée" -#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78 -#: web/templates/admin/taxDetails.gohtml:170 -#: web/templates/admin/booking/payment.gohtml:65 -msgctxt "action" -msgid "Save changes" -msgstr "Enregistrer les changements" - #: web/templates/admin/campsite/feature/form.gohtml:8 msgctxt "title" msgid "Edit Campsite Feature" @@ -971,7 +1155,7 @@ msgstr "Actions" #: web/templates/admin/campsite/type/feature/index.gohtml:36 #: web/templates/admin/amenity/feature/index.gohtml:35 msgid "Are you sure you wish to delete this feature?" -msgstr "Êtes-vous sûr de vouloir supprimer cette caractéristique ?" +msgstr "Êtes-vous sûr de vouloir supprimer cette caractéristique ?" #: web/templates/admin/campsite/feature/index.gohtml:47 #: web/templates/admin/campsite/carousel/index.gohtml:49 @@ -1048,7 +1232,7 @@ msgstr "Légende" #: web/templates/admin/amenity/carousel/index.gohtml:35 #: web/templates/admin/home/index.gohtml:103 msgid "Are you sure you wish to delete this slide?" -msgstr "Êtes-vous sûr de vouloir supprimer cette diapositive ?" +msgstr "Êtes-vous sûr de vouloir supprimer cette diapositive ?" #: web/templates/admin/campsite/carousel/index.gohtml:58 #: web/templates/admin/campsite/type/carousel/index.gohtml:59 @@ -1145,22 +1329,6 @@ msgctxt "action" msgid "Edit Carousel" msgstr "Modifier le carrousel" -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "Yes" -msgstr "Oui" - -#: web/templates/admin/campsite/index.gohtml:41 -#: web/templates/admin/campsite/type/index.gohtml:53 -#: web/templates/admin/season/index.gohtml:44 -#: web/templates/admin/user/login-attempts.gohtml:31 -#: web/templates/admin/amenity/index.gohtml:40 -msgid "No" -msgstr "Non" - #: web/templates/admin/campsite/index.gohtml:47 msgid "No campsites added yet." msgstr "Aucun camping n’a encore été ajouté." @@ -1368,13 +1536,6 @@ msgctxt "title" msgid "New Campsite Type Option" msgstr "Nouvelle option de type d’emplacement de camping" -#: web/templates/admin/campsite/type/option/form.gohtml:18 -#: web/templates/admin/campsite/type/option/index.gohtml:6 -#: web/templates/admin/campsite/type/option/index.gohtml:17 -msgctxt "title" -msgid "Campsite Type Options" -msgstr "Options de type d’emplacement de camping" - #: web/templates/admin/campsite/type/option/form.gohtml:54 msgctxt "input" msgid "Minimum" @@ -1402,7 +1563,7 @@ msgstr "Ajouter une option" #: web/templates/admin/campsite/type/option/index.gohtml:35 msgid "Are you sure you wish to delete this option?" -msgstr "Êtes-vous sûr de vouloir supprimer cette option ?" +msgstr "Êtes-vous sûr de vouloir supprimer cette option ?" #: web/templates/admin/campsite/type/option/index.gohtml:56 msgid "No campsite type options added yet." @@ -1541,7 +1702,7 @@ msgstr "Service" #: web/templates/admin/services/index.gohtml:79 msgid "Are you sure you wish to delete this service?" -msgstr "Êtes-vous sûr de vouloir supprimer ce service ?" +msgstr "Êtes-vous sûr de vouloir supprimer ce service ?" #: web/templates/admin/services/index.gohtml:100 msgid "No services added yet." @@ -1568,11 +1729,6 @@ msgctxt "input" msgid "Password Confirmation" msgstr "Confirmation du mot de passe" -#: web/templates/admin/profile.gohtml:68 -msgctxt "input" -msgid "Language" -msgstr "Langue" - #: web/templates/admin/user/login-attempts.gohtml:6 #: web/templates/admin/user/login-attempts.gohtml:15 msgctxt "title" @@ -1587,11 +1743,6 @@ msgctxt "title" msgid "Users" msgstr "Utilisateurs" -#: web/templates/admin/user/login-attempts.gohtml:19 -msgctxt "header" -msgid "Date" -msgstr "Date" - #: web/templates/admin/user/login-attempts.gohtml:20 #: web/templates/admin/user/index.gohtml:21 msgctxt "header" @@ -1625,7 +1776,7 @@ msgstr "Rôle" #: web/templates/admin/user/index.gohtml:27 msgid "Are you sure you wish to delete this user?" -msgstr "Êtes-vous sûr de vouloir supprimer ce utilisateur ?" +msgstr "Êtes-vous sûr de vouloir supprimer ce utilisateur ?" #: web/templates/admin/taxDetails.gohtml:6 #: web/templates/admin/taxDetails.gohtml:15 @@ -1649,26 +1800,11 @@ msgctxt "input" msgid "Trade Name" msgstr "Nom commercial" -#: web/templates/admin/taxDetails.gohtml:69 -msgctxt "input" -msgid "Address" -msgstr "Adresse" - -#: web/templates/admin/taxDetails.gohtml:77 -msgctxt "input" -msgid "City" -msgstr "Ville" - #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Province" -#: web/templates/admin/taxDetails.gohtml:93 -msgctxt "input" -msgid "Postcode" -msgstr "Code Postal" - #: web/templates/admin/taxDetails.gohtml:111 msgctxt "input" msgid "Currency" @@ -1762,7 +1898,7 @@ msgstr "Ajouter un point d’intérêt" #: web/templates/admin/surroundings/index.gohtml:88 msgid "Are you sure you wish to delete this highlight?" -msgstr "Êtes-vous sûr de vouloir supprimer cette point d’intérêt ?" +msgstr "Êtes-vous sûr de vouloir supprimer cette point d’intérêt ?" #: web/templates/admin/surroundings/index.gohtml:110 msgid "No highlights added yet." @@ -1838,7 +1974,7 @@ msgstr "Ajouter un installation" #: web/templates/admin/amenity/index.gohtml:29 msgid "Are you sure you wish to delete this amenity?" -msgstr "Êtes-vous sûr de vouloir supprimer ce installation ?" +msgstr "Êtes-vous sûr de vouloir supprimer ce installation ?" #: web/templates/admin/amenity/index.gohtml:53 msgid "No amenities added yet." @@ -1854,13 +1990,6 @@ msgctxt "title" msgid "Company Settings" msgstr "Paramètres de l’entreprise" -#: web/templates/admin/layout.gohtml:40 -#: web/templates/admin/booking/payment.gohtml:6 -#: web/templates/admin/booking/payment.gohtml:15 -msgctxt "title" -msgid "Payment Settings" -msgstr "Paramètres de paiement" - #: web/templates/admin/layout.gohtml:55 #: web/templates/admin/media/form.gohtml:10 #: web/templates/admin/media/index.gohtml:6 @@ -1988,36 +2117,6 @@ msgctxt "title" msgid "Upload Media" msgstr "Envoyer un fichier" -#: web/templates/admin/booking/payment.gohtml:20 -msgctxt "input" -msgid "Merchant Code" -msgstr "Code Marchant" - -#: web/templates/admin/booking/payment.gohtml:29 -msgctxt "input" -msgid "Terminal Number" -msgstr "Numéro de terminal" - -#: web/templates/admin/booking/payment.gohtml:39 -msgctxt "input" -msgid "Merchant Key (only if must change it)" -msgstr "Clé marchande (uniquement si vous devez la changer)" - -#: web/templates/admin/booking/payment.gohtml:41 -msgctxt "input" -msgid "Merchant Key" -msgstr "Clé Marchant" - -#: web/templates/admin/booking/payment.gohtml:51 -msgctxt "title" -msgid "Environment" -msgstr "Environnement" - -#: web/templates/admin/booking/payment.gohtml:58 -msgctxt "title" -msgid "Integration" -msgstr "Intégration" - #: web/templates/admin/booking/index.gohtml:14 msgctxt "action" msgid "Add Booking" @@ -2028,11 +2127,6 @@ msgctxt "action" msgid "Export Bookings" msgstr "Exporter les réservations" -#: web/templates/admin/booking/index.gohtml:21 -msgctxt "header" -msgid "Reference" -msgstr "Référence" - #: web/templates/admin/booking/index.gohtml:22 msgctxt "header" msgid "Arrival Date" @@ -2048,21 +2142,68 @@ msgctxt "header" msgid "Holder Name" msgstr "Nom du titulaire" -#: web/templates/admin/booking/index.gohtml:25 -msgctxt "header" -msgid "Status" -msgstr "Statut" - #: web/templates/admin/booking/index.gohtml:41 msgid "No booking found." msgstr "Aucune réservation trouvée." -#: pkg/payment/public.go:109 +#: pkg/payment/settings.go:37 +msgctxt "redsys environment" +msgid "Test" +msgstr "Test" + +#: pkg/payment/settings.go:41 +msgctxt "redsys environment" +msgid "Live" +msgstr "Live" + +#: pkg/payment/settings.go:50 +msgctxt "redsys integration" +msgid "InSite" +msgstr "Insite" + +#: pkg/payment/settings.go:54 +msgctxt "redsys integration" +msgid "Redirect" +msgstr "Redirection" + +#: pkg/payment/settings.go:98 +msgid "Merchant code can not be empty." +msgstr "Le code marchand ne peut pas être vide." + +#: pkg/payment/settings.go:99 +msgid "Merchant code must be exactly nine digits long." +msgstr "Le code marchand doit comporter exactement neuf chiffres." + +#: pkg/payment/settings.go:100 +msgid "Merchant code must be a number." +msgstr "Le code du commerçant doit être un chiffre." + +#: pkg/payment/settings.go:104 +msgid "Terminal number can not be empty." +msgstr "Le numéro de terminal ne peut pas être vide." + +#: pkg/payment/settings.go:105 +msgid "Terminal number must be a number between 1 and 999." +msgstr "Le numéro de terminal doit être compris entre 1 et 999." + +#: pkg/payment/settings.go:113 +msgid "Selected environment is not valid." +msgstr "L’environnement sélectionné n’est pas valide." + +#: pkg/payment/settings.go:114 +msgid "Selected integration is not valid." +msgstr "L’intégration sélectionnée n’est pas valide." + +#: pkg/payment/settings.go:117 +msgid "The merchant key is not valid." +msgstr "La clé marchand n’est pas valide." + +#: pkg/payment/public.go:110 msgctxt "order product name" msgid "Campsite Booking" msgstr "Réservation camping" -#: pkg/payment/public.go:346 +#: pkg/payment/public.go:342 msgctxt "subject" msgid "Booking payment successfully received" msgstr "Paiement de réservation reçu avec succès" @@ -2140,7 +2281,7 @@ msgstr "La langue sélectionnée n’est pas valide." msgid "File must be a valid PNG or JPEG image." msgstr "Le fichier doit être une image PNG ou JPEG valide." -#: pkg/app/admin.go:70 +#: pkg/app/admin.go:73 msgid "Access forbidden" msgstr "Accès interdit" @@ -2563,93 +2704,36 @@ 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:151 +#: pkg/booking/cart.go:150 msgctxt "cart" msgid "Night" msgstr "Nuit" -#: pkg/booking/cart.go:152 +#: pkg/booking/cart.go:151 msgctxt "cart" msgid "Adult" msgstr "Adulte" -#: pkg/booking/cart.go:153 +#: pkg/booking/cart.go:152 msgctxt "cart" msgid "Teenager" msgstr "Adolescent" -#: pkg/booking/cart.go:154 +#: pkg/booking/cart.go:153 msgctxt "cart" msgid "Child" msgstr "Enfant" -#: pkg/booking/cart.go:155 +#: pkg/booking/cart.go:154 msgctxt "cart" msgid "Dog" msgstr "Chien" -#: pkg/booking/cart.go:190 -msgctxt "cart" -msgid "Tourist tax" -msgstr "Taxe touristique" - -#: pkg/booking/admin.go:149 +#: pkg/booking/admin.go:126 msgctxt "filename" msgid "bookings.ods" msgstr "reservations.ods" -#: pkg/booking/admin.go:177 -msgctxt "redsys environment" -msgid "Test" -msgstr "Test" - -#: pkg/booking/admin.go:181 -msgctxt "redsys environment" -msgid "Live" -msgstr "Live" - -#: pkg/booking/admin.go:190 -msgctxt "redsys integration" -msgid "InSite" -msgstr "Insite" - -#: pkg/booking/admin.go:194 -msgctxt "redsys integration" -msgid "Redirect" -msgstr "Redirection" - -#: pkg/booking/admin.go:238 -msgid "Merchant code can not be empty." -msgstr "Le code marchand ne peut pas être vide." - -#: pkg/booking/admin.go:239 -msgid "Merchant code must be exactly nine digits long." -msgstr "Le code marchand doit comporter exactement neuf chiffres." - -#: pkg/booking/admin.go:240 -msgid "Merchant code must be a number." -msgstr "Le code du commerçant doit être un chiffre." - -#: pkg/booking/admin.go:244 -msgid "Terminal number can not be empty." -msgstr "Le numéro de terminal ne peut pas être vide." - -#: pkg/booking/admin.go:245 -msgid "Terminal number must be a number between 1 and 999." -msgstr "Le numéro de terminal doit être compris entre 1 et 999." - -#: pkg/booking/admin.go:253 -msgid "Selected environment is not valid." -msgstr "L’environnement sélectionné n’est pas valide." - -#: pkg/booking/admin.go:254 -msgid "Selected integration is not valid." -msgstr "L’intégration sélectionnée n’est pas valide." - -#: pkg/booking/admin.go:257 -msgid "The merchant key is not valid." -msgstr "La clé marchand n’est pas valide." - #: pkg/booking/public.go:275 pkg/booking/public.go:304 msgid "Arrival date must be a valid date." msgstr "La date d’arrivée doit être une date valide." @@ -2771,10 +2855,6 @@ msgstr "Le nom complet doit comporter au moins une lettre." msgid "It is mandatory to agree to the reservation conditions." msgstr "Il est obligatoire d’accepter les conditions de réservation." -#~ msgctxt "title" -#~ msgid "Payment" -#~ msgstr "Paiement" - #~ msgctxt "action" #~ msgid "Pay" #~ msgstr "Payer" diff --git a/revert/payment_reference.sql b/revert/payment_reference.sql new file mode 100644 index 0000000..78b1702 --- /dev/null +++ b/revert/payment_reference.sql @@ -0,0 +1,7 @@ +-- Revert camper:order_code from pg + +begin; + +drop function if exists camper.reference(camper.payment); + +commit; diff --git a/sqitch.plan b/sqitch.plan index 6c2888b..911bf0a 100644 --- a/sqitch.plan +++ b/sqitch.plan @@ -246,7 +246,7 @@ payment_status_i18n [roles schema_camper payment_status language] 2024-02-11T21: available_payment_status [payment_status payment_status_i18n] 2024-02-11T21:22:38Z jordi fita mas # Add available payment statuses positive_integer [schema_camper] 2024-02-13T20:24:09Z jordi fita mas # Add positive integer domain percentage [schema_camper] 2024-02-13T20:09:10Z jordi fita mas # Add percentage domain -payment [roles schema_camper company campsite_type payment_status positive_integer nonnegative_integer percentage] 2024-02-11T21:54:13Z jordi fita mas # Add relation for payments +payment [roles schema_camper company campsite_type payment_status positive_integer nonnegative_integer percentage currency_code currency] 2024-02-11T21:54:13Z jordi fita mas # Add relation for payments payment_customer [roles schema_camper payment country country_code extension_pg_libphonenumber] 2024-02-12T00:10:20Z jordi fita mas # Add relation of payment customer payment_option [roles schema_camper payment campsite_type_option positive_integer nonnegative_integer] 2024-02-12T00:58:07Z jordi fita mas # 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 # Add function to create a payment draft @@ -257,3 +257,4 @@ redsys_decode_response [roles schema_camper extension_pgcrypto decode_base64url payment_redsys_response [roles schema_camper payment currency_code] 2024-02-12T21:32:23Z jordi fita mas # Add relation for Redsys responses to payments process_payment_response [roles schema_camper redsys_response payment payment_redsys_response parse_price currency] 2024-02-12T22:04:48Z jordi fita mas # Add function to process Redsys response of a payment down_payment [roles schema_camper payment] 2024-02-13T21:53:44Z jordi fita mas # Add function to compute payment down payment from its percentage +payment_reference [roles schema_camper payment] 2024-02-14T01:45:37Z jordi fita mas # Add function to generate a payment reference diff --git a/test/down_payment.sql b/test/down_payment.sql index 9925f54..34a42ab 100644 --- a/test/down_payment.sql +++ b/test/down_payment.sql @@ -46,14 +46,14 @@ insert into campsite_type (campsite_type_id, slug, company_id, name, media_id, m values (12, 'c1b6f4fc-32c1-4cd5-b796-0c5059152a52', 2, 'Plots', 10, 6, '[1, 7]', 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, down_payment_percent, zone_preferences) -values (22, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, '') - , (23, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, '') - , (24, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2500, 0.75, '') - , (25, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1234, 0.99, '') - , (26, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, '') - , (27, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 987654, 0.33, '') - , (28, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 987654, 0.19, '') +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, currency_code, down_payment_percent, zone_preferences) +values (22, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', 1.0, '') + , (23, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', 0.5, '') + , (24, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2500, 'EUR', 0.75, '') + , (25, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1234, 'EUR', 0.99, '') + , (26, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 'EUR', 0.5, '') + , (27, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 987654, 'EUR', 0.33, '') + , (28, 2, 12, '2024-08-28', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 987654, 'EUR', 0.19, '') ; select bag_eq( diff --git a/test/draft_payment.sql b/test/draft_payment.sql index b3e1f95..96fb66a 100644 --- a/test/draft_payment.sql +++ b/test/draft_payment.sql @@ -95,9 +95,9 @@ values (16, 4, 800) , (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, payment_status, created_at, updated_at) -values (22, '7cccfe16-695e-486d-a6a5-1162fb85cafb', 2, 12, current_date + 60, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 'draft', '2024-01-01 01:01:01', '2024-01-01 01:01:01') - , (24, '6eeae04c-2fea-4d67-97dc-a4b8a83df99f', 2, 12, current_date + 61, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 'pending', '2024-01-01 02:02:02', '2024-01-01 02:02:02') +insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, zone_preferences, payment_status, created_at, updated_at) +values (22, '7cccfe16-695e-486d-a6a5-1162fb85cafb', 2, 12, current_date + 60, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'USD', '', 'draft', '2024-01-01 01:01:01', '2024-01-01 01:01:01') + , (24, '6eeae04c-2fea-4d67-97dc-a4b8a83df99f', 2, 12, current_date + 61, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'USD', '', 'pending', '2024-01-01 02:02:02', '2024-01-01 02:02:02') ; insert into payment_option (payment_id, campsite_type_option_id, units, subtotal) @@ -128,12 +128,12 @@ select results_ne( ); select bag_eq( - $$ select 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, down_payment_percent, zone_preferences, payment_status, created_at, updated_at from payment $$, - $$ values (2, 12, current_date + 58, current_date + 65, 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 0.3, 'pref I before E', 'draft', '2024-01-01 01:01:01', current_timestamp) - , (2, 14, current_date + 59, current_date + 64, 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 0.3, '', 'draft', current_timestamp, current_timestamp) - , (2, 14, current_date + 6, current_date + 11, 85000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 86750, 1.0, '', 'draft', current_timestamp, current_timestamp) - , (2, 12, current_date + 61, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, '', 'pending', '2024-01-01 02:02:02', '2024-01-01 02:02:02') - , (2, 14, current_date + 31, current_date + 36, 85000, 2, 0, 1, 0, 1, 0, 1, 0, 3500, 96000, 0.3, 'under a tree', 'draft', current_timestamp, current_timestamp) + $$ select company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, down_payment_percent, zone_preferences, payment_status, created_at, updated_at from payment $$, + $$ values (2, 12, current_date + 58, current_date + 65, 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'EUR', 0.3, 'pref I before E', 'draft', '2024-01-01 01:01:01', current_timestamp) + , (2, 14, current_date + 59, current_date + 64, 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', 0.3, '', 'draft', current_timestamp, current_timestamp) + , (2, 14, current_date + 6, current_date + 11, 85000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 86750, 'EUR', 1.0, '', 'draft', current_timestamp, current_timestamp) + , (2, 12, current_date + 61, current_date + 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'USD', 1.0, '', 'pending', '2024-01-01 02:02:02', '2024-01-01 02:02:02') + , (2, 14, current_date + 31, current_date + 36, 85000, 2, 0, 1, 0, 1, 0, 1, 0, 3500, 96000, 'EUR', 0.3, 'under a tree', 'draft', current_timestamp, current_timestamp) $$, 'Should have added and updated payments' ); diff --git a/test/payment.sql b/test/payment.sql index c17161d..3cc25d3 100644 --- a/test/payment.sql +++ b/test/payment.sql @@ -5,7 +5,7 @@ reset client_min_messages; begin; -select plan(108); +select plan(114); set search_path to camper, public; @@ -108,6 +108,13 @@ select col_type_is('payment', 'total', 'nonnegative_integer'); select col_not_null('payment', 'total'); select col_hasnt_default('payment', 'total'); +select has_column('payment', 'currency_code'); +select col_is_fk('payment', 'currency_code'); +select fk_ok('payment', 'currency_code', 'currency', 'currency_code'); +select col_type_is('payment', 'currency_code', 'currency_code'); +select col_not_null('payment', 'currency_code'); +select col_hasnt_default('payment', 'currency_code'); + select has_column('payment', 'down_payment_percent'); select col_type_is('payment', 'down_payment_percent', 'percentage'); select col_not_null('payment', 'down_payment_percent'); @@ -166,7 +173,7 @@ values (10, 1, 2, 'Type A', '

A

', 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, '') $$, + $$ 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, currency_code, zone_preferences) values (1, 10, '2024-07-07', '2024-07-07', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') $$, '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)' ); diff --git a/test/payment_option.sql b/test/payment_option.sql index 31913bd..c79809c 100644 --- a/test/payment_option.sql +++ b/test/payment_option.sql @@ -42,42 +42,6 @@ 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', '

A

', 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 * from finish(); diff --git a/test/payment_reference.sql b/test/payment_reference.sql new file mode 100644 index 0000000..9e8d880 --- /dev/null +++ b/test/payment_reference.sql @@ -0,0 +1,74 @@ +-- Test reference +set client_min_messages to warning; +create extension if not exists pgtap; +reset client_min_messages; + +begin; + +select plan(10); + +set search_path to camper, public; + +select has_function('camper', 'reference', array['payment']); +select function_lang_is('camper', 'reference', array['payment'], 'sql'); +select function_returns('camper', 'reference', array['payment'], 'text'); +select isnt_definer('camper', 'reference', array['payment']); +select volatility_is('camper', 'reference', array['payment'], 'stable'); +select function_privs_are('camper', 'reference', array['payment'], 'guest', array['EXECUTE']); +select function_privs_are('camper', 'reference', array['payment'], 'employee', array['EXECUTE']); +select function_privs_are('camper', 'reference', array['payment'], 'admin', array['EXECUTE']); +select function_privs_are('camper', 'reference', array['payment'], 'authenticator', array[]::text[]); + + +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 (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 350, '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 (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) +; + +insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, zone_preferences) +values (22, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (23, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (24, '8d38a482-8a25-4d85-9929-e5f425fcac04', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (25, 'b770f8b7-f148-4ab4-a786-aa070af598e5', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (26, '31910d73-d343-44b7-8a29-f7e075b64933', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (27, 'c9488490-ac09-4402-90cd-f6f0546f04c0', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') + , (28, '5819823e-c0ac-4baa-a3ae-515fbb70e909', 2, 12, '2024-08-29', '2024-09-03', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'EUR', '') +; + +select bag_eq( + $$ select payment_id, payment.reference from payment $$, + $$ values (22, '000000224ef3') + , (23, '000000236d1b') + , (24, '000000248d38') + , (25, '00000025b770') + , (26, '000000263191') + , (27, '00000027c948') + , (28, '000000285819') + $$, + 'Should give out the order code for each payment' +); + + +select * +from finish(); + +rollback; diff --git a/test/process_payment_response.sql b/test/process_payment_response.sql index 4000a64..87f7f4a 100644 --- a/test/process_payment_response.sql +++ b/test/process_payment_response.sql @@ -44,14 +44,14 @@ insert into campsite_type (campsite_type_id, slug, company_id, name, media_id, m values (12, 'c1b6f4fc-32c1-4cd5-b796-0c5059152a52', 2, 'Plots', 10, 6, '[1, 7]', true) ; -insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, zone_preferences, payment_status, created_at, updated_at) -values (22, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'pref I before E', 'draft', '2024-01-01 01:01:01', '2024-01-01 01:01:01') - , (24, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'pending', '2024-01-02 02:02:02', '2024-01-02 02:02:02') - , (26, '8d38a482-8a25-4d85-9929-e5f425fcac04', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'completed', '2024-01-03 03:03:03', '2024-01-03 03:03:03') - , (28, 'b770f8b7-f148-4ab4-a786-aa070af598e5', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'failed', '2024-01-04 04:04:04', '2024-01-04 04:04:04') - , (30, '31910d73-d343-44b7-8a29-f7e075b64933', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'refunded', '2024-01-05 05:05:05', '2024-01-05 05:05:05') - , (32, 'c9488490-ac09-4402-90cd-f6f0546f04c0', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'pending', '2024-01-05 05:05:05', '2024-01-05 05:05:05') - , (34, '5819823e-c0ac-4baa-a3ae-515fbb70e909', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'pending', '2024-01-05 05:05:05', '2024-01-06 06:06:06') +insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, zone_preferences, payment_status, created_at, updated_at) +values (22, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'EUR', 'pref I before E', 'draft', '2024-01-01 01:01:01', '2024-01-01 01:01:01') + , (24, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'pending', '2024-01-02 02:02:02', '2024-01-02 02:02:02') + , (26, '8d38a482-8a25-4d85-9929-e5f425fcac04', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'completed', '2024-01-03 03:03:03', '2024-01-03 03:03:03') + , (28, 'b770f8b7-f148-4ab4-a786-aa070af598e5', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'failed', '2024-01-04 04:04:04', '2024-01-04 04:04:04') + , (30, '31910d73-d343-44b7-8a29-f7e075b64933', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'refunded', '2024-01-05 05:05:05', '2024-01-05 05:05:05') + , (32, 'c9488490-ac09-4402-90cd-f6f0546f04c0', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'pending', '2024-01-05 05:05:05', '2024-01-05 05:05:05') + , (34, '5819823e-c0ac-4baa-a3ae-515fbb70e909', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'pending', '2024-01-05 05:05:05', '2024-01-06 06:06:06') ; insert into payment_redsys_response (payment_id, response_code, date_time, secure_payment, transaction_type, amount, currency_code, order_number, authorization_code, merchant_code, terminal_number, error_code) diff --git a/test/ready_payment.sql b/test/ready_payment.sql index 5b58d03..1e8ccae 100644 --- a/test/ready_payment.sql +++ b/test/ready_payment.sql @@ -45,9 +45,9 @@ insert into campsite_type (campsite_type_id, slug, company_id, name, media_id, m values (12, 'c1b6f4fc-32c1-4cd5-b796-0c5059152a52', 2, 'Plots', 10, 6, '[1, 7]', true) ; -insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, zone_preferences, payment_status, created_at, updated_at) -values (22, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'pref I before E', 'draft', '2024-01-01 01:01:01', '2024-01-01') - , (24, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, '', 'draft', current_timestamp, current_timestamp) +insert into payment (payment_id, slug, company_id, campsite_type_id, arrival_date, departure_date, subtotal_nights, number_adults, subtotal_adults, number_teenagers, subtotal_teenagers, number_children, subtotal_children, number_dogs, subtotal_dogs, subtotal_tourist_tax, total, currency_code, zone_preferences, payment_status, created_at, updated_at) +values (22, '4ef35e2f-ef98-42d6-a724-913bd761ca8c', 2, 12, '2024-08-28', '2024-09-04', 3200, 2, 10420, 4, 20840, 6, 25080, 3, 2450, 4900, 79160, 'EUR', 'pref I before E', 'draft', '2024-01-01 01:01:01', '2024-01-01') + , (24, '6d1b8e4c-c3c6-4fe4-92c1-2cbf94526693', 2, 12, '2024-08-29', '2024-09-03', 71000, 1, 0, 2, 0, 3, 0, 0, 0, 1750, 72750, 'EUR', '', 'draft', current_timestamp, current_timestamp) ; insert into payment_customer (payment_id, full_name, address, postal_code, city, country_code, email, phone, acsi_card, lang_tag) diff --git a/verify/payment.sql b/verify/payment.sql index 0e36804..cf01473 100644 --- a/verify/payment.sql +++ b/verify/payment.sql @@ -19,6 +19,7 @@ select payment_id , subtotal_dogs , subtotal_tourist_tax , total + , currency_code , down_payment_percent , zone_preferences , payment_status diff --git a/verify/payment_reference.sql b/verify/payment_reference.sql new file mode 100644 index 0000000..ec1d266 --- /dev/null +++ b/verify/payment_reference.sql @@ -0,0 +1,7 @@ +-- Verify camper:order_code on pg + +begin; + +select has_function_privilege('camper.reference(camper.payment)', 'execute'); + +rollback; diff --git a/web/static/camper.css b/web/static/camper.css index 6bce16f..23d0b00 100644 --- a/web/static/camper.css +++ b/web/static/camper.css @@ -289,6 +289,8 @@ main { padding: 2rem 3rem; } +/**/ + table:not(.month) { width: 100%; border-collapse: collapse; @@ -304,6 +306,11 @@ table:not(.month) th { text-align: start; } +table:not(.month) .numeric, .numeric { + text-align: end; +} + +/**/ /* user menu */ nav details { position: relative; @@ -719,25 +726,30 @@ label[x-show] > span, label[x-show] > br { } /**/ -/**/ +/**/ -.booking-created .booking-status { +.booking-created .booking-status, +.payment-draft .payment-status { background-color: var(--camper--color--light-blue); } -.booking-cancelled .booking-status { +.booking-cancelled .booking-status, +.payment-failed .payment-status { background-color: var(--camper--color--rosy); } -.booking-confirmed .booking-status { +.booking-confirmed .booking-status, +.payment-pending .payment-status { background-color: var(--camper--color--hay); } -.booking-checked-in .booking-status { +.booking-checked-in .booking-status, +.payment-complete .payment-status { background-color: var(--camper--color--light-green); } -.booking-invoiced .booking-status { +.booking-invoiced .booking-status, +.payment-refunded .payment-status { background-color: var(--camper--color--light-gray); } diff --git a/web/templates/admin/layout.gohtml b/web/templates/admin/layout.gohtml index 763fd32..263a93e 100644 --- a/web/templates/admin/layout.gohtml +++ b/web/templates/admin/layout.gohtml @@ -37,7 +37,7 @@ {{( pgettext "Company Settings" "title" )}}
  • - {{( pgettext "Payment Settings" "title" )}} + {{( pgettext "Payments" "title" )}}
  • {{( pgettext "Campsite Types" "title" )}} diff --git a/web/templates/admin/payment/details.gohtml b/web/templates/admin/payment/details.gohtml new file mode 100644 index 0000000..bacc0da --- /dev/null +++ b/web/templates/admin/payment/details.gohtml @@ -0,0 +1,148 @@ + +{{ define "title" -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/payment.paymentDetails*/ -}} + {{ printf ( pgettext "Payment %s" "title" ) .Reference }} +{{- end }} + +{{ define "breadcrumb" -}} +
  • {{( pgettext "Payments" "title" )}}
  • +{{- end }} + +{{ define "content" -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/payment.paymentDetails*/ -}} +

    {{ template "title" . }}

    + + + + + + + + + + + + + + + + + + + + + +
    {{( pgettext "Payment" "title" )}}
    {{( pgettext "Reference" "header" )}}{{ .Reference }}
    {{( pgettext "Status" "header" )}}{{ .StatusLabel }}
    {{( pgettext "Created at" "payment header" )}}{{ .CreatedAt | formatDateTime }}
    {{( pgettext "Last updated at" "payment header" )}}{{ .UpdatedAt | formatDateTime }}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {{( pgettext "Booking" "title" )}}
    {{( pgettext "Accommodation" "title" )}}{{ .CampsiteType }}
    {{( pgettext "Area preferences" "header" )}}{{ .ZonePreferences }}
    {{( pgettext "Arrival date" "input" )}}{{ .ArrivalDate | formatDate }}
    {{( pgettext "Departure date" "input" )}}{{ .DepartureDate | formatDate }}
    {{( pgettext "Nights" "cart" )}}{{ .NumNights }}
    {{( pgettext "Adults aged 17 or older" "input" )}}{{ .NumAdults }}
    {{( pgettext "Teenagers from 11 to 16 years old" "input" )}}{{ .NumTeenagers }}
    {{( pgettext "Children from 2 to 10 years old" "input" )}}{{ .NumChildren }}
    {{( pgettext "Dogs" "input" )}}{{ .NumDogs }}
    {{( pgettext "Tourist tax" "cart" )}}{{ .SubtotalTouristTax | formatPrice }}
    {{( pgettext "Down payment" "cart" )}}{{ .DownPaymentPercent }} %, {{ .DownPayment | formatPrice }}
    + + {{ with .Options -}} + + + + {{ range . -}} + + + + + {{- end }} + +
    {{( pgettext "Campsite Type Options" "title" )}}
    {{ .Label }}{{ .Units }}
    + {{- end }} + + {{ with .Customer -}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {{( pgettext "Customer Details" "title" )}}
    {{( pgettext "Full name" "input" )}}{{ .FullName }}
    {{( pgettext "Address" "input" )}}{{ .Address }}
    {{( pgettext "Postcode" "input" )}}{{ .PostalCode }}
    {{( pgettext "City" "input" )}}{{ .City }}
    {{( pgettext "Country" "input" )}}{{ .Country }}
    {{( pgettext "Email" "input" )}}{{ .Email }}
    {{( pgettext "Phone" "input" )}}{{ .Phone }}
    {{( pgettext "Language" "input" )}}{{ .Language }}
    {{( pgettext "ACSI card?" "input" )}}{{if .ACSICard}}{{( gettext "Yes" )}}{{ else }}{{( gettext "No" )}}{{ end }}
    + {{- end }} + +{{- end }} diff --git a/web/templates/admin/payment/index.gohtml b/web/templates/admin/payment/index.gohtml new file mode 100644 index 0000000..89fe9e5 --- /dev/null +++ b/web/templates/admin/payment/index.gohtml @@ -0,0 +1,42 @@ + +{{ define "title" -}} + {{( pgettext "Payments" "title" )}} +{{- end }} + +{{ define "breadcrumb" -}} +{{- end }} + +{{ define "content" -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/payment.paymentIndex*/ -}} + {{( pgettext "Payment Settings" "title" )}} +

    {{ template "title" . }}

    + {{ if .Payments -}} + + + + + + + + + + + + {{ range .Payments -}} + + + + + + + + {{- end }} + +
    {{( pgettext "Date" "header" )}}{{( pgettext "Reference" "header" )}}{{( pgettext "Status" "header" )}}{{( pgettext "Down payment" "header" )}}{{( pgettext "Total" "header" )}}
    {{ .CreatedAt | formatDate }}{{ .Reference }}{{ .StatusLabel }}{{ .DownPayment | formatPrice }}{{ .Total | formatPrice }}
    + {{ else -}} +

    {{( gettext "No payments found." )}}

    + {{- end }} +{{- end }} diff --git a/web/templates/admin/booking/payment.gohtml b/web/templates/admin/payment/settings.gohtml similarity index 91% rename from web/templates/admin/booking/payment.gohtml rename to web/templates/admin/payment/settings.gohtml index 702a311..e78cee6 100644 --- a/web/templates/admin/booking/payment.gohtml +++ b/web/templates/admin/payment/settings.gohtml @@ -7,12 +7,13 @@ {{- end }} {{ define "breadcrumb" -}} +
  • {{( pgettext "Payments" "title" )}}
  • {{- end }} {{ define "content" -}} - {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/booking.paymentForm*/ -}} -
    -

    {{( pgettext "Payment Settings" "title" )}}

    + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/payment.settingsForm*/ -}} + +

    {{ template "title" . }}

    {{ CSRFInput }}
    {{ with .MerchantCode -}} diff --git a/web/templates/public/payment/details.gohtml b/web/templates/public/payment/details.gohtml index c99b0b7..29b5d59 100644 --- a/web/templates/public/payment/details.gohtml +++ b/web/templates/public/payment/details.gohtml @@ -2,7 +2,7 @@
    {{( pgettext "Order Number" "title" )}}
    -
    {{ .OrderNumber }}
    +
    {{ .Reference }}
    {{( pgettext "Date" "title" )}}