Organisation des justificatifs de remboursement d'entreprise
Transformez un ensemble de justificatifs bruts fournis par l'utilisateur en un livrable structuré, nommé conformément aux normes et directement remettable au service comptable : documents archivés par catégorie, tableau de frais détaillé rempli, notes explicatives supplémentaires pour la comptabilité et journal de bord traçable.
Trois règles intangibles
- Les documents originaux et les modèles ne sont jamais modifiés. Toutes les modifications concernent des sauvegardes et des copies des modèles.
- Ne jamais inventer d'informations. Les éléments illisibles, incohérents ou manquants sont placés dans une liste de doutes à demander à l'utilisateur. Il vaut mieux demander que d'inventer.
- Une dépense = une seule ligne dans le tableau, jamais de double comptabilisation. La facture et sa capture de paiement correspondent à la même dépense ; avant et après un changement de réservation correspondent au même trajet ; les frais déjà pris en charge par l'entreprise ne sont pas remboursés. Voir
references/regles_classement_nommage.mdsections 3.1–3.3 et 6.
Utilisez toujours
python3(beaucoup d'environnements n'ont pas d'aliaspython) ; les chemins des scripts sont relatifs à ce répertoire skill :scripts/....
Ce qu'il faut obtenir avant de commencer
- Le chemin du dossier contenant les documents bruts (peut contenir des fichiers jpg/png/pdf/ofd/excel dans divers formats, éventuellement des sous-dossiers).
- Le chemin du modèle de remboursement .xlsx.
- Les informations d'identité (nom, service, date de soumission, devise, service par défaut, code projet par défaut, avance de trésorerie).
- Vérifiez d'abord si le fichier
process_files/identity.jsonexiste déjà (sauvegardé lors de la précédente exécution). S'il existe, chargez-le et confirmez avec l'utilisateur s'il souhaite le réutiliser. - S'il n'existe pas ou est incomplet, demandez les champs manquants à l'utilisateur, puis écrivez-les dans
process_files/identity.jsonpour une utilisation ultérieure.
- Vérifiez d'abord si le fichier
Lisez references/regles_mapping_modele_champs.md avant de commencer pour connaître la signification des colonnes du modèle et les éléments obligatoires pour les motifs.
Trois comportements par défaut modifiables (l'utilisateur peut les changer d'un mot)
- Niveau d'autonomie (par défaut : demander seulement en cas de doute). Les éléments à haute confiance sont automatiquement classés ; les éléments ambigus (distinction entre transport interurbain et transport urbain, montants illisibles, dépenses personnelles suspectées, motifs incomplets) sont regroupés dans une liste de doutes et soumis en une fois à l'utilisateur. L'utilisateur peut aussi demander un mode entièrement automatique ou confirmation ligne par ligne.
- Informations d'identité (par défaut : demander la première fois, puis réutiliser). Voir ci-dessus.
- Devises multiples (par défaut : convertir en RMB pour le tableau). Les reçus en devises étrangères (USD/KRW, etc., comme les reçus Uber à l'étranger) sont convertis selon le taux de change fourni par l'utilisateur. Sans taux fourni, ne faites pas la conversion vous-même – placez d'abord ces éléments dans la liste de doutes pour les demander à l'utilisateur (ou utilisez le cours de la Banque de Chine à la date du reçu en indiquant la source). Le montant original en devise, le taux, le résultat et la devise d'origine doivent figurer dans un fichier texte sous
notes_explicatives/, et dans le journal de bord, les colonnes « Montant devise d'origine / Taux de change » doivent être renseignées. Vous pouvez aussi choisir de remplir le tableau en devise d'origine et laisser l'utilisateur gérer le taux.
Flux de travail
Étape 0 : Configuration de l'espace de travail + sauvegarde (script)
python3 scripts/setup_workspace.py --source <dossier_documents_bruts> [--out <racine_espace_travail>] [--template <modele_remboursement.xlsx>]
--outfacultatif : par défaut, un nouvel espace de travail avec un nom explicite<nom_dossier_original>_remboursement_<AAAAMMJJ>est créé à côté du dossier contenant les documents bruts (son répertoire parent = emplacement par défaut). Vous pouvez aussi spécifier un répertoire avec--out.--templatefacultatif : les modèles peuvent varier selon l'utilisateur, voire ne pas exister. Sans modèle, le flux « sans modèle » est utilisé (voir étape 6), etmake_default_table.pygénère un tableau de frais générique. Le script crée dix sous-dossiers (avec_facture/sans_facture/justificatifs/a_verifier/remplacement/notes_explicatives/process_files/sauvegarde/complements/hors_sujet), sauvegarde l'intégralité des documents bruts danssauvegarde/(les modèles et fichiers*.skillne sont pas considérés comme des documents et sont automatiquement ignorés), place une copie du modèle original danssauvegarde/_modele_original/et génère une copie modifiable<nom_original>_rempli.xlsx, et créeprocess_files/manifest.json. L'espace de travail est créé en dehors du dossier des documents bruts. Le résultat stdout renvoie les chemins clés (workspace/writable_template, ouwritable_templateest nul en l'absence de modèle). Tous les scripts sont enpython3pur, multi-plateforme (mac/linux/windows), sans dépendances système.
Étape 1 : Lecture et compréhension des documents un par un
Lisez les documents dans l'ordre du manifest.json, selon leur type :
- Images (jpg/png/webp, etc.) : utilisez directement la compréhension visuelle (ce modèle peut lire les images), pas besoin d'OCR d'abord. Extrayez : date de la dépense, marchand/projet, montant, s'il s'agit d'une facture officielle, lieu de départ/d'arrivée, nombre de personnes, etc.
- PDF : utilisez d'abord
extract-textou un skill de lecture PDF pour obtenir le texte. Pour les documents scannés ou les reçus formatés sans texte, convertissez-les en images puis lisez-les visuellement (référez-vous à la méthode de rasterisation du skill de lecture PDF). - OFD (facture électronique nationale) :
Si le texte n'est pas récupérable (OFD purement graphique), solution de repli : convertissez en image puis reconnaissance visuelle.python3 scripts/extract_ofd.py <fichier.ofd> --json- Billet de train électronique : lisez le « prix du billet » (montant remboursable en voyage normal) ou les « frais d'annulation/remboursement partiel » (annulation, montant faible) ; notez le marqueur « changement de réservation avant le départ ».
- Facture TVA : le montant à inscrire dans le tableau est le total TTC (taxe comprise), pas le montant HT (voir
references/regles_mapping_modele_champs.md).
- Excel/CSV : utilisez
extract-text fichier.xlsxou pandas pour lire, courant pour les relevés téléphoniques, les relevés de compte, les récapitulatifs. - Autres formats inconnus : utilisez d'abord
file <chemin>pour identifier le type, puis choisissez une méthode de lecture adaptée. Si la lecture est impossible, placez le document dans la liste de doutes.
Pour chaque document, écrivez les éléments extraits dans process_files/extracted/<nom_original>.json.
Étape 2 : Classement par dossier + catégorisation + association d'événements
Selon references/regles_classement_nommage.md :
- Déterminez dans quel dossier avec_facture / sans_facture / justificatifs le document doit être placé (voir section 1 du document de référence). Point clé : une dépense réelle avec seulement une capture d'écran et sans facture officielle va dans « sans_facture » (c'est la preuve principale), pas dans « justificatifs » (section 1.1). Un justificatif doit être accompagné de la preuve principale. Dès qu'un élément « sans_facture » apparaît, rappelez à l'utilisateur qu'il peut fournir des pièces de remplacement dans
remplacement/(voir « Répertoire spécial : remplacement/ »). - Déterminez à laquelle des 12 catégories de frais il appartient, puis à quelle colonne du modèle cela correspond (voir
references/regles_mapping_modele_champs.md). Notez la distinction entre J (transport interurbain) et Q (transport urbain). - Attribuez le même numéro d'événement à plusieurs documents d'une même dépense (facture + capture de paiement + bon de voyage + capture de remboursement sont liés au même événement). Les changements de réservation avant/pendant le voyage, les paiements par l'entreprise / par l'employé sont également liés au même événement (sections 3.1–3.3).
- Les éléments suspectés personnels/hors voyage (abonnements personnels, visas de pays sans rapport, reçus sans facture d'un montant élevé, etc.) sont placés dans la liste de doutes, par défaut non comptabilisés (section 5). Après confirmation de l'utilisateur qu'ils sont sans rapport/non-remboursables/hors période, déplacez-les dans
hors_sujet/(non comptabilisés dans cette période). - Ne forcez pas les éléments douteux : les documents dont le dossier/catégorie/remboursabilité est incertain doivent d'abord être placés dans
a_verifier/, pas directement dansavec_facture/ousans_facture/. Regroupez-les dans une liste de doutes et demandez à l'utilisateur, puis déplacez-les dea_verifier/vers le bon dossier après confirmation.
Étape 3 : Création du journal de bord (fichiers de processus)
Dans process_files/journal_materiel.csv (UTF-8-SIG), chaque document brut occupe une ligne. La structure des colonnes est définie à la section 4 de references/regles_classement_nommage.md. Le journal de bord est la seule source de données pour les étapes suivantes et le rapport d'audit – faites-le d'abord correctement.
Étape 4 : Copie + renommage + classement dans les dossiers
Copiez les documents de sauvegarde/ vers le dossier correspondant en les renommant selon la convention date_type_frais_info_cle_montant. Les documents du même événement dans différents dossiers portent le même nom ; dans le même dossier, ajoutez un suffixe sémantique (voir les règles dans le document de référence). Mettez à jour le journal de bord avec les nouveaux noms de fichiers.
Étape 5 : Rédaction de notes explicatives (si nécessaire)
Pour toute opération de regroupement, remboursement partiel, conversion de devise, partage/AA, ou lorsque le montant du document ≠ montant dans le tableau, rédigez un fichier txt selon references/regles_redaction_notes_explicatives.md dans notes_explicatives/, et indiquez-le dans la colonne « Remarques » du journal de bord.
Étape 6 : Journal de bord → dédoublement et rapprochement → génération du ledger → remplissage du modèle copié (script)
D'abord, dédoublement et rapprochement (section 6 de references/regles_classement_nommage.md) : pliez le journal de bord par numéro d'événement (une ligne par événement) – les factures/preuves principales « sans_facture » donnent le montant, les justificatifs et les captures de remboursement ne constituent pas une ligne à part ; les annulations ne comptent que les frais d'annulation ; les paiements par l'entreprise ne comptent que les avances personnelles ; convertissez les devises en RMB. Notez Σ(montant du ledger) comme base de rapprochement.
Tri par ordre chronologique : l'en-tête du modèle exige un « remplissage dans l'ordre chronologique ». Les éléments du ledger doivent être triés par date de la dépense croissante (plusieurs le même jour : d'abord les factures normales, puis les annulations/ajustements). fill_template.py trie également par défaut par mois/jour de manière stable (utilisez --no-sort pour conserver l'ordre que vous donnez).
Organisez ensuite dans process_files/ledger.json (structure : identity + items, chaque item a une « colonne » ou « catégorie » + montant + motif + lieu de départ/arrivée/service/code projet). Le motif doit inclure les éléments exigés par le service comptable selon references/regles_mapping_modele_champs.md. Puis :
python3 scripts/fill_template.py --xlsx <modele_modifiable> --ledger process_files/ledger.json
fill_template.py gère automatiquement l'insertion de lignes pour plus de 31 lignes et l'extension des sommes, et fournit dans son résultat computed les valeurs attendues des sous-totaux et du total par colonne – vérifiez d'abord leur cohérence avec votre base de rapprochement.
Recalculez ensuite les formules (au choix) :
# Option privilégiée : skill xlsx (nécessite LibreOffice)
python3 /mnt/skills/public/xlsx/scripts/recalc.py <modele_modifiable>
# Sans LibreOffice / si le chemin n'existe pas, utilisez le repli fourni par ce skill (--write écrit les valeurs, le livrable affiche les nombres directement) :
python3 scripts/recalc_fallback.py <modele_modifiable> --write
Assurez-vous que total_errors est à 0, et que le résultat du recalcul est cohérent avec computed de fill_template et avec la somme totale du journal de bord (les trois doivent être identiques).
Branche sans modèle : si l'utilisateur n'a pas de modèle, ignorez fill_template.py/recalc, et utilisez le script pour générer un tableau de frais générique (avec valeurs et totaux directement écrits, accompagné d'un aperçu .md) :
python3 scripts/make_default_table.py --ledger process_files/ledger.json --out <espace_travail>/<nom_explicite>.xlsx
Dans ce cas, ledger.json utilise une structure « version sans modèle » (voir les commentaires en haut de make_default_table.py : identity peut inclure titre/nom du remboursé/service/etc., chaque item a date/catégorie/motif/marchand/devise/montant original/taux/montant (RMB)/remarques). Le total du xlsx généré doit correspondre à la somme du journal de bord.
Étape 7 : Rapport d'audit + livraison
Écrivez rapport_audit.md à la racine de l'espace de travail :
- Résumé par catégorie de frais, montant total à rembourser ;
- Vérification de cohérence : somme du journal de bord = total du modèle = somme des montants des documents dans chaque dossier (énumérez chaque élément, signalez en rouge toute incohérence) ;
- Liste des doutes : éléments nécessitant un complément d'utilisateur (nombre de convives, jours de déplacement, taux de change, montants illisibles, dépenses personnelles suspectées, etc.) ;
- Nombre de fichiers par dossier, liste des notes explicatives.
Placez
<modele_modifiable>en premier (utilisez un outil de présentation commepresent_filessi disponible, sinon donnez le chemin de l'espace de travail et la liste des fichiers), présentez le tout à l'utilisateur avec le rapport d'audit, et posez-lui les questions de la liste de doutes en face-à-face.
Répertoires spéciaux (traités au besoin, aucun n'affecte le flux principal de rapprochement)
En plus du flux principal 0–7, quatre répertoires sont activables selon les besoins ; ils sont indépendants et n'affectent pas le journal de bord ni le rapprochement des dossiers avec_facture/, sans_facture/, justificatifs/.
a_verifier/ — Placez ici les éléments douteux en attente
Les documents dont le classement (dossier, catégorie, remboursabilité) est incertain doivent d'abord être placés dans a_verifier/, jamais directement dans avec_facture/ ou sans_facture/. Regroupez-les dans une liste de doutes et demandez à l'utilisateur en une seule fois. Une fois que l'utilisateur a tranché, déplacez-les de a_verifier/ vers le bon dossier et intégrez-les dans la comptabilité. Idéalement, a_verifier/ doit être vide au moment de la livraison ; si des éléments restent en suspens, mentionnez-les dans le rapport d'audit.
hors_sujet/ — Éléments sans rapport / non remboursables cette période / hors période
Les documents qui, après confirmation de l'utilisateur, sont sans rapport avec le remboursement en cours, non remboursables cette période ou hors période (billet d'avion pour une autre période, visa sans rapport avec ce voyage, etc.) sont copiés de la sauvegarde vers hors_sujet/ pour être conservés séparément, non comptabilisés dans le journal de bord ni le modèle de cette période ; le rapport d'audit mentionne « déplacé vers hors_sujet ». Cela évite de fausser le rapprochement tout en ne perdant aucun document.
remplacement/ — Répertoire de pièces de remplacement (optionnel, non transférées dans avec_facture, non comptabilisées)
Certains éléments « sans_facture » sont des dépenses réelles sans facture officielle (frais d'électricité du logement de l'entreprise, remboursements ponctuels personnels, etc.). Le client peut, en option, fournir des factures officielles d'autres consommations courantes à placer dans remplacement/, pour couvrir approximativement le montant des éléments « sans_facture » et fournir des factures au service comptable – mais il peut aussi ne pas en fournir.
Point crucial : les pièces de remplacement ne sont pas des factures réelles correspondant une à une aux éléments sans facture ; leurs montants sont simplement proches. Donc :
- Les pièces de remplacement ne sont jamais transférées dans
avec_facture/, et les éléments « sans_facture » ne sont jamais reclassés comme « avec facture » – ils restent gérés comme « sans_facture » (c'est l'enregistrement de cette dépense réelle). - Les pièces de remplacement restent dans
remplacement/et sont fournies séparément au service comptable, elles n'entrent pas dans les lignes du journal de bord, ne sont pas incluses dans le montant total à rembourser (sinon elles seraient comptabilisées en double avec les éléments sans facture). - Seule une liste des pièces de remplacement et leur total poolé (dans
process_files/pool_remplacement.csv) est enregistrée, avec une comparaison approximative avec le total des éléments sans facture ; pas de correspondance 1:1, pas de changement de dossier, pas de modification du ledger. - Dès qu'un élément « sans_facture » apparaît, rappelez à l'utilisateur (en option) qu'il peut fournir des pièces de remplacement (listez les éléments sans facture et leur montant total, en précisant « facultatif »). Ne forcez pas la recherche de pièces de remplacement, ne supposez pas que l'utilisateur en fournira.
complements/ — Documents complémentaires fournis ultérieurement par le client (traités puis vidés)
Les documents complémentaires (factures manquantes, reçus oubliés) sont placés dans complements/. Lors de l'exécution suivante, traitez-les comme suit, après traitement, complements/ doit être vidé :
- Sauvegarde : copiez chaque document dans
sauvegarde/_complement_<date>/(les originaux ne sont pas perdus). - Compréhension + association d'événement : utilisez la méthode de l'étape 1 pour les identifier, attachez-les à un événement existant ou créez un nouvel événement.
- Ajout de facture : pour un élément initialement « sans_facture (facture à obtenir) », une fois la facture officielle obtenue – la facture va dans
avec_facture/, la capture d'écran originale est reclassée dansjustificatifs/, le dossier/confiance/montant (TTC) de l'événement dans le journal de bord sont mis à jour, et l'élément de doute correspondant est supprimé. - Réexécution du dédoublement/rapprochement + remplissage : recalculez selon l'étape 6, vérifiez que le total est mis à jour et que les trois sources sont toujours cohérentes.
- Vidage de
complements/: supprimez les fichiers après traitement (les sauvegardes et les copies dans les dossiers existent déjà), gardez le dossier vide pour la prochaine fois.
Structure finale du répertoire après achèvement
<espace_travail>/
├── <nom_original>_rempli.xlsx ← Tableau de frais détaillé rempli (livrable)
├── rapport_audit.md
├── avec_facture/ Documents avec facture officielle, pouvant servir de preuve indépendante (placés ici après confirmation)
├── sans_facture/ Preuves principales de dépenses réelles sans facture officielle (placées ici après confirmation)
├── justificatifs/ Pièces justificatives secondaires (captures de commande/paiement/voyage)
├── a_verifier/ Éléments douteux (dossier/catégorie/remboursabilité) placés ici en attente, pas directement dans avec_facture/sans_facture ; déplacés après vérification
├── remplacement/ Pool optionnel de pièces de remplacement : approximativement couvrir le montant des sans_facture pour la comptabilité, non transférées dans avec_facture, non comptabilisées (voir « Répertoires spéciaux »)
├── notes_explicatives/ Fichiers txt à destination de la comptabilité (regroupement/remboursement/devise/partage)
├── process_files/ identity.json, manifest.json, extracted/, journal_materiel.csv, ledger.json, (pool_remplacement.csv)
├── sauvegarde/ Sauvegarde 1:1 des documents bruts + _modele_original/ (modèles et *.skill ne sont pas inclus dans la sauvegarde des documents)
├── complements/ Documents complémentaires fournis ultérieurement par le client ; vidé après traitement (voir « Répertoires spéciaux »)
└── hors_sujet/ Documents sans rapport / non remboursables cette période / hors période, conservés séparément, non comptabilisés
Vérification finale
- Les documents originaux et le modèle original n'ont pas été modifiés (seules les sauvegardes/copies ont été touchées)
- Chaque document a été placé dans un dossier et figure sur une ligne du journal de bord
- Pas de double comptabilisation : chaque numéro d'événement n'apparaît qu'une seule fois dans le ledger ; les factures + captures de paiement, les changements de réservation avant/pendant, les remboursements n'ont pas été comptés comme plusieurs lignes
- Les factures TVA sont inscrites TTC ; les annulations ne comptent que les frais d'annulation ; les paiements par l'entreprise ne comptent que les avances personnelles
- Les devises étrangères ont été converties avec un taux ayant une source (ou listées comme douteuses)
- Le modèle est rempli dans l'ordre chronologique ; après recalcul, aucune erreur de formule, et total du modèle = somme du ledger =
computeddefill_template - Les motifs respectent tous les exigences de commentaire correspondantes (nombre de personnes/période/lieu de départ-arrivée/nombre de jours, etc.)
-
a_verifier/est vide (tout a été décidé) ;complements/est vide ;remplacement/(le cas échéant) n'est pas comptabilisé - Les éléments suspectés personnels/sans rapport et autres doutes ont tous été confirmés en face à face avec l'utilisateur