mlucas/invoiceiq-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mlucas/invoiceiq-bundle

最新稳定版本:v0.1.0

Composer 安装命令:

composer require mlucas/invoiceiq-bundle

包简介

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

README 文档

README

CI

InvoiceIQBundle (v0.1)

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

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

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

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)

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

cURL

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

Postman

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)

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

<?php
namespace App\Subscriber;

use Mlucas\InvoiceIQBundle\Event\PreValidateEvent;
use Mlucas\InvoiceIQBundle\Event\PostValidateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Psr\Log\LoggerInterface;

final class InvoiceIQSubscriber implements EventSubscriberInterface
{
    public function __construct(private LoggerInterface $logger) {}

    public static function getSubscribedEvents(): array
    {
        return [
            PreValidateEvent::NAME  => 'onPreValidate',
            PostValidateEvent::NAME => 'onPostValidate',
        ];
    }

    public function onPreValidate(PreValidateEvent $e): void
    {
        $this->logger->info('invoiceiq.pre_validate', [
            'name' => $e->getOriginalFilename(),
            'mime' => $e->getMimeType(),
            'size' => $e->getSize(),
            'hash' => $e->getSha256(),
        ]);
    }

    public function onPostValidate(PostValidateEvent $e): void
    {
        $this->logger->info('invoiceiq.post_validate', [
            'ms'     => $e->getDurationMs(),
            'hash'   => $e->getSha256(),
            'status' => $e->getReport()->getStatus(),
            'score'  => $e->getReport()->getScore(),
        ]);
    }
}

Stockage optionnel (OFF par défaut)

Active un stockage local de l’original (et ses métadonnées) + renvoie storage_key :

# config/packages/invoice_iq.yaml
invoice_iq:
  storage:
    enabled: true
    adapter: 'local'                                   # v0.1
    local_dir: '%kernel.project_dir%/var/invoiceiq'    # dossier cible
  • Si enabled: false : aucune écriture disque et pas de storage_key.

Troubleshooting

  • 400 – missing file : le champ file est absent.
  • 415 – unsupported media type : mimetype non supporté.
  • 200 + issues : parsing OK mais au moins une règle a levé une issue (TOTALS_MISMATCH VAT_FORMAT_SUSPECT, etc.).
  • Doublons : détection via store mémoire (hash SHA-256). v0.1 n’écrit pas encore en base.

Versionning & licence

  • Versionning : SemVer (MAJOR.MINOR.PATCH).
  • Licence : MIT.
  • Voir le CHANGELOG pour l’historique.

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-09-26