Introduce the concept of tax class
We want to show the percentage of the tax as columns in the invoice, but until now it was not possible to have a single VAT column when products have different VAT (e.g., 4 % and 10 %), because, as far as the application is concerned, these where ”different taxes”. We also think it would be hard later on to compute the tax due to the government. So, tax classes is just a taxonomy to be able to have different names and rates for the same type of tax, mostly VAT and retention in our case.
This commit is contained in:
parent
0d4fb124b4
commit
11d51df7fa
|
@ -17,12 +17,18 @@ values (1, 1)
|
||||||
, (1, 2)
|
, (1, 2)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
alter sequence tax_class_tax_class_id_seq restart;
|
||||||
|
insert into tax_class (company_id, name)
|
||||||
|
values (1, 'IRPF')
|
||||||
|
, (1, 'IVA')
|
||||||
|
;
|
||||||
|
|
||||||
alter sequence tax_tax_id_seq restart;
|
alter sequence tax_tax_id_seq restart;
|
||||||
insert into tax (company_id, name, rate)
|
insert into tax (company_id, tax_class_id, name, rate)
|
||||||
values (1, 'Retenció 15 %', -0.15)
|
values (1, 1, 'Retenció 15 %', -0.15)
|
||||||
, (1, 'IVA 21 %', 0.21)
|
, (1, 2, 'IVA 21 %', 0.21)
|
||||||
, (1, 'IVA 10 %', 0.10)
|
, (1, 2, 'IVA 10 %', 0.10)
|
||||||
, (1, 'IVA 4 %', 0.04)
|
, (1, 2, 'IVA 4 %', 0.04)
|
||||||
;
|
;
|
||||||
|
|
||||||
alter sequence contact_contact_id_seq restart;
|
alter sequence contact_contact_id_seq restart;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
-- requires: schema_numerus
|
-- requires: schema_numerus
|
||||||
-- requires: company
|
-- requires: company
|
||||||
-- requires: tax_rate
|
-- requires: tax_rate
|
||||||
|
-- requires: tax_class
|
||||||
|
|
||||||
begin;
|
begin;
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ set search_path to numerus, public;
|
||||||
create table tax (
|
create table tax (
|
||||||
tax_id serial primary key,
|
tax_id serial primary key,
|
||||||
company_id integer not null references company,
|
company_id integer not null references company,
|
||||||
|
tax_class_id integer not null references tax_class,
|
||||||
name text not null constraint name_not_empty check(length(trim(name)) > 0),
|
name text not null constraint name_not_empty check(length(trim(name)) > 0),
|
||||||
rate tax_rate not null
|
rate tax_rate not null
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
-- Deploy numerus:tax_class to pg
|
||||||
|
-- requires: schema_numerus
|
||||||
|
-- requires: company
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
set search_path to numerus, public;
|
||||||
|
|
||||||
|
create table tax_class (
|
||||||
|
tax_class_id serial not null primary key,
|
||||||
|
company_id integer not null references company,
|
||||||
|
name text not null constraint name_not_empty check(length(trim(name)) > 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
grant select, insert, update, delete on table tax_class to invoicer;
|
||||||
|
grant select, insert, update, delete on table tax_class to admin;
|
||||||
|
|
||||||
|
grant usage on sequence tax_class_tax_class_id_seq to invoicer;
|
||||||
|
grant usage on sequence tax_class_tax_class_id_seq to admin;
|
||||||
|
|
||||||
|
alter table tax_class enable row level security;
|
||||||
|
|
||||||
|
create policy company_policy
|
||||||
|
on tax_class
|
||||||
|
using (
|
||||||
|
exists(
|
||||||
|
select 1
|
||||||
|
from company_user
|
||||||
|
join user_profile using (user_id)
|
||||||
|
where company_user.company_id = tax_class.company_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
commit;
|
|
@ -71,9 +71,10 @@ type CountryOption struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tax struct {
|
type Tax struct {
|
||||||
Id int
|
Id int
|
||||||
Name string
|
Name string
|
||||||
Rate int
|
Class string
|
||||||
|
Rate int
|
||||||
}
|
}
|
||||||
|
|
||||||
type taxDetailsForm struct {
|
type taxDetailsForm struct {
|
||||||
|
@ -161,10 +162,9 @@ func HandleCompanyTaxDetailsForm(w http.ResponseWriter, r *http.Request, _ httpr
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustRenderTaxDetailsForm(w http.ResponseWriter, r *http.Request, form *taxDetailsForm) {
|
func mustRenderTaxDetailsForm(w http.ResponseWriter, r *http.Request, form *taxDetailsForm) {
|
||||||
locale := getLocale(r)
|
|
||||||
page := &TaxDetailsPage{
|
page := &TaxDetailsPage{
|
||||||
DetailsForm: form,
|
DetailsForm: form,
|
||||||
NewTaxForm: newTaxForm(locale),
|
NewTaxForm: newTaxForm(r.Context(), getConn(r), mustGetCompany(r), getLocale(r)),
|
||||||
}
|
}
|
||||||
mustRenderTexDetailsPage(w, r, page)
|
mustRenderTexDetailsPage(w, r, page)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ func mustGetCompany(r *http.Request) *Company {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetTaxes(ctx context.Context, conn *Conn, company *Company) []*Tax {
|
func mustGetTaxes(ctx context.Context, conn *Conn, company *Company) []*Tax {
|
||||||
rows, err := conn.Query(ctx, "select tax_id, name, (rate * 100)::integer from tax where company_id = $1 order by rate, name", company.Id)
|
rows, err := conn.Query(ctx, "select tax_id, tax.name, tax_class.name, (rate * 100)::integer from tax join tax_class using (tax_class_id) where tax.company_id = $1 order by rate, tax.name", company.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ func mustGetTaxes(ctx context.Context, conn *Conn, company *Company) []*Tax {
|
||||||
var taxes []*Tax
|
var taxes []*Tax
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
tax := &Tax{}
|
tax := &Tax{}
|
||||||
err = rows.Scan(&tax.Id, &tax.Name, &tax.Rate)
|
err = rows.Scan(&tax.Id, &tax.Name, &tax.Class, &tax.Rate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -218,10 +218,11 @@ func mustGetTaxes(ctx context.Context, conn *Conn, company *Company) []*Tax {
|
||||||
type taxForm struct {
|
type taxForm struct {
|
||||||
locale *Locale
|
locale *Locale
|
||||||
Name *InputField
|
Name *InputField
|
||||||
|
Class *SelectField
|
||||||
Rate *InputField
|
Rate *InputField
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTaxForm(locale *Locale) *taxForm {
|
func newTaxForm(ctx context.Context, conn *Conn, company *Company, locale *Locale) *taxForm {
|
||||||
return &taxForm{
|
return &taxForm{
|
||||||
locale: locale,
|
locale: locale,
|
||||||
Name: &InputField{
|
Name: &InputField{
|
||||||
|
@ -230,6 +231,13 @@ func newTaxForm(locale *Locale) *taxForm {
|
||||||
Type: "text",
|
Type: "text",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
|
Class: &SelectField{
|
||||||
|
Name: "tax_class",
|
||||||
|
Label: pgettext("input", "Tax Class", locale),
|
||||||
|
Options: MustGetOptions(ctx, conn, "select tax_class_id::text, name from tax_class where company_id = $1 order by name", company.Id),
|
||||||
|
Required: true,
|
||||||
|
EmptyLabel: gettext("Select a tax class", locale),
|
||||||
|
},
|
||||||
Rate: &InputField{
|
Rate: &InputField{
|
||||||
Name: "tax_rate",
|
Name: "tax_rate",
|
||||||
Label: pgettext("input", "Rate (%)", locale),
|
Label: pgettext("input", "Rate (%)", locale),
|
||||||
|
@ -248,6 +256,7 @@ func (form *taxForm) Parse(r *http.Request) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
form.Name.FillValue(r)
|
form.Name.FillValue(r)
|
||||||
|
form.Class.FillValue(r)
|
||||||
form.Rate.FillValue(r)
|
form.Rate.FillValue(r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -255,6 +264,7 @@ func (form *taxForm) Parse(r *http.Request) error {
|
||||||
func (form *taxForm) Validate() bool {
|
func (form *taxForm) Validate() bool {
|
||||||
validator := newFormValidator()
|
validator := newFormValidator()
|
||||||
validator.CheckRequiredInput(form.Name, gettext("Tax name can not be empty.", form.locale))
|
validator.CheckRequiredInput(form.Name, gettext("Tax name can not be empty.", form.locale))
|
||||||
|
validator.CheckValidSelectOption(form.Class, gettext("Selected tax class is not valid.", form.locale))
|
||||||
if validator.CheckRequiredInput(form.Rate, gettext("Tax rate can not be empty.", form.locale)) {
|
if validator.CheckRequiredInput(form.Rate, gettext("Tax rate can not be empty.", form.locale)) {
|
||||||
validator.CheckValidInteger(form.Rate, -99, 99, gettext("Tax rate must be an integer between -99 and 99.", form.locale))
|
validator.CheckValidInteger(form.Rate, -99, 99, gettext("Tax rate must be an integer between -99 and 99.", form.locale))
|
||||||
}
|
}
|
||||||
|
@ -278,7 +288,9 @@ func HandleDeleteCompanyTax(w http.ResponseWriter, r *http.Request, params httpr
|
||||||
|
|
||||||
func HandleAddCompanyTax(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func HandleAddCompanyTax(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
locale := getLocale(r)
|
locale := getLocale(r)
|
||||||
form := newTaxForm(locale)
|
conn := getConn(r)
|
||||||
|
company := mustGetCompany(r)
|
||||||
|
form := newTaxForm(r.Context(), conn, company, locale)
|
||||||
if err := form.Parse(r); err != nil {
|
if err := form.Parse(r); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
@ -292,8 +304,6 @@ func HandleAddCompanyTax(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
|
||||||
mustRenderTaxForm(w, r, form)
|
mustRenderTaxForm(w, r, form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn := getConn(r)
|
conn.MustExec(r.Context(), "insert into tax (company_id, tax_class_id, name, rate) values ($1, $2, $3, $4 / 100::decimal)", company.Id, form.Class, form.Name, form.Rate.Integer())
|
||||||
company := mustGetCompany(r)
|
|
||||||
conn.MustExec(r.Context(), "insert into tax (company_id, name, rate) values ($1, $2, $3 / 100::decimal)", company.Id, form.Name, form.Rate.Integer())
|
|
||||||
http.Redirect(w, r, companyURI(company, "/tax-details"), http.StatusSeeOther)
|
http.Redirect(w, r, companyURI(company, "/tax-details"), http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
96
po/ca.po
96
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-02-26 17:11+0100\n"
|
"POT-Creation-Date: 2023-02-28 11:56+0100\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"
|
||||||
|
@ -69,7 +69,7 @@ msgstr "Preu"
|
||||||
msgid "No products added yet."
|
msgid "No products added yet."
|
||||||
msgstr "No hi ha cap producte."
|
msgstr "No hi ha cap producte."
|
||||||
|
|
||||||
#: web/template/invoices/products.gohtml:64 web/template/invoices/new.gohtml:59
|
#: web/template/invoices/products.gohtml:65 web/template/invoices/new.gohtml:60
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Add products"
|
msgid "Add products"
|
||||||
msgstr "Afegeix productes"
|
msgstr "Afegeix productes"
|
||||||
|
@ -85,12 +85,12 @@ msgctxt "title"
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr "Total"
|
msgstr "Total"
|
||||||
|
|
||||||
#: web/template/invoices/new.gohtml:61
|
#: web/template/invoices/new.gohtml:63
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Update"
|
msgid "Update"
|
||||||
msgstr "Actualitza"
|
msgstr "Actualitza"
|
||||||
|
|
||||||
#: web/template/invoices/new.gohtml:63 web/template/invoices/index.gohtml:13
|
#: web/template/invoices/new.gohtml:65 web/template/invoices/index.gohtml:13
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "New invoice"
|
msgid "New invoice"
|
||||||
msgstr "Nova factura"
|
msgstr "Nova factura"
|
||||||
|
@ -276,7 +276,7 @@ msgctxt "title"
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Idioma"
|
msgstr "Idioma"
|
||||||
|
|
||||||
#: web/template/profile.gohtml:35 web/template/tax-details.gohtml:96
|
#: web/template/profile.gohtml:35 web/template/tax-details.gohtml:101
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Save changes"
|
msgid "Save changes"
|
||||||
msgstr "Desa canvis"
|
msgstr "Desa canvis"
|
||||||
|
@ -302,16 +302,21 @@ msgctxt "title"
|
||||||
msgid "Rate (%)"
|
msgid "Rate (%)"
|
||||||
msgstr "Percentatge"
|
msgstr "Percentatge"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:71
|
#: web/template/tax-details.gohtml:49
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Class"
|
||||||
|
msgstr "Classe"
|
||||||
|
|
||||||
|
#: web/template/tax-details.gohtml:73
|
||||||
msgid "No taxes added yet."
|
msgid "No taxes added yet."
|
||||||
msgstr "No hi ha cap impost."
|
msgstr "No hi ha cap impost."
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:77
|
#: web/template/tax-details.gohtml:79
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "New Line"
|
msgid "New Line"
|
||||||
msgstr "Nova línia"
|
msgstr "Nova línia"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:88
|
#: web/template/tax-details.gohtml:93
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Add new tax"
|
msgid "Add new tax"
|
||||||
msgstr "Afegeix nou impost"
|
msgstr "Afegeix nou impost"
|
||||||
|
@ -369,71 +374,84 @@ 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:165 pkg/invoices.go:435
|
#: pkg/products.go:165 pkg/invoices.go:446
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
#: pkg/products.go:171 pkg/invoices.go:440
|
#: pkg/products.go:171 pkg/invoices.go:451
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripció"
|
msgstr "Descripció"
|
||||||
|
|
||||||
#: pkg/products.go:176 pkg/invoices.go:444
|
#: pkg/products.go:176 pkg/invoices.go:455
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr "Preu"
|
msgstr "Preu"
|
||||||
|
|
||||||
#: pkg/products.go:186 pkg/invoices.go:350 pkg/invoices.go:470
|
#: pkg/products.go:186 pkg/invoices.go:344 pkg/invoices.go:481
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Taxes"
|
msgid "Taxes"
|
||||||
msgstr "Imposts"
|
msgstr "Imposts"
|
||||||
|
|
||||||
#: pkg/products.go:206 pkg/profile.go:92 pkg/invoices.go:383
|
#: pkg/products.go:206 pkg/profile.go:92 pkg/invoices.go:377
|
||||||
#: pkg/invoices.go:506
|
#: pkg/invoices.go:517
|
||||||
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:207 pkg/invoices.go:507
|
#: pkg/products.go:207 pkg/invoices.go:518
|
||||||
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:208 pkg/invoices.go:508
|
#: pkg/products.go:208 pkg/invoices.go:519
|
||||||
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:210 pkg/invoices.go:387 pkg/invoices.go:516
|
#: pkg/products.go:210 pkg/invoices.go:381 pkg/invoices.go:527
|
||||||
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/company.go:89
|
#: pkg/company.go:90
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Currency"
|
msgid "Currency"
|
||||||
msgstr "Moneda"
|
msgstr "Moneda"
|
||||||
|
|
||||||
#: pkg/company.go:107
|
#: pkg/company.go:108
|
||||||
msgid "Selected currency is not valid."
|
msgid "Selected currency is not valid."
|
||||||
msgstr "Heu seleccionat una moneda que no és vàlida."
|
msgstr "Heu seleccionat una moneda que no és vàlida."
|
||||||
|
|
||||||
#: pkg/company.go:229
|
#: pkg/company.go:230
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Tax name"
|
msgid "Tax name"
|
||||||
msgstr "Nom impost"
|
msgstr "Nom impost"
|
||||||
|
|
||||||
#: pkg/company.go:235
|
#: pkg/company.go:236
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Tax Class"
|
||||||
|
msgstr "Classe d’impost"
|
||||||
|
|
||||||
|
#: pkg/company.go:239
|
||||||
|
msgid "Select a tax class"
|
||||||
|
msgstr "Escolliu una classe d’impost"
|
||||||
|
|
||||||
|
#: pkg/company.go:243
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Rate (%)"
|
msgid "Rate (%)"
|
||||||
msgstr "Percentatge"
|
msgstr "Percentatge"
|
||||||
|
|
||||||
#: pkg/company.go:257
|
#: pkg/company.go:266
|
||||||
msgid "Tax name can not be empty."
|
msgid "Tax name can not be empty."
|
||||||
msgstr "No podeu deixar el nom de l’impost en blanc."
|
msgstr "No podeu deixar el nom de l’impost en blanc."
|
||||||
|
|
||||||
#: pkg/company.go:258
|
#: pkg/company.go:267
|
||||||
|
msgid "Selected tax class is not valid."
|
||||||
|
msgstr "Heu seleccionat una classe d’impost que no és vàlida."
|
||||||
|
|
||||||
|
#: pkg/company.go:268
|
||||||
msgid "Tax rate can not be empty."
|
msgid "Tax rate can not be empty."
|
||||||
msgstr "No podeu deixar percentatge en blanc."
|
msgstr "No podeu deixar percentatge en blanc."
|
||||||
|
|
||||||
#: pkg/company.go:259
|
#: pkg/company.go:269
|
||||||
msgid "Tax rate must be an integer between -99 and 99."
|
msgid "Tax rate must be an integer between -99 and 99."
|
||||||
msgstr "El percentatge ha de ser entre -99 i 99."
|
msgstr "El percentatge ha de ser entre -99 i 99."
|
||||||
|
|
||||||
|
@ -465,70 +483,70 @@ 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/invoices.go:201
|
#: pkg/invoices.go:207
|
||||||
msgid "Select a customer to bill."
|
msgid "Select a customer to bill."
|
||||||
msgstr "Escolliu un client a facturar."
|
msgstr "Escolliu un client a facturar."
|
||||||
|
|
||||||
#: pkg/invoices.go:276
|
#: pkg/invoices.go:300
|
||||||
msgid "Invalid action"
|
msgid "Invalid action"
|
||||||
msgstr "Acció invàlida."
|
msgstr "Acció invàlida."
|
||||||
|
|
||||||
#: pkg/invoices.go:327
|
#: pkg/invoices.go:321
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Customer"
|
msgid "Customer"
|
||||||
msgstr "Client"
|
msgstr "Client"
|
||||||
|
|
||||||
#: pkg/invoices.go:333
|
#: pkg/invoices.go:327
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Number"
|
msgid "Number"
|
||||||
msgstr "Número"
|
msgstr "Número"
|
||||||
|
|
||||||
#: pkg/invoices.go:339
|
#: pkg/invoices.go:333
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Invoice Date"
|
msgid "Invoice Date"
|
||||||
msgstr "Data de factura"
|
msgstr "Data de factura"
|
||||||
|
|
||||||
#: pkg/invoices.go:345
|
#: pkg/invoices.go:339
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Notes"
|
msgid "Notes"
|
||||||
msgstr "Notes"
|
msgstr "Notes"
|
||||||
|
|
||||||
#: pkg/invoices.go:384
|
#: pkg/invoices.go:378
|
||||||
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:385
|
#: pkg/invoices.go:379
|
||||||
msgid "Invoice date must be a valid date."
|
msgid "Invoice date must be a valid date."
|
||||||
msgstr "La data de facturació ha de ser vàlida."
|
msgstr "La data de facturació ha de ser vàlida."
|
||||||
|
|
||||||
#: pkg/invoices.go:430
|
#: pkg/invoices.go:441
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
|
|
||||||
#: pkg/invoices.go:453
|
#: pkg/invoices.go:464
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Quantitat"
|
msgstr "Quantitat"
|
||||||
|
|
||||||
#: pkg/invoices.go:461
|
#: pkg/invoices.go:472
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Discount (%)"
|
msgid "Discount (%)"
|
||||||
msgstr "Descompte (%)"
|
msgstr "Descompte (%)"
|
||||||
|
|
||||||
#: pkg/invoices.go:510
|
#: pkg/invoices.go:521
|
||||||
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:511
|
#: pkg/invoices.go:522
|
||||||
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:513
|
#: pkg/invoices.go:524
|
||||||
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:514
|
#: pkg/invoices.go:525
|
||||||
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."
|
||||||
|
|
||||||
|
|
96
po/es.po
96
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-02-26 17:11+0100\n"
|
"POT-Creation-Date: 2023-02-28 11:56+0100\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"
|
||||||
|
@ -69,7 +69,7 @@ msgstr "Precio"
|
||||||
msgid "No products added yet."
|
msgid "No products added yet."
|
||||||
msgstr "No hay productos."
|
msgstr "No hay productos."
|
||||||
|
|
||||||
#: web/template/invoices/products.gohtml:64 web/template/invoices/new.gohtml:59
|
#: web/template/invoices/products.gohtml:65 web/template/invoices/new.gohtml:60
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Add products"
|
msgid "Add products"
|
||||||
msgstr "Añadir productos"
|
msgstr "Añadir productos"
|
||||||
|
@ -85,12 +85,12 @@ msgctxt "title"
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr "Total"
|
msgstr "Total"
|
||||||
|
|
||||||
#: web/template/invoices/new.gohtml:61
|
#: web/template/invoices/new.gohtml:63
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Update"
|
msgid "Update"
|
||||||
msgstr "Actualizar"
|
msgstr "Actualizar"
|
||||||
|
|
||||||
#: web/template/invoices/new.gohtml:63 web/template/invoices/index.gohtml:13
|
#: web/template/invoices/new.gohtml:65 web/template/invoices/index.gohtml:13
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "New invoice"
|
msgid "New invoice"
|
||||||
msgstr "Nueva factura"
|
msgstr "Nueva factura"
|
||||||
|
@ -276,7 +276,7 @@ msgctxt "title"
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Idioma"
|
msgstr "Idioma"
|
||||||
|
|
||||||
#: web/template/profile.gohtml:35 web/template/tax-details.gohtml:96
|
#: web/template/profile.gohtml:35 web/template/tax-details.gohtml:101
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Save changes"
|
msgid "Save changes"
|
||||||
msgstr "Guardar cambios"
|
msgstr "Guardar cambios"
|
||||||
|
@ -302,16 +302,21 @@ msgctxt "title"
|
||||||
msgid "Rate (%)"
|
msgid "Rate (%)"
|
||||||
msgstr "Porcentaje"
|
msgstr "Porcentaje"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:71
|
#: web/template/tax-details.gohtml:49
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Class"
|
||||||
|
msgstr "Clase"
|
||||||
|
|
||||||
|
#: web/template/tax-details.gohtml:73
|
||||||
msgid "No taxes added yet."
|
msgid "No taxes added yet."
|
||||||
msgstr "No hay impuestos."
|
msgstr "No hay impuestos."
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:77
|
#: web/template/tax-details.gohtml:79
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "New Line"
|
msgid "New Line"
|
||||||
msgstr "Nueva línea"
|
msgstr "Nueva línea"
|
||||||
|
|
||||||
#: web/template/tax-details.gohtml:88
|
#: web/template/tax-details.gohtml:93
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Add new tax"
|
msgid "Add new tax"
|
||||||
msgstr "Añadir nuevo impuesto"
|
msgstr "Añadir nuevo impuesto"
|
||||||
|
@ -369,71 +374,84 @@ 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:165 pkg/invoices.go:435
|
#: pkg/products.go:165 pkg/invoices.go:446
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nombre"
|
msgstr "Nombre"
|
||||||
|
|
||||||
#: pkg/products.go:171 pkg/invoices.go:440
|
#: pkg/products.go:171 pkg/invoices.go:451
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripción"
|
msgstr "Descripción"
|
||||||
|
|
||||||
#: pkg/products.go:176 pkg/invoices.go:444
|
#: pkg/products.go:176 pkg/invoices.go:455
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr "Precio"
|
msgstr "Precio"
|
||||||
|
|
||||||
#: pkg/products.go:186 pkg/invoices.go:350 pkg/invoices.go:470
|
#: pkg/products.go:186 pkg/invoices.go:344 pkg/invoices.go:481
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Taxes"
|
msgid "Taxes"
|
||||||
msgstr "Impuestos"
|
msgstr "Impuestos"
|
||||||
|
|
||||||
#: pkg/products.go:206 pkg/profile.go:92 pkg/invoices.go:383
|
#: pkg/products.go:206 pkg/profile.go:92 pkg/invoices.go:377
|
||||||
#: pkg/invoices.go:506
|
#: pkg/invoices.go:517
|
||||||
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:207 pkg/invoices.go:507
|
#: pkg/products.go:207 pkg/invoices.go:518
|
||||||
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:208 pkg/invoices.go:508
|
#: pkg/products.go:208 pkg/invoices.go:519
|
||||||
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:210 pkg/invoices.go:387 pkg/invoices.go:516
|
#: pkg/products.go:210 pkg/invoices.go:381 pkg/invoices.go:527
|
||||||
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/company.go:89
|
#: pkg/company.go:90
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Currency"
|
msgid "Currency"
|
||||||
msgstr "Moneda"
|
msgstr "Moneda"
|
||||||
|
|
||||||
#: pkg/company.go:107
|
#: pkg/company.go:108
|
||||||
msgid "Selected currency is not valid."
|
msgid "Selected currency is not valid."
|
||||||
msgstr "Habéis escogido una moneda que no es válida."
|
msgstr "Habéis escogido una moneda que no es válida."
|
||||||
|
|
||||||
#: pkg/company.go:229
|
#: pkg/company.go:230
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Tax name"
|
msgid "Tax name"
|
||||||
msgstr "Nombre impuesto"
|
msgstr "Nombre impuesto"
|
||||||
|
|
||||||
#: pkg/company.go:235
|
#: pkg/company.go:236
|
||||||
|
msgctxt "input"
|
||||||
|
msgid "Tax Class"
|
||||||
|
msgstr "Clase de impuesto"
|
||||||
|
|
||||||
|
#: pkg/company.go:239
|
||||||
|
msgid "Select a tax class"
|
||||||
|
msgstr "Escoged una clase de impuesto"
|
||||||
|
|
||||||
|
#: pkg/company.go:243
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Rate (%)"
|
msgid "Rate (%)"
|
||||||
msgstr "Porcentaje"
|
msgstr "Porcentaje"
|
||||||
|
|
||||||
#: pkg/company.go:257
|
#: pkg/company.go:266
|
||||||
msgid "Tax name can not be empty."
|
msgid "Tax name can not be empty."
|
||||||
msgstr "No podéis dejar el nombre del impuesto en blanco."
|
msgstr "No podéis dejar el nombre del impuesto en blanco."
|
||||||
|
|
||||||
#: pkg/company.go:258
|
#: pkg/company.go:267
|
||||||
|
msgid "Selected tax class is not valid."
|
||||||
|
msgstr "Habéis escogido una clase impuesto que no es válida."
|
||||||
|
|
||||||
|
#: pkg/company.go:268
|
||||||
msgid "Tax rate can not be empty."
|
msgid "Tax rate can not be empty."
|
||||||
msgstr "No podéis dejar el porcentaje en blanco."
|
msgstr "No podéis dejar el porcentaje en blanco."
|
||||||
|
|
||||||
#: pkg/company.go:259
|
#: pkg/company.go:269
|
||||||
msgid "Tax rate must be an integer between -99 and 99."
|
msgid "Tax rate must be an integer between -99 and 99."
|
||||||
msgstr "El porcentaje tiene que estar entre -99 y 99."
|
msgstr "El porcentaje tiene que estar entre -99 y 99."
|
||||||
|
|
||||||
|
@ -465,70 +483,70 @@ 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/invoices.go:201
|
#: pkg/invoices.go:207
|
||||||
msgid "Select a customer to bill."
|
msgid "Select a customer to bill."
|
||||||
msgstr "Escoged un cliente a facturar."
|
msgstr "Escoged un cliente a facturar."
|
||||||
|
|
||||||
#: pkg/invoices.go:276
|
#: pkg/invoices.go:300
|
||||||
msgid "Invalid action"
|
msgid "Invalid action"
|
||||||
msgstr "Acción inválida."
|
msgstr "Acción inválida."
|
||||||
|
|
||||||
#: pkg/invoices.go:327
|
#: pkg/invoices.go:321
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Customer"
|
msgid "Customer"
|
||||||
msgstr "Cliente"
|
msgstr "Cliente"
|
||||||
|
|
||||||
#: pkg/invoices.go:333
|
#: pkg/invoices.go:327
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Number"
|
msgid "Number"
|
||||||
msgstr "Número"
|
msgstr "Número"
|
||||||
|
|
||||||
#: pkg/invoices.go:339
|
#: pkg/invoices.go:333
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Invoice Date"
|
msgid "Invoice Date"
|
||||||
msgstr "Fecha de factura"
|
msgstr "Fecha de factura"
|
||||||
|
|
||||||
#: pkg/invoices.go:345
|
#: pkg/invoices.go:339
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Notes"
|
msgid "Notes"
|
||||||
msgstr "Notas"
|
msgstr "Notas"
|
||||||
|
|
||||||
#: pkg/invoices.go:384
|
#: pkg/invoices.go:378
|
||||||
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:385
|
#: pkg/invoices.go:379
|
||||||
msgid "Invoice date must be a valid date."
|
msgid "Invoice date must be a valid date."
|
||||||
msgstr "La fecha de factura debe ser válida."
|
msgstr "La fecha de factura debe ser válida."
|
||||||
|
|
||||||
#: pkg/invoices.go:430
|
#: pkg/invoices.go:441
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
|
|
||||||
#: pkg/invoices.go:453
|
#: pkg/invoices.go:464
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Cantidad"
|
msgstr "Cantidad"
|
||||||
|
|
||||||
#: pkg/invoices.go:461
|
#: pkg/invoices.go:472
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
msgid "Discount (%)"
|
msgid "Discount (%)"
|
||||||
msgstr "Descuento (%)"
|
msgstr "Descuento (%)"
|
||||||
|
|
||||||
#: pkg/invoices.go:510
|
#: pkg/invoices.go:521
|
||||||
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:511
|
#: pkg/invoices.go:522
|
||||||
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:513
|
#: pkg/invoices.go:524
|
||||||
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:514
|
#: pkg/invoices.go:525
|
||||||
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 percentage entre 0 y 100."
|
msgstr "El descuento tiene que ser un percentage entre 0 y 100."
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Revert numerus:tax_class from pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
drop table if exists numerus.tax_class;
|
||||||
|
|
||||||
|
commit;
|
|
@ -36,8 +36,9 @@ country_i18n [schema_numerus country_code language country] 2023-01-27T19:20:43Z
|
||||||
available_countries [schema_numerus country country_i18n] 2023-01-27T18:49:28Z jordi fita mas <jordi@tandem.blog> # Add the list of available countries
|
available_countries [schema_numerus country country_i18n] 2023-01-27T18:49:28Z jordi fita mas <jordi@tandem.blog> # Add the list of available countries
|
||||||
company [schema_numerus extension_vat email extension_pg_libphonenumber extension_uri currency_code currency country_code country] 2023-01-24T15:03:15Z jordi fita mas <jordi@tandem.blog> # Add the relation for companies
|
company [schema_numerus extension_vat email extension_pg_libphonenumber extension_uri currency_code currency country_code country] 2023-01-24T15:03:15Z jordi fita mas <jordi@tandem.blog> # Add the relation for companies
|
||||||
company_user [schema_numerus user company] 2023-01-24T17:50:06Z jordi fita mas <jordi@tandem.blog> # Add the relation of companies and their users
|
company_user [schema_numerus user company] 2023-01-24T17:50:06Z jordi fita mas <jordi@tandem.blog> # Add the relation of companies and their users
|
||||||
|
tax_class [schema_numerus company] 2023-02-28T10:13:14Z jordi fita mas <jordi@tandem.blog> # Add the relation for tax classes
|
||||||
tax_rate [schema_numerus] 2023-01-28T11:33:39Z jordi fita mas <jordi@tandem.blog> # Add domain for tax rates
|
tax_rate [schema_numerus] 2023-01-28T11:33:39Z jordi fita mas <jordi@tandem.blog> # Add domain for tax rates
|
||||||
tax [schema_numerus company tax_rate] 2023-01-28T11:45:47Z jordi fita mas <jordi@tandem.blog> # Add relation for taxes
|
tax [schema_numerus company tax_rate tax_class] 2023-01-28T11:45:47Z jordi fita mas <jordi@tandem.blog> # Add relation for taxes
|
||||||
contact [schema_numerus company extension_vat email extension_pg_libphonenumber extension_uri currency_code currency country_code country] 2023-01-29T12:59:18Z jordi fita mas <jordi@tandem.blog> # Add the relation for contacts
|
contact [schema_numerus company extension_vat email extension_pg_libphonenumber extension_uri currency_code currency country_code country] 2023-01-29T12:59:18Z jordi fita mas <jordi@tandem.blog> # Add the relation for contacts
|
||||||
product [schema_numerus company tax] 2023-02-04T09:17:24Z jordi fita mas <jordi@tandem.blog> # Add relation for products
|
product [schema_numerus company tax] 2023-02-04T09:17:24Z jordi fita mas <jordi@tandem.blog> # Add relation for products
|
||||||
parse_price [schema_public] 2023-02-05T11:04:54Z jordi fita mas <jordi@tandem.blog> # Add function to convert from price to cents
|
parse_price [schema_public] 2023-02-05T11:04:54Z jordi fita mas <jordi@tandem.blog> # Add function to convert from price to cents
|
||||||
|
|
|
@ -28,6 +28,7 @@ truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -41,11 +42,16 @@ values (1, 2023, '5')
|
||||||
, (2, 2023, '55')
|
, (2, 2023, '55')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (3, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (4, 1, 'IVA 21 %', 0.21)
|
, (22, 2, 'tax')
|
||||||
, (5, 2, 'IRPF -7 %', -0.07)
|
;
|
||||||
, (6, 2, 'IVA 10 %', 0.10)
|
|
||||||
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (3, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (4, 1, 11, 'IVA 21 %', 0.21)
|
||||||
|
, (5, 2, 22, 'IRPF -7 %', -0.07)
|
||||||
|
, (6, 2, 22, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
insert into product (product_id, company_id, name, price)
|
||||||
|
|
|
@ -24,6 +24,7 @@ set client_min_messages to warning;
|
||||||
truncate product_tax cascade;
|
truncate product_tax cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -33,11 +34,16 @@ values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '
|
||||||
, (2, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD')
|
, (2, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (3, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (4, 1, 'IVA 21 %', 0.21)
|
, (22, 2, 'tax')
|
||||||
, (5, 2, 'IRPF -7 %', -0.07)
|
;
|
||||||
, (6, 2, 'IVA 10 %', 0.10)
|
|
||||||
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (3, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (4, 1, 11, 'IVA 21 %', 0.21)
|
||||||
|
, (5, 2, 22, 'IRPF -7 %', -0.07)
|
||||||
|
, (6, 2, 22, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ select function_privs_are('numerus', 'compute_new_invoice_amount', array ['integ
|
||||||
|
|
||||||
set client_min_messages to warning;
|
set client_min_messages to warning;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -28,11 +29,15 @@ insert into company (company_id, business_name, vatin, trade_name, phone, email,
|
||||||
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (2, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (3, 1, 'IVA 4 %', 0.04)
|
;
|
||||||
, (4, 1, 'IVA 10 %', 0.10)
|
|
||||||
, (5, 1, 'IVA 21 %', 0.21)
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (3, 1, 11, 'IVA 4 %', 0.04)
|
||||||
|
, (4, 1, 11, 'IVA 10 %', 0.10)
|
||||||
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
select is(
|
select is(
|
||||||
|
|
|
@ -24,6 +24,7 @@ set client_min_messages to warning;
|
||||||
truncate product_tax cascade;
|
truncate product_tax cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -33,11 +34,16 @@ values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '
|
||||||
, (2, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD')
|
, (2, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (3, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (4, 1, 'IVA 21 %', 0.21)
|
, (22, 2, 'tax')
|
||||||
, (5, 2, 'IRPF -7 %', -0.07)
|
;
|
||||||
, (6, 2, 'IVA 10 %', 0.10)
|
|
||||||
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (3, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (4, 1, 11, 'IVA 21 %', 0.21)
|
||||||
|
, (5, 2, 22, 'IRPF -7 %', -0.07)
|
||||||
|
, (6, 2, 22, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, slug, name, description, price)
|
insert into product (product_id, company_id, slug, name, description, price)
|
||||||
|
|
|
@ -32,6 +32,7 @@ truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -39,11 +40,15 @@ insert into company (company_id, business_name, vatin, trade_name, phone, email,
|
||||||
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (2, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (3, 1, 'IVA 4 %', 0.04)
|
;
|
||||||
, (4, 1, 'IVA 10 %', 0.10)
|
|
||||||
, (5, 1, 'IVA 21 %', 0.21)
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (3, 1, 11, 'IVA 4 %', 0.04)
|
||||||
|
, (4, 1, 11, 'IVA 10 %', 0.10)
|
||||||
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
insert into product (product_id, company_id, name, price)
|
||||||
|
|
|
@ -43,6 +43,7 @@ truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate company_user cascade;
|
truncate company_user cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
|
@ -64,9 +65,14 @@ values (2, 1)
|
||||||
, (4, 5)
|
, (4, 5)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (3, 2, 'IVA 21 %', 0.21)
|
values (22, 2, 'vat')
|
||||||
, (6, 4, 'IVA 10 %', 0.10)
|
, (44, 4, 'vat')
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (3, 2, 22, 'IVA 21 %', 0.21)
|
||||||
|
, (6, 4, 44, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
insert into product (product_id, company_id, name, price)
|
||||||
|
|
|
@ -32,6 +32,7 @@ truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
reset client_min_messages;
|
reset client_min_messages;
|
||||||
|
|
||||||
|
@ -39,11 +40,15 @@ insert into company (company_id, business_name, vatin, trade_name, phone, email,
|
||||||
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
values (1, 'Company 1', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (2, 1, 'IRPF -15 %', -0.15)
|
values (11, 1, 'tax')
|
||||||
, (3, 1, 'IVA 4 %', 0.04)
|
;
|
||||||
, (4, 1, 'IVA 10 %', 0.10)
|
|
||||||
, (5, 1, 'IVA 21 %', 0.21)
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
|
, (3, 1, 11, 'IVA 4 %', 0.04)
|
||||||
|
, (4, 1, 11, 'IVA 10 %', 0.10)
|
||||||
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
insert into product (product_id, company_id, name, price)
|
||||||
|
|
|
@ -36,6 +36,7 @@ set client_min_messages to warning;
|
||||||
truncate product_tax cascade;
|
truncate product_tax cascade;
|
||||||
truncate product cascade;
|
truncate product cascade;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company_user cascade;
|
truncate company_user cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
truncate auth."user" cascade;
|
truncate auth."user" cascade;
|
||||||
|
@ -56,9 +57,14 @@ values (2, 1)
|
||||||
, (4, 5)
|
, (4, 5)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (tax_id, company_id, name, rate)
|
insert into tax_class (tax_class_id, company_id, name)
|
||||||
values (3, 2, 'IVA 21 %', 0.21)
|
values (22, 2, 'iva')
|
||||||
, (6, 4, 'IVA 10 %', 0.10)
|
, (44, 4, 'iva')
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into tax (tax_id, company_id, tax_class_id, name, rate)
|
||||||
|
values (3, 2, 22, 'IVA 21 %', 0.21)
|
||||||
|
, (6, 4, 44, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, description, price)
|
insert into product (product_id, company_id, name, description, price)
|
||||||
|
|
36
test/tax.sql
36
test/tax.sql
|
@ -5,7 +5,7 @@ reset client_min_messages;
|
||||||
|
|
||||||
begin;
|
begin;
|
||||||
|
|
||||||
select plan(36);
|
select plan(42);
|
||||||
|
|
||||||
set search_path to numerus, auth, public;
|
set search_path to numerus, auth, public;
|
||||||
|
|
||||||
|
@ -36,6 +36,13 @@ select col_type_is('tax', 'company_id', 'integer');
|
||||||
select col_not_null('tax', 'company_id');
|
select col_not_null('tax', 'company_id');
|
||||||
select col_hasnt_default('tax', 'company_id');
|
select col_hasnt_default('tax', 'company_id');
|
||||||
|
|
||||||
|
select has_column('tax', 'tax_class_id');
|
||||||
|
select col_is_fk('tax', 'tax_class_id');
|
||||||
|
select fk_ok('tax', 'tax_class_id', 'tax_class', 'tax_class_id');
|
||||||
|
select col_type_is('tax', 'tax_class_id', 'integer');
|
||||||
|
select col_not_null('tax', 'tax_class_id');
|
||||||
|
select col_hasnt_default('tax', 'tax_class_id');
|
||||||
|
|
||||||
select has_column('tax', 'name');
|
select has_column('tax', 'name');
|
||||||
select col_type_is('tax', 'name', 'text');
|
select col_type_is('tax', 'name', 'text');
|
||||||
select col_not_null('tax', 'name');
|
select col_not_null('tax', 'name');
|
||||||
|
@ -49,6 +56,7 @@ select col_hasnt_default('tax', 'rate');
|
||||||
|
|
||||||
set client_min_messages to warning;
|
set client_min_messages to warning;
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
|
truncate tax_class cascade;
|
||||||
truncate company_user cascade;
|
truncate company_user cascade;
|
||||||
truncate company cascade;
|
truncate company cascade;
|
||||||
truncate auth."user" cascade;
|
truncate auth."user" cascade;
|
||||||
|
@ -69,14 +77,20 @@ values (2, 1)
|
||||||
, (4, 5)
|
, (4, 5)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into tax (company_id, name, rate)
|
insert into tax_class(tax_class_id, company_id, name)
|
||||||
values (2, 'VAT 21 %', 0.21)
|
values (5, 2, 'vat')
|
||||||
, (2, 'IRPF -15 %', -0.15)
|
, (6, 2, 'irpf')
|
||||||
, (4, 'VAT 21 %', 0.21)
|
, (7, 4, 'vat')
|
||||||
, (4, 'VAT 10 %', 0.10)
|
;
|
||||||
, (4, 'VAT 5 %', 0.05)
|
|
||||||
, (4, 'VAT 4 %', 0.04)
|
insert into tax (company_id, tax_class_id, name, rate)
|
||||||
, (4, 'VAT 0 %', 0.00)
|
values (2, 5, 'VAT 21 %', 0.21)
|
||||||
|
, (2, 6, 'IRPF -15 %', -0.15)
|
||||||
|
, (4, 7, 'VAT 21 %', 0.21)
|
||||||
|
, (4, 7, 'VAT 10 %', 0.10)
|
||||||
|
, (4, 7, 'VAT 5 %', 0.05)
|
||||||
|
, (4, 7, 'VAT 4 %', 0.04)
|
||||||
|
, (4, 7, 'VAT 0 %', 0.00)
|
||||||
;
|
;
|
||||||
|
|
||||||
prepare tax_data as
|
prepare tax_data as
|
||||||
|
@ -120,8 +134,8 @@ select throws_ok(
|
||||||
reset role;
|
reset role;
|
||||||
|
|
||||||
select throws_ok( $$
|
select throws_ok( $$
|
||||||
insert into tax (company_id, name, rate)
|
insert into tax (company_id, tax_class_id, name, rate)
|
||||||
values (2, ' ', 0.22)
|
values (2, 6, ' ', 0.22)
|
||||||
$$,
|
$$,
|
||||||
'23514', 'new row for relation "tax" violates check constraint "name_not_empty"',
|
'23514', 'new row for relation "tax" violates check constraint "name_not_empty"',
|
||||||
'Should not allow taxs with blank name'
|
'Should not allow taxs with blank name'
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
-- Test tax_class
|
||||||
|
set client_min_messages to warning;
|
||||||
|
create extension if not exists pgtap;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select plan(32);
|
||||||
|
|
||||||
|
set search_path to numerus, auth, public;
|
||||||
|
|
||||||
|
select has_table('tax_class');
|
||||||
|
select has_pk('tax_class' );
|
||||||
|
select table_privs_are('tax_class', 'guest', array []::text[]);
|
||||||
|
select table_privs_are('tax_class', 'invoicer', array ['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||||
|
select table_privs_are('tax_class', 'admin', array ['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||||
|
select table_privs_are('tax_class', 'authenticator', array []::text[]);
|
||||||
|
|
||||||
|
select has_sequence('tax_class_tax_class_id_seq');
|
||||||
|
select sequence_privs_are('tax_class_tax_class_id_seq', 'guest', array[]::text[]);
|
||||||
|
select sequence_privs_are('tax_class_tax_class_id_seq', 'invoicer', array['USAGE']);
|
||||||
|
select sequence_privs_are('tax_class_tax_class_id_seq', 'admin', array['USAGE']);
|
||||||
|
select sequence_privs_are('tax_class_tax_class_id_seq', 'authenticator', array[]::text[]);
|
||||||
|
|
||||||
|
select has_column('tax_class', 'tax_class_id');
|
||||||
|
select col_is_pk('tax_class', 'tax_class_id');
|
||||||
|
select col_type_is('tax_class', 'tax_class_id', 'integer');
|
||||||
|
select col_not_null('tax_class', 'tax_class_id');
|
||||||
|
select col_has_default('tax_class', 'tax_class_id');
|
||||||
|
select col_default_is('tax_class', 'tax_class_id', 'nextval(''tax_class_tax_class_id_seq''::regclass)');
|
||||||
|
|
||||||
|
select has_column('tax_class', 'company_id');
|
||||||
|
select col_is_fk('tax_class', 'company_id');
|
||||||
|
select fk_ok('tax_class', 'company_id', 'company', 'company_id');
|
||||||
|
select col_type_is('tax_class', 'company_id', 'integer');
|
||||||
|
select col_not_null('tax_class', 'company_id');
|
||||||
|
select col_hasnt_default('tax_class', 'company_id');
|
||||||
|
|
||||||
|
select has_column('tax_class', 'name');
|
||||||
|
select col_type_is('tax_class', 'name', 'text');
|
||||||
|
select col_not_null('tax_class', 'name');
|
||||||
|
select col_hasnt_default('tax_class', 'name');
|
||||||
|
|
||||||
|
|
||||||
|
set client_min_messages to warning;
|
||||||
|
truncate tax_class cascade;
|
||||||
|
truncate company_user cascade;
|
||||||
|
truncate company cascade;
|
||||||
|
truncate auth."user" cascade;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at)
|
||||||
|
values (1, 'demo@tandem.blog', 'Demo', 'test', 'invoicer', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month')
|
||||||
|
, (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month')
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code)
|
||||||
|
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR')
|
||||||
|
, (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD')
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into company_user (company_id, user_id)
|
||||||
|
values (2, 1)
|
||||||
|
, (4, 5)
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into tax_class (company_id, name)
|
||||||
|
values (2, 'VAT')
|
||||||
|
, (2, 'IRPF')
|
||||||
|
, (4, 'VAT')
|
||||||
|
, (4, 'import')
|
||||||
|
;
|
||||||
|
|
||||||
|
prepare tax_class_data as
|
||||||
|
select company_id, name
|
||||||
|
from tax_class
|
||||||
|
order by company_id;
|
||||||
|
|
||||||
|
set role invoicer;
|
||||||
|
select is_empty('tax_class_data', 'Should show no data when cookie is not set yet');
|
||||||
|
reset role;
|
||||||
|
|
||||||
|
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog');
|
||||||
|
select bag_eq(
|
||||||
|
'tax_class_data',
|
||||||
|
$$ values (2, 'VAT')
|
||||||
|
, (2, 'IRPF')
|
||||||
|
$$,
|
||||||
|
'Should only list taxes of the companies where demo@tandem.blog is user of'
|
||||||
|
);
|
||||||
|
reset role;
|
||||||
|
|
||||||
|
select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog');
|
||||||
|
select bag_eq(
|
||||||
|
'tax_class_data',
|
||||||
|
$$ values (4, 'VAT')
|
||||||
|
, (4, 'import')
|
||||||
|
$$,
|
||||||
|
'Should only list taxes of the companies where admin@tandem.blog is user of'
|
||||||
|
);
|
||||||
|
reset role;
|
||||||
|
|
||||||
|
select set_cookie('not-a-cookie');
|
||||||
|
select throws_ok(
|
||||||
|
'tax_class_data',
|
||||||
|
'42501', 'permission denied for table tax_class',
|
||||||
|
'Should not allow select to guest users'
|
||||||
|
);
|
||||||
|
reset role;
|
||||||
|
|
||||||
|
select throws_ok( $$
|
||||||
|
insert into tax_class (company_id, name)
|
||||||
|
values (2, ' ')
|
||||||
|
$$,
|
||||||
|
'23514', 'new row for relation "tax_class" violates check constraint "name_not_empty"',
|
||||||
|
'Should not allow classes with blank name'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
select *
|
||||||
|
from finish();
|
||||||
|
|
||||||
|
rollback;
|
||||||
|
|
|
@ -4,6 +4,7 @@ begin;
|
||||||
|
|
||||||
select tax_id
|
select tax_id
|
||||||
, company_id
|
, company_id
|
||||||
|
, tax_class_id
|
||||||
, name
|
, name
|
||||||
, rate
|
, rate
|
||||||
from numerus.tax
|
from numerus.tax
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
-- Verify numerus:tax_class on pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select tax_class_id
|
||||||
|
, company_id
|
||||||
|
, name
|
||||||
|
from numerus.tax_class
|
||||||
|
where false;
|
||||||
|
|
||||||
|
select 1 / count(*) from pg_class where oid = 'numerus.tax_class'::regclass and relrowsecurity;
|
||||||
|
select 1 / count(*) from pg_policy where polname = 'company_policy' and polrelid = 'numerus.tax_class'::regclass;
|
||||||
|
|
||||||
|
rollback;
|
|
@ -46,6 +46,7 @@
|
||||||
<th width="50%"></th>
|
<th width="50%"></th>
|
||||||
<th>{{( pgettext "Tax Name" "title" )}}</th>
|
<th>{{( pgettext "Tax Name" "title" )}}</th>
|
||||||
<th>{{( pgettext "Rate (%)" "title" )}}</th>
|
<th>{{( pgettext "Rate (%)" "title" )}}</th>
|
||||||
|
<th>{{( pgettext "Class" "title" )}}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>{{ .Name }}</td>
|
<td>{{ .Name }}</td>
|
||||||
<td>{{ .Rate }}</td>
|
<td>{{ .Rate }}</td>
|
||||||
|
<td>{{ .Class }}</td>
|
||||||
<td>
|
<td>
|
||||||
<form method="POST" action="{{ companyURI "/tax"}}/{{ .Id }}">
|
<form method="POST" action="{{ companyURI "/tax"}}/{{ .Id }}">
|
||||||
{{ csrfToken }}
|
{{ csrfToken }}
|
||||||
|
@ -78,9 +80,12 @@
|
||||||
<td>
|
<td>
|
||||||
{{ template "input-field" .NewTaxForm.Name | addInputAttr `form="newtax"` }}
|
{{ template "input-field" .NewTaxForm.Name | addInputAttr `form="newtax"` }}
|
||||||
</td>
|
</td>
|
||||||
<td colspan="2">
|
<td>
|
||||||
{{ template "input-field" .NewTaxForm.Rate | addInputAttr `form="newtax"` }}
|
{{ template "input-field" .NewTaxForm.Rate | addInputAttr `form="newtax"` }}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ template "select-field" .NewTaxForm.Class | addSelectAttr `form="newtax"` }}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2"></td>
|
<td colspan="2"></td>
|
||||||
|
|
Loading…
Reference in New Issue