Apparence
Quote
Devis. Composé d'une liste de DocumentLine, avec calcul de TVA et remise éventuelle.
- Path Firestore :
users/{userId}/quotes/{quoteId} - Source TS :
klapy-crm/src/types/index.ts - Limite plan Starter : 10 devis actifs simultanés (enforced en Cloud Function)
Interface
ts
interface Quote {
id: string;
number: string;
contact_id?: string;
lines: DocumentLine[];
subtotal: number;
tva_rate: number;
tva_amount: number;
discount?: number;
discount_type?: 'percentage' | 'fixed';
total_ttc: number;
status: QuoteStatus;
payment_conditions?: string;
validity_date?: Timestamp;
notes?: string;
created_at: Timestamp;
updated_at: Timestamp;
}Champs
| Champ | Notes |
|---|---|
number | 🔒 Immuable après création. Format : <quote_prefix><année>-<seq> |
contact_id | Référence optionnelle vers un Contact |
lines | Tableau de lignes, voir sous-objet ci-dessous |
subtotal | Somme des lines[].total avant remise et TVA |
tva_rate | Taux de TVA appliqué (ex. 20 pour 20 %) |
tva_amount | Calculé : (subtotal − remise) × tva_rate / 100 |
discount | Valeur brute (montant ou pourcentage selon discount_type) |
discount_type | 'percentage' ou 'fixed' |
total_ttc | subtotal − remise + tva_amount |
status | Voir constante ci-dessous |
validity_date | Date d'expiration du devis. Au-delà, transition vers expired |
Constante liée
QUOTE_STATUS : draft, sent, accepted, refused, expired
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
Conversion en facture
Quand un devis passe accepted, on peut générer une Invoice qui référence le devis source via quote_id. Le devis n'est ni supprimé ni modifié, juste référencé.
Numérotation
number est immuable après création (rule Firestore). La séquence n'a pas la même contrainte légale que les factures, mais on évite les trous pour la lisibilité.
Voir aussi
Invoice: facture issue d'un devisContactOpportunity: un devis peut être créé depuis une opportunité- Règles de sécurité : champ
numberimmuable