ajout analyses osmose dans les pages de détail
This commit is contained in:
parent
359d4ba6b8
commit
0aaddb44c5
13 changed files with 1963 additions and 12 deletions
262
src/Command/CreateMissingStatsFromCsvCommand.php
Normal file
262
src/Command/CreateMissingStatsFromCsvCommand.php
Normal file
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\Stats;
|
||||
use App\Repository\StatsRepository;
|
||||
use App\Service\ActionLogger;
|
||||
use App\Service\BudgetService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
#[AsCommand(
|
||||
name: 'app:create-missing-stats-from-csv',
|
||||
description: 'Crée des objets Stats manquants à partir du fichier communes_france.csv',
|
||||
)]
|
||||
class CreateMissingStatsFromCsvCommand extends Command
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
private StatsRepository $statsRepository;
|
||||
private ActionLogger $actionLogger;
|
||||
private ?BudgetService $budgetService;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $entityManager,
|
||||
StatsRepository $statsRepository,
|
||||
ActionLogger $actionLogger,
|
||||
?BudgetService $budgetService = null
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->entityManager = $entityManager;
|
||||
$this->statsRepository = $statsRepository;
|
||||
$this->actionLogger = $actionLogger;
|
||||
$this->budgetService = $budgetService;
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Limite le nombre de communes à traiter', 0)
|
||||
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Simule sans modifier la base de données')
|
||||
->setHelp('Cette commande examine le fichier CSV des communes et crée des objets Stats pour les communes qui n\'en ont pas encore. Les objets sont créés avec les informations du CSV et complétés avec des données supplémentaires (coordonnées, budget, etc.).');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$io->title('Création des objets Stats manquants à partir du fichier CSV');
|
||||
|
||||
$limit = (int) $input->getOption('limit');
|
||||
$dryRun = $input->getOption('dry-run');
|
||||
|
||||
$this->actionLogger->log('command/create_missing_stats_from_csv', [
|
||||
'limit' => $limit,
|
||||
'dry_run' => $dryRun
|
||||
]);
|
||||
|
||||
// Vérifier si le fichier CSV existe
|
||||
$csvFile = 'communes_france.csv';
|
||||
if (!file_exists($csvFile)) {
|
||||
$io->error('Le fichier CSV des communes n\'existe pas. Veuillez exécuter le script fetch_communes.py pour le générer.');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$createdCount = 0;
|
||||
$skippedCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Ouvrir le fichier CSV
|
||||
$handle = fopen($csvFile, 'r');
|
||||
if (!$handle) {
|
||||
$io->error('Impossible d\'ouvrir le fichier CSV des communes.');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
// Lire l'en-tête pour déterminer les indices des colonnes
|
||||
$header = fgetcsv($handle);
|
||||
$indices = array_flip($header);
|
||||
|
||||
// Vérifier que les colonnes nécessaires existent
|
||||
$requiredColumns = ['code', 'nom'];
|
||||
foreach ($requiredColumns as $column) {
|
||||
if (!isset($indices[$column])) {
|
||||
$io->error("La colonne '$column' est manquante dans le fichier CSV.");
|
||||
fclose($handle);
|
||||
return Command::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
$io->info(sprintf('Lecture du fichier CSV: %s', $csvFile));
|
||||
$io->info(sprintf('Colonnes trouvées: %s', implode(', ', $header)));
|
||||
|
||||
// Compter le nombre total de lignes pour la barre de progression
|
||||
$totalLines = 0;
|
||||
$tempHandle = fopen($csvFile, 'r');
|
||||
if ($tempHandle) {
|
||||
// Skip header
|
||||
fgetcsv($tempHandle);
|
||||
while (fgetcsv($tempHandle) !== false) {
|
||||
$totalLines++;
|
||||
}
|
||||
fclose($tempHandle);
|
||||
}
|
||||
|
||||
$io->info(sprintf('Nombre total de communes dans le CSV: %d', $totalLines));
|
||||
|
||||
// Créer une barre de progression
|
||||
$progressBar = $io->createProgressBar($totalLines);
|
||||
$progressBar->start();
|
||||
|
||||
// Traiter chaque ligne du CSV
|
||||
while (($data = fgetcsv($handle)) !== false) {
|
||||
try {
|
||||
$inseeCode = $data[$indices['code']];
|
||||
|
||||
// Vérifier si une Stats existe déjà pour ce code INSEE
|
||||
$existingStat = $this->statsRepository->findOneBy(['zone' => $inseeCode]);
|
||||
if ($existingStat) {
|
||||
$skippedCount++;
|
||||
$progressBar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats
|
||||
$stat = new Stats();
|
||||
$stat->setZone($inseeCode)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('command'); // Utiliser 'command' comme source
|
||||
|
||||
// Ajouter le nom si disponible
|
||||
if (isset($indices['nom']) && !empty($data[$indices['nom']])) {
|
||||
$stat->setName($data[$indices['nom']]);
|
||||
}
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($indices['population']) && !empty($data[$indices['population']])) {
|
||||
$stat->setPopulation((int)$data[$indices['population']]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($indices['codesPostaux']) && !empty($data[$indices['codesPostaux']])) {
|
||||
$stat->setCodesPostaux($data[$indices['codesPostaux']]);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($indices['siren']) && !empty($data[$indices['siren']])) {
|
||||
$stat->setSiren((int)$data[$indices['siren']]);
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($indices['codeEpci']) && !empty($data[$indices['codeEpci']])) {
|
||||
$stat->setCodeEpci((int)$data[$indices['codeEpci']]);
|
||||
}
|
||||
|
||||
// Compléter les données manquantes (coordonnées, budget, etc.)
|
||||
if (!$dryRun) {
|
||||
$this->completeStatsData($stat);
|
||||
}
|
||||
|
||||
// Persister l'objet Stats
|
||||
if (!$dryRun) {
|
||||
$this->entityManager->persist($stat);
|
||||
}
|
||||
$createdCount++;
|
||||
|
||||
// Appliquer la limite si spécifiée
|
||||
if ($limit > 0 && $createdCount >= $limit) {
|
||||
$io->info(sprintf('Limite de %d communes atteinte.', $limit));
|
||||
break;
|
||||
}
|
||||
|
||||
// Flush tous les 100 objets pour éviter de surcharger la mémoire
|
||||
if (!$dryRun && $createdCount % 100 === 0) {
|
||||
$this->entityManager->flush();
|
||||
$this->entityManager->clear(Stats::class);
|
||||
$io->info(sprintf('Flush après création de %d objets Stats', $createdCount));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errorCount++;
|
||||
$this->actionLogger->log('error_command_create_missing_stats_from_csv', [
|
||||
'insee_code' => $inseeCode ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
if ($output->isVerbose()) {
|
||||
$io->warning(sprintf('Erreur pour la commune %s: %s', $inseeCode ?? 'unknown', $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
$progressBar->advance();
|
||||
}
|
||||
|
||||
$progressBar->finish();
|
||||
$io->newLine(2);
|
||||
|
||||
// Flush les derniers objets
|
||||
if (!$dryRun && $createdCount > 0) {
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
if ($dryRun) {
|
||||
$io->success(sprintf('Simulation terminée. %d communes auraient été ajoutées, %d déjà existantes, %d erreurs.', $createdCount, $skippedCount, $errorCount));
|
||||
} else {
|
||||
$io->success(sprintf('Création des Stats manquantes terminée : %d communes ajoutées, %d déjà existantes, %d erreurs.', $createdCount, $skippedCount, $errorCount));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complète les données manquantes d'un objet Stats (coordonnées, budget, etc.)
|
||||
*/
|
||||
private function completeStatsData(Stats $stat): void
|
||||
{
|
||||
$insee_code = $stat->getZone();
|
||||
|
||||
// Compléter les coordonnées si manquantes
|
||||
if (!$stat->getLat() || !$stat->getLon()) {
|
||||
try {
|
||||
$apiUrl = 'https://geo.api.gouv.fr/communes/' . $insee_code . '?fields=centre';
|
||||
$response = @file_get_contents($apiUrl);
|
||||
if ($response !== false) {
|
||||
$data = json_decode($response, true);
|
||||
if (isset($data['centre']['coordinates']) && count($data['centre']['coordinates']) === 2) {
|
||||
$stat->setLon((string)$data['centre']['coordinates'][0]);
|
||||
$stat->setLat((string)$data['centre']['coordinates'][1]);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch coordinates: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Compléter le budget si manquant
|
||||
if (!$stat->getBudgetAnnuel() && $this->budgetService !== null) {
|
||||
try {
|
||||
$budget = $this->budgetService->getBudgetAnnuel($insee_code);
|
||||
if ($budget !== null) {
|
||||
$stat->setBudgetAnnuel((string)$budget);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch budget: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculer le pourcentage de complétion
|
||||
$stat->computeCompletionPercent();
|
||||
}
|
||||
}
|
|
@ -613,8 +613,60 @@ final class AdminController extends AbstractController
|
|||
{
|
||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||
if (!$stats) {
|
||||
$this->addFlash('error', '2 Aucune stats trouvée pour ce code INSEE.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
// Si aucune stats n'existe, rechercher dans l'API geo.api.gouv.fr
|
||||
$apiUrl = "https://geo.api.gouv.fr/communes/{$insee_code}";
|
||||
$response = @file_get_contents($apiUrl);
|
||||
|
||||
if ($response === false) {
|
||||
$this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE et impossible de récupérer les informations depuis l\'API geo.api.gouv.fr.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$communeData = json_decode($response, true);
|
||||
if (!$communeData || !isset($communeData['nom'])) {
|
||||
$this->addFlash('error', 'Aucune commune trouvée avec ce code INSEE dans l\'API geo.api.gouv.fr.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats avec les données de l'API
|
||||
$stats = new Stats();
|
||||
$stats->setZone($insee_code)
|
||||
->setName($communeData['nom'])
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('request');
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($communeData['population'])) {
|
||||
$stats->setPopulation($communeData['population']);
|
||||
}
|
||||
|
||||
// Ajouter les coordonnées si disponibles
|
||||
if (isset($communeData['centre']) && isset($communeData['centre']['coordinates'])) {
|
||||
$stats->setLon((string)$communeData['centre']['coordinates'][0]);
|
||||
$stats->setLat((string)$communeData['centre']['coordinates'][1]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($communeData['codesPostaux']) && !empty($communeData['codesPostaux'])) {
|
||||
$stats->setCodesPostaux(implode(',', $communeData['codesPostaux']));
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($communeData['codeEpci'])) {
|
||||
$stats->setCodeEpci((int)$communeData['codeEpci']);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($communeData['siren'])) {
|
||||
$stats->setSiren((int)$communeData['siren']);
|
||||
}
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stats);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.');
|
||||
}
|
||||
|
||||
$themes = \App\Service\FollowUpService::getFollowUpThemes();
|
||||
|
@ -1372,6 +1424,274 @@ final class AdminController extends AbstractController
|
|||
$this->addFlash('success', $budgetsMisAJour . ' budgets mis à jour.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
#[Route('/admin/import-stats-from-csv', name: 'app_admin_import_stats_from_csv')]
|
||||
public function importStatsFromCsv(): Response
|
||||
{
|
||||
$this->actionLogger->log('admin/import_stats_from_csv', []);
|
||||
|
||||
$csvFile = 'communes_france.csv';
|
||||
if (!file_exists($csvFile)) {
|
||||
$this->addFlash('error', 'Le fichier CSV des communes n\'existe pas. Veuillez exécuter le script fetch_communes.py pour le générer.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$statsRepo = $this->entityManager->getRepository(Stats::class);
|
||||
$createdCount = 0;
|
||||
$skippedCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Ouvrir le fichier CSV
|
||||
$handle = fopen($csvFile, 'r');
|
||||
if (!$handle) {
|
||||
$this->addFlash('error', 'Impossible d\'ouvrir le fichier CSV des communes.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Lire l'en-tête pour déterminer les indices des colonnes
|
||||
$header = fgetcsv($handle);
|
||||
$indices = array_flip($header);
|
||||
|
||||
// Vérifier que les colonnes nécessaires existent
|
||||
$requiredColumns = ['code', 'nom'];
|
||||
foreach ($requiredColumns as $column) {
|
||||
if (!isset($indices[$column])) {
|
||||
$this->addFlash('error', "La colonne '$column' est manquante dans le fichier CSV.");
|
||||
fclose($handle);
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
}
|
||||
|
||||
// Traiter chaque ligne du CSV
|
||||
while (($data = fgetcsv($handle)) !== false) {
|
||||
try {
|
||||
$inseeCode = $data[$indices['code']];
|
||||
|
||||
// Vérifier si une Stats existe déjà pour ce code INSEE
|
||||
$existingStat = $statsRepo->findOneBy(['zone' => $inseeCode]);
|
||||
if ($existingStat) {
|
||||
$skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats
|
||||
$stat = new Stats();
|
||||
$stat->setZone($inseeCode)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('request');
|
||||
|
||||
// Ajouter le nom si disponible
|
||||
if (isset($indices['nom']) && !empty($data[$indices['nom']])) {
|
||||
$stat->setName($data[$indices['nom']]);
|
||||
}
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($indices['population']) && !empty($data[$indices['population']])) {
|
||||
$stat->setPopulation((int)$data[$indices['population']]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($indices['codesPostaux']) && !empty($data[$indices['codesPostaux']])) {
|
||||
$stat->setCodesPostaux($data[$indices['codesPostaux']]);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($indices['siren']) && !empty($data[$indices['siren']])) {
|
||||
$stat->setSiren((int)$data[$indices['siren']]);
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($indices['codeEpci']) && !empty($data[$indices['codeEpci']])) {
|
||||
$stat->setCodeEpci((int)$data[$indices['codeEpci']]);
|
||||
}
|
||||
|
||||
// Ajouter les coordonnées si disponibles
|
||||
if (isset($indices['longitude']) && isset($indices['latitude']) &&
|
||||
!empty($data[$indices['longitude']]) && !empty($data[$indices['latitude']])) {
|
||||
$stat->setLon((string)$data[$indices['longitude']])
|
||||
->setLat((string)$data[$indices['latitude']]);
|
||||
}
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stat);
|
||||
$createdCount++;
|
||||
|
||||
// Flush tous les 100 objets pour éviter de surcharger la mémoire
|
||||
if ($createdCount % 100 === 0) {
|
||||
$this->entityManager->flush();
|
||||
$this->entityManager->clear(Stats::class);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush les derniers objets
|
||||
$this->entityManager->flush();
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->addFlash('success', "Import terminé : $createdCount communes ajoutées, $skippedCount déjà existantes, $errorCount erreurs.");
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
#[Route('/admin/create-missing-stats-from-csv', name: 'app_admin_create_missing_stats_from_csv')]
|
||||
public function createMissingStatsFromCsv(): Response
|
||||
{
|
||||
$this->actionLogger->log('admin/create_missing_stats_from_csv', []);
|
||||
|
||||
$csvFile = 'communes_france.csv';
|
||||
if (!file_exists($csvFile)) {
|
||||
$this->addFlash('error', 'Le fichier CSV des communes n\'existe pas. Veuillez exécuter le script fetch_communes.py pour le générer.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$statsRepo = $this->entityManager->getRepository(Stats::class);
|
||||
$createdCount = 0;
|
||||
$skippedCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Ouvrir le fichier CSV
|
||||
$handle = fopen($csvFile, 'r');
|
||||
if (!$handle) {
|
||||
$this->addFlash('error', 'Impossible d\'ouvrir le fichier CSV des communes.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Lire l'en-tête pour déterminer les indices des colonnes
|
||||
$header = fgetcsv($handle);
|
||||
$indices = array_flip($header);
|
||||
|
||||
// Vérifier que les colonnes nécessaires existent
|
||||
$requiredColumns = ['code', 'nom'];
|
||||
foreach ($requiredColumns as $column) {
|
||||
if (!isset($indices[$column])) {
|
||||
$this->addFlash('error', "La colonne '$column' est manquante dans le fichier CSV.");
|
||||
fclose($handle);
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
}
|
||||
|
||||
// Traiter chaque ligne du CSV
|
||||
while (($data = fgetcsv($handle)) !== false) {
|
||||
try {
|
||||
$inseeCode = $data[$indices['code']];
|
||||
|
||||
// Vérifier si une Stats existe déjà pour ce code INSEE
|
||||
$existingStat = $statsRepo->findOneBy(['zone' => $inseeCode]);
|
||||
if ($existingStat) {
|
||||
$skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats
|
||||
$stat = new Stats();
|
||||
$stat->setZone($inseeCode)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('command'); // Utiliser 'command' comme source
|
||||
|
||||
// Ajouter le nom si disponible
|
||||
if (isset($indices['nom']) && !empty($data[$indices['nom']])) {
|
||||
$stat->setName($data[$indices['nom']]);
|
||||
}
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($indices['population']) && !empty($data[$indices['population']])) {
|
||||
$stat->setPopulation((int)$data[$indices['population']]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($indices['codesPostaux']) && !empty($data[$indices['codesPostaux']])) {
|
||||
$stat->setCodesPostaux($data[$indices['codesPostaux']]);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($indices['siren']) && !empty($data[$indices['siren']])) {
|
||||
$stat->setSiren((int)$data[$indices['siren']]);
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($indices['codeEpci']) && !empty($data[$indices['codeEpci']])) {
|
||||
$stat->setCodeEpci((int)$data[$indices['codeEpci']]);
|
||||
}
|
||||
|
||||
// Compléter les données manquantes (coordonnées, budget, etc.)
|
||||
$this->completeStatsData($stat);
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stat);
|
||||
$createdCount++;
|
||||
|
||||
// Flush tous les 100 objets pour éviter de surcharger la mémoire
|
||||
if ($createdCount % 100 === 0) {
|
||||
$this->entityManager->flush();
|
||||
$this->entityManager->clear(Stats::class);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errorCount++;
|
||||
$this->actionLogger->log('error_create_missing_stats_from_csv', [
|
||||
'insee_code' => $inseeCode ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Flush les derniers objets
|
||||
$this->entityManager->flush();
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->addFlash('success', "Création des Stats manquantes terminée : $createdCount communes ajoutées, $skippedCount déjà existantes, $errorCount erreurs.");
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Complète les données manquantes d'un objet Stats (coordonnées, budget, etc.)
|
||||
*/
|
||||
private function completeStatsData(Stats $stat): void
|
||||
{
|
||||
$insee_code = $stat->getZone();
|
||||
|
||||
// Compléter les coordonnées si manquantes
|
||||
if (!$stat->getLat() || !$stat->getLon()) {
|
||||
try {
|
||||
$apiUrl = 'https://geo.api.gouv.fr/communes/' . $insee_code . '?fields=centre';
|
||||
$response = @file_get_contents($apiUrl);
|
||||
if ($response !== false) {
|
||||
$data = json_decode($response, true);
|
||||
if (isset($data['centre']['coordinates']) && count($data['centre']['coordinates']) === 2) {
|
||||
$stat->setLon((string)$data['centre']['coordinates'][0]);
|
||||
$stat->setLat((string)$data['centre']['coordinates'][1]);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch coordinates: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Compléter le budget si manquant
|
||||
if (!$stat->getBudgetAnnuel() && property_exists($this, 'budgetService') && $this->budgetService !== null) {
|
||||
try {
|
||||
$budget = $this->budgetService->getBudgetAnnuel($insee_code);
|
||||
if ($budget !== null) {
|
||||
$stat->setBudgetAnnuel((string)$budget);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch budget: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculer le pourcentage de complétion
|
||||
$stat->computeCompletionPercent();
|
||||
}
|
||||
|
||||
#[Route('/admin/podium-contributeurs-osm', name: 'app_admin_podium_contributeurs_osm')]
|
||||
public function podiumContributeursOsm(): Response
|
||||
|
@ -1401,7 +1721,7 @@ final class AdminController extends AbstractController
|
|||
$topContributors = array_slice($contributions, 0, 10, true);
|
||||
|
||||
return $this->render('admin/podium_contributeurs_osm.html.twig', [
|
||||
'contributors' => $topContributors
|
||||
'podium' => $topContributors
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1015,6 +1015,7 @@ class PublicController extends AbstractController
|
|||
'count_data' => json_encode($countData),
|
||||
'completion_data' => json_encode($completionData),
|
||||
'icons' => \App\Service\FollowUpService::getFollowUpIcons(),
|
||||
'maptiler_token' => $_ENV['MAPTILER_TOKEN'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue