mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-09 17:02:46 +02:00
227 lines
No EOL
9.1 KiB
PHP
227 lines
No EOL
9.1 KiB
PHP
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Entity\Stats;
|
|
use App\Entity\CityFollowUp;
|
|
use App\Service\Motocultrice;
|
|
use App\Service\FollowUpService;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
|
|
class FollowUpController extends AbstractController
|
|
{
|
|
private FollowUpService $followUpService;
|
|
|
|
public function __construct(FollowUpService $followUpService)
|
|
{
|
|
$this->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',
|
|
]);
|
|
}
|
|
}
|