feat(commercial) : catégories de type Adresse pour les blocs adresse (client + fournisseur)
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 51s
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m24s

Introduit un CategoryType dédié ADRESSE (module Catalog) consommé par le champ
« Catégorie » des blocs adresse, en remplacement de la réutilisation détournée des
types CLIENT/FOURNISSEUR.

- Migration de seed du type ADRESSE + 6 catégories (Siège, Contact issues,
  Facturation, Livraison, Approvisionnement, Méthaniseur) ; fixtures alignées.
- ClientAddress : validation blacklist (DISTRIBUTEUR/COURTIER) remplacée par une
  whitelist « catégories de type ADRESSE uniquement ».
- SupplierAddress : type requis FOURNISSEUR -> ADRESSE (le bloc principal
  fournisseur reste en FOURNISSEUR).
- Front : ref dédiée addressCategories (typeCode=ADRESSE) dans les composables
  référentiels client et fournisseur ; pages new/edit câblées sur les blocs adresse.
- Tests : CategoryAdresseSeedTest + adaptation des tests d'adresse client/fournisseur.
This commit is contained in:
2026-06-25 09:22:24 +02:00
parent 2e50a760c6
commit 55c136df66
22 changed files with 444 additions and 168 deletions
@@ -55,8 +55,7 @@ use Symfony\Component\DependencyInjection\Attribute\Autowire;
* Audit / Blamable : persist hors contexte HTTP -> created_by / updated_by
* restent null (« Systeme » cote front), c'est attendu. Les donnees respectent
* les CHECK BDD ET les validators applicatifs (exclusivite Prospect, billingEmail
* ssi facturation, aucune categorie de code DISTRIBUTEUR/COURTIER sur une adresse
* — RG-1.29, ERP-78).
* ssi facturation, categories de type ADRESSE sur les adresses).
*
* Depend de CategoryFixtures (categories), SitesFixtures (sites) et
* CommercialReferentialFixtures (referentiels comptables Bank / PaymentType).
@@ -116,7 +115,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
);
if ($gsoIsNew) {
$this->addContact($gso, 'Paul', 'Garnier', 'Directeur commercial', '05 56 10 20 30', null, 'paul.garnier@distrib-gso.fr');
$this->addAddress($gso, ['Pommevic'], '82400', 'Pommevic', '1 Av. Jean Duquesne', isDelivery: true, categoryNames: ['Transport/Logistique']);
$this->addAddress($gso, ['Pommevic'], '82400', 'Pommevic', '1 Av. Jean Duquesne', isDelivery: true, categoryNames: ['Livraison']);
}
// Courtier reference par d'autres clients.
@@ -140,7 +139,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
$dubois->setPaymentType($this->paymentType($manager, 'VIREMENT'));
$dubois->setBank($this->bank($manager, 'SG'));
$this->addContact($dubois, 'Jean', 'Dubois', 'Gérant', '05 49 00 00 01', null, 'jean.dubois@menuiserie-dubois.fr');
$this->addAddress($dubois, ['Chatellerault'], '86100', 'Châtellerault', '12 rue de l\'Atelier', isDelivery: true, categoryNames: ['BTP']);
$this->addAddress($dubois, ['Chatellerault'], '86100', 'Châtellerault', '12 rue de l\'Atelier', isDelivery: true, categoryNames: ['Livraison']);
}
// === Dependant d'un distributeur (RG-1.03) ===
@@ -176,7 +175,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
if ($isNew) {
$transports->setPaymentType($this->paymentType($manager, 'LCR'));
$this->addContact($transports, null, 'Bernard', 'Responsable exploitation', '05 56 12 13 14', null, 'expl@transports-rapides.fr');
$this->addAddress($transports, ['Saint-Jean'], '17400', 'Fontenet', '2 zone industrielle', isDelivery: true, categoryNames: ['Transport/Logistique']);
$this->addAddress($transports, ['Saint-Jean'], '17400', 'Fontenet', '2 zone industrielle', isDelivery: true, categoryNames: ['Approvisionnement']);
$this->addRib($transports, 'Compte principal', 'BNPAFRPPXXX', 'FR1420041010050500013M02606', 0);
$this->addRib($transports, 'Compte secondaire', 'SOGEFRPPXXX', 'FR7630006000011234567890189', 1);
}
@@ -192,9 +191,9 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
// Prospect : exclusif de livraison/facturation (sans billingEmail).
$this->addAddress($industries, ['Chatellerault'], '86100', 'Châtellerault', '1 avenue de la Prospection', isProspect: true, position: 0);
// Livraison.
$this->addAddress($industries, ['Saint-Jean'], '17400', 'Fontenet', '4 rue de la Livraison', isDelivery: true, categoryNames: ['Industrie'], position: 1);
$this->addAddress($industries, ['Saint-Jean'], '17400', 'Fontenet', '4 rue de la Livraison', isDelivery: true, categoryNames: ['Livraison'], position: 1);
// Facturation : billingEmail obligatoire.
$this->addAddress($industries, ['Chatellerault'], '86100', 'Châtellerault', '7 boulevard des Factures', isBilling: true, billingEmail: 'Compta@Industries-Vertes.FR', position: 2);
$this->addAddress($industries, ['Chatellerault'], '86100', 'Châtellerault', '7 boulevard des Factures', isBilling: true, billingEmail: 'Compta@Industries-Vertes.FR', categoryNames: ['Facturation'], position: 2);
}
// === 3 contacts dont un avec telephone secondaire (RG-1.05/1.02) ===
@@ -249,7 +248,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
$holding->setDirectorName('Antoine Lefèvre');
$holding->setProfitAmount('1250000.00');
$this->addContact($holding, 'Antoine', 'Lefèvre', 'PDG', '05 56 51 52 53', null, 'antoine.lefevre@holding-premium.fr');
$this->addAddress($holding, ['Pommevic'], '82400', 'Pommevic', '1 allée des Investisseurs', isDelivery: true, categoryNames: ['Industrie']);
$this->addAddress($holding, ['Pommevic'], '82400', 'Pommevic', '1 allée des Investisseurs', isDelivery: true, categoryNames: ['Siège']);
}
// === Multi-categories M2M ===
@@ -260,7 +259,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
);
if ($isNew) {
$this->addContact($conglo, 'Hélène', 'Faure', 'Directrice générale', '05 49 61 62 63', null, 'helene.faure@conglomerat-multi.fr');
$this->addAddress($conglo, ['Chatellerault', 'Saint-Jean'], '86100', 'Châtellerault', '20 rue des Activités', isDelivery: true, categoryNames: ['BTP', 'Services']);
$this->addAddress($conglo, ['Chatellerault', 'Saint-Jean'], '86100', 'Châtellerault', '20 rue des Activités', isDelivery: true, categoryNames: ['Livraison', 'Approvisionnement']);
}
// === Prospect seul ===
@@ -282,7 +281,7 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
);
if ($isNew) {
$this->addContact($association, null, 'Caron', 'Président', '05 49 81 82 83', null, 'president@asso-riverains.fr');
$this->addAddress($association, ['Saint-Jean'], '17400', 'Fontenet', '6 chemin du Village', isDelivery: true, categoryNames: ['Association']);
$this->addAddress($association, ['Saint-Jean'], '17400', 'Fontenet', '6 chemin du Village', isDelivery: true, categoryNames: ['Contact issues']);
}
$manager->flush();
@@ -359,10 +358,10 @@ class ClientFixtures extends Fixture implements DependentFixtureInterface
/**
* Ajoute une adresse au client (cascade persist via Client.addresses). Les
* donnees respectent les validators : exclusivite Prospect, billingEmail ssi
* facturation, aucune categorie de code DISTRIBUTEUR/COURTIER (RG-1.29).
* facturation, categories de type ADRESSE uniquement.
*
* @param list<string> $siteNames au moins un site (RG-1.10)
* @param list<string> $categoryNames categories hors DISTRIBUTEUR/COURTIER (RG-1.29)
* @param list<string> $categoryNames categories de type ADRESSE (Siege, Livraison...)
*/
private function addAddress(
Client $client,