ajout stat hist

This commit is contained in:
Tykayn 2025-06-17 18:27:19 +02:00 committed by tykayn
parent 918527e15e
commit 7fb0c9c8c2
19 changed files with 695 additions and 314 deletions

View file

@ -30,18 +30,29 @@ final class AdminController extends AbstractController
]);
}
#[Route('/admin/stats/{zip_code}', name: 'app_admin_stats')]
public function calculer_stats(string $zip_code): Response
#[Route('/admin/stats/{insee_code}', name: 'app_admin_stats')]
public function calculer_stats(string $insee_code): Response
{
// Récupérer tous les commerces de la zone
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $zip_code]);
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
// Récupérer les stats existantes pour la zone
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zip_code]);
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
$statsHistory = $this->entityManager->getRepository(StatsHistory::class)
->createQueryBuilder('sh')
->where('sh.stats = :stats')
->setParameter('stats', $stats)
->orderBy('sh.id', 'DESC')
->setMaxResults(365)
->getQuery()
->getResult();
if(!$stats) {
$stats = new Stats();
$stats->setZone($zip_code);
$stats->setZone($insee_code);
}
// Calculer les statistiques
@ -72,11 +83,12 @@ final class AdminController extends AbstractController
return $this->render('admin/stats.html.twig', [
'stats' => $stats,
'zip_code' => $zip_code,
'query_places' => $this->motocultrice->get_query_places($zip_code),
'insee_code' => $insee_code,
'query_places' => $this->motocultrice->get_query_places($insee_code),
'counters' => $calculatedStats['counters'],
'maptiler_token' => $_ENV['MAPTILER_TOKEN'],
'mapbox_token' => $_ENV['MAPBOX_TOKEN'],
'statsHistory' => $statsHistory,
]);
}
@ -122,19 +134,19 @@ final class AdminController extends AbstractController
/**
* récupérer les commerces de la zone, créer les nouveaux lieux, et mettre à jour les existants
* récupérer les commerces de la zone selon le code INSEE, créer les nouveaux lieux, et mettre à jour les existants
*/
#[Route('/admin/labourer/{zip_code}', name: 'app_admin_labourer')]
public function labourer(string $zip_code, bool $updateExisting = true): Response
#[Route('/admin/labourer/{insee_code}', name: 'app_admin_labourer')]
public function labourer(string $insee_code, bool $updateExisting = true): Response
{
try {
// Récupérer ou créer les stats pour cette zone
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zip_code]);
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
$city = $this->motocultrice->get_city_osm_from_zip_code($zip_code);
$city = $this->motocultrice->get_city_osm_from_zip_code($insee_code);
if (!$stats) {
$stats = new Stats();
$stats->setZone($zip_code)
$stats->setZone($insee_code)
->setPlacesCount(0)
->setAvecHoraires(0)
->setAvecAdresse(0)
@ -150,7 +162,7 @@ final class AdminController extends AbstractController
// Récupérer la population via l'API
$population = null;
try {
$apiUrl = 'https://geo.api.gouv.fr/communes/' . $zip_code . '?fields=population';
$apiUrl = 'https://geo.api.gouv.fr/communes/' . $insee_code;
$response = file_get_contents($apiUrl);
if ($response !== false) {
$data = json_decode($response, true);
@ -158,13 +170,23 @@ final class AdminController extends AbstractController
$population = (int)$data['population'];
$stats->setPopulation($population);
}
if (isset($data['siren'])) {
$stats->setSiren((int)$data['siren']);
}
if (isset($data['codeEpci'])) {
$stats->setCodeEpci((int)$data['codeEpci']);
}
if (isset($data['codesPostaux'])) {
$stats->setCodesPostaux(implode(';', $data['codesPostaux']));
}
}
} catch (\Exception $e) {
// Ne rien faire si l'API échoue
$this->addFlash('error', 'Erreur lors de la récupération des données de l\'API : ' . $e->getMessage());
}
// Récupérer toutes les données
$places = $this->motocultrice->labourer($zip_code);
$places = $this->motocultrice->labourer($insee_code);
$processedCount = 0;
$updatedCount = 0;
@ -177,7 +199,7 @@ final class AdminController extends AbstractController
$place = new Place();
$place->setOsmId($placeData['id'])
->setOsmKind($placeData['type'])
->setZipCode($zip_code)
->setZipCode($insee_code)
->setUuidForUrl($this->motocultrice->uuid_create())
->setModifiedDate(new \DateTime())
->setStats($stats)
@ -212,6 +234,14 @@ final class AdminController extends AbstractController
// Mettre à jour les statistiques finales
$stats->computeCompletionPercent();
// Créer un historique des statistiques
$statsHistory = new StatsHistory();
$statsHistory->setPlacesCount($stats->getPlaces()->count())
->setCompletionPercent($stats->getCompletionPercent())
->setStats($stats);
$this->entityManager->persist($statsHistory);
$this->entityManager->persist($stats);
$this->entityManager->flush();
@ -225,7 +255,8 @@ final class AdminController extends AbstractController
$this->addFlash('error', 'Erreur lors du labourage : ' . $e->getMessage());
}
return $this->redirectToRoute('app_admin_stats', ['zip_code' => $zip_code]);
return $this->redirectToRoute('app_public_dashboard');
// return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
}
#[Route('/admin/delete/{id}', name: 'app_admin_delete')]
@ -244,11 +275,11 @@ final class AdminController extends AbstractController
return $this->redirectToRoute('app_public_dashboard');
}
#[Route('/admin/delete_by_zone/{zip_code}', name: 'app_admin_delete_by_zone')]
public function delete_by_zone(string $zip_code): Response
#[Route('/admin/delete_by_zone/{insee_code}', name: 'app_admin_delete_by_zone')]
public function delete_by_zone(string $insee_code): Response
{
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $zip_code]);
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zip_code]);
$commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]);
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
foreach ($commerces as $commerce) {
$this->entityManager->remove($commerce);
@ -256,7 +287,7 @@ final class AdminController extends AbstractController
$this->entityManager->remove($stats);
$this->entityManager->flush();
$this->addFlash('success', 'Tous les commerces de la zone '.$zip_code.' ont été supprimés avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.');
$this->addFlash('success', 'Tous les commerces de la zone '.$insee_code.' ont été supprimés avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.');
return $this->redirectToRoute('app_public_dashboard');
}
@ -322,16 +353,16 @@ final class AdminController extends AbstractController
return $response;
}
#[Route('/admin/export_csv/{zip_code}', name: 'app_admin_export_csv')]
public function export_csv(string $zip_code): Response
#[Route('/admin/export_csv/{insee_code}', name: 'app_admin_export_csv')]
public function export_csv(string $insee_code): Response
{
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zip_code]);
$response = new Response($this->motocultrice->export($zip_code));
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
$response = new Response($this->motocultrice->export($insee_code));
$response->headers->set('Content-Type', 'text/csv');
$slug_name = str_replace(' ', '-', $stats->getName());
$response->headers->set('Content-Disposition', 'attachment; filename="osm-commerces-export_' . $zip_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"');
return $response;
}

View file

@ -16,9 +16,6 @@ class History
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(type: Types::SMALLINT, nullable: true)]
private ?int $completion_percent = null;

View file

@ -59,6 +59,21 @@ class Stats
#[ORM\Column(type: Types::INTEGER, nullable: true)]
private ?int $population = null;
#[ORM\Column(type: Types::SMALLINT, nullable: true)]
private ?int $siren = null;
#[ORM\Column(type: Types::SMALLINT, nullable: true)]
private ?int $codeEpci = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $codesPostaux = null;
/**
* @var Collection<int, StatsHistory>
*/
#[ORM\OneToMany(targetEntity: StatsHistory::class, mappedBy: 'stats')]
private Collection $statsHistories;
// calcule le pourcentage de complétion de la zone
public function computeCompletionPercent(): ?int
{
@ -115,6 +130,7 @@ class Stats
public function __construct()
{
$this->places = new ArrayCollection();
$this->statsHistories = new ArrayCollection();
}
public function getId(): ?int
@ -270,6 +286,72 @@ class Stats
$this->population = $population;
return $this;
}
public function getSiren(): ?int
{
return $this->siren;
}
public function setSiren(?int $siren): static
{
$this->siren = $siren;
return $this;
}
public function getCodeEpci(): ?int
{
return $this->codeEpci;
}
public function setCodeEpci(?int $codeEpci): static
{
$this->codeEpci = $codeEpci;
return $this;
}
public function getCodesPostaux(): ?string
{
return $this->codesPostaux;
}
public function setCodesPostaux(?string $codesPostaux): static
{
$this->codesPostaux = $codesPostaux;
return $this;
}
/**
* @return Collection<int, StatsHistory>
*/
public function getStatsHistories(): Collection
{
return $this->statsHistories;
}
public function addStatsHistory(StatsHistory $statsHistory): static
{
if (!$this->statsHistories->contains($statsHistory)) {
$this->statsHistories->add($statsHistory);
$statsHistory->setStats($this);
}
return $this;
}
public function removeStatsHistory(StatsHistory $statsHistory): static
{
if ($this->statsHistories->removeElement($statsHistory)) {
// set the owning side to null (unless already changed)
if ($statsHistory->getStats() === $this) {
$statsHistory->setStats(null);
}
}
return $this;
}
}

View file

@ -0,0 +1,98 @@
<?php
namespace App\Entity;
use App\Repository\StatsHistoryRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: StatsHistoryRepository::class)]
class StatsHistory
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(nullable: true)]
private ?int $places_count = null;
#[ORM\Column(nullable: true)]
private ?int $emails_count = null;
#[ORM\Column(type: Types::SMALLFLOAT, nullable: true)]
private ?float $completion_percent = null;
#[ORM\Column(nullable: true)]
private ?int $emails_sent = null;
#[ORM\ManyToOne(inversedBy: 'statsHistories')]
private ?Stats $stats = null;
public function getId(): ?int
{
return $this->id;
}
public function getPlacesCount(): ?int
{
return $this->places_count;
}
public function setPlacesCount(?int $places_count): static
{
$this->places_count = $places_count;
return $this;
}
public function getEmailsCount(): ?int
{
return $this->emails_count;
}
public function setEmailsCount(?int $emails_count): static
{
$this->emails_count = $emails_count;
return $this;
}
public function getCompletionPercent(): ?float
{
return $this->completion_percent;
}
public function setCompletionPercent(?float $completion_percent): static
{
$this->completion_percent = $completion_percent;
return $this;
}
public function getEmailsSent(): ?int
{
return $this->emails_sent;
}
public function setEmailsSent(?int $emails_sent): static
{
$this->emails_sent = $emails_sent;
return $this;
}
public function getStats(): ?Stats
{
return $this->stats;
}
public function setStats(?Stats $stats): static
{
$this->stats = $stats;
return $this;
}
}

View file

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\StatsHistory;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<StatsHistory>
*/
class StatsHistoryRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, StatsHistory::class);
}
// /**
// * @return StatsHistory[] Returns an array of StatsHistory objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('s.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?StatsHistory
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}