From 0cbf973cbb4dd142be19878cded974a8c6b131aa Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Fri, 27 Oct 2023 16:04:43 +0200 Subject: [PATCH] Add the payment form to admin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Had to change setup_redsys because admins can not read the current encrypt key, thus it is not possible to `set encrypt_key = coalesce(…, encrypt_key)`. Not that it did much sense, anyway, as i was already inside the branch of the if when encrpty_key is null. However, it seems that this also affects in the `on conflict` update. I assume this is because `excluded` is some kind of row of the relation and has the same restrictions. --- deploy/setup_redsys.sql | 5 +- pkg/app/admin.go | 7 +- pkg/booking/admin.go | 171 +++++++++++++++++++++++++++++ pkg/database/funcs.go | 9 ++ pkg/form/validator.go | 10 ++ po/ca.po | 163 ++++++++++++++++++++------- po/es.po | 163 ++++++++++++++++++++------- web/templates/admin/form.gohtml | 7 ++ web/templates/admin/layout.gohtml | 7 +- web/templates/admin/payment.gohtml | 65 +++++++++++ 10 files changed, 523 insertions(+), 84 deletions(-) create mode 100644 pkg/booking/admin.go create mode 100644 web/templates/admin/payment.gohtml diff --git a/deploy/setup_redsys.sql b/deploy/setup_redsys.sql index 2b422e3..f4db6e7 100644 --- a/deploy/setup_redsys.sql +++ b/deploy/setup_redsys.sql @@ -17,8 +17,7 @@ begin set merchant_code = setup_redsys.merchant_code, terminal_number = setup_redsys.terminal_number, environment = setup_redsys.environment, - integration = setup_redsys.integration, - encrypt_key = coalesce(decode(setup_redsys.encrypt_key, 'base64'), redsys.encrypt_key) + integration = setup_redsys.integration where company_id = company ; else @@ -29,7 +28,7 @@ begin terminal_number = excluded.terminal_number, environment = excluded.environment, integration = excluded.integration, - encrypt_key = coalesce(excluded.encrypt_key, redsys.encrypt_key) + encrypt_key = decode(setup_redsys.encrypt_key, 'base64') ; end if; end diff --git a/pkg/app/admin.go b/pkg/app/admin.go index 4fbf642..a84fdc6 100644 --- a/pkg/app/admin.go +++ b/pkg/app/admin.go @@ -6,16 +6,17 @@ package app import ( - "dev.tandem.ws/tandem/camper/pkg/media" "net/http" "dev.tandem.ws/tandem/camper/pkg/auth" + "dev.tandem.ws/tandem/camper/pkg/booking" "dev.tandem.ws/tandem/camper/pkg/campsite" "dev.tandem.ws/tandem/camper/pkg/company" "dev.tandem.ws/tandem/camper/pkg/database" "dev.tandem.ws/tandem/camper/pkg/home" httplib "dev.tandem.ws/tandem/camper/pkg/http" "dev.tandem.ws/tandem/camper/pkg/locale" + "dev.tandem.ws/tandem/camper/pkg/media" "dev.tandem.ws/tandem/camper/pkg/season" "dev.tandem.ws/tandem/camper/pkg/services" "dev.tandem.ws/tandem/camper/pkg/template" @@ -26,6 +27,7 @@ type adminHandler struct { company *company.AdminHandler home *home.AdminHandler media *media.AdminHandler + payment *booking.AdminHandler season *season.AdminHandler services *services.AdminHandler } @@ -36,6 +38,7 @@ func newAdminHandler(locales locale.Locales, mediaDir string) *adminHandler { company: company.NewAdminHandler(), home: home.NewAdminHandler(locales), media: media.NewAdminHandler(mediaDir), + payment: booking.NewAdminHandler(), season: season.NewAdminHandler(locales), services: services.NewAdminHandler(locales), } @@ -65,6 +68,8 @@ func (h *adminHandler) Handle(user *auth.User, company *auth.Company, conn *data h.home.Handler(user, company, conn).ServeHTTP(w, r) case "media": h.media.Handler(user, company, conn).ServeHTTP(w, r) + case "payment": + 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 new file mode 100644 index 0000000..718511b --- /dev/null +++ b/pkg/booking/admin.go @@ -0,0 +1,171 @@ +/* + * SPDX-FileCopyrightText: 2023 jordi fita mas + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package booking + +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 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: + f := newPaymentForm(user.Locale) + if err := f.FillFromDatabase(r.Context(), company, conn); err != nil { + 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) + } + }) +} + +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, "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/payment", http.StatusSeeOther) +} diff --git a/pkg/database/funcs.go b/pkg/database/funcs.go index 44e76ac..015225d 100644 --- a/pkg/database/funcs.go +++ b/pkg/database/funcs.go @@ -58,3 +58,12 @@ func (c *Conn) TranslateCampsiteTypeFeature(ctx context.Context, id int, langTag _, err := c.Exec(ctx, "select translate_campsite_type_feature($1, $2, $3)", id, langTag, name) return err } + +func (c *Conn) SetupRedsys(ctx context.Context, companyID int, merchantCode string, terminalNumber int, environment string, integration string, encryptKey string) error { + var encryptKeyParam interface{} + if encryptKey != "" { + encryptKeyParam = encryptKey + } + _, err := c.Exec(ctx, "select setup_redsys($1, $2, $3, $4, $5, $6)", companyID, merchantCode, terminalNumber, environment, integration, encryptKeyParam) + return err +} diff --git a/pkg/form/validator.go b/pkg/form/validator.go index 87673e9..c7722bc 100644 --- a/pkg/form/validator.go +++ b/pkg/form/validator.go @@ -7,6 +7,7 @@ package form import ( "context" + "encoding/base64" "errors" "net/mail" "net/url" @@ -38,6 +39,10 @@ func (v *Validator) CheckMinLength(input *Input, min int, message string) bool { return v.Check(input, len(input.Val) >= min, message) } +func (v *Validator) CheckExactLength(input *Input, length int, message string) bool { + return v.Check(input, len(input.Val) == length, message) +} + func (v *Validator) CheckMinInteger(input *Input, min int, message string) bool { i, _ := strconv.Atoi(input.Val) return v.Check(input, i >= min, message) @@ -58,6 +63,11 @@ func (v *Validator) CheckValidInteger(input *Input, message string) bool { return v.Check(input, err == nil, message) } +func (v *Validator) CheckValidBase64(input *Input, message string) bool { + _, err := base64.StdEncoding.DecodeString(input.Val) + return v.Check(input, err == nil, message) +} + func (v *Validator) CheckValidDecimal(input *Input, message string) bool { _, err := strconv.ParseFloat(input.Val, 64) return v.Check(input, err == nil, message) diff --git a/po/ca.po b/po/ca.po index fa7ba25..fd54d15 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: 2023-10-27 01:12+0200\n" +"POT-Creation-Date: 2023-10-27 15:59+0200\n" "PO-Revision-Date: 2023-07-22 23:45+0200\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -111,7 +111,7 @@ msgid "Check-out Date" msgstr "Data de sortida" #: web/templates/public/campsite/type.gohtml:54 -#: web/templates/public/booking.gohtml:175 +#: web/templates/public/booking.gohtml:194 msgctxt "action" msgid "Book" msgstr "Reserva" @@ -289,100 +289,100 @@ msgctxt "input" msgid "Full name" msgstr "Nom i cognoms" -#: web/templates/public/booking.gohtml:26 +#: web/templates/public/booking.gohtml:27 msgctxt "input" msgid "Address (optional)" msgstr "Adreça (opcional)" -#: web/templates/public/booking.gohtml:34 +#: web/templates/public/booking.gohtml:36 msgctxt "input" msgid "Postcode (optional)" msgstr "Codi postal (opcional)" -#: web/templates/public/booking.gohtml:42 +#: web/templates/public/booking.gohtml:45 msgctxt "input" msgid "Town or village (optional)" msgstr "Població (opcional)" -#: web/templates/public/booking.gohtml:50 +#: web/templates/public/booking.gohtml:54 #: web/templates/admin/taxDetails.gohtml:98 msgctxt "input" msgid "Country" msgstr "País" -#: web/templates/public/booking.gohtml:53 +#: web/templates/public/booking.gohtml:57 msgid "Choose a country" msgstr "Esculli un país" -#: web/templates/public/booking.gohtml:60 web/templates/admin/login.gohtml:22 +#: web/templates/public/booking.gohtml:65 web/templates/admin/login.gohtml:22 #: web/templates/admin/profile.gohtml:35 #: web/templates/admin/taxDetails.gohtml:50 msgctxt "input" msgid "Email" msgstr "Correu-e" -#: web/templates/public/booking.gohtml:68 +#: web/templates/public/booking.gohtml:74 #: web/templates/admin/taxDetails.gohtml:42 msgctxt "input" msgid "Phone" msgstr "Telèfon" -#: web/templates/public/booking.gohtml:76 +#: web/templates/public/booking.gohtml:83 msgctxt "title" msgid "Party Details" msgstr "Dades dels visitants" -#: web/templates/public/booking.gohtml:79 +#: web/templates/public/booking.gohtml:86 msgctxt "input" msgid "Adults" msgstr "Adults" -#: web/templates/public/booking.gohtml:87 +#: web/templates/public/booking.gohtml:95 msgctxt "input" msgid "Teenagers (from 11 to 16 years old)" msgstr "Adolescents (entre 11 i 16 anys)" -#: web/templates/public/booking.gohtml:95 +#: web/templates/public/booking.gohtml:104 msgctxt "input" msgid "Children (up to 10 years old)" msgstr "Nens (fins a 10 anys)" -#: web/templates/public/booking.gohtml:103 +#: web/templates/public/booking.gohtml:113 msgctxt "input" msgid "Dogs" msgstr "Gossos" -#: web/templates/public/booking.gohtml:111 +#: web/templates/public/booking.gohtml:122 msgctxt "title" msgid "Accomodation" msgstr "Acomodacions" -#: web/templates/public/booking.gohtml:136 +#: web/templates/public/booking.gohtml:150 msgctxt "title" msgid "Booking Period" msgstr "Període de reserva" -#: web/templates/public/booking.gohtml:139 +#: web/templates/public/booking.gohtml:153 msgctxt "input" msgid "Arrival date" msgstr "Data d’arribada" -#: web/templates/public/booking.gohtml:147 +#: web/templates/public/booking.gohtml:162 msgctxt "input" msgid "Departure date" msgstr "Data de sortida" -#: web/templates/public/booking.gohtml:155 +#: web/templates/public/booking.gohtml:171 msgctxt "input" msgid "Area preferences (optional)" msgstr "Preferències d’àrea (opcional)" -#: web/templates/public/booking.gohtml:165 +#: web/templates/public/booking.gohtml:182 msgctxt "input" msgid "ACSI card? (optional)" msgstr "Targeta ACSI? (opcional)" -#: web/templates/public/booking.gohtml:171 +#: web/templates/public/booking.gohtml:189 msgctxt "input" msgid "I have read and I accept the reservation conditions" msgstr "He llegit i accepto les condicions de reserves" @@ -399,7 +399,7 @@ msgstr "Salta al contingut principal" #: web/templates/public/layout.gohtml:35 web/templates/public/layout.gohtml:80 #: web/templates/admin/campsite/index.gohtml:6 #: web/templates/admin/campsite/index.gohtml:12 -#: web/templates/admin/layout.gohtml:40 web/templates/admin/layout.gohtml:71 +#: web/templates/admin/layout.gohtml:43 web/templates/admin/layout.gohtml:74 msgctxt "title" msgid "Campsites" msgstr "Allotjaments" @@ -826,7 +826,7 @@ msgstr "Descripció" #: web/templates/admin/campsite/type/index.gohtml:6 #: web/templates/admin/campsite/type/index.gohtml:12 -#: web/templates/admin/layout.gohtml:37 +#: web/templates/admin/layout.gohtml:40 msgctxt "title" msgid "Campsite Types" msgstr "Tipus d’allotjaments" @@ -901,7 +901,7 @@ msgstr "Color" #: web/templates/admin/season/index.gohtml:6 #: web/templates/admin/season/index.gohtml:12 -#: web/templates/admin/layout.gohtml:43 +#: web/templates/admin/layout.gohtml:46 msgctxt "title" msgid "Seasons" msgstr "Temporades" @@ -932,8 +932,50 @@ msgctxt "action" msgid "Cancel" msgstr "Canceŀla" +#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12 +#: web/templates/admin/layout.gohtml:37 +msgctxt "title" +msgid "Payment Settings" +msgstr "Paràmetres de pagament" + +#: web/templates/admin/payment.gohtml:17 +msgctxt "input" +msgid "Merchant Code" +msgstr "Codi del comerç" + +#: web/templates/admin/payment.gohtml:26 +msgctxt "input" +msgid "Terminal Number" +msgstr "Número de terminal" + +#: web/templates/admin/payment.gohtml:36 +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.gohtml:38 +msgctxt "input" +msgid "Merchant Key" +msgstr "Clau del comerç" + +#: web/templates/admin/payment.gohtml:48 +msgctxt "title" +msgid "Environment" +msgstr "Entorn" + +#: web/templates/admin/payment.gohtml:55 +msgctxt "title" +msgid "Integration" +msgstr "Integració" + +#: web/templates/admin/payment.gohtml:62 web/templates/admin/profile.gohtml:75 +#: web/templates/admin/taxDetails.gohtml:152 +msgctxt "action" +msgid "Save changes" +msgstr "Desa els canvis" + #: web/templates/admin/dashboard.gohtml:6 -#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68 +#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:71 msgctxt "title" msgid "Dashboard" msgstr "Tauler" @@ -966,7 +1008,7 @@ msgid "New Service" msgstr "Nou servei" #: web/templates/admin/services/index.gohtml:6 -#: web/templates/admin/layout.gohtml:52 +#: web/templates/admin/layout.gohtml:55 msgctxt "title" msgid "Services Page" msgstr "Pàgina de serveis" @@ -1027,12 +1069,6 @@ msgctxt "input" msgid "Language" msgstr "Idioma" -#: web/templates/admin/profile.gohtml:75 -#: web/templates/admin/taxDetails.gohtml:152 -msgctxt "action" -msgid "Save changes" -msgstr "Desa els canvis" - #: web/templates/admin/taxDetails.gohtml:6 #: web/templates/admin/taxDetails.gohtml:12 msgctxt "title" @@ -1110,19 +1146,19 @@ msgctxt "title" msgid "Company Settings" msgstr "Paràmetres de l’empresa" -#: web/templates/admin/layout.gohtml:46 +#: web/templates/admin/layout.gohtml:49 #: web/templates/admin/media/index.gohtml:6 #: web/templates/admin/media/index.gohtml:11 msgctxt "title" msgid "Media" msgstr "Mèdia" -#: web/templates/admin/layout.gohtml:49 web/templates/admin/home/index.gohtml:6 +#: web/templates/admin/layout.gohtml:52 web/templates/admin/home/index.gohtml:6 msgctxt "title" msgid "Home Page" msgstr "Pàgina d’inici" -#: web/templates/admin/layout.gohtml:57 +#: web/templates/admin/layout.gohtml:60 msgctxt "action" msgid "Logout" msgstr "Surt" @@ -1253,7 +1289,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:53 +#: pkg/app/admin.go:56 msgid "Access forbidden" msgstr "Accés prohibit" @@ -1522,6 +1558,58 @@ 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/admin.go:74 +msgctxt "redsys environment" +msgid "Test" +msgstr "Proves" + +#: pkg/booking/admin.go:78 +msgctxt "redsys environment" +msgid "Live" +msgstr "Real" + +#: pkg/booking/admin.go:87 +msgctxt "redsys integration" +msgid "InSite" +msgstr "InSite" + +#: pkg/booking/admin.go:91 +msgctxt "redsys integration" +msgid "Redirect" +msgstr "Redirecció" + +#: pkg/booking/admin.go:135 +msgid "Merchant code can not be empty." +msgstr "No podeu deixar el codi del comerç en blanc." + +#: pkg/booking/admin.go:136 +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:137 +msgid "Merchant code must be a number." +msgstr "El codi del comerç." + +#: pkg/booking/admin.go:141 +msgid "Terminal number can not be empty." +msgstr "No podeu deixar el número del terminal en blanc." + +#: pkg/booking/admin.go:142 +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:150 +msgid "Selected environment is not valid." +msgstr "L’entorn escollit no és vàlid." + +#: pkg/booking/admin.go:151 +msgid "Selected integration is not valid." +msgstr "La integració escollida no és vàlida." + +#: pkg/booking/admin.go:154 +msgid "The merchant key is not valid." +msgstr "Aquesta clau del comerç no és vàlid." + #: pkg/booking/public.go:279 msgid "Full name can not be empty." msgstr "No podeu deixar el nom i els cognoms en blanc." @@ -1650,9 +1738,6 @@ msgstr "El valor de %s ha de ser com a màxim %d." #~ msgid "Legend" #~ msgstr "Llegenda" -#~ msgid "Environment" -#~ msgstr "Entorn" - #~ msgctxt "input" #~ msgid "Title" #~ msgstr "Títol" diff --git a/po/es.po b/po/es.po index 6fdbae1..4e95f41 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: 2023-10-27 01:12+0200\n" +"POT-Creation-Date: 2023-10-27 15:59+0200\n" "PO-Revision-Date: 2023-07-22 23:46+0200\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -111,7 +111,7 @@ msgid "Check-out Date" msgstr "Fecha de salida" #: web/templates/public/campsite/type.gohtml:54 -#: web/templates/public/booking.gohtml:175 +#: web/templates/public/booking.gohtml:194 msgctxt "action" msgid "Book" msgstr "Reservar" @@ -289,100 +289,100 @@ msgctxt "input" msgid "Full name" msgstr "Nombre y apellidos" -#: web/templates/public/booking.gohtml:26 +#: web/templates/public/booking.gohtml:27 msgctxt "input" msgid "Address (optional)" msgstr "Dirección (opcional)" -#: web/templates/public/booking.gohtml:34 +#: web/templates/public/booking.gohtml:36 msgctxt "input" msgid "Postcode (optional)" msgstr "Código postal (opcional)" -#: web/templates/public/booking.gohtml:42 +#: web/templates/public/booking.gohtml:45 msgctxt "input" msgid "Town or village (optional)" msgstr "Población (opcional)" -#: web/templates/public/booking.gohtml:50 +#: web/templates/public/booking.gohtml:54 #: web/templates/admin/taxDetails.gohtml:98 msgctxt "input" msgid "Country" msgstr "País" -#: web/templates/public/booking.gohtml:53 +#: web/templates/public/booking.gohtml:57 msgid "Choose a country" msgstr "Escoja un país" -#: web/templates/public/booking.gohtml:60 web/templates/admin/login.gohtml:22 +#: web/templates/public/booking.gohtml:65 web/templates/admin/login.gohtml:22 #: web/templates/admin/profile.gohtml:35 #: web/templates/admin/taxDetails.gohtml:50 msgctxt "input" msgid "Email" msgstr "Correo-e" -#: web/templates/public/booking.gohtml:68 +#: web/templates/public/booking.gohtml:74 #: web/templates/admin/taxDetails.gohtml:42 msgctxt "input" msgid "Phone" msgstr "Teléfono" -#: web/templates/public/booking.gohtml:76 +#: web/templates/public/booking.gohtml:83 msgctxt "title" msgid "Party Details" msgstr "Datos de los visitantes" -#: web/templates/public/booking.gohtml:79 +#: web/templates/public/booking.gohtml:86 msgctxt "input" msgid "Adults" msgstr "Adultos" -#: web/templates/public/booking.gohtml:87 +#: web/templates/public/booking.gohtml:95 msgctxt "input" msgid "Teenagers (from 11 to 16 years old)" msgstr "Adolescentes (de 11 a 16 años)" -#: web/templates/public/booking.gohtml:95 +#: web/templates/public/booking.gohtml:104 msgctxt "input" msgid "Children (up to 10 years old)" msgstr "Niños (hasta 10 años)" -#: web/templates/public/booking.gohtml:103 +#: web/templates/public/booking.gohtml:113 msgctxt "input" msgid "Dogs" msgstr "Perros" -#: web/templates/public/booking.gohtml:111 +#: web/templates/public/booking.gohtml:122 msgctxt "title" msgid "Accomodation" msgstr "Acomodaciones" -#: web/templates/public/booking.gohtml:136 +#: web/templates/public/booking.gohtml:150 msgctxt "title" msgid "Booking Period" msgstr "Periodo de reserva" -#: web/templates/public/booking.gohtml:139 +#: web/templates/public/booking.gohtml:153 msgctxt "input" msgid "Arrival date" msgstr "Fecha de llegada" -#: web/templates/public/booking.gohtml:147 +#: web/templates/public/booking.gohtml:162 msgctxt "input" msgid "Departure date" msgstr "Fecha de salida" -#: web/templates/public/booking.gohtml:155 +#: web/templates/public/booking.gohtml:171 msgctxt "input" msgid "Area preferences (optional)" msgstr "Preferencias de área (opcional)" -#: web/templates/public/booking.gohtml:165 +#: web/templates/public/booking.gohtml:182 msgctxt "input" msgid "ACSI card? (optional)" msgstr "¿Tarjeta ACSI? (opcional)" -#: web/templates/public/booking.gohtml:171 +#: web/templates/public/booking.gohtml:189 msgctxt "input" msgid "I have read and I accept the reservation conditions" msgstr "He leído y acepto las condiciones de reserva" @@ -399,7 +399,7 @@ msgstr "Saltar al contenido principal" #: web/templates/public/layout.gohtml:35 web/templates/public/layout.gohtml:80 #: web/templates/admin/campsite/index.gohtml:6 #: web/templates/admin/campsite/index.gohtml:12 -#: web/templates/admin/layout.gohtml:40 web/templates/admin/layout.gohtml:71 +#: web/templates/admin/layout.gohtml:43 web/templates/admin/layout.gohtml:74 msgctxt "title" msgid "Campsites" msgstr "Alojamientos" @@ -826,7 +826,7 @@ msgstr "Descripción" #: web/templates/admin/campsite/type/index.gohtml:6 #: web/templates/admin/campsite/type/index.gohtml:12 -#: web/templates/admin/layout.gohtml:37 +#: web/templates/admin/layout.gohtml:40 msgctxt "title" msgid "Campsite Types" msgstr "Tipos de alojamientos" @@ -901,7 +901,7 @@ msgstr "Color" #: web/templates/admin/season/index.gohtml:6 #: web/templates/admin/season/index.gohtml:12 -#: web/templates/admin/layout.gohtml:43 +#: web/templates/admin/layout.gohtml:46 msgctxt "title" msgid "Seasons" msgstr "Temporadas" @@ -932,8 +932,50 @@ msgctxt "action" msgid "Cancel" msgstr "Cancelar" +#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12 +#: web/templates/admin/layout.gohtml:37 +msgctxt "title" +msgid "Payment Settings" +msgstr "Parámetros de pago" + +#: web/templates/admin/payment.gohtml:17 +msgctxt "input" +msgid "Merchant Code" +msgstr "Código del comercio" + +#: web/templates/admin/payment.gohtml:26 +msgctxt "input" +msgid "Terminal Number" +msgstr "Número de terminal" + +#: web/templates/admin/payment.gohtml:36 +msgctxt "input" +msgid "Merchant Key (only if must change it)" +msgstr "Clave del comercio (sólo si se debe cambiar)" + +#: web/templates/admin/payment.gohtml:38 +msgctxt "input" +msgid "Merchant Key" +msgstr "Clave del comercio" + +#: web/templates/admin/payment.gohtml:48 +msgctxt "title" +msgid "Environment" +msgstr "Entorno" + +#: web/templates/admin/payment.gohtml:55 +msgctxt "title" +msgid "Integration" +msgstr "Integración" + +#: web/templates/admin/payment.gohtml:62 web/templates/admin/profile.gohtml:75 +#: web/templates/admin/taxDetails.gohtml:152 +msgctxt "action" +msgid "Save changes" +msgstr "Guardar los cambios" + #: web/templates/admin/dashboard.gohtml:6 -#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68 +#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:71 msgctxt "title" msgid "Dashboard" msgstr "Panel" @@ -966,7 +1008,7 @@ msgid "New Service" msgstr "Nuevo servicio" #: web/templates/admin/services/index.gohtml:6 -#: web/templates/admin/layout.gohtml:52 +#: web/templates/admin/layout.gohtml:55 msgctxt "title" msgid "Services Page" msgstr "Página de servicios" @@ -1027,12 +1069,6 @@ msgctxt "input" msgid "Language" msgstr "Idioma" -#: web/templates/admin/profile.gohtml:75 -#: web/templates/admin/taxDetails.gohtml:152 -msgctxt "action" -msgid "Save changes" -msgstr "Guardar los cambios" - #: web/templates/admin/taxDetails.gohtml:6 #: web/templates/admin/taxDetails.gohtml:12 msgctxt "title" @@ -1110,19 +1146,19 @@ msgctxt "title" msgid "Company Settings" msgstr "Parámetros de la empresa" -#: web/templates/admin/layout.gohtml:46 +#: web/templates/admin/layout.gohtml:49 #: web/templates/admin/media/index.gohtml:6 #: web/templates/admin/media/index.gohtml:11 msgctxt "title" msgid "Media" msgstr "Medios" -#: web/templates/admin/layout.gohtml:49 web/templates/admin/home/index.gohtml:6 +#: web/templates/admin/layout.gohtml:52 web/templates/admin/home/index.gohtml:6 msgctxt "title" msgid "Home Page" msgstr "Página de inicio" -#: web/templates/admin/layout.gohtml:57 +#: web/templates/admin/layout.gohtml:60 msgctxt "action" msgid "Logout" msgstr "Salir" @@ -1253,7 +1289,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:53 +#: pkg/app/admin.go:56 msgid "Access forbidden" msgstr "Acceso prohibido" @@ -1522,6 +1558,58 @@ 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/admin.go:74 +msgctxt "redsys environment" +msgid "Test" +msgstr "Pruebas" + +#: pkg/booking/admin.go:78 +msgctxt "redsys environment" +msgid "Live" +msgstr "Real" + +#: pkg/booking/admin.go:87 +msgctxt "redsys integration" +msgid "InSite" +msgstr "InSite" + +#: pkg/booking/admin.go:91 +msgctxt "redsys integration" +msgid "Redirect" +msgstr "Redirección" + +#: pkg/booking/admin.go:135 +msgid "Merchant code can not be empty." +msgstr "No podéis dejar el código del comercio en blanco." + +#: pkg/booking/admin.go:136 +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:137 +msgid "Merchant code must be a number." +msgstr "El código del comercio tiene que ser un número." + +#: pkg/booking/admin.go:141 +msgid "Terminal number can not be empty." +msgstr "No podéis dejar el número de terminal en blanco." + +#: pkg/booking/admin.go:142 +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:150 +msgid "Selected environment is not valid." +msgstr "El entorno escogido no es válido." + +#: pkg/booking/admin.go:151 +msgid "Selected integration is not valid." +msgstr "La integración escogida no es válida." + +#: pkg/booking/admin.go:154 +msgid "The merchant key is not valid." +msgstr "Esta clave del comercio no es válida." + #: pkg/booking/public.go:279 msgid "Full name can not be empty." msgstr "No podéis dejar el nombre y los apellidos en blanco." @@ -1650,9 +1738,6 @@ msgstr "%s tiene que ser como máximo %d" #~ msgid "Legend" #~ msgstr "Leyenda" -#~ msgid "Environment" -#~ msgstr "Entorno" - #~ msgctxt "input" #~ msgid "Title" #~ msgstr "Título" diff --git a/web/templates/admin/form.gohtml b/web/templates/admin/form.gohtml index f1d2512..75209c2 100644 --- a/web/templates/admin/form.gohtml +++ b/web/templates/admin/form.gohtml @@ -16,6 +16,13 @@ {{- end }} {{- end }} +{{ define "radio-options" -}} + {{- range .Options }} + + {{- end }} +{{- end }} + {{ define "media-picker" -}} {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/form.Media*/ -}}
diff --git a/web/templates/admin/layout.gohtml b/web/templates/admin/layout.gohtml index cc8e2a7..4eeba73 100644 --- a/web/templates/admin/layout.gohtml +++ b/web/templates/admin/layout.gohtml @@ -26,13 +26,16 @@ {{( pgettext "User Menu" "title" )}}
    -
  • +
  • {{( pgettext "Profile" "title" )}}
  • {{ if isAdmin -}} -
  • +
  • {{( pgettext "Company Settings" "title" )}}
  • +
  • + {{( pgettext "Payment Settings" "title" )}} +
  • {{( pgettext "Campsite Types" "title" )}}
  • diff --git a/web/templates/admin/payment.gohtml b/web/templates/admin/payment.gohtml new file mode 100644 index 0000000..2efbd88 --- /dev/null +++ b/web/templates/admin/payment.gohtml @@ -0,0 +1,65 @@ + +{{ define "title" -}} + {{( pgettext "Payment Settings" "title" )}} +{{- end }} + +{{ define "content" -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/booking.paymentForm*/ -}} +
    +

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

    + {{ CSRFInput }} +
    + {{ with .MerchantCode -}} + + {{ template "error-message" . }} + {{- end }} + {{ with .TerminalNumber -}} + + {{ template "error-message" . }} + {{- end }} + {{ with .EncryptKey -}} + + {{ template "error-message" . }} + {{- end }} + {{ with .Environment -}} +
    + {{( pgettext "Environment" "title")}} + {{ template "radio-options" . }} +
    + {{ template "error-message" . }} + {{- end }} + {{ with .Integration -}} +
    + {{( pgettext "Integration" "title")}} + {{ template "radio-options" . }} +
    + {{ template "error-message" . }} + {{- end }} +
    + +
    +{{- end }}