diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php index 0f44d1c..39427b1 100644 --- a/src/Controller/AdminController.php +++ b/src/Controller/AdminController.php @@ -142,8 +142,74 @@ final class AdminController extends AbstractController } $stats->computeCompletionPercent(); - $this->entityManager->persist($stats); + + // Calculer les statistiques de fraîcheur des données OSM + $timestamps = []; + foreach ($stats->getPlaces() as $place) { + if ($place->getOsmDataDate()) { + $timestamps[] = $place->getOsmDataDate()->getTimestamp(); + } + } + if (!empty($timestamps)) { + // Date la plus ancienne (min) + $minTimestamp = min($timestamps); + $stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp)); + + // Date la plus récente (max) + $maxTimestamp = max($timestamps); + $stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp)); + + // Date moyenne + $avgTimestamp = array_sum($timestamps) / count($timestamps); + $stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp)); + } + + if($stats->getDateCreated() == null) { + $stats->setDateCreated(new \DateTime()); + } + + $stats->setDateModified(new \DateTime()); + + // Créer un historique des statistiques + $statsHistory = new StatsHistory(); + $statsHistory->setDate(new \DateTime()) + ->setStats($stats); + + // Compter les Places avec email et SIRET + $placesWithEmail = 0; + $placesWithSiret = 0; + foreach ($stats->getPlaces() as $place) { + if ($place->getEmail() && $place->getEmail() !== '') { + $placesWithEmail++; + } + if ($place->getSiret() && $place->getSiret() !== '') { + $placesWithSiret++; + } + } + + $statsHistory->setPlacesCount($stats->getPlaces()->count()) + ->setOpeningHoursCount($stats->getAvecHoraires()) + ->setAddressCount($stats->getAvecAdresse()) + ->setWebsiteCount($stats->getAvecSite()) + ->setSiretCount($placesWithSiret) + ->setEmailsCount($placesWithEmail) + // ->setAccessibiliteCount($stats->getAvecAccessibilite()) + // ->setNoteCount($stats->getAvecNote()) + ->setCompletionPercent($stats->getCompletionPercent()) + ->setStats($stats); + + $this->entityManager->persist($statsHistory); + + + $this->entityManager->persist($stats); + $this->entityManager->flush(); + + $message = 'Labourage terminé avec succès. ' . $processedCount . ' nouveaux lieux traités.'; + if ($updateExisting) { + $message .= ' ' . $updatedCount . ' lieux existants mis à jour pour la zone '.$stats->getName().' ('.$stats->getZone().').'; + } + $this->addFlash('success', $message); } $this->entityManager->flush(); @@ -200,10 +266,69 @@ final class AdminController extends AbstractController $this->entityManager->flush(); $stats->computeCompletionPercent(); + + // Calculer les statistiques de fraîcheur des données OSM + $timestamps = []; + foreach ($stats->getPlaces() as $place) { + if ($place->getOsmDataDate()) { + $timestamps[] = $place->getOsmDataDate()->getTimestamp(); + } + } + + if (!empty($timestamps)) { + // Date la plus ancienne (min) + $minTimestamp = min($timestamps); + $stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp)); + + // Date la plus récente (max) + $maxTimestamp = max($timestamps); + $stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp)); + + // Date moyenne + $avgTimestamp = array_sum($timestamps) / count($timestamps); + $stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp)); + } + + if($stats->getDateCreated() == null) { + $stats->setDateCreated(new \DateTime()); + } + + $stats->setDateModified(new \DateTime()); + + // Créer un historique des statistiques + $statsHistory = new StatsHistory(); + $statsHistory->setDate(new \DateTime()) + ->setStats($stats); + + // Compter les Places avec email et SIRET + $placesWithEmail = 0; + $placesWithSiret = 0; + foreach ($stats->getPlaces() as $place) { + if ($place->getEmail() && $place->getEmail() !== '') { + $placesWithEmail++; + } + if ($place->getSiret() && $place->getSiret() !== '') { + $placesWithSiret++; + } + } + + $statsHistory->setPlacesCount($stats->getPlaces()->count()) + ->setOpeningHoursCount($stats->getAvecHoraires()) + ->setAddressCount($stats->getAvecAdresse()) + ->setWebsiteCount($stats->getAvecSite()) + ->setSiretCount($placesWithSiret) + ->setEmailsCount($placesWithEmail) + // ->setAccessibiliteCount($stats->getAvecAccessibilite()) + // ->setNoteCount($stats->getAvecNote()) + ->setCompletionPercent($stats->getCompletionPercent()) + ->setStats($stats); + + $this->entityManager->persist($statsHistory); + + $this->entityManager->persist($stats); $this->entityManager->flush(); - - // Récupérer l'historique des stats APRÈS que l'entité soit persistée + $statsHistory = $this->entityManager->getRepository(StatsHistory::class) ->createQueryBuilder('sh') ->where('sh.stats = :stats') @@ -375,6 +500,28 @@ final class AdminController extends AbstractController // Mettre à jour les statistiques finales $stats->computeCompletionPercent(); + // Calculer les statistiques de fraîcheur des données OSM + $timestamps = []; + foreach ($stats->getPlaces() as $place) { + if ($place->getOsmDataDate()) { + $timestamps[] = $place->getOsmDataDate()->getTimestamp(); + } + } + + if (!empty($timestamps)) { + // Date la plus ancienne (min) + $minTimestamp = min($timestamps); + $stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp)); + + // Date la plus récente (max) + $maxTimestamp = max($timestamps); + $stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp)); + + // Date moyenne + $avgTimestamp = array_sum($timestamps) / count($timestamps); + $stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp)); + } + if($stats->getDateCreated() == null) { $stats->setDateCreated(new \DateTime()); } diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig index e1c1abe..7418afc 100644 --- a/templates/admin/stats.html.twig +++ b/templates/admin/stats.html.twig @@ -19,6 +19,28 @@ .completion-info { margin-bottom: 2rem; } + .osm-modification-info { + font-size: 0.85rem; + line-height: 1.3; + } + .osm-modification-info .text-muted { + font-size: 0.75rem; + } + .osm-modification-info a { + text-decoration: none; + color: #0d6efd; + } + .osm-modification-info a:hover { + text-decoration: underline; + } + .osm-freshness-info { + font-size: 0.95rem; + line-height: 1.4; + } + .osm-freshness-info .alert { + border-left: 4px solid #0dcaf0; + background-color: #f8f9fa; + } {% endblock %} @@ -59,6 +81,74 @@ {% endif %} + + {# Affichage de la fraîcheur des données OSM #} + {% if stats.osmDataDateMin and stats.osmDataDateMax and stats.osmDataDateAvg %} + {% set now = "now"|date("U") %} + {% set minDate = stats.osmDataDateMin|date("U") %} + {% set maxDate = stats.osmDataDateMax|date("U") %} + {% set avgDate = stats.osmDataDateAvg|date("U") %} + + {% set minDiff = now - minDate %} + {% set maxDiff = now - maxDate %} + {% set avgDiff = now - avgDate %} + + {% set minYears = (minDiff / 31536000)|round(0, 'floor') %} + {% set minMonths = ((minDiff % 31536000) / 2592000)|round(0, 'floor') %} + {% set maxYears = (maxDiff / 31536000)|round(0, 'floor') %} + {% set maxMonths = ((maxDiff % 31536000) / 2592000)|round(0, 'floor') %} + {% set avgYears = (avgDiff / 31536000)|round(0, 'floor') %} + {% set avgMonths = ((avgDiff % 31536000) / 2592000)|round(0, 'floor') %} + +