Compare commits
No commits in common. "ca0298213e9b2c292b6eca7c0d1dc7b0847999fd" and "5717a5b9ed9495377c2ebc3752eda7d09210c1a4" have entirely different histories.
ca0298213e
...
5717a5b9ed
|
@ -61,12 +61,12 @@ select add_product(1, 'Teia', 'Fusta resinosa de pi i d’altres arbres, provine
|
|||
|
||||
alter sequence invoice_invoice_id_seq restart;
|
||||
alter sequence invoice_product_invoice_product_id_seq restart;
|
||||
select add_invoice(1, (current_date - '28 days'::interval)::date, 6, 'Vol esmorzar!', 1, '{producte}','{"(1,Teia,\"Fusta resinosa de pi i d’altres arbres, provinent sobretot del cor de l’arbre, que crema amb molta facilitat.\",7.00,1,0.0,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, (current_date - '24 days'::interval)::date, 5, '', 1, '{producte,bestia}','{"(1,Palla,Tija seca dels cereals després que el gra o llavor ha estat separat mitjançant la trilla.,25.00,25,0.0,{3})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, (current_date - '17 days'::interval)::date, 4, '', 1, '{producte,higiene}','{"(1,\"Paper higiènic (pack de 32 U)\",Paper que s’usa per mantenir la higiene personal després de defecar o orinar.,7.99,10,0.0,{4})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, (current_date - '7 days'::interval)::date, 3, '', 1, '{producte,mag}','{"(1,Mirra,Goma resinosa aromàtica de color gris groguenc i gust amargant.,7.22,144,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",4.45,1,0.0,{2})"}');
|
||||
select add_invoice(1, (current_date - '4 days'::interval)::date, 2, '', 1, '{producte,mag}','{"(1,Encens,Goma resina fragrant que desprèn una olor característica quan es crema.,2.26,460,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",4.53,1,0.0,{2})"}');
|
||||
select add_invoice(1, (current_date - '1 days'::interval)::date, 1, '', 1, '{producte,mag}','{"(1,Or,\"Metall de transició tou, brillant, groc, pesant, mal·leable, dúctil i que no reacciona amb la majoria de productes químics, però és sensible al clor i a l’aigua règia.\",57.82,18,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.43,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '28 days'::interval)::date, 6, 'Vol esmorzar!', 1, '{producte}','{"(1,Teia,\"Fusta resinosa de pi i d’altres arbres, provinent sobretot del cor de l’arbre, que crema amb molta facilitat.\",7.00,1,0.0,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '24 days'::interval)::date, 5, '', 1, '{producte,bestia}','{"(1,Palla,Tija seca dels cereals després que el gra o llavor ha estat separat mitjançant la trilla.,25.00,25,0.0,{3})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '17 days'::interval)::date, 4, '', 1, '{producte,higiene}','{"(1,\"Paper higiènic (pack de 32 U)\",Paper que s’usa per mantenir la higiene personal després de defecar o orinar.,7.99,10,0.0,{4})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.64,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '7 days'::interval)::date, 3, '', 1, '{producte,mag}','{"(1,Mirra,Goma resinosa aromàtica de color gris groguenc i gust amargant.,7.22,144,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",4.45,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '4 days'::interval)::date, 2, '', 1, '{producte,mag}','{"(1,Encens,Goma resina fragrant que desprèn una olor característica quan es crema.,2.26,460,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",4.53,1,0.0,{2})"}');
|
||||
select add_invoice(1, '', (current_date - '1 days'::interval)::date, 1, '', 1, '{producte,mag}','{"(1,Or,\"Metall de transició tou, brillant, groc, pesant, mal·leable, dúctil i que no reacciona amb la majoria de productes químics, però és sensible al clor i a l’aigua règia.\",57.82,18,0.05,{2})","(5,Cavall Fort,\"Revista quinzenal en llengua catalana i de còmic en català, destinada a infants i joves.\",3.43,1,0.0,{2})"}');
|
||||
|
||||
update invoice set invoice_status = 'paid' where invoice_id in (1, 5);
|
||||
update invoice set invoice_status = 'unpaid' where invoice_id = 3;
|
||||
|
|
|
@ -16,7 +16,7 @@ begin;
|
|||
|
||||
set search_path to numerus, public;
|
||||
|
||||
create or replace function add_invoice(company integer, invoice_date date, contact_id integer, notes text, payment_method_id integer, tags tag_name[], products new_invoice_product[]) returns uuid as
|
||||
create or replace function add_invoice(company integer, invoice_number text, invoice_date date, contact_id integer, notes text, payment_method_id integer, tags tag_name[], products new_invoice_product[]) returns uuid as
|
||||
$$
|
||||
declare
|
||||
iid integer;
|
||||
|
@ -25,9 +25,13 @@ declare
|
|||
ccode text;
|
||||
ipid integer;
|
||||
begin
|
||||
if invoice_number is null or length(trim(invoice_number)) = 0 then
|
||||
invoice_number = next_invoice_number(company, invoice_date);
|
||||
end if;
|
||||
|
||||
insert into invoice (company_id, invoice_number, invoice_date, contact_id, notes, currency_code, payment_method_id)
|
||||
select company_id
|
||||
, next_invoice_number(add_invoice.company, invoice_date)
|
||||
, invoice_number
|
||||
, invoice_date
|
||||
, contact_id
|
||||
, notes
|
||||
|
@ -66,8 +70,8 @@ end;
|
|||
$$
|
||||
language plpgsql;
|
||||
|
||||
revoke execute on function add_invoice(integer, date, integer, text, integer, tag_name[], new_invoice_product[]) from public;
|
||||
grant execute on function add_invoice(integer, date, integer, text, integer, tag_name[], new_invoice_product[]) to invoicer;
|
||||
grant execute on function add_invoice(integer, date, integer, text, integer, tag_name[], new_invoice_product[]) to admin;
|
||||
revoke execute on function add_invoice(integer, text, date, integer, text, integer, tag_name[], new_invoice_product[]) from public;
|
||||
grant execute on function add_invoice(integer, text, date, integer, text, integer, tag_name[], new_invoice_product[]) to invoicer;
|
||||
grant execute on function add_invoice(integer, text, date, integer, text, integer, tag_name[], new_invoice_product[]) to admin;
|
||||
|
||||
commit;
|
||||
|
|
|
@ -217,6 +217,7 @@ func ServeInvoice(w http.ResponseWriter, r *http.Request, params httprouter.Para
|
|||
if invoiceToDuplicate := r.URL.Query().Get("duplicate"); invoiceToDuplicate != "" {
|
||||
form.MustFillFromDatabase(r.Context(), conn, invoiceToDuplicate)
|
||||
form.InvoiceStatus.Selected = []string{"created"}
|
||||
form.Number.Val = ""
|
||||
}
|
||||
form.Date.Val = time.Now().Format("2006-01-02")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -336,7 +337,7 @@ func mustGetInvoice(ctx context.Context, conn *Conn, company *Company, slug stri
|
|||
if err := conn.QueryRow(ctx, "select array_agg(array[name, to_price(amount, $2)]) from invoice_tax_amount join tax using (tax_id) where invoice_id = $1", invoiceId, decimalDigits).Scan(&inv.Taxes); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rows := conn.MustQuery(ctx, "select invoice_product.name, description, to_price(price, $2), (discount_rate * 100)::integer, quantity, to_price(subtotal, $2), to_price(total, $2), array_agg(array[tax_class.name, (tax_rate * 100)::integer::text]) filter (where tax_rate is not null) from invoice_product join invoice_product_amount using (invoice_product_id) left join invoice_product_tax using (invoice_product_id) left join tax using (tax_id) left join tax_class using (tax_class_id) where invoice_id = $1 group by invoice_product.name, description, discount_rate, price, quantity, subtotal, total", invoiceId, decimalDigits)
|
||||
rows := conn.MustQuery(ctx, "select invoice_product.name, description, to_price(price, $2), (discount_rate * 100)::integer, quantity, to_price(subtotal, $2), to_price(total, $2), array_agg(array[tax_class.name, (tax_rate * 100)::integer::text]) from invoice_product join invoice_product_amount using (invoice_product_id) left join invoice_product_tax using (invoice_product_id) left join tax using (tax_id) left join tax_class using (tax_class_id) where invoice_id = $1 group by invoice_product.name, description, discount_rate, price, quantity, subtotal, total", invoiceId, decimalDigits)
|
||||
defer rows.Close()
|
||||
taxClasses := map[string]bool{}
|
||||
for rows.Next() {
|
||||
|
@ -455,7 +456,7 @@ func HandleAddInvoice(w http.ResponseWriter, r *http.Request, _ httprouter.Param
|
|||
mustRenderNewInvoiceForm(w, r, form)
|
||||
return
|
||||
}
|
||||
slug := conn.MustGetText(r.Context(), "", "select add_invoice($1, $2, $3, $4, $5, $6, $7)", company.Id, form.Date, form.Customer, form.Notes, form.PaymentMethod, form.Tags, NewInvoiceProductArray(form.Products))
|
||||
slug := conn.MustGetText(r.Context(), "", "select add_invoice($1, $2, $3, $4, $5, $6, $7, $8)", company.Id, form.Number, form.Date, form.Customer, form.Notes, form.PaymentMethod, form.Tags, NewInvoiceProductArray(form.Products))
|
||||
if IsHTMxRequest(r) {
|
||||
w.Header().Set("HX-Trigger", "closeModal")
|
||||
w.Header().Set("HX-Refresh", "true")
|
||||
|
@ -528,9 +529,9 @@ func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte {
|
|||
type invoiceForm struct {
|
||||
locale *Locale
|
||||
company *Company
|
||||
Number string
|
||||
InvoiceStatus *SelectField
|
||||
Customer *SelectField
|
||||
Number *InputField
|
||||
Date *InputField
|
||||
Notes *InputField
|
||||
PaymentMethod *SelectField
|
||||
|
@ -555,6 +556,11 @@ func newInvoiceForm(ctx context.Context, conn *Conn, locale *Locale, company *Co
|
|||
Required: true,
|
||||
Options: MustGetOptions(ctx, conn, "select contact_id::text, business_name from contact where company_id = $1 order by business_name", company.Id),
|
||||
},
|
||||
Number: &InputField{
|
||||
Name: "number",
|
||||
Label: pgettext("input", "Number", locale),
|
||||
Type: "text",
|
||||
},
|
||||
Date: &InputField{
|
||||
Name: "date",
|
||||
Label: pgettext("input", "Invoice Date", locale),
|
||||
|
@ -586,6 +592,7 @@ func (form *invoiceForm) Parse(r *http.Request) error {
|
|||
}
|
||||
form.InvoiceStatus.FillValue(r)
|
||||
form.Customer.FillValue(r)
|
||||
form.Number.FillValue(r)
|
||||
form.Date.FillValue(r)
|
||||
form.Notes.FillValue(r)
|
||||
form.Tags.FillValue(r)
|
||||
|
@ -682,7 +689,7 @@ func (form *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *Conn, s
|
|||
, invoice_date
|
||||
, notes
|
||||
, payment_method_id
|
||||
`, slug).Scan(&invoiceId, form.InvoiceStatus, form.Customer, &form.Number, form.Date, form.Notes, form.PaymentMethod, form.Tags)) {
|
||||
`, slug).Scan(&invoiceId, form.InvoiceStatus, form.Customer, form.Number, form.Date, form.Notes, form.PaymentMethod, form.Tags)) {
|
||||
form.PaymentMethod.Selected = selectedPaymentMethod
|
||||
form.InvoiceStatus.Selected = selectedInvoiceStatus
|
||||
return false
|
||||
|
@ -883,7 +890,7 @@ func newEditInvoicePage(slug string, form *invoiceForm, r *http.Request) *editIn
|
|||
return &editInvoicePage{
|
||||
newNewInvoicePage(form, r),
|
||||
slug,
|
||||
form.Number,
|
||||
form.Number.String(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
begin;
|
||||
|
||||
drop function if exists numerus.add_invoice(integer, date, integer, text, integer, numerus.tag_name[], numerus.new_invoice_product[]);
|
||||
drop function if exists numerus.add_invoice(integer, text, date, integer, text, integer, numerus.tag_name[], numerus.new_invoice_product[]);
|
||||
|
||||
commit;
|
||||
|
|
|
@ -5,19 +5,19 @@ reset client_min_messages;
|
|||
|
||||
begin;
|
||||
|
||||
select plan(17);
|
||||
select plan(19);
|
||||
|
||||
set search_path to auth, numerus, public;
|
||||
|
||||
select has_function('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]']);
|
||||
select function_lang_is('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'plpgsql');
|
||||
select function_returns('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'uuid');
|
||||
select isnt_definer('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]']);
|
||||
select volatility_is('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'volatile');
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'guest', array []::text[]);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'invoicer', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'admin', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'authenticator', array []::text[]);
|
||||
select has_function('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]']);
|
||||
select function_lang_is('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'plpgsql');
|
||||
select function_returns('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'uuid');
|
||||
select isnt_definer('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]']);
|
||||
select volatility_is('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'volatile');
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'guest', array []::text[]);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'invoicer', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'admin', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'add_invoice', array ['integer', 'text', 'date', 'integer', 'text', 'integer', 'tag_name[]', 'new_invoice_product[]'], 'authenticator', array []::text[]);
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
|
@ -83,45 +83,59 @@ values (12, 1, 'Contact 2.1', 'XX555', '', '777-777-777', 'c@c', '', '', '', '',
|
|||
|
||||
|
||||
select lives_ok(
|
||||
$$ select add_invoice(1, '2023-02-15', 12, 'Notes 1', 111, '{tag1,tag2}','{"(7,Product 1,Description 1,12.24,2,0.0,{4})"}') $$,
|
||||
$$ select add_invoice(1, 'INV001', '2023-02-15', 12, 'Notes 1', 111, '{tag1,tag2}','{"(7,Product 1,Description 1,12.24,2,0.0,{4})"}') $$,
|
||||
'Should be able to insert an invoice for the first company with a product'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select add_invoice(1, '2023-02-16', 13, 'Notes 2', 111, '{}', '{"(7,Product 1 bis,Description 1 bis,33.33,1,0.50,\"{4,3}\")","(8,Product 2,Description 2,24.00,3,0.75,{})"}') $$,
|
||||
$$ select add_invoice(1, 'INV002', '2023-02-16', 13, 'Notes 2', 111, '{}', '{"(7,Product 1 bis,Description 1 bis,33.33,1,0.50,\"{4,3}\")","(8,Product 2,Description 2,24.00,3,0.75,{})"}') $$,
|
||||
'Should be able to insert a second invoice for the first company with two product'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select add_invoice(2, '2023-02-14', 15, 'Notes 3', 222, '{tag3}','{"(11,Product 4.3,,11.11,1,0.0,{6})"}') $$,
|
||||
$$ select add_invoice(2, 'INV101', '2023-02-14', 15, 'Notes 3', 222, '{tag3}','{"(11,Product 4.3,,11.11,1,0.0,{6})"}') $$,
|
||||
'Should be able to insert an invoice for the second company with a product'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select add_invoice(1, NULL, '2023-03-15', 13, '', 111, '{tag2}', '{"(7,PA1,DA1,44.33,1,0.50,{})"}') $$,
|
||||
'Should be able to insert an invoice with an autogenerated number'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select add_invoice(2, ' ', '2023-04-16', 14, '', 222, '{tag2,tag3,tag4}','{"(11,PA2,DA2,55.33,10,0.75,{})"}') $$,
|
||||
'Should consider non-null, but otherwise empty numbers the same as null and autogenerate it'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select company_id, invoice_number, invoice_date, contact_id, invoice_status, notes, payment_method_id, currency_code, created_at from invoice $$,
|
||||
$$ values (1, 'F20230006', '2023-02-15'::date, 12, 'created', 'Notes 1', 111, 'EUR', current_timestamp)
|
||||
, (1, 'F20230007', '2023-02-16'::date, 13, 'created', 'Notes 2', 111, 'EUR', current_timestamp)
|
||||
, (2, 'INV056-23', '2023-02-14'::date, 15, 'created', 'Notes 3', 222, 'USD', current_timestamp)
|
||||
$$ values (1, 'INV001', '2023-02-15'::date, 12, 'created', 'Notes 1', 111, 'EUR', current_timestamp)
|
||||
, (1, 'INV002', '2023-02-16'::date, 13, 'created', 'Notes 2', 111, 'EUR', current_timestamp)
|
||||
, (2, 'INV101', '2023-02-14'::date, 15, 'created', 'Notes 3', 222, 'USD', current_timestamp)
|
||||
, (1, 'F20230006', '2023-03-15'::date, 13, 'created', '', 111, 'EUR', current_timestamp)
|
||||
, (2, 'INV056-23', '2023-04-16'::date, 14, 'created', '', 222, 'USD', current_timestamp)
|
||||
$$,
|
||||
'Should have created all invoices'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select invoice_number, product_id, name, description, price, quantity, discount_rate from invoice_product join invoice using (invoice_id) $$,
|
||||
$$ values ('F20230006', 7, 'Product 1', 'Description 1', 1224, 2, 0.00)
|
||||
, ('F20230007', 7, 'Product 1 bis', 'Description 1 bis', 3333, 1, 0.50)
|
||||
, ('F20230007', 8, 'Product 2', 'Description 2', 2400, 3, 0.75)
|
||||
, ('INV056-23', 11, 'Product 4.3', '', 1111, 1, 0.0)
|
||||
$$ values ('INV001', 7, 'Product 1', 'Description 1', 1224, 2, 0.00)
|
||||
, ('INV002', 7, 'Product 1 bis', 'Description 1 bis', 3333, 1, 0.50)
|
||||
, ('INV002', 8, 'Product 2', 'Description 2', 2400, 3, 0.75)
|
||||
, ('INV101', 11, 'Product 4.3', '', 1111, 1, 0.0)
|
||||
, ('F20230006', 7, 'PA1', 'DA1', 4433, 1, 0.50)
|
||||
, ('INV056-23', 11, 'PA2', 'DA2', 5533, 10, 0.75)
|
||||
$$,
|
||||
'Should have created all invoice products'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select invoice_number, product_id, tax_id, tax_rate from invoice_product_tax join invoice_product using (invoice_product_id) join invoice using (invoice_id) $$,
|
||||
$$ values ('F20230006', 7, 4, 0.21)
|
||||
, ('F20230007', 7, 4, 0.21)
|
||||
, ('F20230007', 7, 3, -0.15)
|
||||
, ('INV056-23', 11, 6, 0.10)
|
||||
$$ values ('INV001', 7, 4, 0.21)
|
||||
, ('INV002', 7, 4, 0.21)
|
||||
, ('INV002', 7, 3, -0.15)
|
||||
, ('INV101', 11, 6, 0.10)
|
||||
$$,
|
||||
'Should have created all invoice product taxes'
|
||||
);
|
||||
|
@ -130,16 +144,22 @@ select bag_eq(
|
|||
$$ select company_id, name from tag $$,
|
||||
$$ values (1, 'tag1')
|
||||
, (1, 'tag2')
|
||||
, (2, 'tag2')
|
||||
, (2, 'tag3')
|
||||
, (2, 'tag4')
|
||||
$$,
|
||||
'Should have added all new tags once'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
$$ select invoice_number, tag.name from invoice_tag join invoice using (invoice_id) join tag using (tag_id) $$,
|
||||
$$ values ('F20230006', 'tag1')
|
||||
$$ values ('INV001', 'tag1')
|
||||
, ('INV001', 'tag2')
|
||||
, ('INV101', 'tag3')
|
||||
, ('F20230006', 'tag2')
|
||||
, ('INV056-23', 'tag2')
|
||||
, ('INV056-23', 'tag3')
|
||||
, ('INV056-23', 'tag4')
|
||||
$$,
|
||||
'Should have assigned the tags to invoices'
|
||||
);
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('numerus.add_invoice(integer, date, integer, text, integer, numerus.tag_name[], numerus.new_invoice_product[])', 'execute');
|
||||
select has_function_privilege('numerus.add_invoice(integer, text, date, integer, text, integer, numerus.tag_name[], numerus.new_invoice_product[])', 'execute');
|
||||
|
||||
rollback;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
{{ with .Form -}}
|
||||
{{ template "select-field" .Customer }}
|
||||
{{ template "hidden-field" .Number }}
|
||||
{{ template "hidden-field" .Date }}
|
||||
{{ template "tags-field" .Tags }}
|
||||
{{ template "select-field" .PaymentMethod }}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
{{ with .Form -}}
|
||||
{{ template "hidden-select-field" .InvoiceStatus }}
|
||||
{{ template "select-field" .Customer }}
|
||||
{{ template "input-field" .Number }}
|
||||
{{ template "input-field" .Date }}
|
||||
{{ template "tags-field" .Tags }}
|
||||
{{ template "select-field" .PaymentMethod }}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<p>
|
||||
<a href="{{ companyURI "/" }}">{{( pgettext "Home" "title" )}}</a> /
|
||||
<a href="{{ companyURI "/invoices"}}">{{( pgettext "Invoices" "title" )}}</a> /
|
||||
{{ if eq .Form.Number "" }}
|
||||
{{ if eq .Form.Number.Val "" }}
|
||||
<a>{{( pgettext "New Invoice" "title" )}}</a>
|
||||
{{ else }}
|
||||
<a>{{ .Form.Number }}</a>
|
||||
|
@ -26,19 +26,22 @@
|
|||
|
||||
{{- with .Form }}
|
||||
{{ template "hidden-select-field" .Customer }}
|
||||
{{ template "hidden-field" .Number }}
|
||||
{{ template "hidden-field" .Date }}
|
||||
{{ template "hidden-field" .Notes }}
|
||||
{{ template "hidden-field" .Tags }}
|
||||
|
||||
{{- range $product := .Products }}
|
||||
{{ template "hidden-field" .InvoiceProductId }}
|
||||
{{ template "hidden-field" .ProductId }}
|
||||
{{ template "hidden-field" .Name }}
|
||||
{{ template "hidden-field" .Description }}
|
||||
{{ template "hidden-field" .Price }}
|
||||
{{ template "hidden-field" .Quantity }}
|
||||
{{ template "hidden-field" .Discount }}
|
||||
{{ template "hidden-select-field" .Tax }}
|
||||
<fieldset>
|
||||
{{ template "hidden-field" .InvoiceProductId }}
|
||||
{{ template "hidden-field" .ProductId }}
|
||||
{{ template "hidden-field" .Name }}
|
||||
{{ template "hidden-field" .Description }}
|
||||
{{ template "hidden-field" .Price }}
|
||||
{{ template "hidden-field" .Quantity }}
|
||||
{{ template "hidden-field" .Discount }}
|
||||
{{ template "hidden-select-field" .Tax }}
|
||||
</fieldset>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
|
Loading…
Reference in New Issue