Allow to create the customer to invoice “in flight”

That way i can get the data from the booking or the actual customer.
This commit is contained in:
jordi fita mas 2024-04-28 22:36:21 +02:00
parent ff9f33dfba
commit 2299f2325e
10 changed files with 591 additions and 464 deletions

View File

@ -37,13 +37,13 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
case "new": case "new":
switch r.Method { switch r.Method {
case http.MethodGet: case http.MethodGet:
f := newCustomerForm(r.Context(), conn, user.Locale) f := NewContactForm(r.Context(), conn, user.Locale)
f.MustRender(w, r, user, company) f.MustRender(w, r, user, company)
default: default:
httplib.MethodNotAllowed(w, r, http.MethodGet) httplib.MethodNotAllowed(w, r, http.MethodGet)
} }
default: 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 err := f.FillFromDatabase(r.Context(), conn, head); err != nil {
if database.ErrorIsNotFound(err) { if database.ErrorIsNotFound(err) {
http.NotFound(w, r) 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) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var head string var head string
head, r.URL.Path = httplib.ShiftPath(r.URL.Path) 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) { 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 { processCustomerForm(w, r, user, company, conn, f, func(ctx context.Context, tx *database.Tx) error {
var err 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()) 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 { 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()) _, 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 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 { if err := f.Parse(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return return
@ -181,7 +181,7 @@ func processCustomerForm(w http.ResponseWriter, r *http.Request, user *auth.User
httplib.Redirect(w, r, "/admin/customers", http.StatusSeeOther) httplib.Redirect(w, r, "/admin/customers", http.StatusSeeOther)
} }
type customerForm struct { type ContactForm struct {
URL string URL string
Slug string Slug string
FullName *form.Input FullName *form.Input
@ -196,8 +196,8 @@ type customerForm struct {
Phone *form.Input Phone *form.Input
} }
func newCustomerForm(ctx context.Context, conn *database.Conn, l *locale.Locale) *customerForm { func NewContactForm(ctx context.Context, conn *database.Conn, l *locale.Locale) *ContactForm {
return &customerForm{ return &ContactForm{
FullName: &form.Input{ FullName: &form.Input{
Name: "full_name", 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, ` row := conn.QueryRow(ctx, `
select '/admin/customers/' || slug select '/admin/customers/' || slug
, 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 { if err := r.ParseForm(); err != nil {
return err return err
} }
@ -286,7 +319,7 @@ func (f *customerForm) Parse(r *http.Request) error {
return nil 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) v := form.NewValidator(l)
var country string var country string
@ -319,6 +352,36 @@ func (f *customerForm) Valid(ctx context.Context, conn *database.Conn, l *locale
return v.AllOK, nil return v.AllOK, nil
} }
func (f *customerForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { func (f *ContactForm) UpdateOrCreate(ctx context.Context, company *auth.Company, tx *database.Tx) (int, error) {
template.MustRenderAdmin(w, r, user, company, "customer/form.gohtml", f) 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")
} }

View File

@ -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) 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) { func (tx *Tx) 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) 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) { 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) {

View File

@ -2,7 +2,6 @@ package invoice
import ( import (
"context" "context"
"dev.tandem.ws/tandem/camper/pkg/ods"
"fmt" "fmt"
"net/http" "net/http"
"sort" "sort"
@ -13,10 +12,12 @@ import (
"github.com/jackc/pgtype" "github.com/jackc/pgtype"
"dev.tandem.ws/tandem/camper/pkg/auth" "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/database"
"dev.tandem.ws/tandem/camper/pkg/form" "dev.tandem.ws/tandem/camper/pkg/form"
httplib "dev.tandem.ws/tandem/camper/pkg/http" httplib "dev.tandem.ws/tandem/camper/pkg/http"
"dev.tandem.ws/tandem/camper/pkg/locale" "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/template"
"dev.tandem.ws/tandem/camper/pkg/uuid" "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 { switch r.Method {
case http.MethodGet: case http.MethodGet:
f := newInvoiceForm(r.Context(), conn, company, user.Locale) 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.MustFillFromDatabase(r.Context(), conn, user.Locale, invoiceToDuplicate)
f.Slug = "" f.Slug = ""
f.InvoiceStatus.Selected = []string{"created"} 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) 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.Date.Val = time.Now().Format("2006-01-02")
f.MustRender(w, r, user, company, conn) 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) http.Error(w, err.Error(), http.StatusBadRequest)
return 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) { if !httplib.IsHTMxRequest(r) {
w.WriteHeader(http.StatusUnprocessableEntity) 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()) tx := conn.MustBegin(r.Context())
defer tx.Rollback(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 { if err != nil {
panic(err) panic(err)
} }
@ -775,12 +787,12 @@ func mustMakeTaxMap(ctx context.Context, conn *database.Conn, ids *pgtype.Int4Ar
} }
type invoiceForm struct { type invoiceForm struct {
company *auth.Company
Slug string Slug string
Number string Number string
BookingID *form.Input BookingID *form.Input
company *auth.Company
InvoiceStatus *form.Select InvoiceStatus *form.Select
Customer *form.Select Customer *customer.ContactForm
Date *form.Input Date *form.Input
Notes *form.Input Notes *form.Input
Products []*invoiceProductForm Products []*invoiceProductForm
@ -790,7 +802,7 @@ type invoiceForm struct {
Total string 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{ return &invoiceForm{
company: company, company: company,
BookingID: &form.Input{ BookingID: &form.Input{
@ -799,12 +811,9 @@ func newInvoiceForm(ctx context.Context, conn *database.Conn, company *auth.Comp
InvoiceStatus: &form.Select{ InvoiceStatus: &form.Select{
Name: "invoice_status", Name: "invoice_status",
Selected: []string{"created"}, Selected: []string{"created"},
Options: mustGetInvoiceStatusOptions(ctx, conn, locale), Options: mustGetInvoiceStatusOptions(ctx, conn, l),
},
Customer: &form.Select{
Name: "customer",
Options: mustGetCustomerOptions(ctx, conn, company),
}, },
Customer: customer.NewContactForm(ctx, conn, l),
Date: &form.Input{ Date: &form.Input{
Name: "date", Name: "date",
}, },
@ -830,7 +839,6 @@ func (f *invoiceForm) Parse(r *http.Request, conn *database.Conn, l *locale.Loca
} }
f.BookingID.FillValue(r) f.BookingID.FillValue(r)
f.InvoiceStatus.FillValue(r) f.InvoiceStatus.FillValue(r)
f.Customer.FillValue(r)
f.Date.FillValue(r) f.Date.FillValue(r)
f.Notes.FillValue(r) f.Notes.FillValue(r)
if _, ok := r.Form["product.id.0"]; ok { 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) 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 := form.NewValidator(l)
v.CheckSelectedOptions(f.InvoiceStatus, l.GettextNoop("Selected invoice status is not valid.")) 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.")) { 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.")) 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 { for _, product := range f.Products {
allOK = product.Validate(l) && allOK 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) { 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 { if len(f.Products) == 0 {
f.Products = append(f.Products, newInvoiceProductForm(0, company, user.Locale, mustGetTaxOptions(r.Context(), conn, company))) 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 = ` 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 { func (f *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *database.Conn, l *locale.Locale, slug string) bool {
var invoiceId int var invoiceId int
var contactSlug string
selectedInvoiceStatus := f.InvoiceStatus.Selected selectedInvoiceStatus := f.InvoiceStatus.Selected
f.InvoiceStatus.Selected = nil f.InvoiceStatus.Selected = nil
err := conn.QueryRow(ctx, ` err := conn.QueryRow(ctx, `
select invoice_id select invoice_id
, array[invoice_status] , array[invoice_status]
, array[contact_id::text] , contact.slug
, invoice_number , invoice_number
, invoice_date::text , invoice_date::text
, notes , notes
from invoice from invoice
where slug = $1 join contact using (contact_id)
`, slug).Scan(&invoiceId, &f.InvoiceStatus.Selected, &f.Customer.Selected, &f.Number, &f.Date.Val, &f.Notes.Val) where invoice.slug = $1
`, slug).Scan(&invoiceId, &f.InvoiceStatus.Selected, &contactSlug, &f.Number, &f.Date.Val, &f.Notes.Val)
if err != nil { if err != nil {
if database.ErrorIsNotFound(err) { if database.ErrorIsNotFound(err) {
f.InvoiceStatus.Selected = selectedInvoiceStatus f.InvoiceStatus.Selected = selectedInvoiceStatus
@ -997,6 +1013,9 @@ func (f *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *database.C
f.Slug = slug f.Slug = slug
f.Products = []*invoiceProductForm{} 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) 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 return true
} }
@ -1048,6 +1067,9 @@ func (f *invoiceForm) MustFillFromBooking(ctx context.Context, conn *database.Co
l.Pgettext("Dogs", "input"), l.Pgettext("Dogs", "input"),
l.Pgettext("Tourist tax", "cart"), l.Pgettext("Tourist tax", "cart"),
) )
if err := f.Customer.FillFromBooking(ctx, conn, bookingID); err != nil && !database.ErrorIsNotFound(err) {
panic(err)
}
return true 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) 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 { type invoiceProductForm struct {
locale *locale.Locale locale *locale.Locale
company *auth.Company 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) httplib.Relocate(w, r, "/admin/invoices", http.StatusSeeOther)
} else { } 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) { if !httplib.IsHTMxRequest(r) {
w.WriteHeader(http.StatusUnprocessableEntity) w.WriteHeader(http.StatusUnprocessableEntity)
} }
f.MustRender(w, r, user, company, conn) f.MustRender(w, r, user, company, conn)
return return
} }
var err error tx := conn.MustBegin(r.Context())
slug, err = conn.EditInvoice(r.Context(), slug, f.InvoiceStatus.String(), f.Customer.Int(), f.Notes.Val, defaultPaymentMethod, editedInvoiceProducts(f.Products)) defer tx.Rollback(r.Context())
customerID, err := f.Customer.UpdateOrCreate(r.Context(), company, tx)
if err != nil { if err != nil {
panic(err) 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 == "" { if slug == "" {
http.NotFound(w, r) http.NotFound(w, r)
return return

198
po/ca.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: camper\n" "Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\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" "PO-Revision-Date: 2024-02-06 10:04+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n" "Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n" "Language-Team: Catalan <ca@dodds.net>\n"
@ -178,7 +178,7 @@ msgstr "Nits"
#: web/templates/mail/payment/details.gotxt:22 #: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60 #: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98 #: 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" msgctxt "input"
msgid "Adults aged 17 or older" msgid "Adults aged 17 or older"
msgstr "Adults de 17 anys o més" 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/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71 #: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102 #: 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" msgctxt "input"
msgid "Teenagers from 11 to 16 years old" msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescents dentre 11 i 16 anys" msgstr "Adolescents dentre 11 i 16 anys"
@ -194,7 +194,7 @@ msgstr "Adolescents dentre 11 i 16 anys"
#: web/templates/mail/payment/details.gotxt:24 #: web/templates/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82 #: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106 #: 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" msgctxt "input"
msgid "Children from 2 to 10 years old" msgid "Children from 2 to 10 years old"
msgstr "Nens dentre 2 i 10 anys" msgstr "Nens dentre 2 i 10 anys"
@ -202,14 +202,15 @@ msgstr "Nens dentre 2 i 10 anys"
#: web/templates/mail/payment/details.gotxt:25 #: web/templates/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100 #: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110 #: 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" msgctxt "input"
msgid "Dogs" msgid "Dogs"
msgstr "Gossos" msgstr "Gossos"
#: web/templates/mail/payment/details.gotxt:26 #: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 #: 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" msgctxt "cart"
msgid "Tourist tax" msgid "Tourist tax"
msgstr "Impost turístic" msgstr "Impost turístic"
@ -239,7 +240,7 @@ msgstr "Opcions del tipus dallotjament"
#: web/templates/mail/payment/details.gotxt:39 #: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146 #: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140 #: 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 #: web/templates/admin/booking/fields.gohtml:188
msgctxt "title" msgctxt "title"
msgid "Customer Details" msgid "Customer Details"
@ -248,7 +249,7 @@ msgstr "Detalls del client"
#: web/templates/mail/payment/details.gotxt:41 #: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149 #: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143 #: 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 #: web/templates/admin/booking/fields.gohtml:191
msgctxt "input" msgctxt "input"
msgid "Full name" msgid "Full name"
@ -257,7 +258,7 @@ msgstr "Nom i cognoms"
#: web/templates/mail/payment/details.gotxt:42 #: web/templates/mail/payment/details.gotxt:42
#: web/templates/public/booking/fields.gohtml:158 #: web/templates/public/booking/fields.gohtml:158
#: web/templates/admin/payment/details.gohtml:147 #: 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 #: web/templates/admin/taxDetails.gohtml:69
msgctxt "input" msgctxt "input"
msgid "Address" msgid "Address"
@ -266,7 +267,7 @@ msgstr "Adreça"
#: web/templates/mail/payment/details.gotxt:43 #: web/templates/mail/payment/details.gotxt:43
#: web/templates/public/booking/fields.gohtml:167 #: web/templates/public/booking/fields.gohtml:167
#: web/templates/admin/payment/details.gohtml:151 #: 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 #: web/templates/admin/taxDetails.gohtml:93
msgctxt "input" msgctxt "input"
msgid "Postcode" msgid "Postcode"
@ -282,7 +283,7 @@ msgstr "Població"
#: web/templates/mail/payment/details.gotxt:45 #: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:187 #: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159 #: 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 #: web/templates/admin/taxDetails.gohtml:101
msgctxt "input" msgctxt "input"
msgid "Country" msgid "Country"
@ -423,7 +424,7 @@ msgid "Date"
msgstr "Data" msgstr "Data"
#: web/templates/public/payment/details.gohtml:12 #: 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:63
#: web/templates/admin/invoice/view.gohtml:103 #: web/templates/admin/invoice/view.gohtml:103
msgctxt "title" msgctxt "title"
@ -1019,13 +1020,13 @@ msgid "Campground map"
msgstr "Mapa del càmping" msgstr "Mapa del càmping"
#: web/templates/public/booking/fields.gohtml:176 #: web/templates/public/booking/fields.gohtml:176
#: web/templates/admin/customer/form.gohtml:81 #: web/templates/admin/customer/contact.gohtml:56
msgctxt "input" msgctxt "input"
msgid "Town or village" msgid "Town or village"
msgstr "Població" msgstr "Població"
#: web/templates/public/booking/fields.gohtml:193 #: 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/fields.gohtml:204
#: web/templates/admin/booking/guest.gohtml:111 #: web/templates/admin/booking/guest.gohtml:111
msgid "Choose a country" msgid "Choose a country"
@ -1206,8 +1207,8 @@ msgstr "Contingut"
#: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/form.gohtml:287
#: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/campsite/type/option/form.gohtml:98
#: web/templates/admin/season/form.gohtml:73 #: web/templates/admin/season/form.gohtml:73
#: web/templates/admin/customer/form.gohtml:153 #: web/templates/admin/customer/form.gohtml:34
#: web/templates/admin/invoice/form.gohtml:137 #: web/templates/admin/invoice/form.gohtml:129
#: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/services/form.gohtml:81
#: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/form.gohtml:69
#: web/templates/admin/surroundings/index.gohtml:58 #: web/templates/admin/surroundings/index.gohtml:58
@ -1216,7 +1217,7 @@ msgstr "Contingut"
#: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39 #: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/form.gohtml:45 #: web/templates/admin/booking/form.gohtml:48
msgctxt "action" msgctxt "action"
msgid "Update" msgid "Update"
msgstr "Actualitza" msgstr "Actualitza"
@ -1231,13 +1232,13 @@ msgstr "Actualitza"
#: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/form.gohtml:289
#: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/campsite/type/option/form.gohtml:100
#: web/templates/admin/season/form.gohtml:75 #: 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/services/form.gohtml:83
#: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/surroundings/form.gohtml:71
#: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93 #: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/form.gohtml:47 #: web/templates/admin/booking/form.gohtml:50
msgctxt "action" msgctxt "action"
msgid "Add" msgid "Add"
msgstr "Afegeix" msgstr "Afegeix"
@ -1863,36 +1864,41 @@ msgctxt "title"
msgid "Customer" msgid "Customer"
msgstr "Client" 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 #: web/templates/admin/booking/guest.gohtml:8
msgctxt "input" msgctxt "input"
msgid "ID document number" msgid "ID document number"
msgstr "Número de document didentitat" msgstr "Número de document didentitat"
#: web/templates/admin/customer/form.gohtml:56 #: web/templates/admin/customer/contact.gohtml:31
#: web/templates/admin/booking/guest.gohtml:20 #: web/templates/admin/booking/guest.gohtml:20
msgctxt "input" msgctxt "input"
msgid "ID document type" msgid "ID document type"
msgstr "Tipus de document" 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 #: web/templates/admin/booking/guest.gohtml:25
msgid "Choose an ID document type" msgid "Choose an ID document type"
msgstr "Esculli un tipus de document" 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 #: web/templates/admin/taxDetails.gohtml:85
msgctxt "input" msgctxt "input"
msgid "Province" msgid "Province"
msgstr "Província" msgstr "Província"
#: web/templates/admin/customer/form.gohtml:129 #: web/templates/admin/customer/contact.gohtml:104
#: web/templates/admin/booking/fields.gohtml:239 #: web/templates/admin/booking/fields.gohtml:239
msgctxt "input" msgctxt "input"
msgid "Email (optional)" msgid "Email (optional)"
msgstr "Correu-e (opcional)" 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/fields.gohtml:248
#: web/templates/admin/booking/guest.gohtml:119 #: web/templates/admin/booking/guest.gohtml:119
msgctxt "input" msgctxt "input"
@ -1975,53 +1981,48 @@ msgctxt "title"
msgid "Invoices" msgid "Invoices"
msgstr "Factures" msgstr "Factures"
#: web/templates/admin/invoice/form.gohtml:32 #: web/templates/admin/invoice/form.gohtml:34
msgid "Product “%s” removed" msgid "Product “%s” removed"
msgstr "Sha esborrat el producte «%s»" msgstr "Sha esborrat el producte «%s»"
#: web/templates/admin/invoice/form.gohtml:36 #: web/templates/admin/invoice/form.gohtml:38
msgctxt "action" msgctxt "action"
msgid "Undo" msgid "Undo"
msgstr "Desfes" msgstr "Desfes"
#: web/templates/admin/invoice/form.gohtml:51 #: web/templates/admin/invoice/form.gohtml:53
#: 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
msgctxt "input" msgctxt "input"
msgid "Invoice date" msgid "Invoice date"
msgstr "Data de la factura" 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 #: web/templates/admin/invoice/index.gohtml:51
msgctxt "input" msgctxt "input"
msgid "Invoice status" msgid "Invoice status"
msgstr "Estat de la factura" msgstr "Estat de la factura"
#: web/templates/admin/invoice/form.gohtml:92 #: web/templates/admin/invoice/form.gohtml:81
msgctxt "input" msgctxt "input"
msgid "Notes (optional)" msgid "Notes (optional)"
msgstr "Notes (opcional)" 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 #: web/templates/admin/invoice/view.gohtml:59
msgctxt "title" msgctxt "title"
msgid "Subtotal" msgid "Subtotal"
msgstr "Subtotal" msgstr "Subtotal"
#: web/templates/admin/invoice/form.gohtml:133 #: web/templates/admin/invoice/form.gohtml:125
msgctxt "action" msgctxt "action"
msgid "Add products" msgid "Add products"
msgstr "Afegeix productes" msgstr "Afegeix productes"
#: web/templates/admin/invoice/form.gohtml:140 #: web/templates/admin/invoice/form.gohtml:132
msgctxt "action" msgctxt "action"
msgid "Save" msgid "Save"
msgstr "Desa" msgstr "Desa"
@ -2036,6 +2037,11 @@ msgctxt "action"
msgid "Export list" msgid "Export list"
msgstr "Exporta llista" msgstr "Exporta llista"
#: web/templates/admin/invoice/index.gohtml:39
msgctxt "input"
msgid "Customer"
msgstr "Client"
#: web/templates/admin/invoice/index.gohtml:43 #: web/templates/admin/invoice/index.gohtml:43
msgid "All customers" msgid "All customers"
msgstr "Tots els clients" msgstr "Tots els clients"
@ -2645,7 +2651,8 @@ msgctxt "header"
msgid "Decription" msgid "Decription"
msgstr "Descripció" 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" msgctxt "cart"
msgid "Night" msgid "Night"
msgstr "Nit" msgstr "Nit"
@ -2686,6 +2693,11 @@ msgctxt "action"
msgid "Check-in Booking" msgid "Check-in Booking"
msgstr "Registra la reserva" 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 #: web/templates/admin/booking/checkin.gohtml:6
msgctxt "title" msgctxt "title"
msgid "Check-in Booking" 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/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/types/feature.go:272 pkg/campsite/types/admin.go:577
#: pkg/campsite/feature.go:269 pkg/season/admin.go:411 #: 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/surroundings/admin.go:340 pkg/amenity/feature.go:269
#: pkg/amenity/admin.go:283 #: pkg/amenity/admin.go:283
msgid "Name can not be empty." 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." msgid "Email can not be empty."
msgstr "No podeu deixar el correu-e en blanc." 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/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345
#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 #: 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." 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." 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." 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." 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." msgid "Price can not be empty."
msgstr "No podeu deixar el preu en blanc." 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." msgid "Price must be a decimal number."
msgstr "El preu ha de ser un número decimal." 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." msgid "Price must be zero or greater."
msgstr "El preu ha de ser com a mínim zero." msgstr "El preu ha de ser com a mínim zero."
@ -3092,7 +3104,7 @@ msgctxt "header"
msgid "Children (aged 2 to 10)" msgid "Children (aged 2 to 10)"
msgstr "Mainada (entre 2 i 10 anys)" 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 #: pkg/booking/public.go:232
msgid "Selected campsite type is not valid." msgid "Selected campsite type is not valid."
msgstr "El tipus dallotjament escollit no és vàlid." msgstr "El tipus dallotjament 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." msgid "End date must be a valid date."
msgstr "La data de fi ha de ser una data vàlida." 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 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577
msgid "Selected country is not valid." msgid "Selected country is not valid."
msgstr "El país escollit no és vàlid." 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." msgid "Selected ID document type is not valid."
msgstr "El tipus de document didentitat escollit no és vàlid." msgstr "El tipus de document didentitat 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." msgid "ID document number can not be empty."
msgstr "No podeu deixar el número document didentitat en blanc." msgstr "No podeu deixar el número document didentitat en blanc."
#: pkg/customer/admin.go:300 pkg/booking/checkin.go:288 #: pkg/customer/admin.go:333 pkg/booking/checkin.go:288
#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 #: pkg/booking/checkin.go:289 pkg/booking/admin.go:429
#: pkg/booking/public.go:581 #: pkg/booking/public.go:581
msgid "Full name can not be empty." msgid "Full name can not be empty."
msgstr "No podeu deixar el nom i els cognoms en blanc." 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." msgid "Full name must have at least one letter."
msgstr "El nom i els cognoms han de tenir com a mínim una lletra." 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." msgid "Address can not be empty."
msgstr "No podeu deixar ladreça en blanc." msgstr "No podeu deixar ladreç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." msgid "Town or village can not be empty."
msgstr "No podeu deixar la població en blanc." 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." msgid "Postcode can not be empty."
msgstr "No podeu deixar el codi postal en blanc." 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 #: pkg/booking/public.go:588
msgid "This postcode is not valid." msgid "This postcode is not valid."
msgstr "Aquest codi postal no és vàlid." msgstr "Aquest codi postal no és vàlid."
#: pkg/customer/admin.go:315 pkg/company/admin.go:220 #: pkg/customer/admin.go:348 pkg/company/admin.go:220
#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 #: pkg/booking/checkin.go:301 pkg/booking/admin.go:446
#: pkg/booking/public.go:596 #: pkg/booking/public.go:596
msgid "This phone number is not valid." msgid "This phone number is not valid."
msgstr "Aquest número de telèfon no és vàlid." msgstr "Aquest número de telèfon no és vàlid."
#: pkg/invoice/admin.go:649 #: pkg/invoice/admin.go:681
msgctxt "filename" msgctxt "filename"
msgid "invoices.zip" msgid "invoices.zip"
msgstr "factures.zip" msgstr "factures.zip"
#: pkg/invoice/admin.go:664 #: pkg/invoice/admin.go:696
msgctxt "filename" msgctxt "filename"
msgid "invoices.ods" msgid "invoices.ods"
msgstr "factures.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" msgid "Invalid action"
msgstr "Acció invàlida" msgstr "Acció invàlida"
#: pkg/invoice/admin.go:830 #: pkg/invoice/admin.go:863
msgid "Selected invoice status is not valid." msgid "Selected invoice status is not valid."
msgstr "Lestat de factura escollit no és vàlid." msgstr "Lestat de factura escollit no és vàlid."
#: pkg/invoice/admin.go:831 #: pkg/invoice/admin.go:864
msgid "Selected customer is not valid."
msgstr "El client escollit no és vàlid."
#: pkg/invoice/admin.go:832
msgid "Invoice date can not be empty." msgid "Invoice date can not be empty."
msgstr "No podeu deixar la data de factura en blanc." 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." msgid "Invoice date must be a valid date."
msgstr "La data de factura ha de ser una data vàlida." msgstr "La data de factura ha de ser una data vàlida."
#: pkg/invoice/admin.go:980 #: pkg/invoice/admin.go:1023
#, c-format #, c-format
msgid "Re: quotation #%s of %s" msgid "Re: booking #%s of %s%s"
msgstr "" msgstr "Ref: reserva núm. %s del %s-%s"
#: pkg/invoice/admin.go:981 #: pkg/invoice/admin.go:1024
msgctxt "to_char" msgctxt "to_char"
msgid "MM/DD/YYYY" msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY" msgstr "DD/MM/YYYY"
#: pkg/invoice/admin.go:1083 #: pkg/invoice/admin.go:1151
msgid "Invoice product ID must be an integer." msgid "Invoice product ID must be an integer."
msgstr "LID de producte de factura ha de ser enter." msgstr "LID 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." msgid "Invoice product ID one or greater."
msgstr "LID de producte de factura ha de ser com a mínim u." msgstr "LID 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." msgid "Product ID must be an integer."
msgstr "LID de producte ha de ser un número enter." msgstr "LID 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." msgid "Product ID must zero or greater."
msgstr "LID de producte ha de ser com a mínim zero." msgstr "LID 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." msgid "Quantity can not be empty."
msgstr "No podeu deixar la quantitat en blanc." msgstr "No podeu deixar la quantitat en blanc."
#: pkg/invoice/admin.go:1099 #: pkg/invoice/admin.go:1167
msgid "Quantity must be an integer." msgid "Quantity must be an integer."
msgstr "La quantitat ha de ser un número enter." 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." msgid "Quantity must one or greater."
msgstr "La quantitat ha de ser com a mínim u." 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." msgid "Discount can not be empty."
msgstr "No podeu deixar el descompte en blanc." msgstr "No podeu deixar el descompte en blanc."
#: pkg/invoice/admin.go:1104 #: pkg/invoice/admin.go:1172
msgid "Discount must be an integer." msgid "Discount must be an integer."
msgstr "El descompte ha de ser un número enter." 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." msgid "Discount must be a percentage between 0 and 100."
msgstr "El descompte ha de ser un percentatge entre 0 i 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." msgid "Selected tax is not valid."
msgstr "Limpost escollit no és vàlid." msgstr "Limpost escollit no és vàlid."
@ -3444,19 +3452,19 @@ msgctxt "filename"
msgid "bookings.ods" msgid "bookings.ods"
msgstr "reserves.ods" msgstr "reserves.ods"
#: pkg/booking/admin.go:432 #: pkg/booking/admin.go:435
msgid "Country can not be empty to validate the postcode." msgid "Country can not be empty to validate the postcode."
msgstr "No podeu deixar el país en blanc per validar el codi postal." 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." msgid "Country can not be empty to validate the phone."
msgstr "No podeu deixar el país en blanc per validar el telèfon." 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." msgid "You must select at least one accommodation."
msgstr "Heu descollir com a mínim un allotjament." msgstr "Heu descollir 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." msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Els allotjaments escollits no estan disponibles a les dates demanades." 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." msgid "It is mandatory to agree to the reservation conditions."
msgstr "És obligatori acceptar les condicions de reserves." 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" #~ msgctxt "title"
#~ msgid "Accomodations" #~ msgid "Accomodations"
#~ msgstr "Allotjaments" #~ msgstr "Allotjaments"

198
po/es.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: camper\n" "Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\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" "PO-Revision-Date: 2024-02-06 10:04+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n" "Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n" "Language-Team: Spanish <es@tp.org.es>\n"
@ -178,7 +178,7 @@ msgstr "Noches"
#: web/templates/mail/payment/details.gotxt:22 #: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60 #: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98 #: 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" msgctxt "input"
msgid "Adults aged 17 or older" msgid "Adults aged 17 or older"
msgstr "Adultos de 17 años o más" 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/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71 #: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102 #: 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" msgctxt "input"
msgid "Teenagers from 11 to 16 years old" msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescentes de 11 a 16 años" 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/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82 #: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106 #: 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" msgctxt "input"
msgid "Children from 2 to 10 years old" msgid "Children from 2 to 10 years old"
msgstr "Niños de 2 a 10 años" 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/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100 #: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110 #: 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" msgctxt "input"
msgid "Dogs" msgid "Dogs"
msgstr "Perros" msgstr "Perros"
#: web/templates/mail/payment/details.gotxt:26 #: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 #: 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" msgctxt "cart"
msgid "Tourist tax" msgid "Tourist tax"
msgstr "Impuesto turístico" msgstr "Impuesto turístico"
@ -239,7 +240,7 @@ msgstr "Opciones del tipo de alojamiento"
#: web/templates/mail/payment/details.gotxt:39 #: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146 #: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140 #: 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 #: web/templates/admin/booking/fields.gohtml:188
msgctxt "title" msgctxt "title"
msgid "Customer Details" msgid "Customer Details"
@ -248,7 +249,7 @@ msgstr "Detalles del cliente"
#: web/templates/mail/payment/details.gotxt:41 #: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149 #: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143 #: 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 #: web/templates/admin/booking/fields.gohtml:191
msgctxt "input" msgctxt "input"
msgid "Full name" msgid "Full name"
@ -257,7 +258,7 @@ msgstr "Nombre y apellidos"
#: web/templates/mail/payment/details.gotxt:42 #: web/templates/mail/payment/details.gotxt:42
#: web/templates/public/booking/fields.gohtml:158 #: web/templates/public/booking/fields.gohtml:158
#: web/templates/admin/payment/details.gohtml:147 #: 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 #: web/templates/admin/taxDetails.gohtml:69
msgctxt "input" msgctxt "input"
msgid "Address" msgid "Address"
@ -266,7 +267,7 @@ msgstr "Dirección"
#: web/templates/mail/payment/details.gotxt:43 #: web/templates/mail/payment/details.gotxt:43
#: web/templates/public/booking/fields.gohtml:167 #: web/templates/public/booking/fields.gohtml:167
#: web/templates/admin/payment/details.gohtml:151 #: 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 #: web/templates/admin/taxDetails.gohtml:93
msgctxt "input" msgctxt "input"
msgid "Postcode" msgid "Postcode"
@ -282,7 +283,7 @@ msgstr "Población"
#: web/templates/mail/payment/details.gotxt:45 #: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:187 #: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159 #: 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 #: web/templates/admin/taxDetails.gohtml:101
msgctxt "input" msgctxt "input"
msgid "Country" msgid "Country"
@ -423,7 +424,7 @@ msgid "Date"
msgstr "Fecha" msgstr "Fecha"
#: web/templates/public/payment/details.gohtml:12 #: 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:63
#: web/templates/admin/invoice/view.gohtml:103 #: web/templates/admin/invoice/view.gohtml:103
msgctxt "title" msgctxt "title"
@ -1019,13 +1020,13 @@ msgid "Campground map"
msgstr "Mapa del camping" msgstr "Mapa del camping"
#: web/templates/public/booking/fields.gohtml:176 #: web/templates/public/booking/fields.gohtml:176
#: web/templates/admin/customer/form.gohtml:81 #: web/templates/admin/customer/contact.gohtml:56
msgctxt "input" msgctxt "input"
msgid "Town or village" msgid "Town or village"
msgstr "Población" msgstr "Población"
#: web/templates/public/booking/fields.gohtml:193 #: 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/fields.gohtml:204
#: web/templates/admin/booking/guest.gohtml:111 #: web/templates/admin/booking/guest.gohtml:111
msgid "Choose a country" msgid "Choose a country"
@ -1206,8 +1207,8 @@ msgstr "Contenido"
#: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/form.gohtml:287
#: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/campsite/type/option/form.gohtml:98
#: web/templates/admin/season/form.gohtml:73 #: web/templates/admin/season/form.gohtml:73
#: web/templates/admin/customer/form.gohtml:153 #: web/templates/admin/customer/form.gohtml:34
#: web/templates/admin/invoice/form.gohtml:137 #: web/templates/admin/invoice/form.gohtml:129
#: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/services/form.gohtml:81
#: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/form.gohtml:69
#: web/templates/admin/surroundings/index.gohtml:58 #: web/templates/admin/surroundings/index.gohtml:58
@ -1216,7 +1217,7 @@ msgstr "Contenido"
#: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39 #: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/form.gohtml:45 #: web/templates/admin/booking/form.gohtml:48
msgctxt "action" msgctxt "action"
msgid "Update" msgid "Update"
msgstr "Actualizar" msgstr "Actualizar"
@ -1231,13 +1232,13 @@ msgstr "Actualizar"
#: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/form.gohtml:289
#: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/campsite/type/option/form.gohtml:100
#: web/templates/admin/season/form.gohtml:75 #: 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/services/form.gohtml:83
#: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/surroundings/form.gohtml:71
#: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93 #: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/form.gohtml:47 #: web/templates/admin/booking/form.gohtml:50
msgctxt "action" msgctxt "action"
msgid "Add" msgid "Add"
msgstr "Añadir" msgstr "Añadir"
@ -1863,36 +1864,41 @@ msgctxt "title"
msgid "Customer" msgid "Customer"
msgstr "Cliente" 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 #: web/templates/admin/booking/guest.gohtml:8
msgctxt "input" msgctxt "input"
msgid "ID document number" msgid "ID document number"
msgstr "Número de documento de identidad" 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 #: web/templates/admin/booking/guest.gohtml:20
msgctxt "input" msgctxt "input"
msgid "ID document type" msgid "ID document type"
msgstr "Tipo de documento" 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 #: web/templates/admin/booking/guest.gohtml:25
msgid "Choose an ID document type" msgid "Choose an ID document type"
msgstr "Escoja un tipo de documento" 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 #: web/templates/admin/taxDetails.gohtml:85
msgctxt "input" msgctxt "input"
msgid "Province" msgid "Province"
msgstr "Provincia" msgstr "Provincia"
#: web/templates/admin/customer/form.gohtml:129 #: web/templates/admin/customer/contact.gohtml:104
#: web/templates/admin/booking/fields.gohtml:239 #: web/templates/admin/booking/fields.gohtml:239
msgctxt "input" msgctxt "input"
msgid "Email (optional)" msgid "Email (optional)"
msgstr "Correo-e (opcional)" 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/fields.gohtml:248
#: web/templates/admin/booking/guest.gohtml:119 #: web/templates/admin/booking/guest.gohtml:119
msgctxt "input" msgctxt "input"
@ -1975,53 +1981,48 @@ msgctxt "title"
msgid "Invoices" msgid "Invoices"
msgstr "Facturas" msgstr "Facturas"
#: web/templates/admin/invoice/form.gohtml:32 #: web/templates/admin/invoice/form.gohtml:34
msgid "Product “%s” removed" msgid "Product “%s” removed"
msgstr "Se ha borrado el producto «%s»" msgstr "Se ha borrado el producto «%s»"
#: web/templates/admin/invoice/form.gohtml:36 #: web/templates/admin/invoice/form.gohtml:38
msgctxt "action" msgctxt "action"
msgid "Undo" msgid "Undo"
msgstr "Deshacer" msgstr "Deshacer"
#: web/templates/admin/invoice/form.gohtml:51 #: web/templates/admin/invoice/form.gohtml:53
#: 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
msgctxt "input" msgctxt "input"
msgid "Invoice date" msgid "Invoice date"
msgstr "Fecha de la factura" 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 #: web/templates/admin/invoice/index.gohtml:51
msgctxt "input" msgctxt "input"
msgid "Invoice status" msgid "Invoice status"
msgstr "Estado de factura" msgstr "Estado de factura"
#: web/templates/admin/invoice/form.gohtml:92 #: web/templates/admin/invoice/form.gohtml:81
msgctxt "input" msgctxt "input"
msgid "Notes (optional)" msgid "Notes (optional)"
msgstr "Notas (opcional)" 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 #: web/templates/admin/invoice/view.gohtml:59
msgctxt "title" msgctxt "title"
msgid "Subtotal" msgid "Subtotal"
msgstr "Subtotal" msgstr "Subtotal"
#: web/templates/admin/invoice/form.gohtml:133 #: web/templates/admin/invoice/form.gohtml:125
msgctxt "action" msgctxt "action"
msgid "Add products" msgid "Add products"
msgstr "Añadir productos" msgstr "Añadir productos"
#: web/templates/admin/invoice/form.gohtml:140 #: web/templates/admin/invoice/form.gohtml:132
msgctxt "action" msgctxt "action"
msgid "Save" msgid "Save"
msgstr "Guardar" msgstr "Guardar"
@ -2036,6 +2037,11 @@ msgctxt "action"
msgid "Export list" msgid "Export list"
msgstr "Exportar lista" msgstr "Exportar lista"
#: web/templates/admin/invoice/index.gohtml:39
msgctxt "input"
msgid "Customer"
msgstr "Cliente"
#: web/templates/admin/invoice/index.gohtml:43 #: web/templates/admin/invoice/index.gohtml:43
msgid "All customers" msgid "All customers"
msgstr "Todos los clientes" msgstr "Todos los clientes"
@ -2645,7 +2651,8 @@ msgctxt "header"
msgid "Decription" msgid "Decription"
msgstr "Descripción" 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" msgctxt "cart"
msgid "Night" msgid "Night"
msgstr "Noche" msgstr "Noche"
@ -2686,6 +2693,11 @@ msgctxt "action"
msgid "Check-in Booking" msgid "Check-in Booking"
msgstr "Registrar reserva" 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 #: web/templates/admin/booking/checkin.gohtml:6
msgctxt "title" msgctxt "title"
msgid "Check-in Booking" 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/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/types/feature.go:272 pkg/campsite/types/admin.go:577
#: pkg/campsite/feature.go:269 pkg/season/admin.go:411 #: 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/surroundings/admin.go:340 pkg/amenity/feature.go:269
#: pkg/amenity/admin.go:283 #: pkg/amenity/admin.go:283
msgid "Name can not be empty." 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." msgid "Email can not be empty."
msgstr "No podéis dejar el correo-e en blanco." 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/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345
#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 #: 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." 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." 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." 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." 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." msgid "Price can not be empty."
msgstr "No podéis dejar el precio en blanco." 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." msgid "Price must be a decimal number."
msgstr "El precio tiene que ser un número decimal." 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." msgid "Price must be zero or greater."
msgstr "El precio tiene que ser como mínimo cero." msgstr "El precio tiene que ser como mínimo cero."
@ -3092,7 +3104,7 @@ msgctxt "header"
msgid "Children (aged 2 to 10)" msgid "Children (aged 2 to 10)"
msgstr "Niños (de 2 a 10 años)" 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 #: pkg/booking/public.go:232
msgid "Selected campsite type is not valid." msgid "Selected campsite type is not valid."
msgstr "El tipo de alojamiento escogido no es válido." 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." msgid "End date must be a valid date."
msgstr "La fecha final tiene que ser una fecha válida." 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 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577
msgid "Selected country is not valid." msgid "Selected country is not valid."
msgstr "El país escogido no es válido." 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." msgid "Selected ID document type is not valid."
msgstr "El tipo de documento de identidad escogido no es válido." 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." msgid "ID document number can not be empty."
msgstr "No podéis dejar el número del documento de identidad en blanco." 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/customer/admin.go:333 pkg/booking/checkin.go:288
#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 #: pkg/booking/checkin.go:289 pkg/booking/admin.go:429
#: pkg/booking/public.go:581 #: pkg/booking/public.go:581
msgid "Full name can not be empty." msgid "Full name can not be empty."
msgstr "No podéis dejar el nombre y los apellidos en blanco." 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." msgid "Full name must have at least one letter."
msgstr "El nombre y los apellidos tienen que tener como mínimo una letra." 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." msgid "Address can not be empty."
msgstr "No podéis dejar la dirección en blanco." 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." msgid "Town or village can not be empty."
msgstr "No podéis dejar la población en blanco." 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." msgid "Postcode can not be empty."
msgstr "No podéis dejar el código postal en blanco." 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 #: pkg/booking/public.go:588
msgid "This postcode is not valid." msgid "This postcode is not valid."
msgstr "Este código postal no es válido." msgstr "Este código postal no es válido."
#: pkg/customer/admin.go:315 pkg/company/admin.go:220 #: pkg/customer/admin.go:348 pkg/company/admin.go:220
#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 #: pkg/booking/checkin.go:301 pkg/booking/admin.go:446
#: pkg/booking/public.go:596 #: pkg/booking/public.go:596
msgid "This phone number is not valid." msgid "This phone number is not valid."
msgstr "Este teléfono no es válido." msgstr "Este teléfono no es válido."
#: pkg/invoice/admin.go:649 #: pkg/invoice/admin.go:681
msgctxt "filename" msgctxt "filename"
msgid "invoices.zip" msgid "invoices.zip"
msgstr "facturas.zip" msgstr "facturas.zip"
#: pkg/invoice/admin.go:664 #: pkg/invoice/admin.go:696
msgctxt "filename" msgctxt "filename"
msgid "invoices.ods" msgid "invoices.ods"
msgstr "facturas.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" msgid "Invalid action"
msgstr "Acción inválida" msgstr "Acción inválida"
#: pkg/invoice/admin.go:830 #: pkg/invoice/admin.go:863
msgid "Selected invoice status is not valid." msgid "Selected invoice status is not valid."
msgstr "El estado de factura escogida no es válido." msgstr "El estado de factura escogida no es válido."
#: pkg/invoice/admin.go:831 #: pkg/invoice/admin.go:864
msgid "Selected customer is not valid."
msgstr "El cliente escogido no es válido."
#: pkg/invoice/admin.go:832
msgid "Invoice date can not be empty." msgid "Invoice date can not be empty."
msgstr "No podéis dejar la fecha de factura en blanco." 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." msgid "Invoice date must be a valid date."
msgstr "La fecha de factura tiene que ser una fecha válida." msgstr "La fecha de factura tiene que ser una fecha válida."
#: pkg/invoice/admin.go:980 #: pkg/invoice/admin.go:1023
#, c-format #, c-format
msgid "Re: quotation #%s of %s" msgid "Re: booking #%s of %s%s"
msgstr "" msgstr "Ref.: reserva núm. %s del %s%s"
#: pkg/invoice/admin.go:981 #: pkg/invoice/admin.go:1024
msgctxt "to_char" msgctxt "to_char"
msgid "MM/DD/YYYY" msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY" msgstr "DD/MM/YYYY"
#: pkg/invoice/admin.go:1083 #: pkg/invoice/admin.go:1151
msgid "Invoice product ID must be an integer." msgid "Invoice product ID must be an integer."
msgstr "El ID de producto de factura tiene que ser entero." 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." msgid "Invoice product ID one or greater."
msgstr "El ID de producto de factura tiene que ser como mínimo uno." 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." msgid "Product ID must be an integer."
msgstr "El ID de producto tiene que ser un número entero." 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." msgid "Product ID must zero or greater."
msgstr "El ID de producto tiene que ser como mínimo cero." 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." msgid "Quantity can not be empty."
msgstr "No podéis dejar la cantidad en blanco." 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." msgid "Quantity must be an integer."
msgstr "La cantidad tiene que ser un número entero." 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." msgid "Quantity must one or greater."
msgstr "La cantidad tiene que ser como mínimo uno." 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." msgid "Discount can not be empty."
msgstr "No podéis dejar el descuento en blanco." 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." msgid "Discount must be an integer."
msgstr "El descuento tiene que ser un número entero." 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." msgid "Discount must be a percentage between 0 and 100."
msgstr "El descuento tiene que ser un porcentaje entre 1 y 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." msgid "Selected tax is not valid."
msgstr "El impuesto escogido no es válido." msgstr "El impuesto escogido no es válido."
@ -3444,19 +3452,19 @@ msgctxt "filename"
msgid "bookings.ods" msgid "bookings.ods"
msgstr "reservas.ods" msgstr "reservas.ods"
#: pkg/booking/admin.go:432 #: pkg/booking/admin.go:435
msgid "Country can not be empty to validate the postcode." 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." 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." 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." 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." msgid "You must select at least one accommodation."
msgstr "Tenéis que seleccionar como mínimo un alojamiento." 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." msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Los alojamientos seleccionados no tienen disponibilidad en las fechas pedidas." 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." msgid "It is mandatory to agree to the reservation conditions."
msgstr "Es obligatorio aceptar las condiciones de reserva." 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" #~ msgctxt "title"
#~ msgid "Accomodations" #~ msgid "Accomodations"
#~ msgstr "Alojamientos" #~ msgstr "Alojamientos"

198
po/fr.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: camper\n" "Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\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" "PO-Revision-Date: 2024-02-06 10:05+0100\n"
"Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n" "Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n"
"Language-Team: French <traduc@traduc.org>\n" "Language-Team: French <traduc@traduc.org>\n"
@ -178,7 +178,7 @@ msgstr "Nuits"
#: web/templates/mail/payment/details.gotxt:22 #: web/templates/mail/payment/details.gotxt:22
#: web/templates/public/booking/fields.gohtml:60 #: web/templates/public/booking/fields.gohtml:60
#: web/templates/admin/payment/details.gohtml:98 #: 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" msgctxt "input"
msgid "Adults aged 17 or older" msgid "Adults aged 17 or older"
msgstr "Adultes âgés 17 ans ou plus" 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/mail/payment/details.gotxt:23
#: web/templates/public/booking/fields.gohtml:71 #: web/templates/public/booking/fields.gohtml:71
#: web/templates/admin/payment/details.gohtml:102 #: 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" msgctxt "input"
msgid "Teenagers from 11 to 16 years old" msgid "Teenagers from 11 to 16 years old"
msgstr "Adolescents de 11 à 16 ans" 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/mail/payment/details.gotxt:24
#: web/templates/public/booking/fields.gohtml:82 #: web/templates/public/booking/fields.gohtml:82
#: web/templates/admin/payment/details.gohtml:106 #: 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" msgctxt "input"
msgid "Children from 2 to 10 years old" msgid "Children from 2 to 10 years old"
msgstr "Enfants de 2 à 10 ans" 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/mail/payment/details.gotxt:25
#: web/templates/public/booking/fields.gohtml:100 #: web/templates/public/booking/fields.gohtml:100
#: web/templates/admin/payment/details.gohtml:110 #: 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" msgctxt "input"
msgid "Dogs" msgid "Dogs"
msgstr "Chiens" msgstr "Chiens"
#: web/templates/mail/payment/details.gotxt:26 #: web/templates/mail/payment/details.gotxt:26
#: web/templates/admin/payment/details.gohtml:114 #: 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" msgctxt "cart"
msgid "Tourist tax" msgid "Tourist tax"
msgstr "Taxe touristique" msgstr "Taxe touristique"
@ -239,7 +240,7 @@ msgstr "Options de type demplacement de camping"
#: web/templates/mail/payment/details.gotxt:39 #: web/templates/mail/payment/details.gotxt:39
#: web/templates/public/booking/fields.gohtml:146 #: web/templates/public/booking/fields.gohtml:146
#: web/templates/admin/payment/details.gohtml:140 #: 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 #: web/templates/admin/booking/fields.gohtml:188
msgctxt "title" msgctxt "title"
msgid "Customer Details" msgid "Customer Details"
@ -248,7 +249,7 @@ msgstr "Détails du client"
#: web/templates/mail/payment/details.gotxt:41 #: web/templates/mail/payment/details.gotxt:41
#: web/templates/public/booking/fields.gohtml:149 #: web/templates/public/booking/fields.gohtml:149
#: web/templates/admin/payment/details.gohtml:143 #: 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 #: web/templates/admin/booking/fields.gohtml:191
msgctxt "input" msgctxt "input"
msgid "Full name" msgid "Full name"
@ -257,7 +258,7 @@ msgstr "Nom et prénom"
#: web/templates/mail/payment/details.gotxt:42 #: web/templates/mail/payment/details.gotxt:42
#: web/templates/public/booking/fields.gohtml:158 #: web/templates/public/booking/fields.gohtml:158
#: web/templates/admin/payment/details.gohtml:147 #: 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 #: web/templates/admin/taxDetails.gohtml:69
msgctxt "input" msgctxt "input"
msgid "Address" msgid "Address"
@ -266,7 +267,7 @@ msgstr "Adresse"
#: web/templates/mail/payment/details.gotxt:43 #: web/templates/mail/payment/details.gotxt:43
#: web/templates/public/booking/fields.gohtml:167 #: web/templates/public/booking/fields.gohtml:167
#: web/templates/admin/payment/details.gohtml:151 #: 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 #: web/templates/admin/taxDetails.gohtml:93
msgctxt "input" msgctxt "input"
msgid "Postcode" msgid "Postcode"
@ -282,7 +283,7 @@ msgstr "Ville"
#: web/templates/mail/payment/details.gotxt:45 #: web/templates/mail/payment/details.gotxt:45
#: web/templates/public/booking/fields.gohtml:187 #: web/templates/public/booking/fields.gohtml:187
#: web/templates/admin/payment/details.gohtml:159 #: 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 #: web/templates/admin/taxDetails.gohtml:101
msgctxt "input" msgctxt "input"
msgid "Country" msgid "Country"
@ -423,7 +424,7 @@ msgid "Date"
msgstr "Date" msgstr "Date"
#: web/templates/public/payment/details.gohtml:12 #: 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:63
#: web/templates/admin/invoice/view.gohtml:103 #: web/templates/admin/invoice/view.gohtml:103
msgctxt "title" msgctxt "title"
@ -1019,13 +1020,13 @@ msgid "Campground map"
msgstr "Plan du camping" msgstr "Plan du camping"
#: web/templates/public/booking/fields.gohtml:176 #: web/templates/public/booking/fields.gohtml:176
#: web/templates/admin/customer/form.gohtml:81 #: web/templates/admin/customer/contact.gohtml:56
msgctxt "input" msgctxt "input"
msgid "Town or village" msgid "Town or village"
msgstr "Ville" msgstr "Ville"
#: web/templates/public/booking/fields.gohtml:193 #: 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/fields.gohtml:204
#: web/templates/admin/booking/guest.gohtml:111 #: web/templates/admin/booking/guest.gohtml:111
msgid "Choose a country" msgid "Choose a country"
@ -1206,8 +1207,8 @@ msgstr "Contenu"
#: web/templates/admin/campsite/type/form.gohtml:287 #: web/templates/admin/campsite/type/form.gohtml:287
#: web/templates/admin/campsite/type/option/form.gohtml:98 #: web/templates/admin/campsite/type/option/form.gohtml:98
#: web/templates/admin/season/form.gohtml:73 #: web/templates/admin/season/form.gohtml:73
#: web/templates/admin/customer/form.gohtml:153 #: web/templates/admin/customer/form.gohtml:34
#: web/templates/admin/invoice/form.gohtml:137 #: web/templates/admin/invoice/form.gohtml:129
#: web/templates/admin/services/form.gohtml:81 #: web/templates/admin/services/form.gohtml:81
#: web/templates/admin/surroundings/form.gohtml:69 #: web/templates/admin/surroundings/form.gohtml:69
#: web/templates/admin/surroundings/index.gohtml:58 #: web/templates/admin/surroundings/index.gohtml:58
@ -1216,7 +1217,7 @@ msgstr "Contenu"
#: web/templates/admin/amenity/form.gohtml:91 #: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34 #: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39 #: web/templates/admin/media/form.gohtml:39
#: web/templates/admin/booking/form.gohtml:45 #: web/templates/admin/booking/form.gohtml:48
msgctxt "action" msgctxt "action"
msgid "Update" msgid "Update"
msgstr "Mettre à jour" msgstr "Mettre à jour"
@ -1231,13 +1232,13 @@ msgstr "Mettre à jour"
#: web/templates/admin/campsite/type/form.gohtml:289 #: web/templates/admin/campsite/type/form.gohtml:289
#: web/templates/admin/campsite/type/option/form.gohtml:100 #: web/templates/admin/campsite/type/option/form.gohtml:100
#: web/templates/admin/season/form.gohtml:75 #: 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/services/form.gohtml:83
#: web/templates/admin/surroundings/form.gohtml:71 #: web/templates/admin/surroundings/form.gohtml:71
#: web/templates/admin/amenity/feature/form.gohtml:67 #: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52 #: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93 #: web/templates/admin/amenity/form.gohtml:93
#: web/templates/admin/booking/form.gohtml:47 #: web/templates/admin/booking/form.gohtml:50
msgctxt "action" msgctxt "action"
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
@ -1863,36 +1864,41 @@ msgctxt "title"
msgid "Customer" msgid "Customer"
msgstr "Client" 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 #: web/templates/admin/booking/guest.gohtml:8
msgctxt "input" msgctxt "input"
msgid "ID document number" msgid "ID document number"
msgstr "Numéro de document didentité" msgstr "Numéro de document didentité"
#: web/templates/admin/customer/form.gohtml:56 #: web/templates/admin/customer/contact.gohtml:31
#: web/templates/admin/booking/guest.gohtml:20 #: web/templates/admin/booking/guest.gohtml:20
msgctxt "input" msgctxt "input"
msgid "ID document type" msgid "ID document type"
msgstr "Type de document didentité" msgstr "Type de document didentité"
#: web/templates/admin/customer/form.gohtml:61 #: web/templates/admin/customer/contact.gohtml:36
#: web/templates/admin/booking/guest.gohtml:25 #: web/templates/admin/booking/guest.gohtml:25
msgid "Choose an ID document type" msgid "Choose an ID document type"
msgstr "Choisissez un type de document didentité" msgstr "Choisissez un type de document didentité"
#: web/templates/admin/customer/form.gohtml:93 #: web/templates/admin/customer/contact.gohtml:68
#: web/templates/admin/taxDetails.gohtml:85 #: web/templates/admin/taxDetails.gohtml:85
msgctxt "input" msgctxt "input"
msgid "Province" msgid "Province"
msgstr "Province" msgstr "Province"
#: web/templates/admin/customer/form.gohtml:129 #: web/templates/admin/customer/contact.gohtml:104
#: web/templates/admin/booking/fields.gohtml:239 #: web/templates/admin/booking/fields.gohtml:239
msgctxt "input" msgctxt "input"
msgid "Email (optional)" msgid "Email (optional)"
msgstr "E-mail (facultatif)" 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/fields.gohtml:248
#: web/templates/admin/booking/guest.gohtml:119 #: web/templates/admin/booking/guest.gohtml:119
msgctxt "input" msgctxt "input"
@ -1975,53 +1981,48 @@ msgctxt "title"
msgid "Invoices" msgid "Invoices"
msgstr "Factures" msgstr "Factures"
#: web/templates/admin/invoice/form.gohtml:32 #: web/templates/admin/invoice/form.gohtml:34
msgid "Product “%s” removed" msgid "Product “%s” removed"
msgstr "Produit «%s» supprimé" msgstr "Produit «%s» supprimé"
#: web/templates/admin/invoice/form.gohtml:36 #: web/templates/admin/invoice/form.gohtml:38
msgctxt "action" msgctxt "action"
msgid "Undo" msgid "Undo"
msgstr "Annuler" msgstr "Annuler"
#: web/templates/admin/invoice/form.gohtml:51 #: web/templates/admin/invoice/form.gohtml:53
#: 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
msgctxt "input" msgctxt "input"
msgid "Invoice date" msgid "Invoice date"
msgstr "Date de facture" 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 #: web/templates/admin/invoice/index.gohtml:51
msgctxt "input" msgctxt "input"
msgid "Invoice status" msgid "Invoice status"
msgstr "Statut de la facture" msgstr "Statut de la facture"
#: web/templates/admin/invoice/form.gohtml:92 #: web/templates/admin/invoice/form.gohtml:81
msgctxt "input" msgctxt "input"
msgid "Notes (optional)" msgid "Notes (optional)"
msgstr "Remarques (facultatif)" 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 #: web/templates/admin/invoice/view.gohtml:59
msgctxt "title" msgctxt "title"
msgid "Subtotal" msgid "Subtotal"
msgstr "Sous-totale" msgstr "Sous-totale"
#: web/templates/admin/invoice/form.gohtml:133 #: web/templates/admin/invoice/form.gohtml:125
msgctxt "action" msgctxt "action"
msgid "Add products" msgid "Add products"
msgstr "Ajouter des produits" msgstr "Ajouter des produits"
#: web/templates/admin/invoice/form.gohtml:140 #: web/templates/admin/invoice/form.gohtml:132
msgctxt "action" msgctxt "action"
msgid "Save" msgid "Save"
msgstr "Enregistrer" msgstr "Enregistrer"
@ -2036,6 +2037,11 @@ msgctxt "action"
msgid "Export list" msgid "Export list"
msgstr "Exporter la liste" msgstr "Exporter la liste"
#: web/templates/admin/invoice/index.gohtml:39
msgctxt "input"
msgid "Customer"
msgstr "Client"
#: web/templates/admin/invoice/index.gohtml:43 #: web/templates/admin/invoice/index.gohtml:43
msgid "All customers" msgid "All customers"
msgstr "Tous les clients" msgstr "Tous les clients"
@ -2645,7 +2651,8 @@ msgctxt "header"
msgid "Decription" msgid "Decription"
msgstr "Description" 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" msgctxt "cart"
msgid "Night" msgid "Night"
msgstr "Nuit" msgstr "Nuit"
@ -2686,6 +2693,11 @@ msgctxt "action"
msgid "Check-in Booking" msgid "Check-in Booking"
msgstr "Enregistrer réservation" 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 #: web/templates/admin/booking/checkin.gohtml:6
msgctxt "title" msgctxt "title"
msgid "Check-in Booking" 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/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/types/feature.go:272 pkg/campsite/types/admin.go:577
#: pkg/campsite/feature.go:269 pkg/season/admin.go:411 #: 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/surroundings/admin.go:340 pkg/amenity/feature.go:269
#: pkg/amenity/admin.go:283 #: pkg/amenity/admin.go:283
msgid "Name can not be empty." msgid "Name can not be empty."
@ -2880,8 +2892,8 @@ msgstr "Limage de la diapositive doit être de type média dimage."
msgid "Email can not be empty." msgid "Email can not be empty."
msgstr "Le-mail ne peut pas être vide." msgstr "Le-mail ne peut pas être vide."
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:312 #: pkg/app/login.go:57 pkg/app/user.go:247 pkg/customer/admin.go:345
#: pkg/company/admin.go:225 pkg/booking/admin.go:438 pkg/booking/public.go:593 #: 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." msgid "This email is not valid. It should be like name@domain.com."
msgstr "Cette adresse e-mail nest pas valide. Il devrait en être name@domain.com." msgstr "Cette adresse e-mail nest 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." msgid "Maximum must be equal or greater than minimum."
msgstr "Le maximum doit être égal ou supérieur au 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." msgid "Price can not be empty."
msgstr "Le prix ne peut pas être vide." 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." msgid "Price must be a decimal number."
msgstr "Le prix doit être un nombre décimal." 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." msgid "Price must be zero or greater."
msgstr "Le prix doit être égal ou supérieur à zéro." msgstr "Le prix doit être égal ou supérieur à zéro."
@ -3092,7 +3104,7 @@ msgctxt "header"
msgid "Children (aged 2 to 10)" msgid "Children (aged 2 to 10)"
msgstr "Enfants (de 2 à 10 anys)" 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 #: pkg/booking/public.go:232
msgid "Selected campsite type is not valid." msgid "Selected campsite type is not valid."
msgstr "Le type demplacement sélectionné nest pas valide." msgstr "Le type demplacement sélectionné nest pas valide."
@ -3130,133 +3142,129 @@ msgstr "La date de fin ne peut pas être vide."
msgid "End date must be a valid date." msgid "End date must be a valid date."
msgstr "La date de fin doit être une date valide." 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 #: pkg/booking/checkin.go:297 pkg/booking/public.go:577
msgid "Selected country is not valid." msgid "Selected country is not valid."
msgstr "Le pays sélectionné nest pas valide." msgstr "Le pays sélectionné nest 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." msgid "Selected ID document type is not valid."
msgstr "Le type de document didentité sélectionné nest pas valide." msgstr "Le type de document didentité sélectionné nest 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." msgid "ID document number can not be empty."
msgstr "Le numéro de documento didentité ne peut pas être vide." msgstr "Le numéro de documento didentité ne peut pas être vide."
#: pkg/customer/admin.go:300 pkg/booking/checkin.go:288 #: pkg/customer/admin.go:333 pkg/booking/checkin.go:288
#: pkg/booking/checkin.go:289 pkg/booking/admin.go:426 #: pkg/booking/checkin.go:289 pkg/booking/admin.go:429
#: pkg/booking/public.go:581 #: pkg/booking/public.go:581
msgid "Full name can not be empty." msgid "Full name can not be empty."
msgstr "Le nom complet ne peut pas être vide." 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." msgid "Full name must have at least one letter."
msgstr "Le nom complet doit comporter au moins une lettre." 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." msgid "Address can not be empty."
msgstr "Ladresse ne peut pas être vide." msgstr "Ladresse 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." msgid "Town or village can not be empty."
msgstr "La ville ne peut pas être vide." 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." msgid "Postcode can not be empty."
msgstr "Le code postal ne peut pas être vide." 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 #: pkg/booking/public.go:588
msgid "This postcode is not valid." msgid "This postcode is not valid."
msgstr "Ce code postal nest pas valide." msgstr "Ce code postal nest pas valide."
#: pkg/customer/admin.go:315 pkg/company/admin.go:220 #: pkg/customer/admin.go:348 pkg/company/admin.go:220
#: pkg/booking/checkin.go:301 pkg/booking/admin.go:443 #: pkg/booking/checkin.go:301 pkg/booking/admin.go:446
#: pkg/booking/public.go:596 #: pkg/booking/public.go:596
msgid "This phone number is not valid." msgid "This phone number is not valid."
msgstr "Ce numéro de téléphone nest pas valide." msgstr "Ce numéro de téléphone nest pas valide."
#: pkg/invoice/admin.go:649 #: pkg/invoice/admin.go:681
msgctxt "filename" msgctxt "filename"
msgid "invoices.zip" msgid "invoices.zip"
msgstr "factures.zip" msgstr "factures.zip"
#: pkg/invoice/admin.go:664 #: pkg/invoice/admin.go:696
msgctxt "filename" msgctxt "filename"
msgid "invoices.ods" msgid "invoices.ods"
msgstr "factures.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" msgid "Invalid action"
msgstr "Actin invalide" msgstr "Actin invalide"
#: pkg/invoice/admin.go:830 #: pkg/invoice/admin.go:863
msgid "Selected invoice status is not valid." msgid "Selected invoice status is not valid."
msgstr "Lstatut sélectionné nest pas valide." msgstr "Lstatut sélectionné nest pas valide."
#: pkg/invoice/admin.go:831 #: pkg/invoice/admin.go:864
msgid "Selected customer is not valid."
msgstr "Le client sélectionné nest pas valide."
#: pkg/invoice/admin.go:832
msgid "Invoice date can not be empty." msgid "Invoice date can not be empty."
msgstr "La date de facture ne peut pas être vide." 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." msgid "Invoice date must be a valid date."
msgstr "La date de facture doit être une date valide." msgstr "La date de facture doit être une date valide."
#: pkg/invoice/admin.go:980 #: pkg/invoice/admin.go:1023
#, c-format #, c-format
msgid "Re: quotation #%s of %s" msgid "Re: booking #%s of %s%s"
msgstr "" msgstr "Réf. : réservation num. %s du %s%s"
#: pkg/invoice/admin.go:981 #: pkg/invoice/admin.go:1024
msgctxt "to_char" msgctxt "to_char"
msgid "MM/DD/YYYY" msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY" msgstr "DD/MM/YYYY"
#: pkg/invoice/admin.go:1083 #: pkg/invoice/admin.go:1151
msgid "Invoice product ID must be an integer." msgid "Invoice product ID must be an integer."
msgstr "Le ID de produit de facture doit être un entier." 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." msgid "Invoice product ID one or greater."
msgstr "Le ID de produit de facture doit être égal ou supérieur à un." 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." msgid "Product ID must be an integer."
msgstr "Le ID de produit doit être un entier." 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." msgid "Product ID must zero or greater."
msgstr "Le ID de produit doit être égal ou supérieur à zéro." 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." msgid "Quantity can not be empty."
msgstr "La quantité ne peut pas être vide." msgstr "La quantité ne peut pas être vide."
#: pkg/invoice/admin.go:1099 #: pkg/invoice/admin.go:1167
msgid "Quantity must be an integer." msgid "Quantity must be an integer."
msgstr "La quantité doit être un entier." msgstr "La quantité doit être un entier."
#: pkg/invoice/admin.go:1100 #: pkg/invoice/admin.go:1168
msgid "Quantity must one or greater." msgid "Quantity must one or greater."
msgstr "La quantité doit être égnal ou supérieur à zéro." 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." msgid "Discount can not be empty."
msgstr "Le rabais ne peut pas être vide." msgstr "Le rabais ne peut pas être vide."
#: pkg/invoice/admin.go:1104 #: pkg/invoice/admin.go:1172
msgid "Discount must be an integer." msgid "Discount must be an integer."
msgstr "Le rabais doit être un entier." 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." msgid "Discount must be a percentage between 0 and 100."
msgstr "Le rabais doit être un pourcentage compris entre 0 et 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." msgid "Selected tax is not valid."
msgstr "La taxe sélectionnée nest pas valide." msgstr "La taxe sélectionnée nest pas valide."
@ -3444,19 +3452,19 @@ msgctxt "filename"
msgid "bookings.ods" msgid "bookings.ods"
msgstr "reservations.ods" msgstr "reservations.ods"
#: pkg/booking/admin.go:432 #: pkg/booking/admin.go:435
msgid "Country can not be empty to validate the postcode." msgid "Country can not be empty to validate the postcode."
msgstr "Le pays ne peut pas être vide pour valider le code postal." 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." msgid "Country can not be empty to validate the phone."
msgstr "Le pays ne peut pas être vide pour valider le télé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." msgid "You must select at least one accommodation."
msgstr "Vous devez sélectionner au moins un hébergement." 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." msgid "The selected accommodations have no available openings in the requested dates."
msgstr "Les hébergements sélectionnés nont pas de disponibilités aux dates demandées." msgstr "Les hébergements sélectionnés nont 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." msgid "It is mandatory to agree to the reservation conditions."
msgstr "Il est obligatoire daccepter les conditions de réservation." msgstr "Il est obligatoire daccepter les conditions de réservation."
#~ msgid "Select a customer"
#~ msgstr "Choisissez un client"
#~ msgid "Selected customer is not valid."
#~ msgstr "Le client sélectionné nest pas valide."
#~ msgctxt "title" #~ msgctxt "title"
#~ msgid "Accomodations" #~ msgid "Accomodations"
#~ msgstr "Hébergement" #~ msgstr "Hébergement"

View File

@ -1133,22 +1133,22 @@ label[x-show] > span, label[x-show] > br {
/*</editor-fold>*/ /*</editor-fold>*/
/* <editor-fold desc="Contact"> */ /* <editor-fold desc="Contact"> */
#contact-form label + label { :is(#contact-form, #invoice-form) label + label {
margin-top: 0; margin-top: 0;
} }
#contact-form :is(input, select) { :is(#contact-form, #invoice-form) :is(input, select) {
width: 100%; width: 100%;
} }
#contact-form .customer-details { :is(#contact-form, #invoice-form) .customer-details {
display: grid; display: grid;
gap: .5em; gap: .5em;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
align-content: start; 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; grid-column: 1 / -1;
} }

View File

@ -0,0 +1,124 @@
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}}
<fieldset class="customer-details">
<legend>{{( pgettext "Customer Details" "title" )}}</legend>
{{ with .FullName -}}
<label>
{{( pgettext "Full name" "input" )}}<br>
<input type="text"
required
minlength="2"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .IDDocumentNumber -}}
<label>
{{( pgettext "ID document number" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .IDDocumentType -}}
<label>
{{( pgettext "ID document type" "input" )}}<br>
<select name="{{ .Name }}"
required
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Choose an ID document type" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Address -}}
<label class="colspan">
{{( pgettext "Address" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .City -}}
<label>
{{( pgettext "Town or village" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Province -}}
<label>
{{( pgettext "Province" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .PostalCode -}}
<label>
{{( pgettext "Postcode" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Country -}}
<label>
{{( pgettext "Country" "input" )}}<br>
<select name="{{ .Name }}"
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Choose a country" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Email -}}
<label>
{{( pgettext "Email (optional)" "input" )}}<br>
<input type="email"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Phone -}}
<label>
{{( pgettext "Phone (optional)" "input" )}}<br>
<input type="tel"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
</fieldset>

View File

@ -3,7 +3,7 @@
SPDX-License-Identifier: AGPL-3.0-only SPDX-License-Identifier: AGPL-3.0-only
--> -->
{{ define "title" -}} {{ define "title" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.customerForm*/ -}} {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}}
{{ if .Slug }} {{ if .Slug }}
{{( pgettext "Edit Customer" "title" )}} {{( pgettext "Edit Customer" "title" )}}
{{ else }} {{ else }}
@ -16,7 +16,10 @@
{{- end }} {{- end }}
{{ define "content" -}} {{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.customerForm*/ -}} {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/customer.ContactForm*/ -}}
{{ if .Slug -}}
<a href="/admin/invoices/new?customer={{ .Slug }}">{{( pgettext "Invoice Customer" "action" )}}</a>
{{- end }}
<h2>{{ template "title" .}}</h2> <h2>{{ template "title" .}}</h2>
<form id="contact-form" <form id="contact-form"
{{- if .URL }} data-hx-put="{{ .URL }}" {{- if .URL }} data-hx-put="{{ .URL }}"
@ -24,129 +27,7 @@
{{- end -}} {{- end -}}
> >
{{ CSRFInput }} {{ CSRFInput }}
<fieldset class="customer-details"> {{ template "contact.gohtml" . }}
<legend>{{( pgettext "Customer Details" "title" )}}</legend>
{{ with .FullName -}}
<label>
{{( pgettext "Full name" "input" )}}<br>
<input type="text"
required
minlength="2"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .IDDocumentNumber -}}
<label>
{{( pgettext "ID document number" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .IDDocumentType -}}
<label>
{{( pgettext "ID document type" "input" )}}<br>
<select name="{{ .Name }}"
required
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Choose an ID document type" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Address -}}
<label class="colspan">
{{( pgettext "Address" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .City -}}
<label>
{{( pgettext "Town or village" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Province -}}
<label>
{{( pgettext "Province" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .PostalCode -}}
<label>
{{( pgettext "Postcode" "input" )}}<br>
<input type="text"
required
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Country -}}
<label>
{{( pgettext "Country" "input" )}}<br>
<select name="{{ .Name }}"
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Choose a country" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Email -}}
<label>
{{( pgettext "Email (optional)" "input" )}}<br>
<input type="email"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Phone -}}
<label>
{{( pgettext "Phone (optional)" "input" )}}<br>
<input type="tel"
name="{{ .Name }}"
value="{{ .Val }}"
{{ template "error-attrs" . }}
><br>
{{ template "error-message" . }}
</label>
{{- end }}
</fieldset>
<footer> <footer>
<button type="submit"> <button type="submit">
{{- if .Slug -}} {{- if .Slug -}}

View File

@ -19,7 +19,8 @@
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/invoice.invoiceForm*/ -}} {{- /*gotype: dev.tandem.ws/tandem/camper/pkg/invoice.invoiceForm*/ -}}
<section id="invoice-dialog-content" data-hx-target="main"> <section id="invoice-dialog-content" data-hx-target="main">
<h2>{{ template "title" . }}</h2> <h2>{{ template "title" . }}</h2>
<form method="POST" <form id="invoice-form"
method="POST"
{{ if .Slug }} action="/admin/invoices/{{ .Slug }}/edit" {{ else }} action="/admin/invoices/new" {{ end }} {{ if .Slug }} action="/admin/invoices/{{ .Slug }}/edit" {{ else }} action="/admin/invoices/new" {{ end }}
data-hx-boost="true" data-hx-boost="true"
data-hx-ext="morph" data-hx-ext="morph"
@ -47,19 +48,6 @@
{{- end }} {{- end }}
<fieldset class="invoice-data"> <fieldset class="invoice-data">
{{ with .Customer -}}
<label>
{{( pgettext "Customer" "input" )}}<br>
<select name="{{ .Name }}"
required
{{ template "error-attrs" . }}
>
<option value="">{{( gettext "Select a customer" )}}</option>
{{ template "list-options" . }}
</select><br>
{{ template "error-message" . }}
</label>
{{- end }}
{{ with .Date -}} {{ with .Date -}}
<label> <label>
{{( pgettext "Invoice date" "input" )}}<br> {{( pgettext "Invoice date" "input" )}}<br>
@ -100,6 +88,9 @@
{{- end }} {{- end }}
</fieldset> </fieldset>
{{ template "contact.gohtml" .Customer }}
<h3>{{( pgettext "Products" "title" )}}</h3>
{{- range .Products }} {{- range .Products }}
{{ template "product-form.gohtml" . }} {{ template "product-form.gohtml" . }}
{{- end }} {{- end }}