diff --git a/web/modules/custom/figli_compta_ledger/js/home.js b/web/modules/custom/figli_compta_ledger/js/home.js index 0be93c9..bac379a 100644 --- a/web/modules/custom/figli_compta_ledger/js/home.js +++ b/web/modules/custom/figli_compta_ledger/js/home.js @@ -304,8 +304,15 @@ let resteAVerser = 0; let surVerse = 0; const detail = []; + // Kept per-compte (not just folded into the two totals above) -- + // versementStatus() below needs to check a single sortie's own + // compte(s) against the entrée, not the entrée's overall + // reconciliation, which can span *other* comptes tied to other + // sorties linked to the same entrée. + const parCompteResidual = {}; for (const c of comptes) { const residual = Math.round(((entreeRow.parCompte[c] || 0) + (versementsParCompte[c] || 0)) * 100) / 100; + parCompteResidual[c] = residual; if (residual > 0.01) resteAVerser += residual; else if (residual < -0.01) surVerse += -residual; if (Math.abs(residual) > 0.01) detail.push(c + ' : ' + this.formatEur(residual)); @@ -315,6 +322,7 @@ resteAVerser: Math.round(resteAVerser * 100) / 100, surVerse: Math.round(surVerse * 100) / 100, detail: detail.join(', ') || 'Entièrement soldé', + parCompteResidual, }); } return map; @@ -423,13 +431,16 @@ }, // Flags a "versement freelance" row that isn't (fully) backed by // the entrée client it pays out against: either not linked at all, - // or linked but reconciliationByEntree still shows a residual on - // that entrée. The residual belongs to the entrée as a whole, not - // to any one sortie -- when several versements share an entrée, - // each shows the same aggregate residual, since there's no way to - // say which specific one is "the" shortfall. Null (no highlight) - // when the linked entrée isn't in the currently loaded window -- - // same accepted trade-off as reconciliationByEntree itself. + // or linked but its own compte(s) still show a residual against + // that 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 -- 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. Null (no highlight) when the linked entrée isn't in the + // currently loaded window -- same accepted trade-off as + // reconciliationByEntree itself. versementStatus(item) { if (item.type !== 'versement') return null; if (!item.entreeLieeId) { @@ -437,11 +448,18 @@ } const recon = this.reconciliationByEntree.get(item.entreeLieeId); if (!recon) return null; - if (recon.resteAVerser > 0.01) { - return { kind: 'reste', detail: 'Reste à verser sur l’entrée liée : ' + this.formatEur(recon.resteAVerser) }; + let resteAVerser = 0; + let surVerse = 0; + 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 (recon.surVerse > 0.01) { - return { kind: 'sur-verse', detail: 'Sur-versé sur l’entrée liée : ' + this.formatEur(recon.surVerse) }; + 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; },