From 9ce5d87acea5f3b5dfeb2bc2255c49fe13568041 Mon Sep 17 00:00:00 2001 From: bach Date: Sun, 6 Sep 2026 16:43:44 +0200 Subject: [PATCH] Surface signalement (flag) tags on the per-compte dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fetches field_flag alongside the existing entrée/versement data (same JSON:API include list, same buildRows() shape as home.js's flags/ hasFlag). Two changes: - Rows already shown in the reste-à-verser/sur-versé/non-liés tables get the same amber left-edge accent + tag badges as /lignes when they're also flagged. - New "Lignes signalées" section lists every flagged entrée/versement for the selected compte, including ones that don't appear in any of the other tables -- a fully-settled line can still carry a flag for an unrelated reason (e.g. "client injoignable"), which none of the reconciliation-based tables would otherwise surface. Verified live against an isolated test node plus two real flagged lines already present in production data (client had already started using the /lignes signalement feature) -- both the section and the inline badges render correctly. Co-Authored-By: Claude Sonnet 5 --- .../figli_compta_ledger/css/dashboard.css | 19 +++++++++++ .../js/dashboard-compte.js | 18 ++++++++++- .../figli-compta-dashboard-compte.html.twig | 32 +++++++++++++++---- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/web/modules/custom/figli_compta_ledger/css/dashboard.css b/web/modules/custom/figli_compta_ledger/css/dashboard.css index cc02be2..3e511d2 100644 --- a/web/modules/custom/figli_compta_ledger/css/dashboard.css +++ b/web/modules/custom/figli_compta_ledger/css/dashboard.css @@ -8,6 +8,7 @@ --figli-border: #dcdee2; --figli-error: #c9312b; --figli-positive: #1a7f37; + --figli-warning: #b8860b; font-family: Inter, -apple-system, sans-serif; max-width: 1200px; @@ -23,6 +24,7 @@ html.gin--dark-mode #figli-dashboard-app { --figli-border: #3d3e42; --figli-error: #ff6b6b; --figli-positive: #4ade80; + --figli-warning: #f0b429; } #figli-dashboard-app h2 { @@ -124,6 +126,23 @@ html.gin--dark-mode #figli-dashboard-app { #figli-dashboard-app .figli-recon-table tfoot td { font-weight: 700; border-bottom: none; border-top: 2px solid var(--figli-border); } #figli-dashboard-app .figli-recon-table a { color: inherit; text-decoration: underline; text-decoration-color: var(--figli-border); } +/* Signalée rows: same amber left-edge accent as /lignes (box-shadow, not + border, so it doesn't fight the row's existing bottom border). */ +#figli-dashboard-app .figli-recon-table tr.figli-flag-row td:first-child { + box-shadow: inset 4px 0 0 var(--figli-warning); +} +#figli-dashboard-app .figli-flag-badge { + display: inline-block; + padding: 0.05rem 0.4rem; + margin: 0 0 0 0.4rem; + border-radius: 8px; + font-size: 0.68rem; + font-weight: 600; + background: color-mix(in srgb, var(--figli-warning) 15%, transparent); + color: var(--figli-warning); + white-space: nowrap; +} + /* --- Year bars chart (évolution du solde, entrées vs versements) --- */ #figli-dashboard-app .figli-year-chart { display: flex; diff --git a/web/modules/custom/figli_compta_ledger/js/dashboard-compte.js b/web/modules/custom/figli_compta_ledger/js/dashboard-compte.js index cee1b18..b7679fe 100644 --- a/web/modules/custom/figli_compta_ledger/js/dashboard-compte.js +++ b/web/modules/custom/figli_compta_ledger/js/dashboard-compte.js @@ -42,6 +42,8 @@ const clientTerm = resolve(includedMap, rels.field_client && rels.field_client.data); const entreeLieeRefs = (rels.field_entree_liee && rels.field_entree_liee.data) || []; const entreeLieeIds = entreeLieeRefs.map((ref) => ref.id); + const flagRefs = (rels.field_flag && rels.field_flag.data) || []; + const flags = flagRefs.map((ref) => resolve(includedMap, ref)).filter(Boolean).map((t) => t.attributes.name); const parCompte = {}; const repartitionRefs = (rels.field_repartition && rels.field_repartition.data) || []; for (const ref of repartitionRefs) { @@ -61,6 +63,8 @@ libelle: attrs.field_notes || attrs.title, parCompte, entreeLieeIds, + flags, + hasFlag: flags.length > 0, }); } rows.sort((a, b) => (a.date || '').localeCompare(b.date || '')); @@ -76,7 +80,7 @@ // autre/ouverture -- is exactly what this page deliberately excludes). async function fetchEntreesEtVersements() { const params = new URLSearchParams(); - params.set('include', 'field_repartition,field_repartition.field_compte,field_client,field_entree_liee'); + params.set('include', 'field_repartition,field_repartition.field_compte,field_client,field_entree_liee,field_flag'); params.set('filter[typeFilter][condition][path]', 'field_type_ligne'); params.set('filter[typeFilter][condition][operator]', 'IN'); params.append('filter[typeFilter][condition][value][]', 'entree'); @@ -286,6 +290,18 @@ .filter((r) => r.type === 'versement' && r.parCompte[this.selectedCompte] !== undefined && r.entreeLieeIds.length === 0) .sort((a, b) => (b.date || '').localeCompare(a.date || '')); }, + // Toute ligne entrée/versement de ce compte portant un signalement + // (voir /lignes), qu'elle apparaisse déjà dans une des listes + // ci-dessus ou non -- une ligne entièrement soldée peut quand même + // porter un problème sans rapport avec le montant (ex. "client + // injoignable"), auquel cas aucune des trois listes ci-dessus ne + // la montrerait autrement. + lignesSignalees() { + if (!this.selectedCompte) return []; + return this.allRows + .filter((r) => r.hasFlag && r.parCompte[this.selectedCompte] !== undefined) + .sort((a, b) => (b.date || '').localeCompare(a.date || '')); + }, totalResteAVerser() { return Math.round(this.resteAVerserPositif.reduce((sum, r) => sum + r.residual, 0) * 100) / 100; }, diff --git a/web/modules/custom/figli_compta_ledger/templates/figli-compta-dashboard-compte.html.twig b/web/modules/custom/figli_compta_ledger/templates/figli-compta-dashboard-compte.html.twig index ab44e5f..522429d 100644 --- a/web/modules/custom/figli_compta_ledger/templates/figli-compta-dashboard-compte.html.twig +++ b/web/modules/custom/figli_compta_ledger/templates/figli-compta-dashboard-compte.html.twig @@ -52,10 +52,10 @@ DateClientLibelléAttribuéDéjà verséReste à verser - + {{ formatDate(r.entree.date) }} {{ r.entree.client || '—' }} - {{ r.entree.libelle || '—' }} + {{ r.entree.libelle || '—' }}{{ f }} {{ formatEur(r.montantAttribue) }} {{ formatEur(r.dejaVerse) }} {{ formatEur(r.residual) }} @@ -76,10 +76,10 @@ DateClientLibelléAttribuéVerséSur-versé - + {{ formatDate(r.entree.date) }} {{ r.entree.client || '—' }} - {{ r.entree.libelle || '—' }} + {{ r.entree.libelle || '—' }}{{ f }} {{ formatEur(r.montantAttribue) }} {{ formatEur(r.dejaVerse) }} {{ formatEur(-r.residual) }} @@ -96,16 +96,36 @@ DateClientLibelléMontant - + {{ formatDate(r.date) }} {{ r.client || '—' }} - {{ r.libelle || '—' }} + {{ r.libelle || '—' }}{{ f }} {{ formatEur(r.parCompte[selectedCompte]) }} +
+

Lignes signalées

+

Entrées et versements de {{ selectedCompte }} portant un signalement (voir la colonne "Signalement" dans le grand livre) -- indépendant du solde, une ligne déjà réglée peut quand même être signalée pour une autre raison.

+ + + + + + + + + + + + + + +
DateTypeClientLibelléSignalementMontant
{{ formatDate(r.date) }}{{ r.type === 'entree' ? 'Entrée' : 'Versement' }}{{ r.client || '—' }}{{ r.libelle || '—' }}{{ f }}{{ formatEur(r.parCompte[selectedCompte]) }}
+
+

Entrées vs versements par année

Part de {{ selectedCompte }} dans les entrées client (vert) et ses versements (rouge), année par année.