From 0f33d57ec0780a7b83c342cb239ef2ee61e560b7 Mon Sep 17 00:00:00 2001 From: bach Date: Sat, 5 Sep 2026 12:53:30 +0200 Subject: [PATCH] Show a badge on linked-and-settled versements too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit versementStatus() returned null whenever a linked versement's own compte(s) had no residual against any linked entrée -- meaning a versement that was linked but fully reconciled got no badge at all, silently losing the only way to open its drill-down (the badge is also the click target). Only "not linked" and "has a residual" ever rendered one. Now always returns a status for any versement, adding a fourth kind ("ok": linked, no residual on any checked entrée) alongside non-liee/reste/sur-verse. Renders as a plain "Lié" badge in the default green (no is-anomalie/is-reste modifier), matching the convention the entrée side already uses for a fully-settled "N sorties liées" badge, and stays clickable since item.entreeLieeIds is still non-empty. Verified: several previously badge-less linked versements (e.g. "facture-SC-Bachir-260329B-FIGLI", "F58_260506_FIGLI") now show a green "Lié" badge, and clicking one opens the same 3-row drill-down (entrée + both its linked sorties) as before. --- .../custom/figli_compta_ledger/js/home.js | 58 ++++++++++++------- .../templates/figli-compta-home.html.twig | 4 +- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/web/modules/custom/figli_compta_ledger/js/home.js b/web/modules/custom/figli_compta_ledger/js/home.js index 2665b99..7a17b77 100644 --- a/web/modules/custom/figli_compta_ledger/js/home.js +++ b/web/modules/custom/figli_compta_ledger/js/home.js @@ -508,22 +508,29 @@ const detail = relevant.map((compte) => compte + ' : ' + this.formatEur(ecarts[compte])).join(', '); return { detail, comptes: relevant.length }; }, - // Flags a "versement freelance" row that isn't (fully) backed by - // the entrée client(s) it pays out against: either not linked at - // all, or linked but its own compte(s) still show a residual - // against at least one of them. Deliberately scoped to just the - // compte(s) this versement's own répartition touches - // (reconciliationByEntree's parCompteResidual), not the entrée's - // overall resteAVerser/surVerse -- those can be driven entirely by - // a *different* compte tied to some other sortie linked to the - // same entrée, which says nothing about whether this versement's - // own répartition is settled. When linked to several entrées (see - // reconciliationByEntree's equal-split note), each entrée's - // residual for these compte(s) counts separately -- they're - // independent invoices, each with its own outstanding amount. - // Entrées outside the currently loaded window are skipped (same - // accepted trade-off as reconciliationByEntree itself); null only - // if none of them could be checked at all. + // Status badge for a "versement freelance" row -- always present + // when the row is a versement, specifically so a linked-but-settled + // versement still gets a badge to drill down through (it used to + // return null there, silently losing the only way to open the + // linked entrée's filtered view for versements with nothing wrong + // to report). "kind" distinguishes not-linked-at-all, a residual + // against at least one linked entrée, or linked-and-settled: + // - not linked at all + // - linked but its own compte(s) still show a residual against at + // least one linked entrée -- deliberately scoped to just the + // compte(s) this versement's own répartition touches + // (reconciliationByEntree's parCompteResidual), not the + // entrée's overall resteAVerser/surVerse, which can be driven + // entirely by a *different* compte tied to some other sortie + // linked to the same entrée and would say nothing about + // whether this versement's own répartition is settled. When + // linked to several entrées (see reconciliationByEntree's + // equal-split note), each entrée's residual for these compte(s) + // counts separately -- they're independent invoices, each with + // its own outstanding amount. + // - linked and settled (as far as the currently loaded window can + // tell -- a linked entrée outside it is silently skipped, same + // accepted trade-off as reconciliationByEntree itself) versementStatus(item) { if (item.type !== 'versement') return null; if (!item.entreeLieeIds.length) { @@ -531,30 +538,39 @@ } let resteAVerser = 0; let surVerse = 0; - let checked = 0; for (const entreeId of item.entreeLieeIds) { const recon = this.reconciliationByEntree.get(entreeId); if (!recon) continue; - checked++; for (const c of Object.keys(item.parCompte)) { const residual = recon.parCompteResidual[c] || 0; if (residual > 0.01) resteAVerser += residual; else if (residual < -0.01) surVerse += -residual; } } - if (!checked) return null; if (resteAVerser > 0.01) { return { kind: 'reste', detail: 'Reste à verser (comptes de cette ligne) : ' + this.formatEur(Math.round(resteAVerser * 100) / 100) }; } if (surVerse > 0.01) { return { kind: 'sur-verse', detail: 'Sur-versé (comptes de cette ligne) : ' + this.formatEur(Math.round(surVerse * 100) / 100) }; } - return null; + const n = item.entreeLieeIds.length; + return { kind: 'ok', detail: 'Lié à ' + n + ' entrée' + (n > 1 ? 's' : '') + ' client' + (n > 1 ? 's' : '') + '.' }; }, versementStatusLabel(kind) { if (kind === 'non-liee') return 'Non liée'; if (kind === 'reste') return 'Reste à verser'; - return 'Sur-versé'; + if (kind === 'sur-verse') return 'Sur-versé'; + return 'Lié'; + }, + // Only non-liee/sur-versé read as a hard anomaly (red); reste is + // its own softer amber; ok gets neither, falling back to the + // badge's default green -- same "all clear" green the entrée side + // already uses for a fully-settled "N sorties liées". + versementStatusClasses(kind) { + return { + 'is-anomalie': kind === 'non-liee' || kind === 'sur-verse', + 'is-reste': kind === 'reste', + }; }, // jj/mm/aa -- shorter than the API's ISO yyyy-mm-dd, saves column // width in a table already packed with 8 compte columns. diff --git a/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig b/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig index 1f15c6c..bbb21fb 100644 --- a/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig +++ b/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig @@ -161,10 +161,10 @@ ⚠ {{ versementStatusLabel(versementStatus(item).kind) }} + >{{ versementStatus(item).kind === 'ok' ? '' : '⚠ ' }}{{ versementStatusLabel(versementStatus(item).kind) }} {{ formatEur(item.montant_ht) }} {{ formatEur(item.montant_ttc) }}