Skip to content

Latest commit

 

History

History
95 lines (77 loc) · 4.6 KB

File metadata and controls

95 lines (77 loc) · 4.6 KB

Architecture de Facturia

Facturia est une application web Django de facturation mono-entreprise pour la zone UEMOA (devise FCFA / XOF). Une seule société (l'émetteur) gère ses clients, son catalogue, et émet des factures conformes avec calcul de TVA, PDF, tableau de bord et API REST.

Stack

  • Backend : Django 5.2 (LTS), Django REST Framework.
  • Base de données : SQLite en développement, PostgreSQL en production (via DATABASE_URL).
  • PDF : WeasyPrint (rendu HTML/CSS → PDF).
  • Frontend : Tailwind CSS (CLI standalone, CSS compilé committé) + Alpine.js (auto-hébergé). Pas de build Node requis.
  • Configuration : variables d'environnement via python-decouple.

Structure du projet

config/      Projet Django : settings (pilotés par l'env), urls, wsgi/asgi
core/        Transverse : CompanySettings (émetteur singleton), dashboard,
             page Paramètres, formatage monétaire (filtre fcfa + montant en lettres)
billing/     Domaine métier : Customer, Product, Invoice, InvoiceItem,
             InvoiceSequence ; services (calcul, numérotation, finalisation),
             selectors (KPIs), API DRF, génération PDF
templates/   base.html + pages core/billing + modèles PDF (billing/pdf/)
static/      CSS Tailwind compilé, Alpine.js
theme/       Sources Tailwind (input.css, config)

Sens des dépendances : billing → core (paramètres). Le tableau de bord de core consomme billing.selectors (aucune importation des modèles billing dans core.models).

Modèle de données

  • core.CompanySettings — singleton (pk=1) : émetteur unique (raison sociale, adresse, identifiant fiscal NINEA/IFU, RCCM, logo, devise, taux de TVA par défaut, délai de paiement, format de numéro, mentions de bas de page, modèle de PDF choisi).
  • Customer — nom, société, contacts, adresse, identifiant fiscal.
  • Product — produit ou service, prix HT, taux de TVA, actif/inactif.
  • Invoice — client, statut, dates, totaux dénormalisés (HT/TVA/TTC + ventilation par taux), et champs « snapshot » (identité émetteur + client figés à la finalisation).
  • InvoiceItem — ligne (désignation, quantité, PU HT, taux de TVA) ; les valeurs sont figées sur la ligne (le lien product n'est qu'une référence).
  • InvoiceSequence — compteur de numérotation par année.

Règles métier (billing/services.py)

  • Montants : tout en FCFA sans décimales. Arrondi ROUND_HALF_UP, Decimal uniquement. Par ligne : HT = arrondi(qté × PU), TVA = arrondi(HT × taux/100). Totaux = sommes ; ventilation TVA par taux.
  • Numérotation : un brouillon n'a pas de numéro. À la finalisation, un numéro séquentiel par année est attribué de façon atomique (InvoiceSequence + select_for_update, avec repli IntegrityError/retry pour SQLite). Le numéro est immuable et la finalisation est transactionnelle.
  • Statuts : draft → sent → paid (+ cancelled). overdue est dérivé (émise, échue, non payée), jamais stocké.
  • Immuabilité : à la finalisation, l'identité de l'émetteur et du client est copiée sur la facture (snapshot) ; les lignes sont verrouillées. Une facture finalisée n'est plus modifiable (garde côté vue, sérialiseur et admin).
  • Recalcul des totaux : centralisé (recalculate_totals), déclenché après modification des lignes (vues, API, signaux).

Modèles de PDF (extensible)

Le rendu PDF repose sur un registre (billing/pdf_templates.py) et un corps partagé (templates/billing/pdf/_invoice_body.html) contenant toute la donnée légale une seule fois. Chaque modèle (ledger, classic, compact) n'est qu'un habillage CSS qui inclut ce corps. Le modèle est choisi dans les Paramètres. Ajouter un modèle = un fichier <clé>.html + une entrée dans le registre.

Frontend

  • Tailwind compilé (theme/input.cssstatic/css/app.css, committé). Police d'affichage Fraunces + Hanken Grotesk (chargées via Google Fonts).
  • Alpine.js (local) pour l'interactivité légère ; l'éditeur de lignes de facture calcule les totaux en direct côté client, le serveur restant la source de vérité.

API REST (/api/)

Endpoints DRF pour clients, produits et factures (avec lignes imbriquées) + actions finalize / status / duplicate / pdf. Authentification par session (UI) et par token (intégrations).

Tests

Suite pytest couvrant le calcul des montants, la numérotation atomique, les transitions de statut, les vues, l'API, la génération PDF et les KPIs du dashboard. Lancez pytest -q.