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 != "" {
form.MustFillFromDatabase(r.Context(), conn, invoiceToDuplicate)
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")
w.WriteHeader(http.StatusOK)
@ -774,6 +776,31 @@ func (form *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *Conn, s
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 {
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 ""
"Project-Id-Version: numerus\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"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n"
@ -65,7 +65,7 @@ msgstr "Nom"
#: web/template/invoices/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"
msgid "Price"
msgstr "Preu"
@ -95,15 +95,15 @@ msgstr "Desfes"
#: 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/quotes/view.gohtml:73 web/template/quotes/edit.gohtml:62
#: web/template/quotes/view.gohtml:76 web/template/quotes/edit.gohtml:62
msgctxt "title"
msgid "Subtotal"
msgstr "Subtotal"
#: 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/quotes/new.gohtml:71 web/template/quotes/view.gohtml:77
#: web/template/quotes/view.gohtml:117 web/template/quotes/edit.gohtml:72
#: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:80
#: web/template/quotes/view.gohtml:120 web/template/quotes/edit.gohtml:72
msgctxt "title"
msgid "Total"
msgstr "Total"
@ -146,7 +146,7 @@ msgid "All"
msgstr "Totes"
#: 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"
msgid "Date"
msgstr "Data"
@ -199,7 +199,7 @@ msgid "Select invoice %v"
msgstr "Selecciona factura %v"
#: 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/products/index.gohtml:72
msgctxt "action"
@ -207,7 +207,7 @@ msgid "Edit"
msgstr "Edita"
#: 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"
msgid "Duplicate"
msgstr "Duplica"
@ -226,22 +226,22 @@ msgctxt "action"
msgid "Download invoice"
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"
msgid "Concept"
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"
msgid "Discount"
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"
msgid "Units"
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"
msgid "Tax Base"
msgstr "Base imposable"
@ -339,21 +339,26 @@ msgctxt "action"
msgid "Select quotation %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."
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"
msgid "Quotation %s"
msgstr "Pressupost %s"
#: web/template/quotes/view.gohtml:22
#: web/template/quotes/view.gohtml:25
msgctxt "action"
msgid "Download quotation"
msgstr "Descarrega pressupost"
#: web/template/quotes/view.gohtml:60
#: web/template/quotes/view.gohtml:63
msgid "Terms and Conditions:"
msgstr "Condicions dacceptació:"
@ -645,7 +650,7 @@ msgstr "No podeu deixar la contrasenya en blanc."
msgid "Invalid user or password."
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
msgctxt "input"
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/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
msgctxt "input"
msgid "Tags"
@ -687,40 +692,40 @@ msgstr "Qualsevol"
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."
#: 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"
msgid "Description"
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"
msgid "Price"
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"
msgid "Taxes"
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."
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."
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."
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/invoices.go:930
#: pkg/invoices.go:957
msgid "Selected tax is not valid."
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/invoices.go:931
#: pkg/invoices.go:958
msgid "You can only select a tax of each class."
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."
#: 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"
msgid "Customer"
msgstr "Client"
@ -873,8 +878,8 @@ msgstr "Els pressuposts han de tenir com a mínim una de les etiquetes."
msgid "quotations.zip"
msgstr "pressuposts.zip"
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:533
#: pkg/invoices.go:1098 pkg/invoices.go:1106
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535
#: pkg/invoices.go:1125 pkg/invoices.go:1133
msgid "Invalid action"
msgstr "Acció invàlida."
@ -892,12 +897,12 @@ msgctxt "input"
msgid "Terms and conditions"
msgstr "Condicions dacceptació"
#: pkg/quote.go:603 pkg/invoices.go:596
#: pkg/quote.go:603 pkg/invoices.go:598
msgctxt "input"
msgid "Notes"
msgstr "Notes"
#: pkg/quote.go:612 pkg/invoices.go:606
#: pkg/quote.go:612 pkg/invoices.go:608
msgctxt "input"
msgid "Payment Method"
msgstr "Mètode de pagament"
@ -910,7 +915,7 @@ msgstr "Escolliu un mètode de pagament."
msgid "Selected quotation status is not valid."
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."
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."
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."
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"
msgid "Id"
msgstr "Identificador"
#: pkg/quote.go:829 pkg/invoices.go:852
#: pkg/quote.go:829 pkg/invoices.go:879
msgctxt "input"
msgid "Quantity"
msgstr "Quantitat"
#: pkg/quote.go:838 pkg/invoices.go:861
#: pkg/quote.go:838 pkg/invoices.go:888
msgctxt "input"
msgid "Discount (%)"
msgstr "Descompte (%)"
@ -945,23 +950,23 @@ msgstr "Descompte (%)"
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."
#: 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."
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."
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."
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."
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."
msgstr "El descompte ha de ser un percentatge entre 0 i 100."
@ -1042,7 +1047,7 @@ msgctxt "input"
msgid "Invoice number"
msgstr "Número de factura"
#: pkg/expenses.go:175 pkg/invoices.go:590
#: pkg/expenses.go:175 pkg/invoices.go:592
msgctxt "input"
msgid "Invoice Date"
msgstr "Data de factura"
@ -1061,7 +1066,7 @@ msgstr "Fitxer"
msgid "Selected contact is not valid."
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."
msgstr "La data de facturació ha de ser vàlida."
@ -1078,28 +1083,38 @@ msgctxt "input"
msgid "Invoice Number"
msgstr "Número de factura"
#: pkg/invoices.go:168 pkg/invoices.go:578
#: pkg/invoices.go:168 pkg/invoices.go:580
msgctxt "input"
msgid "Invoice Status"
msgstr "Estat de la factura"
#: pkg/invoices.go:426
#: pkg/invoices.go:428
msgid "Select a customer to bill."
msgstr "Escolliu un client a facturar."
#: pkg/invoices.go:527
#: pkg/invoices.go:529
msgid "invoices.zip"
msgstr "factures.zip"
#: pkg/invoices.go:642
#: pkg/invoices.go:644
msgid "Selected invoice status is not valid."
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."
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."
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 ""
"Project-Id-Version: numerus\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"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
@ -65,7 +65,7 @@ msgstr "Nombre"
#: web/template/invoices/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"
msgid "Price"
msgstr "Precio"
@ -95,15 +95,15 @@ msgstr "Deshacer"
#: 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/quotes/view.gohtml:73 web/template/quotes/edit.gohtml:62
#: web/template/quotes/view.gohtml:76 web/template/quotes/edit.gohtml:62
msgctxt "title"
msgid "Subtotal"
msgstr "Subtotal"
#: 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/quotes/new.gohtml:71 web/template/quotes/view.gohtml:77
#: web/template/quotes/view.gohtml:117 web/template/quotes/edit.gohtml:72
#: web/template/quotes/new.gohtml:71 web/template/quotes/view.gohtml:80
#: web/template/quotes/view.gohtml:120 web/template/quotes/edit.gohtml:72
msgctxt "title"
msgid "Total"
msgstr "Total"
@ -146,7 +146,7 @@ msgid "All"
msgstr "Todas"
#: 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"
msgid "Date"
msgstr "Fecha"
@ -199,7 +199,7 @@ msgid "Select invoice %v"
msgstr "Seleccionar factura %v"
#: 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/products/index.gohtml:72
msgctxt "action"
@ -207,7 +207,7 @@ msgid "Edit"
msgstr "Editar"
#: 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"
msgid "Duplicate"
msgstr "Duplicar"
@ -226,22 +226,22 @@ msgctxt "action"
msgid "Download invoice"
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"
msgid "Concept"
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"
msgid "Discount"
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"
msgid "Units"
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"
msgid "Tax Base"
msgstr "Base imponible"
@ -339,21 +339,26 @@ msgctxt "action"
msgid "Select quotation %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."
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"
msgid "Quotation %s"
msgstr "Estado del presupuesto"
#: web/template/quotes/view.gohtml:22
#: web/template/quotes/view.gohtml:25
msgctxt "action"
msgid "Download quotation"
msgstr "Descargar presupuesto"
#: web/template/quotes/view.gohtml:60
#: web/template/quotes/view.gohtml:63
msgid "Terms and Conditions:"
msgstr "Condiciones de aceptación:"
@ -645,7 +650,7 @@ msgstr "No podéis dejar la contraseña en blanco."
msgid "Invalid user or password."
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
msgctxt "input"
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/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
msgctxt "input"
msgid "Tags"
@ -687,40 +692,40 @@ msgstr "Cualquiera"
msgid "Invoices must have at least one of the specified labels."
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"
msgid "Description"
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"
msgid "Price"
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"
msgid "Taxes"
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."
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."
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."
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/invoices.go:930
#: pkg/invoices.go:957
msgid "Selected tax is not valid."
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/invoices.go:931
#: pkg/invoices.go:958
msgid "You can only select a tax of each class."
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."
#: 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"
msgid "Customer"
msgstr "Cliente"
@ -873,8 +878,8 @@ msgstr "Los presupuestos deben tener como mínimo una de las etiquetas."
msgid "quotations.zip"
msgstr "presupuestos.zip"
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:533
#: pkg/invoices.go:1098 pkg/invoices.go:1106
#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535
#: pkg/invoices.go:1125 pkg/invoices.go:1133
msgid "Invalid action"
msgstr "Acción inválida."
@ -892,12 +897,12 @@ msgctxt "input"
msgid "Terms and conditions"
msgstr "Condiciones de aceptación"
#: pkg/quote.go:603 pkg/invoices.go:596
#: pkg/quote.go:603 pkg/invoices.go:598
msgctxt "input"
msgid "Notes"
msgstr "Notas"
#: pkg/quote.go:612 pkg/invoices.go:606
#: pkg/quote.go:612 pkg/invoices.go:608
msgctxt "input"
msgid "Payment Method"
msgstr "Método de pago"
@ -910,7 +915,7 @@ msgstr "Escoged un método e pago."
msgid "Selected quotation status is not valid."
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."
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."
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."
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"
msgid "Id"
msgstr "Identificador"
#: pkg/quote.go:829 pkg/invoices.go:852
#: pkg/quote.go:829 pkg/invoices.go:879
msgctxt "input"
msgid "Quantity"
msgstr "Cantidad"
#: pkg/quote.go:838 pkg/invoices.go:861
#: pkg/quote.go:838 pkg/invoices.go:888
msgctxt "input"
msgid "Discount (%)"
msgstr "Descuento (%)"
@ -945,23 +950,23 @@ msgstr "Descuento (%)"
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."
#: 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."
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."
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."
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."
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."
msgstr "El descuento tiene que ser un porcentaje entre 0 y 100."
@ -1042,7 +1047,7 @@ msgctxt "input"
msgid "Invoice number"
msgstr "Número de factura"
#: pkg/expenses.go:175 pkg/invoices.go:590
#: pkg/expenses.go:175 pkg/invoices.go:592
msgctxt "input"
msgid "Invoice Date"
msgstr "Fecha de factura"
@ -1061,7 +1066,7 @@ msgstr "Archivo"
msgid "Selected contact is not valid."
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."
msgstr "La fecha de factura debe ser válida."
@ -1078,28 +1083,38 @@ msgctxt "input"
msgid "Invoice Number"
msgstr "Número de factura"
#: pkg/invoices.go:168 pkg/invoices.go:578
#: pkg/invoices.go:168 pkg/invoices.go:580
msgctxt "input"
msgid "Invoice Status"
msgstr "Estado de la factura"
#: pkg/invoices.go:426
#: pkg/invoices.go:428
msgid "Select a customer to bill."
msgstr "Escoged un cliente a facturar."
#: pkg/invoices.go:527
#: pkg/invoices.go:529
msgid "invoices.zip"
msgstr "facturas.zip"
#: pkg/invoices.go:642
#: pkg/invoices.go:644
msgid "Selected invoice status is not valid."
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."
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."
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" )}}
</a>
</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>
</details>
</td>

View File

@ -11,6 +11,9 @@
<a>{{ .Number }}</a>
</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"
data-hx-target="main" data-hx-boost="true"
href="{{ companyURI "/quotes/new"}}?duplicate={{ .Slug }}">{{( pgettext "Duplicate" "action" )}}</a>