Skip to content

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

ChampNotes
number🔒 Immuable. Format : <invoice_prefix><année>-<seq>. Séquence ininterrompue exigée par la loi française
contact_idRéférence optionnelle vers un Contact
quote_idLien optionnel vers le devis source
linesTableau de lignes, voir sous-objet ci-dessous
subtotalSomme des lines[].total avant remise et TVA
tva_amountCalculé : (subtotal − remise) × tva_rate / 100
total_ttcsubtotal − remise + tva_amount
statusVoir constante ci-dessous
due_dateDate d'échéance. Au-delà sans paiement, transition vers overdue
paid_datePosée à la transition vers paid
payment_methodTexte 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;
}
ChampNotes
descriptionTexte libre affiché sur le PDF
quantityNombre d'unités, toujours positif
unit_pricePrix unitaire HT en euros
totalquantity × 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 :

  • number est immuable après création (rule Firestore)
  • Ne jamais supprimer une facture validée (sent ou plus). Elle doit rester pour l'audit comptable
  • Pour annuler une facture validée, créer un avoir (à modéliser : statut annulee ou collection credit_notes)

Voir aussi