mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-06-20 01:44:42 +02:00
ajout view email proposé pour les commerçants
This commit is contained in:
parent
e71177dee1
commit
dbe2f62c45
12 changed files with 275 additions and 12 deletions
35
migrations/Version20250619074501.php
Normal file
35
migrations/Version20250619074501.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250619074501 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->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);
|
||||
}
|
||||
}
|
53
migrations/Version20250619074657.php
Normal file
53
migrations/Version20250619074657.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250619074657 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->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);
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
27
templates/admin/email_content.html.twig
Normal file
27
templates/admin/email_content.html.twig
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div class="content">
|
||||
<i class="bi bi-shop-window"></i>
|
||||
<p>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.
|
||||
|
||||
<br>
|
||||
Plus les informations seront à jour et plus vous aurez de chances d'avoir des clients satisfaits.</p>
|
||||
|
||||
<p> Vous pouvez le modifier en cliquant sur le bouton ci-dessous, c'est gratuit et sans engagement.</p>
|
||||
|
||||
|
||||
<a href="{{ path('app_admin_commerce', {'id': place.id}) }}" class="btn btn-primary">
|
||||
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
Compléter les informations de mon commerce</a>
|
||||
<br>
|
||||
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 <a href="mailto:contact@openstreetmap.fr">contact@openstreetmap.fr</a>.
|
||||
<br>
|
||||
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 <a href="https://fposm.fr">https://fposm.fr</a>.
|
||||
<br>
|
||||
En vous souhaitant une bonne journée.
|
||||
<br>
|
||||
- Les bénévoles de l'association OpenStreetMap France.
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<a href="{{ path('app_admin_commerce', {'id': place.id}) }}">Ne plus être sollicité pour mettre à jour mon commerce</a>
|
||||
</div>
|
|
@ -10,6 +10,12 @@
|
|||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ path('app_admin_make_email_for_place', {'id': commerce.id}) }}">
|
||||
voir email
|
||||
<i class="bi bi-envelope-fill"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right completion-cell"
|
||||
style="background : rgba(0,255,0,{{ commerce.getCompletionPercentage() / 100 }})"
|
||||
data-bs-toggle="popover"
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<tr>
|
||||
<th>Nom ({{ stats.places|length }})</th>
|
||||
<th>
|
||||
<i class="bi bi-envelope-fill"></i>
|
||||
Email
|
||||
</th>
|
||||
<th>
|
||||
<i class="bi bi-circle-fill"></i>
|
||||
Completion %
|
||||
</th>
|
||||
|
|
12
templates/admin/view_email_for_place.html.twig
Normal file
12
templates/admin/view_email_for_place.html.twig
Normal file
|
@ -0,0 +1,12 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Email pour {{ place.name }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
<h1>Email pour {{ place.name }}</h1>
|
||||
<div class="content">
|
||||
{% include 'admin/email_content.html.twig' with {'place': place} %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -97,6 +97,7 @@
|
|||
>
|
||||
<i class="bi bi-recycle"></i>
|
||||
</a>
|
||||
|
||||
<a href="{{ path('app_admin_delete_by_zone', {'insee_code': stat.zone}) }}"
|
||||
class="btn btn-sm btn-danger"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir supprimer cette zone ?')"
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th>Code postal</th>
|
||||
<th>Code insee</th>
|
||||
<th>Note</th>
|
||||
<th>contenu de note</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -25,6 +26,7 @@
|
|||
<td>
|
||||
{{place.zipcode}}
|
||||
</td>
|
||||
<td>{{ place.note }}</td>
|
||||
<td>{{ place.noteContent }}</td>
|
||||
<td><a class="btn btn-primary" href="{{ path('app_admin_commerce', {'id': place.id}) }}">
|
||||
<i class="bi bi-pencil"></i>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue