b495e4030a
Auto Tag Develop / tag (push) Failing after 28s
## Contexte Ticket Lesstime **#54** (1.1 / Backend / M) — spec `docs/specs/M1-clients/spec-back.md` § 3.4 / § 3.5. > 🔗 **MR stackée sur ERP-53** — cible `feature/ERP-53-migrer-tables-client-m1`, **pas** `develop`. À repointer vers `develop` quand ERP-53 sera mergé (cf. `STACK-BRANCHES-PROCEDURE.md`). Le diff ne montre que les fichiers d'ERP-54. ## Contenu **9 entités** (`src/Module/Commercial/Domain/Entity/`) : - Métier : `Client`, `ClientContact`, `ClientAddress`, `ClientRib` — `#[Auditable]` + Timestampable/Blamable. - Référentiels statiques lecture seule : `TvaMode`, `PaymentDelay`, `PaymentType`, `Bank` — whitelistés dans `EntitiesAreTimestampableBlamableTest::EXCLUDED`. **8 repositories** interfaces (`Domain/Repository/`) + impl Doctrine (`Infrastructure/Doctrine/`). > La spec § 3.5 ne définit que 8 entités (4 métier + 4 référentiels) ; pas de 9ᵉ entité malgré la formulation « 9 paires » du ticket. ## Décisions - **Aucun `#[ApiResource]` dans ce ticket** : le bloc ApiResource du `Client` (§ 3.4) référence `ClientProvider`/`ClientProcessor` = périmètre **ERP-55**. L'inclure casserait `cache:clear`/`make test`/`schema:validate`. Les entités sont des entités Doctrine pures (ORM + Assert + Groups). Endpoints lecture seule des référentiels → ticket dédié. - **Q4** : `Client` sans `#[ORM\UniqueConstraint]` — unicité du nom de société portée par l'index partiel Postgres `uq_client_company_name_active` (inexprimable en attribut ORM). - **Audit RIB (29/05)** : aucun `#[AuditIgnore]` sur `ClientRib.iban`/`bic` (tous champs audités, audit admin-only). - **Cross-module (règle n°1)** : M2M `Category` via le contrat `Shared\Domain\Contract\CategoryInterface` + `resolve_target_entities` (pas d'import direct Catalog→Commercial) ; `ClientAddress.sites` via `SiteInterface` existant. ## Infra nécessaire (découvert pendant le dev) - `doctrine.yaml` : mapping ORM du module `Commercial` (mappings explicites par module) + résolution `CategoryInterface → Category`. - `CommercialReferentialFixtures` **créée** (n'existait pas — ERP-53 avait seedé les CategoryType côté Catalog) : re-seed idempotent des 4 référentiels, sinon vidés au `db-reset` (désormais tables mappées). - `ColumnCommentsCatalog` étendu (colonnes M1) pour le chemin `schema:update`/test — sinon `ColumnsHaveSqlCommentTest` (garde-fou n°12) échoue. - Migration retrofit `Version20260528120000` (ERP-67) rendue résiliente (`$schema->hasTable()`) : elle rejouait tout le catalogue mais s'exécute avant la création des tables M1 → `relation tva_mode does not exist`. Conforme à son docblock (« les futures migrations posent leurs propres COMMENT »). - `makefile test-db-setup` : recréation de l'index partiel `uq_client_company_name_active` (analogue de la ligne existante pour `category`). ## Vérifications - `make php-cs-fixer-allow-risky` ✓ - `make db-reset` ✓ (bout en bout ; 4 référentiels + 4 CategoryType présents, 2 index partiels créés) - `make test` ✓ **312/312** (Architecture vert, 0 régression M0) - `doctrine:schema:validate` : Mapping **OK** ; « not in sync » = bruit cosmétique pré-existant du projet (clear COMMENT hors-ORM, drop index partiels, renommages d'index). Seul diff introduit : renommage cosmétique de l'index M2M `idx_client_category_category` (même colonne) — aucun écart de type/colonne/FK vs migration ERP-53. --------- Co-authored-by: admin malio <malio@yuno.malio.fr> Co-authored-by: Matthieu <contact@malio.fr> Co-authored-by: Matthieu <mtholot19@gmail.com> Reviewed-on: #29 Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr> Co-committed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
95 lines
3.5 KiB
PHP
95 lines
3.5 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\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).
|
|
*
|
|
* Pourquoi cette fixture EN PLUS du seed de la migration : depuis ERP-54 ces
|
|
* 4 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],
|
|
],
|
|
];
|
|
|
|
public function load(ObjectManager $manager): void
|
|
{
|
|
foreach (self::REFERENTIALS as $entityClass => $rows) {
|
|
$this->seedReferential($manager, $entityClass, $rows);
|
|
}
|
|
|
|
$manager->flush();
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
}
|
|
}
|