From fa3087230074d7aa581ab59c50b3da739ca3b3a9 Mon Sep 17 00:00:00 2001 From: Manus Date: Wed, 10 Jun 2026 07:30:44 +0000 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20La=20vue=20=C3=89tablissements=20?= =?UTF-8?q?de=20la=20page=20OPEX=20recalcule=20d=C3=A9sormais=20dynamiquem?= =?UTF-8?q?ent=20les=20montants=20par=20=C3=A9tablissement=20depuis=20les?= =?UTF-8?q?=20postes=20=C3=A9ditables=20(totalPostes=20=C3=97=20ratio=5Fba?= =?UTF-8?q?se=5Frepartition),=20au=20lieu=20de=20lire=20les=20montants=20p?= =?UTF-8?q?r=C3=A9-calcul=C3=A9s=20erron=C3=A9s=20du=20JSON=20source=20(qu?= =?UTF-8?q?i=20=C3=A9taient=20doubl=C3=A9s).=20Le=20total=20des=20=C3=A9ta?= =?UTF-8?q?blissements=20est=20maintenant=20coh=C3=A9rent=20avec=20le=20to?= =?UTF-8?q?tal=20des=20postes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/DsiOpex.tsx | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/client/src/pages/DsiOpex.tsx b/client/src/pages/DsiOpex.tsx index fe767f7..d5daa77 100644 --- a/client/src/pages/DsiOpex.tsx +++ b/client/src/pages/DsiOpex.tsx @@ -597,14 +597,44 @@ export default function DsiOpex() { ); // Établissements (vue par établissement) - const filteredEtabs = useMemo(() => { + // ── Vue établissements : recalcul dynamique depuis les postes éditables (version C) ──────────── + // Le total de chaque établissement = somme(montant_poste × ratio_etab) + // ratio_etab = base_repartition_etab / somme_base_repartition_tous_etabs + const etablissementsRecalcules = useMemo(() => { const srcData = getOpexDataForAnnee(annee); - return srcData.etablissements.filter(e => { + const totalBase = srcData.etablissements.reduce((s, e) => s + e.base_repartition, 0); + if (totalBase === 0) return srcData.etablissements; + + // Total des postes éditables (source de vérité) + const totalPostes = opexState.lignes.reduce((s, l) => s + l.montant, 0); + + return srcData.etablissements.map(etab => { + const ratio = etab.base_repartition / totalBase; + const totalEtab = Math.round(totalPostes * ratio); + + // Ventiler chaque poste éditable au prorata + const montantsRecalcules: Record = {}; + for (const ligne of opexState.lignes) { + if (ligne.montant > 0) { + montantsRecalcules[ligne.libelle] = Math.round(ligne.montant * ratio); + } + } + + return { + ...etab, + montants: montantsRecalcules, + total: totalEtab, + }; + }); + }, [opexState.lignes, annee]); + + const filteredEtabs = useMemo(() => { + return etablissementsRecalcules.filter(e => { if (search && !e.nom.toLowerCase().includes(search.toLowerCase()) && !e.code.toLowerCase().includes(search.toLowerCase())) return false; return true; }); - }, [search]); + }, [etablissementsRecalcules, search]); const sortedEtabs = useMemo(() => { const arr = [...filteredEtabs];