PHPackages                             mlucas/invoiceiq-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. mlucas/invoiceiq-bundle

ActiveSymfony-bundle[Validation &amp; Sanitization](/categories/validation)

mlucas/invoiceiq-bundle
=======================

Analyse et validation de factures pour Symfony (OCR, règles, VIES plus tard, LLM optionnel).

v0.1.0(9mo ago)01[19 issues](https://github.com/Mlucas44/invoiceiq-bundle/issues)MITPHPPHP &gt;=8.3CI passing

Since Sep 26Pushed 9mo agoCompare

[ Source](https://github.com/Mlucas44/invoiceiq-bundle)[ Packagist](https://packagist.org/packages/mlucas/invoiceiq-bundle)[ RSS](/packages/mlucas-invoiceiq-bundle/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (2)Versions (3)Used By (0)

[![CI](https://github.com/Mlucas44/invoiceiq-bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/Mlucas44/invoiceiq-bundle/actions/workflows/ci.yml)

InvoiceIQBundle (v0.1)
======================

[](#invoiceiqbundle-v01)

Bundle Symfony **plug-and-play** pour **analyser et valider des factures** (PDF/JPG/PNG/TXT).
v0.1 = MVP : OCR *stub* → parsing texte → pipeline de vérifications (Totaux / TVA / Doublons) → **endpoint HTTP** qui renvoie un **JSON contract**.

---

Sommaire
--------

[](#sommaire)

- [InvoiceIQBundle (v0.1)](#invoiceiqbundle-v01)
    - [Sommaire](#sommaire)
    - [Pourquoi](#pourquoi)
    - [Installation](#installation)
    - [Configuration minimale](#configuration-minimale)
    - [Utilisation (HTTP)](#utilisation-http)
    - [Contrat JSON](#contrat-json)
    - [Événements (pre\_validate / post\_validate)](#%C3%A9v%C3%A9nements-pre_validate--post_validate)
    - [Exemple de subscriber](#exemple-de-subscriber)
    - [Stockage optionnel (OFF par défaut)](#stockage-optionnel-off-par-d%C3%A9faut)
    - [Troubleshooting](#troubleshooting)
    - [Versionning &amp; licence](#versionning--licence)

---

Pourquoi
--------

[](#pourquoi)

- Extraire rapidement les champs clés (numéro, date, devise, totaux).
- Enchaîner des **contrôles** (cohérence des totaux, format de TVA plausible, détection de doublons basés sur le hash).
- Obtenir un **rapport JSON** normalisé (status / score / fields / issues).

---

Installation
------------

[](#installation)

```
composer require mlucas44/invoiceiq-bundle:^0.1
```

Ajoutez les routes du bundle (si non importées automatiquement) :

```
# config/routes/invoiceiq.yaml (APP HÔTE)
invoiceiq:
  resource: '@InvoiceIQBundle/Resources/config/routes.yaml'
  prefix: /
```

Configuration minimale
----------------------

[](#configuration-minimale)

Clé racine : invoice\_iq.

```
# config/packages/invoice_iq.yaml
invoice_iq:
  ocr:
    provider: 'tesseract'          # v0.1 utilise un stub (aucun appel binaire)
  checks:
    totals: true                   # vérifie HT + Taxe = TTC (avec tolérance)
    duplicates: true               # détection doublons via hash mémoire
    vat_format: true               # vérif heuristique du format TVA
  totals_tolerance: 0.01           # tolérance d’arrondi (ex: 1 centime)
  storage:
    enabled: false                 # OFF par défaut (voir section Stockage)
```

MIME types acceptés v0.1 : application/pdf, image/png, image/jpeg, text/plain.

Utilisation (HTTP)
------------------

[](#utilisation-http)

Endpoint : POST /\_invoiceiq/validate (multipart, champ file)

cURL

```
curl -F "file=@/chemin/vers/facture.pdf" http://127.0.0.1:8000/_invoiceiq/validate
```

Postman

- Méthode POST
- URL : [http://127.0.0.1:8000/\_invoiceiq/validate](http://127.0.0.1:8000/_invoiceiq/validate)
- Body → form-data → clé file (type File) → choisissez un fichier

Contrat JSON
------------

[](#contrat-json)

```
{
  "status": "ALERT",          // "OK" | "ALERT" | "REJECT"
  "score": 75,                // 0..100 (diminue avec les issues)
  "fields": {
    "invoice_number": "F2025-001",
    "date": "2025-09-01",
    "currency": "EUR",
    "vat_number": "FR12345678901",
    "totals": { "ht": 98.76, "tax": 19.75, "ttc": 118.51 }
  },
  "issues": [
    { "code": "TOTALS_MISMATCH", "severity": "error", "message": "Totaux incohérents ..." }
  ],
  "source_file_hash": "1f9f13f2cf2bba5a7731...",   // SHA-256 de l’original
  "storage_key": "2025/09/01/abcd1234.pdf"         // présent si storage.enabled = true
}
```

- status/score : agrégés par la pipeline de checks.
- issues\[\].severity : "warning" ou "error".

Événements (pre\_validate / post\_validate)
-------------------------------------------

[](#événements-pre_validate--post_validate)

Deux hooks Symfony pour étendre côté app hôte :

invoiceiq.pre\_validate

- Quand : juste avant le traitement.
- Payload (PreValidateEvent) :
    - originalFilename (string)
    - mimeType (string)
    - size (int)
    - sha256 (string|null)
    - receivedAt (DateTimeImmutable)

invoiceiq.post\_validate

- Quand : juste après le traitement.
- Payload (PostValidateEvent) :
    - invoice (Mlucas\\InvoiceIQBundle\\Domain\\Invoice)
    - report (Mlucas\\InvoiceIQBundle\\Domain\\ValidationReport)
    - durationMs (float)
    - sha256 (string|null)

Exemple de subscriber
---------------------

[](#exemple-de-subscriber)

```
