fix : brouillon à contrepartie incomplète enregistrable sans erreur 500 (ERP-193)

Un brouillon dont le type de contrepartie est choisi sans son champ associé
(client/fournisseur null, ou libellé « Autre » vide) violait chk_wt_*_branch
et levait une 500 : le callback de cohérence RG-5.03 ne joue qu'au groupe
finalize, laissant passer l'incohérence à l'enregistrement du brouillon.

- back : WeighingTicketProcessor retire la contrepartie entière quand le champ
  de branche est absent (clearCounterparty) au lieu de persister un état
  incohérent. N'affecte que le brouillon (à la validation, le callback finalize
  lève déjà une 422 avant le processor).
- front : buildDraftPayload n'émet le type que si son champ associé est rempli ;
  la validation continue d'envoyer toujours le type pour la 422 métier.
- tests : 2 cas back (CLIENT sans client, AUTRE libellé vide) + 2 cas front.
This commit is contained in:
2026-06-24 16:12:40 +02:00
parent 9e2206a7d6
commit 391f383c4b
4 changed files with 134 additions and 8 deletions
@@ -82,6 +82,30 @@ describe('useWeighingTicketForm', () => {
expect(form.buildDraftPayload().otherLabel).toBe('Reprise interne')
})
it('buildDraftPayload : type choisi mais champ associé vide → contrepartie omise (pas de 500 chk_wt_*_branch)', () => {
const form = useWeighingTicketForm()
// L'opérateur ouvre le menu « Client » mais n'a pas encore choisi le client.
form.setCounterpartyType('CLIENT')
const draft = form.buildDraftPayload()
// On n'émet ni le type ni la FK : un brouillon incohérent serait rejeté en 500 par le back.
expect(draft).not.toHaveProperty('counterpartyType')
expect(draft).not.toHaveProperty('client')
// En revanche la validation envoie toujours le type, pour déclencher la 422 métier.
expect(form.buildValidatePayload().counterpartyType).toBe('CLIENT')
})
it('buildDraftPayload : AUTRE avec libellé vide → contrepartie omise', () => {
const form = useWeighingTicketForm()
form.setCounterpartyType('AUTRE')
form.otherLabel.value = ' '
const draft = form.buildDraftPayload()
expect(draft).not.toHaveProperty('counterpartyType')
expect(draft).not.toHaveProperty('otherLabel')
})
// ── Immatriculation / « Tout format » partagés entre blocs (RG-5.01) ──────
it('immatriculation et plateFreeFormat sont partagés (une seule valeur)', () => {
const form = useWeighingTicketForm()