Compare commits

...

2 Commits

Author SHA1 Message Date
jordi fita mas c3fa23727f Include customer’s VAT number to the expense list in ODS too
It was requested by Clara.
2024-07-20 22:52:23 +02:00
jordi fita mas 505fa0f154 Include customer’s VAT number to the invoice list in ODS
It was requested by Clara.
2024-07-20 22:52:23 +02:00
5 changed files with 153 additions and 87 deletions

View File

@ -741,9 +741,10 @@ func HandleBatchExpenseAction(w http.ResponseWriter, r *http.Request, _ httprout
return return
} }
entries := mustCollectExpenseEntries(r.Context(), conn, locale, filters) entries := mustCollectExpenseEntries(r.Context(), conn, locale, filters)
vatin := mustCollectExpenseEntriesVATIN(r.Context(), conn, entries)
taxes := mustCollectExpenseEntriesTaxes(r.Context(), conn, entries) taxes := mustCollectExpenseEntriesTaxes(r.Context(), conn, entries)
taxColumns := mustCollectTaxColumns(r.Context(), conn, company) taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
ods := mustWriteExpensesOds(entries, taxes, taxColumns, locale, company) ods := mustWriteExpensesOds(entries, vatin, taxes, taxColumns, locale, company)
writeOdsResponse(w, ods, gettext("expenses.ods", locale)) writeOdsResponse(w, ods, gettext("expenses.ods", locale))
default: default:
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
@ -764,3 +765,16 @@ func mustCollectExpenseEntriesTaxes(ctx context.Context, conn *Conn, entries []*
where expense_id = any ($1) where expense_id = any ($1)
`) `)
} }
func mustCollectExpenseEntriesVATIN(ctx context.Context, conn *Conn, entries []*ExpenseEntry) map[int]string {
ids := mustMakeIDArray(entries, func(entry *ExpenseEntry) int {
return entry.ID
})
return mustMakeVATINMap(ctx, conn, ids, `
select expense_id
, vatin::text
from contact_tax_details as tax
join expense using (contact_id)
where expense_id = any ($1)
`)
}

View File

@ -675,9 +675,10 @@ func HandleBatchInvoiceAction(w http.ResponseWriter, r *http.Request, _ httprout
return return
} }
entries := mustCollectInvoiceEntries(r.Context(), conn, locale, filters) entries := mustCollectInvoiceEntries(r.Context(), conn, locale, filters)
vatin := mustCollectInvoiceEntriesVATIN(r.Context(), conn, entries)
taxes := mustCollectInvoiceEntriesTaxes(r.Context(), conn, entries) taxes := mustCollectInvoiceEntriesTaxes(r.Context(), conn, entries)
taxColumns := mustCollectTaxColumns(r.Context(), conn, company) taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
ods := mustWriteInvoicesOds(entries, taxes, taxColumns, locale, company) ods := mustWriteInvoicesOds(entries, vatin, taxes, taxColumns, locale, company)
writeOdsResponse(w, ods, gettext("invoices.ods", locale)) writeOdsResponse(w, ods, gettext("invoices.ods", locale))
default: default:
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
@ -771,6 +772,43 @@ func mustMakeTaxMap(ctx context.Context, conn *Conn, ids *pgtype.Int4Array, sql
return taxes return taxes
} }
func mustCollectInvoiceEntriesVATIN(ctx context.Context, conn *Conn, entries []*InvoiceEntry) map[int]string {
ids := mustMakeIDArray(entries, func(entry *InvoiceEntry) int {
return entry.ID
})
return mustMakeVATINMap(ctx, conn, ids, `
select invoice_id
, vatin::text
from contact_tax_details
join invoice using (contact_id)
where invoice_id = any ($1)
`)
}
func mustMakeVATINMap(ctx context.Context, conn *Conn, ids *pgtype.Int4Array, sql string) map[int]string {
rows, err := conn.Query(ctx, sql, ids)
if err != nil {
panic(err)
}
defer rows.Close()
vatin := make(map[int]string)
for rows.Next() {
var entryID int
var number string
err := rows.Scan(&entryID, &number)
if err != nil {
panic(err)
}
vatin[entryID] = number
}
if rows.Err() != nil {
panic(rows.Err())
}
return vatin
}
func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte { func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte {
conn := getConn(r) conn := getConn(r)
company := mustGetCompany(r) company := mustGetCompany(r)

View File

@ -53,14 +53,15 @@ func extractTaxIDs(taxColumns map[int]string) []int {
return taxIDs return taxIDs
} }
func mustWriteInvoicesOds(invoices []*InvoiceEntry, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte { func mustWriteInvoicesOds(invoices []*InvoiceEntry, vatin map[int]string, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
taxIDs := extractTaxIDs(taxColumns) taxIDs := extractTaxIDs(taxColumns)
columns := make([]string, 6+len(taxIDs)) columns := make([]string, 7+len(taxIDs))
columns[0] = "Date" columns[0] = "Date"
columns[1] = "Invoice Num." columns[1] = "Invoice Num."
columns[2] = "Customer" columns[2] = "Customer"
columns[3] = "Status" columns[3] = pgettext("title", "VAT number", locale)
i := 4 columns[4] = "Status"
i := 5
for _, taxID := range taxIDs { for _, taxID := range taxIDs {
columns[i] = taxColumns[taxID] columns[i] = taxColumns[taxID]
i++ i++
@ -71,6 +72,7 @@ func mustWriteInvoicesOds(invoices []*InvoiceEntry, taxes map[int]taxMap, taxCol
writeCellDate(sb, invoice.Date) writeCellDate(sb, invoice.Date)
writeCellString(sb, invoice.Number) writeCellString(sb, invoice.Number)
writeCellString(sb, invoice.CustomerName) writeCellString(sb, invoice.CustomerName)
writeCellString(sb, vatin[invoice.ID])
writeCellString(sb, invoice.StatusLabel) writeCellString(sb, invoice.StatusLabel)
writeTaxes(sb, taxes[invoice.ID], taxIDs, locale, company) writeTaxes(sb, taxes[invoice.ID], taxIDs, locale, company)
writeCellFloat(sb, invoice.Total, locale, company) writeCellFloat(sb, invoice.Total, locale, company)
@ -97,15 +99,16 @@ func mustWriteQuotesOds(quotes []*QuoteEntry, locale *Locale, company *Company)
}) })
} }
func mustWriteExpensesOds(expenses []*ExpenseEntry, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte { func mustWriteExpensesOds(expenses []*ExpenseEntry, vatin map[int]string, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
taxIDs := extractTaxIDs(taxColumns) taxIDs := extractTaxIDs(taxColumns)
columns := make([]string, 7+len(taxIDs)) columns := make([]string, 8+len(taxIDs))
columns[0] = "Contact" columns[0] = "Contact"
columns[1] = "Invoice Date" columns[1] = pgettext("title", "VAT number", locale)
columns[2] = "Invoice Number" columns[2] = "Invoice Date"
columns[3] = "Status" columns[3] = "Invoice Number"
columns[4] = "Amount" columns[4] = "Status"
i := 5 columns[5] = "Amount"
i := 6
for _, taxID := range taxIDs { for _, taxID := range taxIDs {
columns[i] = taxColumns[taxID] columns[i] = taxColumns[taxID]
i++ i++
@ -115,6 +118,7 @@ func mustWriteExpensesOds(expenses []*ExpenseEntry, taxes map[int]taxMap, taxCol
return mustWriteTableOds(expenses, columns, locale, func(sb *strings.Builder, expense *ExpenseEntry) { return mustWriteTableOds(expenses, columns, locale, func(sb *strings.Builder, expense *ExpenseEntry) {
writeCellString(sb, expense.InvoicerName) writeCellString(sb, expense.InvoicerName)
writeCellString(sb, vatin[expense.ID])
writeCellDate(sb, expense.InvoiceDate) writeCellDate(sb, expense.InvoiceDate)
writeCellString(sb, expense.InvoiceNumber) writeCellString(sb, expense.InvoiceNumber)
writeCellString(sb, expense.StatusLabel) writeCellString(sb, expense.StatusLabel)

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: 2024-01-26 02:25+0100\n" "POT-Creation-Date: 2024-07-20 22:51+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"
@ -731,6 +731,11 @@ msgctxt "title"
msgid "Edit Product “%s”" msgid "Edit Product “%s”"
msgstr "Edició del producte «%s»" msgstr "Edició del producte «%s»"
#: pkg/ods.go:62 pkg/ods.go:106
msgctxt "title"
msgid "VAT number"
msgstr "DNI / NIF"
#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276 #: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276
msgctxt "input" msgctxt "input"
msgid "Email" msgid "Email"
@ -758,14 +763,14 @@ msgid "Invalid user or password."
msgstr "Nom dusuari o contrasenya incorrectes." msgstr "Nom dusuari o contrasenya incorrectes."
#: pkg/products.go:172 pkg/products.go:276 pkg/quote.go:901 #: pkg/products.go:172 pkg/products.go:276 pkg/quote.go:901
#: pkg/invoices.go:1109 pkg/contacts.go:149 pkg/contacts.go:262 #: pkg/invoices.go:1147 pkg/contacts.go:149 pkg/contacts.go:262
msgctxt "input" msgctxt "input"
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
#: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708 #: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708
#: pkg/expenses.go:343 pkg/expenses.go:511 pkg/invoices.go:177 #: pkg/expenses.go:343 pkg/expenses.go:511 pkg/invoices.go:177
#: pkg/invoices.go:839 pkg/invoices.go:1424 pkg/contacts.go:154 #: pkg/invoices.go:877 pkg/invoices.go:1462 pkg/contacts.go:154
#: pkg/contacts.go:362 #: pkg/contacts.go:362
msgctxt "input" msgctxt "input"
msgid "Tags" msgid "Tags"
@ -799,42 +804,42 @@ 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:282 pkg/quote.go:915 pkg/invoices.go:1123 #: pkg/products.go:282 pkg/quote.go:915 pkg/invoices.go:1161
msgctxt "input" msgctxt "input"
msgid "Description" msgid "Description"
msgstr "Descripció" msgstr "Descripció"
#: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1127 #: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1165
msgctxt "input" msgctxt "input"
msgid "Price" msgid "Price"
msgstr "Preu" msgstr "Preu"
#: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:311 #: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:311
#: pkg/invoices.go:1156 #: pkg/invoices.go:1194
msgctxt "input" msgctxt "input"
msgid "Taxes" msgid "Taxes"
msgstr "Imposts" msgstr "Imposts"
#: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1205 #: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1243
#: pkg/contacts.go:412 #: pkg/contacts.go:412
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:323 pkg/quote.go:998 pkg/invoices.go:1206 #: pkg/products.go:323 pkg/quote.go:998 pkg/invoices.go:1244
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:324 pkg/quote.go:999 pkg/invoices.go:1207 #: pkg/products.go:324 pkg/quote.go:999 pkg/invoices.go:1245
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:326 pkg/quote.go:1007 pkg/expenses.go:379 #: pkg/products.go:326 pkg/quote.go:1007 pkg/expenses.go:379
#: pkg/invoices.go:1215 #: pkg/invoices.go:1253
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:327 pkg/quote.go:1008 pkg/expenses.go:380 #: pkg/products.go:327 pkg/quote.go:1008 pkg/expenses.go:380
#: pkg/invoices.go:1216 #: pkg/invoices.go:1254
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."
@ -1043,7 +1048,7 @@ msgstr "No podeu deixar el nom del mètode de pagament en blanc."
msgid "Payment instructions can not be empty." 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:147 pkg/quote.go:686 pkg/invoices.go:150 pkg/invoices.go:822 #: pkg/quote.go:147 pkg/quote.go:686 pkg/invoices.go:150 pkg/invoices.go:860
msgctxt "input" msgctxt "input"
msgid "Customer" msgid "Customer"
msgstr "Client" msgstr "Client"
@ -1093,8 +1098,8 @@ msgid "quotations.ods"
msgstr "pressuposts.ods" msgstr "pressuposts.ods"
#: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:720 #: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:720
#: pkg/expenses.go:749 pkg/invoices.go:683 pkg/invoices.go:1399 #: pkg/expenses.go:750 pkg/invoices.go:684 pkg/invoices.go:1437
#: pkg/invoices.go:1407 #: pkg/invoices.go:1445
msgid "Invalid action" msgid "Invalid action"
msgstr "Acció invàlida." msgstr "Acció invàlida."
@ -1112,12 +1117,12 @@ msgctxt "input"
msgid "Terms and conditions" msgid "Terms and conditions"
msgstr "Condicions dacceptació" msgstr "Condicions dacceptació"
#: pkg/quote.go:703 pkg/invoices.go:834 #: pkg/quote.go:703 pkg/invoices.go:872
msgctxt "input" msgctxt "input"
msgid "Notes" msgid "Notes"
msgstr "Notes" msgstr "Notes"
#: pkg/quote.go:712 pkg/invoices.go:844 #: pkg/quote.go:712 pkg/invoices.go:882
msgctxt "input" msgctxt "input"
msgid "Payment Method" msgid "Payment Method"
msgstr "Mètode de pagament" msgstr "Mètode de pagament"
@ -1130,7 +1135,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:751 pkg/invoices.go:899 #: pkg/quote.go:751 pkg/invoices.go:937
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."
@ -1142,21 +1147,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:757 pkg/invoices.go:903 #: pkg/quote.go:757 pkg/invoices.go:941
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:891 pkg/quote.go:896 pkg/invoices.go:1099 pkg/invoices.go:1104 #: pkg/quote.go:891 pkg/quote.go:896 pkg/invoices.go:1137 pkg/invoices.go:1142
msgctxt "input" msgctxt "input"
msgid "Id" msgid "Id"
msgstr "Identificador" msgstr "Identificador"
#: pkg/quote.go:929 pkg/invoices.go:1137 #: pkg/quote.go:929 pkg/invoices.go:1175
msgctxt "input" msgctxt "input"
msgid "Quantity" msgid "Quantity"
msgstr "Quantitat" msgstr "Quantitat"
#: pkg/quote.go:938 pkg/invoices.go:1146 #: pkg/quote.go:938 pkg/invoices.go:1184
msgctxt "input" msgctxt "input"
msgid "Discount (%)" msgid "Discount (%)"
msgstr "Descompte (%)" msgstr "Descompte (%)"
@ -1165,23 +1170,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:995 pkg/invoices.go:1203 #: pkg/quote.go:995 pkg/invoices.go:1241
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:1001 pkg/invoices.go:1209 #: pkg/quote.go:1001 pkg/invoices.go:1247
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:1002 pkg/invoices.go:1210 #: pkg/quote.go:1002 pkg/invoices.go:1248
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:1004 pkg/invoices.go:1212 #: pkg/quote.go:1004 pkg/invoices.go:1250
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:1005 pkg/invoices.go:1213 #: pkg/quote.go:1005 pkg/invoices.go:1251
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."
@ -1262,7 +1267,7 @@ msgctxt "input"
msgid "Invoice number" msgid "Invoice number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:305 pkg/invoices.go:828 #: pkg/expenses.go:305 pkg/invoices.go:866
msgctxt "input" msgctxt "input"
msgid "Invoice Date" msgid "Invoice Date"
msgstr "Data de factura" msgstr "Data de factura"
@ -1272,7 +1277,7 @@ msgctxt "input"
msgid "Amount" msgid "Amount"
msgstr "Import" msgstr "Import"
#: pkg/expenses.go:331 pkg/invoices.go:850 #: pkg/expenses.go:331 pkg/invoices.go:888
msgctxt "input" msgctxt "input"
msgid "File" msgid "File"
msgstr "Fitxer" msgstr "Fitxer"
@ -1286,7 +1291,7 @@ msgstr "Estat de la despesa"
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:378 pkg/invoices.go:901 #: pkg/expenses.go:378 pkg/invoices.go:939
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."
@ -1311,11 +1316,11 @@ msgctxt "input"
msgid "Invoice Number" msgid "Invoice Number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:747 #: pkg/expenses.go:748
msgid "expenses.ods" msgid "expenses.ods"
msgstr "despeses.ods" msgstr "despeses.ods"
#: pkg/invoices.go:156 pkg/invoices.go:816 #: pkg/invoices.go:156 pkg/invoices.go:854
msgctxt "input" msgctxt "input"
msgid "Invoice Status" msgid "Invoice Status"
msgstr "Estat de la factura" msgstr "Estat de la factura"
@ -1328,29 +1333,29 @@ msgstr "Escolliu un client a facturar."
msgid "invoices.zip" msgid "invoices.zip"
msgstr "factures.zip" msgstr "factures.zip"
#: pkg/invoices.go:681 #: pkg/invoices.go:682
msgid "invoices.ods" msgid "invoices.ods"
msgstr "factures.ods" msgstr "factures.ods"
#: pkg/invoices.go:898 #: pkg/invoices.go:936
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:900 #: pkg/invoices.go:938
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:1036 #: pkg/invoices.go:1074
#, c-format #, c-format
msgid "Re: quotation #%s of %s" msgid "Re: quotation #%s of %s"
msgstr "Ref: pressupost núm. %s del %s" msgstr "Ref: pressupost núm. %s del %s"
#: pkg/invoices.go:1037 #: pkg/invoices.go:1075
msgctxt "to_char" msgctxt "to_char"
msgid "MM/DD/YYYY" msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY" msgstr "DD/MM/YYYY"
#: pkg/invoices.go:1200 #: pkg/invoices.go:1238
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."

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: 2024-01-26 02:25+0100\n" "POT-Creation-Date: 2024-07-20 22:51+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"
@ -731,6 +731,11 @@ msgctxt "title"
msgid "Edit Product “%s”" msgid "Edit Product “%s”"
msgstr "Edición del producto «%s»" msgstr "Edición del producto «%s»"
#: pkg/ods.go:62 pkg/ods.go:106
msgctxt "title"
msgid "VAT number"
msgstr "DNI / NIF"
#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276 #: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276
msgctxt "input" msgctxt "input"
msgid "Email" msgid "Email"
@ -758,14 +763,14 @@ 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:172 pkg/products.go:276 pkg/quote.go:901 #: pkg/products.go:172 pkg/products.go:276 pkg/quote.go:901
#: pkg/invoices.go:1109 pkg/contacts.go:149 pkg/contacts.go:262 #: pkg/invoices.go:1147 pkg/contacts.go:149 pkg/contacts.go:262
msgctxt "input" msgctxt "input"
msgid "Name" msgid "Name"
msgstr "Nombre" msgstr "Nombre"
#: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708 #: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708
#: pkg/expenses.go:343 pkg/expenses.go:511 pkg/invoices.go:177 #: pkg/expenses.go:343 pkg/expenses.go:511 pkg/invoices.go:177
#: pkg/invoices.go:839 pkg/invoices.go:1424 pkg/contacts.go:154 #: pkg/invoices.go:877 pkg/invoices.go:1462 pkg/contacts.go:154
#: pkg/contacts.go:362 #: pkg/contacts.go:362
msgctxt "input" msgctxt "input"
msgid "Tags" msgid "Tags"
@ -799,42 +804,42 @@ 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:282 pkg/quote.go:915 pkg/invoices.go:1123 #: pkg/products.go:282 pkg/quote.go:915 pkg/invoices.go:1161
msgctxt "input" msgctxt "input"
msgid "Description" msgid "Description"
msgstr "Descripción" msgstr "Descripción"
#: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1127 #: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1165
msgctxt "input" msgctxt "input"
msgid "Price" msgid "Price"
msgstr "Precio" msgstr "Precio"
#: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:311 #: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:311
#: pkg/invoices.go:1156 #: pkg/invoices.go:1194
msgctxt "input" msgctxt "input"
msgid "Taxes" msgid "Taxes"
msgstr "Impuestos" msgstr "Impuestos"
#: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1205 #: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1243
#: pkg/contacts.go:412 #: pkg/contacts.go:412
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:323 pkg/quote.go:998 pkg/invoices.go:1206 #: pkg/products.go:323 pkg/quote.go:998 pkg/invoices.go:1244
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:324 pkg/quote.go:999 pkg/invoices.go:1207 #: pkg/products.go:324 pkg/quote.go:999 pkg/invoices.go:1245
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:326 pkg/quote.go:1007 pkg/expenses.go:379 #: pkg/products.go:326 pkg/quote.go:1007 pkg/expenses.go:379
#: pkg/invoices.go:1215 #: pkg/invoices.go:1253
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:327 pkg/quote.go:1008 pkg/expenses.go:380 #: pkg/products.go:327 pkg/quote.go:1008 pkg/expenses.go:380
#: pkg/invoices.go:1216 #: pkg/invoices.go:1254
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."
@ -1043,7 +1048,7 @@ msgstr "No podéis dejar el nombre del método de pago en blanco."
msgid "Payment instructions can not be empty." 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:147 pkg/quote.go:686 pkg/invoices.go:150 pkg/invoices.go:822 #: pkg/quote.go:147 pkg/quote.go:686 pkg/invoices.go:150 pkg/invoices.go:860
msgctxt "input" msgctxt "input"
msgid "Customer" msgid "Customer"
msgstr "Cliente" msgstr "Cliente"
@ -1093,8 +1098,8 @@ msgid "quotations.ods"
msgstr "presupuestos.ods" msgstr "presupuestos.ods"
#: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:720 #: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:720
#: pkg/expenses.go:749 pkg/invoices.go:683 pkg/invoices.go:1399 #: pkg/expenses.go:750 pkg/invoices.go:684 pkg/invoices.go:1437
#: pkg/invoices.go:1407 #: pkg/invoices.go:1445
msgid "Invalid action" msgid "Invalid action"
msgstr "Acción inválida." msgstr "Acción inválida."
@ -1112,12 +1117,12 @@ msgctxt "input"
msgid "Terms and conditions" msgid "Terms and conditions"
msgstr "Condiciones de aceptación" msgstr "Condiciones de aceptación"
#: pkg/quote.go:703 pkg/invoices.go:834 #: pkg/quote.go:703 pkg/invoices.go:872
msgctxt "input" msgctxt "input"
msgid "Notes" msgid "Notes"
msgstr "Notas" msgstr "Notas"
#: pkg/quote.go:712 pkg/invoices.go:844 #: pkg/quote.go:712 pkg/invoices.go:882
msgctxt "input" msgctxt "input"
msgid "Payment Method" msgid "Payment Method"
msgstr "Método de pago" msgstr "Método de pago"
@ -1130,7 +1135,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:751 pkg/invoices.go:899 #: pkg/quote.go:751 pkg/invoices.go:937
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."
@ -1142,21 +1147,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:757 pkg/invoices.go:903 #: pkg/quote.go:757 pkg/invoices.go:941
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:891 pkg/quote.go:896 pkg/invoices.go:1099 pkg/invoices.go:1104 #: pkg/quote.go:891 pkg/quote.go:896 pkg/invoices.go:1137 pkg/invoices.go:1142
msgctxt "input" msgctxt "input"
msgid "Id" msgid "Id"
msgstr "Identificador" msgstr "Identificador"
#: pkg/quote.go:929 pkg/invoices.go:1137 #: pkg/quote.go:929 pkg/invoices.go:1175
msgctxt "input" msgctxt "input"
msgid "Quantity" msgid "Quantity"
msgstr "Cantidad" msgstr "Cantidad"
#: pkg/quote.go:938 pkg/invoices.go:1146 #: pkg/quote.go:938 pkg/invoices.go:1184
msgctxt "input" msgctxt "input"
msgid "Discount (%)" msgid "Discount (%)"
msgstr "Descuento (%)" msgstr "Descuento (%)"
@ -1165,23 +1170,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:995 pkg/invoices.go:1203 #: pkg/quote.go:995 pkg/invoices.go:1241
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:1001 pkg/invoices.go:1209 #: pkg/quote.go:1001 pkg/invoices.go:1247
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:1002 pkg/invoices.go:1210 #: pkg/quote.go:1002 pkg/invoices.go:1248
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:1004 pkg/invoices.go:1212 #: pkg/quote.go:1004 pkg/invoices.go:1250
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:1005 pkg/invoices.go:1213 #: pkg/quote.go:1005 pkg/invoices.go:1251
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."
@ -1262,7 +1267,7 @@ msgctxt "input"
msgid "Invoice number" msgid "Invoice number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:305 pkg/invoices.go:828 #: pkg/expenses.go:305 pkg/invoices.go:866
msgctxt "input" msgctxt "input"
msgid "Invoice Date" msgid "Invoice Date"
msgstr "Fecha de factura" msgstr "Fecha de factura"
@ -1272,7 +1277,7 @@ msgctxt "input"
msgid "Amount" msgid "Amount"
msgstr "Importe" msgstr "Importe"
#: pkg/expenses.go:331 pkg/invoices.go:850 #: pkg/expenses.go:331 pkg/invoices.go:888
msgctxt "input" msgctxt "input"
msgid "File" msgid "File"
msgstr "Archivo" msgstr "Archivo"
@ -1286,7 +1291,7 @@ msgstr "Estado del gasto"
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:378 pkg/invoices.go:901 #: pkg/expenses.go:378 pkg/invoices.go:939
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."
@ -1311,11 +1316,11 @@ msgctxt "input"
msgid "Invoice Number" msgid "Invoice Number"
msgstr "Número de factura" msgstr "Número de factura"
#: pkg/expenses.go:747 #: pkg/expenses.go:748
msgid "expenses.ods" msgid "expenses.ods"
msgstr "gastos.ods" msgstr "gastos.ods"
#: pkg/invoices.go:156 pkg/invoices.go:816 #: pkg/invoices.go:156 pkg/invoices.go:854
msgctxt "input" msgctxt "input"
msgid "Invoice Status" msgid "Invoice Status"
msgstr "Estado de la factura" msgstr "Estado de la factura"
@ -1328,29 +1333,29 @@ msgstr "Escoged un cliente a facturar."
msgid "invoices.zip" msgid "invoices.zip"
msgstr "facturas.zip" msgstr "facturas.zip"
#: pkg/invoices.go:681 #: pkg/invoices.go:682
msgid "invoices.ods" msgid "invoices.ods"
msgstr "facturas.ods" msgstr "facturas.ods"
#: pkg/invoices.go:898 #: pkg/invoices.go:936
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:900 #: pkg/invoices.go:938
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:1036 #: pkg/invoices.go:1074
#, c-format #, c-format
msgid "Re: quotation #%s of %s" msgid "Re: quotation #%s of %s"
msgstr "Ref: presupuesto n.º %s del %s" msgstr "Ref: presupuesto n.º %s del %s"
#: pkg/invoices.go:1037 #: pkg/invoices.go:1075
msgctxt "to_char" msgctxt "to_char"
msgid "MM/DD/YYYY" msgid "MM/DD/YYYY"
msgstr "DD/MM/YYYY" msgstr "DD/MM/YYYY"
#: pkg/invoices.go:1200 #: pkg/invoices.go:1238
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."