155 lines
3.9 KiB
TypeScript
155 lines
3.9 KiB
TypeScript
import { Migration } from '@mikro-orm/migrations';
|
|
|
|
export class Migration20260626140000 extends Migration {
|
|
|
|
override async up(): Promise<void> {
|
|
|
|
this.addSql(`
|
|
CREATE OR REPLACE FUNCTION recalc_invoice_totals()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
v_invoice_id char(26);
|
|
v_subtotal int;
|
|
v_discount int;
|
|
v_tax int;
|
|
v_total int;
|
|
v_paid int;
|
|
v_enable_tax boolean;
|
|
v_confirm_status text;
|
|
BEGIN
|
|
|
|
v_invoice_id := COALESCE(NEW.invoice_id, OLD.invoice_id);
|
|
|
|
SELECT
|
|
COALESCE(SUM(sub_total),0),
|
|
COALESCE(SUM(discount),0)
|
|
INTO
|
|
v_subtotal,
|
|
v_discount
|
|
FROM invoice_items
|
|
WHERE invoice_id = v_invoice_id
|
|
AND deleted_at IS NULL;
|
|
|
|
SELECT enable_tax
|
|
INTO v_enable_tax
|
|
FROM invoices
|
|
WHERE id = v_invoice_id;
|
|
|
|
IF v_enable_tax THEN
|
|
v_tax := (v_subtotal - v_discount) * 0.10;
|
|
ELSE
|
|
v_tax := 0;
|
|
END IF;
|
|
|
|
v_total := (v_subtotal - v_discount) + v_tax;
|
|
|
|
SELECT COALESCE(SUM(amount),0)::int
|
|
INTO v_paid
|
|
FROM payments
|
|
WHERE invoice_id = v_invoice_id
|
|
AND status = 'paid'
|
|
AND deleted_at IS NULL;
|
|
|
|
SELECT CASE
|
|
WHEN NOT EXISTS (
|
|
SELECT 1
|
|
FROM invoice_items
|
|
WHERE invoice_id = v_invoice_id
|
|
AND deleted_at IS NULL
|
|
AND confirmed_at IS NOT NULL
|
|
) THEN 'pending'
|
|
WHEN NOT EXISTS (
|
|
SELECT 1
|
|
FROM invoice_items
|
|
WHERE invoice_id = v_invoice_id
|
|
AND deleted_at IS NULL
|
|
AND confirmed_at IS NULL
|
|
) THEN 'confirmed'
|
|
ELSE 'partially_confirmed'
|
|
END
|
|
INTO v_confirm_status;
|
|
|
|
UPDATE invoices
|
|
SET
|
|
sub_total = v_subtotal,
|
|
discount = v_discount,
|
|
tax_amount = v_tax,
|
|
total = v_total,
|
|
paid_amount = v_paid,
|
|
balance = v_total - v_paid,
|
|
confirm_status = v_confirm_status
|
|
WHERE id = v_invoice_id;
|
|
|
|
RETURN NULL;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
`);
|
|
|
|
this.addSql(`
|
|
CREATE OR REPLACE FUNCTION recalc_invoice_payments()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
v_invoice_id char(26);
|
|
v_paid int;
|
|
v_total int;
|
|
BEGIN
|
|
|
|
v_invoice_id := COALESCE(NEW.invoice_id, OLD.invoice_id);
|
|
|
|
SELECT COALESCE(SUM(amount),0)::int
|
|
INTO v_paid
|
|
FROM payments
|
|
WHERE invoice_id = v_invoice_id
|
|
AND status = 'paid'
|
|
AND deleted_at IS NULL;
|
|
|
|
SELECT total
|
|
INTO v_total
|
|
FROM invoices
|
|
WHERE id = v_invoice_id;
|
|
|
|
UPDATE invoices
|
|
SET
|
|
paid_amount = v_paid,
|
|
balance = v_total - v_paid
|
|
WHERE id = v_invoice_id;
|
|
|
|
RETURN NULL;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
`);
|
|
|
|
this.addSql(`DROP TRIGGER IF EXISTS trg_invoice_items_recalc ON invoice_items;`);
|
|
this.addSql(`
|
|
CREATE TRIGGER trg_invoice_items_recalc
|
|
AFTER INSERT OR UPDATE OR DELETE
|
|
ON invoice_items
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION recalc_invoice_totals();
|
|
`);
|
|
|
|
this.addSql(`DROP TRIGGER IF EXISTS trg_payments_recalc ON payments;`);
|
|
this.addSql(`
|
|
CREATE TRIGGER trg_payments_recalc
|
|
AFTER INSERT OR UPDATE OR DELETE
|
|
ON payments
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION recalc_invoice_payments();
|
|
`);
|
|
|
|
this.addSql(`
|
|
UPDATE invoice_items
|
|
SET quantity = quantity
|
|
WHERE deleted_at IS NULL;
|
|
`);
|
|
}
|
|
|
|
override async down(): Promise<void> {
|
|
this.addSql(`DROP TRIGGER IF EXISTS trg_invoice_items_recalc ON invoice_items;`);
|
|
this.addSql(`DROP TRIGGER IF EXISTS trg_payments_recalc ON payments;`);
|
|
this.addSql(`DROP FUNCTION IF EXISTS recalc_invoice_totals();`);
|
|
this.addSql(`DROP FUNCTION IF EXISTS recalc_invoice_payments();`);
|
|
}
|
|
|
|
}
|