diff --git a/migrations/Version20250619074501.php b/migrations/Version20250619074501.php
new file mode 100644
index 0000000..2dffe19
--- /dev/null
+++ b/migrations/Version20250619074501.php
@@ -0,0 +1,35 @@
+addSql(<<<'SQL'
+ ALTER TABLE place ADD osm_data_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
+ SQL);
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql(<<<'SQL'
+ ALTER TABLE place DROP osm_data_date
+ SQL);
+ }
+}
diff --git a/migrations/Version20250619074657.php b/migrations/Version20250619074657.php
new file mode 100644
index 0000000..59d6d8a
--- /dev/null
+++ b/migrations/Version20250619074657.php
@@ -0,0 +1,53 @@
+addSql(<<<'SQL'
+ ALTER TABLE place ADD osm_data_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats ADD osm_data_date_min TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats ADD osm_data_date_avg TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats ADD osm_data_date_max TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
+ SQL);
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql(<<<'SQL'
+ ALTER TABLE place DROP osm_data_date
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats DROP osm_data_date_min
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats DROP osm_data_date_avg
+ SQL);
+ $this->addSql(<<<'SQL'
+ ALTER TABLE stats DROP osm_data_date_max
+ SQL);
+ }
+}
diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php
index c554415..fd2b5be 100644
--- a/src/Controller/AdminController.php
+++ b/src/Controller/AdminController.php
@@ -82,8 +82,11 @@ final class AdminController extends AbstractController
->setSiret($this->motocultrice->find_siret($placeData['tags']) ?? '')
->setAskedHumainsSupport(false)
->setLastContactAttemptDate(null)
- ->setNote('')
- ->setPlaceCount(0);
+ ->setNote($this->motocultrice->find_tag($placeData['tags'], 'note') ? true : false)
+ ->setNoteContent($this->motocultrice->find_tag($placeData['tags'], 'note') ?? '')
+ ->setPlaceCount(0)
+ // ->setOsmData($placeData['modified'] ?? null)
+ ;
// Mettre à jour les données depuis Overpass
$place->update_place_from_overpass_data($placeData);
@@ -175,15 +178,6 @@ final class AdminController extends AbstractController
$urls = $stats->getAllCTCUrlsMap();
- $statsHistory = $this->entityManager->getRepository(StatsHistory::class)
- ->createQueryBuilder('sh')
- ->where('sh.stats = :stats')
- ->setParameter('stats', $stats)
- ->orderBy('sh.id', 'DESC')
- ->setMaxResults(365)
- ->getQuery()
- ->getResult();
-
// Calculer les statistiques
$calculatedStats = $this->motocultrice->calculateStats($commerces);
@@ -209,6 +203,15 @@ final class AdminController extends AbstractController
$this->entityManager->persist($stats);
$this->entityManager->flush();
+ // Récupérer l'historique des stats APRÈS que l'entité soit persistée
+ $statsHistory = $this->entityManager->getRepository(StatsHistory::class)
+ ->createQueryBuilder('sh')
+ ->where('sh.stats = :stats')
+ ->setParameter('stats', $stats)
+ ->orderBy('sh.id', 'DESC')
+ ->setMaxResults(365)
+ ->getQuery()
+ ->getResult();
return $this->render('admin/stats.html.twig', [
'stats' => $stats,
@@ -514,4 +517,23 @@ final class AdminController extends AbstractController
return $response;
}
+
+ #[Route('/admin/make_email_for_place/{id}', name: 'app_admin_make_email_for_place')]
+ public function make_email_for_place(Place $place): Response
+ {
+
+ 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')]
+ public function no_more_sollicitation_for_place(Place $place): Response
+ {
+ $place->setOptedOut(true);
+ $this->entityManager->persist($place);
+ $this->entityManager->flush();
+
+ $this->addFlash('success', 'Votre lieu '.$place->getName().' ne sera plus sollicité pour mettre à jour ses informations.');
+
+ return $this->redirectToRoute('app_public_index');
+ }
}
diff --git a/src/Entity/Place.php b/src/Entity/Place.php
index f7b1c25..867a642 100644
--- a/src/Entity/Place.php
+++ b/src/Entity/Place.php
@@ -103,6 +103,43 @@ class Place
#[ORM\Column(nullable: true)]
private ?int $habitants = null;
+ #[ORM\Column(nullable: true)]
+ private ?\DateTime $osm_data_date = null;
+
+
+ public function getPlaceTypeName(): ?string
+ {
+ if ($this->main_tag == 'amenity=restaurant') {
+ return 'restaurant';
+ }
+ if ($this->main_tag == 'amenity=bar') {
+ return 'bar';
+ }
+ if ($this->main_tag == 'amenity=cafe') {
+ return 'café';
+ }
+ if ($this->main_tag == 'amenity=hotel') {
+ return 'hôtel';
+ }
+ if ($this->main_tag == 'amenity=supermarket') {
+ return 'supermarché';
+ }
+ if ($this->main_tag == 'amenity=pharmacy') {
+ return 'pharmacie';
+ }
+ if ($this->main_tag == 'amenity=bank') {
+ return 'banque';
+ }
+ if ($this->main_tag == 'amenity=post_office') {
+ return 'poste';
+ }
+ if ($this->main_tag == 'amenity=school') {
+ return 'école';
+ }
+
+ return 'lieu';
+ }
+
public function getMainTag(): ?string
{
return $this->main_tag;
@@ -594,4 +631,16 @@ class Place
return $this;
}
+
+ public function getOsmDataDate(): ?\DateTime
+ {
+ return $this->osm_data_date;
+ }
+
+ public function setOsmDataDate(?\DateTime $osm_data_date): static
+ {
+ $this->osm_data_date = $osm_data_date;
+
+ return $this;
+ }
}
diff --git a/src/Entity/Stats.php b/src/Entity/Stats.php
index 2295028..cc59cf7 100644
--- a/src/Entity/Stats.php
+++ b/src/Entity/Stats.php
@@ -86,6 +86,15 @@ class Stats
#[ORM\Column(nullable: true)]
private ?int $avec_name = null;
+ #[ORM\Column(nullable: true)]
+ private ?\DateTime $osm_data_date_min = null;
+
+ #[ORM\Column(nullable: true)]
+ private ?\DateTime $osm_data_date_avg = null;
+
+ #[ORM\Column(nullable: true)]
+ private ?\DateTime $osm_data_date_max = null;
+
public function getCTCurlBase(): ?string
{
$base = 'https://complete-tes-commerces.fr/';
@@ -493,6 +502,42 @@ class Stats
return $this;
}
+
+ public function getOsmDataDateMin(): ?\DateTime
+ {
+ return $this->osm_data_date_min;
+ }
+
+ public function setOsmDataDateMin(?\DateTime $osm_data_date_min): static
+ {
+ $this->osm_data_date_min = $osm_data_date_min;
+
+ return $this;
+ }
+
+ public function getOsmDataDateAvg(): ?\DateTime
+ {
+ return $this->osm_data_date_avg;
+ }
+
+ public function setOsmDataDateAvg(?\DateTime $osm_data_date_avg): static
+ {
+ $this->osm_data_date_avg = $osm_data_date_avg;
+
+ return $this;
+ }
+
+ public function getOsmDataDateMax(): ?\DateTime
+ {
+ return $this->osm_data_date_max;
+ }
+
+ public function setOsmDataDateMax(?\DateTime $osm_data_date_max): static
+ {
+ $this->osm_data_date_max = $osm_data_date_max;
+
+ return $this;
+ }
}
diff --git a/src/Service/Motocultrice.php b/src/Service/Motocultrice.php
index c92fd42..6cd6fed 100644
--- a/src/Service/Motocultrice.php
+++ b/src/Service/Motocultrice.php
@@ -216,6 +216,13 @@ out center tags;';
return null;
}
+ public function find_tag($tags, $tag) {
+ if(isset($tags[$tag]) && $tags[$tag] != '') {
+ return $tags[$tag];
+ }
+ return null;
+ }
+
public function get_city_osm_from_zip_code($zip_code) {
// Requête Overpass pour obtenir la zone administrative de niveau 8 avec un nom
$query = "[out:json][timeout:25];
diff --git a/templates/admin/email_content.html.twig b/templates/admin/email_content.html.twig
new file mode 100644
index 0000000..7dce523
--- /dev/null
+++ b/templates/admin/email_content.html.twig
@@ -0,0 +1,27 @@
+
+
+
Bonjour, votre {{place.getPlaceTypeName()}} "{{place.name }}" est présent dans la base de données mondiale OpenStreetMap avec 650 000 autres en France. Ces informations sont utilisées dans des milliers de sites web, par Île de France mobilités, TomTom, Geovelo, Cartes IGN, Facebook, Instagram, et Apple Plans.
+
+
+ Plus les informations seront à jour et plus vous aurez de chances d'avoir des clients satisfaits.
+
+
Vous pouvez le modifier en cliquant sur le bouton ci-dessous, c'est gratuit et sans engagement.
+
+
+
+
+
+ Compléter les informations de mon commerce
+
+ Les bénévoles de l'association OpenStreetMap France ont mis en place cet outil pour faciliter la mise à jour des informations de vos commerces et améliorer la souveraineté numérique. Si vous avez besoin d'aide, n'hésitez pas à nous contacter à l'adresse
contact@openstreetmap.fr.
+
+ Pour des besoins de prestation de services concernant l'intégration de données, vous pouvez contacter la fédération des pros d'OpenStreetMap France sur
https://fposm.fr.
+
+En vous souhaitant une bonne journée.
+
+- Les bénévoles de l'association OpenStreetMap France.
+
+
+
+
Ne plus être sollicité pour mettre à jour mon commerce
+
\ No newline at end of file
diff --git a/templates/admin/stats/row.html.twig b/templates/admin/stats/row.html.twig
index cbabaed..ead6726 100644
--- a/templates/admin/stats/row.html.twig
+++ b/templates/admin/stats/row.html.twig
@@ -10,6 +10,12 @@
{% endif %}
+
+
+ voir email
+
+
+ |
| Nom ({{ stats.places|length }}) |
+
+ Email
+ |
+
Completion %
|
diff --git a/templates/admin/view_email_for_place.html.twig b/templates/admin/view_email_for_place.html.twig
new file mode 100644
index 0000000..59830de
--- /dev/null
+++ b/templates/admin/view_email_for_place.html.twig
@@ -0,0 +1,12 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}Email pour {{ place.name }}{% endblock %}
+
+{% block body %}
+
+
Email pour {{ place.name }}
+
+ {% include 'admin/email_content.html.twig' with {'place': place} %}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/public/dashboard.html.twig b/templates/public/dashboard.html.twig
index 35f2df1..db5f5b5 100644
--- a/templates/public/dashboard.html.twig
+++ b/templates/public/dashboard.html.twig
@@ -97,6 +97,7 @@
>
+
Nom |
- Code postal |
+ Code insee |
Note |
+ contenu de note |
Actions |
@@ -25,6 +26,7 @@
{{place.zipcode}}
|
+ {{ place.note }} |
{{ place.noteContent }} |
|