fix(back) : 422 de validation mappables + poids obligatoire sur le ticket de pesée (ERP-189)

- collectDenormalizationErrors sur Post/Patch : les erreurs de dénormalisation
  (date/type/IRI) reviennent en 422 avec propertyPath (et non 400 opaque), donc
  mappables inline côté front (miroir M1 Client).
- NotBlank sur emptyWeight : le poids à vide est obligatoire à la création, sa
  violation est renvoyée avec counterpartyType / immatriculation d'un seul coup.
This commit is contained in:
2026-06-23 14:03:32 +02:00
parent 4dcc247436
commit 68e7205793
@@ -95,6 +95,10 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
'default:read', 'default:read',
]], ]],
denormalizationContext: ['groups' => ['weighing_ticket:write']], denormalizationContext: ['groups' => ['weighing_ticket:write']],
// Erreurs de denormalisation (date non parsable, type/IRI invalide)
// remontees en 422 avec propertyPath (et non 400 opaque) -> mapping
// inline par champ cote front via useFormErrors (miroir M1 Client).
collectDenormalizationErrors: true,
processor: WeighingTicketProcessor::class, processor: WeighingTicketProcessor::class,
), ),
new Patch( new Patch(
@@ -108,6 +112,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
'default:read', 'default:read',
]], ]],
denormalizationContext: ['groups' => ['weighing_ticket:write']], denormalizationContext: ['groups' => ['weighing_ticket:write']],
collectDenormalizationErrors: true,
provider: WeighingTicketProvider::class, provider: WeighingTicketProvider::class,
processor: WeighingTicketProcessor::class, processor: WeighingTicketProcessor::class,
), ),
@@ -190,8 +195,15 @@ class WeighingTicket implements TimestampableInterface, BlamableInterface
#[Groups(['weighing_ticket:item:read', 'weighing_ticket:write'])] #[Groups(['weighing_ticket:item:read', 'weighing_ticket:write'])]
private ?DateTimeImmutable $emptyDate = null; private ?DateTimeImmutable $emptyDate = null;
/** Poids a vide (tare) en kg — readonly UI, rempli par la pesee (RG-5.07). */ /**
* Poids a vide (tare) en kg — readonly UI, rempli par la pesee (RG-5.07).
* Obligatoire : un ticket est cree APRES la pesee a vide (POST). NotBlank ici
* (et non sur empty_dsd, alloue serveur) rend la 422 « poids obligatoire »
* coherente avec les autres champs requis (counterpartyType / immatriculation),
* toutes renvoyees d'un coup -> mapping inline front (ERP-101).
*/
#[ORM\Column(name: 'empty_weight', nullable: true)] #[ORM\Column(name: 'empty_weight', nullable: true)]
#[Assert\NotBlank(message: 'Le poids est obligatoire : effectuez une pesée.')]
#[Groups(['weighing_ticket:item:read', 'weighing_ticket:write'])] #[Groups(['weighing_ticket:item:read', 'weighing_ticket:write'])]
private ?int $emptyWeight = null; private ?int $emptyWeight = null;