feat(transport) : sous-ressource prix transporteur (ERP-161)

POST /api/carriers/{id}/prices + PATCH/DELETE /api/carrier_prices/{id}
(security transport.carriers.manage) via CarrierPriceProcessor.

RG-4.09->4.11 : coherence de branche CLIENT/FOURNISSEUR (champs requis +
appartenance de l'adresse de livraison au client / de l'adresse d'appro au
fournisseur, sinon 422), nettoyage de la branche opposee (CHECK BDD). Champs
communs obligatoires via Assert\NotBlank + Assert\Choice.

Les contrats Shared ClientAddressInterface / SupplierAddressInterface exposent
desormais getClient() / getSupplier() (canal cross-module, regle n°1) pour la
verification d'appartenance. Colonnes enum du prix whitelistees dans le miroir
Assert\Length (deja bornees par Choice).
This commit is contained in:
Matthieu
2026-06-16 10:42:41 +02:00
parent daa8224b8b
commit 7d2812cea6
6 changed files with 570 additions and 17 deletions
@@ -64,6 +64,11 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
'Carrier::certificationType' => 'Choice des 5 certifications borne deja les valeurs.',
// Le Choice {BENNE,FOND_MOUVANT} borne les valeurs (<= 12).
'Carrier::containerType' => 'Choice {BENNE,FOND_MOUVANT} borne deja les valeurs.',
// Colonnes enum du prix transporteur (M4) : le Choice borne deja les valeurs.
'CarrierPrice::direction' => 'Choice {CLIENT,FOURNISSEUR} borne deja les valeurs.',
'CarrierPrice::containerType' => 'Choice {BENNE,FOND_MOUVANT} borne deja les valeurs.',
'CarrierPrice::pricingUnit' => 'Choice {FORFAIT,TONNE} borne deja les valeurs.',
'CarrierPrice::priceState' => 'Choice {EN_COURS,VALIDE,NON_VALIDE} borne deja les valeurs.',
// Le Regex /^#[0-9A-Fa-f]{6}$/ borne la longueur a exactement 7 caracteres.
'Site::color' => 'Regex code hex #RRGGBB borne deja la longueur.',
];
@@ -109,7 +114,7 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
}
/** @var Constraint $constraint */
$constraint = $attribute->newInstance();
$constraint = $attribute->newInstance();
$messageProps = $this->messagePropertiesFor($constraint);
self::assertNotNull(
@@ -180,6 +185,7 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
foreach ($constraints as $c) {
if ($c instanceof Assert\Length) {
$length = $c->max;
break;
}
}
@@ -251,7 +257,7 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
* Liste des proprietes de message a verifier pour une contrainte donnee, ou
* null si la contrainte n'est pas geree (le test echoue alors explicitement).
*
* @return list<string>|null
* @return null|list<string>
*/
private function messagePropertiesFor(Constraint $constraint): ?array
{
@@ -325,7 +331,7 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
}
/**
* @param list<Constraint> $constraints
* @param list<Constraint> $constraints
* @param list<class-string<Constraint>> $classes
*/
private function hasAnyConstraint(array $constraints, array $classes): bool