Ajoute la répartition par type et le top clients par année sur /dashboard
Reprend exactement le pattern des petits multiples déjà en place sur /dashboard/compte (grille figli-year-hbar-grid, variante compacte de h-bar-chart) -- mêmes classes CSS, aucun nouveau style nécessaire. Backend : DashboardStatsController::stats() calcule maintenant aussi total_par_type_par_annee et top_clients_par_annee (top 8, contre 12 en toutes années confondues) à partir des mêmes requêtes SQL déjà en place, sans requête supplémentaire. Frontend : dashboard.js n'a jamais de données ligne par ligne (contraire- ment à dashboard-compte.js qui filtre côté client) -- l'agrégation par année doit donc venir du serveur. Ajout du prop "compact" au HBarChart de dashboard.js (jusqu'ici absent, seule la copie de dashboard-compte.js l'avait).
This commit is contained in:
@@ -82,7 +82,9 @@ class DashboardStatsController extends ControllerBase {
|
||||
// --- Aggregate the node-level rows in PHP. ---
|
||||
$caParAnnee = [];
|
||||
$totalParType = [];
|
||||
$totalParTypeParAnnee = [];
|
||||
$caParClient = [];
|
||||
$caParClientParAnnee = [];
|
||||
$annees = [];
|
||||
foreach ($nodeRows as $row) {
|
||||
$montant = $row->montant_ht !== NULL ? (float) $row->montant_ht : 0.0;
|
||||
@@ -104,6 +106,17 @@ class DashboardStatsController extends ControllerBase {
|
||||
$annees[$row->annee] = TRUE;
|
||||
if ($row->type === 'entree') {
|
||||
$caParAnnee[$row->annee] = ($caParAnnee[$row->annee] ?? 0) + $montant;
|
||||
// Per-année équivalent of $caParClient above -- backs the "Top
|
||||
// clients par année" small multiples, same rows, no extra query.
|
||||
$client = $row->client ?: '(sans client)';
|
||||
$caParClientParAnnee[$row->annee][$client] =
|
||||
($caParClientParAnnee[$row->annee][$client] ?? 0) + $montant;
|
||||
}
|
||||
// Per-année équivalent of $totalParType above -- backs the
|
||||
// "Répartition de l'activité par type" small multiples.
|
||||
if ($row->type !== 'ouverture') {
|
||||
$totalParTypeParAnnee[$row->annee][$row->type] =
|
||||
($totalParTypeParAnnee[$row->annee][$row->type] ?? 0) + abs($montant);
|
||||
}
|
||||
}
|
||||
arsort($caParClient);
|
||||
@@ -116,6 +129,25 @@ class DashboardStatsController extends ControllerBase {
|
||||
$topClients[] = ['client' => $client, 'ca' => round($total, 2)];
|
||||
}
|
||||
|
||||
// Top 8 (not 12 like the all-time chart above) -- one per year keeps
|
||||
// the small-multiples grid readable, same reasoning as the per-compte
|
||||
// équivalent on /dashboard/compte (there it's top 5, computed
|
||||
// client-side from full row data; here it's top 8, computed here
|
||||
// since dashboard.js only ever gets pre-aggregated SQL, never full
|
||||
// rows -- see this controller's docblock).
|
||||
$topClientsParAnnee = [];
|
||||
foreach ($caParClientParAnnee as $annee => $parClient) {
|
||||
arsort($parClient);
|
||||
$topClientsParAnnee[$annee] = [];
|
||||
$i = 0;
|
||||
foreach ($parClient as $client => $total) {
|
||||
if ($i++ >= 8) {
|
||||
break;
|
||||
}
|
||||
$topClientsParAnnee[$annee][] = ['client' => $client, 'ca' => round($total, 2)];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Aggregate the répartition-level rows in PHP. ---
|
||||
$soldeParCompte = [];
|
||||
$soldeParCompteParAnnee = [];
|
||||
@@ -170,12 +202,19 @@ class DashboardStatsController extends ControllerBase {
|
||||
// year, which can differ year to year.
|
||||
ksort($soldeParCompteParAnnee);
|
||||
ksort($totalParTypeParCompteParAnnee);
|
||||
ksort($totalParTypeParAnnee);
|
||||
ksort($topClientsParAnnee);
|
||||
|
||||
return new JsonResponse([
|
||||
'annees' => $anneesList,
|
||||
'ca_par_annee' => array_map(fn ($v) => round($v, 2), $caParAnnee),
|
||||
'total_par_type' => array_map(fn ($v) => round($v, 2), $totalParType),
|
||||
'total_par_type_par_annee' => array_map(
|
||||
fn ($parType) => array_map(fn ($v) => round($v, 2), $parType),
|
||||
$totalParTypeParAnnee
|
||||
),
|
||||
'top_clients' => $topClients,
|
||||
'top_clients_par_annee' => $topClientsParAnnee,
|
||||
'solde_par_compte' => array_map(fn ($v) => round($v, 2), $soldeParCompte),
|
||||
'solde_par_compte_par_annee' => $soldeParCompteParAnnee,
|
||||
'total_par_type_par_compte' => array_map(
|
||||
|
||||
Reference in New Issue
Block a user