Aller au contenu principal

Cycle de Vie des Documents de Facturation

Ce document définit les états et transitions autorisées pour les factures, devis, et avoirs.

Vue d'ensemble

Une facture émise doit être immutable (pas de modification destructive). Les corrections se font via des avoirs ou une annulation + réémission.

États des Factures

États Principaux

ÉtatDescriptionModifiableÉmis
DRAFTBrouillon en cours de création✅ Oui❌ Non
ISSUEDFacture émise (immutable)❌ Non✅ Oui
SENTFacture envoyée au client❌ Non✅ Oui
PARTIALLY_PAIDPaiement partiel reçu❌ Non✅ Oui
PAIDFacture entièrement payée❌ Non✅ Oui
OVERDUEFacture en retard de paiement❌ Non✅ Oui
CANCELLEDFacture annulée❌ Non❌ Non
CREDIT_NOTE_ISSUEDAvoir émis (total ou partiel)❌ Non✅ Oui

Règles par État

DRAFT (Brouillon)

  • Modifiable : Tous les champs peuvent être modifiés librement
  • Supprimable : Oui
  • Émission : Non encore émise
  • Numérotation : Aucun numéro
  • PDF : Pas de PDF définitif

ISSUED (Émise)

  • Modifiable : ❌ AUCUNE modification possible (immutable)
  • Supprimable : Non (seulement annulation possible)
  • Émission : ✅ Émise, numérotée, PDF hashé
  • Numérotation : Numéro séquentiel unique attribué
  • PDF : PDF généré et hashé (SHA-256)
  • Snapshots : Toutes les données figées (montants, taxes, client, vendeur)

Actions déclenchées lors du passage DRAFT → ISSUED :

  1. Validation compliance (mentions obligatoires)
  2. Attribution numéro séquentiel unique
  3. Calcul et figement des totaux (HT, TVA, TTC)
  4. Création snapshots (vendeur, client, conditions de paiement)
  5. Génération PDF définitif
  6. Calcul hash PDF (SHA-256)
  7. Enregistrement issued_at et issued_by
  8. Création événement audit INVOICE_ISSUED

SENT (Envoyée)

  • Modifiable : Non (hérite d'ISSUED)
  • État intermédiaire : Optionnel, indique que la facture a été envoyée au client
  • Transition : ISSUED → SENT (via envoi email ou action manuelle)

PARTIALLY_PAID (Paiement Partiel)

  • Modifiable : Non
  • Calcul automatique : Si balance_due > 0 et balance_due < total_ttc
  • Transition : ISSUED/SENT → PARTIALLY_PAID (automatique lors enregistrement paiement partiel)
  • Modifiable : Non
  • Calcul automatique : Si balance_due <= tolerance (tolérance configurable pour frais)
  • Transition : ISSUED/SENT/PARTIALLY_PAID → PAID (automatique lors paiement complet)

OVERDUE (En Retard)

  • Modifiable : Non
  • Calcul automatique : Si due_date < today et status != PAID et status != CANCELLED
  • Transition : ISSUED/SENT/PARTIALLY_PAID → OVERDUE (automatique via job périodique)

CANCELLED (Annulée)

  • Modifiable : Non
  • Raison : Doit avoir une raison d'annulation
  • Transition : DRAFT/ISSUED/SENT → CANCELLED (action manuelle)
  • Note : Une facture annulée peut être réémise (nouvelle facture avec nouveau numéro)

CREDIT_NOTE_ISSUED (Avoir Émis)

  • Modifiable : Non
  • Transition : ISSUED/SENT/PARTIALLY_PAID/PAID → CREDIT_NOTE_ISSUED (après création avoir total)
  • Note : Avoir partiel ne change pas le statut (reste ISSUED/PARTIALLY_PAID)

Diagramme de Transitions

stateDiagram-v2
[*] --> DRAFT: Création

DRAFT --> DRAFT: Modification
DRAFT --> ISSUED: Émission<br/>(compliance OK)
DRAFT --> CANCELLED: Annulation

ISSUED --> SENT: Envoi email/client
ISSUED --> PARTIALLY_PAID: Paiement partiel
ISSUED --> PAID: Paiement complet
ISSUED --> OVERDUE: Échéance dépassée<br/>(auto)
ISSUED --> CREDIT_NOTE_ISSUED: Avoir total
ISSUED --> CANCELLED: Annulation

SENT --> PARTIALLY_PAID: Paiement partiel
SENT --> PAID: Paiement complet
SENT --> OVERDUE: Échéance dépassée<br/>(auto)
SENT --> CREDIT_NOTE_ISSUED: Avoir total

PARTIALLY_PAID --> PAID: Paiement complémentaire
PARTIALLY_PAID --> OVERDUE: Échéance dépassée<br/>(auto)
PARTIALLY_PAID --> CREDIT_NOTE_ISSUED: Avoir total/partiel

PAID --> CREDIT_NOTE_ISSUED: Avoir/remboursement

OVERDUE --> PARTIALLY_PAID: Paiement partiel
OVERDUE --> PAID: Paiement complet

CREDIT_NOTE_ISSUED --> [*]
CANCELLED --> [*]

note right of ISSUED
Immutable
Numérotée
PDF hashé
end note

note right of CANCELLED
Peut être réémise
avec nouveau numéro
end note

Table des Transitions Autorisées

État SourceÉtat CibleConditionAutomatiqueAction Déclenchée
DRAFTDRAFTModification manuelle-
DRAFTISSUEDCompliance OK + émissionNumérotation, snapshots, PDF, hash, audit
DRAFTCANCELLEDAnnulation manuelleAudit
ISSUEDSENTEnvoi email/clientAudit INVOICE_SENT
ISSUEDPARTIALLY_PAIDbalance_due > 0 et < total_ttcRecalcul balance_due
ISSUEDPAIDbalance_due <= toleranceMise à jour statut
ISSUEDOVERDUEdue_date < today et non payéeJob périodique
ISSUEDCREDIT_NOTE_ISSUEDAvoir total crééAudit CREDIT_NOTE_ISSUED
ISSUEDCANCELLEDAnnulation manuelleAudit INVOICE_CANCELLED
SENTPARTIALLY_PAIDPaiement partiel-
SENTPAIDPaiement complet-
SENTOVERDUEÉchéance dépasséeJob périodique
SENTCREDIT_NOTE_ISSUEDAvoir totalAudit
PARTIALLY_PAIDPAIDPaiement complémentaire-
PARTIALLY_PAIDOVERDUEÉchéance dépasséeJob périodique
PARTIALLY_PAIDCREDIT_NOTE_ISSUEDAvoirAudit
PAIDCREDIT_NOTE_ISSUEDRemboursement/avoirAudit
OVERDUEPARTIALLY_PAIDPaiement partiel-
OVERDUEPAIDPaiement complet-

Transitions Interdites

Les transitions suivantes sont strictement interdites :

  • ISSUEDDRAFT (une fois émise, impossible de revenir en brouillon)
  • PAIDISSUED (une facture payée ne peut pas revenir à émise)
  • CREDIT_NOTE_ISSUEDISSUED (une fois avoir émis, pas de retour en arrière)
  • CANCELLEDISSUED (annulation définitive, réémission = nouvelle facture)

Immutabilité

Règles d'Immutabilité

Une facture ISSUED (ou supérieur) est immutable :

  • ❌ Pas de modification des montants
  • ❌ Pas de modification des items
  • ❌ Pas de modification des taxes
  • ❌ Pas de modification des snapshots (vendeur, client)
  • ❌ Pas de modification du numéro
  • ❌ Pas de régénération PDF (sauf endpoint admin explicitement auditée)

Corrections

Les corrections se font via :

  1. Avoir (credit note) : Pour corriger une facture émise

    • Avoir partiel : ajuste le montant restant dû
    • Avoir total : annule complètement la facture
  2. Annulation + Réémission : Pour une facture avec erreurs majeures

    • Annuler la facture (CANCELLED)
    • Créer une nouvelle facture (DRAFTISSUED) avec nouveau numéro

Validation des Transitions

Validateur de Cycle de Vie

Un validateur doit être créé pour vérifier les transitions :

class BillingLifecycleValidator {
canTransition(from: InvoiceStatus, to: InvoiceStatus): boolean {
// Implémentation de la table des transitions autorisées
}

requiresCompliance(status: InvoiceStatus): boolean {
return status === 'ISSUED';
}

isImmutable(status: InvoiceStatus): boolean {
return ['ISSUED', 'SENT', 'PARTIALLY_PAID', 'PAID', 'OVERDUE', 'CREDIT_NOTE_ISSUED'].includes(status);
}
}

Guards API

  • Vérifier que la transition est autorisée avant mise à jour
  • Bloquer toute modification si isImmutable(status) === true
  • Retourner erreur 400/403 si tentative de modification sur facture immutable

États des Avoirs (Credit Notes)

Les avoirs suivent un cycle de vie similaire mais simplifié :

ÉtatDescription
DRAFTBrouillon
ISSUEDAvoir émis (immutable)

Transitions avoirs :

  • DRAFTISSUED : Émission (avec numérotation, PDF, hash)
  • ISSUED : État final (immutable)

Notes d'Implémentation

  • Les transitions automatiques (PARTIALLY_PAID, PAID, OVERDUE) sont gérées par des jobs/services
  • Le calcul de balance_due détermine les transitions automatiques de paiement
  • Un job périodique vérifie les factures OVERDUE
  • Les transitions manuelles nécessitent des permissions appropriées