Allow to create an invoice from the data of a quotation

This commit is contained in:
jordi fita mas 2023-06-10 20:46:03 +02:00
parent f43949dd43
commit a16f696be5
5 changed files with 166 additions and 98 deletions

View File

@ -231,6 +231,8 @@ func ServeInvoice(w http.ResponseWriter, r *http.Request, params httprouter.Para
if invoiceToDuplicate := r.URL.Query().Get("duplicate"); invoiceToDuplicate != "" { if invoiceToDuplicate := r.URL.Query().Get("duplicate"); invoiceToDuplicate != "" {
form.MustFillFromDatabase(r.Context(), conn, invoiceToDuplicate) form.MustFillFromDatabase(r.Context(), conn, invoiceToDuplicate)
form.InvoiceStatus.Selected = []string{"created"} form.InvoiceStatus.Selected = []string{"created"}
} else if quoteToInvoice := r.URL.Query().Get("quote"); quoteToInvoice != "" {
form.MustFillFromQuote(r.Context(), conn, quoteToInvoice)
} }
form.Date.Val = time.Now().Format("2006-01-02") form.Date.Val = time.Now().Format("2006-01-02")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
@ -774,6 +776,31 @@ func (form *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *Conn, s
return true return true
} }
func (form *invoiceForm) MustFillFromQuote(ctx context.Context, conn *Conn, slug string) bool {
var quoteId int
selectedPaymentMethod := form.PaymentMethod.Selected
note := gettext("Re: quotation #%s of %s", form.locale)
dateFormat := pgettext("to_char", "MM/DD/YYYY", form.locale)
form.PaymentMethod.Clear()
if notFoundErrorOrPanic(conn.QueryRow(ctx, `
select quote_id
, coalesce(contact_id::text, '')
, (case when length(trim(notes)) = 0 then '' else notes || E'\n\n' end) || format($2, quote_number, to_char(quote_date, $3))
, coalesce(payment_method_id::text, $4)
, tags
from quote
left join quote_contact using (quote_id)
left join quote_payment_method using (quote_id)
where slug = $1
`, slug, note, dateFormat, selectedPaymentMethod[0]).Scan(&quoteId, form.Customer, form.Notes, form.PaymentMethod, form.Tags)) {
form.PaymentMethod.Selected = selectedPaymentMethod
return false
}
form.Products = []*invoiceProductForm{}
form.mustAddProductsFromQuery(ctx, conn, "select '', coalesce(product_id, 0), name, description, to_price(price, $2), quantity, (discount_rate * 100)::integer, array_remove(array_agg(tax_id), null) from quote_product left join quote_product_product using (quote_product_id) left join quote_product_tax using (quote_product_id) where quote_id = $1 group by quote_product_id, coalesce(product_id, 0), name, description, discount_rate, price, quantity", quoteId, form.company.DecimalDigits)
return true
}
func mustGetTaxOptions(ctx context.Context, conn *Conn, company *Company) []*SelectOption { func mustGetTaxOptions(ctx context.Context, conn *Conn, company *Company) []*SelectOption {
return MustGetGroupedOptions(ctx, conn, "select tax_id::text, tax.name, tax_class.name from tax join tax_class using (tax_class_id) where tax.company_id = $1 order by tax_class.name, tax.name", company.Id) return MustGetGroupedOptions(ctx, conn, "select tax_id::text, tax.name, tax_class.name from tax join tax_class using (tax_class_id) where tax.company_id = $1 order by tax_class.name, tax.name", company.Id)
} }

113
po/ca.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: numerus\n" "Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-06-09 12:38+0200\n" "POT-Creation-Date: 2023-06-10 20:40+0200\n"
"PO-Revision-Date: 2023-01-18 17:08+0100\n" "PO-Revision-Date: 2023-01-18 17:08+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"
@ -65,7 +65,7 @@ msgstr "Nom"
#: web/template/invoices/products.gohtml:50 #: web/template/invoices/products.gohtml:50
#: web/template/invoices/view.gohtml:62 web/template/quotes/products.gohtml:50 #: web/template/invoices/view.gohtml:62 web/template/quotes/products.gohtml:50
#: web/template/quotes/view.gohtml:68 web/template/products/index.gohtml:42 #: web/template/quotes/view.gohtml:71 web/template/products/index.gohtml:42
msgctxt "title" msgctxt "title"
msgid "Price" msgid "Price"
msgstr "Preu" msgstr "Preu"
@ -95,15 +95,15 @@ msgstr "Desfes"
#: web/template/invoices/new.gohtml:60 web/template/invoices/view.gohtml:67 #: web/template/invoices/new.gohtml:60 web/template/invoices/view.gohtml:67
#: web/template/invoices/edit.gohtml:61 web/template/quotes/new.gohtml:61 #: web/template/invoices/edit.gohtml:61 web/template/quotes/new.gohtml:61
#: web/template/quotes/view.gohtml:73 web/template/quotes/edit.gohtml:62 #: web/template/quotes/view.gohtml:76 web/template/quotes/edit.gohtml:62
msgctxt "title" msgctxt "title"
msgid "Subtotal" msgid "Subtotal"
msgstr "Subtotal" msgstr "Subtotal"
#: web/template/invoices/new.gohtml:70 web/template/invoices/view.gohtml:71 #: web/template/invoices/new.gohtml:70 web/template/invoices/view.gohtml:71
#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:71 #: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:71
#: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:77 #: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:80
#: web/template/quotes/view.gohtml:117 web/template/quotes/edit.gohtml:72 #: web/template/quotes/view.gohtml:120 web/template/quotes/edit.gohtml:72
msgctxt "title" msgctxt "title"
msgid "Total" msgid "Total"
msgstr "Total" msgstr "Total"
@ -146,7 +146,7 @@ msgid "All"
msgstr "Totes" msgstr "Totes"
#: web/template/invoices/index.gohtml:50 web/template/invoices/view.gohtml:34 #: web/template/invoices/index.gohtml:50 web/template/invoices/view.gohtml:34
#: web/template/quotes/index.gohtml:50 web/template/quotes/view.gohtml:34 #: web/template/quotes/index.gohtml:50 web/template/quotes/view.gohtml:37
msgctxt "title" msgctxt "title"
msgid "Date" msgid "Date"
msgstr "Data" msgstr "Data"
@ -199,7 +199,7 @@ msgid "Select invoice %v"
msgstr "Selecciona factura %v" msgstr "Selecciona factura %v"
#: web/template/invoices/index.gohtml:119 web/template/invoices/view.gohtml:19 #: web/template/invoices/index.gohtml:119 web/template/invoices/view.gohtml:19
#: web/template/quotes/index.gohtml:119 web/template/quotes/view.gohtml:19 #: web/template/quotes/index.gohtml:119 web/template/quotes/view.gohtml:22
#: web/template/contacts/index.gohtml:74 web/template/expenses/index.gohtml:88 #: web/template/contacts/index.gohtml:74 web/template/expenses/index.gohtml:88
#: web/template/products/index.gohtml:72 #: web/template/products/index.gohtml:72
msgctxt "action" msgctxt "action"
@ -207,7 +207,7 @@ msgid "Edit"
msgstr "Edita" msgstr "Edita"
#: web/template/invoices/index.gohtml:127 web/template/invoices/view.gohtml:16 #: web/template/invoices/index.gohtml:127 web/template/invoices/view.gohtml:16
#: web/template/quotes/index.gohtml:127 web/template/quotes/view.gohtml:16 #: web/template/quotes/index.gohtml:127 web/template/quotes/view.gohtml:19
msgctxt "action" msgctxt "action"
msgid "Duplicate" msgid "Duplicate"
msgstr "Duplica" msgstr "Duplica"
@ -226,22 +226,22 @@ msgctxt "action"
msgid "Download invoice" msgid "Download invoice"
msgstr "Descarrega factura" msgstr "Descarrega factura"
#: web/template/invoices/view.gohtml:61 web/template/quotes/view.gohtml:67 #: web/template/invoices/view.gohtml:61 web/template/quotes/view.gohtml:70
msgctxt "title" msgctxt "title"
msgid "Concept" msgid "Concept"
msgstr "Concepte" msgstr "Concepte"
#: web/template/invoices/view.gohtml:64 web/template/quotes/view.gohtml:70 #: web/template/invoices/view.gohtml:64 web/template/quotes/view.gohtml:73
msgctxt "title" msgctxt "title"
msgid "Discount" msgid "Discount"
msgstr "Descompte" msgstr "Descompte"
#: web/template/invoices/view.gohtml:66 web/template/quotes/view.gohtml:72 #: web/template/invoices/view.gohtml:66 web/template/quotes/view.gohtml:75
msgctxt "title" msgctxt "title"
msgid "Units" msgid "Units"
msgstr "Unitats" msgstr "Unitats"
#: web/template/invoices/view.gohtml:101 web/template/quotes/view.gohtml:107 #: web/template/invoices/view.gohtml:101 web/template/quotes/view.gohtml:110
msgctxt "title" msgctxt "title"
msgid "Tax Base" msgid "Tax Base"
msgstr "Base imposable" msgstr "Base imposable"
@ -339,21 +339,26 @@ msgctxt "action"
msgid "Select quotation %v" msgid "Select quotation %v"
msgstr "Selecciona pressupost %v" msgstr "Selecciona pressupost %v"
#: web/template/quotes/index.gohtml:137 #: web/template/quotes/index.gohtml:135 web/template/quotes/view.gohtml:16
msgctxt "action"
msgid "Create invoice"
msgstr "Crea factura"
#: web/template/quotes/index.gohtml:145
msgid "No quotations added yet." msgid "No quotations added yet."
msgstr "No hi ha cap pressupost." msgstr "No hi ha cap pressupost."
#: web/template/quotes/view.gohtml:2 web/template/quotes/view.gohtml:33 #: web/template/quotes/view.gohtml:2 web/template/quotes/view.gohtml:36
msgctxt "title" msgctxt "title"
msgid "Quotation %s" msgid "Quotation %s"
msgstr "Pressupost %s" msgstr "Pressupost %s"
#: web/template/quotes/view.gohtml:22 #: web/template/quotes/view.gohtml:25
msgctxt "action" msgctxt "action"
msgid "Download quotation" msgid "Download quotation"
msgstr "Descarrega pressupost" msgstr "Descarrega pressupost"
#: web/template/quotes/view.gohtml:60 #: web/template/quotes/view.gohtml:63
msgid "Terms and Conditions:" msgid "Terms and Conditions:"
msgstr "Condicions dacceptació:" msgstr "Condicions dacceptació:"
@ -645,7 +650,7 @@ msgstr "No podeu deixar la contrasenya en blanc."
msgid "Invalid user or password." msgid "Invalid user or password."
msgstr "Nom dusuari o contrasenya incorrectes." msgstr "Nom dusuari o contrasenya incorrectes."
#: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:801 pkg/invoices.go:824 #: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:801 pkg/invoices.go:851
#: pkg/contacts.go:135 #: pkg/contacts.go:135
msgctxt "input" msgctxt "input"
msgid "Name" msgid "Name"
@ -653,7 +658,7 @@ msgstr "Nom"
#: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:188 pkg/quote.go:608 #: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:188 pkg/quote.go:608
#: pkg/expenses.go:202 pkg/expenses.go:361 pkg/invoices.go:189 #: pkg/expenses.go:202 pkg/expenses.go:361 pkg/invoices.go:189
#: pkg/invoices.go:601 pkg/invoices.go:1123 pkg/contacts.go:140 #: pkg/invoices.go:603 pkg/invoices.go:1150 pkg/contacts.go:140
#: pkg/contacts.go:325 #: pkg/contacts.go:325
msgctxt "input" msgctxt "input"
msgid "Tags" msgid "Tags"
@ -687,40 +692,40 @@ msgstr "Qualsevol"
msgid "Invoices must have at least one of the specified labels." msgid "Invoices must have at least one of the specified labels."
msgstr "Les factures han de tenir com a mínim una de les etiquetes." msgstr "Les factures han de tenir com a mínim una de les etiquetes."
#: pkg/products.go:269 pkg/quote.go:815 pkg/invoices.go:838 #: pkg/products.go:269 pkg/quote.go:815 pkg/invoices.go:865
msgctxt "input" msgctxt "input"
msgid "Description" msgid "Description"
msgstr "Descripció" msgstr "Descripció"
#: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:842 #: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:869
msgctxt "input" msgctxt "input"
msgid "Price" msgid "Price"
msgstr "Preu" msgstr "Preu"
#: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:871 #: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:898
msgctxt "input" msgctxt "input"
msgid "Taxes" msgid "Taxes"
msgstr "Imposts" msgstr "Imposts"
#: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:920 #: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:947
msgid "Name can not be empty." msgid "Name can not be empty."
msgstr "No podeu deixar el nom en blanc." msgstr "No podeu deixar el nom en blanc."
#: pkg/products.go:310 pkg/quote.go:898 pkg/invoices.go:921 #: pkg/products.go:310 pkg/quote.go:898 pkg/invoices.go:948
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/products.go:311 pkg/quote.go:899 pkg/invoices.go:922 #: pkg/products.go:311 pkg/quote.go:899 pkg/invoices.go:949
msgid "Price must be a number greater than zero." msgid "Price must be a number greater than zero."
msgstr "El preu ha de ser un número major a zero." msgstr "El preu ha de ser un número major a zero."
#: pkg/products.go:313 pkg/quote.go:907 pkg/expenses.go:227 pkg/expenses.go:232 #: pkg/products.go:313 pkg/quote.go:907 pkg/expenses.go:227 pkg/expenses.go:232
#: pkg/invoices.go:930 #: pkg/invoices.go:957
msgid "Selected tax is not valid." msgid "Selected tax is not valid."
msgstr "Heu seleccionat un impost que no és vàlid." msgstr "Heu seleccionat un impost que no és vàlid."
#: pkg/products.go:314 pkg/quote.go:908 pkg/expenses.go:228 pkg/expenses.go:233 #: pkg/products.go:314 pkg/quote.go:908 pkg/expenses.go:228 pkg/expenses.go:233
#: pkg/invoices.go:931 #: pkg/invoices.go:958
msgid "You can only select a tax of each class." msgid "You can only select a tax of each class."
msgstr "Només podeu seleccionar un impost de cada classe." msgstr "Només podeu seleccionar un impost de cada classe."
@ -828,7 +833,7 @@ msgid "Payment instructions can not be empty."
msgstr "No podeu deixar les instruccions de pagament en blanc." msgstr "No podeu deixar les instruccions de pagament en blanc."
#: pkg/quote.go:161 pkg/quote.go:586 pkg/expenses.go:340 pkg/invoices.go:162 #: pkg/quote.go:161 pkg/quote.go:586 pkg/expenses.go:340 pkg/invoices.go:162
#: pkg/invoices.go:584 #: pkg/invoices.go:586
msgctxt "input" msgctxt "input"
msgid "Customer" msgid "Customer"
msgstr "Client" msgstr "Client"
@ -873,8 +878,8 @@ msgstr "Els pressuposts han de tenir com a mínim una de les etiquetes."
msgid "quotations.zip" msgid "quotations.zip"
msgstr "pressuposts.zip" msgstr "pressuposts.zip"
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:533 #: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535
#: pkg/invoices.go:1098 pkg/invoices.go:1106 #: pkg/invoices.go:1125 pkg/invoices.go:1133
msgid "Invalid action" msgid "Invalid action"
msgstr "Acció invàlida." msgstr "Acció invàlida."
@ -892,12 +897,12 @@ msgctxt "input"
msgid "Terms and conditions" msgid "Terms and conditions"
msgstr "Condicions dacceptació" msgstr "Condicions dacceptació"
#: pkg/quote.go:603 pkg/invoices.go:596 #: pkg/quote.go:603 pkg/invoices.go:598
msgctxt "input" msgctxt "input"
msgid "Notes" msgid "Notes"
msgstr "Notes" msgstr "Notes"
#: pkg/quote.go:612 pkg/invoices.go:606 #: pkg/quote.go:612 pkg/invoices.go:608
msgctxt "input" msgctxt "input"
msgid "Payment Method" msgid "Payment Method"
msgstr "Mètode de pagament" msgstr "Mètode de pagament"
@ -910,7 +915,7 @@ msgstr "Escolliu un mètode de pagament."
msgid "Selected quotation status is not valid." msgid "Selected quotation status is not valid."
msgstr "Heu seleccionat un estat de pressupost que no és vàlid." msgstr "Heu seleccionat un estat de pressupost que no és vàlid."
#: pkg/quote.go:651 pkg/invoices.go:643 #: pkg/quote.go:651 pkg/invoices.go:645
msgid "Selected customer is not valid." msgid "Selected customer is not valid."
msgstr "Heu seleccionat un client que no és vàlid." msgstr "Heu seleccionat un client que no és vàlid."
@ -922,21 +927,21 @@ msgstr "No podeu deixar la data del pressupost en blanc."
msgid "Quotation date must be a valid date." msgid "Quotation date must be a valid date."
msgstr "La data del pressupost ha de ser vàlida." msgstr "La data del pressupost ha de ser vàlida."
#: pkg/quote.go:657 pkg/invoices.go:647 #: pkg/quote.go:657 pkg/invoices.go:649
msgid "Selected payment method is not valid." msgid "Selected payment method is not valid."
msgstr "Heu seleccionat un mètode de pagament que no és vàlid." msgstr "Heu seleccionat un mètode de pagament que no és vàlid."
#: pkg/quote.go:791 pkg/quote.go:796 pkg/invoices.go:814 pkg/invoices.go:819 #: pkg/quote.go:791 pkg/quote.go:796 pkg/invoices.go:841 pkg/invoices.go:846
msgctxt "input" msgctxt "input"
msgid "Id" msgid "Id"
msgstr "Identificador" msgstr "Identificador"
#: pkg/quote.go:829 pkg/invoices.go:852 #: pkg/quote.go:829 pkg/invoices.go:879
msgctxt "input" msgctxt "input"
msgid "Quantity" msgid "Quantity"
msgstr "Quantitat" msgstr "Quantitat"
#: pkg/quote.go:838 pkg/invoices.go:861 #: pkg/quote.go:838 pkg/invoices.go:888
msgctxt "input" msgctxt "input"
msgid "Discount (%)" msgid "Discount (%)"
msgstr "Descompte (%)" msgstr "Descompte (%)"
@ -945,23 +950,23 @@ msgstr "Descompte (%)"
msgid "Quotation product ID must be a number greater than zero." msgid "Quotation product ID must be a number greater than zero."
msgstr "LID del producte de pressupost ha de ser un número major a zero." msgstr "LID del producte de pressupost ha de ser un número major a zero."
#: pkg/quote.go:895 pkg/invoices.go:918 #: pkg/quote.go:895 pkg/invoices.go:945
msgid "Product ID must be a positive number or zero." msgid "Product ID must be a positive number or zero."
msgstr "LID del producte ha de ser un número positiu o zero." msgstr "LID del producte ha de ser un número positiu o zero."
#: pkg/quote.go:901 pkg/invoices.go:924 #: pkg/quote.go:901 pkg/invoices.go:951
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/quote.go:902 pkg/invoices.go:925 #: pkg/quote.go:902 pkg/invoices.go:952
msgid "Quantity must be a number greater than zero." msgid "Quantity must be a number greater than zero."
msgstr "La quantitat ha de ser un número major a zero." msgstr "La quantitat ha de ser un número major a zero."
#: pkg/quote.go:904 pkg/invoices.go:927 #: pkg/quote.go:904 pkg/invoices.go:954
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/quote.go:905 pkg/invoices.go:928 #: pkg/quote.go:905 pkg/invoices.go:955
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."
@ -1042,7 +1047,7 @@ msgctxt "input"
msgid "Invoice number" msgid "Invoice number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:175 pkg/invoices.go:590 #: pkg/expenses.go:175 pkg/invoices.go:592
msgctxt "input" msgctxt "input"
msgid "Invoice Date" msgid "Invoice Date"
msgstr "Data de factura" msgstr "Data de factura"
@ -1061,7 +1066,7 @@ msgstr "Fitxer"
msgid "Selected contact is not valid." msgid "Selected contact is not valid."
msgstr "Heu seleccionat un contacte que no és vàlid." msgstr "Heu seleccionat un contacte que no és vàlid."
#: pkg/expenses.go:226 pkg/invoices.go:645 #: pkg/expenses.go:226 pkg/invoices.go:647
msgid "Invoice date must be a valid date." msgid "Invoice date must be a valid date."
msgstr "La data de facturació ha de ser vàlida." msgstr "La data de facturació ha de ser vàlida."
@ -1078,28 +1083,38 @@ msgctxt "input"
msgid "Invoice Number" msgid "Invoice Number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/invoices.go:168 pkg/invoices.go:578 #: pkg/invoices.go:168 pkg/invoices.go:580
msgctxt "input" msgctxt "input"
msgid "Invoice Status" msgid "Invoice Status"
msgstr "Estat de la factura" msgstr "Estat de la factura"
#: pkg/invoices.go:426 #: pkg/invoices.go:428
msgid "Select a customer to bill." msgid "Select a customer to bill."
msgstr "Escolliu un client a facturar." msgstr "Escolliu un client a facturar."
#: pkg/invoices.go:527 #: pkg/invoices.go:529
msgid "invoices.zip" msgid "invoices.zip"
msgstr "factures.zip" msgstr "factures.zip"
#: pkg/invoices.go:642 #: pkg/invoices.go:644
msgid "Selected invoice status is not valid." msgid "Selected invoice status is not valid."
msgstr "Heu seleccionat un estat de factura que no és vàlid." msgstr "Heu seleccionat un estat de factura que no és vàlid."
#: pkg/invoices.go:644 #: pkg/invoices.go:646
msgid "Invoice date can not be empty." msgid "Invoice date can not be empty."
msgstr "No podeu deixar la data de la factura en blanc." msgstr "No podeu deixar la data de la factura en blanc."
#: pkg/invoices.go:915 #: pkg/invoices.go:782
#, c-format
msgid "Re: quotation #%s of %s"
msgstr "Ref: pressupost núm. %s del %s"
#: pkg/invoices.go:783
msgctxt "to_char"
msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY"
#: pkg/invoices.go:942
msgid "Invoice product ID must be a number greater than zero." msgid "Invoice product ID must be a number greater than zero."
msgstr "LID del producte de factura ha de ser un número major a zero." msgstr "LID del producte de factura ha de ser un número major a zero."

113
po/es.po
View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: numerus\n" "Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-06-09 12:38+0200\n" "POT-Creation-Date: 2023-06-10 20:40+0200\n"
"PO-Revision-Date: 2023-01-18 17:45+0100\n" "PO-Revision-Date: 2023-01-18 17:45+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"
@ -65,7 +65,7 @@ msgstr "Nombre"
#: web/template/invoices/products.gohtml:50 #: web/template/invoices/products.gohtml:50
#: web/template/invoices/view.gohtml:62 web/template/quotes/products.gohtml:50 #: web/template/invoices/view.gohtml:62 web/template/quotes/products.gohtml:50
#: web/template/quotes/view.gohtml:68 web/template/products/index.gohtml:42 #: web/template/quotes/view.gohtml:71 web/template/products/index.gohtml:42
msgctxt "title" msgctxt "title"
msgid "Price" msgid "Price"
msgstr "Precio" msgstr "Precio"
@ -95,15 +95,15 @@ msgstr "Deshacer"
#: web/template/invoices/new.gohtml:60 web/template/invoices/view.gohtml:67 #: web/template/invoices/new.gohtml:60 web/template/invoices/view.gohtml:67
#: web/template/invoices/edit.gohtml:61 web/template/quotes/new.gohtml:61 #: web/template/invoices/edit.gohtml:61 web/template/quotes/new.gohtml:61
#: web/template/quotes/view.gohtml:73 web/template/quotes/edit.gohtml:62 #: web/template/quotes/view.gohtml:76 web/template/quotes/edit.gohtml:62
msgctxt "title" msgctxt "title"
msgid "Subtotal" msgid "Subtotal"
msgstr "Subtotal" msgstr "Subtotal"
#: web/template/invoices/new.gohtml:70 web/template/invoices/view.gohtml:71 #: web/template/invoices/new.gohtml:70 web/template/invoices/view.gohtml:71
#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:71 #: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:71
#: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:77 #: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:80
#: web/template/quotes/view.gohtml:117 web/template/quotes/edit.gohtml:72 #: web/template/quotes/view.gohtml:120 web/template/quotes/edit.gohtml:72
msgctxt "title" msgctxt "title"
msgid "Total" msgid "Total"
msgstr "Total" msgstr "Total"
@ -146,7 +146,7 @@ msgid "All"
msgstr "Todas" msgstr "Todas"
#: web/template/invoices/index.gohtml:50 web/template/invoices/view.gohtml:34 #: web/template/invoices/index.gohtml:50 web/template/invoices/view.gohtml:34
#: web/template/quotes/index.gohtml:50 web/template/quotes/view.gohtml:34 #: web/template/quotes/index.gohtml:50 web/template/quotes/view.gohtml:37
msgctxt "title" msgctxt "title"
msgid "Date" msgid "Date"
msgstr "Fecha" msgstr "Fecha"
@ -199,7 +199,7 @@ msgid "Select invoice %v"
msgstr "Seleccionar factura %v" msgstr "Seleccionar factura %v"
#: web/template/invoices/index.gohtml:119 web/template/invoices/view.gohtml:19 #: web/template/invoices/index.gohtml:119 web/template/invoices/view.gohtml:19
#: web/template/quotes/index.gohtml:119 web/template/quotes/view.gohtml:19 #: web/template/quotes/index.gohtml:119 web/template/quotes/view.gohtml:22
#: web/template/contacts/index.gohtml:74 web/template/expenses/index.gohtml:88 #: web/template/contacts/index.gohtml:74 web/template/expenses/index.gohtml:88
#: web/template/products/index.gohtml:72 #: web/template/products/index.gohtml:72
msgctxt "action" msgctxt "action"
@ -207,7 +207,7 @@ msgid "Edit"
msgstr "Editar" msgstr "Editar"
#: web/template/invoices/index.gohtml:127 web/template/invoices/view.gohtml:16 #: web/template/invoices/index.gohtml:127 web/template/invoices/view.gohtml:16
#: web/template/quotes/index.gohtml:127 web/template/quotes/view.gohtml:16 #: web/template/quotes/index.gohtml:127 web/template/quotes/view.gohtml:19
msgctxt "action" msgctxt "action"
msgid "Duplicate" msgid "Duplicate"
msgstr "Duplicar" msgstr "Duplicar"
@ -226,22 +226,22 @@ msgctxt "action"
msgid "Download invoice" msgid "Download invoice"
msgstr "Descargar factura" msgstr "Descargar factura"
#: web/template/invoices/view.gohtml:61 web/template/quotes/view.gohtml:67 #: web/template/invoices/view.gohtml:61 web/template/quotes/view.gohtml:70
msgctxt "title" msgctxt "title"
msgid "Concept" msgid "Concept"
msgstr "Concepto" msgstr "Concepto"
#: web/template/invoices/view.gohtml:64 web/template/quotes/view.gohtml:70 #: web/template/invoices/view.gohtml:64 web/template/quotes/view.gohtml:73
msgctxt "title" msgctxt "title"
msgid "Discount" msgid "Discount"
msgstr "Descuento" msgstr "Descuento"
#: web/template/invoices/view.gohtml:66 web/template/quotes/view.gohtml:72 #: web/template/invoices/view.gohtml:66 web/template/quotes/view.gohtml:75
msgctxt "title" msgctxt "title"
msgid "Units" msgid "Units"
msgstr "Unidades" msgstr "Unidades"
#: web/template/invoices/view.gohtml:101 web/template/quotes/view.gohtml:107 #: web/template/invoices/view.gohtml:101 web/template/quotes/view.gohtml:110
msgctxt "title" msgctxt "title"
msgid "Tax Base" msgid "Tax Base"
msgstr "Base imponible" msgstr "Base imponible"
@ -339,21 +339,26 @@ msgctxt "action"
msgid "Select quotation %v" msgid "Select quotation %v"
msgstr "Seleccionar presupuesto %v" msgstr "Seleccionar presupuesto %v"
#: web/template/quotes/index.gohtml:137 #: web/template/quotes/index.gohtml:135 web/template/quotes/view.gohtml:16
msgctxt "action"
msgid "Create invoice"
msgstr "Crear factura"
#: web/template/quotes/index.gohtml:145
msgid "No quotations added yet." msgid "No quotations added yet."
msgstr "No hay presupuestos." msgstr "No hay presupuestos."
#: web/template/quotes/view.gohtml:2 web/template/quotes/view.gohtml:33 #: web/template/quotes/view.gohtml:2 web/template/quotes/view.gohtml:36
msgctxt "title" msgctxt "title"
msgid "Quotation %s" msgid "Quotation %s"
msgstr "Estado del presupuesto" msgstr "Estado del presupuesto"
#: web/template/quotes/view.gohtml:22 #: web/template/quotes/view.gohtml:25
msgctxt "action" msgctxt "action"
msgid "Download quotation" msgid "Download quotation"
msgstr "Descargar presupuesto" msgstr "Descargar presupuesto"
#: web/template/quotes/view.gohtml:60 #: web/template/quotes/view.gohtml:63
msgid "Terms and Conditions:" msgid "Terms and Conditions:"
msgstr "Condiciones de aceptación:" msgstr "Condiciones de aceptación:"
@ -645,7 +650,7 @@ msgstr "No podéis dejar la contraseña en blanco."
msgid "Invalid user or password." msgid "Invalid user or password."
msgstr "Nombre de usuario o contraseña inválido." msgstr "Nombre de usuario o contraseña inválido."
#: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:801 pkg/invoices.go:824 #: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:801 pkg/invoices.go:851
#: pkg/contacts.go:135 #: pkg/contacts.go:135
msgctxt "input" msgctxt "input"
msgid "Name" msgid "Name"
@ -653,7 +658,7 @@ msgstr "Nombre"
#: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:188 pkg/quote.go:608 #: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:188 pkg/quote.go:608
#: pkg/expenses.go:202 pkg/expenses.go:361 pkg/invoices.go:189 #: pkg/expenses.go:202 pkg/expenses.go:361 pkg/invoices.go:189
#: pkg/invoices.go:601 pkg/invoices.go:1123 pkg/contacts.go:140 #: pkg/invoices.go:603 pkg/invoices.go:1150 pkg/contacts.go:140
#: pkg/contacts.go:325 #: pkg/contacts.go:325
msgctxt "input" msgctxt "input"
msgid "Tags" msgid "Tags"
@ -687,40 +692,40 @@ msgstr "Cualquiera"
msgid "Invoices must have at least one of the specified labels." msgid "Invoices must have at least one of the specified labels."
msgstr "Las facturas deben tener como mínimo una de las etiquetas." msgstr "Las facturas deben tener como mínimo una de las etiquetas."
#: pkg/products.go:269 pkg/quote.go:815 pkg/invoices.go:838 #: pkg/products.go:269 pkg/quote.go:815 pkg/invoices.go:865
msgctxt "input" msgctxt "input"
msgid "Description" msgid "Description"
msgstr "Descripción" msgstr "Descripción"
#: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:842 #: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:869
msgctxt "input" msgctxt "input"
msgid "Price" msgid "Price"
msgstr "Precio" msgstr "Precio"
#: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:871 #: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:898
msgctxt "input" msgctxt "input"
msgid "Taxes" msgid "Taxes"
msgstr "Impuestos" msgstr "Impuestos"
#: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:920 #: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:947
msgid "Name can not be empty." msgid "Name can not be empty."
msgstr "No podéis dejar el nombre en blanco." msgstr "No podéis dejar el nombre en blanco."
#: pkg/products.go:310 pkg/quote.go:898 pkg/invoices.go:921 #: pkg/products.go:310 pkg/quote.go:898 pkg/invoices.go:948
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/products.go:311 pkg/quote.go:899 pkg/invoices.go:922 #: pkg/products.go:311 pkg/quote.go:899 pkg/invoices.go:949
msgid "Price must be a number greater than zero." msgid "Price must be a number greater than zero."
msgstr "El precio tiene que ser un número mayor a cero." msgstr "El precio tiene que ser un número mayor a cero."
#: pkg/products.go:313 pkg/quote.go:907 pkg/expenses.go:227 pkg/expenses.go:232 #: pkg/products.go:313 pkg/quote.go:907 pkg/expenses.go:227 pkg/expenses.go:232
#: pkg/invoices.go:930 #: pkg/invoices.go:957
msgid "Selected tax is not valid." msgid "Selected tax is not valid."
msgstr "Habéis escogido un impuesto que no es válido." msgstr "Habéis escogido un impuesto que no es válido."
#: pkg/products.go:314 pkg/quote.go:908 pkg/expenses.go:228 pkg/expenses.go:233 #: pkg/products.go:314 pkg/quote.go:908 pkg/expenses.go:228 pkg/expenses.go:233
#: pkg/invoices.go:931 #: pkg/invoices.go:958
msgid "You can only select a tax of each class." msgid "You can only select a tax of each class."
msgstr "Solo podéis escoger un impuesto de cada clase." msgstr "Solo podéis escoger un impuesto de cada clase."
@ -828,7 +833,7 @@ msgid "Payment instructions can not be empty."
msgstr "No podéis dejar las instrucciones de pago en blanco." msgstr "No podéis dejar las instrucciones de pago en blanco."
#: pkg/quote.go:161 pkg/quote.go:586 pkg/expenses.go:340 pkg/invoices.go:162 #: pkg/quote.go:161 pkg/quote.go:586 pkg/expenses.go:340 pkg/invoices.go:162
#: pkg/invoices.go:584 #: pkg/invoices.go:586
msgctxt "input" msgctxt "input"
msgid "Customer" msgid "Customer"
msgstr "Cliente" msgstr "Cliente"
@ -873,8 +878,8 @@ msgstr "Los presupuestos deben tener como mínimo una de las etiquetas."
msgid "quotations.zip" msgid "quotations.zip"
msgstr "presupuestos.zip" msgstr "presupuestos.zip"
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:533 #: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535
#: pkg/invoices.go:1098 pkg/invoices.go:1106 #: pkg/invoices.go:1125 pkg/invoices.go:1133
msgid "Invalid action" msgid "Invalid action"
msgstr "Acción inválida." msgstr "Acción inválida."
@ -892,12 +897,12 @@ msgctxt "input"
msgid "Terms and conditions" msgid "Terms and conditions"
msgstr "Condiciones de aceptación" msgstr "Condiciones de aceptación"
#: pkg/quote.go:603 pkg/invoices.go:596 #: pkg/quote.go:603 pkg/invoices.go:598
msgctxt "input" msgctxt "input"
msgid "Notes" msgid "Notes"
msgstr "Notas" msgstr "Notas"
#: pkg/quote.go:612 pkg/invoices.go:606 #: pkg/quote.go:612 pkg/invoices.go:608
msgctxt "input" msgctxt "input"
msgid "Payment Method" msgid "Payment Method"
msgstr "Método de pago" msgstr "Método de pago"
@ -910,7 +915,7 @@ msgstr "Escoged un método e pago."
msgid "Selected quotation status is not valid." msgid "Selected quotation status is not valid."
msgstr "Habéis escogido un estado de presupuesto que no es válido." msgstr "Habéis escogido un estado de presupuesto que no es válido."
#: pkg/quote.go:651 pkg/invoices.go:643 #: pkg/quote.go:651 pkg/invoices.go:645
msgid "Selected customer is not valid." msgid "Selected customer is not valid."
msgstr "Habéis escogido un cliente que no es válido." msgstr "Habéis escogido un cliente que no es válido."
@ -922,21 +927,21 @@ msgstr "No podéis dejar la fecha del presupuesto en blanco."
msgid "Quotation date must be a valid date." msgid "Quotation date must be a valid date."
msgstr "La fecha de presupuesto debe ser válida." msgstr "La fecha de presupuesto debe ser válida."
#: pkg/quote.go:657 pkg/invoices.go:647 #: pkg/quote.go:657 pkg/invoices.go:649
msgid "Selected payment method is not valid." msgid "Selected payment method is not valid."
msgstr "Habéis escogido un método de pago que no es válido." msgstr "Habéis escogido un método de pago que no es válido."
#: pkg/quote.go:791 pkg/quote.go:796 pkg/invoices.go:814 pkg/invoices.go:819 #: pkg/quote.go:791 pkg/quote.go:796 pkg/invoices.go:841 pkg/invoices.go:846
msgctxt "input" msgctxt "input"
msgid "Id" msgid "Id"
msgstr "Identificador" msgstr "Identificador"
#: pkg/quote.go:829 pkg/invoices.go:852 #: pkg/quote.go:829 pkg/invoices.go:879
msgctxt "input" msgctxt "input"
msgid "Quantity" msgid "Quantity"
msgstr "Cantidad" msgstr "Cantidad"
#: pkg/quote.go:838 pkg/invoices.go:861 #: pkg/quote.go:838 pkg/invoices.go:888
msgctxt "input" msgctxt "input"
msgid "Discount (%)" msgid "Discount (%)"
msgstr "Descuento (%)" msgstr "Descuento (%)"
@ -945,23 +950,23 @@ msgstr "Descuento (%)"
msgid "Quotation product ID must be a number greater than zero." msgid "Quotation product ID must be a number greater than zero."
msgstr "El ID de producto de presupuesto tiene que ser un número mayor a cero." msgstr "El ID de producto de presupuesto tiene que ser un número mayor a cero."
#: pkg/quote.go:895 pkg/invoices.go:918 #: pkg/quote.go:895 pkg/invoices.go:945
msgid "Product ID must be a positive number or zero." msgid "Product ID must be a positive number or zero."
msgstr "El ID de producto tiene que ser un número positivo o cero." msgstr "El ID de producto tiene que ser un número positivo o cero."
#: pkg/quote.go:901 pkg/invoices.go:924 #: pkg/quote.go:901 pkg/invoices.go:951
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/quote.go:902 pkg/invoices.go:925 #: pkg/quote.go:902 pkg/invoices.go:952
msgid "Quantity must be a number greater than zero." msgid "Quantity must be a number greater than zero."
msgstr "La cantidad tiene que ser un número mayor a cero." msgstr "La cantidad tiene que ser un número mayor a cero."
#: pkg/quote.go:904 pkg/invoices.go:927 #: pkg/quote.go:904 pkg/invoices.go:954
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/quote.go:905 pkg/invoices.go:928 #: pkg/quote.go:905 pkg/invoices.go:955
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 0 y 100." msgstr "El descuento tiene que ser un porcentaje entre 0 y 100."
@ -1042,7 +1047,7 @@ msgctxt "input"
msgid "Invoice number" msgid "Invoice number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:175 pkg/invoices.go:590 #: pkg/expenses.go:175 pkg/invoices.go:592
msgctxt "input" msgctxt "input"
msgid "Invoice Date" msgid "Invoice Date"
msgstr "Fecha de factura" msgstr "Fecha de factura"
@ -1061,7 +1066,7 @@ msgstr "Archivo"
msgid "Selected contact is not valid." msgid "Selected contact is not valid."
msgstr "Habéis escogido un contacto que no es válido." msgstr "Habéis escogido un contacto que no es válido."
#: pkg/expenses.go:226 pkg/invoices.go:645 #: pkg/expenses.go:226 pkg/invoices.go:647
msgid "Invoice date must be a valid date." msgid "Invoice date must be a valid date."
msgstr "La fecha de factura debe ser válida." msgstr "La fecha de factura debe ser válida."
@ -1078,28 +1083,38 @@ msgctxt "input"
msgid "Invoice Number" msgid "Invoice Number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/invoices.go:168 pkg/invoices.go:578 #: pkg/invoices.go:168 pkg/invoices.go:580
msgctxt "input" msgctxt "input"
msgid "Invoice Status" msgid "Invoice Status"
msgstr "Estado de la factura" msgstr "Estado de la factura"
#: pkg/invoices.go:426 #: pkg/invoices.go:428
msgid "Select a customer to bill." msgid "Select a customer to bill."
msgstr "Escoged un cliente a facturar." msgstr "Escoged un cliente a facturar."
#: pkg/invoices.go:527 #: pkg/invoices.go:529
msgid "invoices.zip" msgid "invoices.zip"
msgstr "facturas.zip" msgstr "facturas.zip"
#: pkg/invoices.go:642 #: pkg/invoices.go:644
msgid "Selected invoice status is not valid." msgid "Selected invoice status is not valid."
msgstr "Habéis escogido un estado de factura que no es válido." msgstr "Habéis escogido un estado de factura que no es válido."
#: pkg/invoices.go:644 #: pkg/invoices.go:646
msgid "Invoice date can not be empty." msgid "Invoice date can not be empty."
msgstr "No podéis dejar la fecha de la factura en blanco." msgstr "No podéis dejar la fecha de la factura en blanco."
#: pkg/invoices.go:915 #: pkg/invoices.go:782
#, c-format
msgid "Re: quotation #%s of %s"
msgstr "Ref: presupuesto n.º %s del %s"
#: pkg/invoices.go:783
msgctxt "to_char"
msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY"
#: pkg/invoices.go:942
msgid "Invoice product ID must be a number greater than zero." msgid "Invoice product ID must be a number greater than zero."
msgstr "El ID de producto de factura tiene que ser un número mayor a cero." msgstr "El ID de producto de factura tiene que ser un número mayor a cero."

View File

@ -127,6 +127,14 @@
{{( pgettext "Duplicate" "action" )}} {{( pgettext "Duplicate" "action" )}}
</a> </a>
</li> </li>
<li role="presentation">
<a role="menuitem" href="{{ companyURI "/invoices/new"}}?quote={{ .Slug }}"
data-hx-target="main" data-hx-boost="true"
>
<i class="ri-bill-line"></i>
{{( pgettext "Create invoice" "action" )}}
</a>
</li>
</ul> </ul>
</details> </details>
</td> </td>

View File

@ -11,6 +11,9 @@
<a>{{ .Number }}</a> <a>{{ .Number }}</a>
</p> </p>
<p> <p>
<a class="button primary"
data-hx-target="main" data-hx-boost="true"
href="{{ companyURI "/invoices/new"}}?quote={{ .Slug }}">{{( pgettext "Create invoice" "action" )}}</a>
<a class="button primary" <a class="button primary"
data-hx-target="main" data-hx-boost="true" data-hx-target="main" data-hx-boost="true"
href="{{ companyURI "/quotes/new"}}?duplicate={{ .Slug }}">{{( pgettext "Duplicate" "action" )}}</a> href="{{ companyURI "/quotes/new"}}?duplicate={{ .Slug }}">{{( pgettext "Duplicate" "action" )}}</a>