# Facturation électronique — génération Factur-X (étape 1)

Suite de l'export CII (voir `docs/facture_electronique_CII_D22B.md`) : production d'une facture **Factur-X**, c'est-à-dire le PDF lisible de la facture au format PDF/A-3, avec le XML CII EN 16931 embarqué sous le nom `factur-x.xml`.

## Ce qui a été livré

| Fichier | Changement |
|---|---|
| `composer.json` / `composer.lock` | Ajout de `horstoeko/zugferd` (^1.0, v1.0.132) et de ses 8 dépendances (jms/serializer, symfony/validator, smalot/pdfparser…). Aucune mise à jour des paquets existants. |
| `app/Services/generer_facturx_pdf_service.php` | **Nouveau.** `generer(facture $facture, string $pdfSource): string` génère le XML via les services CII existants, puis l'assemble avec le PDF via `ZugferdDocumentPdfMerger`. |
| `app/Http/Controllers/facture_controller.php` | Nouvelle action `test_facture_facturx` (même logique que `test_facture_electronique`) : génère le PDF classique avec `genererPdfFactures([$id], new Request())` (fond + CGV inclus), le convertit en Factur-X et le télécharge. Répond en HTTP 422 si un champ obligatoire EN 16931 manque. |
| `routes/web.php` | Ajout de `facture.test_facture_facturx`. **Rétablissement** de `facture.telecharger_facture_cii` et `facture.test_facture_electronique`, perdues lors du reformatage du fichier dans le commit « Dashboard en laravel » (b6b1ffc6). Sans elles, la page d'export de factures électroniques plantait (`route()` introuvable). |

### Utilisation

```
GET /facture/test_facture_facturx               -> dernière facture créée
GET /facture/test_facture_facturx?numero=XXXXX  -> facture précise
```

## Décisions prises

- **On garde notre générateur XML CII.** La librairie ne sert qu'à l'assemblage PDF : pièce jointe, métadonnées XMP `fx:*`, déclaration PDF/A-3 et profil de couleurs (OutputIntent). Le contenu métier est donc identique à l'export CII.
- **Le profil est détecté automatiquement** à partir de BT-24 (`urn:cen.eu:en16931:2017`), ce qui donne le profil EN 16931, la pièce jointe `factur-x.xml` et `ConformanceLevel = EN 16931`.
- **`AFRelationship = Alternative`** (la librairie met `Data` par défaut) : c'est la valeur attendue pour les profils EN 16931 et EXTENDED. **À confirmer avec la PDP.**
- **Composer doit être lancé avec PHP 8.1.** La commande `composer` du poste utilise PHP 7.4. Il faut lancer `C:\wamp64\bin\php\php8.1.28\php.exe composer.phar …`, avec `--ignore-platform-req=ext-ftp` car l'extension `ftp` n'est pas activée en ligne de commande (`league/flysystem-ftp` est déjà dans le lock).

## Tests effectués

Sur la base de dev, la seule société (01) n'a ni logo (html2pdf plante : `data:image/jpeg;base64,` vide), ni SIRET, ni n° de TVA (le XML est refusé par le contrôle des champs obligatoires). Le test de bout en bout depuis le vrai PDF n'a donc pas pu aboutir **à cause des données**. On a donc testé l'assemblage sur la facture F0126090021, avec un SIRET et un n° de TVA fictifs **en mémoire (rien n'est enregistré en base)** et un PDF minimal FPDF :

- PDF relu par la librairie : profil `en16931`, numéro `F0126090021`, type 380, EUR ✅
- Totaux XML = totaux en base (HT 1530, TVA 306, TTC 1836) ✅
- Pièce jointe `factur-x.xml`, `AFRelationship /Alternative`, `pdfaid:part 3`, `fx:ConformanceLevel EN 16931`, `OutputIntents` ✅
- XML embarqué validé contre le XSD officiel Factur-X EN 16931 ✅

## Reste à faire

1. Tester `/facture/test_facture_facturx` avec une société complète (logo, SIRET, TVA), via le navigateur ou sur la préproduction.
2. Passer le PDF produit dans **veraPDF** (PDF/A-3B). La librairie *déclare* le PDF en PDF/A-3 mais ne corrige pas le PDF source. Points de vigilance : police Arial non embarquée dans html2pdf, transparence éventuelle du fond de page, PDF récupérés via `url_pdf` (modèles spécifiques).
3. Si veraPDF signale des erreurs, faire l'étape 2 : polices embarquées (DejaVu) ou conversion par Ghostscript en PDF/A-3 avant l'assemblage.
4. Export en masse (ZIP de PDF Factur-X) et option `2 = Factur-X` dans `parametre_type_export_facture_electronique`.
5. Hors sujet mais repéré : la route nommée `convocation_chauffeur.` a aussi disparu de `routes/web.php` dans le commit b6b1ffc6.
