Ventes & Facturation
Ventes & Facturation
Périmètre : clients, devis, commandes, factures, avoirs, règlements, fournisseurs (devis/commandes/factures/règlements miroir), entités de facturation, modes de paiement, comptabilité opérationnelle et e-invoicing (réforme FR 2026/2027 — provider : Agicap).
/workspace/<ressource> (et non /workspace/sales/<ressource> — convention retenue à l'implémentation). Routes API : /api/workspace/sales/*, /api/workspace/purchases/*, /api/workspace/accounting/*, /api/workspace/einvoicing/*. Source : docs/10-domain-sales-billing.md.Vocabulaire & entités
| Terme | Entité | Définition |
|---|---|---|
| Client | Customer | Entité acheteuse rattachée à une Company. |
| Fournisseur | Supplier | Entité vendeuse rattachée à une Company. |
| Entité de facturation | BillingEntity | Entité légale émettrice (ex. Pulse Group SAS). Une org peut en avoir plusieurs. |
| Devis | Quote / QuoteLine | Proposition commerciale chiffrée ; numéro alloué à la création. |
| Commande | Order / OrderLine | Engagement client ferme ; issu d'une conversion de devis ou libre. |
| Facture | Invoice / InvoiceLine | Document légal ; numéro alloué à l'émission (DRAFT → ISSUED). |
| Avoir | CreditNote | Facture négative ; numérotation séparée (AV-YYYY-NNN). |
| Règlement | Payment | Encaissement client ; alloué à une ou plusieurs factures. |
| Numéro légal | Invoice.number | Séquence sans trou, immuable, par (BillingEntity, type, year). |
| PA (Plateforme Agréée) | — | Opérateur fiscal (Agicap) émettant/recevant les e-factures via Peppol. |
| PPF | — | Portail Public de Facturation — annuaire destinataires + concentrateur fiscal. |
| Factur-X | — | Format hybride PDF/A-3 + XML CII embarqué (EN 16931). |
| E-reporting | EReportingSubmission | Transmission des données B2C / encaissements hors e-invoicing. |
| 3-way match | — | Rapprochement commande + PV réception + facture fournisseur. |
| Facture fournisseur | SupplierInvoice | Upload PDF + OCR ; qualifiée analytiquement (nature, exercice, contrat). |
| Règlement fournisseur | SupplierPayment | Sortie vers fournisseur ; enregistré sur la fiche SupplierInvoice. |
Le modèle complet est dans
docs/04-data-model.md§8. La comptabilité analytique (plan comptable, nature de prestation, clôture FNP/CCA/CAP) fait l'objet d'un domaine dédié :docs/23-domain-accounting.md.
Écrans
| Écran | Route | Contenu |
|---|---|---|
| Dashboard ventes | /workspace/sales | KPI CA MTD/YTD, DSO, alertes devis/factures en retard. |
| Liste clients | /workspace/customers | DataTable + encours TTC + CA YTD + DSO. |
| Fiche client | …/customers/[id] | Synthèse KYB, devis, commandes, factures, contrats LLD, conditions. |
| Liste devis | /workspace/quotes | DataTable + kanban (Drafts / Envoyés / Acceptés / Convertis). |
| Création devis | /workspace/quotes/new | Wizard 5 étapes : client → BillingEntity → lignes → conditions → envoi. |
| Fiche devis | …/quotes/[id] | Lignes éditables si DRAFT, envoi, conversion commande, PDF. |
| Page publique devis | /q/[token] | Acceptation / refus client via Quote.publicToken (hors auth). |
| Liste commandes | /workspace/orders | DataTable + statuts CONFIRMED → SHIPPED → RECEIVED → INVOICED. |
| Fiche commande | …/orders/[id] | Lignes, tracking expédition, génération facture. |
| Liste factures | /workspace/invoices | DataTable + statut e-invoicing Agicap, actions de masse. |
| Création facture | /workspace/invoices/new | Depuis commande, contrat LLD ou libre ; aperçu Factur-X. |
| Fiche facture | …/invoices/[id] | Timeline e-invoicing, règlements, avoirs, re-soumission Agicap. |
| Liste règlements | /workspace/payments | Lettrage manuel ou auto ; import bancaire CSV/EBICS. |
| Fournisseurs | /workspace/suppliers | Miroir module clients. |
| Factures fournisseur | /workspace/supplier-invoices | Upload PDF + OCR + 3-way match + affectation analytique. |
| E-reporting | /workspace/einvoicing/ereporting | Génération DRAFT + soumission périodique à Agicap. |
| Soumissions e-invoice | /workspace/einvoicing/submissions | DataTable cross-factures paginée, filtres statut/provider. |
| Paramètres facturation | /workspace/admin/settings/billing | BillingEntities, modes de paiement, templates PDF, numérotation, Agicap. |
Modèle de données (points clés)
Invoice.number: alloué sous verrou consultatif Postgres (pg_advisory_xact_lock) à la transitionDRAFT → ISSUED. Jamais avant. Test de concurrence validé : 12 émissions parallèles →FAC-1…FAC-12, sans trou ni doublon.- Format numéro :
{prefix}{YYYY}{sequence:6}— ex.FAC-2026-000123. Reset annuel optionnel parBillingEntity. Invoice.facturXProfile: stocké à l'émission (audit). PDF/A-3 + XML CII embarqué généré viaxmlbuilder2; validation XSD vialibxmljs2.EInvoiceSubmission: relation 1-N avecInvoice(plusieurs tentatives, champattemptNumber). Contrainte@@unique([invoiceId, attemptNumber]).SupplierInvoice.accountingCodeId+fiscalYear: contrôle bloquant pour la clôture — une facture fournisseur validée doit impérativement porter ces deux champs.SupplierInvoiceAllocation: ventilation multi-contrats d'une charge réseau — la somme des lignes doit égalertotalHtde la facture.EReportingSubmission: contrainte d'unicité(organizationId, yearMonth, type); statutsDRAFT → SUBMITTED → ACCEPTED / REJECTED.Quote.publicToken: clé signée pour la page d'acceptation publique/q/[token]; hors authentification.SupplierEInvoiceReceipt: idempotence à la réception inbound — dédup par(provider, externalInvoiceId).
API
Ventes
| Méthode | Route | Permission |
|---|---|---|
GET | /api/workspace/sales/quotes | sales.quote:read |
POST | /api/workspace/sales/quotes | sales.quote:create |
PATCH | /api/workspace/sales/quotes/[id] | sales.quote:update |
POST | …/quotes/[id]/send | sales.quote:send |
POST | …/quotes/[id]/accept | sales.quote:update |
POST | …/quotes/[id]/convert | sales.quote:convert |
GET | …/quotes/[id]/pdf | sales.quote:read |
GET | /api/workspace/sales/orders | sales.order:read |
POST | /api/workspace/sales/orders | sales.order:create |
POST | …/orders/[id]/ship | sales.order:update |
POST | …/orders/[id]/invoice | sales.invoice:create |
GET | /api/workspace/sales/invoices | sales.invoice:read |
POST | /api/workspace/sales/invoices | sales.invoice:create |
POST | …/invoices/[id]/issue | sales.invoice:issue |
POST | …/invoices/[id]/cancel | sales.invoice:cancel |
GET | …/invoices/[id]/factur-x | sales.invoice:read |
GET | …/invoices/[id]/validate-fr2026 | sales.invoice:read |
POST | …/invoices/[id]/credit-note | sales.invoice:credit |
POST | …/invoices/[id]/reminder | sales.invoice:issue |
POST | …/invoices/[id]/resubmit-einvoice | sales.invoice:issue |
POST | /api/workspace/sales/payments | sales.payment:create |
POST | …/payments/import | sales.payment:create |
POST | …/payments/reconcile | sales.payment:reconcile |
Achats (miroir)
| Méthode | Route | Permission |
|---|---|---|
GET | /api/workspace/purchases/suppliers | purchasing.supplier:read |
POST | /api/workspace/purchases/invoices | purchasing.invoice:create |
POST | …/invoices/[id]/validate | purchasing.invoice:update |
PATCH | …/invoices/[id]/allocate | accounting.allocation:update |
POST | …/invoices/upload | purchasing.invoice:create |
POST | /api/workspace/purchases/payments | purchasing.payment:create |
Facturation électronique (Agicap)
| Méthode | Route | Auth |
|---|---|---|
POST | /api/workspace/invoices/[id]/e-submit | sales.invoice:issue |
GET | /api/workspace/invoices/[id]/e-lifecycle | sales.invoice:read |
POST | /api/workspace/einvoicing/ereporting/generate | billing.export:download |
POST | /api/workspace/einvoicing/ereporting/[id]/submit | billing.export:download |
GET | /api/workspace/einvoicing/submissions | sales.invoice:read |
POST | /api/webhooks/einvoicing/agicap/inbound | Signature HMAC |
POST | /api/webhooks/agicap | Signature HMAC |
Exemple de référence d'endpoint :
/api/workspace/sales/invoices/[id]/issueAuth Valide un brouillon et émet la facture : alloue le numéro légal sous advisory lock,
vérifie les mentions FR 2026, génère le PDF Factur-X, déclenche la soumission Agicap.
Retourne 422 avec liste détaillée si les mentions obligatoires sont incomplètes.
Corps (JSON)
Requête
curl -s -X POST "$API/api/workspace/sales/invoices/$ID/issue" \
-H "Content-Type: application/json" -H "Cookie: $SESSION" \
-d '{"sendEmail": true}'
Réponse
{
"id": "inv_…",
"number": "FAC-2026-000042",
"status": "ISSUED",
"facturXProfile": "EN16931",
"issuedAt": "2026-06-16T10:00:00Z"
}
Comptabilité opérationnelle
| Méthode | Route | Permission |
|---|---|---|
GET | /api/workspace/accounting/journal-sales | billing.export:download |
GET | /api/workspace/accounting/journal-purchases | billing.export:download |
GET | /api/workspace/accounting/balance-customers | billing.export:download |
GET | /api/workspace/accounting/vat-summary | billing.export:download |
GET | /api/workspace/accounting/export?format=fec|sage|cegid|pennylane | billing.export:download |
Workflows
Cycle vente standard
Opportunity (CRM)
│
└─→ Quote (DRAFT) → SENT → ACCEPTED → CONVERTED
│
Order (CONFIRMED)
│
SHIPPED → RECEIVED
│
Invoice (DRAFT) → ISSUED → PAID
À l'émission (DRAFT → ISSUED) : advisory lock, numérotation légale irréversible, génération Factur-X, contrôle mentions FR 2026, soumission Agicap.
Numérotation légale (garde-fou)
Séquence par (BillingEntity, type, year). Le numéro est consommé une seule fois, à la transition vers ISSUED. Toute tentative d'émission concurrente attend la libération du verrou (pg_advisory_xact_lock). Reset annuel optionnel. La suppression d'une facture ISSUED est interdite — seule une annulation avec création d'avoir total est possible.
Facturation électronique B2B — réforme FR
| Échéance | Obligation |
|---|---|
| 1ᵉʳ septembre 2026 | Réception obligatoire pour toutes les entreprises ; émission pour grandes entreprises et ETI. |
| 1ᵉʳ septembre 2027 | Émission obligatoire pour PME et TPE. |
Pulse ERP vise la conformité complète (émission + réception + e-reporting) au 1ᵉʳ septembre 2026, indépendamment du seuil par BillingEntity.
Workflow émission (Agicap, Phase 7 — livré) :
- Facture
ISSUED→ génération Factur-X (XML CII + PDF/A-3). - Contrôle bloquant des mentions obligatoires FR 2026 (SIREN client, adresse livraison, nature opération, option TVA sur débits).
- Résolution du destinataire (SIREN/SIRET → identifiant Agicap/Peppol).
- Soumission API Agicap →
EInvoiceSubmission.providerInvoiceId. - Suivi cycle de vie via webhook HMAC
POST /api/webhooks/agicap— statuts :SUBMITTED → RECEIVED_BY_PDP → DEPOSITED → RECEIVED_BY_RECIPIENT → APPROVED / REFUSED / IN_DISPUTE / PAID / REJECTED_BY_PDP. - En cas de rejet/refus : re-soumission via
POST …/resubmit-einvoice(incrémenteattemptNumber).
Workflow réception inbound : webhook POST /api/webhooks/einvoicing/agicap/inbound → parser CII (cii-parser.ts) → matching fournisseur par SIREN → création SupplierInvoice status RECEIVED. Idempotence via SupplierEInvoiceReceipt.
Relances impayés
Job nocturne invoice-reminder :
- J-3 avant échéance → relance amicale.
- J+1 → 1ʳᵉ relance ferme.
- J+15 → 2ᵉ relance avec frais.
- J+30 → mise en demeure (PDF généré).
- J+45 → escalade direction + suggestion contentieux.
Suivi : Invoice.lastReminderSentAt, reminderCount. Désactivable par client.
E-reporting périodique
POST /api/workspace/einvoicing/ereporting/generate — body { yearMonth, type } (types : TRANSACTIONS, PAYMENTS, B2C). Soumission via …/[id]/submit. Contrainte d'unicité (organizationId, yearMonth, type) évite les doubles envois.
Règles métier
- Numérotation sans trou, immuable, par
BillingEntity— obligation légale FR. Advisory lock Postgres à chaque émission. - Date facture = date d'émission = date où la facture passe
ISSUED. Non modifiable après. - TVA multi-taux dans une facture (5,5 %, 10 %, 20 %). Auto-liquidation pour clients intra-UE (mention obligatoire + vérification VIES).
- Facture > 5 € HT : mentions légales obligatoires (SIRET, N° TVA, conditions règlement, taux pénalité, indemnité 40 €).
- Avoir partiel : total avoirs ne peut pas dépasser le total facture. Avoir total → facture passe
CANCELED. - Paiement : ne peut pas dépasser le montant dû.
- Suppression facture
ISSUEDinterdite ; soft delete surDRAFTuniquement. - 3-way match fournisseur : refus de paiement si écart > seuil (5 % ou montant absolu configurable).
SupplierInvoicevalidée sansaccountingCodeIdoufiscalYear: bloquant pour la clôture comptable.- Ventilation
SupplierInvoiceAllocation: somme des lignes doit égalertotalHtde la facture.
KPIs
CA HT MTD, YTD, comparatif N-1 · panier moyen · DSO global et par client · % factures payées dans les délais · encours > 30/60/90 jours · taux d'acceptation devis · cycle moyen Quote → Order → Invoice → Paid · TVA collectée / déductible / nette · marge brute par produit.
Notifications
| Événement | Canal | Destinataire |
|---|---|---|
| Devis envoyé | Client | |
| Devis accepté (lien public) | In-app + email | Commercial |
| Facture émise | Email (avec PDF) | Client |
| Facture proche échéance (J-3) | Client (si activé) | |
| Facture en retard (J+1) | Client + commercial | |
| Facture > 30j retard | In-app + email | Comptable + manager |
| Avoir émis | Client | |
| Paiement reçu | In-app + email | Comptable |
| Facture fournisseur reçue (Agicap) | In-app | Comptable |
| Facture rejetée / refusée (Agicap) | In-app + email | Comptable + commercial |
| E-reporting transmis / en échec | In-app | Comptable |
| 3-way match KO | In-app | Comptable |
Achats
Référence technique du domaine Achats fournisseurs — devis multi-fournisseurs, inbox OCR IA, comparateur, commandes, réception→asset, rapprochement 3 voies et boucle achats↔leasing.
Location
Référence technique du domaine Location — affaires, contrats, financement PMT, agréments bailleurs, cessions, assurance, maintenance, prélèvements et engagements bancaires.