Aller au contenu

Lot 2, séquence L2-6 — Dévalidation, annulation, registre

04/10/2026. Mise en œuvre de la séquence L2-6 du plan d’exécution du Lot 2. Règles : RG-032, RG-143, RG-144 ; reprend EC-116 (7). Écart : EC-123.

  • Deux mécanismes distincts (EC-008). La dévalidation ramène un objet à l’état précédent ; l’annulation clôt un lot ou une vente. Les deux passent par une contre-passation du mouvement d’origine : rien ne s’efface (I2).
  • Retour à l’état précédent, pas de lot « brouillon » (EC-123) : I1 et I4 restent intacts.
Objet Dévalider Annuler
Réception validée lot annulé (numéro conservé), réception en attente sur un nouveau lot ; la revalidation numérote de nouveau —
Étape validée mouvement contre-passé, lots de sortie annulés, lots d’entrée consommés rendus, étape en cours, ordre terminé en cours —
Expédition validée mouvement contre-passé, lots rendus, expédition en brouillon, vente soldée validée —
Vente — validée ou brouillon → annulée, sans expédition validée
Lot validé — contre-passation de la création, lot annulé, numéro conservé ; réception d’origine rejetée
  • L’aval d’abord. Un objet dont une opération aval s’appuie dessus ne se défait pas : le refus aval_non_contrepasse liste les objets bloquants (details.bloquants) ; on remonte la chaîne. Un lot en quarantaine se refuse à part (lot_en_quarantaine) : la levée précède la contre-passation, aucune levée automatique (I5, EC-116 (7)).
  • Qui. Permission stock.reverse, donnée à la direction seule (cahier, RG-032). Motif obligatoire.
  • Trace. Une ligne du registre par opération ; un constat (RG-032, origine processus, déjà justifié par le motif) par dévalidation (AM-15).

Migration lot2_l6_annulations : table registre_annulation (ajout seul) ; colonne sortie_etape.mouvement_id (une étape refaite garde ses anciennes sorties, qui ne comptent plus quand leur mouvement est contre-passé) ; vue bilan_etape et fonction verifier_bilan_etape limitées aux mouvements non contre-passés. Transitions nouvelles, verrouillées par déclencheur : lot consommé → validé (seulement si une contre-passation lui a rendu de la matière), lot validé → annulé (seulement si sa création est contre-passée), réception validée → en attente | rejetée (le lot d’origine doit être annulé par contre-passation), étape validée → en cours (tous ses mouvements contre-passés), ordre terminé → en cours, expédition validée → brouillon (mouvement contre-passé), vente soldée → validée (l’expédié repasse sous l’engagement). Test : sh db/tests/lancer.sh l2-6.

Module annulations : peutDevalider, peutAnnuler, lotsBloquants, transitionsAnnulation. Fonctions pures : les faits (statut, motif, lots touchés, aval) sont passés en paramètre. Vecteurs VT-ANN-001 à 008 et 101 à 109.

Module apps/api/src/annulations/. Six routes (contrat 1.25.0) : POST /v1/receptions/{id}/devalider, /v1/etapes/{id}/devalider, /v1/expeditions/{id}/devalider, /v1/ventes/{id}/annuler, /v1/lots/{id}/annuler, GET /v1/registre-annulations. Une transaction par opération, objets verrouillés FOR UPDATE, fonction commune contrepasser qui inverse les lignes. Le helper ecrireConstatProcessus (apps/api/src/regles/constat-processus.ts) remplace les deux copies des services de réception et de vente.

  • Accroche *.avant_devalidation : non créée (gel des spécifications), EC-123.
  • Annulation d’une expédition en brouillon : non exposée (une expédition validée se dévalide, un brouillon reste modifiable).
  • Aucun écran ; l’édition imprimable du registre (RG-144) attend le module documents.