From 2b212b933e2fc8a7149ee7498799b3ce32cd9c3d Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Mon, 6 Apr 2026 14:49:30 +0000 Subject: [PATCH] fix(anaf): show TVA badge only on GoMag vs ANAF mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the TVA badge/dot appeared whenever ANAF reported neplatitor. Now it only appears when GoMag CUI prefix (RO=platitor) disagrees with ANAF status — aligned across JS badges, red dots, SQL filter and count. Co-Authored-By: Claude Opus 4.5 --- api/app/services/sqlite_service.py | 14 +++++++++++--- api/app/static/js/dashboard.js | 4 ++-- api/app/static/js/shared.js | 6 +++++- api/app/templates/base.html | 2 +- api/app/templates/dashboard.html | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/api/app/services/sqlite_service.py b/api/app/services/sqlite_service.py index 37573ea..756296a 100644 --- a/api/app/services/sqlite_service.py +++ b/api/app/services/sqlite_service.py @@ -697,7 +697,12 @@ async def get_orders(page: int = 1, per_page: int = 50, if status_filter.upper() == "IMPORTED": data_clauses.append("UPPER(status) IN ('IMPORTED', 'ALREADY_IMPORTED')") elif status_filter.upper() == "DIFFS": - data_clauses.append("(anaf_cod_fiscal_adjusted = 1 OR anaf_denumire_mismatch = 1 OR address_mismatch = 1)") + data_clauses.append( + "(anaf_cod_fiscal_adjusted = 1 OR anaf_denumire_mismatch = 1 OR address_mismatch = 1" + " OR (cod_fiscal_gomag IS NOT NULL AND cod_fiscal_gomag != '' AND anaf_platitor_tva IS NOT NULL" + " AND ((UPPER(cod_fiscal_gomag) LIKE 'RO%' AND anaf_platitor_tva = 0)" + " OR (UPPER(cod_fiscal_gomag) NOT LIKE 'RO%' AND anaf_platitor_tva = 1))))" + ) else: data_clauses.append("UPPER(status) = ?") data_params.append(status_filter.upper()) @@ -751,9 +756,12 @@ async def get_orders(page: int = 1, per_page: int = 50, cursor = await db.execute(f"SELECT COUNT(*) FROM orders {uninv_old_where}", base_params) uninvoiced_old = (await cursor.fetchone())[0] - # Diffs count: orders with ANAF adjustments or address mismatches + # Diffs count: orders with ANAF adjustments, address mismatches, or TVA mismatch diffs_clauses = list(base_clauses) + [ - "(anaf_cod_fiscal_adjusted = 1 OR anaf_denumire_mismatch = 1 OR address_mismatch = 1)" + "(anaf_cod_fiscal_adjusted = 1 OR anaf_denumire_mismatch = 1 OR address_mismatch = 1" + " OR (cod_fiscal_gomag IS NOT NULL AND cod_fiscal_gomag != '' AND anaf_platitor_tva IS NOT NULL" + " AND ((UPPER(cod_fiscal_gomag) LIKE 'RO%' AND anaf_platitor_tva = 0)" + " OR (UPPER(cod_fiscal_gomag) NOT LIKE 'RO%' AND anaf_platitor_tva = 1))))" ] diffs_where = "WHERE " + " AND ".join(diffs_clauses) cursor = await db.execute(f"SELECT COUNT(*) FROM orders {diffs_where}", base_params) diff --git a/api/app/static/js/dashboard.js b/api/app/static/js/dashboard.js index 9b320bb..f619881 100644 --- a/api/app/static/js/dashboard.js +++ b/api/app/static/js/dashboard.js @@ -368,7 +368,7 @@ async function loadDashOrders() { ${statusDot(o.status)} ${dateStr} ${renderClientCell(o)} - ${esc(o.order_number)}${(o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva===0))?'':''}${(o.address_mismatch===1||o.price_match===false)?'':''} + ${esc(o.order_number)}${(o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva!==null&&(/^RO/i.test(o.cod_fiscal_gomag)!==(o.anaf_platitor_tva===1))))?'':''}${(o.address_mismatch===1||o.price_match===false)?'':''} ${o.items_count || 0} ${fmtCost(o.delivery_cost)} ${fmtCost(o.discount_total)} @@ -394,7 +394,7 @@ async function loadDashOrders() { } const name = o.customer_name || o.shipping_name || o.billing_name || '\u2014'; const totalStr = o.order_total ? Number(o.order_total).toFixed(2) : ''; - const anafDiffDot = (o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva===0)) ? '' : ''; + const anafDiffDot = (o.anaf_cod_fiscal_adjusted===1||o.anaf_denumire_mismatch===1||(o.cod_fiscal_gomag&&o.anaf_platitor_tva!==null&&(/^RO/i.test(o.cod_fiscal_gomag)!==(o.anaf_platitor_tva===1)))) ? '' : ''; const addrDiffDot = o.address_mismatch===1 ? '' : ''; const priceMismatch = o.price_match === false ? ' ' : ''; return `
diff --git a/api/app/static/js/shared.js b/api/app/static/js/shared.js index d7e4969..edce0b3 100644 --- a/api/app/static/js/shared.js +++ b/api/app/static/js/shared.js @@ -1020,7 +1020,11 @@ function _renderHeaderInfo(order) { const badges = []; if (isPJ && pi.anaf_cod_fiscal_adjusted) badges.push({label:'CUI', cls:'diff-badge-anaf', aria:'CUI ajustat conform ANAF'}); if (isPJ && pi.anaf_denumire_mismatch) badges.push({label:'Denumire', cls:'diff-badge-anaf', aria:'Denumire diferita fata de ANAF'}); - if (isPJ && pi.anaf_platitor_tva === 0) badges.push({label:'TVA', cls:'diff-badge-anaf', aria:'Neplatitor TVA conform ANAF'}); + if (isPJ && pi.anaf_platitor_tva !== null && pi.anaf_platitor_tva !== undefined) { + const gomagImpliesPlatitor = pi.cod_fiscal_gomag && /^RO/i.test(pi.cod_fiscal_gomag); + const anafPlatitor = pi.anaf_platitor_tva === 1; + if (gomagImpliesPlatitor !== anafPlatitor) badges.push({label:'TVA', cls:'diff-badge-anaf', aria: anafPlatitor ? 'Platitor TVA conform ANAF (GoMag fara RO)' : 'Neplatitor TVA conform ANAF (GoMag cu RO)'}); + } if (addr && addr.livrare_roa && !addrMatch(addr.livrare_gomag, addr.livrare_roa)) badges.push({label:'Adr. livr.', cls:'diff-badge-info', aria:'Adresa livrare diferita'}); if (addr && addr.facturare_roa && !addrMatch(addr.facturare_gomag, addr.facturare_roa)) badges.push({label:'Adr. fact.', cls:'diff-badge-info', aria:'Adresa facturare diferita'}); if (order.price_check && order.price_check.mismatches > 0) badges.push({label:'Preturi (' + order.price_check.mismatches + ')', cls:'diff-badge-info', aria:'Preturi diferite: ' + order.price_check.mismatches}); diff --git a/api/app/templates/base.html b/api/app/templates/base.html index 7a6277f..a366fd8 100644 --- a/api/app/templates/base.html +++ b/api/app/templates/base.html @@ -161,7 +161,7 @@ - + + {% endblock %}