From cf1ad968ca117a909bc4808f70a74dfa4f532edb Mon Sep 17 00:00:00 2001 From: Sidney Date: Fri, 15 May 2026 08:16:20 -0300 Subject: [PATCH] Fix: restore and force amount recovery bugfix to run even for JSON values, preventing the Portal UI from double-discounting corrupted historical payments --- manager/scratch/check_json.js | 6 ++++++ portal/server.js | 10 ++++++++-- portal/server.selfhosted.js | 10 ++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 manager/scratch/check_json.js diff --git a/manager/scratch/check_json.js b/manager/scratch/check_json.js new file mode 100644 index 0000000..7efb194 --- /dev/null +++ b/manager/scratch/check_json.js @@ -0,0 +1,6 @@ +import { pool } from '../services/database.js'; +pool.query("SELECT data FROM app_state WHERE id = 'school_data'").then(r => { + const p = r.rows[0].data.payments.find(p => p.asaasPaymentId === 'pay_iipssljwa9df3fsq'); + console.log('JSON AMOUNT:', p.amount, 'JSON DISCOUNT:', p.discount); + process.exit(0); +}).catch(e => console.error(e)); diff --git a/portal/server.js b/portal/server.js index 27d23d2..775bc53 100644 --- a/portal/server.js +++ b/portal/server.js @@ -288,11 +288,17 @@ app.get('/api/portal/financeiro', authMiddleware, async (req, res) => { } } - // [ATENÇÃO]: Priorizando o JSON (jsonP) sobre o banco (db) para igualar o comportamento do Manager. - // O Manager lê exclusivamente de school_data.payments, garantindo os valores corretos. + // [Bugfix Crítico]: O webhook do Asaas sobrescreveu o JSON e o banco com o valor LÍQUIDO. + // Ou seja, jsonP.amount e db.valor estão iguais (ex: 150), mas o correto é 170. + // Se detectarmos essa corrupção (amountOriginal == db.valor) e houver desconto, restauramos o valor bruto. let amountOriginal = jsonP.amount !== undefined ? Number(jsonP.amount) : (Number(db.amount_original) || Number(db.valor) || 0); const discount = jsonP.discount !== undefined ? Number(jsonP.discount) : (Number(db.discount) || 0); + // Aplica a recuperação matemática INDEPENDENTE de onde veio (SQL ou JSON) + if (amountOriginal > 0 && amountOriginal === Number(db.valor) && discount > 0) { + amountOriginal += discount; + } + finalPayments.push({ id: jsonP.id || asaasId, studentId: req.user.studentId, diff --git a/portal/server.selfhosted.js b/portal/server.selfhosted.js index d267921..6625335 100644 --- a/portal/server.selfhosted.js +++ b/portal/server.selfhosted.js @@ -278,11 +278,17 @@ app.get('/api/portal/financeiro', authMiddleware, async (req, res) => { } } - // [ATENÇÃO]: Priorizando o JSON (jsonP) sobre o banco (db) para igualar o comportamento do Manager. - // O Manager lê exclusivamente de school_data.payments, garantindo os valores corretos. + // [Bugfix Crítico]: O webhook do Asaas sobrescreveu o JSON e o banco com o valor LÍQUIDO. + // Ou seja, jsonP.amount e db.valor estão iguais (ex: 150), mas o correto é 170. + // Se detectarmos essa corrupção (amountOriginal == db.valor) e houver desconto, restauramos o valor bruto. let amountOriginal = jsonP.amount !== undefined ? Number(jsonP.amount) : (Number(db.amount_original) || Number(db.valor) || 0); const discount = jsonP.discount !== undefined ? Number(jsonP.discount) : (Number(db.discount) || 0); + // Aplica a recuperação matemática INDEPENDENTE de onde veio (SQL ou JSON) + if (amountOriginal > 0 && amountOriginal === Number(db.valor) && discount > 0) { + amountOriginal += discount; + } + finalPayments.push({ id: jsonP.id || asaasId, studentId: req.user.studentId,