diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php
index d5f61b4c..0e3117e7 100644
--- a/src/Controller/AdminController.php
+++ b/src/Controller/AdminController.php
@@ -590,6 +590,7 @@ final class AdminController extends AbstractController
{
$deleteMissing = $request->query->getBoolean('deleteMissing', true);
$disableFollowUpCleanup = $request->query->getBoolean('disableFollowUpCleanup', false);
+ $debug = $request->query->getBoolean('debug', false);
$this->actionLogger->log('labourer', ['insee_code' => $insee_code]);
@@ -599,11 +600,51 @@ final class AdminController extends AbstractController
$this->actionLogger->log('ERROR_labourer_bad_insee', ['insee_code' => $insee_code]);
return $this->redirectToRoute('app_public_index');
}
+ $city = null;
+ $city_insee_found = null;
+ $city_debug = null;
try {
// Récupérer ou créer les stats pour cette zone
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
$city = $this->motocultrice->get_city_osm_from_zip_code($insee_code);
+ // Si la fonction retourne un tableau ou un objet, on tente d'en extraire le code INSEE
+ if (is_array($city) && isset($city['insee'])) {
+ $city_insee_found = $city['insee'];
+ $city_debug = $city;
+ $city = $city['name'] ?? $city_insee_found;
+ } elseif (is_object($city) && isset($city->insee)) {
+ $city_insee_found = $city->insee;
+ $city_debug = (array)$city;
+ $city = $city->name ?? $city_insee_found;
+ } else {
+ $city_insee_found = $insee_code;
+ }
+
+ // Si le code INSEE trouvé ne correspond pas à celui demandé, afficher un message et stopper
+ if ($city_insee_found !== $insee_code) {
+ $msg = "Attention : le code INSEE trouvé (" . $city_insee_found . ") ne correspond pas à celui demandé (" . $insee_code . "). Aucune modification effectuée.";
+ if ($debug) {
+ return $this->render('admin/labourage_debug.html.twig', [
+ 'insee_code' => $insee_code,
+ 'city_insee_found' => $city_insee_found,
+ 'city_debug' => $city_debug,
+ 'city_name' => $city,
+ 'message' => $msg,
+ 'stats' => $stats,
+ ]);
+ }
+ $this->addFlash('error', $msg);
+ return $this->render('admin/labourage_debug.html.twig', [
+ 'insee_code' => $insee_code,
+ 'city_insee_found' => $city_insee_found,
+ 'city_debug' => $city_debug,
+ 'city_name' => $city,
+ 'message' => $msg,
+ 'stats' => $stats,
+ ]);
+ }
+
if (!$stats) {
$stats = new Stats();
$stats->setDateCreated(new \DateTime());
@@ -970,10 +1011,29 @@ final class AdminController extends AbstractController
return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
} catch (\Exception $e) {
$this->addFlash('error', 'Erreur lors du labourage : ' . $e->getMessage());
- die(var_dump($e));
+ if ($debug) {
+ return $this->render('admin/labourage_debug.html.twig', [
+ 'insee_code' => $insee_code,
+ 'city_insee_found' => $city_insee_found,
+ 'city_debug' => $city_debug,
+ 'city_name' => $city,
+ 'message' => $e->getMessage(),
+ 'stats' => $stats ?? null,
+ ]);
+ }
+ return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
+ }
+ // ... (fin normale du traitement, on peut ajouter un affichage debug si besoin)
+ if ($debug) {
+ return $this->render('admin/labourage_debug.html.twig', [
+ 'insee_code' => $insee_code,
+ 'city_insee_found' => $city_insee_found,
+ 'city_debug' => $city_debug,
+ 'city_name' => $city,
+ 'message' => null,
+ 'stats' => $stats,
+ ]);
}
-
- // return $this->redirectToRoute('app_public_dashboard');
return $this->redirectToRoute('app_admin_stats', ['insee_code' => $insee_code]);
}
@@ -1673,4 +1733,33 @@ final class AdminController extends AbstractController
$response->setContent($csv);
return $response;
}
+
+ #[Route('/admin/test-ctc/{insee_code}', name: 'admin_test_ctc', requirements: ['insee_code' => '\d+'], defaults: ['insee_code' => null])]
+ public function testCTC(Request $request, ?string $insee_code = null): Response
+ {
+ $json = null;
+ $url = null;
+ $error = null;
+ $stats = null;
+ if ($insee_code) {
+ $stats = $this->entityManager->getRepository(\App\Entity\Stats::class)->findOneBy(['zone' => $insee_code]);
+ if ($stats) {
+ $url = $stats->getCTCurlBase();
+ try {
+ $json = file_get_contents($url . '_last_stats.json');
+ } catch (\Exception $e) {
+ $error = $e->getMessage();
+ }
+ } else {
+ $error = "Aucune stats trouvée pour ce code INSEE.";
+ }
+ }
+ return $this->render('admin/test_ctc.html.twig', [
+ 'insee_code' => $insee_code,
+ 'url' => $url ? $url . '_last_stats.json' : null,
+ 'json' => $json,
+ 'error' => $error,
+ 'stats' => $stats
+ ]);
+ }
}
diff --git a/templates/admin/followup_embed_graph.html.twig b/templates/admin/followup_embed_graph.html.twig
index 70cb046b..cea0bfd2 100644
--- a/templates/admin/followup_embed_graph.html.twig
+++ b/templates/admin/followup_embed_graph.html.twig
@@ -10,6 +10,9 @@
Voir la page de la ville
+
+ Graphe détaillé
+
OSM Mon Commerce
diff --git a/templates/admin/labourage_debug.html.twig b/templates/admin/labourage_debug.html.twig
new file mode 100644
index 00000000..cf48a1b1
--- /dev/null
+++ b/templates/admin/labourage_debug.html.twig
@@ -0,0 +1,25 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}Debug Labourage{% endblock %}
+
+{% block body %}
+
+
Debug Labourage
+
+ Code INSEE demandé : {{ insee_code }}
+ Code INSEE trouvé : {{ city_insee_found }}
+ Nom de la ville trouvé : {{ city_name }}
+
+ {% if message %}
+
{{ message }}
+ {% endif %}
+
Détails bruts de la ville trouvée :
+
{{ city_debug|json_encode(constant('JSON_PRETTY_PRINT')) }}
+ {% if stats %}
+
Stats associées :
+
{{ dump(stats) }}
+ {% endif %}
+
Rafraîchir debug
+
Retour aux stats
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig
index 24fe1f8c..b68edc5a 100644
--- a/templates/admin/stats.html.twig
+++ b/templates/admin/stats.html.twig
@@ -62,6 +62,54 @@
background: #388e3c;
border-color: #1b5e20;
}
+
+ .compact-theme-card {
+ transition: transform 0.2s ease-in-out;
+ }
+
+ .compact-theme-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1) !important;
+ }
+
+ .theme-title a {
+ font-size: 0.85rem;
+ line-height: 1.2;
+ }
+
+ .theme-stats {
+ font-size: 0.75rem;
+ color: #6c757d;
+ }
+
+ .theme-actions .btn {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.75rem;
+ }
+ .theme-row-scroll {
+ overflow-x: auto;
+ white-space: nowrap;
+ padding-bottom: 0.5rem;
+ }
+ .theme-row-scroll .col-auto {
+ display: inline-block;
+ float: none;
+ }
+ .theme-row-scroll .compact-theme-card {
+ display: inline-block;
+ vertical-align: top;
+ margin-right: 8px;
+ }
+ .tab-content {
+ margin-top: 1.5rem;
+ }
+ .table-theme th, .table-theme td {
+ vertical-align: middle;
+ font-size: 0.95em;
+ }
+ .table-theme th {
+ background: #f8f9fa;
+ }
{% endblock %}
@@ -149,70 +197,179 @@
'healthcare': 'nwr["healthcare"](area.searchArea);nwr["amenity"="doctors"](area.searchArea);nwr["amenity"="pharmacy"](area.searchArea);nwr["amenity"="hospital"](area.searchArea);nwr["amenity"="clinic"](area.searchArea);nwr["amenity"="social_facility"](area.searchArea);'
} %}
-
- {% for type, data in latestFollowups %}
- {% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ overpass_type_queries[type]|default('') ~ ');\n(._;>;);\nout meta;\n>;' %}
- {% set completion = data.completion is defined ? data.completion.getMeasure() : null %}
- {% set completion_class = '' %}
- {% if completion is not null %}
- {% if completion < 40 %}
- {% set completion_class = 'completion-low' %}
- {% elseif completion < 80 %}
- {% set completion_class = 'completion-medium' %}
- {% else %}
- {% set completion_class = 'completion-high' %}
- {% endif %}
- {% endif %}
- {% if data is defined and (data.count is defined or data.completion is defined) %}
-
-
-
-
-
-
{{ followup_labels[type]|default(type|capitalize) }}
-
-
-
-
{{ data.count is defined ? data.count.getMeasure() : '?' }}
-
{{ completion is not null ? completion : '?' }}%
- {% if progression7Days[type] is defined %}
- {% set countDelta = progression7Days[type].count %}
- {% set completionDelta = progression7Days[type].completion %}
- {% if countDelta is not null or completionDelta is not null %}
-
- {% if countDelta is not null %}
-
- {{ countDelta > 0 ? '+' ~ countDelta : countDelta == 0 ? '0' : countDelta }}
-
+{% set theme_groups = {
+ 'emergency': ['fire_hydrant', 'defibrillator'],
+ 'transport': ['bus_stop', 'charging_station'],
+ 'healthcare': ['healthcare', 'laboratory'],
+ 'education': ['school'],
+ 'security': ['police', 'camera'],
+ 'infrastructure': ['toilets', 'recycling', 'substation']
+} %}
+
+
+
+
+
+
+
+
+
+ Catégorie |
+ Thème |
+ Nombre |
+ Complétion |
+ Progression 7j |
+ Actions |
+
+
+
+ {% for group_name, group_types in theme_groups %}
+ {% for type in group_types %}
+ {% set data = latestFollowups[type]|default(null) %}
+ {% set completion = data and data.completion is defined ? data.completion.getMeasure() : null %}
+ {% set count = data and data.count is defined ? data.count.getMeasure() : null %}
+ {% set completion_class = '' %}
+ {% if completion is not null %}
+ {% if completion < 40 %}
+ {% set completion_class = 'completion-low' %}
+ {% elseif completion < 80 %}
+ {% set completion_class = 'completion-medium' %}
+ {% else %}
+ {% set completion_class = 'completion-high' %}
{% endif %}
- {% if completionDelta is not null %}
-
- {{ completionDelta > 0 ? '+' ~ completionDelta|round(1) : completionDelta == 0 ? '0' : completionDelta|round(1) }}%
-
+ {% endif %}
+
+
+ {% if loop.first %}
+ {% if group_name == 'emergency' %}🚨 Urgence
+ {% elseif group_name == 'transport' %}🚌 Transport
+ {% elseif group_name == 'healthcare' %}🏥 Santé
+ {% elseif group_name == 'education' %}🎓 Éducation
+ {% elseif group_name == 'security' %}🛡️ Sécurité
+ {% elseif group_name == 'infrastructure' %}🏗️ Infrastructure
+ {% else %}{{ group_name|capitalize }}
+ {% endif %}
+ {% endif %}
+ |
+
+
+ {{ followup_labels[type]|default(type|capitalize) }}
+ |
+ {{ count is not null ? count : '?' }} |
+ {{ completion is not null ? completion ~ '%' : '?' }} |
+
+ {% if progression7Days[type] is defined %}
+ {% set countDelta = progression7Days[type].count %}
+ {% set completionDelta = progression7Days[type].completion %}
+
+ {% if countDelta is not null %}
+
+ {{ countDelta > 0 ? '+' ~ countDelta : countDelta == 0 ? '0' : countDelta }}
+
+ {% endif %}
+ {% if completionDelta is not null %}
+
+ {{ completionDelta > 0 ? '+' ~ completionDelta|round(1) : completionDelta == 0 ? '0' : completionDelta|round(1) }}%
+
+ {% endif %}
+
+ {% endif %}
+ |
+
+
+
+
+ |
+
+ {% endfor %}
+ {% endfor %}
+
+
+
+
+ {% for group_name, group_types in theme_groups %}
+
+
+ {% if group_name == 'emergency' %}🚨 Urgence
+ {% elseif group_name == 'transport' %}🚌 Transport
+ {% elseif group_name == 'healthcare' %}🏥 Santé
+ {% elseif group_name == 'education' %}🎓 Éducation
+ {% elseif group_name == 'security' %}🛡️ Sécurité
+ {% elseif group_name == 'infrastructure' %}🏗️ Infrastructure
+ {% else %}{{ group_name|capitalize }}
+ {% endif %}
+
+
+ {% for type in group_types %}
+ {% set data = latestFollowups[type]|default(null) %}
+ {% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ overpass_type_queries[type]|default('') ~ ');\n(._;>;);\nout meta;\n>;' %}
+ {% set completion = data and data.completion is defined ? data.completion.getMeasure() : null %}
+ {% set completion_class = '' %}
+ {% if completion is not null %}
+ {% if completion < 40 %}
+ {% set completion_class = 'completion-low' %}
+ {% elseif completion < 80 %}
+ {% set completion_class = 'completion-medium' %}
+ {% else %}
+ {% set completion_class = 'completion-high' %}
+ {% endif %}
{% endif %}
-
- {% endif %}
- {% endif %}
-
+
+
+
+
+
+
+
+
+
+ {{ data and data.count is defined ? data.count.getMeasure() : '?' }} |
+ {{ completion is not null ? completion : '?' }}%
+
+
+ {% if progression7Days[type] is defined %}
+ {% set countDelta = progression7Days[type].count %}
+ {% set completionDelta = progression7Days[type].completion %}
+ {% if countDelta is not null or completionDelta is not null %}
+
+ {% if countDelta is not null %}
+
+ {{ countDelta > 0 ? '+' ~ countDelta : countDelta == 0 ? '0' : countDelta }}
+
+ {% endif %}
+ {% if completionDelta is not null %}
+
+ {{ completionDelta > 0 ? '+' ~ completionDelta|round(1) : completionDelta == 0 ? '0' : completionDelta|round(1) }}%
+
+ {% endif %}
+
+ {% endif %}
+ {% endif %}
+
+
+
+ {% endfor %}
+
+
+ {% endfor %}
- {% else %}
-
-
-
-
-
-
{{ followup_labels[type]|default(type|capitalize) }}
-
- Graphique
-
-
N = ?
-
?%
-
-
-
- {% endif %}
- {% endfor %}
+
diff --git a/templates/admin/test_ctc.html.twig b/templates/admin/test_ctc.html.twig
new file mode 100644
index 00000000..2fd1ef6a
--- /dev/null
+++ b/templates/admin/test_ctc.html.twig
@@ -0,0 +1,31 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}Test Complète tes commerces{% endblock %}
+
+{% block body %}
+
+
Test Complète tes commerces
+
+ {% if url %}
+
+ {% endif %}
+ {% if error %}
+
{{ error }}
+ {% endif %}
+ {% if json %}
+
JSON reçu :
+
{{ json|json_decode(constant('JSON_OBJECT_AS_ARRAY'))|json_encode(constant('JSON_PRETTY_PRINT')) }}
+ {% elseif url and not error %}
+
Aucune donnée reçue.
+ {% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/public/labourage-form.html.twig b/templates/public/labourage-form.html.twig
index fba9e47c..4780b9dc 100644
--- a/templates/public/labourage-form.html.twig
+++ b/templates/public/labourage-form.html.twig
@@ -1,3 +1,52 @@
+
+