Apparence
Invoice
Facture. Identique à Quote à quelques champs près : pas de validity_date, ajout de due_date, paid_date, payment_method, et lien optionnel vers le devis source via quote_id.
- Path Firestore :
users/{userId}/invoices/{invoiceId} - Source TS :
klapy-crm/src/types/index.ts - Limite plan Starter : 10 factures par mois civil (enforced en Cloud Function)
Interface
ts
interface Invoice {
id: string;
number: string;
contact_id?: string;
quote_id?: string;
lines: DocumentLine[];
subtotal: number;
tva_rate: number;
tva_amount: number;
discount?: number;
discount_type?: 'percentage' | 'fixed';
total_ttc: number;
status: InvoiceStatus;
due_date?: Timestamp;
paid_date?: Timestamp;
payment_method?: string;
payment_conditions?: string;
notes?: string;
created_at: Timestamp;
updated_at: Timestamp;
}Champs
| Champ | Notes |
|---|---|
number | 🔒 Immuable. Format : <invoice_prefix><année>-<seq>. Séquence ininterrompue exigée par la loi française |
contact_id | Référence optionnelle vers un Contact |
quote_id | Lien optionnel vers le devis source |
lines | Tableau de lignes, voir sous-objet ci-dessous |
subtotal | Somme des lines[].total avant remise et TVA |
tva_amount | Calculé : (subtotal − remise) × tva_rate / 100 |
total_ttc | subtotal − remise + tva_amount |
status | Voir constante ci-dessous |
due_date | Date d'échéance. Au-delà sans paiement, transition vers overdue |
paid_date | Posée à la transition vers paid |
payment_method | Texte libre : virement, cb, chèque, espèces, etc. |
Constante liée
INVOICE_STATUS : draft, sent, partially_paid, paid, overdue
Sous-objet DocumentLine
ts
interface DocumentLine {
description: string;
quantity: number;
unit_price: number;
total: number;
}| Champ | Notes |
|---|---|
description | Texte libre affiché sur le PDF |
quantity | Nombre d'unités, toujours positif |
unit_price | Prix unitaire HT en euros |
total | quantity × unit_price, stocké pour figer les montants historiques |
Pourquoi total est stocké
total est stocké et non calculé à la volée pour figer les montants en cas d'évolution des règles de calcul (TVA, format, arrondi). À recalculer côté client à chaque édition de la ligne.
Cycle de vie
Numérotation et suppression
La séquence des numéros de facture doit être ininterrompue et chronologique (obligation légale FR).
Conséquences :
numberest immuable après création (rule Firestore)- Ne jamais supprimer une facture validée (
sentou plus). Elle doit rester pour l'audit comptable - Pour annuler une facture validée, créer un avoir (à modéliser : statut
annuleeou collectioncredit_notes)
Voir aussi
Quote: devis pouvant être converti en factureContact- Règles de sécurité : champ
numberimmuable - Cloud Functions : enforcement de la limite Starter