affichage fraicheur des données

This commit is contained in:
Tykayn 2025-06-19 12:49:30 +02:00 committed by tykayn
parent 43139d50d9
commit ca00f8c0be
4 changed files with 290 additions and 5 deletions

View file

@ -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());
}

View file

@ -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;
}
</style>
{% endblock %}
@ -59,6 +81,74 @@
</div>
</div>
{% 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') %}
<div class="row mb-3">
<div class="col-12">
<div class="alert alert-info osm-freshness-info">
<i class="bi bi-clock-history"></i>
<strong>Fraîcheur des données OSM :</strong>
{% if minYears == maxYears and minMonths == maxMonths %}
Toutes les modifications ont été faites il y a
{% if minYears > 0 %}
{{ minYears }} an{{ minYears > 1 ? 's' : '' }}
{% if minMonths > 0 %}, {{ minMonths }} mois{% endif %}
{% elseif minMonths > 0 %}
{{ minMonths }} mois
{% else %}
moins d'un mois
{% endif %}
{% else %}
Les modifications ont été faites entre il y a
{% if maxYears > 0 %}
{{ maxYears }} an{{ maxYears > 1 ? 's' : '' }}
{% if maxMonths > 0 %}, {{ maxMonths }} mois{% endif %}
{% elseif maxMonths > 0 %}
{{ maxMonths }} mois
{% else %}
moins d'un mois
{% endif %}
et il y a
{% if minYears > 0 %}
{{ minYears }} an{{ minYears > 1 ? 's' : '' }}
{% if minMonths > 0 %}, {{ minMonths }} mois{% endif %}
{% elseif minMonths > 0 %}
{{ minMonths }} mois
{% else %}
moins d'un mois
{% endif %},
en moyenne il y a
{% if avgYears > 0 %}
{{ avgYears }} an{{ avgYears > 1 ? 's' : '' }}
{% if avgMonths > 0 %}, {{ avgMonths }} mois{% endif %}
{% elseif avgMonths > 0 %}
{{ avgMonths }} mois
{% else %}
moins d'un mois
{% endif %}
{% endif %}
</div>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-md-3 col-12">
<span class="badge {% if stats.getCompletionPercent() > 85 %}bg-success{% else %}bg-warning{% endif %}">
@ -954,8 +1044,8 @@ window.updateMarkers = updateMarkers;
{# markClosedSiretsOnTable(); #}
function makeDonutGraphOfTags() {
// Récupérer tous les tags de la colonne 2
const tags = Array.from(document.querySelectorAll('table tbody tr td:nth-child(3)'))
// Récupérer tous les tags de la colonne 4 (Type)
const tags = Array.from(document.querySelectorAll('table tbody tr td:nth-child(4)'))
.map(cell => cell.textContent.trim())
.filter(tag => tag.includes('=')) // Filtrer les cellules qui ne contiennent pas de =
.filter(tag => tag); // Filtrer les cellules vides

View file

@ -107,6 +107,50 @@
{# (si siret clos) #}
</td>
<td>
{% if commerce.osmDataDate %}
{% set now = "now"|date("U") %}
{% set osmDate = commerce.osmDataDate|date("U") %}
{% set diff = now - osmDate %}
{% set years = (diff / 31536000)|round(0, 'floor') %}
{% set months = ((diff % 31536000) / 2592000)|round(0, 'floor') %}
{% set days = ((diff % 2592000) / 86400)|round(0, 'floor') %}
<div class="small osm-modification-info">
<div>
<i class="bi bi-calendar"></i>
{{ commerce.osmDataDate|date('d/m/Y H:i') }}
</div>
{% if commerce.osmUser %}
<div>
<i class="bi bi-person"></i>
<a href="https://www.openstreetmap.org/user/{{ commerce.osmUser }}" target="_blank" title="Voir le profil OSM">
{{ commerce.osmUser }}
</a>
</div>
{% endif %}
<div class="text-muted">
<small>
{% if diff < 86400 %}
Aujourd'hui
{% elseif years > 0 %}
{{ years }} an{{ years > 1 ? 's' : '' }}
{% if months > 0 %}, {{ months }} mois{% endif %}
{% elseif months > 0 %}
{{ months }} mois
{% if days > 0 %}, {{ days }} jour{{ days > 1 ? 's' : '' }}{% endif %}
{% elseif days > 0 %}
{{ days }} jour{{ days > 1 ? 's' : '' }}
{% else %}
Aujourd'hui
{% endif %}
</small>
</div>
</div>
{% else %}
<span class="text-muted">Non disponible</span>
{% endif %}
</td>
<td>
<a href="https://www.openstreetmap.org/{{ commerce.osmKind }}/{{ commerce.osmId }}" title="{{ commerce.osmKind }} - {{ commerce.osmId }} " >
<i class="bi bi-globe"></i>

View file

@ -50,6 +50,10 @@
Siret clos
</th>
<th>
<i class="bi bi-clock-history"></i>
Dernière modif. OSM
</th>
<th>
Osm id</th>
<th>