Skip to main content

Génération, validation et assemblage de factures électroniques Factur-X / EN 16931 en Python.

Project description

eFacturePy — ads-facturx

Génération, validation et assemblage de factures électroniques Factur-X / EN 16931 en Python.

Python Version Build Status


🧭 Sommaire


📖 À propos

eFacturePy est le dépôt de travail du package Python ads-facturx, un outil qui permet de :

  • produire un XML Cross Industry Invoice conforme au profil urn:cen.eu:en16931:2017 ;
  • générer le PDF/A-3 associé à l’aide de ReportLab ;
  • embarquer ce XML dans le PDF pour obtenir une Factur-X valide (via factur-x) ;
  • valider la facture via XSD (EN16931) et Schematron (moteur SaxonC-HE).

✨ Fonctionnalités

  • ✅ Génération d’un XML Factur-X / EN 16931 à partir d’un dict métier
  • ✅ Génération d’un PDF de facture (template par défaut + logo personnalisable)
  • ✅ Fusion PDF + XML → fichier Factur-X conforme
  • ✅ Validation XSD (profil en16931)
  • ✅ Validation Schematron via XSLT précompilé (SaxonC)
  • ✅ Modèles Pydantic v2 pour typer et valider les données métier

🏗️ Architecture du dépôt

eFacturePy/
├─ ads_facturx/              # Package distribué sur PyPI
│  ├─ Builders/              # Génération XML + PDF + Factur-X
│  ├─ Validators/            # XSD + Schematron (XSLT EN16931-CII)
│  ├─ models/                # Schémas Pydantic (DevisData, Invoice, …)
│  ├─ Samples/               # Jeu de données et XML de référence
│  └─ tests/                 # Tests unitaires pytest
├─ eFacturePy/               # Sorties d’exemple (PDF/XML générés)
├─ archive/                  # Ressources brutes : XSD, XSL, Schematron, Saxon
├─ dist/                     # Wheels et sdist historiques                   
├─ pyproject.toml            # Configuration Poetry
└─ poetry.lock

📦 Installation

Depuis PyPI :

pip install ads-facturx

Prérequis : Python ≥ 3.12. SaxonC-HE est installé automatiquement via la dépendance saxonche.


🚀 Démarrage rapide

Pipeline complet : validation → XML → contrôles XSD/Schematron → PDF → Factur-X.

from ads_facturx import (
    DevisData,
    export_xml,
    write_xml_from_string,
    xml_check_xsd,
    xml_check_schematron,
    export_pdf,
    generate_facturx,
)

# 1. Données métier (dict) → modèle validé
data = {...}  # voir docs/pdf/examples/sample_data.py
validated = DevisData.model_validate(data)

DESTINATION = "eFacturePy"
invoice_name = validated.invoice.name

# 2. XML EN 16931
xml_string = export_xml(validated)
xml_path = write_xml_from_string(
    xml_string=xml_string,
    destination_folder=DESTINATION,
    file_name=invoice_name,
)

# 3. Validation XSD + Schematron
xml_check_xsd(xml_string)
report = xml_check_schematron(xml_path=xml_path)
print(report)

# 4. PDF (template par défaut)
export_pdf(
    title=invoice_name,
    output_path=f"{DESTINATION}/{invoice_name}.pdf",
    data=validated,
)

# 5. PDF + XML → Factur-X
generate_facturx(
    file_name=f"{invoice_name}.pdf",
    destination_folder=DESTINATION,
    xml=xml_string,
)

Un jeu de données complet, validable tel quel par DevisData, est fourni dans docs/pdf/examples/sample_data.py.


🔌 API publique

Exposée via from ads_facturx import ... (cf. ads_facturx/__init__.py).

Pipeline principal

Symbole Rôle
DevisData Modèle Pydantic v2 d'entrée (validation EN 16931).
export_xml(validated) Construit la chaîne XML CII profil en16931.
write_xml_from_string Sérialise l'XML sur disque (destination_folder, file_name).
xml_check_xsd Valide l'XML avec le XSD facturx / niveau en16931.
xml_check_schematron Applique les règles Schematron EN16931-CII via SaxonC.
export_pdf Génère le PDF de facture (ReportLab — template par défaut ou custom).
generate_facturx Embarque le XML dans le PDF pour produire la Factur-X finale.

Briques pour personnaliser le PDF (détails dans la doc PDF)

Template · ParagraphComponent · SpacerComponent · PageBreakComponent · BoxComponent · TableComponent · KeepInFrameComponent · DiyComponent · Header · Footer · TextElement · CenteredText · ImageElement · HorizontalLine · Theme · TableStyles · FontName · TableConfig · TableColumn · TableBox · ParagraphConfig · KeepInFrameConfig · FormatText · FormatDate · ExtraRow · ExtraRowCell · DocConfig · mm · A4 · colors.


🔤 Utiliser une autre police

La librairie embarque DejaVu (régulier + gras) et s'en sert par défaut. Pour employer une police à soi, il suffit de la déclarer à register_fonts — inutile d'importer ReportLab :

from ads_facturx import Theme, export_pdf, register_fonts
from ads_facturx.Builders.pdf.config.config import DocConfig

register_fonts(extra={"Inter": "fonts/Inter-Regular.ttf"})

titre = Theme(name="titre", fontName="Inter", fontSize=14)

Le nom logique ("Inter") se réutilise ensuite dans Theme(fontName=...), TableStyles(body_font=..., header_font=...) et DocConfig(page_number_font=...). Un fichier .ttf introuvable lève un FileNotFoundError immédiatement, plutôt qu'au moment du rendu.

Trois points à connaître :

  • La police est embarquée en sous-ensemble dans le PDF, ce qu'exige PDF/A-3. Un document rendu entièrement dans une police tierce reste conforme.
  • Le template par défaut reste en DejaVu. Pour changer la police de tout le document, il faut fournir ses propres Theme / TableStyles via export_pdf(structure=...). Les clés header et footer y sont facultatives.
  • Les 14 polices standard du PDF sont refusées (voir ci-dessous).

Pourquoi Helvetica & consorts sont refusées

Theme(fontName="Helvetica") lève désormais un NonEmbeddableFontError, de même que Times, Courier, Symbol, ZapfDingbats et leurs variantes de casse ("Helvetica-bold"). Ces 14 polices sont fournies par le lecteur de PDF, donc jamais écrites dans le fichier. Deux conséquences :

  • PDF/A l'interdit — « the font programs for all fonts used for rendering within a conforming file shall be embedded » (ISO 19005-3, clause 6.2.11.4.1). veraPDF rejette le document, et la facture avec.
  • Helvetica, Times et Courier sont des marques déposées : ads-facturx ne peut pas en distribuer les fichiers pour contourner le point précédent.

Le piège, c'est qu'un tel PDF s'ouvre et s'imprime normalement : sans ce contrôle, rien n'échoue avant la validation de conformité — souvent chez le destinataire. La substitution (register_fonts(extra={"Helvetica": ...})) est refusée elle aussi : ReportLab l'ignore silencieusement dès qu'il a déjà instancié la police d'origine, ce qui rendrait la conformité dépendante de l'ordre des appels.

Le remède est toujours le même — une police libre déclarée à register_fonts, ou les DejaVu livrées avec la librairie.


🧾 Modèle de données

Schémas Pydantic v2 dans ads_facturx/models : DevisData (racine), Partner, Address, Invoice, InvoiceLine, InvoiceSummary, Footer, plus les énumérations normatives (CountryCode, CurrencyCode, UnitCode, VatCategory).

DevisData.model_validate(data) applique les contraintes EN 16931 critiques (formats de dates YYYYMMDD, codes pays/devise/unité, type TVA, …).

Détail des champs et exemple JSON complet : docs/pdf/03-input-data.md.


📚 Documentation détaillée

La génération PDF dispose de sa propre documentation, en 12 sections progressives :

docs/pdf/README.md — table des matières.

Au menu : quickstart, mental model, schéma DevisData, construction de templates, catalogue de composants, personnalisation (style / config), header & footer, composants DIY, défauts fournis, cookbook, erreurs courantes, référence API.

Tous les exemples sont exécutables :

python docs/pdf/examples/run_examples.py
# → PDFs écrits dans docs/pdf/examples/out/

✅ Validation EN 16931

  • XSD : xml_check_xsd s’appuie sur factur-x (flavor="facturx", level="en16931").
  • Schematron : xml_check_schematron exécute Validators/xslt/EN16931-CII-validation.xslt avec SaxonC et renvoie la liste des failed-assert (id, location, message).

📚 Dépendances

factur-x, saxonche, pydantic, reportlab (voir pyproject.toml et poetry.lock).

👤 Auteur

Antoine DucoulombierAlchimie Data Solutions · antoine.ducoulombier@alchimiedatasolutions.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ads_facturx-0.7.3.tar.gz (947.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ads_facturx-0.7.3-py3-none-any.whl (960.6 kB view details)

Uploaded Python 3

File details

Details for the file ads_facturx-0.7.3.tar.gz.

File metadata

  • Download URL: ads_facturx-0.7.3.tar.gz
  • Upload date:
  • Size: 947.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.12.7 Windows/11

File hashes

Hashes for ads_facturx-0.7.3.tar.gz
Algorithm Hash digest
SHA256 d81758d52dd67765984f635be4f9c073fdb5c96c4f4755887b578362b5291cfc
MD5 f09b08361ce58305b5b6894b2eb27493
BLAKE2b-256 986b17c02914dd89cced6e1864ef95f7b919c36970ca9c68c3a607c85948dcf9

See more details on using hashes here.

File details

Details for the file ads_facturx-0.7.3-py3-none-any.whl.

File metadata

  • Download URL: ads_facturx-0.7.3-py3-none-any.whl
  • Upload date:
  • Size: 960.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.12.7 Windows/11

File hashes

Hashes for ads_facturx-0.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0ec0c75357117767371a5fdd25c2954494fcbd34a5c7824d29a176d45ebe8e85
MD5 7db72fbf2ad20683c9f506b362e5a9e2
BLAKE2b-256 e509370e6cd16ccd62a55694110805cce3ff00df8fb47d0edd8a00c20fdd747c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page