Files
negareh-api/database/migrations/Migration20260404083020.ts
T
2026-04-04 15:24:29 +03:30

150 lines
3.5 KiB
TypeScript

import { Migration } from '@mikro-orm/migrations';
export class Migration20260404083020 extends Migration {
override async up(): Promise<void> {
//recalc_invoice_totals
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;
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)
INTO v_paid
FROM payments
WHERE invoice_id = v_invoice_id
AND status = 'SUCCESS';
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
WHERE id = v_invoice_id;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
`);
// trigger
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();
`);
// recalc_invoice_payments
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)
INTO v_paid
FROM payments
WHERE invoice_id = v_invoice_id
AND status = 'paid';
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;
`);
// trigger
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(`CREATE SEQUENCE invoice_number_seq START 1;`);
this.addSql(`
ALTER TABLE invoices
ALTER COLUMN invoice_number
SET DEFAULT nextval('invoice_number_seq');
`);
}
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;`);
// remove default from invoice_number
this.addSql(`
ALTER TABLE invoices
ALTER COLUMN invoice_number
DROP DEFAULT;
`);
// drop sequence
this.addSql(`DROP SEQUENCE IF EXISTS invoice_number_seq;`);
}
}