Add expenses’ index and add form
This commit is contained in:
parent
97ad76d82c
commit
55d650bd62
|
@ -0,0 +1,239 @@
|
||||||
|
package pkg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/julienschmidt/httprouter"
|
||||||
|
"html/template"
|
||||||
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExpenseEntry struct {
|
||||||
|
Slug string
|
||||||
|
InvoiceDate time.Time
|
||||||
|
InvoiceNumber string
|
||||||
|
Amount string
|
||||||
|
InvoicerName string
|
||||||
|
Tags []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type expensesIndexPage struct {
|
||||||
|
Expenses []*ExpenseEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
func IndexExpenses(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
|
conn := getConn(r)
|
||||||
|
company := mustGetCompany(r)
|
||||||
|
page := &expensesIndexPage{
|
||||||
|
Expenses: mustCollectExpenseEntries(r.Context(), conn, company),
|
||||||
|
}
|
||||||
|
mustRenderMainTemplate(w, r, "expenses/index.gohtml", page)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustCollectExpenseEntries(ctx context.Context, conn *Conn, company *Company) []*ExpenseEntry {
|
||||||
|
rows, err := conn.Query(ctx, `
|
||||||
|
select expense.slug
|
||||||
|
, invoice_date
|
||||||
|
, invoice_number
|
||||||
|
, to_price(amount, decimal_digits)
|
||||||
|
, contact.business_name
|
||||||
|
, expense.tags
|
||||||
|
from expense
|
||||||
|
join contact using (contact_id)
|
||||||
|
join currency using (currency_code)
|
||||||
|
where expense.company_id = $1
|
||||||
|
order by invoice_date
|
||||||
|
`, company.Id)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var entries []*ExpenseEntry
|
||||||
|
for rows.Next() {
|
||||||
|
entry := &ExpenseEntry{}
|
||||||
|
err = rows.Scan(&entry.Slug, &entry.InvoiceDate, &entry.InvoiceNumber, &entry.Amount, &entry.InvoicerName, &entry.Tags)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
panic(rows.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries
|
||||||
|
}
|
||||||
|
func ServeExpenseForm(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
|
locale := getLocale(r)
|
||||||
|
conn := getConn(r)
|
||||||
|
company := mustGetCompany(r)
|
||||||
|
form := newExpenseForm(r.Context(), conn, locale, company)
|
||||||
|
slug := params[0].Value
|
||||||
|
if slug == "new" {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
form.InvoiceDate.Val = time.Now().Format("2006-01-02")
|
||||||
|
mustRenderNewExpenseForm(w, r, form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !form.MustFillFromDatabase(r.Context(), conn, slug) {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
mustRenderEditExpenseForm(w, r, slug, form)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustRenderNewExpenseForm(w http.ResponseWriter, r *http.Request, form *expenseForm) {
|
||||||
|
locale := getLocale(r)
|
||||||
|
form.Invoicer.EmptyLabel = gettext("Select a contact.", locale)
|
||||||
|
mustRenderMainTemplate(w, r, "expenses/new.gohtml", form)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustRenderEditExpenseForm(w http.ResponseWriter, r *http.Request, slug string, form *expenseForm) {
|
||||||
|
page := &editExpensePage{
|
||||||
|
Slug: slug,
|
||||||
|
Form: form,
|
||||||
|
}
|
||||||
|
mustRenderMainTemplate(w, r, "expenses/edit.gohtml", page)
|
||||||
|
}
|
||||||
|
|
||||||
|
type editExpensePage struct {
|
||||||
|
Slug string
|
||||||
|
Form *expenseForm
|
||||||
|
}
|
||||||
|
|
||||||
|
type expenseForm struct {
|
||||||
|
locale *Locale
|
||||||
|
company *Company
|
||||||
|
Invoicer *SelectField
|
||||||
|
InvoiceNumber *InputField
|
||||||
|
InvoiceDate *InputField
|
||||||
|
Tax *SelectField
|
||||||
|
Amount *InputField
|
||||||
|
Tags *TagsField
|
||||||
|
}
|
||||||
|
|
||||||
|
func newExpenseForm(ctx context.Context, conn *Conn, locale *Locale, company *Company) *expenseForm {
|
||||||
|
return &expenseForm{
|
||||||
|
locale: locale,
|
||||||
|
company: company,
|
||||||
|
Invoicer: &SelectField{
|
||||||
|
Name: "invoicer",
|
||||||
|
Label: pgettext("input", "Contact", locale),
|
||||||
|
Required: true,
|
||||||
|
Options: mustGetContactOptions(ctx, conn, company),
|
||||||
|
},
|
||||||
|
InvoiceNumber: &InputField{
|
||||||
|
Name: "invoice_number",
|
||||||
|
Label: pgettext("input", "Invoice number", locale),
|
||||||
|
Type: "text",
|
||||||
|
},
|
||||||
|
InvoiceDate: &InputField{
|
||||||
|
Name: "invoice_date",
|
||||||
|
Label: pgettext("input", "Invoice Date", locale),
|
||||||
|
Required: true,
|
||||||
|
Type: "date",
|
||||||
|
},
|
||||||
|
Tax: &SelectField{
|
||||||
|
Name: "tax",
|
||||||
|
Label: pgettext("input", "Taxes", locale),
|
||||||
|
Multiple: true,
|
||||||
|
Options: mustGetTaxOptions(ctx, conn, company),
|
||||||
|
},
|
||||||
|
Amount: &InputField{
|
||||||
|
Name: "amount",
|
||||||
|
Label: pgettext("input", "Amount", locale),
|
||||||
|
Type: "number",
|
||||||
|
Required: true,
|
||||||
|
Attributes: []template.HTMLAttr{
|
||||||
|
`min="0"`,
|
||||||
|
template.HTMLAttr(fmt.Sprintf(`step="%v"`, company.MinCents())),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Tags: &TagsField{
|
||||||
|
Name: "tags",
|
||||||
|
Label: pgettext("input", "Tags", locale),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (form *expenseForm) Parse(r *http.Request) error {
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
form.Invoicer.FillValue(r)
|
||||||
|
form.InvoiceNumber.FillValue(r)
|
||||||
|
form.InvoiceDate.FillValue(r)
|
||||||
|
form.Tax.FillValue(r)
|
||||||
|
form.Amount.FillValue(r)
|
||||||
|
form.Tags.FillValue(r)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (form *expenseForm) Validate() bool {
|
||||||
|
validator := newFormValidator()
|
||||||
|
validator.CheckValidSelectOption(form.Invoicer, gettext("Selected contact is not valid.", form.locale))
|
||||||
|
validator.CheckValidDate(form.InvoiceDate, gettext("Invoice date must be a valid date.", form.locale))
|
||||||
|
validator.CheckValidSelectOption(form.Tax, gettext("Selected tax is not valid.", form.locale))
|
||||||
|
validator.CheckAtMostOneOfEachGroup(form.Tax, gettext("You can only select a tax of each class.", form.locale))
|
||||||
|
if validator.CheckRequiredInput(form.Amount, gettext("Amount can not be empty.", form.locale)) {
|
||||||
|
validator.CheckValidDecimal(form.Amount, form.company.MinCents(), math.MaxFloat64, gettext("Amount must be a number greater than zero.", form.locale))
|
||||||
|
}
|
||||||
|
validator.CheckValidSelectOption(form.Tax, gettext("Selected tax is not valid.", form.locale))
|
||||||
|
validator.CheckAtMostOneOfEachGroup(form.Tax, gettext("You can only select a tax of each class.", form.locale))
|
||||||
|
return validator.AllOK()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (form *expenseForm) MustFillFromDatabase(ctx context.Context, conn *Conn, slug string) bool {
|
||||||
|
return !notFoundErrorOrPanic(conn.QueryRow(ctx, `
|
||||||
|
select contact_id
|
||||||
|
, invoice_number
|
||||||
|
, invoice_date
|
||||||
|
, to_price(amount, decimal_digits)
|
||||||
|
, array_agg(tax_id)
|
||||||
|
, array_to_string(tags, ',')
|
||||||
|
from expense
|
||||||
|
left join expense_tax using (expense_id)
|
||||||
|
join currency using (currency_code)
|
||||||
|
where expense.slug = $1
|
||||||
|
group by contact_id
|
||||||
|
, invoice_number
|
||||||
|
, invoice_date
|
||||||
|
, amount
|
||||||
|
, decimal_digits
|
||||||
|
, tags
|
||||||
|
`, slug).Scan(
|
||||||
|
form.Invoicer,
|
||||||
|
form.InvoiceNumber,
|
||||||
|
form.InvoiceDate,
|
||||||
|
form.Amount,
|
||||||
|
form.Tax,
|
||||||
|
form.Tags))
|
||||||
|
}
|
||||||
|
func HandleAddExpense(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
|
conn := getConn(r)
|
||||||
|
locale := getLocale(r)
|
||||||
|
company := mustGetCompany(r)
|
||||||
|
form := newExpenseForm(r.Context(), conn, locale, company)
|
||||||
|
if err := form.Parse(r); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := verifyCsrfTokenValid(r); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !form.Validate() {
|
||||||
|
if !IsHTMxRequest(r) {
|
||||||
|
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||||
|
}
|
||||||
|
mustRenderNewExpenseForm(w, r, form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
taxes := mustSliceAtoi(form.Tax.Selected)
|
||||||
|
conn.MustExec(r.Context(), "select add_expense($1, $2, $3, $4, $5, $6, $7)", company.Id, form.InvoiceDate, form.Invoicer, form.InvoiceNumber, form.Amount, taxes, form.Tags)
|
||||||
|
htmxRedirect(w, r, companyURI(company, "/expenses"))
|
||||||
|
}
|
|
@ -34,6 +34,9 @@ func NewRouter(db *Db) http.Handler {
|
||||||
companyRouter.PUT("/invoices/:slug/tags", HandleUpdateInvoiceTags)
|
companyRouter.PUT("/invoices/:slug/tags", HandleUpdateInvoiceTags)
|
||||||
companyRouter.GET("/invoices/:slug/tags/edit", ServeEditInvoiceTags)
|
companyRouter.GET("/invoices/:slug/tags/edit", ServeEditInvoiceTags)
|
||||||
companyRouter.GET("/search/products", HandleProductSearch)
|
companyRouter.GET("/search/products", HandleProductSearch)
|
||||||
|
companyRouter.GET("/expenses", IndexExpenses)
|
||||||
|
companyRouter.POST("/expenses", HandleAddExpense)
|
||||||
|
companyRouter.GET("/expenses/:slug", ServeExpenseForm)
|
||||||
companyRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
companyRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
mustRenderMainTemplate(w, r, "dashboard.gohtml", nil)
|
mustRenderMainTemplate(w, r, "dashboard.gohtml", nil)
|
||||||
})
|
})
|
||||||
|
|
158
po/ca.po
158
po/ca.po
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: numerus\n"
|
"Project-Id-Version: numerus\n"
|
||||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||||
"POT-Creation-Date: 2023-04-28 00:05+0200\n"
|
"POT-Creation-Date: 2023-05-03 12:40+0200\n"
|
||||||
"PO-Revision-Date: 2023-01-18 17:08+0100\n"
|
"PO-Revision-Date: 2023-01-18 17:08+0100\n"
|
||||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||||
|
@ -27,9 +27,10 @@ msgstr "Afegeix productes a la factura"
|
||||||
#: web/template/invoices/index.gohtml:9 web/template/invoices/view.gohtml:9
|
#: web/template/invoices/index.gohtml:9 web/template/invoices/view.gohtml:9
|
||||||
#: web/template/invoices/edit.gohtml:9 web/template/contacts/new.gohtml:9
|
#: web/template/invoices/edit.gohtml:9 web/template/contacts/new.gohtml:9
|
||||||
#: web/template/contacts/index.gohtml:9 web/template/contacts/edit.gohtml:10
|
#: web/template/contacts/index.gohtml:9 web/template/contacts/edit.gohtml:10
|
||||||
#: web/template/profile.gohtml:9 web/template/tax-details.gohtml:9
|
#: web/template/profile.gohtml:9 web/template/expenses/new.gohtml:10
|
||||||
#: web/template/products/new.gohtml:9 web/template/products/index.gohtml:9
|
#: web/template/expenses/index.gohtml:10 web/template/expenses/edit.gohtml:10
|
||||||
#: web/template/products/edit.gohtml:10
|
#: web/template/tax-details.gohtml:9 web/template/products/new.gohtml:9
|
||||||
|
#: web/template/products/index.gohtml:9 web/template/products/edit.gohtml:10
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "Inici"
|
msgstr "Inici"
|
||||||
|
@ -48,7 +49,7 @@ msgid "New Invoice"
|
||||||
msgstr "Nova factura"
|
msgstr "Nova factura"
|
||||||
|
|
||||||
#: web/template/invoices/products.gohtml:48
|
#: web/template/invoices/products.gohtml:48
|
||||||
#: web/template/products/index.gohtml:38
|
#: web/template/expenses/index.gohtml:25 web/template/products/index.gohtml:38
|
||||||
msgctxt "product"
|
msgctxt "product"
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tots"
|
msgstr "Tots"
|
||||||
|
@ -139,7 +140,7 @@ msgctxt "title"
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetes"
|
msgstr "Etiquetes"
|
||||||
|
|
||||||
#: web/template/invoices/index.gohtml:52
|
#: web/template/invoices/index.gohtml:52 web/template/expenses/index.gohtml:29
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Amount"
|
msgid "Amount"
|
||||||
msgstr "Import"
|
msgstr "Import"
|
||||||
|
@ -245,10 +246,15 @@ msgstr "Factures"
|
||||||
|
|
||||||
#: web/template/app.gohtml:48
|
#: web/template/app.gohtml:48
|
||||||
msgctxt "nav"
|
msgctxt "nav"
|
||||||
|
msgid "Expenses"
|
||||||
|
msgstr "Despeses"
|
||||||
|
|
||||||
|
#: web/template/app.gohtml:49
|
||||||
|
msgctxt "nav"
|
||||||
msgid "Products"
|
msgid "Products"
|
||||||
msgstr "Productes"
|
msgstr "Productes"
|
||||||
|
|
||||||
#: web/template/app.gohtml:49
|
#: web/template/app.gohtml:50
|
||||||
msgctxt "nav"
|
msgctxt "nav"
|
||||||
msgid "Contacts"
|
msgid "Contacts"
|
||||||
msgstr "Contactes"
|
msgstr "Contactes"
|
||||||
|
@ -335,6 +341,52 @@ msgctxt "action"
|
||||||
msgid "Save changes"
|
msgid "Save changes"
|
||||||
msgstr "Desa canvis"
|
msgstr "Desa canvis"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:3 web/template/expenses/new.gohtml:12
|
||||||
|
#: web/template/expenses/new.gohtml:20
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "New Expense"
|
||||||
|
msgstr "Nova despesa"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:11 web/template/expenses/index.gohtml:3
|
||||||
|
#: web/template/expenses/index.gohtml:11 web/template/expenses/edit.gohtml:11
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Expenses"
|
||||||
|
msgstr "Despeses"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:32 web/template/expenses/index.gohtml:15
|
||||||
|
msgctxt "action"
|
||||||
|
msgid "New expense"
|
||||||
|
msgstr "Nova despesa"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:26
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Contact"
|
||||||
|
msgstr "Contacte"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:27
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Invoice Date"
|
||||||
|
msgstr "Data de factura"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:28
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Invoice Number"
|
||||||
|
msgstr "Número de factura"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:52
|
||||||
|
msgid "No expenses added yet."
|
||||||
|
msgstr "No hi ha cap despesa."
|
||||||
|
|
||||||
|
#: web/template/expenses/edit.gohtml:3 web/template/expenses/edit.gohtml:20
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Edit Expense “%s”"
|
||||||
|
msgstr "Edició de la despesa «%s»"
|
||||||
|
|
||||||
|
#: web/template/expenses/edit.gohtml:35
|
||||||
|
msgctxt "action"
|
||||||
|
msgid "Update expense"
|
||||||
|
msgstr "Actualitza despesa"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:10
|
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:10
|
||||||
#: web/template/tax-details.gohtml:18
|
#: web/template/tax-details.gohtml:18
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
|
@ -460,13 +512,14 @@ msgstr "No podeu deixar la contrasenya en blanc."
|
||||||
msgid "Invalid user or password."
|
msgid "Invalid user or password."
|
||||||
msgstr "Nom d’usuari o contrasenya incorrectes."
|
msgstr "Nom d’usuari o contrasenya incorrectes."
|
||||||
|
|
||||||
#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:771
|
#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:776
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
#: pkg/products.go:166 pkg/products.go:287 pkg/invoices.go:187
|
#: pkg/products.go:166 pkg/products.go:287 pkg/expenses.go:158
|
||||||
#: pkg/invoices.go:597 pkg/invoices.go:1031 pkg/contacts.go:256
|
#: pkg/invoices.go:187 pkg/invoices.go:597 pkg/invoices.go:1042
|
||||||
|
#: pkg/contacts.go:256
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetes"
|
msgstr "Etiquetes"
|
||||||
|
@ -494,38 +547,40 @@ msgstr "Qualsevol"
|
||||||
msgid "Invoices must have at least one of the specified labels."
|
msgid "Invoices must have at least one of the specified labels."
|
||||||
msgstr "Les factures han de tenir com a mínim una de les etiquetes."
|
msgstr "Les factures han de tenir com a mínim una de les etiquetes."
|
||||||
|
|
||||||
#: pkg/products.go:266 pkg/invoices.go:785
|
#: pkg/products.go:266 pkg/invoices.go:790
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripció"
|
msgstr "Descripció"
|
||||||
|
|
||||||
#: pkg/products.go:271 pkg/invoices.go:789
|
#: pkg/products.go:271 pkg/invoices.go:794
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr "Preu"
|
msgstr "Preu"
|
||||||
|
|
||||||
#: pkg/products.go:281 pkg/invoices.go:815
|
#: pkg/products.go:281 pkg/expenses.go:142 pkg/invoices.go:823
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Taxes"
|
msgid "Taxes"
|
||||||
msgstr "Imposts"
|
msgstr "Imposts"
|
||||||
|
|
||||||
#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:856
|
#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:867
|
||||||
msgid "Name can not be empty."
|
msgid "Name can not be empty."
|
||||||
msgstr "No podeu deixar el nom en blanc."
|
msgstr "No podeu deixar el nom en blanc."
|
||||||
|
|
||||||
#: pkg/products.go:307 pkg/invoices.go:857
|
#: pkg/products.go:307 pkg/invoices.go:868
|
||||||
msgid "Price can not be empty."
|
msgid "Price can not be empty."
|
||||||
msgstr "No podeu deixar el preu en blanc."
|
msgstr "No podeu deixar el preu en blanc."
|
||||||
|
|
||||||
#: pkg/products.go:308 pkg/invoices.go:858
|
#: pkg/products.go:308 pkg/invoices.go:869
|
||||||
msgid "Price must be a number greater than zero."
|
msgid "Price must be a number greater than zero."
|
||||||
msgstr "El preu ha de ser un número major a zero."
|
msgstr "El preu ha de ser un número major a zero."
|
||||||
|
|
||||||
#: pkg/products.go:310 pkg/invoices.go:866
|
#: pkg/products.go:310 pkg/expenses.go:180 pkg/expenses.go:185
|
||||||
|
#: pkg/invoices.go:877
|
||||||
msgid "Selected tax is not valid."
|
msgid "Selected tax is not valid."
|
||||||
msgstr "Heu seleccionat un impost que no és vàlid."
|
msgstr "Heu seleccionat un impost que no és vàlid."
|
||||||
|
|
||||||
#: pkg/products.go:311 pkg/invoices.go:867
|
#: pkg/products.go:311 pkg/expenses.go:181 pkg/expenses.go:186
|
||||||
|
#: pkg/invoices.go:878
|
||||||
msgid "You can only select a tax of each class."
|
msgid "You can only select a tax of each class."
|
||||||
msgstr "Només podeu seleccionar un impost de cada classe."
|
msgstr "Només podeu seleccionar un impost de cada classe."
|
||||||
|
|
||||||
|
@ -633,6 +688,46 @@ msgstr "La confirmació no és igual a la contrasenya."
|
||||||
msgid "Selected language is not valid."
|
msgid "Selected language is not valid."
|
||||||
msgstr "Heu seleccionat un idioma que no és vàlid."
|
msgstr "Heu seleccionat un idioma que no és vàlid."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:91
|
||||||
|
msgid "Select a contact."
|
||||||
|
msgstr "Escolliu un contacte."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:125
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Contact"
|
||||||
|
msgstr "Contacte"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:131
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Invoice number"
|
||||||
|
msgstr "Número de factura"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:136 pkg/invoices.go:586
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Invoice Date"
|
||||||
|
msgstr "Data de factura"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:148
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr "Import"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:178
|
||||||
|
msgid "Selected contact is not valid."
|
||||||
|
msgstr "Heu seleccionat un contacte que no és vàlid."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:179 pkg/invoices.go:641
|
||||||
|
msgid "Invoice date must be a valid date."
|
||||||
|
msgstr "La data de facturació ha de ser vàlida."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:182
|
||||||
|
msgid "Amount can not be empty."
|
||||||
|
msgstr "No podeu deixar l’import en blanc."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:183
|
||||||
|
msgid "Amount must be a number greater than zero."
|
||||||
|
msgstr "L’import ha de ser un número major a zero."
|
||||||
|
|
||||||
#: pkg/invoices.go:160 pkg/invoices.go:580
|
#: pkg/invoices.go:160 pkg/invoices.go:580
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Customer"
|
msgid "Customer"
|
||||||
|
@ -674,15 +769,10 @@ msgstr "Escolliu un client a facturar."
|
||||||
msgid "invoices.zip"
|
msgid "invoices.zip"
|
||||||
msgstr "factures.zip"
|
msgstr "factures.zip"
|
||||||
|
|
||||||
#: pkg/invoices.go:530 pkg/invoices.go:1017
|
#: pkg/invoices.go:530 pkg/invoices.go:1028
|
||||||
msgid "Invalid action"
|
msgid "Invalid action"
|
||||||
msgstr "Acció invàlida."
|
msgstr "Acció invàlida."
|
||||||
|
|
||||||
#: pkg/invoices.go:586
|
|
||||||
msgctxt "input"
|
|
||||||
msgid "Invoice Date"
|
|
||||||
msgstr "Data de factura"
|
|
||||||
|
|
||||||
#: pkg/invoices.go:592
|
#: pkg/invoices.go:592
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Notes"
|
msgid "Notes"
|
||||||
|
@ -705,46 +795,42 @@ msgstr "Heu seleccionat un client que no és vàlid."
|
||||||
msgid "Invoice date can not be empty."
|
msgid "Invoice date can not be empty."
|
||||||
msgstr "No podeu deixar la data de la factura en blanc."
|
msgstr "No podeu deixar la data de la factura en blanc."
|
||||||
|
|
||||||
#: pkg/invoices.go:641
|
|
||||||
msgid "Invoice date must be a valid date."
|
|
||||||
msgstr "La data de facturació ha de ser vàlida."
|
|
||||||
|
|
||||||
#: pkg/invoices.go:643
|
#: pkg/invoices.go:643
|
||||||
msgid "Selected payment method is not valid."
|
msgid "Selected payment method is not valid."
|
||||||
msgstr "Heu seleccionat un mètode de pagament que no és vàlid."
|
msgstr "Heu seleccionat un mètode de pagament que no és vàlid."
|
||||||
|
|
||||||
#: pkg/invoices.go:761 pkg/invoices.go:766
|
#: pkg/invoices.go:766 pkg/invoices.go:771
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
|
|
||||||
#: pkg/invoices.go:798
|
#: pkg/invoices.go:804
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Quantitat"
|
msgstr "Quantitat"
|
||||||
|
|
||||||
#: pkg/invoices.go:806
|
#: pkg/invoices.go:813
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Discount (%)"
|
msgid "Discount (%)"
|
||||||
msgstr "Descompte (%)"
|
msgstr "Descompte (%)"
|
||||||
|
|
||||||
#: pkg/invoices.go:854
|
#: pkg/invoices.go:865
|
||||||
msgid "Product ID must be a number greater than zero."
|
msgid "Product ID must be a number greater than zero."
|
||||||
msgstr "L’ID del producte ha de ser un número major a zero."
|
msgstr "L’ID del producte ha de ser un número major a zero."
|
||||||
|
|
||||||
#: pkg/invoices.go:860
|
#: pkg/invoices.go:871
|
||||||
msgid "Quantity can not be empty."
|
msgid "Quantity can not be empty."
|
||||||
msgstr "No podeu deixar la quantitat en blanc."
|
msgstr "No podeu deixar la quantitat en blanc."
|
||||||
|
|
||||||
#: pkg/invoices.go:861
|
#: pkg/invoices.go:872
|
||||||
msgid "Quantity must be a number greater than zero."
|
msgid "Quantity must be a number greater than zero."
|
||||||
msgstr "La quantitat ha de ser un número major a zero."
|
msgstr "La quantitat ha de ser un número major a zero."
|
||||||
|
|
||||||
#: pkg/invoices.go:863
|
#: pkg/invoices.go:874
|
||||||
msgid "Discount can not be empty."
|
msgid "Discount can not be empty."
|
||||||
msgstr "No podeu deixar el descompte en blanc."
|
msgstr "No podeu deixar el descompte en blanc."
|
||||||
|
|
||||||
#: pkg/invoices.go:864
|
#: pkg/invoices.go:875
|
||||||
msgid "Discount must be a percentage between 0 and 100."
|
msgid "Discount must be a percentage between 0 and 100."
|
||||||
msgstr "El descompte ha de ser un percentatge entre 0 i 100."
|
msgstr "El descompte ha de ser un percentatge entre 0 i 100."
|
||||||
|
|
||||||
|
|
160
po/es.po
160
po/es.po
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: numerus\n"
|
"Project-Id-Version: numerus\n"
|
||||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||||
"POT-Creation-Date: 2023-04-28 00:05+0200\n"
|
"POT-Creation-Date: 2023-05-03 12:40+0200\n"
|
||||||
"PO-Revision-Date: 2023-01-18 17:45+0100\n"
|
"PO-Revision-Date: 2023-01-18 17:45+0100\n"
|
||||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||||
|
@ -27,9 +27,10 @@ msgstr "Añadir productos a la factura"
|
||||||
#: web/template/invoices/index.gohtml:9 web/template/invoices/view.gohtml:9
|
#: web/template/invoices/index.gohtml:9 web/template/invoices/view.gohtml:9
|
||||||
#: web/template/invoices/edit.gohtml:9 web/template/contacts/new.gohtml:9
|
#: web/template/invoices/edit.gohtml:9 web/template/contacts/new.gohtml:9
|
||||||
#: web/template/contacts/index.gohtml:9 web/template/contacts/edit.gohtml:10
|
#: web/template/contacts/index.gohtml:9 web/template/contacts/edit.gohtml:10
|
||||||
#: web/template/profile.gohtml:9 web/template/tax-details.gohtml:9
|
#: web/template/profile.gohtml:9 web/template/expenses/new.gohtml:10
|
||||||
#: web/template/products/new.gohtml:9 web/template/products/index.gohtml:9
|
#: web/template/expenses/index.gohtml:10 web/template/expenses/edit.gohtml:10
|
||||||
#: web/template/products/edit.gohtml:10
|
#: web/template/tax-details.gohtml:9 web/template/products/new.gohtml:9
|
||||||
|
#: web/template/products/index.gohtml:9 web/template/products/edit.gohtml:10
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "Inicio"
|
msgstr "Inicio"
|
||||||
|
@ -48,7 +49,7 @@ msgid "New Invoice"
|
||||||
msgstr "Nueva factura"
|
msgstr "Nueva factura"
|
||||||
|
|
||||||
#: web/template/invoices/products.gohtml:48
|
#: web/template/invoices/products.gohtml:48
|
||||||
#: web/template/products/index.gohtml:38
|
#: web/template/expenses/index.gohtml:25 web/template/products/index.gohtml:38
|
||||||
msgctxt "product"
|
msgctxt "product"
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
@ -139,7 +140,7 @@ msgctxt "title"
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetes"
|
msgstr "Etiquetes"
|
||||||
|
|
||||||
#: web/template/invoices/index.gohtml:52
|
#: web/template/invoices/index.gohtml:52 web/template/expenses/index.gohtml:29
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Amount"
|
msgid "Amount"
|
||||||
msgstr "Importe"
|
msgstr "Importe"
|
||||||
|
@ -206,7 +207,7 @@ msgstr "Base imponible"
|
||||||
#: web/template/invoices/edit.gohtml:2 web/template/invoices/edit.gohtml:19
|
#: web/template/invoices/edit.gohtml:2 web/template/invoices/edit.gohtml:19
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Edit Invoice “%s”"
|
msgid "Edit Invoice “%s”"
|
||||||
msgstr "Edición del la factura «%s»"
|
msgstr "Edición de la factura «%s»"
|
||||||
|
|
||||||
#: web/template/invoices/edit.gohtml:68
|
#: web/template/invoices/edit.gohtml:68
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
|
@ -245,10 +246,15 @@ msgstr "Facturas"
|
||||||
|
|
||||||
#: web/template/app.gohtml:48
|
#: web/template/app.gohtml:48
|
||||||
msgctxt "nav"
|
msgctxt "nav"
|
||||||
|
msgid "Expenses"
|
||||||
|
msgstr "Gastos"
|
||||||
|
|
||||||
|
#: web/template/app.gohtml:49
|
||||||
|
msgctxt "nav"
|
||||||
msgid "Products"
|
msgid "Products"
|
||||||
msgstr "Productos"
|
msgstr "Productos"
|
||||||
|
|
||||||
#: web/template/app.gohtml:49
|
#: web/template/app.gohtml:50
|
||||||
msgctxt "nav"
|
msgctxt "nav"
|
||||||
msgid "Contacts"
|
msgid "Contacts"
|
||||||
msgstr "Contactos"
|
msgstr "Contactos"
|
||||||
|
@ -335,6 +341,52 @@ msgctxt "action"
|
||||||
msgid "Save changes"
|
msgid "Save changes"
|
||||||
msgstr "Guardar cambios"
|
msgstr "Guardar cambios"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:3 web/template/expenses/new.gohtml:12
|
||||||
|
#: web/template/expenses/new.gohtml:20
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "New Expense"
|
||||||
|
msgstr "Nuevo gasto"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:11 web/template/expenses/index.gohtml:3
|
||||||
|
#: web/template/expenses/index.gohtml:11 web/template/expenses/edit.gohtml:11
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Expenses"
|
||||||
|
msgstr "Gastos"
|
||||||
|
|
||||||
|
#: web/template/expenses/new.gohtml:32 web/template/expenses/index.gohtml:15
|
||||||
|
msgctxt "action"
|
||||||
|
msgid "New expense"
|
||||||
|
msgstr "Nuevo gasto"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:26
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Contact"
|
||||||
|
msgstr "Contacto"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:27
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Invoice Date"
|
||||||
|
msgstr "Fecha de factura"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:28
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Invoice Number"
|
||||||
|
msgstr "Número de factura"
|
||||||
|
|
||||||
|
#: web/template/expenses/index.gohtml:52
|
||||||
|
msgid "No expenses added yet."
|
||||||
|
msgstr "No hay gastos."
|
||||||
|
|
||||||
|
#: web/template/expenses/edit.gohtml:3 web/template/expenses/edit.gohtml:20
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Edit Expense “%s”"
|
||||||
|
msgstr "Edición del gasto «%s»"
|
||||||
|
|
||||||
|
#: web/template/expenses/edit.gohtml:35
|
||||||
|
msgctxt "action"
|
||||||
|
msgid "Update expense"
|
||||||
|
msgstr "Actualizar gasto"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:10
|
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:10
|
||||||
#: web/template/tax-details.gohtml:18
|
#: web/template/tax-details.gohtml:18
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
|
@ -460,13 +512,14 @@ msgstr "No podéis dejar la contraseña en blanco."
|
||||||
msgid "Invalid user or password."
|
msgid "Invalid user or password."
|
||||||
msgstr "Nombre de usuario o contraseña inválido."
|
msgstr "Nombre de usuario o contraseña inválido."
|
||||||
|
|
||||||
#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:771
|
#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:776
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nombre"
|
msgstr "Nombre"
|
||||||
|
|
||||||
#: pkg/products.go:166 pkg/products.go:287 pkg/invoices.go:187
|
#: pkg/products.go:166 pkg/products.go:287 pkg/expenses.go:158
|
||||||
#: pkg/invoices.go:597 pkg/invoices.go:1031 pkg/contacts.go:256
|
#: pkg/invoices.go:187 pkg/invoices.go:597 pkg/invoices.go:1042
|
||||||
|
#: pkg/contacts.go:256
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetes"
|
msgstr "Etiquetes"
|
||||||
|
@ -494,38 +547,40 @@ msgstr "Cualquiera"
|
||||||
msgid "Invoices must have at least one of the specified labels."
|
msgid "Invoices must have at least one of the specified labels."
|
||||||
msgstr "Las facturas debent tener como mínimo una de las etiquetas."
|
msgstr "Las facturas debent tener como mínimo una de las etiquetas."
|
||||||
|
|
||||||
#: pkg/products.go:266 pkg/invoices.go:785
|
#: pkg/products.go:266 pkg/invoices.go:790
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripción"
|
msgstr "Descripción"
|
||||||
|
|
||||||
#: pkg/products.go:271 pkg/invoices.go:789
|
#: pkg/products.go:271 pkg/invoices.go:794
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr "Precio"
|
msgstr "Precio"
|
||||||
|
|
||||||
#: pkg/products.go:281 pkg/invoices.go:815
|
#: pkg/products.go:281 pkg/expenses.go:142 pkg/invoices.go:823
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Taxes"
|
msgid "Taxes"
|
||||||
msgstr "Impuestos"
|
msgstr "Impuestos"
|
||||||
|
|
||||||
#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:856
|
#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:867
|
||||||
msgid "Name can not be empty."
|
msgid "Name can not be empty."
|
||||||
msgstr "No podéis dejar el nombre en blanco."
|
msgstr "No podéis dejar el nombre en blanco."
|
||||||
|
|
||||||
#: pkg/products.go:307 pkg/invoices.go:857
|
#: pkg/products.go:307 pkg/invoices.go:868
|
||||||
msgid "Price can not be empty."
|
msgid "Price can not be empty."
|
||||||
msgstr "No podéis dejar el precio en blanco."
|
msgstr "No podéis dejar el precio en blanco."
|
||||||
|
|
||||||
#: pkg/products.go:308 pkg/invoices.go:858
|
#: pkg/products.go:308 pkg/invoices.go:869
|
||||||
msgid "Price must be a number greater than zero."
|
msgid "Price must be a number greater than zero."
|
||||||
msgstr "El precio tiene que ser un número mayor a cero."
|
msgstr "El precio tiene que ser un número mayor a cero."
|
||||||
|
|
||||||
#: pkg/products.go:310 pkg/invoices.go:866
|
#: pkg/products.go:310 pkg/expenses.go:180 pkg/expenses.go:185
|
||||||
|
#: pkg/invoices.go:877
|
||||||
msgid "Selected tax is not valid."
|
msgid "Selected tax is not valid."
|
||||||
msgstr "Habéis escogido un impuesto que no es válido."
|
msgstr "Habéis escogido un impuesto que no es válido."
|
||||||
|
|
||||||
#: pkg/products.go:311 pkg/invoices.go:867
|
#: pkg/products.go:311 pkg/expenses.go:181 pkg/expenses.go:186
|
||||||
|
#: pkg/invoices.go:878
|
||||||
msgid "You can only select a tax of each class."
|
msgid "You can only select a tax of each class."
|
||||||
msgstr "Solo podéis escoger un impuesto de cada clase."
|
msgstr "Solo podéis escoger un impuesto de cada clase."
|
||||||
|
|
||||||
|
@ -633,6 +688,46 @@ msgstr "La confirmación no corresponde con la contraseña."
|
||||||
msgid "Selected language is not valid."
|
msgid "Selected language is not valid."
|
||||||
msgstr "Habéis escogido un idioma que no es válido."
|
msgstr "Habéis escogido un idioma que no es válido."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:91
|
||||||
|
msgid "Select a contact."
|
||||||
|
msgstr "Escoged un contacto"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:125
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Contact"
|
||||||
|
msgstr "Contacto"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:131
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Invoice number"
|
||||||
|
msgstr "Número de factura"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:136 pkg/invoices.go:586
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Invoice Date"
|
||||||
|
msgstr "Fecha de factura"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:148
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr "Importe"
|
||||||
|
|
||||||
|
#: pkg/expenses.go:178
|
||||||
|
msgid "Selected contact is not valid."
|
||||||
|
msgstr "Habéis escogido un contacto que no es válido."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:179 pkg/invoices.go:641
|
||||||
|
msgid "Invoice date must be a valid date."
|
||||||
|
msgstr "La fecha de factura debe ser válida."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:182
|
||||||
|
msgid "Amount can not be empty."
|
||||||
|
msgstr "No podéis dejar el importe en blanco."
|
||||||
|
|
||||||
|
#: pkg/expenses.go:183
|
||||||
|
msgid "Amount must be a number greater than zero."
|
||||||
|
msgstr "El importe tiene que ser un número mayor a cero."
|
||||||
|
|
||||||
#: pkg/invoices.go:160 pkg/invoices.go:580
|
#: pkg/invoices.go:160 pkg/invoices.go:580
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Customer"
|
msgid "Customer"
|
||||||
|
@ -674,15 +769,10 @@ msgstr "Escoged un cliente a facturar."
|
||||||
msgid "invoices.zip"
|
msgid "invoices.zip"
|
||||||
msgstr "facturas.zip"
|
msgstr "facturas.zip"
|
||||||
|
|
||||||
#: pkg/invoices.go:530 pkg/invoices.go:1017
|
#: pkg/invoices.go:530 pkg/invoices.go:1028
|
||||||
msgid "Invalid action"
|
msgid "Invalid action"
|
||||||
msgstr "Acción inválida."
|
msgstr "Acción inválida."
|
||||||
|
|
||||||
#: pkg/invoices.go:586
|
|
||||||
msgctxt "input"
|
|
||||||
msgid "Invoice Date"
|
|
||||||
msgstr "Fecha de factura"
|
|
||||||
|
|
||||||
#: pkg/invoices.go:592
|
#: pkg/invoices.go:592
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Notes"
|
msgid "Notes"
|
||||||
|
@ -705,46 +795,42 @@ msgstr "Habéis escogido un cliente que no es válido."
|
||||||
msgid "Invoice date can not be empty."
|
msgid "Invoice date can not be empty."
|
||||||
msgstr "No podéis dejar la fecha de la factura en blanco."
|
msgstr "No podéis dejar la fecha de la factura en blanco."
|
||||||
|
|
||||||
#: pkg/invoices.go:641
|
|
||||||
msgid "Invoice date must be a valid date."
|
|
||||||
msgstr "La fecha de factura debe ser válida."
|
|
||||||
|
|
||||||
#: pkg/invoices.go:643
|
#: pkg/invoices.go:643
|
||||||
msgid "Selected payment method is not valid."
|
msgid "Selected payment method is not valid."
|
||||||
msgstr "Habéis escogido un método de pago que no es válido."
|
msgstr "Habéis escogido un método de pago que no es válido."
|
||||||
|
|
||||||
#: pkg/invoices.go:761 pkg/invoices.go:766
|
#: pkg/invoices.go:766 pkg/invoices.go:771
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
|
|
||||||
#: pkg/invoices.go:798
|
#: pkg/invoices.go:804
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Cantidad"
|
msgstr "Cantidad"
|
||||||
|
|
||||||
#: pkg/invoices.go:806
|
#: pkg/invoices.go:813
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Discount (%)"
|
msgid "Discount (%)"
|
||||||
msgstr "Descuento (%)"
|
msgstr "Descuento (%)"
|
||||||
|
|
||||||
#: pkg/invoices.go:854
|
#: pkg/invoices.go:865
|
||||||
msgid "Product ID must be a number greater than zero."
|
msgid "Product ID must be a number greater than zero."
|
||||||
msgstr "El ID de producto tiene que ser un número mayor a cero."
|
msgstr "El ID de producto tiene que ser un número mayor a cero."
|
||||||
|
|
||||||
#: pkg/invoices.go:860
|
#: pkg/invoices.go:871
|
||||||
msgid "Quantity can not be empty."
|
msgid "Quantity can not be empty."
|
||||||
msgstr "No podéis dejar la cantidad en blanco."
|
msgstr "No podéis dejar la cantidad en blanco."
|
||||||
|
|
||||||
#: pkg/invoices.go:861
|
#: pkg/invoices.go:872
|
||||||
msgid "Quantity must be a number greater than zero."
|
msgid "Quantity must be a number greater than zero."
|
||||||
msgstr "La cantidad tiene que ser un número mayor a cero."
|
msgstr "La cantidad tiene que ser un número mayor a cero."
|
||||||
|
|
||||||
#: pkg/invoices.go:863
|
#: pkg/invoices.go:874
|
||||||
msgid "Discount can not be empty."
|
msgid "Discount can not be empty."
|
||||||
msgstr "No podéis dejar el descuento en blanco."
|
msgstr "No podéis dejar el descuento en blanco."
|
||||||
|
|
||||||
#: pkg/invoices.go:864
|
#: pkg/invoices.go:875
|
||||||
msgid "Discount must be a percentage between 0 and 100."
|
msgid "Discount must be a percentage between 0 and 100."
|
||||||
msgstr "El descuento tiene que ser un porcentaje entre 0 y 100."
|
msgstr "El descuento tiene que ser un porcentaje entre 0 y 100."
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ companyURI "/" }}">{{( pgettext "Dashboard" "nav" )}}</a></li>
|
<li><a href="{{ companyURI "/" }}">{{( pgettext "Dashboard" "nav" )}}</a></li>
|
||||||
<li><a href="{{ companyURI "/invoices" }}">{{( pgettext "Invoices" "nav" )}}</a></li>
|
<li><a href="{{ companyURI "/invoices" }}">{{( pgettext "Invoices" "nav" )}}</a></li>
|
||||||
|
<li><a href="{{ companyURI "/expenses" }}">{{( pgettext "Expenses" "nav" )}}</a></li>
|
||||||
<li><a href="{{ companyURI "/products" }}">{{( pgettext "Products" "nav" )}}</a></li>
|
<li><a href="{{ companyURI "/products" }}">{{( pgettext "Products" "nav" )}}</a></li>
|
||||||
<li><a href="{{ companyURI "/contacts" }}">{{( pgettext "Contacts" "nav" )}}</a></li>
|
<li><a href="{{ companyURI "/contacts" }}">{{( pgettext "Contacts" "nav" )}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
{{ define "title" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.editExpensePage*/ -}}
|
||||||
|
{{ printf ( pgettext "Edit Expense “%s”" "title" ) .Slug }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "breadcrumbs" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.editExpensePage*/ -}}
|
||||||
|
<nav data-hx-target="main" data-hx-boost="true">
|
||||||
|
<p>
|
||||||
|
<a href="{{ companyURI "/" }}">{{( pgettext "Home" "title" )}}</a> /
|
||||||
|
<a href="{{ companyURI "/expenses"}}">{{( pgettext "Expenses" "title" )}}</a> /
|
||||||
|
<a>{{ .Slug }}</a>
|
||||||
|
</p>
|
||||||
|
</nav>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "content" }}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.editExpensePage*/ -}}
|
||||||
|
<section class="dialog-content" id="new-expense-dialog-content" data-hx-target="main">
|
||||||
|
<h2>{{ printf (pgettext "Edit Expense “%s”" "title") .Slug }}</h2>
|
||||||
|
<form method="POST" action="{{ companyURI "/expenses/" }}{{ .Slug }}" data-hx-boost="true">
|
||||||
|
{{ csrfToken }}
|
||||||
|
{{ putMethod }}
|
||||||
|
|
||||||
|
{{ with .Form -}}
|
||||||
|
{{ template "select-field" .Invoicer }}
|
||||||
|
{{ template "input-field" .InvoiceNumber }}
|
||||||
|
{{ template "input-field" .InvoiceDate }}
|
||||||
|
{{ template "input-field" .Amount }}
|
||||||
|
{{ template "select-field" .Tax }}
|
||||||
|
{{ template "tags-field" .Tags }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<button class="primary" type="submit">{{( pgettext "Update expense" "action" )}}</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
{{- end }}
|
|
@ -0,0 +1,57 @@
|
||||||
|
{{ define "title" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
||||||
|
{{( pgettext "Expenses" "title" )}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "breadcrumbs" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
||||||
|
<nav data-hx-boost="true" data-hx-target="main">
|
||||||
|
<p>
|
||||||
|
<a href="{{ companyURI "/" }}">{{( pgettext "Home" "title" )}}</a> /
|
||||||
|
<a>{{( pgettext "Expenses" "title" )}}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a class="primary button"
|
||||||
|
href="{{ companyURI "/expenses/new" }}">{{( pgettext "New expense" "action" )}}</a>
|
||||||
|
</p>
|
||||||
|
</nav>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "content" }}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expensesIndexPage*/ -}}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{( pgettext "All" "product" )}}</th>
|
||||||
|
<th>{{( pgettext "Contact" "title" )}}</th>
|
||||||
|
<th>{{( pgettext "Invoice Date" "title" )}}</th>
|
||||||
|
<th>{{( pgettext "Invoice Number" "title" )}}</th>
|
||||||
|
<th>{{( pgettext "Amount" "title" )}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ with .Expenses }}
|
||||||
|
{{- range . }}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><a href="{{ companyURI "/expenses/"}}{{ .Slug }}"
|
||||||
|
data-hx-target="main" data-hx-boost="true">{{ .InvoicerName }}</a></td>
|
||||||
|
<td>{{ .InvoiceDate|formatDate }}</td>
|
||||||
|
<td>{{ .InvoiceNumber }}</td>
|
||||||
|
<td>
|
||||||
|
{{- range $index, $tag := .Tags }}
|
||||||
|
{{- if gt $index 0 }}, {{ end -}}
|
||||||
|
{{ . }}
|
||||||
|
{{- end }}
|
||||||
|
</td>
|
||||||
|
<td class="numeric">{{ .Amount | formatPrice }}</td>
|
||||||
|
</tr>
|
||||||
|
{{- end }}
|
||||||
|
{{ else }}
|
||||||
|
<tr>
|
||||||
|
<td colspan="5">{{( gettext "No expenses added yet." )}}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{- end }}
|
|
@ -0,0 +1,36 @@
|
||||||
|
{{ define "title" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expenseForm*/ -}}
|
||||||
|
{{( pgettext "New Expense" "title" )}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "breadcrumbs" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expenseForm*/ -}}
|
||||||
|
<nav data-hx-target="main" data-hx-boost="true">
|
||||||
|
<p>
|
||||||
|
<a href="{{ companyURI "/" }}">{{( pgettext "Home" "title" )}}</a> /
|
||||||
|
<a href="{{ companyURI "/expenses"}}">{{( pgettext "Expenses" "title" )}}</a> /
|
||||||
|
<a>{{( pgettext "New Expense" "title" )}}</a>
|
||||||
|
</p>
|
||||||
|
</nav>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "content" }}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.expenseForm*/ -}}
|
||||||
|
<section class="dialog-content" id="new-expense-dialog-content" data-hx-target="main">
|
||||||
|
<h2>{{(pgettext "New Expense" "title")}}</h2>
|
||||||
|
<form method="POST" action="{{ companyURI "/expenses" }}" data-hx-boost="true">
|
||||||
|
{{ csrfToken }}
|
||||||
|
|
||||||
|
{{ template "select-field" .Invoicer }}
|
||||||
|
{{ template "input-field" .InvoiceNumber }}
|
||||||
|
{{ template "input-field" .InvoiceDate }}
|
||||||
|
{{ template "input-field" .Amount }}
|
||||||
|
{{ template "select-field" .Tax }}
|
||||||
|
{{ template "tags-field" .Tags }}
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<button class="primary" type="submit">{{( pgettext "New expense" "action" )}}</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
{{- end }}
|
Loading…
Reference in New Issue