Skip to content

Commit

Permalink
load epci #2423
Browse files Browse the repository at this point in the history
  • Loading branch information
sfinx13 committed Apr 6, 2024
1 parent 470242e commit e7a8403
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 12 deletions.
32 changes: 32 additions & 0 deletions migrations/Version20240405172355.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240405172355 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add epci table';
}

public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE epci (id INT AUTO_INCREMENT NOT NULL, nom VARCHAR(255) NOT NULL, slug VARCHAR(255) NOT NULL, UNIQUE INDEX slug_unique (slug), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE commune ADD epci_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE commune ADD CONSTRAINT FK_E2E2D1EE4E7C18CB FOREIGN KEY (epci_id) REFERENCES epci (id)');
$this->addSql('CREATE INDEX IDX_E2E2D1EE4E7C18CB ON commune (epci_id)');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE commune DROP FOREIGN KEY FK_E2E2D1EE4E7C18CB');
$this->addSql('DROP TABLE epci');
$this->addSql('DROP INDEX IDX_E2E2D1EE4E7C18CB ON commune');
$this->addSql('ALTER TABLE commune DROP epci_id');
}
}
98 changes: 98 additions & 0 deletions src/Command/LoadEpciCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace App\Command;

use App\Entity\Epci;
use App\Repository\CommuneRepository;
use App\Repository\EpciRepository;
use App\Repository\TerritoryRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

#[AsCommand(
name: 'app:load-epci',
description: 'Load EPCI to communes',
)]
class LoadEpciCommand extends Command
{
public const API_EPCI_ALL_URL = 'https://geo.api.gouv.fr/epcis?fields=nom';
public const API_EPCI_COMMUNE_URL = 'https://geo.api.gouv.fr/epcis/%d/communes';

public function __construct(
private HttpClientInterface $httpClient,
private TerritoryRepository $territoryRepository,
private CommuneRepository $communeRepository,
private EpciRepository $epciRepository,
private EntityManagerInterface $entityManager,
private SluggerInterface $slugger,
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$response = $this->httpClient->request('GET', self::API_EPCI_ALL_URL);
if (Response::HTTP_OK !== $response->getStatusCode()) {
$io->error('API failed');

return Command::FAILURE;
}

$epciList = json_decode($response->getContent(), true);
$progressBar = new ProgressBar($output, \count($epciList));
$progressBar->start();
foreach ($epciList as $epciItem) {
$epci = $this->epciRepository->findOneBy(['nom' => $epciNom = $epciItem['nom']]);
if (!$epci) {
$epci = (new Epci())
->setNom($epciNom)
->setSlug($this->slugger->slug($epciNom));
}
$response = $this->httpClient->request(
'GET',
$epciCommunesUrl = sprintf(self::API_EPCI_COMMUNE_URL, $epciItem['code'])
);

if (Response::HTTP_OK === $response->getStatusCode()) {
$communeList = json_decode($response->getContent(), true);
foreach ($communeList as $communeItem) {
$communes = $this->communeRepository->findByCodesPostaux($communeItem['codesPostaux']);
foreach ($communes as $commune) {
$epci->addCommune($commune);
}
}
$this->entityManager->flush();
} else {
$io->error(sprintf('API failed for: %s', $epciCommunesUrl));
}
$progressBar->advance();
}

$progressBar->finish();
$this->entityManager->flush();
$nbCommunesWithECPI = $this->communeRepository->count([]);
$nbCommunesWithoutECPI = $this->communeRepository->count(['epci' => null]);
$io->success(sprintf(
'EPCI loaded with %d communes that belong to EPCI',
$nbCommunesWithECPI - $nbCommunesWithoutECPI
));
if ($nbCommunesWithoutECPI > 0) {
$io->warning(sprintf(
'%d communes do not belong to EPCI, the code postal might be obsolete.',
$nbCommunesWithoutECPI
));
}

return Command::SUCCESS;
}
}
17 changes: 11 additions & 6 deletions src/Dto/Request/Signalement/SignalementSearchQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Dto\Request\Signalement;

use App\Entity\Enum\SignalementStatus;
use App\Service\Signalement\SearchFilter;
use Symfony\Component\Validator\Constraints as Assert;

class SignalementSearchQuery
Expand All @@ -14,7 +15,7 @@ public function __construct(
private readonly ?string $searchTerms = null,
#[Assert\Choice(['nouveau', 'en cours', 'ferme', 'refuse'])]
private readonly ?string $status = null,
private readonly ?string $commune = null,
private readonly ?array $communes = null,
private readonly ?array $etiquettes = null,
#[Assert\Date(message: 'La date de début n\'est pas une date valide')]
private readonly ?string $dateDepotDebut = null,
Expand All @@ -29,7 +30,7 @@ public function __construct(
private readonly ?string $dateDernierSuiviDebut = null,
#[Assert\Date(message: 'La date de fin n\'est pas une date valide')]
private readonly ?string $dateDernierSuiviFin = null,
#[Assert\Choice(['accepte', 'en_attente', 'refuse', 'cloture_un_partnaire', 'cloture_tous_partenaire'])]
#[Assert\Choice(['accepte', 'en_attente', 'refuse', 'cloture_un_partenaire', 'cloture_tous_partenaire'])]
private readonly ?string $statusAffectation = null,
#[Assert\GreaterThanOrEqual(0)]
private readonly ?float $criticiteScoreMin = null,
Expand Down Expand Up @@ -69,9 +70,9 @@ public function getStatus(): ?string
return $this->status;
}

public function getCommune(): ?string
public function getCommunes(): ?array
{
return $this->commune;
return $this->communes;
}

public function getEtiquettes(): ?array
Expand Down Expand Up @@ -174,6 +175,10 @@ public function getOrderBy(): string
return $this->orderBy;
}

/**
* Permet de s'appuyer sur le système pour le système de filtre.
* Aprés la MEP s'appuyer exclusivement sur le DTO au lieu du tableau de filtres @see SearchFilter::buildFilters().
*/
public function getFilters(): array
{
$filters = [];
Expand All @@ -182,7 +187,7 @@ public function getFilters(): array
$filters['statuses'] = null !== $this->getStatus()
? [SignalementStatus::mapFilterStatus($this->getStatus())]
: null;
$filters['cities'] = null !== $this->getCommune() ? [$this->getCommune()] : null;
$filters['cities'] = $this->getCommunes() ?? null;
$filters['partners'] = $this->getPartenaires() ?? null;
$filters['allocs'] = null !== $this->getAllocataire() ? [$this->getAllocataire()] : null;
$filters['housetypes'] = match ($this->getNatureParc()) {
Expand Down Expand Up @@ -224,7 +229,7 @@ public function getFilters(): array
}
$filters['statusAffectation'] = $this->getStatusAffectation();
$filters['closed_affectation'] = match ($filters['statusAffectation']) {
'cloture_un_partnaire' => ['ONE_CLOSED'],
'cloture_un_partenaire' => ['ONE_CLOSED'],
'cloture_tous_partenaire' => ['ALL_CLOSED'],
default => null
};
Expand Down
15 changes: 15 additions & 0 deletions src/Entity/Commune.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class Commune
#[ORM\Column(type: 'boolean')]
private $isZonePermisLouer;

#[ORM\ManyToOne(inversedBy: 'communes', cascade: ['persist'])]
private ?Epci $epci = null;

public function getId(): ?int
{
return $this->id;
Expand Down Expand Up @@ -83,6 +86,18 @@ public function setTerritory(?Territory $territory): self
return $this;
}

public function getEpci(): ?Epci
{
return $this->epci;
}

public function setEpci(?Epci $epci): static
{
$this->epci = $epci;

return $this;
}

public function __toString(): string
{
return $this->nom;
Expand Down
92 changes: 92 additions & 0 deletions src/Entity/Epci.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace App\Entity;

use App\Repository\EpciRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\UniqueConstraint;

#[ORM\Entity(repositoryClass: EpciRepository::class)]
#[UniqueConstraint(name: 'slug_unique', columns: ['slug'])]
class Epci
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 255)]
private ?string $nom = null;

#[ORM\Column(length: 255)]
private ?string $slug = null;

#[ORM\OneToMany(mappedBy: 'epci', targetEntity: Commune::class)]
private Collection $communes;

public function __construct()
{
$this->communes = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
}

public function getNom(): ?string
{
return $this->nom;
}

public function setNom(string $nom): static
{
$this->nom = $nom;

return $this;
}

public function getSlug(): ?string
{
return $this->slug;
}

public function setSlug(string $slug): static
{
$this->slug = strtolower($slug);

return $this;
}

/**
* @return Collection<int, Commune>
*/
public function getCommunes(): Collection
{
return $this->communes;
}

public function addCommune(Commune $commune): static
{
if (!$this->communes->contains($commune)) {
$this->communes->add($commune);
$commune->setEpci($this);
}

return $this;
}

public function removeCommune(Commune $commune): static
{
if ($this->communes->removeElement($commune)) {
// set the owning side to null (unless already changed)
if ($commune->getEpci() === $this) {
$commune->setEpci(null);
}
}

return $this;
}
}
9 changes: 9 additions & 0 deletions src/Repository/CommuneRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,13 @@ public function remove(Commune $entity, bool $flush = false): void
$this->getEntityManager()->flush();
}
}

public function findByCodesPostaux(array $codesPostaux): array
{
return $this->createQueryBuilder('c')
->where('c.codePostal IN (:codePostaux)')
->setParameter('codePostaux', $codesPostaux)
->getQuery()
->getResult();
}
}
23 changes: 23 additions & 0 deletions src/Repository/EpciRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Repository;

use App\Entity\Epci;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @extends ServiceEntityRepository<Epci>
*
* @method Epci|null find($id, $lockMode = null, $lockVersion = null)
* @method Epci|null findOneBy(array $criteria, array $orderBy = null)
* @method Epci[] findAll()
* @method Epci[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class EpciRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Epci::class);
}
}
2 changes: 2 additions & 0 deletions src/Service/Signalement/SearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use App\Entity\Suivi;
use App\Entity\Territory;
use App\Entity\User;
use App\Repository\CommuneRepository;
use App\Repository\NotificationRepository;
use App\Repository\SignalementQualificationRepository;
use App\Repository\SuiviRepository;
Expand Down Expand Up @@ -66,6 +67,7 @@ public function __construct(
private TerritoryRepository $territoryRepository,
private EntityManagerInterface $entityManager,
private SignalementQualificationRepository $signalementQualificationRepository,
private CommuneRepository $communeRepository,
) {
}

Expand Down
Loading

0 comments on commit e7a8403

Please sign in to comment.