Move the product_id field from invoice_product to a separate table
We are going to allow invoices with products that are not (yet) inserted into the products table. We always allowed to have products in invoices with a totally different name, description, price, and whatnot, but until now we had the product id in these invoice lines for statistics purposes. However, Oriol raised the concern that this requires for the products to be inserted before we can create an invoice with them, and we do not plan to have a “create product while invoicing” feature, thus it would mean that people would need to cancel the new invoice, create the new product, and then start the invoice again from scratch. The compromise is to allow products in the invoice that do not have a product_id, meaning that at the time the invoice was created they were not (yet) in the products table. Oriol sees this stop-invoice-create- product issue more important than the accurate statistics of product sales, as it will probably be only one or two units off, anyway. I did not want to allow NULL values to the invoice product’s product_id field, because NULL means “dunno” instead of “no product”, so i had to split that field to a separate table that relates an invoice product with a registered product.
This commit is contained in:
parent
835bab357e
commit
90982b49ff
|
@ -7,6 +7,7 @@
|
||||||
-- requires: new_invoice_product
|
-- requires: new_invoice_product
|
||||||
-- requires: tax
|
-- requires: tax
|
||||||
-- requires: invoice_product
|
-- requires: invoice_product
|
||||||
|
-- requires: invoice_product_product
|
||||||
-- requires: invoice_product_tax
|
-- requires: invoice_product_tax
|
||||||
-- requires: next_invoice_number
|
-- requires: next_invoice_number
|
||||||
-- requires: tag_name
|
-- requires: tag_name
|
||||||
|
@ -40,9 +41,8 @@ begin
|
||||||
|
|
||||||
foreach product in array products
|
foreach product in array products
|
||||||
loop
|
loop
|
||||||
insert into invoice_product (invoice_id, product_id, name, description, price, quantity, discount_rate)
|
insert into invoice_product (invoice_id, name, description, price, quantity, discount_rate)
|
||||||
select iid
|
select iid
|
||||||
, product.product_id
|
|
||||||
, product.name
|
, product.name
|
||||||
, coalesce(product.description, '')
|
, coalesce(product.description, '')
|
||||||
, parse_price(product.price, currency.decimal_digits)
|
, parse_price(product.price, currency.decimal_digits)
|
||||||
|
@ -53,6 +53,11 @@ begin
|
||||||
returning invoice_product_id
|
returning invoice_product_id
|
||||||
into ipid;
|
into ipid;
|
||||||
|
|
||||||
|
if product.product_id is not null then
|
||||||
|
insert into invoice_product_product (invoice_product_id, product_id)
|
||||||
|
values (ipid, product.product_id);
|
||||||
|
end if;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
select ipid, tax_id, tax.rate
|
select ipid, tax_id, tax.rate
|
||||||
from tax
|
from tax
|
||||||
|
|
|
@ -42,9 +42,8 @@ begin
|
||||||
foreach product in array products
|
foreach product in array products
|
||||||
loop
|
loop
|
||||||
if product.invoice_product_id is null then
|
if product.invoice_product_id is null then
|
||||||
insert into invoice_product (invoice_id, product_id, name, description, price, quantity, discount_rate)
|
insert into invoice_product (invoice_id, name, description, price, quantity, discount_rate)
|
||||||
select iid
|
select iid
|
||||||
, product.product_id
|
|
||||||
, product.name
|
, product.name
|
||||||
, coalesce(product.description, '')
|
, coalesce(product.description, '')
|
||||||
, parse_price(product.price, currency.decimal_digits)
|
, parse_price(product.price, currency.decimal_digits)
|
||||||
|
@ -58,8 +57,7 @@ begin
|
||||||
ipid := product.invoice_product_id;
|
ipid := product.invoice_product_id;
|
||||||
|
|
||||||
update invoice_product
|
update invoice_product
|
||||||
set product_id = product.product_id
|
set name = product.name
|
||||||
, name = product.name
|
|
||||||
, description = coalesce(product.description, '')
|
, description = coalesce(product.description, '')
|
||||||
, price = parse_price(product.price, currency.decimal_digits)
|
, price = parse_price(product.price, currency.decimal_digits)
|
||||||
, quantity = product.quantity
|
, quantity = product.quantity
|
||||||
|
@ -70,6 +68,15 @@ begin
|
||||||
end if;
|
end if;
|
||||||
products_to_keep := array_append(products_to_keep, ipid);
|
products_to_keep := array_append(products_to_keep, ipid);
|
||||||
|
|
||||||
|
if product.product_id is null then
|
||||||
|
delete from invoice_product_product where invoice_product_id = ipid;
|
||||||
|
else
|
||||||
|
insert into invoice_product_product (invoice_product_id, product_id)
|
||||||
|
values (ipid, product.product_id)
|
||||||
|
on conflict (invoice_product_id) do update
|
||||||
|
set product_id = product.product_id;
|
||||||
|
end if;
|
||||||
|
|
||||||
delete from invoice_product_tax where invoice_product_id = ipid;
|
delete from invoice_product_tax where invoice_product_id = ipid;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
@ -86,6 +93,7 @@ begin
|
||||||
|
|
||||||
if array_length(products_to_delete, 1) > 0 then
|
if array_length(products_to_delete, 1) > 0 then
|
||||||
delete from invoice_product_tax where invoice_product_id = any(products_to_delete);
|
delete from invoice_product_tax where invoice_product_id = any(products_to_delete);
|
||||||
|
delete from invoice_product_product where invoice_product_id = any(products_to_delete);
|
||||||
delete from invoice_product where invoice_product_id = any(products_to_delete);
|
delete from invoice_product where invoice_product_id = any(products_to_delete);
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ set search_path to numerus, public;
|
||||||
create table invoice_product (
|
create table invoice_product (
|
||||||
invoice_product_id serial primary key,
|
invoice_product_id serial primary key,
|
||||||
invoice_id integer not null references invoice,
|
invoice_id integer not null references invoice,
|
||||||
product_id integer not null references product,
|
|
||||||
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),
|
||||||
description text not null default '',
|
description text not null default '',
|
||||||
price integer not null,
|
price integer not null,
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
-- Deploy numerus:invoice_product_product to pg
|
||||||
|
-- requires: schema_numerus
|
||||||
|
-- requires: invoice_product
|
||||||
|
-- requires: product
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
set search_path to numerus;
|
||||||
|
|
||||||
|
create table invoice_product_product (
|
||||||
|
invoice_product_id integer primary key references invoice_product,
|
||||||
|
product_id integer not null references product
|
||||||
|
);
|
||||||
|
|
||||||
|
grant select, insert, update, delete on table invoice_product_product to invoicer;
|
||||||
|
grant select, insert, update, delete on table invoice_product_product to admin;
|
||||||
|
|
||||||
|
commit;
|
|
@ -695,7 +695,7 @@ func (form *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *Conn, s
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
form.Products = []*invoiceProductForm{}
|
form.Products = []*invoiceProductForm{}
|
||||||
form.mustAddProductsFromQuery(ctx, conn, "select invoice_product_id::text, product_id, name, description, to_price(price, $2), quantity, (discount_rate * 100)::integer, array_remove(array_agg(tax_id), null) from invoice_product left join invoice_product_tax using (invoice_product_id) where invoice_id = $1 group by invoice_product_id, product_id, name, description, discount_rate, price, quantity", invoiceId, form.company.DecimalDigits)
|
form.mustAddProductsFromQuery(ctx, conn, "select invoice_product_id::text, coalesce(product_id, 0), name, description, to_price(price, $2), quantity, (discount_rate * 100)::integer, array_remove(array_agg(tax_id), null) from invoice_product left join invoice_product_product using (invoice_product_id) left join invoice_product_tax using (invoice_product_id) where invoice_id = $1 group by invoice_product_id, coalesce(product_id, 0), name, description, discount_rate, price, quantity", invoiceId, form.company.DecimalDigits)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Revert numerus:invoice_product_product from pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
drop table if exists numerus.invoice_product_product;
|
||||||
|
|
||||||
|
commit;
|
|
@ -53,13 +53,14 @@ product_tax [schema_numerus product tax] 2023-02-08T11:36:49Z jordi fita mas <jo
|
||||||
invoice [schema_numerus company contact invoice_status payment_method currency tag_name] 2023-02-09T09:52:21Z jordi fita mas <jordi@tandem.blog> # Add relation for invoice
|
invoice [schema_numerus company contact invoice_status payment_method currency tag_name] 2023-02-09T09:52:21Z jordi fita mas <jordi@tandem.blog> # Add relation for invoice
|
||||||
discount_rate [schema_numerus] 2023-02-10T17:22:40Z jordi fita mas <jordi@tandem.blog> # Add domain for discount rates
|
discount_rate [schema_numerus] 2023-02-10T17:22:40Z jordi fita mas <jordi@tandem.blog> # Add domain for discount rates
|
||||||
invoice_product [schema_numerus invoice discount_rate] 2023-02-10T17:07:08Z jordi fita mas <jordi@tandem.blog> # Add relation for invoice product
|
invoice_product [schema_numerus invoice discount_rate] 2023-02-10T17:07:08Z jordi fita mas <jordi@tandem.blog> # Add relation for invoice product
|
||||||
|
invoice_product_product [schema_numerus invoice_product product] 2023-04-19T16:06:30Z jordi fita mas <jordi@tandem.blog> # Add relation of invoice products and registered products
|
||||||
add_product [schema_numerus product product_tax parse_price company currency tag_name] 2023-02-14T10:32:18Z jordi fita mas <jordi@tandem.blog> # Add function to add new products
|
add_product [schema_numerus product product_tax parse_price company currency tag_name] 2023-02-14T10:32:18Z jordi fita mas <jordi@tandem.blog> # Add function to add new products
|
||||||
edit_product [schema_numerus product product_tax parse_price company currency tag_name] 2023-02-14T11:06:03Z jordi fita mas <jordi@tandem.blog> # Add function to edit products
|
edit_product [schema_numerus product product_tax parse_price company currency tag_name] 2023-02-14T11:06:03Z jordi fita mas <jordi@tandem.blog> # Add function to edit products
|
||||||
invoice_product_tax [schema_numerus invoice_product tax tax_rate] 2023-02-15T13:20:30Z jordi fita mas <jordi@tandem.blog> # Add relation for taxes in invoice products
|
invoice_product_tax [schema_numerus invoice_product tax tax_rate] 2023-02-15T13:20:30Z jordi fita mas <jordi@tandem.blog> # Add relation for taxes in invoice products
|
||||||
new_invoice_product [schema_numerus discount_rate] 2023-02-16T21:06:01Z jordi fita mas <jordi@tandem.blog> # Add type for passing products to new invoices
|
new_invoice_product [schema_numerus discount_rate] 2023-02-16T21:06:01Z jordi fita mas <jordi@tandem.blog> # Add type for passing products to new invoices
|
||||||
invoice_number_counter [schema_numerus company] 2023-02-17T13:04:48Z jordi fita mas <jordi@tandem.blog> # Add relation to count invoice numbers
|
invoice_number_counter [schema_numerus company] 2023-02-17T13:04:48Z jordi fita mas <jordi@tandem.blog> # Add relation to count invoice numbers
|
||||||
next_invoice_number [schema_numerus invoice_number_counter] 2023-02-17T13:21:48Z jordi fita mas <jordi@tandem.blog> # Add function to retrieve the next invoice number
|
next_invoice_number [schema_numerus invoice_number_counter] 2023-02-17T13:21:48Z jordi fita mas <jordi@tandem.blog> # Add function to retrieve the next invoice number
|
||||||
add_invoice [schema_numerus invoice company currency parse_price new_invoice_product tax invoice_product invoice_product_tax next_invoice_number tag_name] 2023-02-16T21:12:46Z jordi fita mas <jordi@tandem.blog> # Add function to create new invoices
|
add_invoice [schema_numerus invoice company currency parse_price new_invoice_product tax invoice_product invoice_product_product invoice_product_tax next_invoice_number tag_name] 2023-02-16T21:12:46Z jordi fita mas <jordi@tandem.blog> # Add function to create new invoices
|
||||||
invoice_tax_amount [schema_numerus invoice_product invoice_product_tax] 2023-02-22T12:08:35Z jordi fita mas <jordi@tandem.blog> # Add view for invoice tax amount
|
invoice_tax_amount [schema_numerus invoice_product invoice_product_tax] 2023-02-22T12:08:35Z jordi fita mas <jordi@tandem.blog> # Add view for invoice tax amount
|
||||||
invoice_product_amount [schema_numerus invoice_product invoice_product_tax] 2023-03-01T11:18:05Z jordi fita mas <jordi@tandem.blog> # Add view for invoice product subtotal and total
|
invoice_product_amount [schema_numerus invoice_product invoice_product_tax] 2023-03-01T11:18:05Z jordi fita mas <jordi@tandem.blog> # Add view for invoice product subtotal and total
|
||||||
invoice_amount [schema_numerus invoice_product invoice_product_amount] 2023-02-22T12:58:46Z jordi fita mas <jordi@tandem.blog> # Add view to compute subtotal and total for invoices
|
invoice_amount [schema_numerus invoice_product invoice_product_amount] 2023-02-22T12:58:46Z jordi fita mas <jordi@tandem.blog> # Add view to compute subtotal and total for invoices
|
||||||
|
|
|
@ -5,7 +5,7 @@ reset client_min_messages;
|
||||||
|
|
||||||
begin;
|
begin;
|
||||||
|
|
||||||
select plan(15);
|
select plan(16);
|
||||||
|
|
||||||
set search_path to auth, numerus, public;
|
set search_path to auth, numerus, public;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ select lives_ok(
|
||||||
);
|
);
|
||||||
|
|
||||||
select lives_ok(
|
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, '2023-02-14', 15, 'Notes 3', 222, '{tag3}','{"(11,Product 4.3,,11.11,1,0.0,{6})","(,Product 4.4,Description 4.4,22.22,3,0.05,{})"}') $$,
|
||||||
'Should be able to insert an invoice for the second company with a product'
|
'Should be able to insert an invoice for the second company with a product'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -105,21 +105,33 @@ select bag_eq(
|
||||||
);
|
);
|
||||||
|
|
||||||
select bag_eq(
|
select bag_eq(
|
||||||
$$ select invoice_number, product_id, name, description, price, quantity, discount_rate from invoice_product join invoice using (invoice_id) $$,
|
$$ select invoice_number, 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)
|
$$ values ('F20230006', 'Product 1', 'Description 1', 1224, 2, 0.00)
|
||||||
, ('F20230007', 7, 'Product 1 bis', 'Description 1 bis', 3333, 1, 0.50)
|
, ('F20230007', 'Product 1 bis', 'Description 1 bis', 3333, 1, 0.50)
|
||||||
, ('F20230007', 8, 'Product 2', 'Description 2', 2400, 3, 0.75)
|
, ('F20230007', 'Product 2', 'Description 2', 2400, 3, 0.75)
|
||||||
, ('INV056-23', 11, 'Product 4.3', '', 1111, 1, 0.0)
|
, ('INV056-23', 'Product 4.3', '', 1111, 1, 0.0)
|
||||||
|
, ('INV056-23', 'Product 4.4', 'Description 4.4', 2222, 3, 0.05)
|
||||||
$$,
|
$$,
|
||||||
'Should have created all invoice products'
|
'Should have created all invoice products'
|
||||||
);
|
);
|
||||||
|
|
||||||
select bag_eq(
|
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) $$,
|
$$ select invoice_number, product_id, name from invoice_product left join invoice_product_product using (invoice_product_id) join invoice using (invoice_id) $$,
|
||||||
$$ values ('F20230006', 7, 4, 0.21)
|
$$ values ('F20230006', 7, 'Product 1')
|
||||||
, ('F20230007', 7, 4, 0.21)
|
, ('F20230007', 7, 'Product 1 bis')
|
||||||
, ('F20230007', 7, 3, -0.15)
|
, ('F20230007', 8, 'Product 2')
|
||||||
, ('INV056-23', 11, 6, 0.10)
|
, ('INV056-23', 11, 'Product 4.3')
|
||||||
|
, ('INV056-23', NULL, 'Product 4.4')
|
||||||
|
$$,
|
||||||
|
'Should have linked all invoice products'
|
||||||
|
);
|
||||||
|
|
||||||
|
select bag_eq(
|
||||||
|
$$ select invoice_number, name, tax_id, tax_rate from invoice_product_tax join invoice_product using (invoice_product_id) join invoice using (invoice_id) $$,
|
||||||
|
$$ values ('F20230006', 'Product 1', 4, 0.21)
|
||||||
|
, ('F20230007', 'Product 1 bis', 4, 0.21)
|
||||||
|
, ('F20230007', 'Product 1 bis', 3, -0.15)
|
||||||
|
, ('INV056-23', 'Product 4.3', 6, 0.10)
|
||||||
$$,
|
$$,
|
||||||
'Should have created all invoice product taxes'
|
'Should have created all invoice product taxes'
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@ reset client_min_messages;
|
||||||
|
|
||||||
begin;
|
begin;
|
||||||
|
|
||||||
select plan(14);
|
select plan(15);
|
||||||
|
|
||||||
set search_path to auth, numerus, public;
|
set search_path to auth, numerus, public;
|
||||||
|
|
||||||
|
@ -71,11 +71,18 @@ values (15, 1, '7ac3ae0e-b0c1-4206-a19b-0be20835edd4', 'INV1', '2023-03-10', 12,
|
||||||
, (16, 1, 'b57b980b-247b-4be4-a0b7-03a7819c53ae', 'INV2', '2023-03-09', 13, 111, 'EUR', '{tag2}')
|
, (16, 1, 'b57b980b-247b-4be4-a0b7-03a7819c53ae', 'INV2', '2023-03-09', 13, 111, 'EUR', '{tag2}')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product (invoice_product_id, invoice_id, product_id, name, price)
|
insert into invoice_product (invoice_product_id, invoice_id, name, price)
|
||||||
values (19, 15, 7, 'P1.0', 1100)
|
values (19, 15, 'P1.0', 1100)
|
||||||
, (20, 15, 8, 'P2.0', 2200)
|
, (20, 15, 'P2.0', 2200)
|
||||||
, (21, 16, 7, 'P1.1', 1111)
|
, (21, 16, 'P1.1', 1111)
|
||||||
, (22, 16, 8, 'P2.1', 2211)
|
, (22, 16, 'P2.1', 2211)
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into invoice_product_product (invoice_product_id, product_id)
|
||||||
|
values (19, 7)
|
||||||
|
, (20, 8)
|
||||||
|
, (21, 7)
|
||||||
|
, (22, 8)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
@ -87,7 +94,7 @@ values (19, 4, 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
select lives_ok(
|
select lives_ok(
|
||||||
$$ select edit_invoice('7ac3ae0e-b0c1-4206-a19b-0be20835edd4', 'paid', 13, 'Notes 1', 112, array['tag1'], '{"(20,7,p1.0,D1,11.01,2,0.50,{4})"}') $$,
|
$$ select edit_invoice('7ac3ae0e-b0c1-4206-a19b-0be20835edd4', 'paid', 13, 'Notes 1', 112, array['tag1'], '{"(20,,p1.0,D1,11.01,2,0.50,{4})","(,,p1.3,D3,33.33,3,0.05,{3})"}') $$,
|
||||||
'Should be able to edit the first invoice'
|
'Should be able to edit the first invoice'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -105,22 +112,35 @@ select bag_eq(
|
||||||
);
|
);
|
||||||
|
|
||||||
select bag_eq(
|
select bag_eq(
|
||||||
$$ select invoice_number, product_id, name, description, price, quantity, discount_rate from invoice_product join invoice using (invoice_id) $$,
|
$$ select invoice_number, name, description, price, quantity, discount_rate from invoice_product join invoice using (invoice_id) $$,
|
||||||
$$ values ('INV1', 7, 'p1.0', 'D1', 1101, 2, 0.50)
|
$$ values ('INV1', 'p1.0', 'D1', 1101, 2, 0.50)
|
||||||
, ('INV2', 7, 'P1.1', '', 1111, 1, 0.00)
|
, ('INV1', 'p1.3', 'D3', 3333, 3, 0.05)
|
||||||
, ('INV2', 8, 'p2.1', 'D2', 2400, 3, 0.75)
|
, ('INV2', 'P1.1', '', 1111, 1, 0.00)
|
||||||
, ('INV2', 9, 'p3.3', '', 3636, 2, 0.05)
|
, ('INV2', 'p2.1', 'D2', 2400, 3, 0.75)
|
||||||
|
, ('INV2', 'p3.3', '', 3636, 2, 0.05)
|
||||||
$$,
|
$$,
|
||||||
'Should have updated all existing invoice products, added new ones, and removed the ones not give to the function'
|
'Should have updated all existing invoice products, added new ones, and removed the ones not give to the function'
|
||||||
);
|
);
|
||||||
|
|
||||||
select bag_eq(
|
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) $$,
|
$$ select invoice_number, product_id, name from invoice_product left join invoice_product_product using (invoice_product_id) join invoice using (invoice_id) $$,
|
||||||
$$ values ('INV1', 7, 4, 0.21)
|
$$ values ('INV1', NULL, 'p1.0')
|
||||||
, ('INV2', 7, 3, -0.15)
|
, ('INV1', NULL, 'p1.3')
|
||||||
, ('INV2', 8, 3, -0.15)
|
, ('INV2', 7, 'P1.1')
|
||||||
, ('INV2', 8, 4, 0.21)
|
, ('INV2', 8, 'p2.1')
|
||||||
, ('INV2', 9, 4, 0.21)
|
, ('INV2', 9, 'p3.3')
|
||||||
|
$$,
|
||||||
|
'Should have updated all existing invoice products id, added new ones, and removed the ones not give to the function'
|
||||||
|
);
|
||||||
|
|
||||||
|
select bag_eq(
|
||||||
|
$$ select invoice_number, name, tax_id, tax_rate from invoice_product_tax join invoice_product using (invoice_product_id) join invoice using (invoice_id) $$,
|
||||||
|
$$ values ('INV1', 'p1.0', 4, 0.21)
|
||||||
|
, ('INV1', 'p1.3', 3, -0.15)
|
||||||
|
, ('INV2', 'P1.1', 3, -0.15)
|
||||||
|
, ('INV2', 'p2.1', 3, -0.15)
|
||||||
|
, ('INV2', 'p2.1', 4, 0.21)
|
||||||
|
, ('INV2', 'p3.3', 4, 0.21)
|
||||||
$$,
|
$$,
|
||||||
'Should have updated all invoice product taxes, added new ones, and removed the ones not given to the function'
|
'Should have updated all invoice product taxes, added new ones, and removed the ones not given to the function'
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,7 +30,6 @@ truncate invoice_product_tax cascade;
|
||||||
truncate invoice_product cascade;
|
truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
truncate tax_class cascade;
|
truncate tax_class cascade;
|
||||||
truncate payment_method cascade;
|
truncate payment_method cascade;
|
||||||
|
@ -60,10 +59,6 @@ values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
, (5, 1, 11, 'IVA 21 %', 0.21)
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
|
||||||
values (6, 1, 'Product', 1212)
|
|
||||||
;
|
|
||||||
|
|
||||||
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
||||||
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
||||||
;
|
;
|
||||||
|
@ -75,14 +70,14 @@ values ( 8, 1, 'I1', current_date, 7, 'EUR', '111')
|
||||||
, (11, 1, 'I4', current_date, 7, 'EUR', '111')
|
, (11, 1, 'I4', current_date, 7, 'EUR', '111')
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product (invoice_product_id, invoice_id, product_id, name, price, quantity, discount_rate)
|
insert into invoice_product (invoice_product_id, invoice_id, name, price, quantity, discount_rate)
|
||||||
values (12, 8, 6, 'P', 100, 1, 0.0)
|
values (12, 8, 'P', 100, 1, 0.0)
|
||||||
, (13, 8, 6, 'P', 200, 2, 0.1)
|
, (13, 8, 'P', 200, 2, 0.1)
|
||||||
, (14, 9, 6, 'P', 222, 3, 0.0)
|
, (14, 9, 'P', 222, 3, 0.0)
|
||||||
, (15, 9, 6, 'P', 333, 4, 0.2)
|
, (15, 9, 'P', 333, 4, 0.2)
|
||||||
, (16, 10, 6, 'P', 444, 5, 0.0)
|
, (16, 10, 'P', 444, 5, 0.0)
|
||||||
, (17, 10, 6, 'P', 555, 6, 0.1)
|
, (17, 10, 'P', 555, 6, 0.1)
|
||||||
, (18, 11, 6, 'P', 777, 8, 0.0)
|
, (18, 11, 'P', 777, 8, 0.0)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
|
|
@ -5,7 +5,7 @@ reset client_min_messages;
|
||||||
|
|
||||||
begin;
|
begin;
|
||||||
|
|
||||||
select plan(57);
|
select plan(51);
|
||||||
|
|
||||||
set search_path to numerus, auth, public;
|
set search_path to numerus, auth, public;
|
||||||
|
|
||||||
|
@ -36,13 +36,6 @@ select col_type_is('invoice_product', 'invoice_id', 'integer');
|
||||||
select col_not_null('invoice_product', 'invoice_id');
|
select col_not_null('invoice_product', 'invoice_id');
|
||||||
select col_hasnt_default('invoice_product', 'invoice_id');
|
select col_hasnt_default('invoice_product', 'invoice_id');
|
||||||
|
|
||||||
select has_column('invoice_product', 'product_id');
|
|
||||||
select col_is_fk('invoice_product', 'product_id');
|
|
||||||
select fk_ok('invoice_product', 'product_id', 'product', 'product_id');
|
|
||||||
select col_type_is('invoice_product', 'product_id', 'integer');
|
|
||||||
select col_not_null('invoice_product', 'product_id');
|
|
||||||
select col_hasnt_default('invoice_product', 'product_id');
|
|
||||||
|
|
||||||
select has_column('invoice_product', 'name');
|
select has_column('invoice_product', 'name');
|
||||||
select col_type_is('invoice_product', 'name', 'text');
|
select col_type_is('invoice_product', 'name', 'text');
|
||||||
select col_not_null('invoice_product', 'name');
|
select col_not_null('invoice_product', 'name');
|
||||||
|
@ -75,7 +68,6 @@ select col_default_is('invoice_product', 'discount_rate', '0.0');
|
||||||
set client_min_messages to warning;
|
set client_min_messages to warning;
|
||||||
truncate invoice_product cascade;
|
truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate product cascade;
|
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate company_user cascade;
|
truncate company_user cascade;
|
||||||
truncate payment_method cascade;
|
truncate payment_method cascade;
|
||||||
|
@ -117,21 +109,16 @@ values (10, 2, 'INV020001', 6, 'EUR', 222)
|
||||||
, (12, 4, 'INV040001', 8, 'EUR', 444)
|
, (12, 4, 'INV040001', 8, 'EUR', 444)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, description, price)
|
insert into invoice_product (invoice_id, name, description, price, quantity)
|
||||||
values (14, 2, 'Product 1', 'Description 1', 1200)
|
values (10, 'product 1', 'description 1', 1212, 1)
|
||||||
, (16, 4, 'Product 2', 'Description 2', 2400)
|
, (12, 'product 2', 'description 2', 2424, 2)
|
||||||
;
|
|
||||||
|
|
||||||
insert into invoice_product (invoice_id, product_id, name, description, price, quantity)
|
|
||||||
values (10, 14, 'product 1', 'description 1', 1212, 1)
|
|
||||||
, (12, 16, 'product 2', 'description 2', 2424, 2)
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
prepare invoice_product_data as
|
prepare invoice_product_data as
|
||||||
select invoice_id, product_id, name, price, quantity
|
select invoice_id, name, price, quantity
|
||||||
from invoice_product
|
from invoice_product
|
||||||
order by invoice_id, product_id;
|
order by invoice_id;
|
||||||
|
|
||||||
set role invoicer;
|
set role invoicer;
|
||||||
select is_empty('invoice_product_data', 'Should show no data when cookie is not set yet');
|
select is_empty('invoice_product_data', 'Should show no data when cookie is not set yet');
|
||||||
|
@ -140,7 +127,7 @@ reset role;
|
||||||
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog');
|
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog');
|
||||||
select bag_eq(
|
select bag_eq(
|
||||||
'invoice_product_data',
|
'invoice_product_data',
|
||||||
$$ values (10, 14, 'product 1', 1212, 1)
|
$$ values (10, 'product 1', 1212, 1)
|
||||||
$$,
|
$$,
|
||||||
'Should only list products of invoices of the companies where demo@tandem.blog is user of'
|
'Should only list products of invoices of the companies where demo@tandem.blog is user of'
|
||||||
);
|
);
|
||||||
|
@ -149,7 +136,7 @@ reset role;
|
||||||
select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog');
|
select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog');
|
||||||
select bag_eq(
|
select bag_eq(
|
||||||
'invoice_product_data',
|
'invoice_product_data',
|
||||||
$$ values (12, 16, 'product 2', 2424, 2)
|
$$ values (12, 'product 2', 2424, 2)
|
||||||
$$,
|
$$,
|
||||||
'Should only list products of invoices of the companies where admin@tandem.blog is user of'
|
'Should only list products of invoices of the companies where admin@tandem.blog is user of'
|
||||||
);
|
);
|
||||||
|
@ -165,8 +152,8 @@ reset role;
|
||||||
|
|
||||||
|
|
||||||
select throws_ok( $$
|
select throws_ok( $$
|
||||||
insert into invoice_product (invoice_id, product_id, name, description, price, quantity)
|
insert into invoice_product (invoice_id, name, description, price, quantity)
|
||||||
values (10, 14, ' ', '', 1212, 1)
|
values (10, ' ', '', 1212, 1)
|
||||||
$$,
|
$$,
|
||||||
'23514', 'new row for relation "invoice_product" violates check constraint "name_not_empty"',
|
'23514', 'new row for relation "invoice_product" violates check constraint "name_not_empty"',
|
||||||
'Should not allow invoice products with blank name'
|
'Should not allow invoice products with blank name'
|
||||||
|
|
|
@ -30,7 +30,6 @@ truncate invoice_product_tax cascade;
|
||||||
truncate invoice_product cascade;
|
truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
truncate tax_class cascade;
|
truncate tax_class cascade;
|
||||||
truncate payment_method cascade;
|
truncate payment_method cascade;
|
||||||
|
@ -60,10 +59,6 @@ values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
, (5, 1, 11, 'IVA 21 %', 0.21)
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
|
||||||
values (6, 1, 'Product', 1212)
|
|
||||||
;
|
|
||||||
|
|
||||||
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
||||||
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
||||||
;
|
;
|
||||||
|
@ -75,14 +70,14 @@ values ( 8, 1, 'I1', current_date, 7, 'EUR', 111)
|
||||||
, (11, 1, 'I4', current_date, 7, 'EUR', 111)
|
, (11, 1, 'I4', current_date, 7, 'EUR', 111)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product (invoice_product_id, invoice_id, product_id, name, price, quantity, discount_rate)
|
insert into invoice_product (invoice_product_id, invoice_id, name, price, quantity, discount_rate)
|
||||||
values (12, 8, 6, 'P', 100, 1, 0.0)
|
values (12, 8, 'P', 100, 1, 0.0)
|
||||||
, (13, 8, 6, 'P', 200, 2, 0.1)
|
, (13, 8, 'P', 200, 2, 0.1)
|
||||||
, (14, 9, 6, 'P', 222, 3, 0.0)
|
, (14, 9, 'P', 222, 3, 0.0)
|
||||||
, (15, 9, 6, 'P', 333, 4, 0.2)
|
, (15, 9, 'P', 333, 4, 0.2)
|
||||||
, (16, 10, 6, 'P', 444, 5, 0.0)
|
, (16, 10, 'P', 444, 5, 0.0)
|
||||||
, (17, 10, 6, 'P', 555, 6, 0.1)
|
, (17, 10, 'P', 555, 6, 0.1)
|
||||||
, (18, 11, 6, 'P', 777, 8, 0.0)
|
, (18, 11, 'P', 777, 8, 0.0)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
-- Test invoice_product_product
|
||||||
|
set client_min_messages to warning;
|
||||||
|
create extension if not exists pgtap;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select plan(19);
|
||||||
|
|
||||||
|
set search_path to numerus, public;
|
||||||
|
|
||||||
|
select has_table('invoice_product_product');
|
||||||
|
select has_pk('invoice_product_product' );
|
||||||
|
select table_privs_are('invoice_product_product', 'guest', array []::text[]);
|
||||||
|
select table_privs_are('invoice_product_product', 'invoicer', array ['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||||
|
select table_privs_are('invoice_product_product', 'admin', array ['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||||
|
select table_privs_are('invoice_product_product', 'authenticator', array []::text[]);
|
||||||
|
|
||||||
|
select has_column('invoice_product_product', 'invoice_product_id');
|
||||||
|
select col_is_pk('invoice_product_product', 'invoice_product_id');
|
||||||
|
select col_is_fk('invoice_product_product', 'invoice_product_id');
|
||||||
|
select fk_ok('invoice_product_product', 'invoice_product_id', 'invoice_product', 'invoice_product_id');
|
||||||
|
select col_type_is('invoice_product_product', 'invoice_product_id', 'integer');
|
||||||
|
select col_not_null('invoice_product_product', 'invoice_product_id');
|
||||||
|
select col_hasnt_default('invoice_product_product', 'invoice_product_id');
|
||||||
|
|
||||||
|
select has_column('invoice_product_product', 'product_id');
|
||||||
|
select col_is_fk('invoice_product_product', 'product_id');
|
||||||
|
select fk_ok('invoice_product_product', 'product_id', 'product', 'product_id');
|
||||||
|
select col_type_is('invoice_product_product', 'product_id', 'integer');
|
||||||
|
select col_not_null('invoice_product_product', 'product_id');
|
||||||
|
select col_hasnt_default('invoice_product_product', 'product_id');
|
||||||
|
|
||||||
|
|
||||||
|
select *
|
||||||
|
from finish();
|
||||||
|
|
||||||
|
rollback;
|
||||||
|
|
|
@ -41,7 +41,6 @@ set client_min_messages to warning;
|
||||||
truncate invoice_product_tax cascade;
|
truncate invoice_product_tax cascade;
|
||||||
truncate invoice_product cascade;
|
truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate product cascade;
|
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
truncate tax_class cascade;
|
truncate tax_class cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
|
@ -85,11 +84,6 @@ values (3, 2, 22, 'IVA 21 %', 0.21)
|
||||||
, (6, 4, 44, 'IVA 10 %', 0.10)
|
, (6, 4, 44, 'IVA 10 %', 0.10)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
|
||||||
values (7, 2, 'Product 1', 1200)
|
|
||||||
, (8, 4, 'Product 2', 2400)
|
|
||||||
;
|
|
||||||
|
|
||||||
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
||||||
values ( 9, 2, 'Customer 1', 'XX555', '', '777-777-777', 'c1@e', '', '', '', '', '', 'ES')
|
values ( 9, 2, 'Customer 1', 'XX555', '', '777-777-777', 'c1@e', '', '', '', '', '', 'ES')
|
||||||
, (10, 4, 'Customer 2', 'XX666', '', '888-888-888', 'c2@e', '', '', '', '', '', 'ES')
|
, (10, 4, 'Customer 2', 'XX666', '', '888-888-888', 'c2@e', '', '', '', '', '', 'ES')
|
||||||
|
@ -100,9 +94,9 @@ values (11, 2, 'INV001', 9, 'EUR', 222)
|
||||||
, (12, 4, 'INV002', 10, 'EUR', 444)
|
, (12, 4, 'INV002', 10, 'EUR', 444)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product (invoice_product_id, invoice_id, product_id, name, price)
|
insert into invoice_product (invoice_product_id, invoice_id, name, price)
|
||||||
values (13, 11, 7, 'Product 1', 1200)
|
values (13, 11, 'Product 1', 1200)
|
||||||
, (14, 12, 8, 'Product 2', 2400)
|
, (14, 12, 'Product 2', 2400)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
|
|
@ -30,7 +30,6 @@ truncate invoice_product_tax cascade;
|
||||||
truncate invoice_product cascade;
|
truncate invoice_product cascade;
|
||||||
truncate invoice cascade;
|
truncate invoice cascade;
|
||||||
truncate contact cascade;
|
truncate contact cascade;
|
||||||
truncate product cascade;
|
|
||||||
truncate tax cascade;
|
truncate tax cascade;
|
||||||
truncate tax_class cascade;
|
truncate tax_class cascade;
|
||||||
truncate payment_method cascade;
|
truncate payment_method cascade;
|
||||||
|
@ -60,10 +59,6 @@ values (2, 1, 11, 'IRPF -15 %', -0.15)
|
||||||
, (5, 1, 11, 'IVA 21 %', 0.21)
|
, (5, 1, 11, 'IVA 21 %', 0.21)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into product (product_id, company_id, name, price)
|
|
||||||
values (6, 1, 'Product', 1212)
|
|
||||||
;
|
|
||||||
|
|
||||||
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
insert into contact (contact_id, company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code)
|
||||||
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
values (7, 1, 'Contact', 'XX555', '', '777-777-777', 'c@c', '', '', '', '', '', 'ES')
|
||||||
;
|
;
|
||||||
|
@ -75,14 +70,14 @@ values ( 8, 1, 'I1', current_date, 7, 'EUR', 111)
|
||||||
, (11, 1, 'I4', current_date, 7, 'EUR', 111)
|
, (11, 1, 'I4', current_date, 7, 'EUR', 111)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product (invoice_product_id, invoice_id, product_id, name, price, quantity, discount_rate)
|
insert into invoice_product (invoice_product_id, invoice_id, name, price, quantity, discount_rate)
|
||||||
values (12, 8, 6, 'P', 100, 1, 0.0)
|
values (12, 8, 'P', 100, 1, 0.0)
|
||||||
, (13, 8, 6, 'P', 200, 2, 0.1)
|
, (13, 8, 'P', 200, 2, 0.1)
|
||||||
, (14, 9, 6, 'P', 222, 3, 0.0)
|
, (14, 9, 'P', 222, 3, 0.0)
|
||||||
, (15, 9, 6, 'P', 333, 4, 0.2)
|
, (15, 9, 'P', 333, 4, 0.2)
|
||||||
, (16, 10, 6, 'P', 444, 5, 0.0)
|
, (16, 10, 'P', 444, 5, 0.0)
|
||||||
, (17, 10, 6, 'P', 555, 6, 0.1)
|
, (17, 10, 'P', 555, 6, 0.1)
|
||||||
, (18, 11, 6, 'P', 777, 8, 0.0)
|
, (18, 11, 'P', 777, 8, 0.0)
|
||||||
;
|
;
|
||||||
|
|
||||||
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
||||||
|
|
|
@ -4,7 +4,6 @@ begin;
|
||||||
|
|
||||||
select invoice_product_id
|
select invoice_product_id
|
||||||
, invoice_id
|
, invoice_id
|
||||||
, product_id
|
|
||||||
, name
|
, name
|
||||||
, description
|
, description
|
||||||
, price
|
, price
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
-- Verify numerus:invoice_product_product on pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select invoice_product_id
|
||||||
|
, product_id
|
||||||
|
from numerus.invoice_product_product
|
||||||
|
where false;
|
||||||
|
|
||||||
|
rollback;
|
Loading…
Reference in New Issue