Notes de frais non traitées (expenseClaim + toPrepare)

Identifie les notes de frais en attente de review en combinant correctement les filtres payableType et status. Évite les faux positifs liés à une mauvaise utilisation des filtres Spendesk.

↓ Télécharger le skill (.md)
78/100·📅 Hebdo·ExpertControllerFinance Analyst
RéconciliationExport ERPget_payables

🎯 But du skill

Identifie les notes de frais en attente de review en combinant correctement les filtres payableType et status. Évite les faux positifs liés à une mauvaise utilisation des filtres Spendesk.

📊 Ce que ça produit

Liste précise des notes de frais à traiter avec employé, montant, date et statut actuel.

⚡ Bénéfice

Avant

Filtre incorrect incluait d'autres types de payables, donnant des résultats parasites.

Après

Liste précise des seules notes de frais en attente, sans faux positifs.



# Instructions — Notes de frais non traitées (expenseClaim + toPrepare)

## ✅ Filtre composé AND : résolu (vérifié le 2026-07-22)

Un filtre `AND` combinant `payableType=expenseClaim` et `bookkeepingStatus=toPrepare` fonctionne désormais normalement — rejoué en direct, plus d'erreur `"Unable to get payables"`. Le filtre composé peut être utilisé directement, sans étape de post-filtrage.

```json
{
  "companyId": "...",
  "filters": {
    "operator": "and",
    "subfilters": [
      { "field": "payableType", "operator": "=", "value": ["expenseClaim"] },
      { "field": "bookkeepingStatus", "operator": "=", "value": ["toPrepare"] }
    ]
  },
  "pageSize": 100
}
```

Paginer si `meta.pagination.hasNextPage=true` (utiliser `cursor` pour la page suivante).

## ⚠️ Champ retourné : `bookkeepingStatus` (pas `state`)

Le payable retourné expose le statut comptable via `bookkeepingStatus` directement (vérifié en direct — aucun champ `state` dans la réponse) :
- `bookkeepingStatus: "toPrepare"` → non encore traité
- `bookkeepingStatus: "toExport"` → prêt pour l'ERP
- `bookkeepingStatus: "exported"` → déjà exporté

## Approche alternative (filtre simple + post-filtrage)

Si l'on préfère éviter le filtre composé (par ex. pour réutiliser un seul filtre sur plusieurs cas d'usage) :

### Option A — Filtrer par payableType, post-filtrer par bookkeepingStatus

```json
// Appel 1 : get_payables avec payableType seulement
{
  "companyId": "...",
  "filters": { "field": "payableType", "operator": "=", "value": ["expenseClaim"] },
  "pageSize": 100
}
```
→ Post-filtrer côté client : `payables.filter(p => p.bookkeepingStatus === "toPrepare")`

### Option B — Filtrer par bookkeepingStatus, post-filtrer par payableType

```json
// Appel 1 : get_payables avec bookkeepingStatus seulement
{
  "companyId": "...",
  "filters": { "field": "bookkeepingStatus", "operator": "=", "value": ["toPrepare"] },
  "pageSize": 100
}
```
→ Post-filtrer côté client : `payables.filter(p => p.payableType === "expenseClaim")`

**Option B préférée** quand le nombre total de `toPrepare` est faible — la liste `toPrepare` est généralement plus petite que la liste totale des notes de frais.

## Champs clés du payable expenseClaim

| Champ | Type | Description |
|-------|------|-------------|
| `id` | string | ID unique de la note de frais |
| `bookkeepingStatus` | string | Statut comptable : `toPrepare` \| `toExport` \| `exported` |
| `payableType` | string | `"expenseClaim"` |
| `memberId` | string | ID de l'employé demandeur (= `counterparty.memberId`) |
| `description` | string | Description de la dépense |
| `amount` | {amount, currency, precision} | Montant total (coefficient entier, diviser par 10^precision) |
| `spendingAmount` | {amount, currency, precision} | Montant dans la devise d'origine (peut différer de `amount`) |
| `spendingCurrency` | string | Devise de la dépense originale (peut être MAD, GBP, USD, etc.) |
| `functionalAmount` | {amount, currency, precision} | Équivalent en devise fonctionnelle (EUR) |
| `itemLines[].analyticalFieldAssociations` | array | Cost center assigné + champs analytiques |
| `allocations[].amount` | amount | Montant déjà remboursé à l'employé |
| `documentaryEvidence.validity.valid` | bool | Justificatif valide |
| `creationDate` | ISO datetime | Date de la dépense déclarée |
| `firstCreatedAt` | ISO datetime | Date d'entrée dans Spendesk |

## ⚠️ Cas de devises multiples

Une note de frais peut être en devise locale (MAD, GBP, USD…) :
- `spendingCurrency` = devise de la dépense
- `currency` = `functionalCurrency` = EUR (en général)
- `spendingExchangeRate` = taux de conversion appliqué
- Toujours utiliser `functionalAmount` pour des comparaisons EUR

Exemple réel :
```json
{
  "currency": "EUR",
  "spendingCurrency": "MAD",
  "functionalExchangeRate": 1,
  "spendingExchangeRate": 10.8821,
  "amount": { "amount": 1213, "currency": "EUR", "precision": 2 },
  "spendingAmount": { "amount": 13200, "currency": "MAD", "precision": 2 }
}
// Dépense de 132.00 MAD = 12.13 EUR
```

## ⚠️ allocations présentes même sur toPrepare

Les notes de frais `toPrepare` ont souvent des `allocations[]` non vides — le remboursement à l'employé (paiement) est déjà effectué, mais la pièce n'a pas encore été validée pour export ERP. Paiement ≠ export comptable.

## Exemple live (données réelles, 20 premières notes de frais sans filtre de statut)

Sur les 20 premières `expenseClaim` retournées :
- 11 en `toPrepare` (à traiter)
- 9 en `exported` (déjà en compta)
- `hasNextPage: true` → il en existe davantage

Exemples `toPrepare` :
| Description | Montant | Requérant |
|-------------|---------|-----------|
| "Dinner" | 14,10 EUR | `__zal3grncttvu` |
| "Billet de train aller 08/01/2023" | 84,00 EUR | `-8zlmfu9gm8-ag` |
| "flight to Berlin Feb 21st 2022" | 248,67 EUR | `HJHszqYeW` |
| "Spendesk Connect 2022" | 69,00 EUR | `9a74l4w9ams5lv` |
| "Breakfast for Raji and I" | 12,13 EUR (= 132 MAD) | `-88mp0xaj8r_r_` |

## Exemple de prompts

- "Liste les notes de frais en attente de review" → filtre composé payableType=expenseClaim AND bookkeepingStatus=toPrepare
- "Quelles notes de frais dois-je traiter avant la clôture ?" → bookkeepingStatus=toPrepare + post-filtrage payableType=expenseClaim
- "Notes de frais en devises étrangères non exportées" → expenseClaim + toPrepare + spendingCurrency != EUR
- "Montant total des NDF en attente" → sum(functionalAmount) sur expenseClaim où bookkeepingStatus=toPrepare

Comment installer ce skill

/
  1. 1
    Télécharger le fichier s11-expense-claims-toPrepare.md via le bouton ci-dessus.
  2. 2
    Placer le fichier dans le répertoire .claude/ de votre projet (ou ~/.claude/ pour une installation globale).
    cp s11-expense-claims-toPrepare.md .claude/s11-expense-claims-toPrepare.md
  3. 3
    Utiliser dans Claude Code — le skill est automatiquement découvert. Décrivez votre besoin en langage naturel et Claude appliquera les instructions du skill.
💡 Assurez-vous que le MCP Spendesk est configuré dans votre .claude/settings.json avec les outils get_payables.

Skills similaires

★ Top
95/100·🔍 Ponctuel·Expert

Auditer la couverture du MCP

Sonde tous les outils MCP disponibles, re-évalue la couverture des 50 cas d'usages persona, détecte les nouveaux champs ou outils, et régénère le rapport d'analyse des gaps.

CFOControllerAP Manager
90/100·📅 Hebdo·Débutant

Demandes de carte via get_requests

Explique comment utiliser get_requests pour les demandes de carte et pourquoi les remboursements de frais n'y apparaissent pas. Évite une source de confusion fréquente entre deux workflows distincts.

ControllerFinance Analyst
90/100·🔍 Ponctuel·Intermédiaire

Cost centers actifs vs archivés

Distingue les centres de coût actifs des archivés via le bon usage de get_cost_centers. Évite le piège de la convention de nommage isArchived vs isActive qui est contre-intuitive.

ControllerFinance Analyst

Interested in AI Agent services or Custom Integrations?