From 0f7440419290c2bdc48dc3a0f09ebc56a946766e Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Sun, 24 May 2026 13:03:56 +0330 Subject: [PATCH] fix paid amount bug --- .../migrations/Migration20260404083020.ts | 6 +- .../migrations/Migration20260524120000.ts | 173 ++++++++++++++++++ 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 database/migrations/Migration20260524120000.ts diff --git a/database/migrations/Migration20260404083020.ts b/database/migrations/Migration20260404083020.ts index 0850877..40a08ad 100644 --- a/database/migrations/Migration20260404083020.ts +++ b/database/migrations/Migration20260404083020.ts @@ -46,7 +46,8 @@ export class Migration20260404083020 extends Migration { INTO v_paid FROM payments WHERE invoice_id = v_invoice_id - AND status = 'SUCCESS'; + AND status = 'paid' + AND deleted_at IS NULL; UPDATE invoices SET @@ -88,7 +89,8 @@ export class Migration20260404083020 extends Migration { INTO v_paid FROM payments WHERE invoice_id = v_invoice_id - AND status = 'paid'; + AND status = 'paid' + AND deleted_at IS NULL; SELECT total INTO v_total diff --git a/database/migrations/Migration20260524120000.ts b/database/migrations/Migration20260524120000.ts new file mode 100644 index 0000000..8f8e1e6 --- /dev/null +++ b/database/migrations/Migration20260524120000.ts @@ -0,0 +1,173 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20260524120000 extends Migration { + + override async up(): Promise { + 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)::int + INTO v_paid + FROM payments + WHERE invoice_id = v_invoice_id + AND status = 'paid' + AND deleted_at IS NULL; + + 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; + `); + + 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(` + UPDATE invoices i + SET + paid_amount = COALESCE(p.paid_sum, 0), + balance = i.total - COALESCE(p.paid_sum, 0) + FROM ( + SELECT invoice_id, SUM(amount)::int AS paid_sum + FROM payments + WHERE status = 'paid' + AND deleted_at IS NULL + GROUP BY invoice_id + ) p + WHERE i.id = p.invoice_id; + `); + } + + override async down(): Promise { + // Restore previous (broken) function bodies from Migration20260404083020 + 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; + `); + + 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 = 'SUCCESS'; + 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; + `); + } + +}