Remove status parameter from edit_expense and forms
For the same reasons as with expenses[0], users are no longer expected
to manually set invoice status, and is now linked to their collections.
In this case, however, we had to remove the ‘sent’ and ‘unpaid’ status
options, because these _should_ only be set manually, as there is no
way for the application to know when to set them. Thus, there could
be inconsistencies, like invoices set to ‘unpaid’ when they actually
have collections, or invoices that were ‘sent’, then transitioned to
‘partial’/‘paid’ due to a collection, but then reset to ‘created’ if the
collection was deleted.
[0]: ac0143b2b0b772e155ef8525e147786700403578
2024-08-26 08:42:38 +00:00
|
|
|
-- Deploy numerus:edit_invoice to pg
|
|
|
|
-- requires: schema_numerus
|
|
|
|
-- requires: invoice
|
|
|
|
-- requires: currency
|
|
|
|
-- requires: parse_price
|
|
|
|
-- requires: edited_invoice_product
|
|
|
|
-- requires: tax
|
|
|
|
-- requires: invoice_product
|
|
|
|
-- requires: invoice_product_product
|
|
|
|
-- requires: invoice_product_tax
|
|
|
|
-- requires: tag_name
|
2023-03-11 19:58:20 +00:00
|
|
|
|
|
|
|
begin;
|
|
|
|
|
Remove status parameter from edit_expense and forms
For the same reasons as with expenses[0], users are no longer expected
to manually set invoice status, and is now linked to their collections.
In this case, however, we had to remove the ‘sent’ and ‘unpaid’ status
options, because these _should_ only be set manually, as there is no
way for the application to know when to set them. Thus, there could
be inconsistencies, like invoices set to ‘unpaid’ when they actually
have collections, or invoices that were ‘sent’, then transitioned to
‘partial’/‘paid’ due to a collection, but then reset to ‘created’ if the
collection was deleted.
[0]: ac0143b2b0b772e155ef8525e147786700403578
2024-08-26 08:42:38 +00:00
|
|
|
set search_path to numerus, public;
|
|
|
|
|
|
|
|
drop function if exists edit_invoice(uuid, integer, text, integer, tag_name[], edited_invoice_product[]);
|
|
|
|
|
|
|
|
create or replace function edit_invoice(invoice_slug uuid, invoice_status text, contact_id integer, notes text, payment_method_id integer, tags tag_name[], products edited_invoice_product[]) returns uuid as
|
|
|
|
$$
|
|
|
|
declare
|
|
|
|
iid integer;
|
|
|
|
products_to_keep integer[];
|
|
|
|
products_to_delete integer[];
|
|
|
|
company integer;
|
|
|
|
ccode text;
|
|
|
|
product edited_invoice_product;
|
|
|
|
ipid integer;
|
|
|
|
begin
|
|
|
|
update invoice
|
|
|
|
set contact_id = edit_invoice.contact_id
|
|
|
|
, invoice_status = edit_invoice.invoice_status
|
|
|
|
, notes = edit_invoice.notes
|
|
|
|
, payment_method_id = edit_invoice.payment_method_id
|
|
|
|
, tags = edit_invoice.tags
|
|
|
|
where slug = invoice_slug
|
|
|
|
returning invoice_id, company_id, currency_code
|
|
|
|
into iid, company, ccode
|
|
|
|
;
|
|
|
|
|
|
|
|
if iid is null then
|
|
|
|
return null;
|
|
|
|
end if;
|
|
|
|
|
|
|
|
foreach product in array products
|
|
|
|
loop
|
|
|
|
if product.invoice_product_id is null then
|
|
|
|
insert into invoice_product (invoice_id, name, description, price, quantity, discount_rate)
|
|
|
|
select iid
|
|
|
|
, product.name
|
|
|
|
, coalesce(product.description, '')
|
|
|
|
, parse_price(product.price, currency.decimal_digits)
|
|
|
|
, product.quantity
|
|
|
|
, product.discount_rate
|
|
|
|
from currency
|
|
|
|
where currency_code = ccode
|
|
|
|
returning invoice_product_id
|
|
|
|
into ipid;
|
|
|
|
else
|
|
|
|
ipid := product.invoice_product_id;
|
|
|
|
|
|
|
|
update invoice_product
|
|
|
|
set name = product.name
|
|
|
|
, description = coalesce(product.description, '')
|
|
|
|
, price = parse_price(product.price, currency.decimal_digits)
|
|
|
|
, quantity = product.quantity
|
|
|
|
, discount_rate = product.discount_rate
|
|
|
|
from currency
|
|
|
|
where invoice_product_id = ipid
|
|
|
|
and currency_code = ccode;
|
|
|
|
end if;
|
|
|
|
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;
|
|
|
|
|
|
|
|
insert into invoice_product_tax (invoice_product_id, tax_id, tax_rate)
|
|
|
|
select ipid, tax_id, tax.rate
|
|
|
|
from tax
|
|
|
|
join unnest(product.tax) as ptax(tax_id) using (tax_id);
|
|
|
|
end loop;
|
|
|
|
|
|
|
|
select array_agg(invoice_product_id)
|
|
|
|
into products_to_delete
|
|
|
|
from invoice_product
|
|
|
|
where invoice_id = iid
|
|
|
|
and not (invoice_product_id = any(products_to_keep));
|
|
|
|
|
|
|
|
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_product where invoice_product_id = any(products_to_delete);
|
|
|
|
delete from invoice_product where invoice_product_id = any(products_to_delete);
|
|
|
|
end if;
|
|
|
|
|
|
|
|
return invoice_slug;
|
|
|
|
end;
|
|
|
|
$$
|
|
|
|
language plpgsql;
|
|
|
|
|
|
|
|
revoke execute on function edit_invoice(uuid, text, integer, text, integer, tag_name[], edited_invoice_product[]) from public;
|
|
|
|
grant execute on function edit_invoice(uuid, text, integer, text, integer, tag_name[], edited_invoice_product[]) to invoicer;
|
|
|
|
grant execute on function edit_invoice(uuid, text, integer, text, integer, tag_name[], edited_invoice_product[]) to admin;
|
|
|
|
|
2023-03-11 19:58:20 +00:00
|
|
|
|
|
|
|
commit;
|