From 2299f2325e64bc43521a99f1b8dfc418b6d5ce03 Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Sun, 28 Apr 2024 22:36:21 +0200 Subject: [PATCH] =?UTF-8?q?Allow=20to=20create=20the=20customer=20to=20inv?= =?UTF-8?q?oice=20=E2=80=9Cin=20flight=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That way i can get the data from the booking or the actual customer. --- pkg/customer/admin.go | 91 +++++++-- pkg/database/funcs.go | 4 +- pkg/invoice/admin.go | 84 ++++++--- po/ca.po | 198 +++++++++++--------- po/es.po | 198 +++++++++++--------- po/fr.po | 198 +++++++++++--------- web/static/camper.css | 8 +- web/templates/admin/customer/contact.gohtml | 124 ++++++++++++ web/templates/admin/customer/form.gohtml | 131 +------------ web/templates/admin/invoice/form.gohtml | 19 +- 10 files changed, 591 insertions(+), 464 deletions(-) create mode 100644 web/templates/admin/customer/contact.gohtml diff --git a/pkg/customer/admin.go b/pkg/customer/admin.go index fedf7ad..a74ef06 100644 --- a/pkg/customer/admin.go +++ b/pkg/customer/admin.go @@ -37,13 +37,13 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat case "new": switch r.Method { case http.MethodGet: - f := newCustomerForm(r.Context(), conn, user.Locale) + f := NewContactForm(r.Context(), conn, user.Locale) f.MustRender(w, r, user, company) default: httplib.MethodNotAllowed(w, r, http.MethodGet) } default: - f := newCustomerForm(r.Context(), conn, user.Locale) + f := NewContactForm(r.Context(), conn, user.Locale) if err := f.FillFromDatabase(r.Context(), conn, head); err != nil { if database.ErrorIsNotFound(err) { http.NotFound(w, r) @@ -56,7 +56,7 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat }) } -func (h *AdminHandler) customerHandler(user *auth.User, company *auth.Company, conn *database.Conn, f *customerForm) http.Handler { +func (h *AdminHandler) customerHandler(user *auth.User, company *auth.Company, conn *database.Conn, f *ContactForm) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var head string head, r.URL.Path = httplib.ShiftPath(r.URL.Path) @@ -133,7 +133,7 @@ func (page *customerIndex) MustRender(w http.ResponseWriter, r *http.Request, us } func addCustomer(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { - f := newCustomerForm(r.Context(), conn, user.Locale) + f := NewContactForm(r.Context(), conn, user.Locale) processCustomerForm(w, r, user, company, conn, f, func(ctx context.Context, tx *database.Tx) error { var err error f.Slug, err = tx.AddContact(ctx, company.ID, f.FullName.Val, f.IDDocumentType.String(), f.IDDocumentNumber.Val, f.Phone.Val, f.Email.Val, f.Address.Val, f.City.Val, f.Province.Val, f.PostalCode.Val, f.Country.String()) @@ -141,14 +141,14 @@ func addCustomer(w http.ResponseWriter, r *http.Request, user *auth.User, compan }) } -func editCustomer(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *customerForm) { +func editCustomer(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *ContactForm) { processCustomerForm(w, r, user, company, conn, f, func(ctx context.Context, tx *database.Tx) error { _, err := tx.EditContact(ctx, f.Slug, f.FullName.Val, f.IDDocumentType.String(), f.IDDocumentNumber.Val, f.Phone.Val, f.Email.Val, f.Address.Val, f.City.Val, f.Province.Val, f.PostalCode.Val, f.Country.String()) return err }) } -func processCustomerForm(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *customerForm, act func(ctx context.Context, tx *database.Tx) error) { +func processCustomerForm(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *ContactForm, act func(ctx context.Context, tx *database.Tx) error) { if err := f.Parse(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -181,7 +181,7 @@ func processCustomerForm(w http.ResponseWriter, r *http.Request, user *auth.User httplib.Redirect(w, r, "/admin/customers", http.StatusSeeOther) } -type customerForm struct { +type ContactForm struct { URL string Slug string FullName *form.Input @@ -196,8 +196,8 @@ type customerForm struct { Phone *form.Input } -func newCustomerForm(ctx context.Context, conn *database.Conn, l *locale.Locale) *customerForm { - return &customerForm{ +func NewContactForm(ctx context.Context, conn *database.Conn, l *locale.Locale) *ContactForm { + return &ContactForm{ FullName: &form.Input{ Name: "full_name", }, @@ -233,7 +233,7 @@ func newCustomerForm(ctx context.Context, conn *database.Conn, l *locale.Locale) } } -func (f *customerForm) FillFromDatabase(ctx context.Context, conn *database.Conn, slug string) error { +func (f *ContactForm) FillFromDatabase(ctx context.Context, conn *database.Conn, slug string) error { row := conn.QueryRow(ctx, ` select '/admin/customers/' || slug , slug @@ -268,7 +268,40 @@ func (f *customerForm) FillFromDatabase(ctx context.Context, conn *database.Conn ) } -func (f *customerForm) Parse(r *http.Request) error { +func (f *ContactForm) FillFromBooking(ctx context.Context, conn *database.Conn, bookingID int) error { + row := conn.QueryRow(ctx, ` + select '' + , '' + , holder_name + , array[]::text[] + , '' + , address + , city + , '' + , postal_code + , array[country_code::text] + , coalesce(email::text, '') + , coalesce(phone::text, '') + from booking + where booking_id = $1 + `, bookingID) + return row.Scan( + &f.URL, + &f.Slug, + &f.FullName.Val, + &f.IDDocumentType.Selected, + &f.IDDocumentNumber.Val, + &f.Address.Val, + &f.City.Val, + &f.Province.Val, + &f.PostalCode.Val, + &f.Country.Selected, + &f.Email.Val, + &f.Phone.Val, + ) +} + +func (f *ContactForm) Parse(r *http.Request) error { if err := r.ParseForm(); err != nil { return err } @@ -286,7 +319,7 @@ func (f *customerForm) Parse(r *http.Request) error { return nil } -func (f *customerForm) Valid(ctx context.Context, conn *database.Conn, l *locale.Locale) (bool, error) { +func (f *ContactForm) Valid(ctx context.Context, conn *database.Conn, l *locale.Locale) (bool, error) { v := form.NewValidator(l) var country string @@ -319,6 +352,36 @@ func (f *customerForm) Valid(ctx context.Context, conn *database.Conn, l *locale return v.AllOK, nil } -func (f *customerForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { - template.MustRenderAdmin(w, r, user, company, "customer/form.gohtml", f) +func (f *ContactForm) UpdateOrCreate(ctx context.Context, company *auth.Company, tx *database.Tx) (int, error) { + var contactID int + row := tx.QueryRow(ctx, ` + select contact_id, slug from contact where id_document_type_id = $1 and id_document_number = $2 and country_code = $3 + `, + f.IDDocumentType.String(), + f.IDDocumentNumber.Val, + f.Country.String(), + ) + if err := row.Scan(&contactID, &f.Slug); err != nil { + if database.ErrorIsNotFound(err) { + f.Slug, err = tx.AddContact(ctx, company.ID, f.FullName.Val, f.IDDocumentType.String(), f.IDDocumentNumber.Val, f.Phone.Val, f.Email.Val, f.Address.Val, f.City.Val, f.Province.Val, f.PostalCode.Val, f.Country.String()) + if err != nil { + return 0, err + } + contactID, err = tx.GetInt(ctx, "select contact_id from contact where slug = $1", f.Slug) + if err != nil { + return 0, err + } + } else { + return 0, err + } + } + _, err := tx.EditContact(ctx, f.Slug, f.FullName.Val, f.IDDocumentType.String(), f.IDDocumentNumber.Val, f.Phone.Val, f.Email.Val, f.Address.Val, f.City.Val, f.Province.Val, f.PostalCode.Val, f.Country.String()) + if err != nil { + return 0, err + } + return contactID, nil +} + +func (f *ContactForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { + template.MustRenderAdminFiles(w, r, user, company, f, "customer/form.gohtml", "customer/contact.gohtml") } diff --git a/pkg/database/funcs.go b/pkg/database/funcs.go index 0eb2f6c..46930f1 100644 --- a/pkg/database/funcs.go +++ b/pkg/database/funcs.go @@ -375,8 +375,8 @@ func (tx *Tx) AddInvoice(ctx context.Context, companyID int, date string, custom return tx.GetText(ctx, "select add_invoice($1, $2, $3, $4, $5, $6)", companyID, date, customerID, notes, paymentMethodID, products) } -func (c *Conn) EditInvoice(ctx context.Context, invoiceSlug string, invoiceStatus string, contactID int, notes string, paymentMethodID int, products EditedInvoiceProductArray) (string, error) { - return c.GetText(ctx, "select edit_invoice($1, $2, $3, $4, $5, $6)", invoiceSlug, invoiceStatus, contactID, notes, paymentMethodID, products) +func (tx *Tx) EditInvoice(ctx context.Context, invoiceSlug string, invoiceStatus string, contactID int, notes string, paymentMethodID int, products EditedInvoiceProductArray) (string, error) { + return tx.GetText(ctx, "select edit_invoice($1, $2, $3, $4, $5, $6)", invoiceSlug, invoiceStatus, contactID, notes, paymentMethodID, products) } func (tx *Tx) AddContact(ctx context.Context, companyID int, name string, idDocumentType string, idDocumentNumber string, phone string, email string, address string, city string, province string, postalCode string, countryCode string) (string, error) { diff --git a/pkg/invoice/admin.go b/pkg/invoice/admin.go index bda8f60..cc5c7c3 100644 --- a/pkg/invoice/admin.go +++ b/pkg/invoice/admin.go @@ -2,7 +2,6 @@ package invoice import ( "context" - "dev.tandem.ws/tandem/camper/pkg/ods" "fmt" "net/http" "sort" @@ -13,10 +12,12 @@ import ( "github.com/jackc/pgtype" "dev.tandem.ws/tandem/camper/pkg/auth" + "dev.tandem.ws/tandem/camper/pkg/customer" "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/ods" "dev.tandem.ws/tandem/camper/pkg/template" "dev.tandem.ws/tandem/camper/pkg/uuid" ) @@ -59,12 +60,17 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat switch r.Method { case http.MethodGet: f := newInvoiceForm(r.Context(), conn, company, user.Locale) - if invoiceToDuplicate := r.URL.Query().Get("duplicate"); uuid.Valid(invoiceToDuplicate) { + query := r.URL.Query() + if invoiceToDuplicate := query.Get("duplicate"); uuid.Valid(invoiceToDuplicate) { f.MustFillFromDatabase(r.Context(), conn, user.Locale, invoiceToDuplicate) f.Slug = "" f.InvoiceStatus.Selected = []string{"created"} - } else if bookingToInvoice, err := strconv.Atoi(r.URL.Query().Get("booking")); err == nil { + } else if bookingToInvoice, err := strconv.Atoi(query.Get("booking")); err == nil { f.MustFillFromBooking(r.Context(), conn, user.Locale, bookingToInvoice) + } else if customerSlug := query.Get("customer"); uuid.Valid(customerSlug) { + if err := f.Customer.FillFromDatabase(r.Context(), conn, customerSlug); err != nil { + panic(err) + } } f.Date.Val = time.Now().Format("2006-01-02") f.MustRender(w, r, user, company, conn) @@ -598,7 +604,9 @@ func addInvoice(w http.ResponseWriter, r *http.Request, user *auth.User, company http.Error(w, err.Error(), http.StatusBadRequest) return } - if !f.Validate(user.Locale) { + if ok, err := f.Validate(r.Context(), conn, user.Locale); err != nil { + panic(err) + } else if !ok { if !httplib.IsHTMxRequest(r) { w.WriteHeader(http.StatusUnprocessableEntity) } @@ -607,7 +615,11 @@ func addInvoice(w http.ResponseWriter, r *http.Request, user *auth.User, company } tx := conn.MustBegin(r.Context()) defer tx.Rollback(r.Context()) - slug, err := tx.AddInvoice(r.Context(), company.ID, f.Date.Val, f.Customer.Int(), f.Notes.Val, defaultPaymentMethod, newInvoiceProducts(f.Products)) + customerID, err := f.Customer.UpdateOrCreate(r.Context(), company, tx) + if err != nil { + panic(err) + } + slug, err := tx.AddInvoice(r.Context(), company.ID, f.Date.Val, customerID, f.Notes.Val, defaultPaymentMethod, newInvoiceProducts(f.Products)) if err != nil { panic(err) } @@ -775,12 +787,12 @@ func mustMakeTaxMap(ctx context.Context, conn *database.Conn, ids *pgtype.Int4Ar } type invoiceForm struct { + company *auth.Company Slug string Number string BookingID *form.Input - company *auth.Company InvoiceStatus *form.Select - Customer *form.Select + Customer *customer.ContactForm Date *form.Input Notes *form.Input Products []*invoiceProductForm @@ -790,7 +802,7 @@ type invoiceForm struct { Total string } -func newInvoiceForm(ctx context.Context, conn *database.Conn, company *auth.Company, locale *locale.Locale) *invoiceForm { +func newInvoiceForm(ctx context.Context, conn *database.Conn, company *auth.Company, l *locale.Locale) *invoiceForm { return &invoiceForm{ company: company, BookingID: &form.Input{ @@ -799,12 +811,9 @@ func newInvoiceForm(ctx context.Context, conn *database.Conn, company *auth.Comp InvoiceStatus: &form.Select{ Name: "invoice_status", Selected: []string{"created"}, - Options: mustGetInvoiceStatusOptions(ctx, conn, locale), - }, - Customer: &form.Select{ - Name: "customer", - Options: mustGetCustomerOptions(ctx, conn, company), + Options: mustGetInvoiceStatusOptions(ctx, conn, l), }, + Customer: customer.NewContactForm(ctx, conn, l), Date: &form.Input{ Name: "date", }, @@ -830,7 +839,6 @@ func (f *invoiceForm) Parse(r *http.Request, conn *database.Conn, l *locale.Loca } f.BookingID.FillValue(r) f.InvoiceStatus.FillValue(r) - f.Customer.FillValue(r) f.Date.FillValue(r) f.Notes.FillValue(r) if _, ok := r.Form["product.id.0"]; ok { @@ -846,14 +854,13 @@ func (f *invoiceForm) Parse(r *http.Request, conn *database.Conn, l *locale.Loca f.Products = append(f.Products, productForm) } } - return nil + return f.Customer.Parse(r) } -func (f *invoiceForm) Validate(l *locale.Locale) bool { +func (f *invoiceForm) Validate(ctx context.Context, conn *database.Conn, l *locale.Locale) (bool, error) { v := form.NewValidator(l) v.CheckSelectedOptions(f.InvoiceStatus, l.GettextNoop("Selected invoice status is not valid.")) - v.CheckSelectedOptions(f.Customer, l.GettextNoop("Selected customer is not valid.")) if v.CheckRequired(f.Date, l.GettextNoop("Invoice date can not be empty.")) { v.CheckValidDate(f.Date, l.GettextNoop("Invoice date must be a valid date.")) } @@ -862,7 +869,14 @@ func (f *invoiceForm) Validate(l *locale.Locale) bool { for _, product := range f.Products { allOK = product.Validate(l) && allOK } - return allOK + + if ok, err := f.Customer.Valid(ctx, conn, l); err != nil { + return false, err + } else if !ok { + allOK = false + } + + return allOK, nil } func (f *invoiceForm) Update(l *locale.Locale) { @@ -907,7 +921,7 @@ func (f *invoiceForm) MustRender(w http.ResponseWriter, r *http.Request, user *a if len(f.Products) == 0 { f.Products = append(f.Products, newInvoiceProductForm(0, company, user.Locale, mustGetTaxOptions(r.Context(), conn, company))) } - template.MustRenderAdminFiles(w, r, user, company, f, "invoice/form.gohtml", "invoice/product-form.gohtml") + template.MustRenderAdminFiles(w, r, user, company, f, "invoice/form.gohtml", "invoice/product-form.gohtml", "customer/contact.gohtml") } const selectProductBySlug = ` @@ -975,18 +989,20 @@ func (f *invoiceForm) InsertProduct(product *invoiceProductForm) { func (f *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *database.Conn, l *locale.Locale, slug string) bool { var invoiceId int + var contactSlug string selectedInvoiceStatus := f.InvoiceStatus.Selected f.InvoiceStatus.Selected = nil err := conn.QueryRow(ctx, ` select invoice_id , array[invoice_status] - , array[contact_id::text] + , contact.slug , invoice_number , invoice_date::text , notes from invoice - where slug = $1 - `, slug).Scan(&invoiceId, &f.InvoiceStatus.Selected, &f.Customer.Selected, &f.Number, &f.Date.Val, &f.Notes.Val) + join contact using (contact_id) + where invoice.slug = $1 + `, slug).Scan(&invoiceId, &f.InvoiceStatus.Selected, &contactSlug, &f.Number, &f.Date.Val, &f.Notes.Val) if err != nil { if database.ErrorIsNotFound(err) { f.InvoiceStatus.Selected = selectedInvoiceStatus @@ -997,6 +1013,9 @@ func (f *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *database.C f.Slug = slug f.Products = []*invoiceProductForm{} f.mustAddProductsFromQuery(ctx, conn, l, "select invoice_product_id::text, coalesce(product_id, 0)::text, name, description, to_price(price, $2), quantity::text, (discount_rate * 100)::integer::text, array_remove(array_agg(tax_id::text), null) from invoice_product left join invoice_product_product using (invoice_product_id) left join invoice_product_tax using (invoice_product_id) where invoice_id = $1 group by invoice_product_id, coalesce(product_id, 0), name, description, discount_rate, price, quantity", invoiceId, f.company.DecimalDigits) + if err := f.Customer.FillFromDatabase(ctx, conn, contactSlug); err != nil { + panic(err) + } return true } @@ -1048,6 +1067,9 @@ func (f *invoiceForm) MustFillFromBooking(ctx context.Context, conn *database.Co l.Pgettext("Dogs", "input"), l.Pgettext("Tourist tax", "cart"), ) + if err := f.Customer.FillFromBooking(ctx, conn, bookingID); err != nil && !database.ErrorIsNotFound(err) { + panic(err) + } return true } @@ -1059,10 +1081,6 @@ func mustGetContactOptions(ctx context.Context, conn *database.Conn, company *au return form.MustGetOptions(ctx, conn, "select contact_id::text, name from contact where company_id = $1 order by name", company.ID) } -func mustGetCustomerOptions(ctx context.Context, conn *database.Conn, company *auth.Company) []*form.Option { - return form.MustGetOptions(ctx, conn, "select contact_id::text, name from contact where company_id = $1 order by name", company.ID) -} - type invoiceProductForm struct { locale *locale.Locale company *auth.Company @@ -1253,18 +1271,26 @@ func handleUpdateInvoice(w http.ResponseWriter, r *http.Request, user *auth.User } httplib.Relocate(w, r, "/admin/invoices", http.StatusSeeOther) } else { - if !f.Validate(user.Locale) { + if ok, err := f.Validate(r.Context(), conn, user.Locale); err != nil { + panic(err) + } else if !ok { if !httplib.IsHTMxRequest(r) { w.WriteHeader(http.StatusUnprocessableEntity) } f.MustRender(w, r, user, company, conn) return } - var err error - slug, err = conn.EditInvoice(r.Context(), slug, f.InvoiceStatus.String(), f.Customer.Int(), f.Notes.Val, defaultPaymentMethod, editedInvoiceProducts(f.Products)) + tx := conn.MustBegin(r.Context()) + defer tx.Rollback(r.Context()) + customerID, err := f.Customer.UpdateOrCreate(r.Context(), company, tx) if err != nil { panic(err) } + slug, err = tx.EditInvoice(r.Context(), slug, f.InvoiceStatus.String(), customerID, f.Notes.Val, defaultPaymentMethod, editedInvoiceProducts(f.Products)) + if err != nil { + panic(err) + } + tx.MustCommit(r.Context()) if slug == "" { http.NotFound(w, r) return diff --git a/po/ca.po b/po/ca.po index efb76bb..d3aca19 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-04-28 20:05+0200\n" +"POT-Creation-Date: 2024-04-28 22:32+0200\n" "PO-Revision-Date: 2024-02-06 10:04+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -178,7 +178,7 @@ msgstr "Nits" #: web/templates/mail/payment/details.gotxt:22 #: web/templates/public/booking/fields.gohtml:60 #: web/templates/admin/payment/details.gohtml:98 -#: web/templates/admin/booking/fields.gohtml:93 +#: web/templates/admin/booking/fields.gohtml:93 pkg/invoice/admin.go:1064 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adults de 17 anys o més" @@ -186,7 +186,7 @@ msgstr "Adults de 17 anys o més" #: web/templates/mail/payment/details.gotxt:23 #: web/templates/public/booking/fields.gohtml:71 #: web/templates/admin/payment/details.gohtml:102 -#: web/templates/admin/booking/fields.gohtml:109 +#: web/templates/admin/booking/fields.gohtml:109 pkg/invoice/admin.go:1065 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescents d’entre 11 i 16 anys" @@ -194,7 +194,7 @@ msgstr "Adolescents d’entre 11 i 16 anys" #: web/templates/mail/payment/details.gotxt:24 #: web/templates/public/booking/fields.gohtml:82 #: web/templates/admin/payment/details.gohtml:106 -#: web/templates/admin/booking/fields.gohtml:125 +#: web/templates/admin/booking/fields.gohtml:125 pkg/invoice/admin.go:1066 msgctxt "input" msgid "Children from 2 to 10 years old" msgstr "Nens d’entre 2 i 10 anys" @@ -202,14 +202,15 @@ msgstr "Nens d’entre 2 i 10 anys" #: web/templates/mail/payment/details.gotxt:25 #: web/templates/public/booking/fields.gohtml:100 #: web/templates/admin/payment/details.gohtml:110 -#: web/templates/admin/booking/fields.gohtml:140 +#: web/templates/admin/booking/fields.gohtml:140 pkg/invoice/admin.go:1067 msgctxt "input" msgid "Dogs" msgstr "Gossos" #: web/templates/mail/payment/details.gotxt:26 #: web/templates/admin/payment/details.gohtml:114 -#: web/templates/admin/booking/fields.gohtml:167 pkg/booking/cart.go:242 +#: web/templates/admin/booking/fields.gohtml:167 pkg/invoice/admin.go:1068 +#: pkg/booking/cart.go:242 msgctxt "cart" msgid "Tourist tax" msgstr "Impost turístic" @@ -239,7 +240,7 @@ msgstr "Opcions del tipus d’allotjament" #: web/templates/mail/payment/details.gotxt:39 #: web/templates/public/booking/fields.gohtml:146 #: web/templates/admin/payment/details.gohtml:140 -#: web/templates/admin/customer/form.gohtml:28 +#: web/templates/admin/customer/contact.gohtml:3 #: web/templates/admin/booking/fields.gohtml:188 msgctxt "title" msgid "Customer Details" @@ -248,7 +249,7 @@ msgstr "Detalls del client" #: web/templates/mail/payment/details.gotxt:41 #: web/templates/public/booking/fields.gohtml:149 #: web/templates/admin/payment/details.gohtml:143 -#: web/templates/admin/customer/form.gohtml:31 +#: web/templates/admin/customer/contact.gohtml:6 #: web/templates/admin/booking/fields.gohtml:191 msgctxt "input" msgid "Full name" @@ -257,7 +258,7 @@ msgstr "Nom i cognoms" #: web/templates/mail/payment/details.gotxt:42 #: web/templates/public/booking/fields.gohtml:158 #: web/templates/admin/payment/details.gohtml:147 -#: web/templates/admin/customer/form.gohtml:69 +#: web/templates/admin/customer/contact.gohtml:44 #: web/templates/admin/taxDetails.gohtml:69 msgctxt "input" msgid "Address" @@ -266,7 +267,7 @@ msgstr "Adreça" #: web/templates/mail/payment/details.gotxt:43 #: web/templates/public/booking/fields.gohtml:167 #: web/templates/admin/payment/details.gohtml:151 -#: web/templates/admin/customer/form.gohtml:105 +#: web/templates/admin/customer/contact.gohtml:80 #: web/templates/admin/taxDetails.gohtml:93 msgctxt "input" msgid "Postcode" @@ -282,7 +283,7 @@ msgstr "Població" #: web/templates/mail/payment/details.gotxt:45 #: web/templates/public/booking/fields.gohtml:187 #: web/templates/admin/payment/details.gohtml:159 -#: web/templates/admin/customer/form.gohtml:117 +#: web/templates/admin/customer/contact.gohtml:92 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -423,7 +424,7 @@ msgid "Date" msgstr "Data" #: web/templates/public/payment/details.gohtml:12 -#: web/templates/admin/invoice/form.gohtml:119 +#: web/templates/admin/invoice/form.gohtml:111 #: web/templates/admin/invoice/view.gohtml:63 #: web/templates/admin/invoice/view.gohtml:103 msgctxt "title" @@ -1019,13 +1020,13 @@ msgid "Campground map" msgstr "Mapa del càmping" #: web/templates/public/booking/fields.gohtml:176 -#: web/templates/admin/customer/form.gohtml:81 +#: web/templates/admin/customer/contact.gohtml:56 msgctxt "input" msgid "Town or village" msgstr "Població" #: web/templates/public/booking/fields.gohtml:193 -#: web/templates/admin/customer/form.gohtml:121 +#: web/templates/admin/customer/contact.gohtml:96 #: web/templates/admin/booking/fields.gohtml:204 #: web/templates/admin/booking/guest.gohtml:111 msgid "Choose a country" @@ -1206,8 +1207,8 @@ msgstr "Contingut" #: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/season/form.gohtml:73 -#: web/templates/admin/customer/form.gohtml:153 -#: web/templates/admin/invoice/form.gohtml:137 +#: web/templates/admin/customer/form.gohtml:34 +#: web/templates/admin/invoice/form.gohtml:129 #: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/index.gohtml:58 @@ -1216,7 +1217,7 @@ msgstr "Contingut" #: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/media/form.gohtml:39 -#: web/templates/admin/booking/form.gohtml:45 +#: web/templates/admin/booking/form.gohtml:48 msgctxt "action" msgid "Update" msgstr "Actualitza" @@ -1231,13 +1232,13 @@ msgstr "Actualitza" #: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/season/form.gohtml:75 -#: web/templates/admin/customer/form.gohtml:155 +#: web/templates/admin/customer/form.gohtml:36 #: web/templates/admin/services/form.gohtml:83 #: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/form.gohtml:93 -#: web/templates/admin/booking/form.gohtml:47 +#: web/templates/admin/booking/form.gohtml:50 msgctxt "action" msgid "Add" msgstr "Afegeix" @@ -1863,36 +1864,41 @@ msgctxt "title" msgid "Customer" msgstr "Client" -#: web/templates/admin/customer/form.gohtml:44 +#: web/templates/admin/customer/form.gohtml:21 +msgctxt "action" +msgid "Invoice Customer" +msgstr "Factura al client" + +#: web/templates/admin/customer/contact.gohtml:19 #: web/templates/admin/booking/guest.gohtml:8 msgctxt "input" msgid "ID document number" msgstr "Número de document d’identitat" -#: web/templates/admin/customer/form.gohtml:56 +#: web/templates/admin/customer/contact.gohtml:31 #: web/templates/admin/booking/guest.gohtml:20 msgctxt "input" msgid "ID document type" msgstr "Tipus de document" -#: web/templates/admin/customer/form.gohtml:61 +#: web/templates/admin/customer/contact.gohtml:36 #: web/templates/admin/booking/guest.gohtml:25 msgid "Choose an ID document type" msgstr "Esculli un tipus de document" -#: web/templates/admin/customer/form.gohtml:93 +#: web/templates/admin/customer/contact.gohtml:68 #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Província" -#: web/templates/admin/customer/form.gohtml:129 +#: web/templates/admin/customer/contact.gohtml:104 #: web/templates/admin/booking/fields.gohtml:239 msgctxt "input" msgid "Email (optional)" msgstr "Correu-e (opcional)" -#: web/templates/admin/customer/form.gohtml:140 +#: web/templates/admin/customer/contact.gohtml:115 #: web/templates/admin/booking/fields.gohtml:248 #: web/templates/admin/booking/guest.gohtml:119 msgctxt "input" @@ -1975,53 +1981,48 @@ msgctxt "title" msgid "Invoices" msgstr "Factures" -#: web/templates/admin/invoice/form.gohtml:32 +#: web/templates/admin/invoice/form.gohtml:34 msgid "Product “%s” removed" msgstr "S’ha esborrat el producte «%s»" -#: web/templates/admin/invoice/form.gohtml:36 +#: web/templates/admin/invoice/form.gohtml:38 msgctxt "action" msgid "Undo" msgstr "Desfes" -#: web/templates/admin/invoice/form.gohtml:51 -#: web/templates/admin/invoice/index.gohtml:39 -msgctxt "input" -msgid "Customer" -msgstr "Client" - -#: web/templates/admin/invoice/form.gohtml:56 -msgid "Select a customer" -msgstr "Esculliu un client" - -#: web/templates/admin/invoice/form.gohtml:64 +#: web/templates/admin/invoice/form.gohtml:53 msgctxt "input" msgid "Invoice date" msgstr "Data de la factura" -#: web/templates/admin/invoice/form.gohtml:77 +#: web/templates/admin/invoice/form.gohtml:66 #: web/templates/admin/invoice/index.gohtml:51 msgctxt "input" msgid "Invoice status" msgstr "Estat de la factura" -#: web/templates/admin/invoice/form.gohtml:92 +#: web/templates/admin/invoice/form.gohtml:81 msgctxt "input" msgid "Notes (optional)" msgstr "Notes (opcional)" -#: web/templates/admin/invoice/form.gohtml:109 +#: web/templates/admin/invoice/form.gohtml:93 +msgctxt "title" +msgid "Products" +msgstr "Productes" + +#: web/templates/admin/invoice/form.gohtml:101 #: web/templates/admin/invoice/view.gohtml:59 msgctxt "title" msgid "Subtotal" msgstr "Subtotal" -#: web/templates/admin/invoice/form.gohtml:133 +#: web/templates/admin/invoice/form.gohtml:125 msgctxt "action" msgid "Add products" msgstr "Afegeix productes" -#: web/templates/admin/invoice/form.gohtml:140 +#: web/templates/admin/invoice/form.gohtml:132 msgctxt "action" msgid "Save" msgstr "Desa" @@ -2036,6 +2037,11 @@ msgctxt "action" msgid "Export list" msgstr "Exporta llista" +#: web/templates/admin/invoice/index.gohtml:39 +msgctxt "input" +msgid "Customer" +msgstr "Client" + #: web/templates/admin/invoice/index.gohtml:43 msgid "All customers" msgstr "Tots els clients" @@ -2645,7 +2651,8 @@ msgctxt "header" msgid "Decription" msgstr "Descripció" -#: web/templates/admin/booking/fields.gohtml:81 pkg/booking/cart.go:232 +#: web/templates/admin/booking/fields.gohtml:81 pkg/invoice/admin.go:1063 +#: pkg/booking/cart.go:232 msgctxt "cart" msgid "Night" msgstr "Nit" @@ -2686,6 +2693,11 @@ msgctxt "action" msgid "Check-in Booking" msgstr "Registra la reserva" +#: web/templates/admin/booking/form.gohtml:28 +msgctxt "action" +msgid "Invoice Booking" +msgstr "Factura la reserva" + #: web/templates/admin/booking/checkin.gohtml:6 msgctxt "title" msgid "Check-in Booking" @@ -2839,7 +2851,7 @@ msgstr "Rebut amb èxit el pagament de la reserva" #: pkg/legal/admin.go:258 pkg/app/user.go:249 pkg/campsite/types/option.go:365 #: pkg/campsite/types/feature.go:272 pkg/campsite/types/admin.go:577 #: pkg/campsite/feature.go:269 pkg/season/admin.go:411 -#: pkg/invoice/admin.go:1092 pkg/services/admin.go:316 +#: pkg/invoice/admin.go:1160 pkg/services/admin.go:316 #: pkg/surroundings/admin.go:340 pkg/amenity/feature.go:269 #: pkg/amenity/admin.go:283 msgid "Name can not be empty." @@ -2880,8 +2892,8 @@ msgstr "La imatge de la diapositiva ha de ser un mèdia de tipus imatge." msgid "Email can not be empty." msgstr "No podeu deixar el correu-e en blanc." -#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:312 -#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 +#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345 +#: pkg/company/admin.go:225 pkg/booking/admin.go:441 pkg/booking/public.go:593 msgid "This email is not valid. It should be like name@domain.com." msgstr "Aquest correu-e no és vàlid. Hauria de ser similar a nom@domini.com." @@ -2938,15 +2950,15 @@ msgstr "El valor del màxim ha de ser un número enter." msgid "Maximum must be equal or greater than minimum." msgstr "El valor del màxim ha de ser igual o superir al del mínim." -#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1093 +#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1161 msgid "Price can not be empty." msgstr "No podeu deixar el preu en blanc." -#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1094 +#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1162 msgid "Price must be a decimal number." msgstr "El preu ha de ser un número decimal." -#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1095 +#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1163 msgid "Price must be zero or greater." msgstr "El preu ha de ser com a mínim zero." @@ -3092,7 +3104,7 @@ msgctxt "header" msgid "Children (aged 2 to 10)" msgstr "Mainada (entre 2 i 10 anys)" -#: pkg/campsite/admin.go:280 pkg/booking/admin.go:414 pkg/booking/public.go:177 +#: pkg/campsite/admin.go:280 pkg/booking/admin.go:417 pkg/booking/public.go:177 #: pkg/booking/public.go:232 msgid "Selected campsite type is not valid." msgstr "El tipus d’allotjament escollit no és vàlid." @@ -3130,133 +3142,129 @@ msgstr "No podeu deixar la data de fi en blanc." msgid "End date must be a valid date." msgstr "La data de fi ha de ser una data vàlida." -#: pkg/customer/admin.go:293 pkg/company/admin.go:207 +#: pkg/customer/admin.go:326 pkg/company/admin.go:207 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577 msgid "Selected country is not valid." msgstr "El país escollit no és vàlid." -#: pkg/customer/admin.go:297 pkg/booking/checkin.go:281 +#: pkg/customer/admin.go:330 pkg/booking/checkin.go:281 msgid "Selected ID document type is not valid." msgstr "El tipus de document d’identitat escollit no és vàlid." -#: pkg/customer/admin.go:298 pkg/booking/checkin.go:282 +#: pkg/customer/admin.go:331 pkg/booking/checkin.go:282 msgid "ID document number can not be empty." msgstr "No podeu deixar el número document d’identitat en blanc." -#: pkg/customer/admin.go:300 pkg/booking/checkin.go:288 -#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 +#: pkg/customer/admin.go:333 pkg/booking/checkin.go:288 +#: pkg/booking/checkin.go:289 pkg/booking/admin.go:429 #: pkg/booking/public.go:581 msgid "Full name can not be empty." msgstr "No podeu deixar el nom i els cognoms en blanc." -#: pkg/customer/admin.go:301 pkg/booking/admin.go:427 pkg/booking/public.go:582 +#: pkg/customer/admin.go:334 pkg/booking/admin.go:430 pkg/booking/public.go:582 msgid "Full name must have at least one letter." msgstr "El nom i els cognoms han de tenir com a mínim una lletra." -#: pkg/customer/admin.go:304 pkg/company/admin.go:230 pkg/booking/public.go:585 +#: pkg/customer/admin.go:337 pkg/company/admin.go:230 pkg/booking/public.go:585 msgid "Address can not be empty." msgstr "No podeu deixar l’adreça en blanc." -#: pkg/customer/admin.go:305 pkg/booking/public.go:586 +#: pkg/customer/admin.go:338 pkg/booking/public.go:586 msgid "Town or village can not be empty." msgstr "No podeu deixar la població en blanc." -#: pkg/customer/admin.go:306 pkg/company/admin.go:233 pkg/booking/public.go:587 +#: pkg/customer/admin.go:339 pkg/company/admin.go:233 pkg/booking/public.go:587 msgid "Postcode can not be empty." msgstr "No podeu deixar el codi postal en blanc." -#: pkg/customer/admin.go:307 pkg/company/admin.go:234 pkg/booking/admin.go:433 +#: pkg/customer/admin.go:340 pkg/company/admin.go:234 pkg/booking/admin.go:436 #: pkg/booking/public.go:588 msgid "This postcode is not valid." msgstr "Aquest codi postal no és vàlid." -#: pkg/customer/admin.go:315 pkg/company/admin.go:220 -#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 +#: pkg/customer/admin.go:348 pkg/company/admin.go:220 +#: pkg/booking/checkin.go:301 pkg/booking/admin.go:446 #: pkg/booking/public.go:596 msgid "This phone number is not valid." msgstr "Aquest número de telèfon no és vàlid." -#: pkg/invoice/admin.go:649 +#: pkg/invoice/admin.go:681 msgctxt "filename" msgid "invoices.zip" msgstr "factures.zip" -#: pkg/invoice/admin.go:664 +#: pkg/invoice/admin.go:696 msgctxt "filename" msgid "invoices.ods" msgstr "factures.ods" -#: pkg/invoice/admin.go:666 pkg/invoice/admin.go:1285 pkg/invoice/admin.go:1292 +#: pkg/invoice/admin.go:698 pkg/invoice/admin.go:1360 pkg/invoice/admin.go:1367 msgid "Invalid action" msgstr "Acció invàlida" -#: pkg/invoice/admin.go:830 +#: pkg/invoice/admin.go:863 msgid "Selected invoice status is not valid." msgstr "L’estat de factura escollit no és vàlid." -#: pkg/invoice/admin.go:831 -msgid "Selected customer is not valid." -msgstr "El client escollit no és vàlid." - -#: pkg/invoice/admin.go:832 +#: pkg/invoice/admin.go:864 msgid "Invoice date can not be empty." msgstr "No podeu deixar la data de factura en blanc." -#: pkg/invoice/admin.go:833 +#: pkg/invoice/admin.go:865 msgid "Invoice date must be a valid date." msgstr "La data de factura ha de ser una data vàlida." -#: pkg/invoice/admin.go:980 +#: pkg/invoice/admin.go:1023 #, c-format -msgid "Re: quotation #%s of %s" -msgstr "" +msgid "Re: booking #%s of %s–%s" +msgstr "Ref: reserva núm. %s del %s-%s" -#: pkg/invoice/admin.go:981 +#: pkg/invoice/admin.go:1024 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoice/admin.go:1083 +#: pkg/invoice/admin.go:1151 msgid "Invoice product ID must be an integer." msgstr "L’ID de producte de factura ha de ser enter." -#: pkg/invoice/admin.go:1084 +#: pkg/invoice/admin.go:1152 msgid "Invoice product ID one or greater." msgstr "L’ID de producte de factura ha de ser com a mínim u." -#: pkg/invoice/admin.go:1088 +#: pkg/invoice/admin.go:1156 msgid "Product ID must be an integer." msgstr "L’ID de producte ha de ser un número enter." -#: pkg/invoice/admin.go:1089 +#: pkg/invoice/admin.go:1157 msgid "Product ID must zero or greater." msgstr "L’ID de producte ha de ser com a mínim zero." -#: pkg/invoice/admin.go:1098 +#: pkg/invoice/admin.go:1166 msgid "Quantity can not be empty." msgstr "No podeu deixar la quantitat en blanc." -#: pkg/invoice/admin.go:1099 +#: pkg/invoice/admin.go:1167 msgid "Quantity must be an integer." msgstr "La quantitat ha de ser un número enter." -#: pkg/invoice/admin.go:1100 +#: pkg/invoice/admin.go:1168 msgid "Quantity must one or greater." msgstr "La quantitat ha de ser com a mínim u." -#: pkg/invoice/admin.go:1103 +#: pkg/invoice/admin.go:1171 msgid "Discount can not be empty." msgstr "No podeu deixar el descompte en blanc." -#: pkg/invoice/admin.go:1104 +#: pkg/invoice/admin.go:1172 msgid "Discount must be an integer." msgstr "El descompte ha de ser un número enter." -#: pkg/invoice/admin.go:1105 pkg/invoice/admin.go:1106 +#: pkg/invoice/admin.go:1173 pkg/invoice/admin.go:1174 msgid "Discount must be a percentage between 0 and 100." msgstr "El descompte ha de ser un percentatge entre 0 i 100" -#: pkg/invoice/admin.go:1110 +#: pkg/invoice/admin.go:1178 msgid "Selected tax is not valid." msgstr "L’impost escollit no és vàlid." @@ -3444,19 +3452,19 @@ msgctxt "filename" msgid "bookings.ods" msgstr "reserves.ods" -#: pkg/booking/admin.go:432 +#: pkg/booking/admin.go:435 msgid "Country can not be empty to validate the postcode." msgstr "No podeu deixar el país en blanc per validar el codi postal." -#: pkg/booking/admin.go:442 +#: pkg/booking/admin.go:445 msgid "Country can not be empty to validate the phone." msgstr "No podeu deixar el país en blanc per validar el telèfon." -#: pkg/booking/admin.go:449 +#: pkg/booking/admin.go:452 msgid "You must select at least one accommodation." msgstr "Heu d’escollir com a mínim un allotjament." -#: pkg/booking/admin.go:455 +#: pkg/booking/admin.go:458 msgid "The selected accommodations have no available openings in the requested dates." msgstr "Els allotjaments escollits no estan disponibles a les dates demanades." @@ -3573,6 +3581,12 @@ msgstr "El valor de %s ha de ser com a màxim %d." msgid "It is mandatory to agree to the reservation conditions." msgstr "És obligatori acceptar les condicions de reserves." +#~ msgid "Select a customer" +#~ msgstr "Esculliu un client" + +#~ msgid "Selected customer is not valid." +#~ msgstr "El client escollit no és vàlid." + #~ msgctxt "title" #~ msgid "Accomodations" #~ msgstr "Allotjaments" diff --git a/po/es.po b/po/es.po index 949db21..9a5c174 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-04-28 20:05+0200\n" +"POT-Creation-Date: 2024-04-28 22:32+0200\n" "PO-Revision-Date: 2024-02-06 10:04+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -178,7 +178,7 @@ msgstr "Noches" #: web/templates/mail/payment/details.gotxt:22 #: web/templates/public/booking/fields.gohtml:60 #: web/templates/admin/payment/details.gohtml:98 -#: web/templates/admin/booking/fields.gohtml:93 +#: web/templates/admin/booking/fields.gohtml:93 pkg/invoice/admin.go:1064 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adultos de 17 años o más" @@ -186,7 +186,7 @@ msgstr "Adultos de 17 años o más" #: web/templates/mail/payment/details.gotxt:23 #: web/templates/public/booking/fields.gohtml:71 #: web/templates/admin/payment/details.gohtml:102 -#: web/templates/admin/booking/fields.gohtml:109 +#: web/templates/admin/booking/fields.gohtml:109 pkg/invoice/admin.go:1065 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescentes de 11 a 16 años" @@ -194,7 +194,7 @@ msgstr "Adolescentes de 11 a 16 años" #: web/templates/mail/payment/details.gotxt:24 #: web/templates/public/booking/fields.gohtml:82 #: web/templates/admin/payment/details.gohtml:106 -#: web/templates/admin/booking/fields.gohtml:125 +#: web/templates/admin/booking/fields.gohtml:125 pkg/invoice/admin.go:1066 msgctxt "input" msgid "Children from 2 to 10 years old" msgstr "Niños de 2 a 10 años" @@ -202,14 +202,15 @@ msgstr "Niños de 2 a 10 años" #: web/templates/mail/payment/details.gotxt:25 #: web/templates/public/booking/fields.gohtml:100 #: web/templates/admin/payment/details.gohtml:110 -#: web/templates/admin/booking/fields.gohtml:140 +#: web/templates/admin/booking/fields.gohtml:140 pkg/invoice/admin.go:1067 msgctxt "input" msgid "Dogs" msgstr "Perros" #: web/templates/mail/payment/details.gotxt:26 #: web/templates/admin/payment/details.gohtml:114 -#: web/templates/admin/booking/fields.gohtml:167 pkg/booking/cart.go:242 +#: web/templates/admin/booking/fields.gohtml:167 pkg/invoice/admin.go:1068 +#: pkg/booking/cart.go:242 msgctxt "cart" msgid "Tourist tax" msgstr "Impuesto turístico" @@ -239,7 +240,7 @@ msgstr "Opciones del tipo de alojamiento" #: web/templates/mail/payment/details.gotxt:39 #: web/templates/public/booking/fields.gohtml:146 #: web/templates/admin/payment/details.gohtml:140 -#: web/templates/admin/customer/form.gohtml:28 +#: web/templates/admin/customer/contact.gohtml:3 #: web/templates/admin/booking/fields.gohtml:188 msgctxt "title" msgid "Customer Details" @@ -248,7 +249,7 @@ msgstr "Detalles del cliente" #: web/templates/mail/payment/details.gotxt:41 #: web/templates/public/booking/fields.gohtml:149 #: web/templates/admin/payment/details.gohtml:143 -#: web/templates/admin/customer/form.gohtml:31 +#: web/templates/admin/customer/contact.gohtml:6 #: web/templates/admin/booking/fields.gohtml:191 msgctxt "input" msgid "Full name" @@ -257,7 +258,7 @@ msgstr "Nombre y apellidos" #: web/templates/mail/payment/details.gotxt:42 #: web/templates/public/booking/fields.gohtml:158 #: web/templates/admin/payment/details.gohtml:147 -#: web/templates/admin/customer/form.gohtml:69 +#: web/templates/admin/customer/contact.gohtml:44 #: web/templates/admin/taxDetails.gohtml:69 msgctxt "input" msgid "Address" @@ -266,7 +267,7 @@ msgstr "Dirección" #: web/templates/mail/payment/details.gotxt:43 #: web/templates/public/booking/fields.gohtml:167 #: web/templates/admin/payment/details.gohtml:151 -#: web/templates/admin/customer/form.gohtml:105 +#: web/templates/admin/customer/contact.gohtml:80 #: web/templates/admin/taxDetails.gohtml:93 msgctxt "input" msgid "Postcode" @@ -282,7 +283,7 @@ msgstr "Población" #: web/templates/mail/payment/details.gotxt:45 #: web/templates/public/booking/fields.gohtml:187 #: web/templates/admin/payment/details.gohtml:159 -#: web/templates/admin/customer/form.gohtml:117 +#: web/templates/admin/customer/contact.gohtml:92 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -423,7 +424,7 @@ msgid "Date" msgstr "Fecha" #: web/templates/public/payment/details.gohtml:12 -#: web/templates/admin/invoice/form.gohtml:119 +#: web/templates/admin/invoice/form.gohtml:111 #: web/templates/admin/invoice/view.gohtml:63 #: web/templates/admin/invoice/view.gohtml:103 msgctxt "title" @@ -1019,13 +1020,13 @@ msgid "Campground map" msgstr "Mapa del camping" #: web/templates/public/booking/fields.gohtml:176 -#: web/templates/admin/customer/form.gohtml:81 +#: web/templates/admin/customer/contact.gohtml:56 msgctxt "input" msgid "Town or village" msgstr "Población" #: web/templates/public/booking/fields.gohtml:193 -#: web/templates/admin/customer/form.gohtml:121 +#: web/templates/admin/customer/contact.gohtml:96 #: web/templates/admin/booking/fields.gohtml:204 #: web/templates/admin/booking/guest.gohtml:111 msgid "Choose a country" @@ -1206,8 +1207,8 @@ msgstr "Contenido" #: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/season/form.gohtml:73 -#: web/templates/admin/customer/form.gohtml:153 -#: web/templates/admin/invoice/form.gohtml:137 +#: web/templates/admin/customer/form.gohtml:34 +#: web/templates/admin/invoice/form.gohtml:129 #: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/index.gohtml:58 @@ -1216,7 +1217,7 @@ msgstr "Contenido" #: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/media/form.gohtml:39 -#: web/templates/admin/booking/form.gohtml:45 +#: web/templates/admin/booking/form.gohtml:48 msgctxt "action" msgid "Update" msgstr "Actualizar" @@ -1231,13 +1232,13 @@ msgstr "Actualizar" #: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/season/form.gohtml:75 -#: web/templates/admin/customer/form.gohtml:155 +#: web/templates/admin/customer/form.gohtml:36 #: web/templates/admin/services/form.gohtml:83 #: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/form.gohtml:93 -#: web/templates/admin/booking/form.gohtml:47 +#: web/templates/admin/booking/form.gohtml:50 msgctxt "action" msgid "Add" msgstr "Añadir" @@ -1863,36 +1864,41 @@ msgctxt "title" msgid "Customer" msgstr "Cliente" -#: web/templates/admin/customer/form.gohtml:44 +#: web/templates/admin/customer/form.gohtml:21 +msgctxt "action" +msgid "Invoice Customer" +msgstr "Facturar al cliente" + +#: web/templates/admin/customer/contact.gohtml:19 #: web/templates/admin/booking/guest.gohtml:8 msgctxt "input" msgid "ID document number" msgstr "Número de documento de identidad" -#: web/templates/admin/customer/form.gohtml:56 +#: web/templates/admin/customer/contact.gohtml:31 #: web/templates/admin/booking/guest.gohtml:20 msgctxt "input" msgid "ID document type" msgstr "Tipo de documento" -#: web/templates/admin/customer/form.gohtml:61 +#: web/templates/admin/customer/contact.gohtml:36 #: web/templates/admin/booking/guest.gohtml:25 msgid "Choose an ID document type" msgstr "Escoja un tipo de documento" -#: web/templates/admin/customer/form.gohtml:93 +#: web/templates/admin/customer/contact.gohtml:68 #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Provincia" -#: web/templates/admin/customer/form.gohtml:129 +#: web/templates/admin/customer/contact.gohtml:104 #: web/templates/admin/booking/fields.gohtml:239 msgctxt "input" msgid "Email (optional)" msgstr "Correo-e (opcional)" -#: web/templates/admin/customer/form.gohtml:140 +#: web/templates/admin/customer/contact.gohtml:115 #: web/templates/admin/booking/fields.gohtml:248 #: web/templates/admin/booking/guest.gohtml:119 msgctxt "input" @@ -1975,53 +1981,48 @@ msgctxt "title" msgid "Invoices" msgstr "Facturas" -#: web/templates/admin/invoice/form.gohtml:32 +#: web/templates/admin/invoice/form.gohtml:34 msgid "Product “%s” removed" msgstr "Se ha borrado el producto «%s»" -#: web/templates/admin/invoice/form.gohtml:36 +#: web/templates/admin/invoice/form.gohtml:38 msgctxt "action" msgid "Undo" msgstr "Deshacer" -#: web/templates/admin/invoice/form.gohtml:51 -#: web/templates/admin/invoice/index.gohtml:39 -msgctxt "input" -msgid "Customer" -msgstr "Cliente" - -#: web/templates/admin/invoice/form.gohtml:56 -msgid "Select a customer" -msgstr "Escoja un cliente" - -#: web/templates/admin/invoice/form.gohtml:64 +#: web/templates/admin/invoice/form.gohtml:53 msgctxt "input" msgid "Invoice date" msgstr "Fecha de la factura" -#: web/templates/admin/invoice/form.gohtml:77 +#: web/templates/admin/invoice/form.gohtml:66 #: web/templates/admin/invoice/index.gohtml:51 msgctxt "input" msgid "Invoice status" msgstr "Estado de factura" -#: web/templates/admin/invoice/form.gohtml:92 +#: web/templates/admin/invoice/form.gohtml:81 msgctxt "input" msgid "Notes (optional)" msgstr "Notas (opcional)" -#: web/templates/admin/invoice/form.gohtml:109 +#: web/templates/admin/invoice/form.gohtml:93 +msgctxt "title" +msgid "Products" +msgstr "Productos" + +#: web/templates/admin/invoice/form.gohtml:101 #: web/templates/admin/invoice/view.gohtml:59 msgctxt "title" msgid "Subtotal" msgstr "Subtotal" -#: web/templates/admin/invoice/form.gohtml:133 +#: web/templates/admin/invoice/form.gohtml:125 msgctxt "action" msgid "Add products" msgstr "Añadir productos" -#: web/templates/admin/invoice/form.gohtml:140 +#: web/templates/admin/invoice/form.gohtml:132 msgctxt "action" msgid "Save" msgstr "Guardar" @@ -2036,6 +2037,11 @@ msgctxt "action" msgid "Export list" msgstr "Exportar lista" +#: web/templates/admin/invoice/index.gohtml:39 +msgctxt "input" +msgid "Customer" +msgstr "Cliente" + #: web/templates/admin/invoice/index.gohtml:43 msgid "All customers" msgstr "Todos los clientes" @@ -2645,7 +2651,8 @@ msgctxt "header" msgid "Decription" msgstr "Descripción" -#: web/templates/admin/booking/fields.gohtml:81 pkg/booking/cart.go:232 +#: web/templates/admin/booking/fields.gohtml:81 pkg/invoice/admin.go:1063 +#: pkg/booking/cart.go:232 msgctxt "cart" msgid "Night" msgstr "Noche" @@ -2686,6 +2693,11 @@ msgctxt "action" msgid "Check-in Booking" msgstr "Registrar reserva" +#: web/templates/admin/booking/form.gohtml:28 +msgctxt "action" +msgid "Invoice Booking" +msgstr "Facturar la reserva" + #: web/templates/admin/booking/checkin.gohtml:6 msgctxt "title" msgid "Check-in Booking" @@ -2839,7 +2851,7 @@ msgstr "Se ha recibido correctamente el pago de la reserva" #: pkg/legal/admin.go:258 pkg/app/user.go:249 pkg/campsite/types/option.go:365 #: pkg/campsite/types/feature.go:272 pkg/campsite/types/admin.go:577 #: pkg/campsite/feature.go:269 pkg/season/admin.go:411 -#: pkg/invoice/admin.go:1092 pkg/services/admin.go:316 +#: pkg/invoice/admin.go:1160 pkg/services/admin.go:316 #: pkg/surroundings/admin.go:340 pkg/amenity/feature.go:269 #: pkg/amenity/admin.go:283 msgid "Name can not be empty." @@ -2880,8 +2892,8 @@ msgstr "La imagen de la diapositiva tiene que ser un medio de tipo imagen." msgid "Email can not be empty." msgstr "No podéis dejar el correo-e en blanco." -#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:312 -#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 +#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345 +#: pkg/company/admin.go:225 pkg/booking/admin.go:441 pkg/booking/public.go:593 msgid "This email is not valid. It should be like name@domain.com." msgstr "Este correo-e no es válido. Tiene que ser parecido a nombre@dominio.com." @@ -2938,15 +2950,15 @@ msgstr "El valor del máximo tiene que ser un número entero." msgid "Maximum must be equal or greater than minimum." msgstr "El valor del máximo tiene que ser igual o mayor al del mínimo." -#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1093 +#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1161 msgid "Price can not be empty." msgstr "No podéis dejar el precio en blanco." -#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1094 +#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1162 msgid "Price must be a decimal number." msgstr "El precio tiene que ser un número decimal." -#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1095 +#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1163 msgid "Price must be zero or greater." msgstr "El precio tiene que ser como mínimo cero." @@ -3092,7 +3104,7 @@ msgctxt "header" msgid "Children (aged 2 to 10)" msgstr "Niños (de 2 a 10 años)" -#: pkg/campsite/admin.go:280 pkg/booking/admin.go:414 pkg/booking/public.go:177 +#: pkg/campsite/admin.go:280 pkg/booking/admin.go:417 pkg/booking/public.go:177 #: pkg/booking/public.go:232 msgid "Selected campsite type is not valid." msgstr "El tipo de alojamiento escogido no es válido." @@ -3130,133 +3142,129 @@ msgstr "No podéis dejar la fecha final en blanco." msgid "End date must be a valid date." msgstr "La fecha final tiene que ser una fecha válida." -#: pkg/customer/admin.go:293 pkg/company/admin.go:207 +#: pkg/customer/admin.go:326 pkg/company/admin.go:207 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577 msgid "Selected country is not valid." msgstr "El país escogido no es válido." -#: pkg/customer/admin.go:297 pkg/booking/checkin.go:281 +#: pkg/customer/admin.go:330 pkg/booking/checkin.go:281 msgid "Selected ID document type is not valid." msgstr "El tipo de documento de identidad escogido no es válido." -#: pkg/customer/admin.go:298 pkg/booking/checkin.go:282 +#: pkg/customer/admin.go:331 pkg/booking/checkin.go:282 msgid "ID document number can not be empty." msgstr "No podéis dejar el número del documento de identidad en blanco." -#: pkg/customer/admin.go:300 pkg/booking/checkin.go:288 -#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 +#: pkg/customer/admin.go:333 pkg/booking/checkin.go:288 +#: pkg/booking/checkin.go:289 pkg/booking/admin.go:429 #: pkg/booking/public.go:581 msgid "Full name can not be empty." msgstr "No podéis dejar el nombre y los apellidos en blanco." -#: pkg/customer/admin.go:301 pkg/booking/admin.go:427 pkg/booking/public.go:582 +#: pkg/customer/admin.go:334 pkg/booking/admin.go:430 pkg/booking/public.go:582 msgid "Full name must have at least one letter." msgstr "El nombre y los apellidos tienen que tener como mínimo una letra." -#: pkg/customer/admin.go:304 pkg/company/admin.go:230 pkg/booking/public.go:585 +#: pkg/customer/admin.go:337 pkg/company/admin.go:230 pkg/booking/public.go:585 msgid "Address can not be empty." msgstr "No podéis dejar la dirección en blanco." -#: pkg/customer/admin.go:305 pkg/booking/public.go:586 +#: pkg/customer/admin.go:338 pkg/booking/public.go:586 msgid "Town or village can not be empty." msgstr "No podéis dejar la población en blanco." -#: pkg/customer/admin.go:306 pkg/company/admin.go:233 pkg/booking/public.go:587 +#: pkg/customer/admin.go:339 pkg/company/admin.go:233 pkg/booking/public.go:587 msgid "Postcode can not be empty." msgstr "No podéis dejar el código postal en blanco." -#: pkg/customer/admin.go:307 pkg/company/admin.go:234 pkg/booking/admin.go:433 +#: pkg/customer/admin.go:340 pkg/company/admin.go:234 pkg/booking/admin.go:436 #: pkg/booking/public.go:588 msgid "This postcode is not valid." msgstr "Este código postal no es válido." -#: pkg/customer/admin.go:315 pkg/company/admin.go:220 -#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 +#: pkg/customer/admin.go:348 pkg/company/admin.go:220 +#: pkg/booking/checkin.go:301 pkg/booking/admin.go:446 #: pkg/booking/public.go:596 msgid "This phone number is not valid." msgstr "Este teléfono no es válido." -#: pkg/invoice/admin.go:649 +#: pkg/invoice/admin.go:681 msgctxt "filename" msgid "invoices.zip" msgstr "facturas.zip" -#: pkg/invoice/admin.go:664 +#: pkg/invoice/admin.go:696 msgctxt "filename" msgid "invoices.ods" msgstr "facturas.ods" -#: pkg/invoice/admin.go:666 pkg/invoice/admin.go:1285 pkg/invoice/admin.go:1292 +#: pkg/invoice/admin.go:698 pkg/invoice/admin.go:1360 pkg/invoice/admin.go:1367 msgid "Invalid action" msgstr "Acción inválida" -#: pkg/invoice/admin.go:830 +#: pkg/invoice/admin.go:863 msgid "Selected invoice status is not valid." msgstr "El estado de factura escogida no es válido." -#: pkg/invoice/admin.go:831 -msgid "Selected customer is not valid." -msgstr "El cliente escogido no es válido." - -#: pkg/invoice/admin.go:832 +#: pkg/invoice/admin.go:864 msgid "Invoice date can not be empty." msgstr "No podéis dejar la fecha de factura en blanco." -#: pkg/invoice/admin.go:833 +#: pkg/invoice/admin.go:865 msgid "Invoice date must be a valid date." msgstr "La fecha de factura tiene que ser una fecha válida." -#: pkg/invoice/admin.go:980 +#: pkg/invoice/admin.go:1023 #, c-format -msgid "Re: quotation #%s of %s" -msgstr "" +msgid "Re: booking #%s of %s–%s" +msgstr "Ref.: reserva núm. %s del %s–%s" -#: pkg/invoice/admin.go:981 +#: pkg/invoice/admin.go:1024 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoice/admin.go:1083 +#: pkg/invoice/admin.go:1151 msgid "Invoice product ID must be an integer." msgstr "El ID de producto de factura tiene que ser entero." -#: pkg/invoice/admin.go:1084 +#: pkg/invoice/admin.go:1152 msgid "Invoice product ID one or greater." msgstr "El ID de producto de factura tiene que ser como mínimo uno." -#: pkg/invoice/admin.go:1088 +#: pkg/invoice/admin.go:1156 msgid "Product ID must be an integer." msgstr "El ID de producto tiene que ser un número entero." -#: pkg/invoice/admin.go:1089 +#: pkg/invoice/admin.go:1157 msgid "Product ID must zero or greater." msgstr "El ID de producto tiene que ser como mínimo cero." -#: pkg/invoice/admin.go:1098 +#: pkg/invoice/admin.go:1166 msgid "Quantity can not be empty." msgstr "No podéis dejar la cantidad en blanco." -#: pkg/invoice/admin.go:1099 +#: pkg/invoice/admin.go:1167 msgid "Quantity must be an integer." msgstr "La cantidad tiene que ser un número entero." -#: pkg/invoice/admin.go:1100 +#: pkg/invoice/admin.go:1168 msgid "Quantity must one or greater." msgstr "La cantidad tiene que ser como mínimo uno." -#: pkg/invoice/admin.go:1103 +#: pkg/invoice/admin.go:1171 msgid "Discount can not be empty." msgstr "No podéis dejar el descuento en blanco." -#: pkg/invoice/admin.go:1104 +#: pkg/invoice/admin.go:1172 msgid "Discount must be an integer." msgstr "El descuento tiene que ser un número entero." -#: pkg/invoice/admin.go:1105 pkg/invoice/admin.go:1106 +#: pkg/invoice/admin.go:1173 pkg/invoice/admin.go:1174 msgid "Discount must be a percentage between 0 and 100." msgstr "El descuento tiene que ser un porcentaje entre 1 y 100." -#: pkg/invoice/admin.go:1110 +#: pkg/invoice/admin.go:1178 msgid "Selected tax is not valid." msgstr "El impuesto escogido no es válido." @@ -3444,19 +3452,19 @@ msgctxt "filename" msgid "bookings.ods" msgstr "reservas.ods" -#: pkg/booking/admin.go:432 +#: pkg/booking/admin.go:435 msgid "Country can not be empty to validate the postcode." msgstr "No podéis dejar el país en blanco para validar el código postal." -#: pkg/booking/admin.go:442 +#: pkg/booking/admin.go:445 msgid "Country can not be empty to validate the phone." msgstr "No podéis dejar el país en blanco para validar el teléfono." -#: pkg/booking/admin.go:449 +#: pkg/booking/admin.go:452 msgid "You must select at least one accommodation." msgstr "Tenéis que seleccionar como mínimo un alojamiento." -#: pkg/booking/admin.go:455 +#: pkg/booking/admin.go:458 msgid "The selected accommodations have no available openings in the requested dates." msgstr "Los alojamientos seleccionados no tienen disponibilidad en las fechas pedidas." @@ -3573,6 +3581,12 @@ msgstr "%s tiene que ser como máximo %d" msgid "It is mandatory to agree to the reservation conditions." msgstr "Es obligatorio aceptar las condiciones de reserva." +#~ msgid "Select a customer" +#~ msgstr "Escoja un cliente" + +#~ msgid "Selected customer is not valid." +#~ msgstr "El cliente escogido no es válido." + #~ msgctxt "title" #~ msgid "Accomodations" #~ msgstr "Alojamientos" diff --git a/po/fr.po b/po/fr.po index e5c1a79..86a0f5b 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2024-04-28 20:05+0200\n" +"POT-Creation-Date: 2024-04-28 22:32+0200\n" "PO-Revision-Date: 2024-02-06 10:05+0100\n" "Last-Translator: Oriol Carbonell \n" "Language-Team: French \n" @@ -178,7 +178,7 @@ msgstr "Nuits" #: web/templates/mail/payment/details.gotxt:22 #: web/templates/public/booking/fields.gohtml:60 #: web/templates/admin/payment/details.gohtml:98 -#: web/templates/admin/booking/fields.gohtml:93 +#: web/templates/admin/booking/fields.gohtml:93 pkg/invoice/admin.go:1064 msgctxt "input" msgid "Adults aged 17 or older" msgstr "Adultes âgés 17 ans ou plus" @@ -186,7 +186,7 @@ msgstr "Adultes âgés 17 ans ou plus" #: web/templates/mail/payment/details.gotxt:23 #: web/templates/public/booking/fields.gohtml:71 #: web/templates/admin/payment/details.gohtml:102 -#: web/templates/admin/booking/fields.gohtml:109 +#: web/templates/admin/booking/fields.gohtml:109 pkg/invoice/admin.go:1065 msgctxt "input" msgid "Teenagers from 11 to 16 years old" msgstr "Adolescents de 11 à 16 ans" @@ -194,7 +194,7 @@ msgstr "Adolescents de 11 à 16 ans" #: web/templates/mail/payment/details.gotxt:24 #: web/templates/public/booking/fields.gohtml:82 #: web/templates/admin/payment/details.gohtml:106 -#: web/templates/admin/booking/fields.gohtml:125 +#: web/templates/admin/booking/fields.gohtml:125 pkg/invoice/admin.go:1066 msgctxt "input" msgid "Children from 2 to 10 years old" msgstr "Enfants de 2 à 10 ans" @@ -202,14 +202,15 @@ msgstr "Enfants de 2 à 10 ans" #: web/templates/mail/payment/details.gotxt:25 #: web/templates/public/booking/fields.gohtml:100 #: web/templates/admin/payment/details.gohtml:110 -#: web/templates/admin/booking/fields.gohtml:140 +#: web/templates/admin/booking/fields.gohtml:140 pkg/invoice/admin.go:1067 msgctxt "input" msgid "Dogs" msgstr "Chiens" #: web/templates/mail/payment/details.gotxt:26 #: web/templates/admin/payment/details.gohtml:114 -#: web/templates/admin/booking/fields.gohtml:167 pkg/booking/cart.go:242 +#: web/templates/admin/booking/fields.gohtml:167 pkg/invoice/admin.go:1068 +#: pkg/booking/cart.go:242 msgctxt "cart" msgid "Tourist tax" msgstr "Taxe touristique" @@ -239,7 +240,7 @@ msgstr "Options de type d’emplacement de camping" #: web/templates/mail/payment/details.gotxt:39 #: web/templates/public/booking/fields.gohtml:146 #: web/templates/admin/payment/details.gohtml:140 -#: web/templates/admin/customer/form.gohtml:28 +#: web/templates/admin/customer/contact.gohtml:3 #: web/templates/admin/booking/fields.gohtml:188 msgctxt "title" msgid "Customer Details" @@ -248,7 +249,7 @@ msgstr "Détails du client" #: web/templates/mail/payment/details.gotxt:41 #: web/templates/public/booking/fields.gohtml:149 #: web/templates/admin/payment/details.gohtml:143 -#: web/templates/admin/customer/form.gohtml:31 +#: web/templates/admin/customer/contact.gohtml:6 #: web/templates/admin/booking/fields.gohtml:191 msgctxt "input" msgid "Full name" @@ -257,7 +258,7 @@ msgstr "Nom et prénom" #: web/templates/mail/payment/details.gotxt:42 #: web/templates/public/booking/fields.gohtml:158 #: web/templates/admin/payment/details.gohtml:147 -#: web/templates/admin/customer/form.gohtml:69 +#: web/templates/admin/customer/contact.gohtml:44 #: web/templates/admin/taxDetails.gohtml:69 msgctxt "input" msgid "Address" @@ -266,7 +267,7 @@ msgstr "Adresse" #: web/templates/mail/payment/details.gotxt:43 #: web/templates/public/booking/fields.gohtml:167 #: web/templates/admin/payment/details.gohtml:151 -#: web/templates/admin/customer/form.gohtml:105 +#: web/templates/admin/customer/contact.gohtml:80 #: web/templates/admin/taxDetails.gohtml:93 msgctxt "input" msgid "Postcode" @@ -282,7 +283,7 @@ msgstr "Ville" #: web/templates/mail/payment/details.gotxt:45 #: web/templates/public/booking/fields.gohtml:187 #: web/templates/admin/payment/details.gohtml:159 -#: web/templates/admin/customer/form.gohtml:117 +#: web/templates/admin/customer/contact.gohtml:92 #: web/templates/admin/taxDetails.gohtml:101 msgctxt "input" msgid "Country" @@ -423,7 +424,7 @@ msgid "Date" msgstr "Date" #: web/templates/public/payment/details.gohtml:12 -#: web/templates/admin/invoice/form.gohtml:119 +#: web/templates/admin/invoice/form.gohtml:111 #: web/templates/admin/invoice/view.gohtml:63 #: web/templates/admin/invoice/view.gohtml:103 msgctxt "title" @@ -1019,13 +1020,13 @@ msgid "Campground map" msgstr "Plan du camping" #: web/templates/public/booking/fields.gohtml:176 -#: web/templates/admin/customer/form.gohtml:81 +#: web/templates/admin/customer/contact.gohtml:56 msgctxt "input" msgid "Town or village" msgstr "Ville" #: web/templates/public/booking/fields.gohtml:193 -#: web/templates/admin/customer/form.gohtml:121 +#: web/templates/admin/customer/contact.gohtml:96 #: web/templates/admin/booking/fields.gohtml:204 #: web/templates/admin/booking/guest.gohtml:111 msgid "Choose a country" @@ -1206,8 +1207,8 @@ msgstr "Contenu" #: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/season/form.gohtml:73 -#: web/templates/admin/customer/form.gohtml:153 -#: web/templates/admin/invoice/form.gohtml:137 +#: web/templates/admin/customer/form.gohtml:34 +#: web/templates/admin/invoice/form.gohtml:129 #: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/index.gohtml:58 @@ -1216,7 +1217,7 @@ msgstr "Contenu" #: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/media/form.gohtml:39 -#: web/templates/admin/booking/form.gohtml:45 +#: web/templates/admin/booking/form.gohtml:48 msgctxt "action" msgid "Update" msgstr "Mettre à jour" @@ -1231,13 +1232,13 @@ msgstr "Mettre à jour" #: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/season/form.gohtml:75 -#: web/templates/admin/customer/form.gohtml:155 +#: web/templates/admin/customer/form.gohtml:36 #: web/templates/admin/services/form.gohtml:83 #: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/form.gohtml:93 -#: web/templates/admin/booking/form.gohtml:47 +#: web/templates/admin/booking/form.gohtml:50 msgctxt "action" msgid "Add" msgstr "Ajouter" @@ -1863,36 +1864,41 @@ msgctxt "title" msgid "Customer" msgstr "Client" -#: web/templates/admin/customer/form.gohtml:44 +#: web/templates/admin/customer/form.gohtml:21 +msgctxt "action" +msgid "Invoice Customer" +msgstr "Facturer le client" + +#: web/templates/admin/customer/contact.gohtml:19 #: web/templates/admin/booking/guest.gohtml:8 msgctxt "input" msgid "ID document number" msgstr "Numéro de document d’identité" -#: web/templates/admin/customer/form.gohtml:56 +#: web/templates/admin/customer/contact.gohtml:31 #: web/templates/admin/booking/guest.gohtml:20 msgctxt "input" msgid "ID document type" msgstr "Type de document d’identité" -#: web/templates/admin/customer/form.gohtml:61 +#: web/templates/admin/customer/contact.gohtml:36 #: web/templates/admin/booking/guest.gohtml:25 msgid "Choose an ID document type" msgstr "Choisissez un type de document d’identité" -#: web/templates/admin/customer/form.gohtml:93 +#: web/templates/admin/customer/contact.gohtml:68 #: web/templates/admin/taxDetails.gohtml:85 msgctxt "input" msgid "Province" msgstr "Province" -#: web/templates/admin/customer/form.gohtml:129 +#: web/templates/admin/customer/contact.gohtml:104 #: web/templates/admin/booking/fields.gohtml:239 msgctxt "input" msgid "Email (optional)" msgstr "E-mail (facultatif)" -#: web/templates/admin/customer/form.gohtml:140 +#: web/templates/admin/customer/contact.gohtml:115 #: web/templates/admin/booking/fields.gohtml:248 #: web/templates/admin/booking/guest.gohtml:119 msgctxt "input" @@ -1975,53 +1981,48 @@ msgctxt "title" msgid "Invoices" msgstr "Factures" -#: web/templates/admin/invoice/form.gohtml:32 +#: web/templates/admin/invoice/form.gohtml:34 msgid "Product “%s” removed" msgstr "Produit «%s» supprimé" -#: web/templates/admin/invoice/form.gohtml:36 +#: web/templates/admin/invoice/form.gohtml:38 msgctxt "action" msgid "Undo" msgstr "Annuler" -#: web/templates/admin/invoice/form.gohtml:51 -#: web/templates/admin/invoice/index.gohtml:39 -msgctxt "input" -msgid "Customer" -msgstr "Client" - -#: web/templates/admin/invoice/form.gohtml:56 -msgid "Select a customer" -msgstr "Choisissez un client" - -#: web/templates/admin/invoice/form.gohtml:64 +#: web/templates/admin/invoice/form.gohtml:53 msgctxt "input" msgid "Invoice date" msgstr "Date de facture" -#: web/templates/admin/invoice/form.gohtml:77 +#: web/templates/admin/invoice/form.gohtml:66 #: web/templates/admin/invoice/index.gohtml:51 msgctxt "input" msgid "Invoice status" msgstr "Statut de la facture" -#: web/templates/admin/invoice/form.gohtml:92 +#: web/templates/admin/invoice/form.gohtml:81 msgctxt "input" msgid "Notes (optional)" msgstr "Remarques (facultatif)" -#: web/templates/admin/invoice/form.gohtml:109 +#: web/templates/admin/invoice/form.gohtml:93 +msgctxt "title" +msgid "Products" +msgstr "Produits" + +#: web/templates/admin/invoice/form.gohtml:101 #: web/templates/admin/invoice/view.gohtml:59 msgctxt "title" msgid "Subtotal" msgstr "Sous-totale" -#: web/templates/admin/invoice/form.gohtml:133 +#: web/templates/admin/invoice/form.gohtml:125 msgctxt "action" msgid "Add products" msgstr "Ajouter des produits" -#: web/templates/admin/invoice/form.gohtml:140 +#: web/templates/admin/invoice/form.gohtml:132 msgctxt "action" msgid "Save" msgstr "Enregistrer" @@ -2036,6 +2037,11 @@ msgctxt "action" msgid "Export list" msgstr "Exporter la liste" +#: web/templates/admin/invoice/index.gohtml:39 +msgctxt "input" +msgid "Customer" +msgstr "Client" + #: web/templates/admin/invoice/index.gohtml:43 msgid "All customers" msgstr "Tous les clients" @@ -2645,7 +2651,8 @@ msgctxt "header" msgid "Decription" msgstr "Description" -#: web/templates/admin/booking/fields.gohtml:81 pkg/booking/cart.go:232 +#: web/templates/admin/booking/fields.gohtml:81 pkg/invoice/admin.go:1063 +#: pkg/booking/cart.go:232 msgctxt "cart" msgid "Night" msgstr "Nuit" @@ -2686,6 +2693,11 @@ msgctxt "action" msgid "Check-in Booking" msgstr "Enregistrer réservation" +#: web/templates/admin/booking/form.gohtml:28 +msgctxt "action" +msgid "Invoice Booking" +msgstr "Facturer la réservation" + #: web/templates/admin/booking/checkin.gohtml:6 msgctxt "title" msgid "Check-in Booking" @@ -2839,7 +2851,7 @@ msgstr "Paiement de réservation reçu avec succès" #: pkg/legal/admin.go:258 pkg/app/user.go:249 pkg/campsite/types/option.go:365 #: pkg/campsite/types/feature.go:272 pkg/campsite/types/admin.go:577 #: pkg/campsite/feature.go:269 pkg/season/admin.go:411 -#: pkg/invoice/admin.go:1092 pkg/services/admin.go:316 +#: pkg/invoice/admin.go:1160 pkg/services/admin.go:316 #: pkg/surroundings/admin.go:340 pkg/amenity/feature.go:269 #: pkg/amenity/admin.go:283 msgid "Name can not be empty." @@ -2880,8 +2892,8 @@ msgstr "L’image de la diapositive doit être de type média d’image." msgid "Email can not be empty." msgstr "L’e-mail ne peut pas être vide." -#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:312 -#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 +#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345 +#: pkg/company/admin.go:225 pkg/booking/admin.go:441 pkg/booking/public.go:593 msgid "This email is not valid. It should be like name@domain.com." msgstr "Cette adresse e-mail n’est pas valide. Il devrait en être name@domain.com." @@ -2938,15 +2950,15 @@ msgstr "Le maximum doit être un nombre entier." msgid "Maximum must be equal or greater than minimum." msgstr "Le maximum doit être égal ou supérieur au minimum." -#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1093 +#: pkg/campsite/types/option.go:382 pkg/invoice/admin.go:1161 msgid "Price can not be empty." msgstr "Le prix ne peut pas être vide." -#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1094 +#: pkg/campsite/types/option.go:383 pkg/invoice/admin.go:1162 msgid "Price must be a decimal number." msgstr "Le prix doit être un nombre décimal." -#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1095 +#: pkg/campsite/types/option.go:384 pkg/invoice/admin.go:1163 msgid "Price must be zero or greater." msgstr "Le prix doit être égal ou supérieur à zéro." @@ -3092,7 +3104,7 @@ msgctxt "header" msgid "Children (aged 2 to 10)" msgstr "Enfants (de 2 à 10 anys)" -#: pkg/campsite/admin.go:280 pkg/booking/admin.go:414 pkg/booking/public.go:177 +#: pkg/campsite/admin.go:280 pkg/booking/admin.go:417 pkg/booking/public.go:177 #: pkg/booking/public.go:232 msgid "Selected campsite type is not valid." msgstr "Le type d’emplacement sélectionné n’est pas valide." @@ -3130,133 +3142,129 @@ msgstr "La date de fin ne peut pas être vide." msgid "End date must be a valid date." msgstr "La date de fin doit être une date valide." -#: pkg/customer/admin.go:293 pkg/company/admin.go:207 +#: pkg/customer/admin.go:326 pkg/company/admin.go:207 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577 msgid "Selected country is not valid." msgstr "Le pays sélectionné n’est pas valide." -#: pkg/customer/admin.go:297 pkg/booking/checkin.go:281 +#: pkg/customer/admin.go:330 pkg/booking/checkin.go:281 msgid "Selected ID document type is not valid." msgstr "Le type de document d’identité sélectionné n’est pas valide." -#: pkg/customer/admin.go:298 pkg/booking/checkin.go:282 +#: pkg/customer/admin.go:331 pkg/booking/checkin.go:282 msgid "ID document number can not be empty." msgstr "Le numéro de documento d’identité ne peut pas être vide." -#: pkg/customer/admin.go:300 pkg/booking/checkin.go:288 -#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 +#: pkg/customer/admin.go:333 pkg/booking/checkin.go:288 +#: pkg/booking/checkin.go:289 pkg/booking/admin.go:429 #: pkg/booking/public.go:581 msgid "Full name can not be empty." msgstr "Le nom complet ne peut pas être vide." -#: pkg/customer/admin.go:301 pkg/booking/admin.go:427 pkg/booking/public.go:582 +#: pkg/customer/admin.go:334 pkg/booking/admin.go:430 pkg/booking/public.go:582 msgid "Full name must have at least one letter." msgstr "Le nom complet doit comporter au moins une lettre." -#: pkg/customer/admin.go:304 pkg/company/admin.go:230 pkg/booking/public.go:585 +#: pkg/customer/admin.go:337 pkg/company/admin.go:230 pkg/booking/public.go:585 msgid "Address can not be empty." msgstr "L’adresse ne peut pas être vide." -#: pkg/customer/admin.go:305 pkg/booking/public.go:586 +#: pkg/customer/admin.go:338 pkg/booking/public.go:586 msgid "Town or village can not be empty." msgstr "La ville ne peut pas être vide." -#: pkg/customer/admin.go:306 pkg/company/admin.go:233 pkg/booking/public.go:587 +#: pkg/customer/admin.go:339 pkg/company/admin.go:233 pkg/booking/public.go:587 msgid "Postcode can not be empty." msgstr "Le code postal ne peut pas être vide." -#: pkg/customer/admin.go:307 pkg/company/admin.go:234 pkg/booking/admin.go:433 +#: pkg/customer/admin.go:340 pkg/company/admin.go:234 pkg/booking/admin.go:436 #: pkg/booking/public.go:588 msgid "This postcode is not valid." msgstr "Ce code postal n’est pas valide." -#: pkg/customer/admin.go:315 pkg/company/admin.go:220 -#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 +#: pkg/customer/admin.go:348 pkg/company/admin.go:220 +#: pkg/booking/checkin.go:301 pkg/booking/admin.go:446 #: pkg/booking/public.go:596 msgid "This phone number is not valid." msgstr "Ce numéro de téléphone n’est pas valide." -#: pkg/invoice/admin.go:649 +#: pkg/invoice/admin.go:681 msgctxt "filename" msgid "invoices.zip" msgstr "factures.zip" -#: pkg/invoice/admin.go:664 +#: pkg/invoice/admin.go:696 msgctxt "filename" msgid "invoices.ods" msgstr "factures.ods" -#: pkg/invoice/admin.go:666 pkg/invoice/admin.go:1285 pkg/invoice/admin.go:1292 +#: pkg/invoice/admin.go:698 pkg/invoice/admin.go:1360 pkg/invoice/admin.go:1367 msgid "Invalid action" msgstr "Actin invalide" -#: pkg/invoice/admin.go:830 +#: pkg/invoice/admin.go:863 msgid "Selected invoice status is not valid." msgstr "L’statut sélectionné n’est pas valide." -#: pkg/invoice/admin.go:831 -msgid "Selected customer is not valid." -msgstr "Le client sélectionné n’est pas valide." - -#: pkg/invoice/admin.go:832 +#: pkg/invoice/admin.go:864 msgid "Invoice date can not be empty." msgstr "La date de facture ne peut pas être vide." -#: pkg/invoice/admin.go:833 +#: pkg/invoice/admin.go:865 msgid "Invoice date must be a valid date." msgstr "La date de facture doit être une date valide." -#: pkg/invoice/admin.go:980 +#: pkg/invoice/admin.go:1023 #, c-format -msgid "Re: quotation #%s of %s" -msgstr "" +msgid "Re: booking #%s of %s–%s" +msgstr "Réf. : réservation num. %s du %s–%s" -#: pkg/invoice/admin.go:981 +#: pkg/invoice/admin.go:1024 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoice/admin.go:1083 +#: pkg/invoice/admin.go:1151 msgid "Invoice product ID must be an integer." msgstr "Le ID de produit de facture doit être un entier." -#: pkg/invoice/admin.go:1084 +#: pkg/invoice/admin.go:1152 msgid "Invoice product ID one or greater." msgstr "Le ID de produit de facture doit être égal ou supérieur à un." -#: pkg/invoice/admin.go:1088 +#: pkg/invoice/admin.go:1156 msgid "Product ID must be an integer." msgstr "Le ID de produit doit être un entier." -#: pkg/invoice/admin.go:1089 +#: pkg/invoice/admin.go:1157 msgid "Product ID must zero or greater." msgstr "Le ID de produit doit être égal ou supérieur à zéro." -#: pkg/invoice/admin.go:1098 +#: pkg/invoice/admin.go:1166 msgid "Quantity can not be empty." msgstr "La quantité ne peut pas être vide." -#: pkg/invoice/admin.go:1099 +#: pkg/invoice/admin.go:1167 msgid "Quantity must be an integer." msgstr "La quantité doit être un entier." -#: pkg/invoice/admin.go:1100 +#: pkg/invoice/admin.go:1168 msgid "Quantity must one or greater." msgstr "La quantité doit être égnal ou supérieur à zéro." -#: pkg/invoice/admin.go:1103 +#: pkg/invoice/admin.go:1171 msgid "Discount can not be empty." msgstr "Le rabais ne peut pas être vide." -#: pkg/invoice/admin.go:1104 +#: pkg/invoice/admin.go:1172 msgid "Discount must be an integer." msgstr "Le rabais doit être un entier." -#: pkg/invoice/admin.go:1105 pkg/invoice/admin.go:1106 +#: pkg/invoice/admin.go:1173 pkg/invoice/admin.go:1174 msgid "Discount must be a percentage between 0 and 100." msgstr "Le rabais doit être un pourcentage compris entre 0 et 100." -#: pkg/invoice/admin.go:1110 +#: pkg/invoice/admin.go:1178 msgid "Selected tax is not valid." msgstr "La taxe sélectionnée n’est pas valide." @@ -3444,19 +3452,19 @@ msgctxt "filename" msgid "bookings.ods" msgstr "reservations.ods" -#: pkg/booking/admin.go:432 +#: pkg/booking/admin.go:435 msgid "Country can not be empty to validate the postcode." msgstr "Le pays ne peut pas être vide pour valider le code postal." -#: pkg/booking/admin.go:442 +#: pkg/booking/admin.go:445 msgid "Country can not be empty to validate the phone." msgstr "Le pays ne peut pas être vide pour valider le téléphone." -#: pkg/booking/admin.go:449 +#: pkg/booking/admin.go:452 msgid "You must select at least one accommodation." msgstr "Vous devez sélectionner au moins un hébergement." -#: pkg/booking/admin.go:455 +#: pkg/booking/admin.go:458 msgid "The selected accommodations have no available openings in the requested dates." msgstr "Les hébergements sélectionnés n’ont pas de disponibilités aux dates demandées." @@ -3573,6 +3581,12 @@ msgstr "%s doit être tout au plus %d." msgid "It is mandatory to agree to the reservation conditions." msgstr "Il est obligatoire d’accepter les conditions de réservation." +#~ msgid "Select a customer" +#~ msgstr "Choisissez un client" + +#~ msgid "Selected customer is not valid." +#~ msgstr "Le client sélectionné n’est pas valide." + #~ msgctxt "title" #~ msgid "Accomodations" #~ msgstr "Hébergement" diff --git a/web/static/camper.css b/web/static/camper.css index db9f23d..de9f707 100644 --- a/web/static/camper.css +++ b/web/static/camper.css @@ -1133,22 +1133,22 @@ label[x-show] > span, label[x-show] > br { /**/ /* */ -#contact-form label + label { +:is(#contact-form, #invoice-form) label + label { margin-top: 0; } -#contact-form :is(input, select) { +:is(#contact-form, #invoice-form) :is(input, select) { width: 100%; } -#contact-form .customer-details { +:is(#contact-form, #invoice-form) .customer-details { display: grid; gap: .5em; grid-template-columns: repeat(3, 1fr); align-content: start; } -#contact-form .customer-details label:nth-of-type(4) { +:is(#contact-form, #invoice-form) .customer-details label:nth-of-type(4) { grid-column: 1 / -1; } diff --git a/web/templates/admin/customer/contact.gohtml b/web/templates/admin/customer/contact.gohtml new file mode 100644 index 0000000..f7d4747 --- /dev/null +++ b/web/templates/admin/customer/contact.gohtml @@ -0,0 +1,124 @@ +{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}} +
+ {{( pgettext "Customer Details" "title" )}} + {{ with .FullName -}} + + {{- end }} + {{ with .IDDocumentNumber -}} + + {{- end }} + {{ with .IDDocumentType -}} + + {{- end }} + {{ with .Address -}} + + {{- end }} + {{ with .City -}} + + {{- end }} + {{ with .Province -}} + + {{- end }} + {{ with .PostalCode -}} + + {{- end }} + {{ with .Country -}} + + {{- end }} + {{ with .Email -}} + + {{- end }} + {{ with .Phone -}} + + {{- end }} +
diff --git a/web/templates/admin/customer/form.gohtml b/web/templates/admin/customer/form.gohtml index 3782ced..e69feed 100644 --- a/web/templates/admin/customer/form.gohtml +++ b/web/templates/admin/customer/form.gohtml @@ -3,7 +3,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> {{ define "title" -}} - {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.customerForm*/ -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}} {{ if .Slug }} {{( pgettext "Edit Customer" "title" )}} {{ else }} @@ -16,7 +16,10 @@ {{- end }} {{ define "content" -}} - {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.customerForm*/ -}} + {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}} + {{ if .Slug -}} + {{( pgettext "Invoice Customer" "action" )}} + {{- end }}

{{ template "title" .}}

{{ CSRFInput }} -
- {{( pgettext "Customer Details" "title" )}} - {{ with .FullName -}} - - {{- end }} - {{ with .IDDocumentNumber -}} - - {{- end }} - {{ with .IDDocumentType -}} - - {{- end }} - {{ with .Address -}} - - {{- end }} - {{ with .City -}} - - {{- end }} - {{ with .Province -}} - - {{- end }} - {{ with .PostalCode -}} - - {{- end }} - {{ with .Country -}} - - {{- end }} - {{ with .Email -}} - - {{- end }} - {{ with .Phone -}} - - {{- end }} -
+ {{ template "contact.gohtml" . }}