add logging data for edit form
This commit is contained in:
parent
f7d659119a
commit
b3d4064841
1 changed files with 229 additions and 224 deletions
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
@ -9,7 +9,7 @@ use Symfony\Component\Routing\Attribute\Route;
|
||||||
use App\Entity\Place;
|
use App\Entity\Place;
|
||||||
use App\Entity\Stats;
|
use App\Entity\Stats;
|
||||||
use App\Entity\StatsHistory;
|
use App\Entity\StatsHistory;
|
||||||
use App\Service\Motocultrice;
|
use App\Service\Motocultrice;
|
||||||
use App\Service\BudgetService;
|
use App\Service\BudgetService;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
@ -22,15 +22,14 @@ use DateTime;
|
||||||
|
|
||||||
final class AdminController extends AbstractController
|
final class AdminController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private EntityManagerInterface $entityManager,
|
private EntityManagerInterface $entityManager,
|
||||||
private Motocultrice $motocultrice,
|
private Motocultrice $motocultrice,
|
||||||
private BudgetService $budgetService,
|
private BudgetService $budgetService,
|
||||||
private Environment $twig,
|
private Environment $twig,
|
||||||
private ActionLogger $actionLogger
|
private ActionLogger $actionLogger
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[Route('/admin/labourer-toutes-les-zones', name: 'app_admin_labourer_tout')]
|
#[Route('/admin/labourer-toutes-les-zones', name: 'app_admin_labourer_tout')]
|
||||||
|
@ -38,72 +37,72 @@ final class AdminController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$this->actionLogger->log('labourer_toutes_les_zones', []);
|
|
||||||
$updateExisting =true;
|
|
||||||
|
|
||||||
$stats_all = $this->entityManager->getRepository(Stats::class)->findAll();
|
$this->actionLogger->log('labourer_toutes_les_zones', []);
|
||||||
|
$updateExisting = true;
|
||||||
|
|
||||||
|
$stats_all = $this->entityManager->getRepository(Stats::class)->findAll();
|
||||||
|
|
||||||
echo 'on a trouvé ' . count($stats_all) . ' zones à labourer<br>';
|
echo 'on a trouvé ' . count($stats_all) . ' zones à labourer<br>';
|
||||||
|
|
||||||
foreach($stats_all as $stats) {
|
|
||||||
|
|
||||||
echo '<br> on laboure la zone '.$stats->getZone() . ' ';
|
foreach ($stats_all as $stats) {
|
||||||
|
|
||||||
|
echo '<br> on laboure la zone ' . $stats->getZone() . ' ';
|
||||||
|
|
||||||
$processedCount = 0;
|
$processedCount = 0;
|
||||||
$updatedCount = 0;
|
$updatedCount = 0;
|
||||||
$insee_code = $stats->getZone();
|
$insee_code = $stats->getZone();
|
||||||
// Vérifier si le code INSEE est un nombre valide
|
// Vérifier si le code INSEE est un nombre valide
|
||||||
// Vérifier si les stats ont été modifiées il y a moins de 24h
|
// Vérifier si les stats ont été modifiées il y a moins de 24h
|
||||||
if ($stats->getDateModified() !== null) {
|
if ($stats->getDateModified() !== null) {
|
||||||
$now = new \DateTime();
|
$now = new \DateTime();
|
||||||
$diff = $now->diff($stats->getDateModified());
|
$diff = $now->diff($stats->getDateModified());
|
||||||
$hours = $diff->h + ($diff->days * 24);
|
$hours = $diff->h + ($diff->days * 24);
|
||||||
|
|
||||||
if ($hours < 24) {
|
if ($hours < 24) {
|
||||||
echo 'Stats modifiées il y a moins de 24h - on passe au suivant<br>';
|
echo 'Stats modifiées il y a moins de 24h - on passe au suivant<br>';
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_numeric($insee_code) || $insee_code == 'undefined' || $insee_code == '') {
|
|
||||||
echo 'Code INSEE invalide : ' . $insee_code . ' - on passe au suivant<br>';
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!is_numeric($insee_code) || $insee_code == 'undefined' || $insee_code == '') {
|
||||||
|
echo 'Code INSEE invalide : ' . $insee_code . ' - on passe au suivant<br>';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$places_overpass = $this->motocultrice->labourer($stats->getZone());
|
$places_overpass = $this->motocultrice->labourer($stats->getZone());
|
||||||
$places = $places_overpass;
|
$places = $places_overpass;
|
||||||
foreach ($places as $placeData) {
|
foreach ($places as $placeData) {
|
||||||
|
|
||||||
|
|
||||||
// Vérifier si le lieu existe déjà
|
// Vérifier si le lieu existe déjà
|
||||||
$existingPlace = $this->entityManager->getRepository(Place::class)
|
$existingPlace = $this->entityManager->getRepository(Place::class)
|
||||||
->findOneBy(['osmId' => $placeData['id']]);
|
->findOneBy(['osmId' => $placeData['id']]);
|
||||||
|
|
||||||
if (!$existingPlace) {
|
if (!$existingPlace) {
|
||||||
$place = new Place();
|
$place = new Place();
|
||||||
$place->setOsmId($placeData['id'])
|
$place->setOsmId($placeData['id'])
|
||||||
->setOsmKind($placeData['type'])
|
->setOsmKind($placeData['type'])
|
||||||
->setZipCode($insee_code)
|
->setZipCode($insee_code)
|
||||||
->setUuidForUrl($this->motocultrice->uuid_create())
|
->setUuidForUrl($this->motocultrice->uuid_create())
|
||||||
->setModifiedDate(new \DateTime())
|
->setModifiedDate(new \DateTime())
|
||||||
->setStats($stats)
|
->setStats($stats)
|
||||||
->setDead(false)
|
->setDead(false)
|
||||||
->setOptedOut(false)
|
->setOptedOut(false)
|
||||||
->setMainTag($this->motocultrice->find_main_tag($placeData['tags']) ?? '')
|
->setMainTag($this->motocultrice->find_main_tag($placeData['tags']) ?? '')
|
||||||
->setStreet($this->motocultrice->find_street($placeData['tags']) ?? '')
|
->setStreet($this->motocultrice->find_street($placeData['tags']) ?? '')
|
||||||
->setHousenumber($this->motocultrice->find_housenumber($placeData['tags']) ?? '')
|
->setHousenumber($this->motocultrice->find_housenumber($placeData['tags']) ?? '')
|
||||||
->setSiret($this->motocultrice->find_siret($placeData['tags']) ?? '')
|
->setSiret($this->motocultrice->find_siret($placeData['tags']) ?? '')
|
||||||
->setAskedHumainsSupport(false)
|
->setAskedHumainsSupport(false)
|
||||||
->setLastContactAttemptDate(null)
|
->setLastContactAttemptDate(null)
|
||||||
->setNote($this->motocultrice->find_tag($placeData['tags'], 'note') ? true : false)
|
->setNote($this->motocultrice->find_tag($placeData['tags'], 'note') ? true : false)
|
||||||
->setNoteContent($this->motocultrice->find_tag($placeData['tags'], 'note') ?? '')
|
->setNoteContent($this->motocultrice->find_tag($placeData['tags'], 'note') ?? '')
|
||||||
->setPlaceCount(0)
|
->setPlaceCount(0)
|
||||||
// ->setOsmData($placeData['modified'] ?? null)
|
// ->setOsmData($placeData['modified'] ?? null)
|
||||||
;
|
;
|
||||||
|
|
||||||
// Mettre à jour les données depuis Overpass
|
// Mettre à jour les données depuis Overpass
|
||||||
$place->update_place_from_overpass_data($placeData);
|
$place->update_place_from_overpass_data($placeData);
|
||||||
|
|
||||||
$this->entityManager->persist($place);
|
$this->entityManager->persist($place);
|
||||||
$stats->addPlace($place);
|
$stats->addPlace($place);
|
||||||
$processedCount++;
|
$processedCount++;
|
||||||
|
@ -118,20 +117,20 @@ final class AdminController extends AbstractController
|
||||||
$this->entityManager->persist($existingPlace);
|
$this->entityManager->persist($existingPlace);
|
||||||
$updatedCount++;
|
$updatedCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// mettre à jour les stats
|
// mettre à jour les stats
|
||||||
// Récupérer tous les commerces de la zone
|
// Récupérer tous les commerces de la zone
|
||||||
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
|
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
|
||||||
|
|
||||||
// Récupérer les stats existantes pour la zone
|
// Récupérer les stats existantes pour la zone
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||||
if(!$stats) {
|
if (!$stats) {
|
||||||
$stats = new Stats();
|
$stats = new Stats();
|
||||||
$stats->setZone($insee_code);
|
$stats->setZone($insee_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
$urls = $stats->getAllCTCUrlsMap();
|
$urls = $stats->getAllCTCUrlsMap();
|
||||||
|
|
||||||
$statsHistory = $this->entityManager->getRepository(StatsHistory::class)
|
$statsHistory = $this->entityManager->getRepository(StatsHistory::class)
|
||||||
->createQueryBuilder('sh')
|
->createQueryBuilder('sh')
|
||||||
->where('sh.stats = :stats')
|
->where('sh.stats = :stats')
|
||||||
|
@ -140,7 +139,7 @@ final class AdminController extends AbstractController
|
||||||
->setMaxResults(365)
|
->setMaxResults(365)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult();
|
->getResult();
|
||||||
|
|
||||||
// Calculer les statistiques
|
// Calculer les statistiques
|
||||||
$calculatedStats = $this->motocultrice->calculateStats($commerces);
|
$calculatedStats = $this->motocultrice->calculateStats($commerces);
|
||||||
|
|
||||||
|
@ -151,7 +150,7 @@ final class AdminController extends AbstractController
|
||||||
$stats->setAvecSite($calculatedStats['counters']['avec_site']);
|
$stats->setAvecSite($calculatedStats['counters']['avec_site']);
|
||||||
$stats->setAvecAccessibilite($calculatedStats['counters']['avec_accessibilite']);
|
$stats->setAvecAccessibilite($calculatedStats['counters']['avec_accessibilite']);
|
||||||
$stats->setAvecNote($calculatedStats['counters']['avec_note']);
|
$stats->setAvecNote($calculatedStats['counters']['avec_note']);
|
||||||
|
|
||||||
$stats->setCompletionPercent($calculatedStats['completion_percent']);
|
$stats->setCompletionPercent($calculatedStats['completion_percent']);
|
||||||
|
|
||||||
// Associer les stats à chaque commerce
|
// Associer les stats à chaque commerce
|
||||||
|
@ -169,22 +168,22 @@ final class AdminController extends AbstractController
|
||||||
$timestamps[] = $place->getOsmDataDate()->getTimestamp();
|
$timestamps[] = $place->getOsmDataDate()->getTimestamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($timestamps)) {
|
if (!empty($timestamps)) {
|
||||||
// Date la plus ancienne (min)
|
// Date la plus ancienne (min)
|
||||||
$minTimestamp = min($timestamps);
|
$minTimestamp = min($timestamps);
|
||||||
$stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp));
|
$stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp));
|
||||||
|
|
||||||
// Date la plus récente (max)
|
// Date la plus récente (max)
|
||||||
$maxTimestamp = max($timestamps);
|
$maxTimestamp = max($timestamps);
|
||||||
$stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp));
|
$stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp));
|
||||||
|
|
||||||
// Date moyenne
|
// Date moyenne
|
||||||
$avgTimestamp = array_sum($timestamps) / count($timestamps);
|
$avgTimestamp = array_sum($timestamps) / count($timestamps);
|
||||||
$stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp));
|
$stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($stats->getDateCreated() == null) {
|
if ($stats->getDateCreated() == null) {
|
||||||
$stats->setDateCreated(new \DateTime());
|
$stats->setDateCreated(new \DateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +192,7 @@ final class AdminController extends AbstractController
|
||||||
// Créer un historique des statistiques
|
// Créer un historique des statistiques
|
||||||
$statsHistory = new StatsHistory();
|
$statsHistory = new StatsHistory();
|
||||||
$statsHistory->setDate(new \DateTime())
|
$statsHistory->setDate(new \DateTime())
|
||||||
->setStats($stats);
|
->setStats($stats);
|
||||||
|
|
||||||
// Compter les Places avec email et SIRET
|
// Compter les Places avec email et SIRET
|
||||||
$placesWithEmail = 0;
|
$placesWithEmail = 0;
|
||||||
|
@ -208,34 +207,33 @@ final class AdminController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
$statsHistory->setPlacesCount($stats->getPlaces()->count())
|
$statsHistory->setPlacesCount($stats->getPlaces()->count())
|
||||||
->setOpeningHoursCount($stats->getAvecHoraires())
|
->setOpeningHoursCount($stats->getAvecHoraires())
|
||||||
->setAddressCount($stats->getAvecAdresse())
|
->setAddressCount($stats->getAvecAdresse())
|
||||||
->setWebsiteCount($stats->getAvecSite())
|
->setWebsiteCount($stats->getAvecSite())
|
||||||
->setSiretCount($placesWithSiret)
|
->setSiretCount($placesWithSiret)
|
||||||
->setEmailsCount($placesWithEmail)
|
->setEmailsCount($placesWithEmail)
|
||||||
->setCompletionPercent($stats->getCompletionPercent())
|
->setCompletionPercent($stats->getCompletionPercent())
|
||||||
->setStats($stats);
|
->setStats($stats);
|
||||||
|
|
||||||
$this->entityManager->persist($statsHistory);
|
$this->entityManager->persist($statsHistory);
|
||||||
|
|
||||||
|
|
||||||
$this->entityManager->persist($stats);
|
$this->entityManager->persist($stats);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$message = 'Labourage terminé avec succès. ' . $processedCount . ' nouveaux lieux traités.';
|
$message = 'Labourage terminé avec succès. ' . $processedCount . ' nouveaux lieux traités.';
|
||||||
if ($updateExisting) {
|
if ($updateExisting) {
|
||||||
$message .= ' ' . $updatedCount . ' lieux existants mis à jour pour la zone '.$stats->getName().' ('.$stats->getZone().').';
|
$message .= ' ' . $updatedCount . ' lieux existants mis à jour pour la zone ' . $stats->getName() . ' (' . $stats->getZone() . ').';
|
||||||
}
|
}
|
||||||
$this->addFlash('success', $message);
|
$this->addFlash('success', $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'Labourage des ' . count($stats_all) . ' zones terminé avec succès.');
|
$this->addFlash('success', 'Labourage des ' . count($stats_all) . ' zones terminé avec succès.');
|
||||||
return $this->redirectToRoute('app_public_dashboard');
|
return $this->redirectToRoute('app_public_dashboard');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/admin', name: 'app_admin')]
|
#[Route('/admin', name: 'app_admin')]
|
||||||
|
@ -249,7 +247,7 @@ final class AdminController extends AbstractController
|
||||||
#[Route('/admin/stats/{insee_code}', name: 'app_admin_stats')]
|
#[Route('/admin/stats/{insee_code}', name: 'app_admin_stats')]
|
||||||
public function calculer_stats(string $insee_code): Response
|
public function calculer_stats(string $insee_code): Response
|
||||||
{
|
{
|
||||||
|
|
||||||
// Récupérer les stats existantes pour la zone
|
// Récupérer les stats existantes pour la zone
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||||
if (!$stats) {
|
if (!$stats) {
|
||||||
|
@ -257,11 +255,11 @@ final class AdminController extends AbstractController
|
||||||
return $this->redirectToRoute('app_admin_labourer', ['insee_code' => $insee_code]);
|
return $this->redirectToRoute('app_admin_labourer', ['insee_code' => $insee_code]);
|
||||||
}
|
}
|
||||||
$commerces = $stats->getPlaces();
|
$commerces = $stats->getPlaces();
|
||||||
|
|
||||||
$this->actionLogger->log('stats_de_ville', ['insee_code' => $insee_code, 'nom' => $stats->getZone()]);
|
$this->actionLogger->log('stats_de_ville', ['insee_code' => $insee_code, 'nom' => $stats->getZone()]);
|
||||||
// Récupérer tous les commerces de la zone
|
// Récupérer tous les commerces de la zone
|
||||||
// $commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code, 'dead' => false]);
|
// $commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code, 'dead' => false]);
|
||||||
if(!$stats) {
|
if (!$stats) {
|
||||||
// Si aucune stat n'existe, on en crée une vide pour éviter les erreurs, mais sans la sauvegarder
|
// Si aucune stat n'existe, on en crée une vide pour éviter les erreurs, mais sans la sauvegarder
|
||||||
$stats = new Stats();
|
$stats = new Stats();
|
||||||
$stats->setZone($insee_code);
|
$stats->setZone($insee_code);
|
||||||
|
@ -276,8 +274,8 @@ final class AdminController extends AbstractController
|
||||||
->orderBy('sh.id', 'DESC')
|
->orderBy('sh.id', 'DESC')
|
||||||
->setMaxResults(100)
|
->setMaxResults(100)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult();
|
->getResult();
|
||||||
|
|
||||||
// Données pour le graphique des modifications par trimestre
|
// Données pour le graphique des modifications par trimestre
|
||||||
$modificationsByQuarter = [];
|
$modificationsByQuarter = [];
|
||||||
foreach ($commerces as $commerce) {
|
foreach ($commerces as $commerce) {
|
||||||
|
@ -335,12 +333,18 @@ final class AdminController extends AbstractController
|
||||||
#[Route('/admin/placeType/{osm_kind}/{osm_id}', name: 'app_admin_by_osm_id')]
|
#[Route('/admin/placeType/{osm_kind}/{osm_id}', name: 'app_admin_by_osm_id')]
|
||||||
public function placeType(string $osm_kind, string $osm_id): Response
|
public function placeType(string $osm_kind, string $osm_id): Response
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('admin/placeType', ['osm_kind' => $osm_kind, 'osm_id' => $osm_id]);
|
|
||||||
$place = $this->entityManager->getRepository(Place::class)->findOneBy(['osm_kind' => $osm_kind, 'osmId' => $osm_id]);
|
$place = $this->entityManager->getRepository(Place::class)->findOneBy(['osm_kind' => $osm_kind, 'osmId' => $osm_id]);
|
||||||
if($place) {
|
if ($place) {
|
||||||
|
$this->actionLogger->log('ERROR_admin/placeType', ['osm_kind' => $osm_kind, 'osm_id' => $osm_id,
|
||||||
|
'name' => $place->getName(),
|
||||||
|
'code_insee' => $place->getZipCode(),
|
||||||
|
'uuid' => $place->getUuidForUrl()
|
||||||
|
]);
|
||||||
return $this->redirectToRoute('app_admin_commerce', ['id' => $place->getId()]);
|
return $this->redirectToRoute('app_admin_commerce', ['id' => $place->getId()]);
|
||||||
} else {
|
} else {
|
||||||
$this->addFlash('error', 'Le lieu n\'existe pas.');
|
$this->addFlash('error', 'Le lieu n\'existe pas.');
|
||||||
|
$this->actionLogger->log('ERROR_admin/placeType', ['osm_kind' => $osm_kind, 'osm_id' => $osm_id]);
|
||||||
return $this->redirectToRoute('app_public_index');
|
return $this->redirectToRoute('app_public_index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,8 +358,7 @@ final class AdminController extends AbstractController
|
||||||
public function commerce(int $id): Response
|
public function commerce(int $id): Response
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->actionLogger->log('admin_show_commerce_form_id', ['id' => $id]);
|
|
||||||
|
|
||||||
// Vérifier si on est en prod
|
// Vérifier si on est en prod
|
||||||
if ($this->getParameter('kernel.environment') === 'prod') {
|
if ($this->getParameter('kernel.environment') === 'prod') {
|
||||||
$this->addFlash('error', 'Vous n\'avez pas accès à cette page en production.');
|
$this->addFlash('error', 'Vous n\'avez pas accès à cette page en production.');
|
||||||
|
@ -365,12 +368,18 @@ final class AdminController extends AbstractController
|
||||||
|
|
||||||
if (!$commerce) {
|
if (!$commerce) {
|
||||||
throw $this->createNotFoundException('Commerce non trouvé');
|
throw $this->createNotFoundException('Commerce non trouvé');
|
||||||
|
$this->actionLogger->log('ERROR_admin_show_commerce_form_id', ['id' => $id]);
|
||||||
}
|
}
|
||||||
|
$this->actionLogger->log('ERROR_admin_show_commerce_form_id', [
|
||||||
|
'id' => $id,
|
||||||
|
'name' => $commerce->getName(),
|
||||||
|
'code_insee' => $commerce->getZipCode(),
|
||||||
|
'uuid' => $commerce->getUuidForUrl()
|
||||||
|
]);
|
||||||
// Redirection vers la page de modification avec les paramètres nécessaires
|
// Redirection vers la page de modification avec les paramètres nécessaires
|
||||||
return $this->redirectToRoute('app_public_edit', [
|
return $this->redirectToRoute('app_public_edit', [
|
||||||
'zipcode' => $commerce->getZipCode(),
|
'zipcode' => $commerce->getZipCode(),
|
||||||
'name' => $commerce->getName()!='' ? $commerce->getName() : '?',
|
'name' => $commerce->getName() != '' ? $commerce->getName() : '?',
|
||||||
'uuid' => $commerce->getUuidForUrl()
|
'uuid' => $commerce->getUuidForUrl()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -402,13 +411,13 @@ final class AdminController extends AbstractController
|
||||||
$stats->setDateCreated(new \DateTime());
|
$stats->setDateCreated(new \DateTime());
|
||||||
$stats->setDateModified(new \DateTime());
|
$stats->setDateModified(new \DateTime());
|
||||||
$stats->setZone($insee_code)
|
$stats->setZone($insee_code)
|
||||||
->setPlacesCount(0)
|
->setPlacesCount(0)
|
||||||
->setAvecHoraires(0)
|
->setAvecHoraires(0)
|
||||||
->setAvecAdresse(0)
|
->setAvecAdresse(0)
|
||||||
->setAvecSite(0)
|
->setAvecSite(0)
|
||||||
->setAvecAccessibilite(0)
|
->setAvecAccessibilite(0)
|
||||||
->setAvecNote(0)
|
->setAvecNote(0)
|
||||||
->setCompletionPercent(0);
|
->setCompletionPercent(0);
|
||||||
$this->entityManager->persist($stats);
|
$this->entityManager->persist($stats);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
}
|
}
|
||||||
|
@ -439,8 +448,6 @@ final class AdminController extends AbstractController
|
||||||
$this->addFlash('error', 'Erreur lors de la récupération des données de l\'API : ' . $e->getMessage());
|
$this->addFlash('error', 'Erreur lors de la récupération des données de l\'API : ' . $e->getMessage());
|
||||||
|
|
||||||
$this->actionLogger->log('ERROR_labourer_geoapi', ['insee_code' => $insee_code, 'message' => $e->getMessage()]);
|
$this->actionLogger->log('ERROR_labourer_geoapi', ['insee_code' => $insee_code, 'message' => $e->getMessage()]);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer le budget annuel via l'API des finances publiques
|
// Récupérer le budget annuel via l'API des finances publiques
|
||||||
|
@ -460,14 +467,14 @@ final class AdminController extends AbstractController
|
||||||
->where('p.zip_code = :zip_code')
|
->where('p.zip_code = :zip_code')
|
||||||
->setParameter('zip_code', $insee_code)
|
->setParameter('zip_code', $insee_code)
|
||||||
->getQuery();
|
->getQuery();
|
||||||
|
|
||||||
$existingPlacesResult = $existingPlacesQuery->getResult();
|
$existingPlacesResult = $existingPlacesQuery->getResult();
|
||||||
$placesByOsmKey = [];
|
$placesByOsmKey = [];
|
||||||
|
|
||||||
foreach ($existingPlacesResult as $placeData) {
|
foreach ($existingPlacesResult as $placeData) {
|
||||||
|
|
||||||
// var_dump($placeData);
|
// var_dump($placeData);
|
||||||
// die( );
|
// die( );
|
||||||
// Clé unique combinant osmId ET osmKind pour éviter les conflits entre node/way
|
// Clé unique combinant osmId ET osmKind pour éviter les conflits entre node/way
|
||||||
$osmKey = $placeData['osm_kind'] . '_' . $placeData['osmId'];
|
$osmKey = $placeData['osm_kind'] . '_' . $placeData['osmId'];
|
||||||
$placesByOsmKey[$osmKey] = $placeData['id'];
|
$placesByOsmKey[$osmKey] = $placeData['id'];
|
||||||
|
@ -482,7 +489,7 @@ final class AdminController extends AbstractController
|
||||||
$overpass_osm_ids = array_map(fn($place) => $place['id'], $places_overpass);
|
$overpass_osm_ids = array_map(fn($place) => $place['id'], $places_overpass);
|
||||||
|
|
||||||
// RÉDUCTION de la taille du batch pour éviter l'explosion mémoire
|
// RÉDUCTION de la taille du batch pour éviter l'explosion mémoire
|
||||||
$batchSize = 10000;
|
$batchSize = 10000;
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$notFoundOsmKeys = [];
|
$notFoundOsmKeys = [];
|
||||||
foreach ($places_overpass as $placeData) {
|
foreach ($places_overpass as $placeData) {
|
||||||
|
@ -492,24 +499,24 @@ final class AdminController extends AbstractController
|
||||||
if (!$existingPlaceId) {
|
if (!$existingPlaceId) {
|
||||||
$place = new Place();
|
$place = new Place();
|
||||||
$place->setOsmId($placeData['id'])
|
$place->setOsmId($placeData['id'])
|
||||||
->setOsmKind($placeData['type'])
|
->setOsmKind($placeData['type'])
|
||||||
->setZipCode($insee_code)
|
->setZipCode($insee_code)
|
||||||
->setUuidForUrl($this->motocultrice->uuid_create())
|
->setUuidForUrl($this->motocultrice->uuid_create())
|
||||||
->setModifiedDate(new \DateTime())
|
->setModifiedDate(new \DateTime())
|
||||||
->setStats($stats)
|
->setStats($stats)
|
||||||
->setDead(false)
|
->setDead(false)
|
||||||
->setOptedOut(false)
|
->setOptedOut(false)
|
||||||
->setMainTag($this->motocultrice->find_main_tag($placeData['tags']) ?? '')
|
->setMainTag($this->motocultrice->find_main_tag($placeData['tags']) ?? '')
|
||||||
->setStreet($this->motocultrice->find_street($placeData['tags']) ?? '')
|
->setStreet($this->motocultrice->find_street($placeData['tags']) ?? '')
|
||||||
->setHousenumber($this->motocultrice->find_housenumber($placeData['tags']) ?? '')
|
->setHousenumber($this->motocultrice->find_housenumber($placeData['tags']) ?? '')
|
||||||
->setSiret($this->motocultrice->find_siret($placeData['tags']) ?? '')
|
->setSiret($this->motocultrice->find_siret($placeData['tags']) ?? '')
|
||||||
->setAskedHumainsSupport(false)
|
->setAskedHumainsSupport(false)
|
||||||
->setLastContactAttemptDate(null)
|
->setLastContactAttemptDate(null)
|
||||||
->setNote($this->motocultrice->find_tag($placeData['tags'], 'note') ? true : false)
|
->setNote($this->motocultrice->find_tag($placeData['tags'], 'note') ? true : false)
|
||||||
->setNoteContent($this->motocultrice->find_tag($placeData['tags'], 'note') ?? '')
|
->setNoteContent($this->motocultrice->find_tag($placeData['tags'], 'note') ?? '')
|
||||||
->setPlaceCount(0)
|
->setPlaceCount(0)
|
||||||
// ->setOsmData($placeData['modified'] ?? null)
|
// ->setOsmData($placeData['modified'] ?? null)
|
||||||
;
|
;
|
||||||
$place->update_place_from_overpass_data($placeData);
|
$place->update_place_from_overpass_data($placeData);
|
||||||
$this->entityManager->persist($place);
|
$this->entityManager->persist($place);
|
||||||
$stats->addPlace($place);
|
$stats->addPlace($place);
|
||||||
|
@ -533,15 +540,15 @@ final class AdminController extends AbstractController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
// FLUSH/CLEAR plus fréquent pour éviter l'explosion mémoire
|
// FLUSH/CLEAR plus fréquent pour éviter l'explosion mémoire
|
||||||
if (($i % $batchSize) === 0) {
|
if (($i % $batchSize) === 0) {
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
$this->entityManager->clear();
|
$this->entityManager->clear();
|
||||||
|
|
||||||
// Forcer le garbage collector
|
// Forcer le garbage collector
|
||||||
gc_collect_cycles();
|
gc_collect_cycles();
|
||||||
|
|
||||||
// Recharger les stats après clear
|
// Recharger les stats après clear
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||||
}
|
}
|
||||||
|
@ -556,11 +563,11 @@ final class AdminController extends AbstractController
|
||||||
$osmKey = $placeData['type'] . '_' . $placeData['id'];
|
$osmKey = $placeData['type'] . '_' . $placeData['id'];
|
||||||
$overpassOsmKeys[$osmKey] = true;
|
$overpassOsmKeys[$osmKey] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ÉLIMINER LES DOUBLONS dans les lieux existants avant suppression
|
// ÉLIMINER LES DOUBLONS dans les lieux existants avant suppression
|
||||||
$uniquePlacesByOsmKey = [];
|
$uniquePlacesByOsmKey = [];
|
||||||
$duplicatePlaceIds = [];
|
$duplicatePlaceIds = [];
|
||||||
|
|
||||||
foreach ($placesByOsmKey as $osmKey => $placeId) {
|
foreach ($placesByOsmKey as $osmKey => $placeId) {
|
||||||
if (isset($uniquePlacesByOsmKey[$osmKey])) {
|
if (isset($uniquePlacesByOsmKey[$osmKey])) {
|
||||||
// Doublon détecté, garder le plus ancien (ID le plus petit)
|
// Doublon détecté, garder le plus ancien (ID le plus petit)
|
||||||
|
@ -574,7 +581,7 @@ final class AdminController extends AbstractController
|
||||||
$uniquePlacesByOsmKey[$osmKey] = $placeId;
|
$uniquePlacesByOsmKey[$osmKey] = $placeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supprimer les doublons détectés
|
// Supprimer les doublons détectés
|
||||||
if (!empty($duplicatePlaceIds)) {
|
if (!empty($duplicatePlaceIds)) {
|
||||||
$duplicateDeleteQuery = $this->entityManager->createQuery(
|
$duplicateDeleteQuery = $this->entityManager->createQuery(
|
||||||
|
@ -583,7 +590,7 @@ final class AdminController extends AbstractController
|
||||||
$duplicateDeleteQuery->setParameter('placeIds', $duplicatePlaceIds);
|
$duplicateDeleteQuery->setParameter('placeIds', $duplicatePlaceIds);
|
||||||
$duplicateDeletedCount = $duplicateDeleteQuery->execute();
|
$duplicateDeletedCount = $duplicateDeleteQuery->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trouver les lieux existants uniques qui ne sont plus dans overpass
|
// Trouver les lieux existants uniques qui ne sont plus dans overpass
|
||||||
$placesToDelete = [];
|
$placesToDelete = [];
|
||||||
foreach ($uniquePlacesByOsmKey as $osmKey => $placeId) {
|
foreach ($uniquePlacesByOsmKey as $osmKey => $placeId) {
|
||||||
|
@ -591,7 +598,7 @@ final class AdminController extends AbstractController
|
||||||
$placesToDelete[] = $placeId;
|
$placesToDelete[] = $placeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supprimer les lieux non trouvés dans overpass en une seule requête
|
// Supprimer les lieux non trouvés dans overpass en une seule requête
|
||||||
if (!empty($placesToDelete)) {
|
if (!empty($placesToDelete)) {
|
||||||
$deleteQuery = $this->entityManager->createQuery(
|
$deleteQuery = $this->entityManager->createQuery(
|
||||||
|
@ -605,10 +612,10 @@ final class AdminController extends AbstractController
|
||||||
// Flush final
|
// Flush final
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
$this->entityManager->clear();
|
$this->entityManager->clear();
|
||||||
|
|
||||||
// NETTOYAGE D'UNICITÉ des Places après le clear pour éliminer les doublons persistants
|
// NETTOYAGE D'UNICITÉ des Places après le clear pour éliminer les doublons persistants
|
||||||
// Approche en deux étapes pour éviter l'erreur MySQL "target table for update in FROM clause"
|
// Approche en deux étapes pour éviter l'erreur MySQL "target table for update in FROM clause"
|
||||||
|
|
||||||
// Étape 1 : Identifier les doublons
|
// Étape 1 : Identifier les doublons
|
||||||
$duplicateIdsQuery = $this->entityManager->createQuery(
|
$duplicateIdsQuery = $this->entityManager->createQuery(
|
||||||
'SELECT p.id FROM App\Entity\Place p
|
'SELECT p.id FROM App\Entity\Place p
|
||||||
|
@ -619,7 +626,7 @@ final class AdminController extends AbstractController
|
||||||
)'
|
)'
|
||||||
);
|
);
|
||||||
$duplicateIds = $duplicateIdsQuery->getResult();
|
$duplicateIds = $duplicateIdsQuery->getResult();
|
||||||
|
|
||||||
// Étape 2 : Supprimer les doublons identifiés
|
// Étape 2 : Supprimer les doublons identifiés
|
||||||
if (!empty($duplicateIds)) {
|
if (!empty($duplicateIds)) {
|
||||||
$duplicateIds = array_column($duplicateIds, 'id');
|
$duplicateIds = array_column($duplicateIds, 'id');
|
||||||
|
@ -631,19 +638,19 @@ final class AdminController extends AbstractController
|
||||||
} else {
|
} else {
|
||||||
$duplicateCleanupCount = 0;
|
$duplicateCleanupCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer tous les commerces de la zone qui n'ont pas été supprimés
|
// Récupérer tous les commerces de la zone qui n'ont pas été supprimés
|
||||||
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
|
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
|
||||||
|
|
||||||
// Récupérer les stats existantes pour la zone
|
// Récupérer les stats existantes pour la zone
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||||
if(!$stats) {
|
if (!$stats) {
|
||||||
$stats = new Stats();
|
$stats = new Stats();
|
||||||
$stats->setZone($insee_code);
|
$stats->setZone($insee_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
$urls = $stats->getAllCTCUrlsMap();
|
$urls = $stats->getAllCTCUrlsMap();
|
||||||
|
|
||||||
$statsHistory = $this->entityManager->getRepository(StatsHistory::class)
|
$statsHistory = $this->entityManager->getRepository(StatsHistory::class)
|
||||||
->createQueryBuilder('sh')
|
->createQueryBuilder('sh')
|
||||||
->where('sh.stats = :stats')
|
->where('sh.stats = :stats')
|
||||||
|
@ -652,7 +659,7 @@ final class AdminController extends AbstractController
|
||||||
->setMaxResults(365)
|
->setMaxResults(365)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult();
|
->getResult();
|
||||||
|
|
||||||
// Calculer les statistiques
|
// Calculer les statistiques
|
||||||
$calculatedStats = $this->motocultrice->calculateStats($commerces);
|
$calculatedStats = $this->motocultrice->calculateStats($commerces);
|
||||||
|
|
||||||
|
@ -680,22 +687,22 @@ final class AdminController extends AbstractController
|
||||||
$timestamps[] = $place->getOsmDataDate()->getTimestamp();
|
$timestamps[] = $place->getOsmDataDate()->getTimestamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($timestamps)) {
|
if (!empty($timestamps)) {
|
||||||
// Date la plus ancienne (min)
|
// Date la plus ancienne (min)
|
||||||
$minTimestamp = min($timestamps);
|
$minTimestamp = min($timestamps);
|
||||||
$stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp));
|
$stats->setOsmDataDateMin(new \DateTime('@' . $minTimestamp));
|
||||||
|
|
||||||
// Date la plus récente (max)
|
// Date la plus récente (max)
|
||||||
$maxTimestamp = max($timestamps);
|
$maxTimestamp = max($timestamps);
|
||||||
$stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp));
|
$stats->setOsmDataDateMax(new \DateTime('@' . $maxTimestamp));
|
||||||
|
|
||||||
// Date moyenne
|
// Date moyenne
|
||||||
$avgTimestamp = array_sum($timestamps) / count($timestamps);
|
$avgTimestamp = array_sum($timestamps) / count($timestamps);
|
||||||
$stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp));
|
$stats->setOsmDataDateAvg(new \DateTime('@' . (int)$avgTimestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($stats->getDateCreated() == null) {
|
if ($stats->getDateCreated() == null) {
|
||||||
$stats->setDateCreated(new \DateTime());
|
$stats->setDateCreated(new \DateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +711,7 @@ final class AdminController extends AbstractController
|
||||||
// Créer un historique des statistiques
|
// Créer un historique des statistiques
|
||||||
$statsHistory = new StatsHistory();
|
$statsHistory = new StatsHistory();
|
||||||
$statsHistory->setDate(new \DateTime())
|
$statsHistory->setDate(new \DateTime())
|
||||||
->setStats($stats);
|
->setStats($stats);
|
||||||
|
|
||||||
// Compter les Places avec email et SIRET
|
// Compter les Places avec email et SIRET
|
||||||
$placesWithEmail = 0;
|
$placesWithEmail = 0;
|
||||||
|
@ -721,25 +728,24 @@ final class AdminController extends AbstractController
|
||||||
if ($place->getName() && $place->getName() !== '') {
|
if ($place->getName() && $place->getName() !== '') {
|
||||||
$placesWithName++;
|
$placesWithName++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$statsHistory->setPlacesCount($stats->getPlaces()->count())
|
$statsHistory->setPlacesCount($stats->getPlaces()->count())
|
||||||
->setOpeningHoursCount($stats->getAvecHoraires())
|
->setOpeningHoursCount($stats->getAvecHoraires())
|
||||||
->setAddressCount($stats->getAvecAdresse())
|
->setAddressCount($stats->getAvecAdresse())
|
||||||
->setWebsiteCount($stats->getAvecSite())
|
->setWebsiteCount($stats->getAvecSite())
|
||||||
->setNamesCount($placesWithName)
|
->setNamesCount($placesWithName)
|
||||||
->setSiretCount($placesWithSiret)
|
->setSiretCount($placesWithSiret)
|
||||||
->setEmailsCount($placesWithEmail)
|
->setEmailsCount($placesWithEmail)
|
||||||
->setCompletionPercent($stats->getCompletionPercent())
|
->setCompletionPercent($stats->getCompletionPercent())
|
||||||
->setStats($stats);
|
->setStats($stats);
|
||||||
|
|
||||||
$this->entityManager->persist($statsHistory);
|
$this->entityManager->persist($statsHistory);
|
||||||
|
|
||||||
|
|
||||||
$this->entityManager->persist($stats);
|
$this->entityManager->persist($stats);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$message = 'Labourage terminé avec succès. ' . $processedCount . ' nouveaux lieux traités.';
|
$message = 'Labourage terminé avec succès. ' . $processedCount . ' nouveaux lieux traités.';
|
||||||
if ($updateExisting) {
|
if ($updateExisting) {
|
||||||
$message .= ' ' . $updatedCount . ' lieux existants mis à jour.';
|
$message .= ' ' . $updatedCount . ' lieux existants mis à jour.';
|
||||||
|
@ -747,7 +753,7 @@ final class AdminController extends AbstractController
|
||||||
if ($deletedCount > 0) {
|
if ($deletedCount > 0) {
|
||||||
$message .= ' ' . $deletedCount . ' lieux ont été supprimés.';
|
$message .= ' ' . $deletedCount . ' lieux ont été supprimés.';
|
||||||
}
|
}
|
||||||
$message .= ' Zone : '.$stats->getName().' ('.$stats->getZone().').';
|
$message .= ' Zone : ' . $stats->getName() . ' (' . $stats->getZone() . ').';
|
||||||
$this->addFlash('success', $message);
|
$this->addFlash('success', $message);
|
||||||
|
|
||||||
// Afficher le log des objets non trouvés à la fin
|
// Afficher le log des objets non trouvés à la fin
|
||||||
|
@ -760,7 +766,7 @@ final class AdminController extends AbstractController
|
||||||
$this->addFlash('error', 'Erreur lors du labourage : ' . $e->getMessage());
|
$this->addFlash('error', 'Erreur lors du labourage : ' . $e->getMessage());
|
||||||
die(var_dump($e));
|
die(var_dump($e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// return $this->redirectToRoute('app_public_dashboard');
|
// return $this->redirectToRoute('app_public_dashboard');
|
||||||
return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
|
return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
|
||||||
}
|
}
|
||||||
|
@ -770,11 +776,11 @@ final class AdminController extends AbstractController
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('admin/delete_place', ['id' => $id]);
|
$this->actionLogger->log('admin/delete_place', ['id' => $id]);
|
||||||
$commerce = $this->entityManager->getRepository(Place::class)->find($id);
|
$commerce = $this->entityManager->getRepository(Place::class)->find($id);
|
||||||
if($commerce) {
|
if ($commerce) {
|
||||||
$this->entityManager->remove($commerce);
|
$this->entityManager->remove($commerce);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'Le lieu '.$commerce->getName().' a été supprimé avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.');
|
$this->addFlash('success', 'Le lieu ' . $commerce->getName() . ' a été supprimé avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.');
|
||||||
} else {
|
} else {
|
||||||
$this->addFlash('error', 'Le lieu n\'existe pas.');
|
$this->addFlash('error', 'Le lieu n\'existe pas.');
|
||||||
}
|
}
|
||||||
|
@ -811,7 +817,6 @@ final class AdminController extends AbstractController
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'La zone ' . $insee_code . ' et toutes les données associées ont été supprimées avec succès.');
|
$this->addFlash('success', 'La zone ' . $insee_code . ' et toutes les données associées ont été supprimées avec succès.');
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->addFlash('error', 'Une erreur est survenue lors de la suppression de la zone ' . $insee_code . ': ' . $e->getMessage());
|
$this->addFlash('error', 'Une erreur est survenue lors de la suppression de la zone ' . $insee_code . ': ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
@ -825,11 +830,11 @@ final class AdminController extends AbstractController
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('export_all_places', []);
|
$this->actionLogger->log('export_all_places', []);
|
||||||
$places = $this->entityManager->getRepository(Place::class)->findAll();
|
$places = $this->entityManager->getRepository(Place::class)->findAll();
|
||||||
|
|
||||||
$csvData = [];
|
$csvData = [];
|
||||||
$csvData[] = [
|
$csvData[] = [
|
||||||
'Nom',
|
'Nom',
|
||||||
'Email',
|
'Email',
|
||||||
'Code postal',
|
'Code postal',
|
||||||
'ID OSM',
|
'ID OSM',
|
||||||
'Type OSM',
|
'Type OSM',
|
||||||
|
@ -840,7 +845,7 @@ final class AdminController extends AbstractController
|
||||||
'Inactif',
|
'Inactif',
|
||||||
'Support humain demandé',
|
'Support humain demandé',
|
||||||
'A des horaires',
|
'A des horaires',
|
||||||
'A une adresse',
|
'A une adresse',
|
||||||
'A un site web',
|
'A un site web',
|
||||||
'A accessibilité',
|
'A accessibilité',
|
||||||
'A une note'
|
'A une note'
|
||||||
|
@ -857,7 +862,7 @@ final class AdminController extends AbstractController
|
||||||
$place->getLastContactAttemptDate() ? $place->getLastContactAttemptDate()->format('Y-m-d H:i:s') : '',
|
$place->getLastContactAttemptDate() ? $place->getLastContactAttemptDate()->format('Y-m-d H:i:s') : '',
|
||||||
$place->getNote(),
|
$place->getNote(),
|
||||||
$place->isOptedOut() ? 'Oui' : 'Non',
|
$place->isOptedOut() ? 'Oui' : 'Non',
|
||||||
$place->isDead() ? 'Oui' : 'Non',
|
$place->isDead() ? 'Oui' : 'Non',
|
||||||
$place->isAskedHumainsSupport() ? 'Oui' : 'Non',
|
$place->isAskedHumainsSupport() ? 'Oui' : 'Non',
|
||||||
$place->hasOpeningHours() ? 'Oui' : 'Non',
|
$place->hasOpeningHours() ? 'Oui' : 'Non',
|
||||||
$place->hasAddress() ? 'Oui' : 'Non',
|
$place->hasAddress() ? 'Oui' : 'Non',
|
||||||
|
@ -879,22 +884,22 @@ final class AdminController extends AbstractController
|
||||||
$response->setContent(stream_get_contents($handle));
|
$response->setContent(stream_get_contents($handle));
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
#[Route('/admin/export_csv/{insee_code}', name: 'app_admin_export_csv')]
|
#[Route('/admin/export_csv/{insee_code}', name: 'app_admin_export_csv')]
|
||||||
public function export_csv(string $insee_code): Response
|
public function export_csv(string $insee_code): Response
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('admin/export_csv', ['insee_code' => $insee_code]);
|
$this->actionLogger->log('admin/export_csv', ['insee_code' => $insee_code]);
|
||||||
|
|
||||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||||
$response = new Response($this->motocultrice->export($insee_code));
|
$response = new Response($this->motocultrice->export($insee_code));
|
||||||
$response->headers->set('Content-Type', 'text/csv');
|
$response->headers->set('Content-Type', 'text/csv');
|
||||||
|
|
||||||
$slug_name = str_replace(' ', '-', $stats->getName());
|
$slug_name = str_replace(' ', '-', $stats->getName());
|
||||||
|
|
||||||
$this->actionLogger->log('export_csv', ['insee_code'=> $insee_code, 'slug_name' => $slug_name]);
|
$this->actionLogger->log('export_csv', ['insee_code' => $insee_code, 'slug_name' => $slug_name]);
|
||||||
|
|
||||||
$response->headers->set('Content-Disposition', 'attachment; filename="osm-commerces-export_' . $insee_code . '_' . $slug_name . '_' . date('Y-m-d_H-i-s') . '.csv"');
|
$response->headers->set('Content-Disposition', 'attachment; filename="osm-commerces-export_' . $insee_code . '_' . $slug_name . '_' . date('Y-m-d_H-i-s') . '.csv"');
|
||||||
|
|
||||||
|
@ -905,20 +910,20 @@ final class AdminController extends AbstractController
|
||||||
public function make_email_for_place(Place $place): Response
|
public function make_email_for_place(Place $place): Response
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('admin/make_email_for_place', ['insee_code' => $place->getId()]);
|
$this->actionLogger->log('admin/make_email_for_place', ['insee_code' => $place->getId()]);
|
||||||
|
|
||||||
return $this->render('admin/view_email_for_place.html.twig', ['place' => $place]);
|
return $this->render('admin/view_email_for_place.html.twig', ['place' => $place]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/admin/no_more_sollicitation_for_place/{id}', name: 'app_admin_no_more_sollicitation_for_place')]
|
#[Route('/admin/no_more_sollicitation_for_place/{id}', name: 'app_admin_no_more_sollicitation_for_place')]
|
||||||
public function no_more_sollicitation_for_place(Place $place): Response
|
public function no_more_sollicitation_for_place(Place $place): Response
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('no_more_sollicitation_for_place', ['place_id'=> $place->getId()]);
|
$this->actionLogger->log('no_more_sollicitation_for_place', ['place_id' => $place->getId()]);
|
||||||
|
|
||||||
$place->setOptedOut(true);
|
$place->setOptedOut(true);
|
||||||
$this->entityManager->persist($place);
|
$this->entityManager->persist($place);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'Votre lieu '.$place->getName().' ne sera plus sollicité pour mettre à jour ses informations.');
|
$this->addFlash('success', 'Votre lieu ' . $place->getName() . ' ne sera plus sollicité pour mettre à jour ses informations.');
|
||||||
|
|
||||||
return $this->redirectToRoute('app_public_index');
|
return $this->redirectToRoute('app_public_index');
|
||||||
}
|
}
|
||||||
|
@ -926,14 +931,14 @@ final class AdminController extends AbstractController
|
||||||
#[Route('/admin/send_email_to_place/{id}', name: 'app_admin_send_email_to_place')]
|
#[Route('/admin/send_email_to_place/{id}', name: 'app_admin_send_email_to_place')]
|
||||||
public function send_email_to_place(Place $place, \Symfony\Component\Mailer\MailerInterface $mailer): Response
|
public function send_email_to_place(Place $place, \Symfony\Component\Mailer\MailerInterface $mailer): Response
|
||||||
{
|
{
|
||||||
$this->actionLogger->log('send_email_to_place', ['place_id'=> $place->getId()]);
|
$this->actionLogger->log('send_email_to_place', ['place_id' => $place->getId()]);
|
||||||
|
|
||||||
|
|
||||||
// Vérifier si le lieu est opted out
|
// Vérifier si le lieu est opted out
|
||||||
if ($place->isOptedOut()) {
|
if ($place->isOptedOut()) {
|
||||||
$this->addFlash('error', 'Ce lieu a demandé à ne plus être sollicité pour mettre à jour ses informations.');
|
$this->addFlash('error', 'Ce lieu a demandé à ne plus être sollicité pour mettre à jour ses informations.');
|
||||||
$this->actionLogger->log('could_not_send_email_to_opted_out_place', ['place_id'=> $place->getId()]);
|
$this->actionLogger->log('could_not_send_email_to_opted_out_place', ['place_id' => $place->getId()]);
|
||||||
|
|
||||||
return $this->redirectToRoute('app_public_index');
|
return $this->redirectToRoute('app_public_index');
|
||||||
}
|
}
|
||||||
// Vérifier si le lieu a déjà été contacté
|
// Vérifier si le lieu a déjà été contacté
|
||||||
|
@ -971,10 +976,10 @@ final class AdminController extends AbstractController
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$place->setLastContactAttemptDate(new \DateTime());
|
$place->setLastContactAttemptDate(new \DateTime());
|
||||||
|
|
||||||
$this->addFlash('success', 'Email envoyé avec succès à ' . $place->getName() . ' le ' . $place->getLastContactAttemptDate()->format('d/m/Y H:i:s'));
|
$this->addFlash('success', 'Email envoyé avec succès à ' . $place->getName() . ' le ' . $place->getLastContactAttemptDate()->format('d/m/Y H:i:s'));
|
||||||
return $this->redirectToRoute('app_public_index');
|
return $this->redirectToRoute('app_public_index');
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/admin/fraicheur/histogramme', name: 'admin_fraicheur_histogramme')]
|
#[Route('/admin/fraicheur/histogramme', name: 'admin_fraicheur_histogramme')]
|
||||||
public function showFraicheurHistogramme(): Response
|
public function showFraicheurHistogramme(): Response
|
||||||
|
@ -991,7 +996,7 @@ final class AdminController extends AbstractController
|
||||||
public function calculateFraicheur(): Response
|
public function calculateFraicheur(): Response
|
||||||
{
|
{
|
||||||
// Ajout d'un log d'action avec le service ActionLogger
|
// Ajout d'un log d'action avec le service ActionLogger
|
||||||
$this->actionLogger->log('fraicheur/calculate' , []);
|
$this->actionLogger->log('fraicheur/calculate', []);
|
||||||
$filesystem = new Filesystem();
|
$filesystem = new Filesystem();
|
||||||
$jsonPath = $this->getParameter('kernel.project_dir') . '/var/fraicheur_osm.json';
|
$jsonPath = $this->getParameter('kernel.project_dir') . '/var/fraicheur_osm.json';
|
||||||
$now = new \DateTime();
|
$now = new \DateTime();
|
||||||
|
@ -1022,7 +1027,7 @@ final class AdminController extends AbstractController
|
||||||
'total' => $total,
|
'total' => $total,
|
||||||
'histogram' => $histogram
|
'histogram' => $histogram
|
||||||
];
|
];
|
||||||
$filesystem->dumpFile($jsonPath, json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
$filesystem->dumpFile($jsonPath, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||||
|
|
||||||
// --- Distribution villes selon lieux/habitants ---
|
// --- Distribution villes selon lieux/habitants ---
|
||||||
$distJsonPath = $this->getParameter('kernel.project_dir') . '/var/distribution_villes_lieux_par_habitant.json';
|
$distJsonPath = $this->getParameter('kernel.project_dir') . '/var/distribution_villes_lieux_par_habitant.json';
|
||||||
|
@ -1057,7 +1062,7 @@ final class AdminController extends AbstractController
|
||||||
'histogram_001' => $histogram_lieux_par_habitant,
|
'histogram_001' => $histogram_lieux_par_habitant,
|
||||||
'histogram_10' => $histogram_habitants_par_lieu
|
'histogram_10' => $histogram_habitants_par_lieu
|
||||||
];
|
];
|
||||||
$filesystem->dumpFile($distJsonPath, json_encode($distData, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
$filesystem->dumpFile($distJsonPath, json_encode($distData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_fraicheur_histogramme');
|
return $this->redirectToRoute('admin_fraicheur_histogramme');
|
||||||
}
|
}
|
||||||
|
@ -1104,7 +1109,7 @@ final class AdminController extends AbstractController
|
||||||
'total_villes' => $totalVilles,
|
'total_villes' => $totalVilles,
|
||||||
'histogram_001' => $histogram
|
'histogram_001' => $histogram
|
||||||
];
|
];
|
||||||
$filesystem->dumpFile($jsonPath, json_encode($distData, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
$filesystem->dumpFile($jsonPath, json_encode($distData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||||
}
|
}
|
||||||
$content = file_get_contents($jsonPath);
|
$content = file_get_contents($jsonPath);
|
||||||
$data = json_decode($content, true);
|
$data = json_decode($content, true);
|
||||||
|
@ -1153,67 +1158,67 @@ final class AdminController extends AbstractController
|
||||||
if ($budgetsMisAJour > 0) {
|
if ($budgetsMisAJour > 0) {
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
}
|
}
|
||||||
$this->addFlash('success', $budgetsMisAJour.' budgets mis à jour.');
|
$this->addFlash('success', $budgetsMisAJour . ' budgets mis à jour.');
|
||||||
return $this->redirectToRoute('app_admin');
|
return $this->redirectToRoute('app_admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/admin/podium-contributeurs-osm', name: 'app_admin_podium_contributeurs_osm')]
|
#[Route('/admin/podium-contributeurs-osm', name: 'app_admin_podium_contributeurs_osm')]
|
||||||
public function podiumContributeursOsm(): Response
|
public function podiumContributeursOsm(): Response
|
||||||
{
|
{
|
||||||
// Ajout d'un log d'action avec le service ActionLogger
|
// Ajout d'un log d'action avec le service ActionLogger
|
||||||
$this->actionLogger->log('podium_contributeurs_osm', []);
|
$this->actionLogger->log('podium_contributeurs_osm', []);
|
||||||
// On suppose que le champ "osmUser" existe sur l'entité Place
|
// On suppose que le champ "osmUser" existe sur l'entité Place
|
||||||
$placeRepo = $this->entityManager->getRepository(\App\Entity\Place::class);
|
$placeRepo = $this->entityManager->getRepository(\App\Entity\Place::class);
|
||||||
|
|
||||||
// Nouvelle requête groupée pour tout calculer d'un coup
|
// Nouvelle requête groupée pour tout calculer d'un coup
|
||||||
$qb = $placeRepo->createQueryBuilder('p')
|
$qb = $placeRepo->createQueryBuilder('p')
|
||||||
->select(
|
->select(
|
||||||
'p.osm_user',
|
'p.osm_user',
|
||||||
'COUNT(p.id) as nb',
|
'COUNT(p.id) as nb',
|
||||||
'AVG((CASE WHEN p.has_opening_hours = true THEN 1 ELSE 0 END) +'
|
'AVG((CASE WHEN p.has_opening_hours = true THEN 1 ELSE 0 END) +'
|
||||||
. ' (CASE WHEN p.has_address = true THEN 1 ELSE 0 END) +'
|
. ' (CASE WHEN p.has_address = true THEN 1 ELSE 0 END) +'
|
||||||
. ' (CASE WHEN p.has_website = true THEN 1 ELSE 0 END) +'
|
. ' (CASE WHEN p.has_website = true THEN 1 ELSE 0 END) +'
|
||||||
. ' (CASE WHEN p.has_wheelchair = true THEN 1 ELSE 0 END) +'
|
. ' (CASE WHEN p.has_wheelchair = true THEN 1 ELSE 0 END) +'
|
||||||
. ' (CASE WHEN p.has_note = true THEN 1 ELSE 0 END)) / 5 * 100 as completion_moyen'
|
. ' (CASE WHEN p.has_note = true THEN 1 ELSE 0 END)) / 5 * 100 as completion_moyen'
|
||||||
)
|
)
|
||||||
->where('p.osm_user IS NOT NULL')
|
->where('p.osm_user IS NOT NULL')
|
||||||
->andWhere("p.osm_user != ''")
|
->andWhere("p.osm_user != ''")
|
||||||
->groupBy('p.osm_user')
|
->groupBy('p.osm_user')
|
||||||
->orderBy('nb', 'DESC')
|
->orderBy('nb', 'DESC')
|
||||||
->setMaxResults(100);
|
->setMaxResults(100);
|
||||||
|
|
||||||
$podium = $qb->getQuery()->getResult();
|
$podium = $qb->getQuery()->getResult();
|
||||||
|
|
||||||
// Calcul du score pondéré et normalisation
|
// Calcul du score pondéré et normalisation
|
||||||
$maxPondere = 0;
|
$maxPondere = 0;
|
||||||
foreach ($podium as &$row) {
|
|
||||||
$row['completion_moyen'] = $row['completion_moyen'] !== null ? round($row['completion_moyen'], 1) : null;
|
|
||||||
$row['completion_pondere'] = ($row['completion_moyen'] !== null && $row['nb'] > 0)
|
|
||||||
? round($row['completion_moyen'] * $row['nb'], 1)
|
|
||||||
: null;
|
|
||||||
if ($row['completion_pondere'] !== null && $row['completion_pondere'] > $maxPondere) {
|
|
||||||
$maxPondere = $row['completion_pondere'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($row);
|
|
||||||
// Normalisation des scores pondérés entre 0 et 100
|
|
||||||
if ($maxPondere > 0) {
|
|
||||||
foreach ($podium as &$row) {
|
foreach ($podium as &$row) {
|
||||||
if ($row['completion_pondere'] !== null) {
|
$row['completion_moyen'] = $row['completion_moyen'] !== null ? round($row['completion_moyen'], 1) : null;
|
||||||
$row['completion_pondere_normalisee'] = round($row['completion_pondere'] / $maxPondere * 100, 1);
|
$row['completion_pondere'] = ($row['completion_moyen'] !== null && $row['nb'] > 0)
|
||||||
} else {
|
? round($row['completion_moyen'] * $row['nb'], 1)
|
||||||
$row['completion_pondere_normalisee'] = null;
|
: null;
|
||||||
|
if ($row['completion_pondere'] !== null && $row['completion_pondere'] > $maxPondere) {
|
||||||
|
$maxPondere = $row['completion_pondere'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unset($row);
|
unset($row);
|
||||||
}
|
// Normalisation des scores pondérés entre 0 et 100
|
||||||
// Tri décroissant sur le score normalisé
|
if ($maxPondere > 0) {
|
||||||
usort($podium, function($a, $b) {
|
foreach ($podium as &$row) {
|
||||||
return ($b['completion_pondere_normalisee'] ?? 0) <=> ($a['completion_pondere_normalisee'] ?? 0);
|
if ($row['completion_pondere'] !== null) {
|
||||||
});
|
$row['completion_pondere_normalisee'] = round($row['completion_pondere'] / $maxPondere * 100, 1);
|
||||||
|
} else {
|
||||||
|
$row['completion_pondere_normalisee'] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($row);
|
||||||
|
}
|
||||||
|
// Tri décroissant sur le score normalisé
|
||||||
|
usort($podium, function ($a, $b) {
|
||||||
|
return ($b['completion_pondere_normalisee'] ?? 0) <=> ($a['completion_pondere_normalisee'] ?? 0);
|
||||||
|
});
|
||||||
|
|
||||||
return $this->render('admin/podium_contributeurs_osm.html.twig', [
|
return $this->render('admin/podium_contributeurs_osm.html.twig', [
|
||||||
'podium' => $podium
|
'podium' => $podium
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue