diff --git a/pkg/expenses.go b/pkg/expenses.go index 9b4ce44..e821add 100644 --- a/pkg/expenses.go +++ b/pkg/expenses.go @@ -23,8 +23,9 @@ type ExpenseEntry struct { } type expensesIndexPage struct { - Expenses []*ExpenseEntry - Filters *expenseFilterForm + Expenses []*ExpenseEntry + TotalAmount string + Filters *expenseFilterForm } func IndexExpenses(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { @@ -37,42 +38,15 @@ func IndexExpenses(w http.ResponseWriter, r *http.Request, _ httprouter.Params) return } page := &expensesIndexPage{ - Expenses: mustCollectExpenseEntries(r.Context(), conn, company, filters), - Filters: filters, + Expenses: mustCollectExpenseEntries(r.Context(), conn, company, filters), + TotalAmount: mustComputeExpensesTotalAmount(r.Context(), conn, filters), + Filters: filters, } mustRenderMainTemplate(w, r, "expenses/index.gohtml", page) } func mustCollectExpenseEntries(ctx context.Context, conn *Conn, company *Company, filters *expenseFilterForm) []*ExpenseEntry { - args := []interface{}{company.Id} - where := []string{"expense.company_id = $1"} - appendWhere := func(expression string, value interface{}) { - args = append(args, value) - where = append(where, fmt.Sprintf(expression, len(args))) - } - maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { - if value != "" { - if conv == nil { - appendWhere(expression, value) - } else { - appendWhere(expression, conv(value)) - } - } - } - maybeAppendWhere("contact_id = $%d", filters.Contact.String(), func(v string) interface{} { - customerId, _ := strconv.Atoi(filters.Contact.Selected[0]) - return customerId - }) - maybeAppendWhere("invoice_number = $%d", filters.InvoiceNumber.String(), nil) - maybeAppendWhere("invoice_date >= $%d", filters.FromDate.String(), nil) - maybeAppendWhere("invoice_date <= $%d", filters.ToDate.String(), nil) - if len(filters.Tags.Tags) > 0 { - if filters.TagsCondition.Selected == "and" { - appendWhere("expense.tags @> $%d", filters.Tags) - } else { - appendWhere("expense.tags && $%d", filters.Tags) - } - } + where, args := filters.BuildQuery(nil) rows := conn.MustQuery(ctx, fmt.Sprintf(` select expense.slug , invoice_date @@ -87,7 +61,7 @@ func mustCollectExpenseEntries(ctx context.Context, conn *Conn, company *Company join currency using (currency_code) where (%s) order by invoice_date - `, strings.Join(where, ") AND (")), args...) + `, where), args...) defer rows.Close() var entries []*ExpenseEntry @@ -104,6 +78,18 @@ func mustCollectExpenseEntries(ctx context.Context, conn *Conn, company *Company return entries } + +func mustComputeExpensesTotalAmount(ctx context.Context, conn *Conn, filters *expenseFilterForm) string { + where, args := filters.BuildQuery(nil) + return conn.MustGetText(ctx, "0", fmt.Sprintf(` + select to_price(sum(amount)::integer, decimal_digits) + from expense + join currency using (currency_code) + where (%s) + group by decimal_digits + `, where), args...) +} + func ServeExpenseForm(w http.ResponseWriter, r *http.Request, params httprouter.Params) { locale := getLocale(r) conn := getConn(r) @@ -391,6 +377,41 @@ func (form *expenseFilterForm) Parse(r *http.Request) error { return nil } +func (form *expenseFilterForm) BuildQuery(args []interface{}) (string, []interface{}) { + var where []string + appendWhere := func(expression string, value interface{}) { + args = append(args, value) + where = append(where, fmt.Sprintf(expression, len(args))) + } + maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { + if value != "" { + if conv == nil { + appendWhere(expression, value) + } else { + appendWhere(expression, conv(value)) + } + } + } + + appendWhere("expense.company_id = $%d", form.company.Id) + maybeAppendWhere("contact_id = $%d", form.Contact.String(), func(v string) interface{} { + customerId, _ := strconv.Atoi(form.Contact.Selected[0]) + return customerId + }) + maybeAppendWhere("invoice_number = $%d", form.InvoiceNumber.String(), nil) + maybeAppendWhere("invoice_date >= $%d", form.FromDate.String(), nil) + maybeAppendWhere("invoice_date <= $%d", form.ToDate.String(), nil) + if len(form.Tags.Tags) > 0 { + if form.TagsCondition.Selected == "and" { + appendWhere("expense.tags @> $%d", form.Tags) + } else { + appendWhere("expense.tags && $%d", form.Tags) + } + } + + return strings.Join(where, ") AND ("), args +} + func ServeEditExpenseTags(w http.ResponseWriter, r *http.Request, params httprouter.Params) { conn := getConn(r) locale := getLocale(r) diff --git a/pkg/invoices.go b/pkg/invoices.go index da67717..b30f257 100644 --- a/pkg/invoices.go +++ b/pkg/invoices.go @@ -35,6 +35,7 @@ type InvoiceEntry struct { type InvoicesIndexPage struct { Invoices []*InvoiceEntry + TotalAmount string Filters *invoiceFilterForm InvoiceStatuses map[string]string } @@ -49,44 +50,16 @@ func IndexInvoices(w http.ResponseWriter, r *http.Request, _ httprouter.Params) return } page := &InvoicesIndexPage{ - Invoices: mustCollectInvoiceEntries(r.Context(), conn, company, locale, filters), + Invoices: mustCollectInvoiceEntries(r.Context(), conn, locale, filters), + TotalAmount: mustComputeInvoicesTotalAmount(r.Context(), conn, filters), Filters: filters, InvoiceStatuses: mustCollectInvoiceStatuses(r.Context(), conn, locale), } mustRenderMainTemplate(w, r, "invoices/index.gohtml", page) } -func mustCollectInvoiceEntries(ctx context.Context, conn *Conn, company *Company, locale *Locale, filters *invoiceFilterForm) []*InvoiceEntry { - args := []interface{}{locale.Language.String(), company.Id} - where := []string{"invoice.company_id = $2"} - appendWhere := func(expression string, value interface{}) { - args = append(args, value) - where = append(where, fmt.Sprintf(expression, len(args))) - } - maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { - if value != "" { - if conv == nil { - appendWhere(expression, value) - } else { - appendWhere(expression, conv(value)) - } - } - } - maybeAppendWhere("contact_id = $%d", filters.Customer.String(), func(v string) interface{} { - customerId, _ := strconv.Atoi(filters.Customer.Selected[0]) - return customerId - }) - maybeAppendWhere("invoice.invoice_status = $%d", filters.InvoiceStatus.String(), nil) - maybeAppendWhere("invoice_number = $%d", filters.InvoiceNumber.String(), nil) - maybeAppendWhere("invoice_date >= $%d", filters.FromDate.String(), nil) - maybeAppendWhere("invoice_date <= $%d", filters.ToDate.String(), nil) - if len(filters.Tags.Tags) > 0 { - if filters.TagsCondition.Selected == "and" { - appendWhere("invoice.tags @> $%d", filters.Tags) - } else { - appendWhere("invoice.tags && $%d", filters.Tags) - } - } +func mustCollectInvoiceEntries(ctx context.Context, conn *Conn, locale *Locale, filters *invoiceFilterForm) []*InvoiceEntry { + where, args := filters.BuildQuery([]interface{}{locale.Language.String()}) rows := conn.MustQuery(ctx, fmt.Sprintf(` select invoice.slug , invoice_date @@ -104,7 +77,7 @@ func mustCollectInvoiceEntries(ctx context.Context, conn *Conn, company *Company where (%s) order by invoice_date desc , invoice_number desc - `, strings.Join(where, ") AND (")), args...) + `, where), args...) defer rows.Close() var entries []*InvoiceEntry @@ -122,6 +95,18 @@ func mustCollectInvoiceEntries(ctx context.Context, conn *Conn, company *Company return entries } +func mustComputeInvoicesTotalAmount(ctx context.Context, conn *Conn, filters *invoiceFilterForm) string { + where, args := filters.BuildQuery(nil) + return conn.MustGetText(ctx, "0", fmt.Sprintf(` + select to_price(sum(total)::integer, decimal_digits) + from invoice + join invoice_amount using (invoice_id) + join currency using (currency_code) + where (%s) + group by decimal_digits + `, where), args...) +} + func mustCollectInvoiceStatuses(ctx context.Context, conn *Conn, locale *Locale) map[string]string { rows := conn.MustQuery(ctx, "select invoice_status.invoice_status, isi18n.name from invoice_status join invoice_status_i18n isi18n using(invoice_status) where isi18n.lang_tag = $1 order by invoice_status", locale.Language.String()) defer rows.Close() @@ -159,7 +144,7 @@ func newInvoiceFilterForm(ctx context.Context, conn *Conn, locale *Locale, compa company: company, Customer: &SelectField{ Name: "customer", - Label: pgettext("input", "Customer", locale), + Label: pgettext("input", "Contact", locale), EmptyLabel: gettext("All customers", locale), Options: mustGetContactOptions(ctx, conn, company), }, @@ -220,6 +205,41 @@ func (form *invoiceFilterForm) Parse(r *http.Request) error { return nil } +func (form *invoiceFilterForm) BuildQuery(args []interface{}) (string, []interface{}) { + var where []string + appendWhere := func(expression string, value interface{}) { + args = append(args, value) + where = append(where, fmt.Sprintf(expression, len(args))) + } + maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { + if value != "" { + if conv == nil { + appendWhere(expression, value) + } else { + appendWhere(expression, conv(value)) + } + } + } + + appendWhere("invoice.company_id = $%d", form.company.Id) + maybeAppendWhere("contact_id = $%d", form.Customer.String(), func(v string) interface{} { + customerId, _ := strconv.Atoi(form.Customer.Selected[0]) + return customerId + }) + maybeAppendWhere("invoice.invoice_status = $%d", form.InvoiceStatus.String(), nil) + maybeAppendWhere("invoice_number = $%d", form.InvoiceNumber.String(), nil) + maybeAppendWhere("invoice_date >= $%d", form.FromDate.String(), nil) + maybeAppendWhere("invoice_date <= $%d", form.ToDate.String(), nil) + if len(form.Tags.Tags) > 0 { + if form.TagsCondition.Selected == "and" { + appendWhere("invoice.tags @> $%d", form.Tags) + } else { + appendWhere("invoice.tags && $%d", form.Tags) + } + } + return strings.Join(where, ") AND ("), args +} + func ServeInvoice(w http.ResponseWriter, r *http.Request, params httprouter.Params) { conn := getConn(r) company := mustGetCompany(r) @@ -583,7 +603,7 @@ func newInvoiceForm(ctx context.Context, conn *Conn, locale *Locale, company *Co }, Customer: &SelectField{ Name: "customer", - Label: pgettext("input", "Customer", locale), + Label: pgettext("input", "Contact", locale), Required: true, Options: mustGetContactOptions(ctx, conn, company), }, diff --git a/pkg/quote.go b/pkg/quote.go index fa277d0..cafa280 100644 --- a/pkg/quote.go +++ b/pkg/quote.go @@ -33,6 +33,7 @@ type QuoteEntry struct { type QuotesIndexPage struct { Quotes []*QuoteEntry + TotalAmount string Filters *quoteFilterForm QuoteStatuses map[string]string } @@ -47,44 +48,16 @@ func IndexQuotes(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { return } page := &QuotesIndexPage{ - Quotes: mustCollectQuoteEntries(r.Context(), conn, company, locale, filters), + Quotes: mustCollectQuoteEntries(r.Context(), conn, locale, filters), + TotalAmount: mustComputeQuotesTotalAmount(r.Context(), conn, filters), Filters: filters, QuoteStatuses: mustCollectQuoteStatuses(r.Context(), conn, locale), } mustRenderMainTemplate(w, r, "quotes/index.gohtml", page) } -func mustCollectQuoteEntries(ctx context.Context, conn *Conn, company *Company, locale *Locale, filters *quoteFilterForm) []*QuoteEntry { - args := []interface{}{locale.Language.String(), company.Id} - where := []string{"quote.company_id = $2"} - appendWhere := func(expression string, value interface{}) { - args = append(args, value) - where = append(where, fmt.Sprintf(expression, len(args))) - } - maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { - if value != "" { - if conv == nil { - appendWhere(expression, value) - } else { - appendWhere(expression, conv(value)) - } - } - } - maybeAppendWhere("contact_id = $%d", filters.Customer.String(), func(v string) interface{} { - customerId, _ := strconv.Atoi(filters.Customer.Selected[0]) - return customerId - }) - maybeAppendWhere("quote.quote_status = $%d", filters.QuoteStatus.String(), nil) - maybeAppendWhere("quote_number = $%d", filters.QuoteNumber.String(), nil) - maybeAppendWhere("quote_date >= $%d", filters.FromDate.String(), nil) - maybeAppendWhere("quote_date <= $%d", filters.ToDate.String(), nil) - if len(filters.Tags.Tags) > 0 { - if filters.TagsCondition.Selected == "and" { - appendWhere("quote.tags @> $%d", filters.Tags) - } else { - appendWhere("quote.tags && $%d", filters.Tags) - } - } +func mustCollectQuoteEntries(ctx context.Context, conn *Conn, locale *Locale, filters *quoteFilterForm) []*QuoteEntry { + where, args := filters.BuildQuery([]interface{}{locale.Language.String()}) rows := conn.MustQuery(ctx, fmt.Sprintf(` select quote.slug , quote_date @@ -103,7 +76,7 @@ func mustCollectQuoteEntries(ctx context.Context, conn *Conn, company *Company, where (%s) order by quote_date desc , quote_number desc - `, strings.Join(where, ") AND (")), args...) + `, where), args...) defer rows.Close() var entries []*QuoteEntry @@ -121,6 +94,19 @@ func mustCollectQuoteEntries(ctx context.Context, conn *Conn, company *Company, return entries } +func mustComputeQuotesTotalAmount(ctx context.Context, conn *Conn, filters *quoteFilterForm) string { + where, args := filters.BuildQuery(nil) + return conn.MustGetText(ctx, "0", fmt.Sprintf(` + select to_price(sum(total)::integer, decimal_digits) + from quote + left join quote_contact using (quote_id) + join quote_amount using (quote_id) + join currency using (currency_code) + where (%s) + group by decimal_digits + `, where), args...) +} + func mustCollectQuoteStatuses(ctx context.Context, conn *Conn, locale *Locale) map[string]string { rows := conn.MustQuery(ctx, "select quote_status.quote_status, isi18n.name from quote_status join quote_status_i18n isi18n using(quote_status) where isi18n.lang_tag = $1 order by quote_status", locale.Language.String()) defer rows.Close() @@ -158,7 +144,7 @@ func newQuoteFilterForm(ctx context.Context, conn *Conn, locale *Locale, company company: company, Customer: &SelectField{ Name: "customer", - Label: pgettext("input", "Customer", locale), + Label: pgettext("input", "Contact", locale), EmptyLabel: gettext("All customers", locale), Options: mustGetContactOptions(ctx, conn, company), }, @@ -219,6 +205,42 @@ func (form *quoteFilterForm) Parse(r *http.Request) error { return nil } +func (form *quoteFilterForm) BuildQuery(args []interface{}) (string, []interface{}) { + var where []string + appendWhere := func(expression string, value interface{}) { + args = append(args, value) + where = append(where, fmt.Sprintf(expression, len(args))) + } + maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) { + if value != "" { + if conv == nil { + appendWhere(expression, value) + } else { + appendWhere(expression, conv(value)) + } + } + } + + appendWhere("quote.company_id = $%d", form.company.Id) + maybeAppendWhere("contact_id = $%d", form.Customer.String(), func(v string) interface{} { + customerId, _ := strconv.Atoi(form.Customer.Selected[0]) + return customerId + }) + maybeAppendWhere("quote.quote_status = $%d", form.QuoteStatus.String(), nil) + maybeAppendWhere("quote_number = $%d", form.QuoteNumber.String(), nil) + maybeAppendWhere("quote_date >= $%d", form.FromDate.String(), nil) + maybeAppendWhere("quote_date <= $%d", form.ToDate.String(), nil) + if len(form.Tags.Tags) > 0 { + if form.TagsCondition.Selected == "and" { + appendWhere("quote.tags @> $%d", form.Tags) + } else { + appendWhere("quote.tags && $%d", form.Tags) + } + } + + return strings.Join(where, ") AND ("), args +} + func ServeQuote(w http.ResponseWriter, r *http.Request, params httprouter.Params) { conn := getConn(r) company := mustGetCompany(r) @@ -583,7 +605,7 @@ func newQuoteForm(ctx context.Context, conn *Conn, locale *Locale, company *Comp }, Customer: &SelectField{ Name: "customer", - Label: pgettext("input", "Customer", locale), + Label: pgettext("input", "Contact", locale), EmptyLabel: gettext("Select a customer to quote.", locale), Options: mustGetContactOptions(ctx, conn, company), }, diff --git a/po/ca.po b/po/ca.po index 4e29275..3696ba3 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: numerus\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-06-20 10:48+0200\n" +"POT-Creation-Date: 2023-06-20 11:29+0200\n" "PO-Revision-Date: 2023-01-18 17:08+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -157,10 +157,9 @@ msgid "Invoice Num." msgstr "Núm. factura" #: web/template/invoices/index.gohtml:52 web/template/quotes/index.gohtml:52 -#: web/template/contacts/index.gohtml:40 web/template/expenses/index.gohtml:43 msgctxt "title" -msgid "Contact" -msgstr "Contacte" +msgid "Customer" +msgstr "Client" #: web/template/invoices/index.gohtml:53 web/template/quotes/index.gohtml:53 msgctxt "title" @@ -216,6 +215,11 @@ msgstr "Duplica" msgid "No invoices added yet." msgstr "No hi ha cap factura." +#: web/template/invoices/index.gohtml:144 web/template/quotes/index.gohtml:152 +#: web/template/expenses/index.gohtml:105 +msgid "Total" +msgstr "Total" + #: web/template/invoices/view.gohtml:2 web/template/invoices/view.gohtml:33 msgctxt "title" msgid "Invoice %s" @@ -449,6 +453,11 @@ msgctxt "action" msgid "New contact" msgstr "Nou contacte" +#: web/template/contacts/index.gohtml:40 web/template/expenses/index.gohtml:43 +msgctxt "title" +msgid "Contact" +msgstr "Contacte" + #: web/template/contacts/index.gohtml:41 msgctxt "title" msgid "Email" @@ -665,82 +674,82 @@ msgstr "No podeu deixar la contrasenya en blanc." msgid "Invalid user or password." msgstr "Nom d’usuari o contrasenya incorrectes." -#: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:801 pkg/invoices.go:851 +#: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:823 pkg/invoices.go:871 #: pkg/contacts.go:135 msgctxt "input" msgid "Name" 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:603 pkg/invoices.go:1150 pkg/contacts.go:140 +#: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:174 pkg/quote.go:630 +#: pkg/expenses.go:188 pkg/expenses.go:347 pkg/invoices.go:174 +#: pkg/invoices.go:623 pkg/invoices.go:1170 pkg/contacts.go:140 #: pkg/contacts.go:325 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:173 pkg/quote.go:192 pkg/expenses.go:365 pkg/invoices.go:193 +#: pkg/products.go:173 pkg/quote.go:178 pkg/expenses.go:351 pkg/invoices.go:178 #: pkg/contacts.go:144 msgctxt "input" msgid "Tags Condition" msgstr "Condició de les etiquetes" -#: pkg/products.go:177 pkg/quote.go:196 pkg/expenses.go:369 pkg/invoices.go:197 +#: pkg/products.go:177 pkg/quote.go:182 pkg/expenses.go:355 pkg/invoices.go:182 #: pkg/contacts.go:148 msgctxt "tag condition" msgid "All" msgstr "Totes" -#: pkg/products.go:178 pkg/expenses.go:370 pkg/invoices.go:198 +#: pkg/products.go:178 pkg/expenses.go:356 pkg/invoices.go:183 #: pkg/contacts.go:149 msgid "Invoices must have all the specified labels." msgstr "Les factures han de tenir totes les etiquetes." -#: pkg/products.go:182 pkg/quote.go:201 pkg/expenses.go:374 pkg/invoices.go:202 +#: pkg/products.go:182 pkg/quote.go:187 pkg/expenses.go:360 pkg/invoices.go:187 #: pkg/contacts.go:153 msgctxt "tag condition" msgid "Any" msgstr "Qualsevol" -#: pkg/products.go:183 pkg/expenses.go:375 pkg/invoices.go:203 +#: pkg/products.go:183 pkg/expenses.go:361 pkg/invoices.go:188 #: pkg/contacts.go:154 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:865 +#: pkg/products.go:269 pkg/quote.go:837 pkg/invoices.go:885 msgctxt "input" msgid "Description" msgstr "Descripció" -#: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:869 +#: pkg/products.go:274 pkg/quote.go:841 pkg/invoices.go:889 msgctxt "input" msgid "Price" msgstr "Preu" -#: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:898 +#: pkg/products.go:284 pkg/quote.go:870 pkg/expenses.go:167 pkg/invoices.go:918 msgctxt "input" msgid "Taxes" msgstr "Imposts" -#: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:947 +#: pkg/products.go:309 pkg/quote.go:919 pkg/profile.go:92 pkg/invoices.go:967 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:948 +#: pkg/products.go:310 pkg/quote.go:920 pkg/invoices.go:968 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:949 +#: pkg/products.go:311 pkg/quote.go:921 pkg/invoices.go:969 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:957 +#: pkg/products.go:313 pkg/quote.go:929 pkg/expenses.go:213 pkg/expenses.go:218 +#: pkg/invoices.go:977 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:958 +#: pkg/products.go:314 pkg/quote.go:930 pkg/expenses.go:214 pkg/expenses.go:219 +#: pkg/invoices.go:978 msgid "You can only select a tax of each class." msgstr "Només podeu seleccionar un impost de cada classe." @@ -847,141 +856,141 @@ msgstr "No podeu deixar el nom del mètode de pagament en blanc." msgid "Payment instructions can not be empty." msgstr "No podeu deixar les instruccions de pagament en blanc." -#: pkg/quote.go:148 pkg/quote.go:609 pkg/expenses.go:164 pkg/expenses.go:340 +#: pkg/quote.go:147 pkg/quote.go:608 pkg/expenses.go:150 pkg/expenses.go:326 #: pkg/invoices.go:147 pkg/invoices.go:606 msgctxt "input" msgid "Contact" msgstr "Contacte" -#: pkg/quote.go:162 pkg/expenses.go:341 pkg/invoices.go:163 +#: pkg/quote.go:148 pkg/invoices.go:148 msgid "All customers" msgstr "Tots els clients" -#: pkg/quote.go:167 pkg/quote.go:580 +#: pkg/quote.go:153 pkg/quote.go:602 msgctxt "input" msgid "Quotation Status" msgstr "Estat del pressupost" -#: pkg/quote.go:168 pkg/invoices.go:169 +#: pkg/quote.go:154 pkg/invoices.go:154 msgid "All status" msgstr "Tots els estats" -#: pkg/quote.go:173 +#: pkg/quote.go:159 msgctxt "input" msgid "Quotation Number" msgstr "Número de pressupost" -#: pkg/quote.go:178 pkg/expenses.go:351 pkg/invoices.go:179 +#: pkg/quote.go:164 pkg/expenses.go:337 pkg/invoices.go:164 msgctxt "input" msgid "From Date" msgstr "A partir de la data" -#: pkg/quote.go:183 pkg/expenses.go:356 pkg/invoices.go:184 +#: pkg/quote.go:169 pkg/expenses.go:342 pkg/invoices.go:169 msgctxt "input" msgid "To Date" msgstr "Fins la data" -#: pkg/quote.go:197 +#: pkg/quote.go:183 msgid "Quotations must have all the specified labels." msgstr "Els pressuposts han de tenir totes les etiquetes." -#: pkg/quote.go:202 +#: pkg/quote.go:188 msgid "Quotations must have at least one of the specified labels." msgstr "Els pressuposts han de tenir com a mínim una de les etiquetes." -#: pkg/quote.go:528 +#: pkg/quote.go:550 msgid "quotations.zip" msgstr "pressuposts.zip" -#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535 -#: pkg/invoices.go:1125 pkg/invoices.go:1133 +#: pkg/quote.go:556 pkg/quote.go:1085 pkg/quote.go:1093 pkg/invoices.go:555 +#: pkg/invoices.go:1145 pkg/invoices.go:1153 msgid "Invalid action" msgstr "Acció invàlida." -#: pkg/quote.go:587 +#: pkg/quote.go:609 msgid "Select a customer to quote." msgstr "Escolliu un client a pressupostar." -#: pkg/quote.go:592 +#: pkg/quote.go:614 msgctxt "input" msgid "Quotation Date" msgstr "Data del pressupost" -#: pkg/quote.go:598 +#: pkg/quote.go:620 msgctxt "input" msgid "Terms and conditions" msgstr "Condicions d’acceptació" -#: pkg/quote.go:603 pkg/invoices.go:598 +#: pkg/quote.go:625 pkg/invoices.go:618 msgctxt "input" msgid "Notes" msgstr "Notes" -#: pkg/quote.go:612 pkg/invoices.go:608 +#: pkg/quote.go:634 pkg/invoices.go:628 msgctxt "input" msgid "Payment Method" msgstr "Mètode de pagament" -#: pkg/quote.go:613 +#: pkg/quote.go:635 msgid "Select a payment method." msgstr "Escolliu un mètode de pagament." -#: pkg/quote.go:649 +#: pkg/quote.go:671 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:645 +#: pkg/quote.go:673 pkg/invoices.go:665 msgid "Selected customer is not valid." msgstr "Heu seleccionat un client que no és vàlid." -#: pkg/quote.go:653 +#: pkg/quote.go:675 msgid "Quotation date can not be empty." msgstr "No podeu deixar la data del pressupost en blanc." -#: pkg/quote.go:654 +#: pkg/quote.go:676 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:649 +#: pkg/quote.go:679 pkg/invoices.go:669 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:841 pkg/invoices.go:846 +#: pkg/quote.go:813 pkg/quote.go:818 pkg/invoices.go:861 pkg/invoices.go:866 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/quote.go:829 pkg/invoices.go:879 +#: pkg/quote.go:851 pkg/invoices.go:899 msgctxt "input" msgid "Quantity" msgstr "Quantitat" -#: pkg/quote.go:838 pkg/invoices.go:888 +#: pkg/quote.go:860 pkg/invoices.go:908 msgctxt "input" msgid "Discount (%)" msgstr "Descompte (%)" -#: pkg/quote.go:892 +#: pkg/quote.go:914 msgid "Quotation product ID must be a number greater than zero." msgstr "L’ID del producte de pressupost ha de ser un número major a zero." -#: pkg/quote.go:895 pkg/invoices.go:945 +#: pkg/quote.go:917 pkg/invoices.go:965 msgid "Product ID must be a positive number or zero." msgstr "L’ID del producte ha de ser un número positiu o zero." -#: pkg/quote.go:901 pkg/invoices.go:951 +#: pkg/quote.go:923 pkg/invoices.go:971 msgid "Quantity can not be empty." msgstr "No podeu deixar la quantitat en blanc." -#: pkg/quote.go:902 pkg/invoices.go:952 +#: pkg/quote.go:924 pkg/invoices.go:972 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:954 +#: pkg/quote.go:926 pkg/invoices.go:974 msgid "Discount can not be empty." msgstr "No podeu deixar el descompte en blanc." -#: pkg/quote.go:905 pkg/invoices.go:955 +#: pkg/quote.go:927 pkg/invoices.go:975 msgid "Discount must be a percentage between 0 and 100." msgstr "El descompte ha de ser un percentatge entre 0 i 100." @@ -1048,87 +1057,87 @@ msgctxt "period option" msgid "Previous year" msgstr "Any anterior" -#: pkg/expenses.go:129 +#: pkg/expenses.go:115 msgid "Select a contact." msgstr "Escolliu un contacte." -#: pkg/expenses.go:170 +#: pkg/expenses.go:156 msgctxt "input" msgid "Invoice number" msgstr "Número de factura" -#: pkg/expenses.go:175 pkg/invoices.go:592 +#: pkg/expenses.go:161 pkg/invoices.go:612 msgctxt "input" msgid "Invoice Date" msgstr "Data de factura" -#: pkg/expenses.go:187 +#: pkg/expenses.go:173 msgctxt "input" msgid "Amount" msgstr "Import" -#: pkg/expenses.go:197 +#: pkg/expenses.go:183 msgctxt "input" msgid "File" msgstr "Fitxer" -#: pkg/expenses.go:225 +#: pkg/expenses.go:211 msgid "Selected contact is not valid." msgstr "Heu seleccionat un contacte que no és vàlid." -#: pkg/expenses.go:226 pkg/invoices.go:647 +#: pkg/expenses.go:212 pkg/invoices.go:667 msgid "Invoice date must be a valid date." msgstr "La data de facturació ha de ser vàlida." -#: pkg/expenses.go:229 +#: pkg/expenses.go:215 msgid "Amount can not be empty." msgstr "No podeu deixar l’import en blanc." -#: pkg/expenses.go:230 +#: pkg/expenses.go:216 msgid "Amount must be a number greater than zero." msgstr "L’import ha de ser un número major a zero." -#: pkg/expenses.go:341 +#: pkg/expenses.go:327 msgid "All contacts" msgstr "Tots els contactes" -#: pkg/expenses.go:346 pkg/invoices.go:159 +#: pkg/expenses.go:332 pkg/invoices.go:159 msgctxt "input" msgid "Invoice Number" msgstr "Número de factura" -#: pkg/invoices.go:168 pkg/invoices.go:580 +#: pkg/invoices.go:153 pkg/invoices.go:600 msgctxt "input" msgid "Invoice Status" msgstr "Estat de la factura" -#: pkg/invoices.go:428 +#: pkg/invoices.go:448 msgid "Select a customer to bill." msgstr "Escolliu un client a facturar." -#: pkg/invoices.go:529 +#: pkg/invoices.go:549 msgid "invoices.zip" msgstr "factures.zip" -#: pkg/invoices.go:644 +#: pkg/invoices.go:664 msgid "Selected invoice status is not valid." msgstr "Heu seleccionat un estat de factura que no és vàlid." -#: pkg/invoices.go:646 +#: pkg/invoices.go:666 msgid "Invoice date can not be empty." msgstr "No podeu deixar la data de la factura en blanc." -#: pkg/invoices.go:782 +#: pkg/invoices.go:802 #, c-format msgid "Re: quotation #%s of %s" msgstr "Ref: pressupost núm. %s del %s" -#: pkg/invoices.go:783 +#: pkg/invoices.go:803 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoices.go:942 +#: pkg/invoices.go:962 msgid "Invoice product ID must be a number greater than zero." msgstr "L’ID del producte de factura ha de ser un número major a zero." @@ -1234,10 +1243,6 @@ msgstr "No podeu deixar el codi postal en blanc." msgid "This value is not a valid postal code." msgstr "Aquest valor no és un codi postal vàlid." -#~ msgctxt "title" -#~ msgid "Customer" -#~ msgstr "Client" - #~ msgctxt "input" #~ msgid "Customer" #~ msgstr "Client" diff --git a/po/es.po b/po/es.po index c345a79..818c5cc 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: numerus\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-06-20 10:48+0200\n" +"POT-Creation-Date: 2023-06-20 11:29+0200\n" "PO-Revision-Date: 2023-01-18 17:45+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -157,10 +157,9 @@ msgid "Invoice Num." msgstr "N.º factura" #: web/template/invoices/index.gohtml:52 web/template/quotes/index.gohtml:52 -#: web/template/contacts/index.gohtml:40 web/template/expenses/index.gohtml:43 msgctxt "title" -msgid "Contact" -msgstr "Contacto" +msgid "Customer" +msgstr "Cliente" #: web/template/invoices/index.gohtml:53 web/template/quotes/index.gohtml:53 msgctxt "title" @@ -216,6 +215,11 @@ msgstr "Duplicar" msgid "No invoices added yet." msgstr "No hay facturas." +#: web/template/invoices/index.gohtml:144 web/template/quotes/index.gohtml:152 +#: web/template/expenses/index.gohtml:105 +msgid "Total" +msgstr "Total" + #: web/template/invoices/view.gohtml:2 web/template/invoices/view.gohtml:33 msgctxt "title" msgid "Invoice %s" @@ -449,6 +453,11 @@ msgctxt "action" msgid "New contact" msgstr "Nuevo contacto" +#: web/template/contacts/index.gohtml:40 web/template/expenses/index.gohtml:43 +msgctxt "title" +msgid "Contact" +msgstr "Contacto" + #: web/template/contacts/index.gohtml:41 msgctxt "title" msgid "Email" @@ -665,82 +674,82 @@ 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:851 +#: pkg/products.go:164 pkg/products.go:263 pkg/quote.go:823 pkg/invoices.go:871 #: pkg/contacts.go:135 msgctxt "input" msgid "Name" 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:603 pkg/invoices.go:1150 pkg/contacts.go:140 +#: pkg/products.go:169 pkg/products.go:290 pkg/quote.go:174 pkg/quote.go:630 +#: pkg/expenses.go:188 pkg/expenses.go:347 pkg/invoices.go:174 +#: pkg/invoices.go:623 pkg/invoices.go:1170 pkg/contacts.go:140 #: pkg/contacts.go:325 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:173 pkg/quote.go:192 pkg/expenses.go:365 pkg/invoices.go:193 +#: pkg/products.go:173 pkg/quote.go:178 pkg/expenses.go:351 pkg/invoices.go:178 #: pkg/contacts.go:144 msgctxt "input" msgid "Tags Condition" msgstr "Condición de las etiquetas" -#: pkg/products.go:177 pkg/quote.go:196 pkg/expenses.go:369 pkg/invoices.go:197 +#: pkg/products.go:177 pkg/quote.go:182 pkg/expenses.go:355 pkg/invoices.go:182 #: pkg/contacts.go:148 msgctxt "tag condition" msgid "All" msgstr "Todas" -#: pkg/products.go:178 pkg/expenses.go:370 pkg/invoices.go:198 +#: pkg/products.go:178 pkg/expenses.go:356 pkg/invoices.go:183 #: pkg/contacts.go:149 msgid "Invoices must have all the specified labels." msgstr "Las facturas deben tener todas las etiquetas." -#: pkg/products.go:182 pkg/quote.go:201 pkg/expenses.go:374 pkg/invoices.go:202 +#: pkg/products.go:182 pkg/quote.go:187 pkg/expenses.go:360 pkg/invoices.go:187 #: pkg/contacts.go:153 msgctxt "tag condition" msgid "Any" msgstr "Cualquiera" -#: pkg/products.go:183 pkg/expenses.go:375 pkg/invoices.go:203 +#: pkg/products.go:183 pkg/expenses.go:361 pkg/invoices.go:188 #: pkg/contacts.go:154 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:865 +#: pkg/products.go:269 pkg/quote.go:837 pkg/invoices.go:885 msgctxt "input" msgid "Description" msgstr "Descripción" -#: pkg/products.go:274 pkg/quote.go:819 pkg/invoices.go:869 +#: pkg/products.go:274 pkg/quote.go:841 pkg/invoices.go:889 msgctxt "input" msgid "Price" msgstr "Precio" -#: pkg/products.go:284 pkg/quote.go:848 pkg/expenses.go:181 pkg/invoices.go:898 +#: pkg/products.go:284 pkg/quote.go:870 pkg/expenses.go:167 pkg/invoices.go:918 msgctxt "input" msgid "Taxes" msgstr "Impuestos" -#: pkg/products.go:309 pkg/quote.go:897 pkg/profile.go:92 pkg/invoices.go:947 +#: pkg/products.go:309 pkg/quote.go:919 pkg/profile.go:92 pkg/invoices.go:967 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:948 +#: pkg/products.go:310 pkg/quote.go:920 pkg/invoices.go:968 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:949 +#: pkg/products.go:311 pkg/quote.go:921 pkg/invoices.go:969 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:957 +#: pkg/products.go:313 pkg/quote.go:929 pkg/expenses.go:213 pkg/expenses.go:218 +#: pkg/invoices.go:977 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:958 +#: pkg/products.go:314 pkg/quote.go:930 pkg/expenses.go:214 pkg/expenses.go:219 +#: pkg/invoices.go:978 msgid "You can only select a tax of each class." msgstr "Solo podéis escoger un impuesto de cada clase." @@ -847,141 +856,141 @@ msgstr "No podéis dejar el nombre del método de pago en blanco." msgid "Payment instructions can not be empty." msgstr "No podéis dejar las instrucciones de pago en blanco." -#: pkg/quote.go:148 pkg/quote.go:609 pkg/expenses.go:164 pkg/expenses.go:340 +#: pkg/quote.go:147 pkg/quote.go:608 pkg/expenses.go:150 pkg/expenses.go:326 #: pkg/invoices.go:147 pkg/invoices.go:606 msgctxt "input" msgid "Contact" msgstr "Contacto" -#: pkg/quote.go:162 pkg/expenses.go:341 pkg/invoices.go:163 +#: pkg/quote.go:148 pkg/invoices.go:148 msgid "All customers" msgstr "Todos los clientes" -#: pkg/quote.go:167 pkg/quote.go:580 +#: pkg/quote.go:153 pkg/quote.go:602 msgctxt "input" msgid "Quotation Status" msgstr "Estado del presupuesto" -#: pkg/quote.go:168 pkg/invoices.go:169 +#: pkg/quote.go:154 pkg/invoices.go:154 msgid "All status" msgstr "Todos los estados" -#: pkg/quote.go:173 +#: pkg/quote.go:159 msgctxt "input" msgid "Quotation Number" msgstr "Número de presupuesto" -#: pkg/quote.go:178 pkg/expenses.go:351 pkg/invoices.go:179 +#: pkg/quote.go:164 pkg/expenses.go:337 pkg/invoices.go:164 msgctxt "input" msgid "From Date" msgstr "A partir de la fecha" -#: pkg/quote.go:183 pkg/expenses.go:356 pkg/invoices.go:184 +#: pkg/quote.go:169 pkg/expenses.go:342 pkg/invoices.go:169 msgctxt "input" msgid "To Date" msgstr "Hasta la fecha" -#: pkg/quote.go:197 +#: pkg/quote.go:183 msgid "Quotations must have all the specified labels." msgstr "Los presupuestos deben tener todas las etiquetas." -#: pkg/quote.go:202 +#: pkg/quote.go:188 msgid "Quotations must have at least one of the specified labels." msgstr "Los presupuestos deben tener como mínimo una de las etiquetas." -#: pkg/quote.go:528 +#: pkg/quote.go:550 msgid "quotations.zip" msgstr "presupuestos.zip" -#: pkg/quote.go:534 pkg/quote.go:1063 pkg/quote.go:1071 pkg/invoices.go:535 -#: pkg/invoices.go:1125 pkg/invoices.go:1133 +#: pkg/quote.go:556 pkg/quote.go:1085 pkg/quote.go:1093 pkg/invoices.go:555 +#: pkg/invoices.go:1145 pkg/invoices.go:1153 msgid "Invalid action" msgstr "Acción inválida." -#: pkg/quote.go:587 +#: pkg/quote.go:609 msgid "Select a customer to quote." msgstr "Escoged un cliente a presupuestar." -#: pkg/quote.go:592 +#: pkg/quote.go:614 msgctxt "input" msgid "Quotation Date" msgstr "Fecha del presupuesto" -#: pkg/quote.go:598 +#: pkg/quote.go:620 msgctxt "input" msgid "Terms and conditions" msgstr "Condiciones de aceptación" -#: pkg/quote.go:603 pkg/invoices.go:598 +#: pkg/quote.go:625 pkg/invoices.go:618 msgctxt "input" msgid "Notes" msgstr "Notas" -#: pkg/quote.go:612 pkg/invoices.go:608 +#: pkg/quote.go:634 pkg/invoices.go:628 msgctxt "input" msgid "Payment Method" msgstr "Método de pago" -#: pkg/quote.go:613 +#: pkg/quote.go:635 msgid "Select a payment method." msgstr "Escoged un método e pago." -#: pkg/quote.go:649 +#: pkg/quote.go:671 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:645 +#: pkg/quote.go:673 pkg/invoices.go:665 msgid "Selected customer is not valid." msgstr "Habéis escogido un cliente que no es válido." -#: pkg/quote.go:653 +#: pkg/quote.go:675 msgid "Quotation date can not be empty." msgstr "No podéis dejar la fecha del presupuesto en blanco." -#: pkg/quote.go:654 +#: pkg/quote.go:676 msgid "Quotation date must be a valid date." msgstr "La fecha de presupuesto debe ser válida." -#: pkg/quote.go:657 pkg/invoices.go:649 +#: pkg/quote.go:679 pkg/invoices.go:669 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:841 pkg/invoices.go:846 +#: pkg/quote.go:813 pkg/quote.go:818 pkg/invoices.go:861 pkg/invoices.go:866 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/quote.go:829 pkg/invoices.go:879 +#: pkg/quote.go:851 pkg/invoices.go:899 msgctxt "input" msgid "Quantity" msgstr "Cantidad" -#: pkg/quote.go:838 pkg/invoices.go:888 +#: pkg/quote.go:860 pkg/invoices.go:908 msgctxt "input" msgid "Discount (%)" msgstr "Descuento (%)" -#: pkg/quote.go:892 +#: pkg/quote.go:914 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:945 +#: pkg/quote.go:917 pkg/invoices.go:965 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:951 +#: pkg/quote.go:923 pkg/invoices.go:971 msgid "Quantity can not be empty." msgstr "No podéis dejar la cantidad en blanco." -#: pkg/quote.go:902 pkg/invoices.go:952 +#: pkg/quote.go:924 pkg/invoices.go:972 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:954 +#: pkg/quote.go:926 pkg/invoices.go:974 msgid "Discount can not be empty." msgstr "No podéis dejar el descuento en blanco." -#: pkg/quote.go:905 pkg/invoices.go:955 +#: pkg/quote.go:927 pkg/invoices.go:975 msgid "Discount must be a percentage between 0 and 100." msgstr "El descuento tiene que ser un porcentaje entre 0 y 100." @@ -1048,87 +1057,87 @@ msgctxt "period option" msgid "Previous year" msgstr "Año anterior" -#: pkg/expenses.go:129 +#: pkg/expenses.go:115 msgid "Select a contact." msgstr "Escoged un contacto" -#: pkg/expenses.go:170 +#: pkg/expenses.go:156 msgctxt "input" msgid "Invoice number" msgstr "Número de factura" -#: pkg/expenses.go:175 pkg/invoices.go:592 +#: pkg/expenses.go:161 pkg/invoices.go:612 msgctxt "input" msgid "Invoice Date" msgstr "Fecha de factura" -#: pkg/expenses.go:187 +#: pkg/expenses.go:173 msgctxt "input" msgid "Amount" msgstr "Importe" -#: pkg/expenses.go:197 +#: pkg/expenses.go:183 msgctxt "input" msgid "File" msgstr "Archivo" -#: pkg/expenses.go:225 +#: pkg/expenses.go:211 msgid "Selected contact is not valid." msgstr "Habéis escogido un contacto que no es válido." -#: pkg/expenses.go:226 pkg/invoices.go:647 +#: pkg/expenses.go:212 pkg/invoices.go:667 msgid "Invoice date must be a valid date." msgstr "La fecha de factura debe ser válida." -#: pkg/expenses.go:229 +#: pkg/expenses.go:215 msgid "Amount can not be empty." msgstr "No podéis dejar el importe en blanco." -#: pkg/expenses.go:230 +#: pkg/expenses.go:216 msgid "Amount must be a number greater than zero." msgstr "El importe tiene que ser un número mayor a cero." -#: pkg/expenses.go:341 +#: pkg/expenses.go:327 msgid "All contacts" msgstr "Todos los contactos" -#: pkg/expenses.go:346 pkg/invoices.go:159 +#: pkg/expenses.go:332 pkg/invoices.go:159 msgctxt "input" msgid "Invoice Number" msgstr "Número de factura" -#: pkg/invoices.go:168 pkg/invoices.go:580 +#: pkg/invoices.go:153 pkg/invoices.go:600 msgctxt "input" msgid "Invoice Status" msgstr "Estado de la factura" -#: pkg/invoices.go:428 +#: pkg/invoices.go:448 msgid "Select a customer to bill." msgstr "Escoged un cliente a facturar." -#: pkg/invoices.go:529 +#: pkg/invoices.go:549 msgid "invoices.zip" msgstr "facturas.zip" -#: pkg/invoices.go:644 +#: pkg/invoices.go:664 msgid "Selected invoice status is not valid." msgstr "Habéis escogido un estado de factura que no es válido." -#: pkg/invoices.go:646 +#: pkg/invoices.go:666 msgid "Invoice date can not be empty." msgstr "No podéis dejar la fecha de la factura en blanco." -#: pkg/invoices.go:782 +#: pkg/invoices.go:802 #, c-format msgid "Re: quotation #%s of %s" msgstr "Ref: presupuesto n.º %s del %s" -#: pkg/invoices.go:783 +#: pkg/invoices.go:803 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoices.go:942 +#: pkg/invoices.go:962 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." @@ -1234,10 +1243,6 @@ msgstr "No podéis dejar el código postal en blanco." msgid "This value is not a valid postal code." msgstr "Este valor no es un código postal válido válido." -#~ msgctxt "title" -#~ msgid "Customer" -#~ msgstr "Cliente" - #~ msgctxt "input" #~ msgid "Customer" #~ msgstr "Cliente" diff --git a/web/static/numerus.css b/web/static/numerus.css index 8975ac0..4f1bdb6 100644 --- a/web/static/numerus.css +++ b/web/static/numerus.css @@ -263,6 +263,10 @@ tbody tr:nth-child(even) { background-color: var(--numerus--header--background-color); } +tfoot th { + text-align: right; +} + div[role="alert"].error { padding: 1.25em; background-color: var(--numerus--color--red); diff --git a/web/template/expenses/index.gohtml b/web/template/expenses/index.gohtml index 3513cbd..581cd81 100644 --- a/web/template/expenses/index.gohtml +++ b/web/template/expenses/index.gohtml @@ -99,5 +99,14 @@ {{ end }} + {{ if .Expenses }} + + + {{( gettext "Total" )}} + {{ .TotalAmount|formatPrice }} + + + + {{ end }} {{- end }} diff --git a/web/template/invoices/index.gohtml b/web/template/invoices/index.gohtml index 6c15570..ea40087 100644 --- a/web/template/invoices/index.gohtml +++ b/web/template/invoices/index.gohtml @@ -138,5 +138,14 @@ {{ end }} + {{ if .Invoices }} + + + {{( gettext "Total" )}} + {{ .TotalAmount|formatPrice }} + + + + {{ end }} {{- end }} diff --git a/web/template/quotes/index.gohtml b/web/template/quotes/index.gohtml index 76119ff..dba2f3d 100644 --- a/web/template/quotes/index.gohtml +++ b/web/template/quotes/index.gohtml @@ -103,9 +103,9 @@ {{ .Total|formatPrice }}