followUpService = $followUpService; } #[Route('/admin/followup/{insee_code}/delete', name: 'admin_followup_delete', requirements: ['insee_code' => '\\d+'])] public function deleteFollowups(string $insee_code, EntityManagerInterface $em): Response { $stats = $em->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); if (!$stats) { $this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE.'); return $this->redirectToRoute('app_admin'); } $followups = $stats->getCityFollowUps(); foreach ($followups as $fu) { $em->remove($fu); } $em->flush(); $this->addFlash('success', 'Tous les suivis ont été supprimés pour cette ville.'); return $this->redirectToRoute('admin_followup_graph', ['insee_code' => $insee_code]); } #[Route('/admin/followup/{insee_code}', name: 'admin_followup', requirements: ['insee_code' => '\\d+'])] public function followup( string $insee_code, Motocultrice $motocultrice, EntityManagerInterface $em ): Response { $stats = $em->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); if (!$stats) { $this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE.'); return $this->redirectToRoute('app_admin'); } $this->followUpService->generateCityFollowUps($stats, $motocultrice, $em); $this->addFlash('success', 'Suivi enregistré pour la ville.'); return $this->redirectToRoute('admin_followup_graph', ['insee_code' => $insee_code]); } #[Route('/admin/followup/{insee_code}/graph', name: 'admin_followup_graph', requirements: ['insee_code' => '\\d+'])] public function followupGraph( string $insee_code, EntityManagerInterface $em, Motocultrice $motocultrice ) { $stats = $em->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); if (!$stats) { $this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE.'); return $this->redirectToRoute('app_admin'); } $followups = $stats->getCityFollowUps(); $refresh = false; if (!$followups->isEmpty()) { $latest = null; foreach ($followups as $fu) { if ($latest === null || $fu->getDate() > $latest->getDate()) { $latest = $fu; } } if ($latest && $latest->getDate() < (new \DateTime('-1 day'))) { $refresh = true; } } else { $refresh = true; } if ($refresh) { $this->followUpService->generateCityFollowUps($stats, $motocultrice, $em); $followups = $stats->getCityFollowUps(); } $followups = $followups->toArray(); usort($followups, fn($a, $b) => $a->getDate() <=> $b->getDate()); $series = []; $all_points = []; foreach ($followups as $fu) { $series[$fu->getName()][] = [ 'date' => $fu->getDate()->format('c'), 'value' => $fu->getMeasure(), 'name' => $fu->getName(), ]; $all_points[] = [ 'date' => $fu->getDate()->format('c'), 'type' => $fu->getName(), 'name' => $fu->getName(), 'value' => $fu->getMeasure(), ]; } usort($all_points, fn($a, $b) => strcmp($b['date'], $a['date'])); $all_points = array_slice($all_points, 0, 20); // Tri par date dans chaque série foreach ($series as &$points) { usort($points, function($a, $b) { return strtotime($a['date']) <=> strtotime($b['date']); }); } unset($points); return $this->render('admin/followup_graph.html.twig', [ 'stats' => $stats, 'series' => $series, 'all_points' => $all_points, 'followup_labels' => FollowUpService::getFollowUpThemes(), 'followup_icons' => FollowUpService::getFollowUpIcons(), 'followup_overpass' => FollowUpService::getFollowUpOverpassQueries(), ]); } #[Route('/admin/followup/all', name: 'admin_followup_all')] public function followupAll( EntityManagerInterface $em, Motocultrice $motocultrice ) { $statsList = $em->getRepository(Stats::class)->findAll(); foreach ($statsList as $stats) { $this->followUpService->generateCityFollowUps($stats, $motocultrice, $em); } $this->addFlash('success', 'Suivi généré pour toutes les villes.'); return $this->redirectToRoute('app_admin'); } #[Route('/admin/followup/global', name: 'admin_followup_global')] public function followupGlobal(EntityManagerInterface $em) { $this->followUpService->generateGlobalFollowUps($em); $this->addFlash('success', 'Suivi global généré pour toutes les villes.'); return $this->redirectToRoute('admin_followup_global_graph'); } #[Route('/admin/followup/global/graph', name: 'admin_followup_global_graph')] public function followupGlobalGraph(EntityManagerInterface $em) { $stats = $em->getRepository(Stats::class)->findOneBy(['zone' => '00000']); if (!$stats) { $this->addFlash('error', 'Aucun suivi global trouvé.'); return $this->redirectToRoute('app_admin'); } $followups = $stats->getCityFollowUps(); $followups = $followups->toArray(); usort($followups, fn($a, $b) => $a->getDate() <=> $b->getDate()); $series = []; foreach ($followups as $fu) { $series[$fu->getName()][] = [ 'date' => $fu->getDate()->format('c'), 'value' => $fu->getMeasure(), 'name' => $fu->getName(), ]; } // Tri par date dans chaque série foreach ($series as &$points) { usort($points, function($a, $b) { return strtotime($a['date']) <=> strtotime($b['date']); }); } unset($points); return $this->render('admin/followup_global_graph.html.twig', [ 'stats' => $stats, 'series' => $series, 'followup_labels' => FollowUpService::getFollowUpThemes(), 'followup_icons' => FollowUpService::getFollowUpIcons(), 'followup_overpass' => FollowUpService::getFollowUpOverpassQueries(), ]); } #[Route('/admin/followup/{insee_code}/embed/{theme}', name: 'admin_followup_embed_graph', requirements: ['insee_code' => '\\d+', 'theme' => '[a-zA-Z0-9_]+'])] public function followupEmbedGraph( string $insee_code, string $theme, EntityManagerInterface $em, Motocultrice $motocultrice ) { $stats = $em->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); if (!$stats) { $this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE.'); return $this->redirectToRoute('app_admin'); } $followups = $stats->getCityFollowUps(); $refresh = false; if (!$followups->isEmpty()) { $latest = null; foreach ($followups as $fu) { if ($latest === null || $fu->getDate() > $latest->getDate()) { $latest = $fu; } } if ($latest && $latest->getDate() < (new \DateTime('-1 day'))) { $refresh = true; } } else { $refresh = true; } if ($refresh) { $this->followUpService->generateCityFollowUps($stats, $motocultrice, $em); $followups = $stats->getCityFollowUps(); } $followups = $followups->toArray(); usort($followups, fn($a, $b) => $a->getDate() <=> $b->getDate()); $series = []; foreach ($followups as $fu) { if (str_starts_with($fu->getName(), $theme)) { $series[$fu->getName()][] = [ 'date' => $fu->getDate()->format('c'), 'value' => $fu->getMeasure(), 'name' => $fu->getName(), ]; } } return $this->render('admin/followup_embed_graph.html.twig', [ 'stats' => $stats, 'series' => $series, 'theme' => $theme, 'label' => FollowUpService::getFollowUpThemes()[$theme] ?? $theme, 'icon' => FollowUpService::getFollowUpIcons()[$theme] ?? 'bi-question-circle', ]); } }