From a4e3c53dcc571bd3cc1774c9036c5b1c5a6aa1dc Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 09:05:47 +0000 Subject: [PATCH] =?UTF-8?q?feat(grille):=20d=C3=A9tail=20par=20magasin=20d?= =?UTF-8?q?ans=20la=20carte,=20en=20mode=20tous=20magasins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit En « tous magasins », les trois tuiles de la carte sont des cumuls : savoir que le stock est de 40 ne dit pas s'il est réparti entre Frouard et Houdemont ou entièrement sur un seul site — or c'est précisément ce qu'on vient vérifier. La carte affiche désormais, sous les cumuls, une ligne par magasin avec ses ventes, ses entrées et son stock de fin de mois. Uniquement en mode tous magasins : sur un magasin unique, les tuiles sont déjà ce détail. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Y26nRZxTR57K7h8yqsF675 --- src/features/grid/components/heatmap-grid.tsx | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/features/grid/components/heatmap-grid.tsx b/src/features/grid/components/heatmap-grid.tsx index 85ccc0e..440b5fa 100644 --- a/src/features/grid/components/heatmap-grid.tsx +++ b/src/features/grid/components/heatmap-grid.tsx @@ -396,10 +396,66 @@ function CellDetailModal({ d, activeMagasin, onClose }: { d: CellDetailData; act Stock fin mois + + {/* + * En « tous magasins », les trois tuiles ci-dessus sont des cumuls. + * Le détail par magasin est justement ce qu'on vient vérifier ici : + * savoir que le stock est de 40 ne dit pas s'il est réparti ou + * entièrement sur un seul site. + */} + {activeMagasin === "TOTAL" && } ); } +/** Détail ventes / entrées / stock du mois, magasin par magasin. */ +function VentilationParMagasin({ d }: { d: CellDetailData }) { + const sites = [...new Set([ + ...Object.keys(d.row.sales12mByStore ?? {}), + ...Object.keys(d.row.stock12mByStore ?? {}), + ])].sort(); + + if (sites.length === 0) return null; + + return ( +
+ + + + + + + + + + + {sites.map((site) => { + const ventes = d.row.sales12mByStore?.[site]?.[d.monthKey] ?? 0; + const entrees = d.row.receptions12mByStore?.[site]?.[d.monthKey] ?? 0; + const stock = d.row.stock12mByStore?.[site]?.[d.monthKey] ?? 0; + return ( + + + + + + + ); + })} + +
MagasinVentesEntréesStock
+ {SITE_LABELS[site]?.nom ?? site} + + {Math.round(ventes).toLocaleString("fr-FR")} + 0 ? "rgb(16,185,129)" : "var(--text-muted)" }}> + {entrees > 0 ? `+${Math.round(entrees).toLocaleString("fr-FR")}` : "—"} + + {Math.round(stock).toLocaleString("fr-FR")} +
+
+ ); +} + // ========================================================================= export function HeatmapGrid({ onSelectionChange, isAdmin }: HeatmapGridProps) {