Add solde footers + per-année small multiples to /dashboard/compte
1. "Entrées sur-versées" and "Versements sans entrée liée" tables get a solde footer, same convention as "Reste à verser" above them -- reuses the totalSurVerse/totalNonLies computeds already backing the summary cards, no new computation. 2. "Répartition de l'activité par type" and "Top clients" keep their all-time chart, now followed by a small-multiples grid of the same chart per année. The type breakdown reuses total_par_type_par_compte_par_annee, a new field on DashboardStatsController::stats() built from the same répartition- level rows already fetched for total_par_type_par_compte (no extra query, just one more level of grouping in the PHP aggregation). Top clients per année is computed client-side from the same entreesDuCompte already used for the all-time version, capped to top 5 (not 10) to keep the grid readable. HBarChart gains a `compact` prop (narrower fixed columns, smaller text) for use inside the small-multiples cards -- the all-time charts above keep the full-width layout unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,7 @@ class DashboardStatsController extends ControllerBase {
|
||||
$soldeParCompte = [];
|
||||
$soldeParCompteParAnnee = [];
|
||||
$totalParTypeParCompte = [];
|
||||
$totalParTypeParCompteParAnnee = [];
|
||||
foreach ($compteRows as $row) {
|
||||
$total = (float) $row->total;
|
||||
// Same reasoning: the all-time balance includes every line; the
|
||||
@@ -144,6 +145,14 @@ class DashboardStatsController extends ControllerBase {
|
||||
// that year+compte would survive.
|
||||
$soldeParCompteParAnnee[$row->annee][$row->compte] =
|
||||
round(($soldeParCompteParAnnee[$row->annee][$row->compte] ?? 0) + $total, 2);
|
||||
|
||||
// Per-année version of $totalParTypeParCompte above, for the
|
||||
// "par année" small multiples on /dashboard/compte -- same rows,
|
||||
// no extra query.
|
||||
if ($row->type !== 'ouverture') {
|
||||
$totalParTypeParCompteParAnnee[$row->annee][$row->compte][$row->type] =
|
||||
($totalParTypeParCompteParAnnee[$row->annee][$row->compte][$row->type] ?? 0) + abs($total);
|
||||
}
|
||||
}
|
||||
|
||||
// array_keys() alone would leak PHP's array-key int-casting here: a
|
||||
@@ -160,6 +169,7 @@ class DashboardStatsController extends ControllerBase {
|
||||
// key order for soldeParCompteParAnnee follows first-seen compte per
|
||||
// year, which can differ year to year.
|
||||
ksort($soldeParCompteParAnnee);
|
||||
ksort($totalParTypeParCompteParAnnee);
|
||||
|
||||
return new JsonResponse([
|
||||
'annees' => $anneesList,
|
||||
@@ -172,6 +182,13 @@ class DashboardStatsController extends ControllerBase {
|
||||
fn ($parType) => array_map(fn ($v) => round($v, 2), $parType),
|
||||
$totalParTypeParCompte
|
||||
),
|
||||
'total_par_type_par_compte_par_annee' => array_map(
|
||||
fn ($parCompte) => array_map(
|
||||
fn ($parType) => array_map(fn ($v) => round($v, 2), $parType),
|
||||
$parCompte
|
||||
),
|
||||
$totalParTypeParCompteParAnnee
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user