Communitygithub.com

OrrZwebner/remboursement-frais-conference

Prépare une demande de remboursement de frais de voyage pour une université israélienne après un déplacement à l'étranger pour une conférence : collecte les reçus du dossier de voyage et par e-mail, les enregistre au format PDF, et génère le tableur de dépenses en hébreu de droite à gauche.

Qu'est-ce que remboursement-frais-conference ?

Cette compétence est conçue pour les employés, chercheurs ou étudiants d'une université israélienne qui reviennent d'un déplacement à l'étranger pour une conférence et doivent soumettre une demande de remboursement de frais de voyage. Elle automatise le processus fastidieux de collecte des reçus (provenant d'un dossier local et de la messagerie électronique), de conversion en fichiers PDF nommés, et de création des deux fichiers tableur obligatoires (un pour la comptabilité, un pour usage interne) en hébreu de droite à gauche. La compétence intègre le taux de change représentatif de la Banque d'Israël, convertit toutes les devises en shekels, et suit un workflow structuré en 7 étapes : rassemblement des justificatifs, choix du mode de demande, sauvegarde des reçus, construction du tableur, vérification, rapport et rédaction du courriel. Elle fonctionne avec Claude Code, Cursor ou tout agent capable d'exécuter des scripts Python et d'accéder au système de fichiers local et à une boîte mail. L'utilisateur est guidé via des questions posées par l'agent, et la sécurité des données bancaires est assurée (fichier de profil local non versionné).

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/OrrZwebner/conference-reimbursement/tree/HEAD/skills/conference-reimbursement

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Remboursement des frais de conférence

Produire deux tableurs à partir des mêmes lignes, avec les mêmes totaux, et enregistrer chaque reçu cité dans <dossier conférence>/החזרים/קבלות/ :

  • Fichier ENVOYÉ <dossier conférence>/החזרים/<nom complet> הוצאות.xlsx — le seul fichier qui part à la comptabilité. Colonne B סעיף = catégorie du budget ; feuille des reçus ; bloc bancaire ; taux de change. Pas de comparaison budget-vs-réel.
  • Fichier INTERNE <dossier conférence>/החזרים/<nom complet> הוצאות - פנימי.xlsx — la copie locale de l'utilisateur, jamais jointe ni envoyée. Colonne B השירות = nature de chaque élément (ex. "קפה", "רכבת שדה–עיר"), une colonne סעיף après הערות, et le tableau de comparaison budgétaire.

Les deux sont en hébreu et en écriture de droite à gauche ; parlez à l'utilisateur en anglais. La mise en page provient du modèle intégré assets/claim-template.xlsx (étiquettes seulement) ; l'utilisateur ne fournit jamais de tableur.

Profil (nom complet et coordonnées bancaires). Lire ~/.config/conference-reimbursement/profile.json ({"full_name": "...", "bank": {"בנק": "...", "סניף": "...", "מספר חשבון": "..."}}). S'il manque ou est incomplet, demandez les champs manquants avec l'outil AskUserQuestion (l'utilisateur saisit les valeurs comme sa propre réponse), puis enregistrez le fichier avec les droits 600. Conservez-le uniquement là — en dehors de tout dépôt ou dossier de projet. Ne le commitez jamais, n'imprimez jamais les coordonnées bancaires dans la conversation ou le rapport (dites "coordonnées bancaires : depuis le profil"), et copiez-les uniquement dans la clé bank du scratchpad.

Posez chaque question à l'utilisateur via l'outil AskUserQuestion — jamais en prose — une décision par question, option recommandée en premier.

Choisir le mode

  • Mode A — demande complète. Le formulaire budgétaire approuvé (PDF), les coordonnées bancaires (profil), le dossier des reçus et l'accès à la boîte mail sont tous disponibles. Exécutez les étapes 1–7.
  • Mode B — saisies partielles. Un ou plusieurs de ces éléments manquent. Exécutez les mêmes étapes et omettez l'élément manquant, ne l'inventez jamais :
    • l'utilisateur refuse de fournir les coordonnées bancaires → omettre bank ; le script écrit des cellules vides étiquetées et avertit "coordonnées bancaires manquantes — remplir à la main" ; le signaler ;
    • pas d'accès à la boîte mail → utiliser uniquement les fichiers que l'utilisateur place dans קבלות/ ; signaler que la messagerie n'a pas été consultée ; à l'étape 7, imprimer le corps du courriel au lieu de le rédiger ;
    • pas de formulaire budgétaire → omettre budget ; le fichier INTERNE est construit sans tableau budgétaire et il n'y a pas de comparaison avec les montants approuvés.

Listez chaque lacune du Mode B dans le rapport sous "à compléter à la main".

1. Rassembler les entrées (lecture seule)

  1. Budget approuvé. Ouvrez le formulaire budgétaire PDF dans le dossier de la conférence (*טופס נסיעות*). Lisez-le vous-même ; les formulaires diffèrent selon les institutions. Enregistrez chaque ligne approuvée en USD (per diem אש״ל, vol טיסה, hôtel, assurance, inscription, autres) ainsi que les dates du voyage.
  2. Profil. Chargez le nom complet et les coordonnées bancaires comme décrit ci-dessus (demandez uniquement la première fois).
  3. Reçus physiques. Listez קבלות/ et lisez chaque image (convertissez d'abord HEIC, étape 3). Enregistrez la date, le fournisseur, le montant, la devise, les quatre derniers chiffres de la carte et le nombre de convives.
  4. Reçus par e-mail. Recherchez dans la boîte mail sur la période allant de la date de réservation à la date de retour plus environ deux semaines, ainsi que le label ou dossier de voyage de l'utilisateur. Exécutez les requêtes par catégorie ensemble en un seul tour — lisez d'abord references/email-sources.md. Cherchez au-delà de ce que l'utilisateur a listé : trouver des dépenses non remarquées fait partie du travail ; proposez chaque élément trouvé.
  5. Exclure les autres voyages. Ouvrez chaque virement financier et chaque réservation de vol dans la fenêtre et faites correspondre la conférence, l'itinéraire et les dates. Enregistrez chaque exclusion pour le rapport.

2. Demander les décisions de politique

Ne demandez que celles qui s'appliquent, une décision par question, option recommandée en premier. Ces valeurs par défaut proviennent d'une précédente demande ; ce sont des suggestions, pas des règles institutionnelles.

  • Réservation d'hôtel partagée → propre chambre uniquement (Recommandé) / réservation entière.
  • Repas partagés → addition complète / juste sa part. Signalez le choix au comptable.
  • Taux de change → taux représentatif de la Banque d'Israël du jour de retour, un taux par devise (Recommandé) / le taux de chaque date de reçu.
  • Éléments partagés (une facture d'affiche couvrant deux personnes) → réclamer la part de l'utilisateur, avec une note.
  • Suppléments achetés avec le vol (siège, bagage, assurance) → dans la ligne du vol (Recommandé).

3. Enregistrer les reçus en PDF

  1. Pièces jointes des e-mails. Si le connecteur mail renvoie le texte du message mais pas les pièces jointes, vérifiez d'abord s'il peut désormais les récupérer ; sinon, téléchargez via l'automatisation du navigateur (ouvrez le message, cliquez sur l'icône de téléchargement de la pièce jointe, puis déplacez le fichier depuis ~/Downloads). Sans automatisation du navigateur, demandez à l'utilisateur de les télécharger ou de les glisser-déposer dans קבלות/.
  2. E-mails sans pièce jointe (confirmations de commande) → imprimer en PDF.
  3. Nommez chaque fichier <quoi> <fournisseur> <numéro de document>.pdf, en hébreu.
  4. Photos HEIC → ajoutez une copie PDF à côté de l'original, ne modifiez jamais l'original. macOS : sips -s format pdf IN.heic --out IN.pdf. Ailleurs, utilisez Pillow avec pillow-heif si installé, sinon demandez à l'utilisateur d'exporter la photo au format PDF ou JPEG. Pour la feuille des reçus du tableur, convertissez également chaque photo et capture d'écran en JPEG nommé d'après le nom de base de son reçu, dans le scratchpad (jamais sur l'original) : sips -s format jpeg -s formatOptions 70 -Z 1400 IN --out "<nom de base du reçu>.jpg".
  5. Lisez chaque PDF enregistré. Prenez le montant sur le document, pas dans le texte de l'e-mail. S'ils diffèrent, utilisez le document et signalez la différence.

4. Construire le tableur

  1. Récupérez les taux représentatifs de la Banque d'Israël (boi.org.il) pour la date choisie pour chaque devise étrangère utilisée. Mettez la date dans rates.label : שער יציג בנק ישראל, <dd.mm.yyyy>. Ne réutilisez jamais un taux de mémoire ou d'une précédente demande.

  2. Écrivez le JSON de spécification dans le scratchpad. Schéma, mise en page et comportement Mode B : references/spec-format.md ; exemple de travail synthétique : references/example-spec.json. Définissez bank depuis le profil. Laissez template de côté : le modèle intégré est le modèle par défaut.

  3. Règles de lignes :

    • une ligne par reçu, triée par date ;
    • le montant dans exactement une clé : sa devise d'origine (usd, eur, ou un code supplémentaire présent aussi dans rates) ou ils ;
    • receipt = nom(s) de fichier de base dans קבלות/, plusieurs joints par + ;
    • note explique tout ce qu'un comptable pourrait questionner (facture partagée, demi-facture, élément extrait d'une facture d'hôtel) ;
    • line = un nom de ligne budgétaire orthographié exactement comme dans budget ; la colonne B du fichier ENVOYÉ l'affiche (catégorie uniquement, jamais "café" ou "dîner" — les comptables voient les catégories d'approbation), et la colonne סעיף du fichier INTERNE et le tableau budgétaire l'utilisent ;
    • service = une courte description en hébreu de l'élément ("קפה", "ארוחת ערב", "רכבת שדה–עיר") ; affichée uniquement dans la colonne B du fichier INTERNE (omise → la catégorie est affichée) ;
    • les repas, y compris le dîner de conférence → la ligne per diem ;
    • les frais de restaurant sur une facture d'hôtel → leur propre ligne de repas, le montant de l'hôtel réduit.
    • receipt_images = les JPEG de l'étape 3 (uniquement les photos et captures d'écran de ce voyage). Ils vont sur la feuille קבלות, 5 par ligne, chacun avec une cellule de légende contenant le nom de base du fichier. Les PDF reçus par e-mail ne sont pas intégrés ; ils vont dans le zip à l'étape 7.
  4. Exécutez :

    python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/build_claim.py" spec.json
    

    Une exécution écrit les deux fichiers. Elle imprime du JSON avec output (ENVOYÉ), output_internal, total_ILS, total_USD et warnings. Corrigez chaque avertissement concernant les lignes budgétaires ; reportez les avertissements Mode B dans le rapport. output_internal par défaut est le chemin ENVOYÉ avec - פנימי avant .xlsx ; ne le définissez dans la spécification que pour placer la copie locale ailleurs.

  5. Le script refuse d'écraser l'un ou l'autre des fichiers de sortie sauf si "overwrite": true. Ne le définissez jamais sur un fichier que l'utilisateur a modifié à la main ; écrivez un nouveau nom ou demandez.

5. Vérifier

"Terminé" signifie exécuté et vérifié. Lisez d'abord references/pitfalls.md.

  1. Exécutez les vérifications :

    python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/check_claim.py" spec.json
    
    • total / total_internal : le total Python du script est égal à la cellule סה״כ בש״ח de chaque fichier après recalcul par LibreOffice (à 0,01 ₪ près), donc les deux fichiers portent le même total ;
    • sent_no_budget : le fichier ENVOYÉ ne contient pas de tableau de comparaison budgétaire ;
    • receipts : chaque fichier cité existe dans קבלות/ ;
    • budget : chaque ligne a une ligne budgétaire et le total réel du tableau budgétaire du fichier INTERNE est égal à total_ILS / taux USD.

    Signalez une vérification not_run comme non exécutée, jamais comme réussie.

  2. Audit indépendant : lancez un sous-agent avec uniquement le fichier ENVOYÉ et le dossier des reçus — pas vos conclusions. Demandez-lui de vérifier chaque ligne (montant, devise, date, fichier) par rapport au reçu et de lister tout ce qu'un comptable pourrait questionner. Corrigez les vraies erreurs ; rapportez le reste.

6. Rapport

Dans cet ordre :

  1. Les deux chemins (ENVOYÉ, à joindre ; INTERNE, local uniquement), nombre de lignes, total ₪ et ≈ USD par rapport au total approuvé.
  2. Reçus ajoutés (et lesquels ont été trouvés en cherchant au-delà de la liste de l'utilisateur).
  3. Taux de change utilisés, avec source et date.
  4. Lignes dépassant le budget, sous forme de tableau : ligne, approuvé, réel, différence.
  5. Écarts entre sources (e-mail versus document).
  6. Exclusions (éléments appartenant à d'autres voyages).
  7. Signaux pour le comptable (depuis references/pitfalls.md).
  8. À compléter à la main (lacunes Mode B, avertissements du script).
  9. Décisions prises sans demander.

7. Rédiger le courriel au responsable financier

Lisez d'abord references/email-draft.md ; suivez-le dans l'ordre. Utilisez et joignez uniquement le fichier ENVOYÉ (output, <nom complet> הוצאות.xlsx) ; ne joignez, ne téléchargez et ne citez jamais le fichier INTERNE - פנימי — email_summary.py le refuse. En bref :

  1. Lisez le précédent fil de demande de l'utilisateur avec le responsable financier (messages envoyés, environ deux ans en arrière, réponses incluses) et copiez son style et son modèle d'objet.
  2. Demandez : coordonnées bancaires incluses ou non ; lignes budgétaires ou taux (par défaut : aucun) ; CCI à un co-voyageur (par défaut : non ; n'inventez jamais d'adresse).
  3. scripts/zip_ereceipts.py spec.json → קבלות אלקטרוניות.zip des PDF de reçus électroniques (noms UTF-8 ; jamais la commande zip de macOS). Les photos et captures d'écran sont dans la feuille קבלות à la place.
  4. scripts/email_summary.py spec.json … → le corps HTML RTL ("היי ," / "מה שלומך? :)" … "תודה רבה!"), le tableau récapitulatif avec une colonne קבלה indiquant où se trouve chaque reçu, et les coordonnées bancaires lues depuis le tableur.
  5. Vérifiez que son total_ILS est égal à celui de la construction ; mentionnez tout rounding_diff.
  6. Gmail create_draft avec htmlBody d'abord. Ensuite, joignez le fichier ENVOYÉ et le zip via Claude dans Chrome (file_upload sur l'entrée de fichier de composition du brouillon) et confirmez les deux puces — le connecteur ne prend les pièces jointes qu'en base64 dans l'appel, et update_draft les abandonne. N'envoyez jamais. Donnez à l'utilisateur le lien vers le brouillon.

Formules

  • Ligne : ILS_i = montant_i × taux[cur_i], ou le montant en ₪ lui-même.
  • Total : T = Σ ILS_i ; en dollars T / taux[USD].
  • Par ligne budgétaire ℓ (fichier INTERNE) : réel_ℓ = Σ_{line_i = ℓ} ILS_i / taux[USD] ; diff_ℓ = approuvé_ℓ − réel_ℓ, négatif signifie dépassement de budget. Σ_ℓ réel_ℓ = T / taux[USD] quand chaque ligne de la spécification est dans le budget.

Exemple : taux USD 4,00, EUR 4,50 ; inscription 500 $, hôtel 600 €, taxi 200 ₪ → 2 000 + 2 700 + 200 = 4 900 ₪ = 1 225 $.

Décisions d'appréciation

  • La facture de l'hôtel prévaut sur la confirmation du site de réservation (c'est le document fiscal).
  • Les coordonnées bancaires proviennent du profil local dans la clé bank de la spécification ; le script les écrit par étiquette. Demandez-les uniquement via AskUserQuestion, jamais en prose, et ne les répétez jamais.
  • Un remboursement partiel antérieur appartenant à ce voyage → marquez ces lignes comme déjà réclamées.
  • Les règles de l'institution de l'utilisateur décident des questions de politique ; demandez plutôt que d'affirmer une règle.

Références

  • references/email-sources.md — requêtes mail par catégorie et quoi vérifier (étape 1.4).
  • references/spec-format.md — clés de spécification, mise en page des deux fichiers, sortie du script, comportement Mode B (étape 4).
  • references/example-spec.json — spécification complète synthétique (étape 4).
  • references/pitfalls.md — échecs déjà rencontrés et liste de vérification pour le comptable (étapes 5–6).
  • references/email-draft.md — le brouillon de courriel : fil précédent, formulation, pièces jointes (étape 7).

Skills associés