Install
openclaw skills install e-facture-rapprochementIngère les FACTURES (Factur-X / UBL / CII en fast-path, et surtout les PHOTOS DE TICKETS DE CAISSE et PDF par extraction LLM avec score de confiance) ET les RELEVÉS BANCAIRES (CAMT.053 / OFX / CSV), puis RAPPROCHE paiements ↔ factures et écrit company.json + rapprochement.json au contrat Pocket-Claw. Déclenche ce skill dès qu'il s'agit de rapprochement bancaire, de lettrage, de matcher des paiements avec des factures, d'ingérer des tickets/factures/relevés pour la compta, de produire rapprochement.json, ou de repérer les factures impayées / paiements orphelins / opérations injustifiées d'un client — même si l'utilisateur ne dit pas explicitement « rapprochement ». Le vrai travail est fait par scripts/main.py ; ne réimplémente jamais le moteur à la main et n'écris jamais le JSON à la main.
openclaw skills install e-facture-rapprochemente-facture-rapprochementPipeline complet factures + banque → rapprochement → rapprochement.json, pour un ou
plusieurs clients. Cas d'usage dominant : photos de tickets de caisse et PDF côté
factures, exports bancaires (CSV/CAMT/OFX) ou PDF côté banque.
Le moteur est dans
scripts/main.py: ingestion (invoice_parsers.py,bank_parsers.py) + extraction LLM des pièces non structurées. Le RAPPROCHEMENT lui-même est délégué au moteur unique et audité du skillrapprochement-paiements(⑤) — un seul moteur pour les deux skills, donc des sorties identiques à entrées identiques (politique conservatrice unique : « payé » seulement sur montant serré, exclusions prudentes). Ce skill = comment le lancer + faire l'extraction LLM + rendre compte. Ne réimplémente pas le rapprochement et n'écris jamaisrapprochement.jsonà la main : le format est contractuel (le backend l'ignore en silence s'il est malformé → le client perd ses données).main.pygarantit le format et l'invariant. (reconcile.pyreste présent pour ses tests unitaires mais n'écrit plus la sortie.)
references/invoice-extraction.md.references/bank-formats.md.rapprochement-paiements) :
match montant + (référence/contrepartie/date), jamais le montant seul ; non matché →
unmatched_bank_lines ; non facturable (salaires, impôts, frais bancaires, retraits…) →
excluded_bank_lines. Politique conservatrice. Voir references/matching-rules.md.company.json + rapprochement.json, invariant vérifié. Voir
references/output-contract.md.<root>/<slug>/invoices|factures/ → factures (pdf, jpg, png, xml…)
<root>/<slug>/bank|releves|banque/ → relevés (xml CAMT, ofx, csv, pdf…)
<root>/<slug>/company.json → identité (optionnel ; sert à déduire achat/vente)
<root> par défaut = sandbox ~/.openclaw/workspace/clients-test/ (pour ne pas écraser
d'autres sorties pendant la mise au point). Ajoute --real pour viser le vrai
~/.openclaw/workspace/clients/. Slug = minuscules-à-tirets ; dossiers _* ignorés.
Les tickets/PDF passent par TON extraction LLM, donc le run se fait en deux passes.
Passe 1 — lancer le moteur :
python3 scripts/main.py [<root>] [--client <slug>] [--today AAAA-MM-JJ]
Le script ingère tout ce qui est structuré. S'il reste des documents non structurés (photos,
PDF sans XML), il s'arrête et imprime une worklist : pour chacun, un chemin sidecar
où écrire le JSON extrait.
Passe 2 — extraire puis relancer : Pour CHAQUE entrée de la worklist :
mode=text → couche texte via pdftotext -layout ; mode=vision →
lis l'image).references/invoice-extraction.md pour une facture,
references/bank-formats.md pour un relevé), avec un confidence honnête.sidecar indiqué (<doc>.<ext>.invoice.json ou .bank.json).Puis relance la même commande. Quand la worklist est vide, main.py rapproche, écrit les
2 fichiers, et imprime l'auto-contrôle. Les sidecars sont un cache : un doc déjà extrait
n'est pas redemandé.
Lis l'auto-contrôle et relaie au comptable un tableau lisible par client : factures
payées / en attente / partielles / en retard, paiements orphelins et factures manquantes,
relances. Mets en avant les factures listées pour validation humaine (_review.json :
montant élevé ou extraction peu sûre) — un humain doit les confirmer. Jamais de chemins
techniques bruts.
rapprochement.json/company.json à la main ;
laisse main.py le faire (écriture atomique, snake_case exact). Pas de champ blocking
(supprimé du produit).rappr + unmatched + excluded == bank_transactions_count (aucune transaction oubliée).
main.py l'affiche (OK/KO) et sort en erreur si une période est KO — ne termine pas
sur un KO ni sur un JSON invalide.confidence:0.0 sans montant →
anomalie facture_illisible (pièce à re-fournir). Mieux vaut une anomalie qu'un faux chiffre.normalize.py :
HUMAN_REVIEW_AMOUNT, HUMAN_REVIEW_CONFIDENCE).--real, tout va dans clients-test/ ; on bascule sur le vrai
clients/ une fois validé.python3 scripts/test_reconcile.py # moteur (montants, dates, matching, invariant, TVA)
python3 scripts/test_e2e.py # bout-en-bout sur fixtures/ (UBL+CII+CAMT+CSV+ticket)
Ce skill produit seulement company.json + rapprochement.json ; il ne touche ni au
backend, ni au front, ni aux e-mails. Il complète l'écosystème compta existant (voir README)
en se concentrant sur l'ingestion e-facture/ticket structurée + LLM.