136 lines
4.9 KiB
PHP
136 lines
4.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Module\Commercial\Infrastructure\DataFixtures;
|
|
|
|
use App\Module\Commercial\Domain\Entity\Bank;
|
|
use App\Module\Commercial\Domain\Entity\Country;
|
|
use App\Module\Commercial\Domain\Entity\PaymentDelay;
|
|
use App\Module\Commercial\Domain\Entity\PaymentType;
|
|
use App\Module\Commercial\Domain\Entity\TvaMode;
|
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
|
use Doctrine\Persistence\ObjectManager;
|
|
|
|
/**
|
|
* Fixtures du module Commercial : re-seed des 4 referentiels comptables
|
|
* (tva_mode, payment_delay, payment_type, bank) seedes par la migration M1
|
|
* (Version20260601000000) + du referentiel pays (country) seede par la
|
|
* migration ERP-116 (Version20260609100000).
|
|
*
|
|
* Pourquoi cette fixture EN PLUS du seed de la migration : ces tables sont des
|
|
* entites managees par l'ORM, donc le purger Doctrine les
|
|
* vide avant chaque `doctrine:fixtures:load`. Sans cette fixture, les
|
|
* referentiels seedes par la migration disparaitraient apres `make db-reset`
|
|
* (0 ligne en dev/test) — cassant les FK Client -> referentiels et les tests
|
|
* RG-1.12/1.13. Le seed migration couvre la prod (ou les fixtures ne tournent
|
|
* pas) ; cette fixture re-aligne dev et test. Memes valeurs des deux cotes.
|
|
*
|
|
* Idempotence : lookup par `code` avant insertion (sur le modele de
|
|
* CategoryTypeFixtures). Rejouable sans doublon meme si le purger est desactive.
|
|
*/
|
|
class CommercialReferentialFixtures extends Fixture
|
|
{
|
|
/**
|
|
* Source unique des referentiels : classe d'entite => [code => [label, position]].
|
|
* Doit rester aligne sur le seed de la migration Version20260601000000.
|
|
*
|
|
* @var array<class-string, array<string, array{string, int}>>
|
|
*/
|
|
private const REFERENTIALS = [
|
|
TvaMode::class => [
|
|
'FRANCE_VENTES' => ['France (ventes)', 10],
|
|
'EXPORT_VENTES' => ['Export (ventes)', 20],
|
|
'INTRACOM_VENTES' => ['Intracom (ventes)', 30],
|
|
],
|
|
PaymentDelay::class => [
|
|
'J15' => ['15 jours', 10],
|
|
'J30' => ['30 jours', 20],
|
|
'A_RECEPTION' => ['À réception', 30],
|
|
],
|
|
PaymentType::class => [
|
|
'VIREMENT' => ['Virement', 10],
|
|
'LCR' => ['LCR', 20],
|
|
'NON_SOUMISE' => ['Non soumise', 30],
|
|
'CHEQUE' => ['Chèque', 40],
|
|
],
|
|
Bank::class => [
|
|
'SG' => ['Société Générale', 10],
|
|
'CIC' => ['CIC', 20],
|
|
'CA' => ['Crédit Agricole', 30],
|
|
],
|
|
];
|
|
|
|
/**
|
|
* Referentiel pays (ERP-116) : code ISO alpha-2 => [name, position].
|
|
* Doit rester aligne sur le seed de la migration Version20260609100000.
|
|
* Traite a part car Country porte `name` (et non `label`).
|
|
*
|
|
* @var array<string, array{string, int}>
|
|
*/
|
|
private const COUNTRIES = [
|
|
'FR' => ['France', 10],
|
|
'DE' => ['Allemagne', 20],
|
|
'BE' => ['Belgique', 30],
|
|
'ES' => ['Espagne', 40],
|
|
'IT' => ['Italie', 50],
|
|
'GB' => ['Royaume-Uni', 60],
|
|
'CH' => ['Suisse', 70],
|
|
];
|
|
|
|
public function load(ObjectManager $manager): void
|
|
{
|
|
foreach (self::REFERENTIALS as $entityClass => $rows) {
|
|
$this->seedReferential($manager, $entityClass, $rows);
|
|
}
|
|
|
|
$this->seedCountries($manager);
|
|
|
|
$manager->flush();
|
|
}
|
|
|
|
/**
|
|
* Upsert idempotent du referentiel pays (lookup par code). Distinct de
|
|
* seedReferential car Country utilise setName au lieu de setLabel.
|
|
*/
|
|
private function seedCountries(ObjectManager $manager): void
|
|
{
|
|
$existingByCode = [];
|
|
foreach ($manager->getRepository(Country::class)->findAll() as $country) {
|
|
$existingByCode[$country->getCode()] = $country;
|
|
}
|
|
|
|
foreach (self::COUNTRIES as $code => [$name, $position]) {
|
|
$country = $existingByCode[$code] ?? new Country();
|
|
$country->setCode($code);
|
|
$country->setName($name);
|
|
$country->setPosition($position);
|
|
$manager->persist($country);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Upsert idempotent d'un referentiel : indexe l'existant par code puis
|
|
* cree/met a jour chaque entree. Les 4 entites partagent le meme contrat
|
|
* setCode/setLabel/setPosition.
|
|
*
|
|
* @param class-string $entityClass
|
|
* @param array<string, array{string, int}> $rows
|
|
*/
|
|
private function seedReferential(ObjectManager $manager, string $entityClass, array $rows): void
|
|
{
|
|
$existingByCode = [];
|
|
foreach ($manager->getRepository($entityClass)->findAll() as $entity) {
|
|
$existingByCode[$entity->getCode()] = $entity;
|
|
}
|
|
|
|
foreach ($rows as $code => [$label, $position]) {
|
|
$entity = $existingByCode[$code] ?? new $entityClass();
|
|
$entity->setCode($code);
|
|
$entity->setLabel($label);
|
|
$entity->setPosition($position);
|
|
$manager->persist($entity);
|
|
}
|
|
}
|
|
}
|