Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}

- name: Install dependencies
uses: php-actions/composer@v7
uses: php-actions/composer@v6
with:
args: --ignore-platform-reqs
php_version: ${{ env.PHP_VERSION }}
Expand All @@ -46,3 +46,4 @@ jobs:
args: --coverage-text --testdox
env:
XDEBUG_MODE: coverage
PHP_MEMORY_LIMIT: 4096M
3 changes: 3 additions & 0 deletions Makefile.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ sync-test-metadata-storage: ## Ensures that the metadata storage is at the lates

phpunit:
docker-compose run --rm rpps-database ./vendor/bin/phpunit --testdox

mytest:
docker-compose run --rm rpps-database ./vendor/bin/phpunit --testdox --group=mygroup
3 changes: 1 addition & 2 deletions config/packages/api_platform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ api_platform:
http_cache:
public: true



mapping:
paths:
- '%kernel.project_dir%/src/Entity'
- '%kernel.project_dir%/src/DTO'
defaults:
pagination_client_items_per_page: true
pagination_maximum_items_per_page: 500
Expand Down
37,545 changes: 37,545 additions & 0 deletions data/insee/v_commune_2024.csv

Large diffs are not rendered by default.

42,218 changes: 42,218 additions & 0 deletions data/insee/v_commune_depuis_1943.csv

Large diffs are not rendered by default.

13,285 changes: 13,285 additions & 0 deletions data/insee/v_mvt_commune_2024.csv

Large diffs are not rendered by default.

466 changes: 466 additions & 0 deletions data/insee/v_pays_et_territoire_depuis_1943.csv

Large diffs are not rendered by default.

229 changes: 229 additions & 0 deletions data/insee/v_pays_territoire_2024.csv

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions migrations/Version20250313102050.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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 Version20250313102050 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add INSEE tables';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE insee_commune (id CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\', type_commune VARCHAR(4) DEFAULT NULL, code_commune VARCHAR(5) DEFAULT NULL, code_region VARCHAR(2) DEFAULT NULL, code_departement VARCHAR(3) DEFAULT NULL, code_collectivite VARCHAR(4) DEFAULT NULL, code_arrondissement VARCHAR(4) DEFAULT NULL, type_nom_en_clair VARCHAR(1) DEFAULT NULL, nom_en_clair VARCHAR(200) NOT NULL, nom_en_clair_typo VARCHAR(200) DEFAULT NULL, nom_en_clair_avec_article VARCHAR(200) DEFAULT NULL, code_canton VARCHAR(5) DEFAULT NULL, code_commune_parente VARCHAR(5) DEFAULT NULL, created_date DATETIME NOT NULL, import_id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE insee_commune_1943 (id CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\', code_commune VARCHAR(5) DEFAULT NULL, type_nom_en_clair VARCHAR(1) DEFAULT NULL, nom_majuscule VARCHAR(200) DEFAULT NULL, nom_typographie VARCHAR(200) DEFAULT NULL, nom_avec_article VARCHAR(200) DEFAULT NULL, date_debut DATE DEFAULT NULL, date_fin DATE DEFAULT NULL, created_date DATETIME NOT NULL, import_id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE insee_commune_event (id CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\', mod_event VARCHAR(2) DEFAULT NULL, date_eff DATE DEFAULT NULL, type_commune_av VARCHAR(4) DEFAULT NULL, code_commune_av VARCHAR(5) DEFAULT NULL, tncc_av VARCHAR(1) DEFAULT NULL, nom_majuscule_av VARCHAR(200) DEFAULT NULL, nom_typo_av VARCHAR(200) DEFAULT NULL, nom_article_av VARCHAR(200) DEFAULT NULL, type_commune_ap VARCHAR(4) DEFAULT NULL, code_commune_ap VARCHAR(5) DEFAULT NULL, tncc_ap VARCHAR(1) DEFAULT NULL, nom_majuscule_ap VARCHAR(200) DEFAULT NULL, nom_typo_ap VARCHAR(200) DEFAULT NULL, nom_article_ap VARCHAR(200) DEFAULT NULL, created_date DATETIME NOT NULL, import_id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE insee_pays (id CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\', code_pays VARCHAR(5) DEFAULT NULL, code_actualite VARCHAR(1) DEFAULT NULL, code_rattachement VARCHAR(5) DEFAULT NULL, annee_apparition VARCHAR(4) DEFAULT NULL, libelle_cog VARCHAR(70) DEFAULT NULL, libelle_officiel VARCHAR(200) DEFAULT NULL, code_iso2 VARCHAR(2) DEFAULT NULL, code_iso3 VARCHAR(3) DEFAULT NULL, code_iso_num3 VARCHAR(3) DEFAULT NULL, created_date DATETIME NOT NULL, import_id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE insee_pays_1943 (id CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\', code_pays VARCHAR(5) DEFAULT NULL, code_rattachement VARCHAR(5) DEFAULT NULL, libelle_cog VARCHAR(70) DEFAULT NULL, libelle_officiel VARCHAR(200) DEFAULT NULL, date_debut DATE DEFAULT NULL, date_fin DATE DEFAULT NULL, created_date DATETIME NOT NULL, import_id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE insee_commune');
$this->addSql('DROP TABLE insee_commune_1943');
$this->addSql('DROP TABLE insee_commune_event');
$this->addSql('DROP TABLE insee_pays');
$this->addSql('DROP TABLE insee_pays_1943');
}
}
4 changes: 3 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" backupGlobals="false" colors="true"
bootstrap="tests/bootstrap.php">
bootstrap="tests/bootstrap.php"
processIsolation="true"
>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
Expand Down
55 changes: 55 additions & 0 deletions src/ApiPlatform/DtoPaginator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\ApiPlatform;

use ApiPlatform\State\Pagination\PaginatorInterface;
use ArrayIterator;
use IteratorAggregate;
use Traversable;

class DtoPaginator implements PaginatorInterface, IteratorAggregate
{
private array $items;
private int $totalItems;
private int $currentPage;
private int $itemsPerPage;

public function __construct(array $data, int $currentPage, int $itemsPerPage)
{
$this->totalItems = count($data);
$this->currentPage = $currentPage;
$this->itemsPerPage = $itemsPerPage;
$offset = ($currentPage - 1) * $itemsPerPage;
$this->items = array_slice($data, $offset, $itemsPerPage);
}

public function getIterator(): Traversable
{
return new ArrayIterator($this->items);
}

public function count(): int
{
return count($this->items);
}

public function getCurrentPage(): float
{
return $this->currentPage;
}

public function getLastPage(): float
{
return (int) ceil($this->totalItems / $this->itemsPerPage);
}

public function getTotalItems(): float
{
return $this->totalItems;
}

public function getItemsPerPage(): float
{
return $this->itemsPerPage;
}
}
147 changes: 147 additions & 0 deletions src/Command/InseeImportCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

namespace App\Command;

use App\Service\InseeService;
use DateTime;
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:insee:import',
description: 'Command to import data from INSEE CSV files.'
)]
class InseeImportCommand extends Command
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly InseeService $inseeService,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addOption(
'purge',
null,
InputOption::VALUE_NONE,
'Purge all related data tables before the import.'
)
->addOption(
'force',
null,
InputOption::VALUE_NONE,
'Must be set to allow the purge when using --purge.'
)
->addOption(
'target',
null,
InputOption::VALUE_REQUIRED,
'Which data to import? Choose "commune","commune1943","event","pays","pays1943" or "all".',
'all'
);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$purge = (bool) $input->getOption('purge');
$force = (bool) $input->getOption('force');
$target = strtolower($input->getOption('target'));

// If purge is requested but --force is not provided, abort
if ($purge && !$force) {
$io->error('You must provide --force to allow the purge when using --purge. Aborting.');

return Command::FAILURE;
}

// Show a brief recap of the chosen options
$io->section('Option Recap');
$io->writeln([
' - Purge: ' . ($purge ? 'Yes' : 'No'),
' - Force: ' . ($force ? 'Yes' : 'No'),
" - Target: $target",
]);

// Paths to CSV files
$communeFilePath = __DIR__ . '/../../data/insee/v_commune_2024.csv';
$commune1943FilePath = __DIR__ . '/../../data/insee/v_commune_depuis_1943.csv';
$communeEventFilePath = __DIR__ . '/../../data/insee/v_mvt_commune_2024.csv';
$paysFilePath = __DIR__ . '/../../data/insee/v_pays_territoire_2024.csv';
$pays1943FilePath = __DIR__ . '/../../data/insee/v_pays_et_territoire_depuis_1943.csv';
Comment on lines +75 to +79
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pour le coup, ces fichiers vont Γ©voluer, donc il faut aller les download directement sur le site de l'ANS, et pas les importer comme Γ§a


// Pass output + verbosity to the service
$this->inseeService->setOutput($output);
$verbose = $output->isVerbose();
$veryVerbose = $output->isVeryVerbose();
$this->inseeService->setVerbose($verbose || $veryVerbose);

// Start time
$startTime = new DateTime();
$io->writeln("<comment>{$startTime->format('d-m-Y G:i:s')} - Start processing</comment>");
$output->writeln("Import ID is {$this->inseeService->getImportId()}");

// Turn off Doctrine's default SQL logger to save memory
$this->em->getConnection()->getConfiguration()->setSQLLogger();

// If purge is requested, execute it before importing
if ($purge) {
$io->writeln('<info>Purging all existing data...</info>');
$this->inseeService->purgeAllData();
$io->success('Purge completed successfully.');
}

// Launch imports based on target
if ('all' === $target || 'commune' === $target) {
$io->section('Importing: COMMUNES');
$this->inseeService->importData($communeFilePath, 'commune');
$io->success('Commune import completed successfully.');
}

if ('all' === $target || 'commune1943' === $target) {
$io->section('Importing: COMMUNES 1943');
$this->inseeService->importData($commune1943FilePath, 'commune1943');
$io->success('Commune 1943 import completed successfully.');
}

if ('all' === $target || 'event' === $target) {
$io->section('Importing: COMMUNE EVENTS');
$this->inseeService->importData($communeEventFilePath, 'event');
$io->success('Commune events import completed successfully.');
}

if ('all' === $target || 'pays' === $target) {
$io->section('Importing: PAYS');
$this->inseeService->importData($paysFilePath, 'pays');
$io->success('Pays import completed successfully.');
}

if ('all' === $target || 'pays1943' === $target) {
$io->section('Importing: PAYS 1943');
$this->inseeService->importData($pays1943FilePath, 'pays1943');
$io->success('Pays 1943 import completed successfully.');
}

$this->inseeService->printFinalStats();

// End time + total execution time
$endTime = new DateTime();
$io->writeln("<comment>{$endTime->format('d-m-Y G:i:s')} - Stop processing</comment>");

// Calculate & display total duration
$durationSec = $endTime->getTimestamp() - $startTime->getTimestamp();
$io->writeln("<comment>Total execution time: {$durationSec}s</comment>");

$io->success('Job done master!');

return Command::SUCCESS;
}
}
33 changes: 33 additions & 0 deletions src/DTO/BirthPlaceDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\DTO;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use App\StateProvider\BirthPlacesProvider;
use Symfony\Component\Serializer\Annotation\Groups;

#[ApiResource(
shortName: 'BirthPlace',
operations: [
new GetCollection(
uriTemplate: '/birth_places',
normalizationContext: ['groups' => ['read']],
provider: BirthPlacesProvider::class
),
],
paginationClientEnabled: true,
paginationPartial: true,
)]
class BirthPlaceDTO
{
public function __construct(
#[Groups(['read'])]
public string $label,
#[Groups(['read'])]
public string $code,
#[Groups(['read'])]
public string $type,
) {
}
}
Loading