diff --git a/pkg/expenses.go b/pkg/expenses.go index d882164..27e0022 100644 --- a/pkg/expenses.go +++ b/pkg/expenses.go @@ -593,14 +593,19 @@ func ServeExpenseAttachment(w http.ResponseWriter, r *http.Request, params httpr func HandleEditExpenseAction(w http.ResponseWriter, r *http.Request, params httprouter.Params) { slug := params[0].Value - if !ValidUuid(slug) { - http.NotFound(w, r) - return + switch slug { + case "batch": + HandleBatchExpenseAction(w, r, params) + default: + if !ValidUuid(slug) { + http.NotFound(w, r) + return + } + actionUri := fmt.Sprintf("/invoices/%s/edit", slug) + handleExpenseAction(w, r, actionUri, func(w http.ResponseWriter, r *http.Request, form *expenseForm) { + mustRenderEditExpenseForm(w, r, slug, form) + }) } - actionUri := fmt.Sprintf("/invoices/%s/edit", slug) - handleExpenseAction(w, r, actionUri, func(w http.ResponseWriter, r *http.Request, form *expenseForm) { - mustRenderEditExpenseForm(w, r, slug, form) - }) } func HandleNewExpenseAction(w http.ResponseWriter, r *http.Request, params httprouter.Params) { @@ -646,3 +651,29 @@ func handleExpenseAction(w http.ResponseWriter, r *http.Request, action string, http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) } } + +func HandleBatchExpenseAction(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := verifyCsrfTokenValid(r); err != nil { + http.Error(w, err.Error(), http.StatusForbidden) + return + } + locale := getLocale(r) + switch r.Form.Get("action") { + case "export": + conn := getConn(r) + company := getCompany(r) + filters := newExpenseFilterForm(r.Context(), conn, locale, company) + if err := filters.Parse(r); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + ods := mustWriteExpensesOds(mustCollectExpenseEntries(r.Context(), conn, locale, filters), locale, company) + writeOdsResponse(w, ods, gettext("expenses.ods", locale)) + default: + http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) + } +} diff --git a/pkg/form.go b/pkg/form.go index 8992aa9..797fdef 100644 --- a/pkg/form.go +++ b/pkg/form.go @@ -428,6 +428,10 @@ func (field *ToggleField) FillValue(r *http.Request) { } } +func (field *ToggleField) String() string { + return field.Selected +} + type FormValidator struct { Valid bool } diff --git a/pkg/invoices.go b/pkg/invoices.go index 59689de..a23e445 100644 --- a/pkg/invoices.go +++ b/pkg/invoices.go @@ -648,14 +648,14 @@ func HandleBatchInvoiceAction(w http.ResponseWriter, r *http.Request, _ httprout http.Error(w, err.Error(), http.StatusForbidden) return } - slugs := r.Form["invoice"] - if len(slugs) == 0 { - http.Redirect(w, r, companyURI(mustGetCompany(r), "/invoices"), http.StatusSeeOther) - return - } locale := getLocale(r) switch r.Form.Get("action") { case "download": + slugs := r.Form["invoice"] + if len(slugs) == 0 { + http.Redirect(w, r, companyURI(mustGetCompany(r), "/invoices"), http.StatusSeeOther) + return + } invoices := mustWriteInvoicesPdf(r, slugs) w.Header().Set("Content-Type", "application/zip") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", gettext("invoices.zip", locale))) @@ -663,6 +663,16 @@ func HandleBatchInvoiceAction(w http.ResponseWriter, r *http.Request, _ httprout if _, err := w.Write(invoices); err != nil { panic(err) } + case "export": + conn := getConn(r) + company := getCompany(r) + filters := newInvoiceFilterForm(r.Context(), conn, locale, company) + if err := filters.Parse(r); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + ods := mustWriteInvoicesOds(mustCollectInvoiceEntries(r.Context(), conn, locale, filters), locale, company) + writeOdsResponse(w, ods, gettext("invoices.ods", locale)) default: http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) } diff --git a/pkg/ods.go b/pkg/ods.go new file mode 100644 index 0000000..ca5e27c --- /dev/null +++ b/pkg/ods.go @@ -0,0 +1,213 @@ +package pkg + +import ( + "archive/zip" + "bytes" + "encoding/xml" + "fmt" + "net/http" + "strings" + "time" +) + +const ( + mimetype = "application/vnd.oasis.opendocument.spreadsheet" + metaDashInfManifestXml = ` + + + + + + +` + metaXml = ` + + + + Numerus + + +` + stylesXml = ` + + +` +) + +func mustWriteInvoicesOds(invoices []*InvoiceEntry, locale *Locale, company *Company) []byte { + columns := []string{ + "Date", + "Invoice Num.", + "Customer", + "Status", + "Tags", + "Amount", + } + return mustWriteTableOds(invoices, columns, locale, func(sb *strings.Builder, invoice *InvoiceEntry) { + writeCellDate(sb, invoice.Date) + writeCellString(sb, invoice.Number) + writeCellString(sb, invoice.CustomerName) + writeCellString(sb, invoice.StatusLabel) + writeCellString(sb, strings.Join(invoice.Tags, ",")) + writeCellFloat(sb, invoice.Total, locale, company) + }) +} + +func mustWriteQuotesOds(quotes []*QuoteEntry, locale *Locale, company *Company) []byte { + columns := []string{ + "Date", + "Quotation Num.", + "Customer", + "Status", + "Tags", + "Amount", + } + return mustWriteTableOds(quotes, columns, locale, func(sb *strings.Builder, quote *QuoteEntry) { + writeCellDate(sb, quote.Date) + writeCellString(sb, quote.Number) + writeCellString(sb, quote.CustomerName) + writeCellString(sb, quote.StatusLabel) + writeCellString(sb, strings.Join(quote.Tags, ",")) + writeCellFloat(sb, quote.Total, locale, company) + }) +} + +func mustWriteExpensesOds(expenses []*ExpenseEntry, locale *Locale, company *Company) []byte { + columns := []string{ + "Contact", + "Invoice Date", + "Invoice Number", + "Status", + "Tags", + "Amount", + } + return mustWriteTableOds(expenses, columns, locale, func(sb *strings.Builder, expense *ExpenseEntry) { + writeCellString(sb, expense.InvoicerName) + writeCellDate(sb, expense.InvoiceDate) + writeCellString(sb, expense.InvoiceNumber) + writeCellString(sb, expense.StatusLabel) + writeCellString(sb, strings.Join(expense.Tags, ",")) + writeCellFloat(sb, expense.Amount, locale, company) + }) +} + +func mustWriteTableOds[K interface{}](rows []*K, columns []string, locale *Locale, writeRow func(*strings.Builder, *K)) []byte { + var sb strings.Builder + + sb.WriteString(` + + + + + + + + + + + + + + + + + + / + + / + + + + + + + + +`) + sb.WriteString(fmt.Sprintf(" \n", len(columns))) + sb.WriteString(` +`) + for _, t := range columns { + writeCellString(&sb, locale.GetC(t, "title")) + } + sb.WriteString(" \n") + for _, row := range rows { + sb.WriteString(" \n") + writeRow(&sb, row) + sb.WriteString(" \n") + } + sb.WriteString(` + + + + +`) + return mustWriteOds(sb.String()) +} + +func mustWriteOds(content string) []byte { + buf := new(bytes.Buffer) + ods := zip.NewWriter(buf) + mustWriteOdsFile(ods, "mimetype", mimetype, zip.Store) + mustWriteOdsFile(ods, "META-INF/manifest.xml", metaDashInfManifestXml, zip.Deflate) + mustWriteOdsFile(ods, "meta.xml", metaXml, zip.Deflate) + mustWriteOdsFile(ods, "styles.xml", stylesXml, zip.Deflate) + mustWriteOdsFile(ods, "content.xml", content, zip.Deflate) + mustClose(ods) + return buf.Bytes() +} + +func mustWriteOdsFile(ods *zip.Writer, name string, content string, method uint16) { + f, err := ods.CreateHeader(&zip.FileHeader{ + Name: name, + Method: method, + Modified: time.Now(), + }) + if err != nil { + panic(err) + } + if _, err = f.Write([]byte(content)); err != nil { + panic(err) + } +} + +func writeCellString(sb *strings.Builder, s string) { + sb.WriteString(` `) + if err := xml.EscapeText(sb, []byte(s)); err != nil { + panic(err) + } + sb.WriteString("\n") +} + +func writeCellDate(sb *strings.Builder, t time.Time) { + sb.WriteString(fmt.Sprintf(" %s\n", t.Format("2006-01-02"), t.Format("02/01/06"))) +} + +func writeCellFloat(sb *strings.Builder, s string, locale *Locale, company *Company) { + sb.WriteString(fmt.Sprintf(" %s\n", s, formatPrice(s, locale.Language, "%.[1]*[2]f", company.DecimalDigits, ""))) +} + +func writeOdsResponse(w http.ResponseWriter, ods []byte, filename string) { + w.Header().Set("Content-Type", "application/vnd.oasis.opendocument.spreadsheet") + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) + w.WriteHeader(http.StatusOK) + if _, err := w.Write(ods); err != nil { + panic(err) + } +} diff --git a/pkg/quote.go b/pkg/quote.go index dc0190d..af98c4d 100644 --- a/pkg/quote.go +++ b/pkg/quote.go @@ -605,14 +605,14 @@ func HandleBatchQuoteAction(w http.ResponseWriter, r *http.Request, _ httprouter http.Error(w, err.Error(), http.StatusForbidden) return } - slugs := r.Form["quote"] - if len(slugs) == 0 { - http.Redirect(w, r, companyURI(mustGetCompany(r), "/quotes"), http.StatusSeeOther) - return - } locale := getLocale(r) switch r.Form.Get("action") { case "download": + slugs := r.Form["quote"] + if len(slugs) == 0 { + http.Redirect(w, r, companyURI(mustGetCompany(r), "/quotes"), http.StatusSeeOther) + return + } quotes := mustWriteQuotesPdf(r, slugs) w.Header().Set("Content-Type", "application/zip") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", gettext("quotations.zip", locale))) @@ -620,6 +620,16 @@ func HandleBatchQuoteAction(w http.ResponseWriter, r *http.Request, _ httprouter if _, err := w.Write(quotes); err != nil { panic(err) } + case "export": + conn := getConn(r) + company := getCompany(r) + filters := newQuoteFilterForm(r.Context(), conn, locale, company) + if err := filters.Parse(r); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + ods := mustWriteQuotesOds(mustCollectQuoteEntries(r.Context(), conn, locale, filters), locale, company) + writeOdsResponse(w, ods, gettext("quotations.ods", locale)) default: http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) } diff --git a/po/ca.po b/po/ca.po index b666c8f..fd6902e 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-07-16 20:50+0200\n" +"POT-Creation-Date: 2023-07-18 13:12+0200\n" "PO-Revision-Date: 2023-01-18 17:08+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -126,117 +126,123 @@ msgctxt "action" msgid "Save" msgstr "Desa" -#: web/template/invoices/index.gohtml:19 +#: web/template/invoices/index.gohtml:28 msgctxt "action" msgid "Download invoices" msgstr "Descarrega factures" -#: web/template/invoices/index.gohtml:21 +#: web/template/invoices/index.gohtml:31 web/template/quotes/index.gohtml:31 +#: web/template/expenses/index.gohtml:29 +msgctxt "action" +msgid "Export list" +msgstr "Exporta llistat" + +#: web/template/invoices/index.gohtml:33 msgctxt "action" msgid "New invoice" msgstr "Nova factura" -#: web/template/invoices/index.gohtml:45 web/template/dashboard.gohtml:23 -#: web/template/quotes/index.gohtml:45 web/template/contacts/index.gohtml:38 -#: web/template/expenses/index.gohtml:39 web/template/products/index.gohtml:36 +#: web/template/invoices/index.gohtml:57 web/template/dashboard.gohtml:23 +#: web/template/quotes/index.gohtml:57 web/template/contacts/index.gohtml:38 +#: web/template/expenses/index.gohtml:56 web/template/products/index.gohtml:36 msgctxt "action" msgid "Filter" msgstr "Filtra" -#: web/template/invoices/index.gohtml:48 web/template/quotes/index.gohtml:48 -#: web/template/contacts/index.gohtml:41 web/template/expenses/index.gohtml:42 +#: web/template/invoices/index.gohtml:60 web/template/quotes/index.gohtml:60 +#: web/template/contacts/index.gohtml:41 web/template/expenses/index.gohtml:59 #: web/template/products/index.gohtml:39 msgctxt "action" msgid "Reset" msgstr "Restableix" -#: web/template/invoices/index.gohtml:54 +#: web/template/invoices/index.gohtml:66 msgctxt "invoice" msgid "All" msgstr "Totes" -#: web/template/invoices/index.gohtml:55 web/template/invoices/view.gohtml:38 -#: web/template/quotes/index.gohtml:55 web/template/quotes/view.gohtml:37 +#: web/template/invoices/index.gohtml:67 web/template/invoices/view.gohtml:38 +#: web/template/quotes/index.gohtml:67 web/template/quotes/view.gohtml:37 msgctxt "title" msgid "Date" msgstr "Data" -#: web/template/invoices/index.gohtml:56 +#: web/template/invoices/index.gohtml:68 msgctxt "title" msgid "Invoice Num." msgstr "Núm. factura" -#: web/template/invoices/index.gohtml:57 web/template/quotes/index.gohtml:57 +#: web/template/invoices/index.gohtml:69 web/template/quotes/index.gohtml:69 msgctxt "title" msgid "Customer" msgstr "Client" -#: web/template/invoices/index.gohtml:58 web/template/quotes/index.gohtml:58 -#: web/template/expenses/index.gohtml:51 +#: web/template/invoices/index.gohtml:70 web/template/quotes/index.gohtml:70 +#: web/template/expenses/index.gohtml:68 msgctxt "title" msgid "Status" msgstr "Estat" -#: web/template/invoices/index.gohtml:59 web/template/quotes/index.gohtml:59 -#: web/template/contacts/index.gohtml:50 web/template/expenses/index.gohtml:52 +#: web/template/invoices/index.gohtml:71 web/template/quotes/index.gohtml:71 +#: web/template/contacts/index.gohtml:50 web/template/expenses/index.gohtml:69 #: web/template/products/index.gohtml:46 msgctxt "title" msgid "Tags" msgstr "Etiquetes" -#: web/template/invoices/index.gohtml:60 web/template/quotes/index.gohtml:60 -#: web/template/expenses/index.gohtml:53 +#: web/template/invoices/index.gohtml:72 web/template/quotes/index.gohtml:72 +#: web/template/expenses/index.gohtml:70 msgctxt "title" msgid "Amount" msgstr "Import" -#: web/template/invoices/index.gohtml:61 web/template/quotes/index.gohtml:61 -#: web/template/expenses/index.gohtml:54 +#: web/template/invoices/index.gohtml:73 web/template/quotes/index.gohtml:73 +#: web/template/expenses/index.gohtml:71 msgctxt "title" msgid "Download" msgstr "Descàrrega" -#: web/template/invoices/index.gohtml:62 web/template/quotes/index.gohtml:62 -#: web/template/contacts/index.gohtml:51 web/template/expenses/index.gohtml:55 +#: web/template/invoices/index.gohtml:74 web/template/quotes/index.gohtml:74 +#: web/template/contacts/index.gohtml:51 web/template/expenses/index.gohtml:72 #: web/template/products/index.gohtml:48 msgctxt "title" msgid "Actions" msgstr "Accions" -#: web/template/invoices/index.gohtml:69 +#: web/template/invoices/index.gohtml:81 msgctxt "action" msgid "Select invoice %v" msgstr "Selecciona factura %v" -#: web/template/invoices/index.gohtml:110 +#: web/template/invoices/index.gohtml:122 msgctxt "action" msgid "Download invoice %s" msgstr "Descarrega factura %s" -#: web/template/invoices/index.gohtml:118 +#: web/template/invoices/index.gohtml:130 msgid "Actions for invoice %s" msgstr "Accions per la factura %s" -#: web/template/invoices/index.gohtml:126 web/template/invoices/view.gohtml:19 -#: web/template/quotes/index.gohtml:125 web/template/quotes/view.gohtml:22 -#: web/template/contacts/index.gohtml:82 web/template/expenses/index.gohtml:117 +#: web/template/invoices/index.gohtml:138 web/template/invoices/view.gohtml:19 +#: web/template/quotes/index.gohtml:137 web/template/quotes/view.gohtml:22 +#: web/template/contacts/index.gohtml:82 web/template/expenses/index.gohtml:134 #: web/template/products/index.gohtml:78 msgctxt "action" msgid "Edit" msgstr "Edita" -#: web/template/invoices/index.gohtml:134 web/template/invoices/view.gohtml:16 -#: web/template/quotes/index.gohtml:133 web/template/quotes/view.gohtml:19 +#: web/template/invoices/index.gohtml:146 web/template/invoices/view.gohtml:16 +#: web/template/quotes/index.gohtml:145 web/template/quotes/view.gohtml:19 msgctxt "action" msgid "Duplicate" msgstr "Duplica" -#: web/template/invoices/index.gohtml:144 +#: web/template/invoices/index.gohtml:156 msgid "No invoices added yet." msgstr "No hi ha cap factura." -#: web/template/invoices/index.gohtml:151 web/template/quotes/index.gohtml:158 -#: web/template/expenses/index.gohtml:134 +#: web/template/invoices/index.gohtml:163 web/template/quotes/index.gohtml:170 +#: web/template/expenses/index.gohtml:151 msgid "Total" msgstr "Total" @@ -363,41 +369,41 @@ msgctxt "title" msgid "New Quotation" msgstr "Nou pressupost" -#: web/template/quotes/index.gohtml:19 +#: web/template/quotes/index.gohtml:28 msgctxt "action" msgid "Download quotations" msgstr "Descarrega pressuposts" -#: web/template/quotes/index.gohtml:21 +#: web/template/quotes/index.gohtml:33 msgctxt "action" msgid "New quotation" msgstr "Nou pressupost" -#: web/template/quotes/index.gohtml:54 +#: web/template/quotes/index.gohtml:66 msgctxt "quote" msgid "All" msgstr "Tots" -#: web/template/quotes/index.gohtml:56 +#: web/template/quotes/index.gohtml:68 msgctxt "title" msgid "Quotation Num." msgstr "Núm. pressupost" -#: web/template/quotes/index.gohtml:69 +#: web/template/quotes/index.gohtml:81 msgctxt "action" msgid "Select quotation %v" msgstr "Selecciona pressupost %v" -#: web/template/quotes/index.gohtml:117 +#: web/template/quotes/index.gohtml:129 msgid "Actions for quote %s" msgstr "Accions pel pressupost %s" -#: web/template/quotes/index.gohtml:141 web/template/quotes/view.gohtml:16 +#: web/template/quotes/index.gohtml:153 web/template/quotes/view.gohtml:16 msgctxt "action" msgid "Create invoice" msgstr "Crea factura" -#: web/template/quotes/index.gohtml:151 +#: web/template/quotes/index.gohtml:163 msgid "No quotations added yet." msgstr "No hi ha cap pressupost." @@ -488,7 +494,7 @@ msgctxt "action" msgid "New contact" msgstr "Nou contacte" -#: web/template/contacts/index.gohtml:47 web/template/expenses/index.gohtml:48 +#: web/template/contacts/index.gohtml:47 web/template/expenses/index.gohtml:65 msgctxt "title" msgid "Contact" msgstr "Contacte" @@ -569,26 +575,26 @@ msgctxt "title" msgid "Expenses" msgstr "Despeses" -#: web/template/expenses/index.gohtml:16 +#: web/template/expenses/index.gohtml:32 msgctxt "action" msgid "New expense" msgstr "Nova despesa" -#: web/template/expenses/index.gohtml:49 +#: web/template/expenses/index.gohtml:66 msgctxt "title" msgid "Invoice Date" msgstr "Data de factura" -#: web/template/expenses/index.gohtml:50 +#: web/template/expenses/index.gohtml:67 msgctxt "title" msgid "Invoice Number" msgstr "Número de factura" -#: web/template/expenses/index.gohtml:109 +#: web/template/expenses/index.gohtml:126 msgid "Actions for expense %s" msgstr "Accions per la despesa %s" -#: web/template/expenses/index.gohtml:127 +#: web/template/expenses/index.gohtml:144 msgid "No expenses added yet." msgstr "No hi ha cap despesa." @@ -695,7 +701,7 @@ msgctxt "title" msgid "Edit Product “%s”" msgstr "Edició del producte «%s»" -#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:267 +#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276 msgctxt "input" msgid "Email" msgstr "Correu-e" @@ -709,7 +715,7 @@ msgstr "Contrasenya" msgid "Email can not be empty." msgstr "No podeu deixar el correu-e en blanc." -#: pkg/login.go:71 pkg/company.go:284 pkg/profile.go:90 pkg/contacts.go:411 +#: pkg/login.go:71 pkg/company.go:284 pkg/profile.go:90 pkg/contacts.go:420 msgid "This value is not a valid email. It should be like name@domain.com." msgstr "Aquest valor no és un correu-e vàlid. Hauria de ser similar a nom@domini.cat." @@ -721,84 +727,84 @@ 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:268 pkg/quote.go:887 -#: pkg/invoices.go:1002 pkg/contacts.go:140 pkg/contacts.go:253 +#: pkg/products.go:172 pkg/products.go:276 pkg/quote.go:901 +#: pkg/invoices.go:1016 pkg/contacts.go:149 pkg/contacts.go:262 msgctxt "input" msgid "Name" msgstr "Nom" -#: pkg/products.go:169 pkg/products.go:295 pkg/quote.go:174 pkg/quote.go:694 -#: pkg/expenses.go:274 pkg/expenses.go:433 pkg/invoices.go:174 -#: pkg/invoices.go:732 pkg/invoices.go:1304 pkg/contacts.go:145 -#: pkg/contacts.go:353 +#: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708 +#: pkg/expenses.go:278 pkg/expenses.go:442 pkg/invoices.go:174 +#: pkg/invoices.go:746 pkg/invoices.go:1331 pkg/contacts.go:154 +#: pkg/contacts.go:362 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:173 pkg/quote.go:178 pkg/expenses.go:443 pkg/invoices.go:178 -#: pkg/contacts.go:149 +#: pkg/products.go:181 pkg/quote.go:178 pkg/expenses.go:452 pkg/invoices.go:178 +#: pkg/contacts.go:158 msgctxt "input" msgid "Tags Condition" msgstr "Condició de les etiquetes" -#: pkg/products.go:177 pkg/quote.go:182 pkg/expenses.go:447 pkg/invoices.go:182 -#: pkg/contacts.go:153 +#: pkg/products.go:185 pkg/quote.go:182 pkg/expenses.go:456 pkg/invoices.go:182 +#: pkg/contacts.go:162 msgctxt "tag condition" msgid "All" msgstr "Totes" -#: pkg/products.go:178 pkg/expenses.go:448 pkg/invoices.go:183 -#: pkg/contacts.go:154 +#: pkg/products.go:186 pkg/expenses.go:457 pkg/invoices.go:183 +#: pkg/contacts.go:163 msgid "Invoices must have all the specified labels." msgstr "Les factures han de tenir totes les etiquetes." -#: pkg/products.go:182 pkg/quote.go:187 pkg/expenses.go:452 pkg/invoices.go:187 -#: pkg/contacts.go:158 +#: pkg/products.go:190 pkg/quote.go:187 pkg/expenses.go:461 pkg/invoices.go:187 +#: pkg/contacts.go:167 msgctxt "tag condition" msgid "Any" msgstr "Qualsevol" -#: pkg/products.go:183 pkg/expenses.go:453 pkg/invoices.go:188 -#: pkg/contacts.go:159 +#: pkg/products.go:191 pkg/expenses.go:462 pkg/invoices.go:188 +#: pkg/contacts.go:168 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:274 pkg/quote.go:901 pkg/invoices.go:1016 +#: pkg/products.go:282 pkg/quote.go:915 pkg/invoices.go:1030 msgctxt "input" msgid "Description" msgstr "Descripció" -#: pkg/products.go:279 pkg/quote.go:905 pkg/invoices.go:1020 +#: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1034 msgctxt "input" msgid "Price" msgstr "Preu" -#: pkg/products.go:289 pkg/quote.go:934 pkg/expenses.go:242 -#: pkg/invoices.go:1049 +#: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:246 +#: pkg/invoices.go:1063 msgctxt "input" msgid "Taxes" msgstr "Imposts" -#: pkg/products.go:314 pkg/quote.go:983 pkg/profile.go:92 pkg/invoices.go:1098 -#: pkg/contacts.go:403 +#: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1112 +#: pkg/contacts.go:412 msgid "Name can not be empty." msgstr "No podeu deixar el nom en blanc." -#: pkg/products.go:315 pkg/quote.go:984 pkg/invoices.go:1099 +#: pkg/products.go:323 pkg/quote.go:998 pkg/invoices.go:1113 msgid "Price can not be empty." msgstr "No podeu deixar el preu en blanc." -#: pkg/products.go:316 pkg/quote.go:985 pkg/invoices.go:1100 +#: pkg/products.go:324 pkg/quote.go:999 pkg/invoices.go:1114 msgid "Price must be a number greater than zero." msgstr "El preu ha de ser un número major a zero." -#: pkg/products.go:318 pkg/quote.go:993 pkg/expenses.go:310 -#: pkg/invoices.go:1108 +#: pkg/products.go:326 pkg/quote.go:1007 pkg/expenses.go:314 +#: pkg/invoices.go:1122 msgid "Selected tax is not valid." msgstr "Heu seleccionat un impost que no és vàlid." -#: pkg/products.go:319 pkg/quote.go:994 pkg/expenses.go:311 -#: pkg/invoices.go:1109 +#: pkg/products.go:327 pkg/quote.go:1008 pkg/expenses.go:315 +#: pkg/invoices.go:1123 msgid "You can only select a tax of each class." msgstr "Només podeu seleccionar un impost de cada classe." @@ -807,47 +813,47 @@ msgctxt "input" msgid "Trade name" msgstr "Nom comercial" -#: pkg/company.go:118 pkg/contacts.go:259 +#: pkg/company.go:118 pkg/contacts.go:268 msgctxt "input" msgid "Phone" msgstr "Telèfon" -#: pkg/company.go:136 pkg/contacts.go:275 +#: pkg/company.go:136 pkg/contacts.go:284 msgctxt "input" msgid "Web" msgstr "Web" -#: pkg/company.go:144 pkg/contacts.go:287 +#: pkg/company.go:144 pkg/contacts.go:296 msgctxt "input" msgid "Business name" msgstr "Nom i cognoms" -#: pkg/company.go:154 pkg/contacts.go:297 +#: pkg/company.go:154 pkg/contacts.go:306 msgctxt "input" msgid "VAT number" msgstr "DNI / NIF" -#: pkg/company.go:160 pkg/contacts.go:303 +#: pkg/company.go:160 pkg/contacts.go:312 msgctxt "input" msgid "Address" msgstr "Adreça" -#: pkg/company.go:169 pkg/contacts.go:312 +#: pkg/company.go:169 pkg/contacts.go:321 msgctxt "input" msgid "City" msgstr "Població" -#: pkg/company.go:175 pkg/contacts.go:318 +#: pkg/company.go:175 pkg/contacts.go:327 msgctxt "input" msgid "Province" msgstr "Província" -#: pkg/company.go:181 pkg/contacts.go:324 +#: pkg/company.go:181 pkg/contacts.go:333 msgctxt "input" msgid "Postal code" msgstr "Codi postal" -#: pkg/company.go:190 pkg/contacts.go:333 +#: pkg/company.go:190 pkg/contacts.go:342 msgctxt "input" msgid "Country" msgstr "País" @@ -882,23 +888,23 @@ msgctxt "input" msgid "Legal disclaimer" msgstr "Nota legal" -#: pkg/company.go:271 pkg/contacts.go:385 +#: pkg/company.go:271 pkg/contacts.go:394 msgid "Selected country is not valid." msgstr "Heu seleccionat un país que no és vàlid." -#: pkg/company.go:275 pkg/contacts.go:388 +#: pkg/company.go:275 pkg/contacts.go:397 msgid "Business name can not be empty." msgstr "No podeu deixar el nom i els cognoms en blanc." -#: pkg/company.go:276 pkg/contacts.go:389 +#: pkg/company.go:276 pkg/contacts.go:398 msgid "Business name must have at least two letters." msgstr "Nom i cognoms han de tenir com a mínim dues lletres." -#: pkg/company.go:277 pkg/contacts.go:391 +#: pkg/company.go:277 pkg/contacts.go:400 msgid "VAT number can not be empty." msgstr "No podeu deixar el DNI o NIF en blanc." -#: pkg/company.go:278 pkg/contacts.go:392 +#: pkg/company.go:278 pkg/contacts.go:401 msgid "This value is not a valid VAT number." msgstr "Aquest valor no és un DNI o NIF vàlid." @@ -906,31 +912,31 @@ msgstr "Aquest valor no és un DNI o NIF vàlid." msgid "Phone can not be empty." msgstr "No podeu deixar el telèfon en blanc." -#: pkg/company.go:281 pkg/contacts.go:408 +#: pkg/company.go:281 pkg/contacts.go:417 msgid "This value is not a valid phone number." msgstr "Aquest valor no és un telèfon vàlid." -#: pkg/company.go:287 pkg/contacts.go:414 +#: pkg/company.go:287 pkg/contacts.go:423 msgid "This value is not a valid web address. It should be like https://domain.com/." msgstr "Aquest valor no és una adreça web vàlida. Hauria de ser similar a https://domini.cat/." -#: pkg/company.go:289 pkg/contacts.go:394 +#: pkg/company.go:289 pkg/contacts.go:403 msgid "Address can not be empty." msgstr "No podeu deixar l’adreça en blanc." -#: pkg/company.go:290 pkg/contacts.go:395 +#: pkg/company.go:290 pkg/contacts.go:404 msgid "City can not be empty." msgstr "No podeu deixar la població en blanc." -#: pkg/company.go:291 pkg/contacts.go:396 +#: pkg/company.go:291 pkg/contacts.go:405 msgid "Province can not be empty." msgstr "No podeu deixar la província en blanc." -#: pkg/company.go:292 pkg/contacts.go:398 +#: pkg/company.go:292 pkg/contacts.go:407 msgid "Postal code can not be empty." msgstr "No podeu deixar el codi postal en blanc." -#: pkg/company.go:293 pkg/contacts.go:399 +#: pkg/company.go:293 pkg/contacts.go:408 msgid "This value is not a valid postal code." msgstr "Aquest valor no és un codi postal vàlid." @@ -1007,7 +1013,7 @@ 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:147 pkg/quote.go:672 pkg/invoices.go:147 pkg/invoices.go:715 +#: pkg/quote.go:147 pkg/quote.go:686 pkg/invoices.go:147 pkg/invoices.go:729 msgctxt "input" msgid "Customer" msgstr "Client" @@ -1016,12 +1022,12 @@ msgstr "Client" msgid "All customers" msgstr "Tots els clients" -#: pkg/quote.go:153 pkg/quote.go:666 +#: pkg/quote.go:153 pkg/quote.go:680 msgctxt "input" msgid "Quotation Status" msgstr "Estat del pressupost" -#: pkg/quote.go:154 pkg/expenses.go:438 pkg/invoices.go:154 +#: pkg/quote.go:154 pkg/expenses.go:447 pkg/invoices.go:154 msgid "All status" msgstr "Tots els estats" @@ -1030,12 +1036,12 @@ msgctxt "input" msgid "Quotation Number" msgstr "Número de pressupost" -#: pkg/quote.go:164 pkg/expenses.go:423 pkg/invoices.go:164 +#: pkg/quote.go:164 pkg/expenses.go:432 pkg/invoices.go:164 msgctxt "input" msgid "From Date" msgstr "A partir de la data" -#: pkg/quote.go:169 pkg/expenses.go:428 pkg/invoices.go:169 +#: pkg/quote.go:169 pkg/expenses.go:437 pkg/invoices.go:169 msgctxt "input" msgid "To Date" msgstr "Fins la data" @@ -1048,99 +1054,104 @@ msgstr "Els pressuposts han de tenir totes les etiquetes." 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:614 +#: pkg/quote.go:618 msgid "quotations.zip" msgstr "pressuposts.zip" -#: pkg/quote.go:620 pkg/quote.go:1149 pkg/quote.go:1157 pkg/expenses.go:620 -#: pkg/invoices.go:663 pkg/invoices.go:1279 pkg/invoices.go:1287 +#: pkg/quote.go:632 +msgid "quotations.ods" +msgstr "pressuposts.ods" + +#: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:651 +#: pkg/expenses.go:677 pkg/invoices.go:677 pkg/invoices.go:1306 +#: pkg/invoices.go:1314 msgid "Invalid action" msgstr "Acció invàlida." -#: pkg/quote.go:673 +#: pkg/quote.go:687 msgid "Select a customer to quote." msgstr "Escolliu un client a pressupostar." -#: pkg/quote.go:678 +#: pkg/quote.go:692 msgctxt "input" msgid "Quotation Date" msgstr "Data del pressupost" -#: pkg/quote.go:684 +#: pkg/quote.go:698 msgctxt "input" msgid "Terms and conditions" msgstr "Condicions d’acceptació" -#: pkg/quote.go:689 pkg/invoices.go:727 +#: pkg/quote.go:703 pkg/invoices.go:741 msgctxt "input" msgid "Notes" msgstr "Notes" -#: pkg/quote.go:698 pkg/invoices.go:737 +#: pkg/quote.go:712 pkg/invoices.go:751 msgctxt "input" msgid "Payment Method" msgstr "Mètode de pagament" -#: pkg/quote.go:699 +#: pkg/quote.go:713 msgid "Select a payment method." msgstr "Escolliu un mètode de pagament." -#: pkg/quote.go:735 +#: pkg/quote.go:749 msgid "Selected quotation status is not valid." msgstr "Heu seleccionat un estat de pressupost que no és vàlid." -#: pkg/quote.go:737 pkg/invoices.go:792 +#: pkg/quote.go:751 pkg/invoices.go:806 msgid "Selected customer is not valid." msgstr "Heu seleccionat un client que no és vàlid." -#: pkg/quote.go:739 +#: pkg/quote.go:753 msgid "Quotation date can not be empty." msgstr "No podeu deixar la data del pressupost en blanc." -#: pkg/quote.go:740 +#: pkg/quote.go:754 msgid "Quotation date must be a valid date." msgstr "La data del pressupost ha de ser vàlida." -#: pkg/quote.go:743 pkg/invoices.go:796 +#: pkg/quote.go:757 pkg/invoices.go:810 msgid "Selected payment method is not valid." msgstr "Heu seleccionat un mètode de pagament que no és vàlid." -#: pkg/quote.go:877 pkg/quote.go:882 pkg/invoices.go:992 pkg/invoices.go:997 +#: pkg/quote.go:891 pkg/quote.go:896 pkg/invoices.go:1006 pkg/invoices.go:1011 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/quote.go:915 pkg/invoices.go:1030 +#: pkg/quote.go:929 pkg/invoices.go:1044 msgctxt "input" msgid "Quantity" msgstr "Quantitat" -#: pkg/quote.go:924 pkg/invoices.go:1039 +#: pkg/quote.go:938 pkg/invoices.go:1053 msgctxt "input" msgid "Discount (%)" msgstr "Descompte (%)" -#: pkg/quote.go:978 +#: pkg/quote.go:992 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:981 pkg/invoices.go:1096 +#: pkg/quote.go:995 pkg/invoices.go:1110 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:987 pkg/invoices.go:1102 +#: pkg/quote.go:1001 pkg/invoices.go:1116 msgid "Quantity can not be empty." msgstr "No podeu deixar la quantitat en blanc." -#: pkg/quote.go:988 pkg/invoices.go:1103 +#: pkg/quote.go:1002 pkg/invoices.go:1117 msgid "Quantity must be a number greater than zero." msgstr "La quantitat ha de ser un número major a zero." -#: pkg/quote.go:990 pkg/invoices.go:1105 +#: pkg/quote.go:1004 pkg/invoices.go:1119 msgid "Discount can not be empty." msgstr "No podeu deixar el descompte en blanc." -#: pkg/quote.go:991 pkg/invoices.go:1106 +#: pkg/quote.go:1005 pkg/invoices.go:1120 msgid "Discount must be a percentage between 0 and 100." msgstr "El descompte ha de ser un percentatge entre 0 i 100." @@ -1207,132 +1218,140 @@ msgctxt "period option" msgid "Previous year" msgstr "Any anterior" -#: pkg/expenses.go:168 +#: pkg/expenses.go:172 msgid "Select a contact." msgstr "Escolliu un contacte." -#: pkg/expenses.go:225 pkg/expenses.go:412 +#: pkg/expenses.go:229 pkg/expenses.go:421 msgctxt "input" msgid "Contact" msgstr "Contacte" -#: pkg/expenses.go:231 +#: pkg/expenses.go:235 msgctxt "input" msgid "Invoice number" msgstr "Número de factura" -#: pkg/expenses.go:236 pkg/invoices.go:721 +#: pkg/expenses.go:240 pkg/invoices.go:735 msgctxt "input" msgid "Invoice Date" msgstr "Data de factura" -#: pkg/expenses.go:251 +#: pkg/expenses.go:255 msgctxt "input" msgid "Amount" msgstr "Import" -#: pkg/expenses.go:262 pkg/invoices.go:743 +#: pkg/expenses.go:266 pkg/invoices.go:757 msgctxt "input" msgid "File" msgstr "Fitxer" -#: pkg/expenses.go:268 pkg/expenses.go:437 +#: pkg/expenses.go:272 pkg/expenses.go:446 msgctxt "input" msgid "Expense Status" msgstr "Estat de la despesa" -#: pkg/expenses.go:308 +#: pkg/expenses.go:312 msgid "Selected contact is not valid." msgstr "Heu seleccionat un contacte que no és vàlid." -#: pkg/expenses.go:309 pkg/invoices.go:794 +#: pkg/expenses.go:313 pkg/invoices.go:808 msgid "Invoice date must be a valid date." msgstr "La data de facturació ha de ser vàlida." -#: pkg/expenses.go:312 +#: pkg/expenses.go:316 msgid "Amount can not be empty." msgstr "No podeu deixar l’import en blanc." -#: pkg/expenses.go:313 +#: pkg/expenses.go:317 msgid "Amount must be a number greater than zero." msgstr "L’import ha de ser un número major a zero." -#: pkg/expenses.go:315 +#: pkg/expenses.go:319 msgid "Selected expense status is not valid." msgstr "Heu seleccionat un estat de despesa que no és vàlid." -#: pkg/expenses.go:413 +#: pkg/expenses.go:422 msgid "All contacts" msgstr "Tots els contactes" -#: pkg/expenses.go:418 pkg/invoices.go:159 +#: pkg/expenses.go:427 pkg/invoices.go:159 msgctxt "input" msgid "Invoice Number" msgstr "Número de factura" -#: pkg/invoices.go:153 pkg/invoices.go:709 +#: pkg/expenses.go:675 +msgid "expenses.ods" +msgstr "despeses.ods" + +#: pkg/invoices.go:153 pkg/invoices.go:723 msgctxt "input" msgid "Invoice Status" msgstr "Estat de la factura" -#: pkg/invoices.go:553 +#: pkg/invoices.go:557 msgid "Select a customer to bill." msgstr "Escolliu un client a facturar." -#: pkg/invoices.go:657 +#: pkg/invoices.go:661 msgid "invoices.zip" msgstr "factures.zip" -#: pkg/invoices.go:791 +#: pkg/invoices.go:675 +msgid "invoices.ods" +msgstr "factures.ods" + +#: pkg/invoices.go:805 msgid "Selected invoice status is not valid." msgstr "Heu seleccionat un estat de factura que no és vàlid." -#: pkg/invoices.go:793 +#: pkg/invoices.go:807 msgid "Invoice date can not be empty." msgstr "No podeu deixar la data de la factura en blanc." -#: pkg/invoices.go:929 +#: pkg/invoices.go:943 #, c-format msgid "Re: quotation #%s of %s" msgstr "Ref: pressupost núm. %s del %s" -#: pkg/invoices.go:930 +#: pkg/invoices.go:944 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoices.go:1093 +#: pkg/invoices.go:1107 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." -#: pkg/contacts.go:283 +#: pkg/contacts.go:292 msgctxt "input" msgid "Need to input tax details" msgstr "Necessito poder facturar aquest contacte" -#: pkg/contacts.go:343 +#: pkg/contacts.go:352 msgctxt "input" msgid "IBAN" msgstr "IBAN" -#: pkg/contacts.go:348 +#: pkg/contacts.go:357 msgctxt "bic" msgid "BIC" msgstr "BIC" -#: pkg/contacts.go:404 +#: pkg/contacts.go:413 msgid "Name must have at least two letters." msgstr "El nom ha de tenir com a mínim dues lletres." -#: pkg/contacts.go:417 +#: pkg/contacts.go:426 msgid "This values is not a valid IBAN." msgstr "Aquest valor no és un IBAN vàlid." -#: pkg/contacts.go:420 +#: pkg/contacts.go:429 msgid "This values is not a valid BIC." msgstr "Aquest valor no és un BIC vàlid." -#: pkg/contacts.go:534 +#: pkg/contacts.go:551 msgctxt "input" msgid "Holded Excel file" msgstr "Fitxer Excel del Holded" diff --git a/po/es.po b/po/es.po index 8478bbb..6ed4ce7 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-07-16 20:50+0200\n" +"POT-Creation-Date: 2023-07-18 13:12+0200\n" "PO-Revision-Date: 2023-01-18 17:45+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -126,117 +126,123 @@ msgctxt "action" msgid "Save" msgstr "Guardad" -#: web/template/invoices/index.gohtml:19 +#: web/template/invoices/index.gohtml:28 msgctxt "action" msgid "Download invoices" msgstr "Descargar facturas" -#: web/template/invoices/index.gohtml:21 +#: web/template/invoices/index.gohtml:31 web/template/quotes/index.gohtml:31 +#: web/template/expenses/index.gohtml:29 +msgctxt "action" +msgid "Export list" +msgstr "Exportar listado" + +#: web/template/invoices/index.gohtml:33 msgctxt "action" msgid "New invoice" msgstr "Nueva factura" -#: web/template/invoices/index.gohtml:45 web/template/dashboard.gohtml:23 -#: web/template/quotes/index.gohtml:45 web/template/contacts/index.gohtml:38 -#: web/template/expenses/index.gohtml:39 web/template/products/index.gohtml:36 +#: web/template/invoices/index.gohtml:57 web/template/dashboard.gohtml:23 +#: web/template/quotes/index.gohtml:57 web/template/contacts/index.gohtml:38 +#: web/template/expenses/index.gohtml:56 web/template/products/index.gohtml:36 msgctxt "action" msgid "Filter" msgstr "Filtrar" -#: web/template/invoices/index.gohtml:48 web/template/quotes/index.gohtml:48 -#: web/template/contacts/index.gohtml:41 web/template/expenses/index.gohtml:42 +#: web/template/invoices/index.gohtml:60 web/template/quotes/index.gohtml:60 +#: web/template/contacts/index.gohtml:41 web/template/expenses/index.gohtml:59 #: web/template/products/index.gohtml:39 msgctxt "action" msgid "Reset" msgstr "Restablecer" -#: web/template/invoices/index.gohtml:54 +#: web/template/invoices/index.gohtml:66 msgctxt "invoice" msgid "All" msgstr "Todas" -#: web/template/invoices/index.gohtml:55 web/template/invoices/view.gohtml:38 -#: web/template/quotes/index.gohtml:55 web/template/quotes/view.gohtml:37 +#: web/template/invoices/index.gohtml:67 web/template/invoices/view.gohtml:38 +#: web/template/quotes/index.gohtml:67 web/template/quotes/view.gohtml:37 msgctxt "title" msgid "Date" msgstr "Fecha" -#: web/template/invoices/index.gohtml:56 +#: web/template/invoices/index.gohtml:68 msgctxt "title" msgid "Invoice Num." msgstr "N.º factura" -#: web/template/invoices/index.gohtml:57 web/template/quotes/index.gohtml:57 +#: web/template/invoices/index.gohtml:69 web/template/quotes/index.gohtml:69 msgctxt "title" msgid "Customer" msgstr "Cliente" -#: web/template/invoices/index.gohtml:58 web/template/quotes/index.gohtml:58 -#: web/template/expenses/index.gohtml:51 +#: web/template/invoices/index.gohtml:70 web/template/quotes/index.gohtml:70 +#: web/template/expenses/index.gohtml:68 msgctxt "title" msgid "Status" msgstr "Estado" -#: web/template/invoices/index.gohtml:59 web/template/quotes/index.gohtml:59 -#: web/template/contacts/index.gohtml:50 web/template/expenses/index.gohtml:52 +#: web/template/invoices/index.gohtml:71 web/template/quotes/index.gohtml:71 +#: web/template/contacts/index.gohtml:50 web/template/expenses/index.gohtml:69 #: web/template/products/index.gohtml:46 msgctxt "title" msgid "Tags" msgstr "Etiquetes" -#: web/template/invoices/index.gohtml:60 web/template/quotes/index.gohtml:60 -#: web/template/expenses/index.gohtml:53 +#: web/template/invoices/index.gohtml:72 web/template/quotes/index.gohtml:72 +#: web/template/expenses/index.gohtml:70 msgctxt "title" msgid "Amount" msgstr "Importe" -#: web/template/invoices/index.gohtml:61 web/template/quotes/index.gohtml:61 -#: web/template/expenses/index.gohtml:54 +#: web/template/invoices/index.gohtml:73 web/template/quotes/index.gohtml:73 +#: web/template/expenses/index.gohtml:71 msgctxt "title" msgid "Download" msgstr "Descargar" -#: web/template/invoices/index.gohtml:62 web/template/quotes/index.gohtml:62 -#: web/template/contacts/index.gohtml:51 web/template/expenses/index.gohtml:55 +#: web/template/invoices/index.gohtml:74 web/template/quotes/index.gohtml:74 +#: web/template/contacts/index.gohtml:51 web/template/expenses/index.gohtml:72 #: web/template/products/index.gohtml:48 msgctxt "title" msgid "Actions" msgstr "Acciones" -#: web/template/invoices/index.gohtml:69 +#: web/template/invoices/index.gohtml:81 msgctxt "action" msgid "Select invoice %v" msgstr "Seleccionar factura %v" -#: web/template/invoices/index.gohtml:110 +#: web/template/invoices/index.gohtml:122 msgctxt "action" msgid "Download invoice %s" msgstr "Descargar factura %s" -#: web/template/invoices/index.gohtml:118 +#: web/template/invoices/index.gohtml:130 msgid "Actions for invoice %s" msgstr "Acciones para la factura %s" -#: web/template/invoices/index.gohtml:126 web/template/invoices/view.gohtml:19 -#: web/template/quotes/index.gohtml:125 web/template/quotes/view.gohtml:22 -#: web/template/contacts/index.gohtml:82 web/template/expenses/index.gohtml:117 +#: web/template/invoices/index.gohtml:138 web/template/invoices/view.gohtml:19 +#: web/template/quotes/index.gohtml:137 web/template/quotes/view.gohtml:22 +#: web/template/contacts/index.gohtml:82 web/template/expenses/index.gohtml:134 #: web/template/products/index.gohtml:78 msgctxt "action" msgid "Edit" msgstr "Editar" -#: web/template/invoices/index.gohtml:134 web/template/invoices/view.gohtml:16 -#: web/template/quotes/index.gohtml:133 web/template/quotes/view.gohtml:19 +#: web/template/invoices/index.gohtml:146 web/template/invoices/view.gohtml:16 +#: web/template/quotes/index.gohtml:145 web/template/quotes/view.gohtml:19 msgctxt "action" msgid "Duplicate" msgstr "Duplicar" -#: web/template/invoices/index.gohtml:144 +#: web/template/invoices/index.gohtml:156 msgid "No invoices added yet." msgstr "No hay facturas." -#: web/template/invoices/index.gohtml:151 web/template/quotes/index.gohtml:158 -#: web/template/expenses/index.gohtml:134 +#: web/template/invoices/index.gohtml:163 web/template/quotes/index.gohtml:170 +#: web/template/expenses/index.gohtml:151 msgid "Total" msgstr "Total" @@ -363,41 +369,41 @@ msgctxt "title" msgid "New Quotation" msgstr "Nuevo presupuesto" -#: web/template/quotes/index.gohtml:19 +#: web/template/quotes/index.gohtml:28 msgctxt "action" msgid "Download quotations" msgstr "Descargar presupuestos" -#: web/template/quotes/index.gohtml:21 +#: web/template/quotes/index.gohtml:33 msgctxt "action" msgid "New quotation" msgstr "Nuevo presupuesto" -#: web/template/quotes/index.gohtml:54 +#: web/template/quotes/index.gohtml:66 msgctxt "quote" msgid "All" msgstr "Todos" -#: web/template/quotes/index.gohtml:56 +#: web/template/quotes/index.gohtml:68 msgctxt "title" msgid "Quotation Num." msgstr "N.º de presupuesto" -#: web/template/quotes/index.gohtml:69 +#: web/template/quotes/index.gohtml:81 msgctxt "action" msgid "Select quotation %v" msgstr "Seleccionar presupuesto %v" -#: web/template/quotes/index.gohtml:117 +#: web/template/quotes/index.gohtml:129 msgid "Actions for quote %s" msgstr "Acciones para el presupuesto %s" -#: web/template/quotes/index.gohtml:141 web/template/quotes/view.gohtml:16 +#: web/template/quotes/index.gohtml:153 web/template/quotes/view.gohtml:16 msgctxt "action" msgid "Create invoice" msgstr "Crear factura" -#: web/template/quotes/index.gohtml:151 +#: web/template/quotes/index.gohtml:163 msgid "No quotations added yet." msgstr "No hay presupuestos." @@ -488,7 +494,7 @@ msgctxt "action" msgid "New contact" msgstr "Nuevo contacto" -#: web/template/contacts/index.gohtml:47 web/template/expenses/index.gohtml:48 +#: web/template/contacts/index.gohtml:47 web/template/expenses/index.gohtml:65 msgctxt "title" msgid "Contact" msgstr "Contacto" @@ -569,26 +575,26 @@ msgctxt "title" msgid "Expenses" msgstr "Gastos" -#: web/template/expenses/index.gohtml:16 +#: web/template/expenses/index.gohtml:32 msgctxt "action" msgid "New expense" msgstr "Nuevo gasto" -#: web/template/expenses/index.gohtml:49 +#: web/template/expenses/index.gohtml:66 msgctxt "title" msgid "Invoice Date" msgstr "Fecha de factura" -#: web/template/expenses/index.gohtml:50 +#: web/template/expenses/index.gohtml:67 msgctxt "title" msgid "Invoice Number" msgstr "Número de factura" -#: web/template/expenses/index.gohtml:109 +#: web/template/expenses/index.gohtml:126 msgid "Actions for expense %s" msgstr "Acciones para el gasto %s" -#: web/template/expenses/index.gohtml:127 +#: web/template/expenses/index.gohtml:144 msgid "No expenses added yet." msgstr "No hay gastos." @@ -695,7 +701,7 @@ msgctxt "title" msgid "Edit Product “%s”" msgstr "Edición del producto «%s»" -#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:267 +#: pkg/login.go:37 pkg/company.go:127 pkg/profile.go:40 pkg/contacts.go:276 msgctxt "input" msgid "Email" msgstr "Correo-e" @@ -709,7 +715,7 @@ msgstr "Contraseña" msgid "Email can not be empty." msgstr "No podéis dejar el correo-e en blanco." -#: pkg/login.go:71 pkg/company.go:284 pkg/profile.go:90 pkg/contacts.go:411 +#: pkg/login.go:71 pkg/company.go:284 pkg/profile.go:90 pkg/contacts.go:420 msgid "This value is not a valid email. It should be like name@domain.com." msgstr "Este valor no es un correo-e válido. Tiene que ser parecido a nombre@dominio.es." @@ -721,84 +727,84 @@ 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:268 pkg/quote.go:887 -#: pkg/invoices.go:1002 pkg/contacts.go:140 pkg/contacts.go:253 +#: pkg/products.go:172 pkg/products.go:276 pkg/quote.go:901 +#: pkg/invoices.go:1016 pkg/contacts.go:149 pkg/contacts.go:262 msgctxt "input" msgid "Name" msgstr "Nombre" -#: pkg/products.go:169 pkg/products.go:295 pkg/quote.go:174 pkg/quote.go:694 -#: pkg/expenses.go:274 pkg/expenses.go:433 pkg/invoices.go:174 -#: pkg/invoices.go:732 pkg/invoices.go:1304 pkg/contacts.go:145 -#: pkg/contacts.go:353 +#: pkg/products.go:177 pkg/products.go:303 pkg/quote.go:174 pkg/quote.go:708 +#: pkg/expenses.go:278 pkg/expenses.go:442 pkg/invoices.go:174 +#: pkg/invoices.go:746 pkg/invoices.go:1331 pkg/contacts.go:154 +#: pkg/contacts.go:362 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:173 pkg/quote.go:178 pkg/expenses.go:443 pkg/invoices.go:178 -#: pkg/contacts.go:149 +#: pkg/products.go:181 pkg/quote.go:178 pkg/expenses.go:452 pkg/invoices.go:178 +#: pkg/contacts.go:158 msgctxt "input" msgid "Tags Condition" msgstr "Condición de las etiquetas" -#: pkg/products.go:177 pkg/quote.go:182 pkg/expenses.go:447 pkg/invoices.go:182 -#: pkg/contacts.go:153 +#: pkg/products.go:185 pkg/quote.go:182 pkg/expenses.go:456 pkg/invoices.go:182 +#: pkg/contacts.go:162 msgctxt "tag condition" msgid "All" msgstr "Todas" -#: pkg/products.go:178 pkg/expenses.go:448 pkg/invoices.go:183 -#: pkg/contacts.go:154 +#: pkg/products.go:186 pkg/expenses.go:457 pkg/invoices.go:183 +#: pkg/contacts.go:163 msgid "Invoices must have all the specified labels." msgstr "Las facturas deben tener todas las etiquetas." -#: pkg/products.go:182 pkg/quote.go:187 pkg/expenses.go:452 pkg/invoices.go:187 -#: pkg/contacts.go:158 +#: pkg/products.go:190 pkg/quote.go:187 pkg/expenses.go:461 pkg/invoices.go:187 +#: pkg/contacts.go:167 msgctxt "tag condition" msgid "Any" msgstr "Cualquiera" -#: pkg/products.go:183 pkg/expenses.go:453 pkg/invoices.go:188 -#: pkg/contacts.go:159 +#: pkg/products.go:191 pkg/expenses.go:462 pkg/invoices.go:188 +#: pkg/contacts.go:168 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:274 pkg/quote.go:901 pkg/invoices.go:1016 +#: pkg/products.go:282 pkg/quote.go:915 pkg/invoices.go:1030 msgctxt "input" msgid "Description" msgstr "Descripción" -#: pkg/products.go:279 pkg/quote.go:905 pkg/invoices.go:1020 +#: pkg/products.go:287 pkg/quote.go:919 pkg/invoices.go:1034 msgctxt "input" msgid "Price" msgstr "Precio" -#: pkg/products.go:289 pkg/quote.go:934 pkg/expenses.go:242 -#: pkg/invoices.go:1049 +#: pkg/products.go:297 pkg/quote.go:948 pkg/expenses.go:246 +#: pkg/invoices.go:1063 msgctxt "input" msgid "Taxes" msgstr "Impuestos" -#: pkg/products.go:314 pkg/quote.go:983 pkg/profile.go:92 pkg/invoices.go:1098 -#: pkg/contacts.go:403 +#: pkg/products.go:322 pkg/quote.go:997 pkg/profile.go:92 pkg/invoices.go:1112 +#: pkg/contacts.go:412 msgid "Name can not be empty." msgstr "No podéis dejar el nombre en blanco." -#: pkg/products.go:315 pkg/quote.go:984 pkg/invoices.go:1099 +#: pkg/products.go:323 pkg/quote.go:998 pkg/invoices.go:1113 msgid "Price can not be empty." msgstr "No podéis dejar el precio en blanco." -#: pkg/products.go:316 pkg/quote.go:985 pkg/invoices.go:1100 +#: pkg/products.go:324 pkg/quote.go:999 pkg/invoices.go:1114 msgid "Price must be a number greater than zero." msgstr "El precio tiene que ser un número mayor a cero." -#: pkg/products.go:318 pkg/quote.go:993 pkg/expenses.go:310 -#: pkg/invoices.go:1108 +#: pkg/products.go:326 pkg/quote.go:1007 pkg/expenses.go:314 +#: pkg/invoices.go:1122 msgid "Selected tax is not valid." msgstr "Habéis escogido un impuesto que no es válido." -#: pkg/products.go:319 pkg/quote.go:994 pkg/expenses.go:311 -#: pkg/invoices.go:1109 +#: pkg/products.go:327 pkg/quote.go:1008 pkg/expenses.go:315 +#: pkg/invoices.go:1123 msgid "You can only select a tax of each class." msgstr "Solo podéis escoger un impuesto de cada clase." @@ -807,47 +813,47 @@ msgctxt "input" msgid "Trade name" msgstr "Nombre comercial" -#: pkg/company.go:118 pkg/contacts.go:259 +#: pkg/company.go:118 pkg/contacts.go:268 msgctxt "input" msgid "Phone" msgstr "Teléfono" -#: pkg/company.go:136 pkg/contacts.go:275 +#: pkg/company.go:136 pkg/contacts.go:284 msgctxt "input" msgid "Web" msgstr "Web" -#: pkg/company.go:144 pkg/contacts.go:287 +#: pkg/company.go:144 pkg/contacts.go:296 msgctxt "input" msgid "Business name" msgstr "Nombre y apellidos" -#: pkg/company.go:154 pkg/contacts.go:297 +#: pkg/company.go:154 pkg/contacts.go:306 msgctxt "input" msgid "VAT number" msgstr "DNI / NIF" -#: pkg/company.go:160 pkg/contacts.go:303 +#: pkg/company.go:160 pkg/contacts.go:312 msgctxt "input" msgid "Address" msgstr "Dirección" -#: pkg/company.go:169 pkg/contacts.go:312 +#: pkg/company.go:169 pkg/contacts.go:321 msgctxt "input" msgid "City" msgstr "Población" -#: pkg/company.go:175 pkg/contacts.go:318 +#: pkg/company.go:175 pkg/contacts.go:327 msgctxt "input" msgid "Province" msgstr "Provincia" -#: pkg/company.go:181 pkg/contacts.go:324 +#: pkg/company.go:181 pkg/contacts.go:333 msgctxt "input" msgid "Postal code" msgstr "Código postal" -#: pkg/company.go:190 pkg/contacts.go:333 +#: pkg/company.go:190 pkg/contacts.go:342 msgctxt "input" msgid "Country" msgstr "País" @@ -882,23 +888,23 @@ msgctxt "input" msgid "Legal disclaimer" msgstr "Nota legal" -#: pkg/company.go:271 pkg/contacts.go:385 +#: pkg/company.go:271 pkg/contacts.go:394 msgid "Selected country is not valid." msgstr "Habéis escogido un país que no es válido." -#: pkg/company.go:275 pkg/contacts.go:388 +#: pkg/company.go:275 pkg/contacts.go:397 msgid "Business name can not be empty." msgstr "No podéis dejar el nombre y los apellidos en blanco." -#: pkg/company.go:276 pkg/contacts.go:389 +#: pkg/company.go:276 pkg/contacts.go:398 msgid "Business name must have at least two letters." msgstr "El nombre y los apellidos deben contener como mínimo dos letras." -#: pkg/company.go:277 pkg/contacts.go:391 +#: pkg/company.go:277 pkg/contacts.go:400 msgid "VAT number can not be empty." msgstr "No podéis dejar el DNI o NIF en blanco." -#: pkg/company.go:278 pkg/contacts.go:392 +#: pkg/company.go:278 pkg/contacts.go:401 msgid "This value is not a valid VAT number." msgstr "Este valor no es un DNI o NIF válido." @@ -906,31 +912,31 @@ msgstr "Este valor no es un DNI o NIF válido." msgid "Phone can not be empty." msgstr "No podéis dejar el teléfono en blanco." -#: pkg/company.go:281 pkg/contacts.go:408 +#: pkg/company.go:281 pkg/contacts.go:417 msgid "This value is not a valid phone number." msgstr "Este valor no es un teléfono válido." -#: pkg/company.go:287 pkg/contacts.go:414 +#: pkg/company.go:287 pkg/contacts.go:423 msgid "This value is not a valid web address. It should be like https://domain.com/." msgstr "Este valor no es una dirección web válida. Tiene que ser parecida a https://dominio.es/." -#: pkg/company.go:289 pkg/contacts.go:394 +#: pkg/company.go:289 pkg/contacts.go:403 msgid "Address can not be empty." msgstr "No podéis dejar la dirección en blanco." -#: pkg/company.go:290 pkg/contacts.go:395 +#: pkg/company.go:290 pkg/contacts.go:404 msgid "City can not be empty." msgstr "No podéis dejar la población en blanco." -#: pkg/company.go:291 pkg/contacts.go:396 +#: pkg/company.go:291 pkg/contacts.go:405 msgid "Province can not be empty." msgstr "No podéis dejar la provincia en blanco." -#: pkg/company.go:292 pkg/contacts.go:398 +#: pkg/company.go:292 pkg/contacts.go:407 msgid "Postal code can not be empty." msgstr "No podéis dejar el código postal en blanco." -#: pkg/company.go:293 pkg/contacts.go:399 +#: pkg/company.go:293 pkg/contacts.go:408 msgid "This value is not a valid postal code." msgstr "Este valor no es un código postal válido válido." @@ -1007,7 +1013,7 @@ 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:147 pkg/quote.go:672 pkg/invoices.go:147 pkg/invoices.go:715 +#: pkg/quote.go:147 pkg/quote.go:686 pkg/invoices.go:147 pkg/invoices.go:729 msgctxt "input" msgid "Customer" msgstr "Cliente" @@ -1016,12 +1022,12 @@ msgstr "Cliente" msgid "All customers" msgstr "Todos los clientes" -#: pkg/quote.go:153 pkg/quote.go:666 +#: pkg/quote.go:153 pkg/quote.go:680 msgctxt "input" msgid "Quotation Status" msgstr "Estado del presupuesto" -#: pkg/quote.go:154 pkg/expenses.go:438 pkg/invoices.go:154 +#: pkg/quote.go:154 pkg/expenses.go:447 pkg/invoices.go:154 msgid "All status" msgstr "Todos los estados" @@ -1030,12 +1036,12 @@ msgctxt "input" msgid "Quotation Number" msgstr "Número de presupuesto" -#: pkg/quote.go:164 pkg/expenses.go:423 pkg/invoices.go:164 +#: pkg/quote.go:164 pkg/expenses.go:432 pkg/invoices.go:164 msgctxt "input" msgid "From Date" msgstr "A partir de la fecha" -#: pkg/quote.go:169 pkg/expenses.go:428 pkg/invoices.go:169 +#: pkg/quote.go:169 pkg/expenses.go:437 pkg/invoices.go:169 msgctxt "input" msgid "To Date" msgstr "Hasta la fecha" @@ -1048,99 +1054,104 @@ msgstr "Los presupuestos deben tener todas las etiquetas." 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:614 +#: pkg/quote.go:618 msgid "quotations.zip" msgstr "presupuestos.zip" -#: pkg/quote.go:620 pkg/quote.go:1149 pkg/quote.go:1157 pkg/expenses.go:620 -#: pkg/invoices.go:663 pkg/invoices.go:1279 pkg/invoices.go:1287 +#: pkg/quote.go:632 +msgid "quotations.ods" +msgstr "presupuestos.ods" + +#: pkg/quote.go:634 pkg/quote.go:1176 pkg/quote.go:1184 pkg/expenses.go:651 +#: pkg/expenses.go:677 pkg/invoices.go:677 pkg/invoices.go:1306 +#: pkg/invoices.go:1314 msgid "Invalid action" msgstr "Acción inválida." -#: pkg/quote.go:673 +#: pkg/quote.go:687 msgid "Select a customer to quote." msgstr "Escoged un cliente a presupuestar." -#: pkg/quote.go:678 +#: pkg/quote.go:692 msgctxt "input" msgid "Quotation Date" msgstr "Fecha del presupuesto" -#: pkg/quote.go:684 +#: pkg/quote.go:698 msgctxt "input" msgid "Terms and conditions" msgstr "Condiciones de aceptación" -#: pkg/quote.go:689 pkg/invoices.go:727 +#: pkg/quote.go:703 pkg/invoices.go:741 msgctxt "input" msgid "Notes" msgstr "Notas" -#: pkg/quote.go:698 pkg/invoices.go:737 +#: pkg/quote.go:712 pkg/invoices.go:751 msgctxt "input" msgid "Payment Method" msgstr "Método de pago" -#: pkg/quote.go:699 +#: pkg/quote.go:713 msgid "Select a payment method." msgstr "Escoged un método e pago." -#: pkg/quote.go:735 +#: pkg/quote.go:749 msgid "Selected quotation status is not valid." msgstr "Habéis escogido un estado de presupuesto que no es válido." -#: pkg/quote.go:737 pkg/invoices.go:792 +#: pkg/quote.go:751 pkg/invoices.go:806 msgid "Selected customer is not valid." msgstr "Habéis escogido un cliente que no es válido." -#: pkg/quote.go:739 +#: pkg/quote.go:753 msgid "Quotation date can not be empty." msgstr "No podéis dejar la fecha del presupuesto en blanco." -#: pkg/quote.go:740 +#: pkg/quote.go:754 msgid "Quotation date must be a valid date." msgstr "La fecha de presupuesto debe ser válida." -#: pkg/quote.go:743 pkg/invoices.go:796 +#: pkg/quote.go:757 pkg/invoices.go:810 msgid "Selected payment method is not valid." msgstr "Habéis escogido un método de pago que no es válido." -#: pkg/quote.go:877 pkg/quote.go:882 pkg/invoices.go:992 pkg/invoices.go:997 +#: pkg/quote.go:891 pkg/quote.go:896 pkg/invoices.go:1006 pkg/invoices.go:1011 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/quote.go:915 pkg/invoices.go:1030 +#: pkg/quote.go:929 pkg/invoices.go:1044 msgctxt "input" msgid "Quantity" msgstr "Cantidad" -#: pkg/quote.go:924 pkg/invoices.go:1039 +#: pkg/quote.go:938 pkg/invoices.go:1053 msgctxt "input" msgid "Discount (%)" msgstr "Descuento (%)" -#: pkg/quote.go:978 +#: pkg/quote.go:992 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:981 pkg/invoices.go:1096 +#: pkg/quote.go:995 pkg/invoices.go:1110 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:987 pkg/invoices.go:1102 +#: pkg/quote.go:1001 pkg/invoices.go:1116 msgid "Quantity can not be empty." msgstr "No podéis dejar la cantidad en blanco." -#: pkg/quote.go:988 pkg/invoices.go:1103 +#: pkg/quote.go:1002 pkg/invoices.go:1117 msgid "Quantity must be a number greater than zero." msgstr "La cantidad tiene que ser un número mayor a cero." -#: pkg/quote.go:990 pkg/invoices.go:1105 +#: pkg/quote.go:1004 pkg/invoices.go:1119 msgid "Discount can not be empty." msgstr "No podéis dejar el descuento en blanco." -#: pkg/quote.go:991 pkg/invoices.go:1106 +#: pkg/quote.go:1005 pkg/invoices.go:1120 msgid "Discount must be a percentage between 0 and 100." msgstr "El descuento tiene que ser un porcentaje entre 0 y 100." @@ -1207,132 +1218,140 @@ msgctxt "period option" msgid "Previous year" msgstr "Año anterior" -#: pkg/expenses.go:168 +#: pkg/expenses.go:172 msgid "Select a contact." msgstr "Escoged un contacto" -#: pkg/expenses.go:225 pkg/expenses.go:412 +#: pkg/expenses.go:229 pkg/expenses.go:421 msgctxt "input" msgid "Contact" msgstr "Contacto" -#: pkg/expenses.go:231 +#: pkg/expenses.go:235 msgctxt "input" msgid "Invoice number" msgstr "Número de factura" -#: pkg/expenses.go:236 pkg/invoices.go:721 +#: pkg/expenses.go:240 pkg/invoices.go:735 msgctxt "input" msgid "Invoice Date" msgstr "Fecha de factura" -#: pkg/expenses.go:251 +#: pkg/expenses.go:255 msgctxt "input" msgid "Amount" msgstr "Importe" -#: pkg/expenses.go:262 pkg/invoices.go:743 +#: pkg/expenses.go:266 pkg/invoices.go:757 msgctxt "input" msgid "File" msgstr "Archivo" -#: pkg/expenses.go:268 pkg/expenses.go:437 +#: pkg/expenses.go:272 pkg/expenses.go:446 msgctxt "input" msgid "Expense Status" msgstr "Estado del gasto" -#: pkg/expenses.go:308 +#: pkg/expenses.go:312 msgid "Selected contact is not valid." msgstr "Habéis escogido un contacto que no es válido." -#: pkg/expenses.go:309 pkg/invoices.go:794 +#: pkg/expenses.go:313 pkg/invoices.go:808 msgid "Invoice date must be a valid date." msgstr "La fecha de factura debe ser válida." -#: pkg/expenses.go:312 +#: pkg/expenses.go:316 msgid "Amount can not be empty." msgstr "No podéis dejar el importe en blanco." -#: pkg/expenses.go:313 +#: pkg/expenses.go:317 msgid "Amount must be a number greater than zero." msgstr "El importe tiene que ser un número mayor a cero." -#: pkg/expenses.go:315 +#: pkg/expenses.go:319 msgid "Selected expense status is not valid." msgstr "Habéis escogido un estado de gasto que no es válido." -#: pkg/expenses.go:413 +#: pkg/expenses.go:422 msgid "All contacts" msgstr "Todos los contactos" -#: pkg/expenses.go:418 pkg/invoices.go:159 +#: pkg/expenses.go:427 pkg/invoices.go:159 msgctxt "input" msgid "Invoice Number" msgstr "Número de factura" -#: pkg/invoices.go:153 pkg/invoices.go:709 +#: pkg/expenses.go:675 +msgid "expenses.ods" +msgstr "gastos.ods" + +#: pkg/invoices.go:153 pkg/invoices.go:723 msgctxt "input" msgid "Invoice Status" msgstr "Estado de la factura" -#: pkg/invoices.go:553 +#: pkg/invoices.go:557 msgid "Select a customer to bill." msgstr "Escoged un cliente a facturar." -#: pkg/invoices.go:657 +#: pkg/invoices.go:661 msgid "invoices.zip" msgstr "facturas.zip" -#: pkg/invoices.go:791 +#: pkg/invoices.go:675 +msgid "invoices.ods" +msgstr "facturas.ods" + +#: pkg/invoices.go:805 msgid "Selected invoice status is not valid." msgstr "Habéis escogido un estado de factura que no es válido." -#: pkg/invoices.go:793 +#: pkg/invoices.go:807 msgid "Invoice date can not be empty." msgstr "No podéis dejar la fecha de la factura en blanco." -#: pkg/invoices.go:929 +#: pkg/invoices.go:943 #, c-format msgid "Re: quotation #%s of %s" msgstr "Ref: presupuesto n.º %s del %s" -#: pkg/invoices.go:930 +#: pkg/invoices.go:944 msgctxt "to_char" msgid "MM/DD/YYYY" msgstr "DD/MM/YYYY" -#: pkg/invoices.go:1093 +#: pkg/invoices.go:1107 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." -#: pkg/contacts.go:283 +#: pkg/contacts.go:292 msgctxt "input" msgid "Need to input tax details" msgstr "Necesito facturar este contacto" -#: pkg/contacts.go:343 +#: pkg/contacts.go:352 msgctxt "input" msgid "IBAN" msgstr "IBAN" -#: pkg/contacts.go:348 +#: pkg/contacts.go:357 msgctxt "bic" msgid "BIC" msgstr "BIC" -#: pkg/contacts.go:404 +#: pkg/contacts.go:413 msgid "Name must have at least two letters." msgstr "El nombre debe contener como mínimo dos letras." -#: pkg/contacts.go:417 +#: pkg/contacts.go:426 msgid "This values is not a valid IBAN." msgstr "Este valor no es un IBAN válido." -#: pkg/contacts.go:420 +#: pkg/contacts.go:429 msgid "This values is not a valid BIC." msgstr "Este valor no es un BIC válido." -#: pkg/contacts.go:534 +#: pkg/contacts.go:551 msgctxt "input" msgid "Holded Excel file" msgstr "Archivo Excel de Holded" diff --git a/web/template/expenses/index.gohtml b/web/template/expenses/index.gohtml index 76e8905..ebbe50a 100644 --- a/web/template/expenses/index.gohtml +++ b/web/template/expenses/index.gohtml @@ -5,16 +5,33 @@ {{ define "breadcrumbs" -}} {{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}} -