# Plan: Kostenplaatsen Bulk Update Tool
## Analyse Resultaten
### Huidige Situatie
- **360 inkoopfacturen** in 2025
- **Alle steekproef-boekingen** hebben `kostenplaats: null`
- Waarschijnlijk **0% heeft een kostenplaats** (of zeer weinig)
### Beschikbare Kostenplaatsen
| Nr | Naam | ID |
|----|------|-----|
| 1 | Platformen | `d5377eec-384b-4046-b64f-48d0eed25deb` |
| 2 | Soulbatical | `aa5d656e-109a-4a5f-97d5-38fa9a186e70` |
| 3 | Vibe Coding Academy | `c4c306a2-dde4-4c7e-adbf-b34c92c1cec6` |
| 4 | Business Coaching | `152c4a52-e6e5-4c69-beed-a22c05777b9c` |
| 5 | Holding Algemeen | `45986119-9f73-41d9-b1f7-72ceebaed743` |
### Leverancier → Kostenplaats Mapping (uit booking-rules.json)
| Leverancier | Kostenplaats |
|-------------|--------------|
| Lulu | Soulbatical |
| Anthropic | Soulbatical |
| OpenAI | Soulbatical |
| Cursor | Soulbatical |
| Supabase | Soulbatical |
| Netlify | Soulbatical |
| GitHub | Soulbatical |
| Speekly | Soulbatical |
**Ontbrekende mapping:** Veel leveranciers hebben nog GEEN kostenplaats in booking-rules.json
---
## Plan van Aanpak
### Stap 1: Analyse Tool - `analyze_kostenplaatsen`
**Doel:** Overzicht genereren van alle boekingen met/zonder kostenplaats
**Implementatie:**
```typescript
// Nieuwe tool in src/tools/boekingen.ts
{
name: "analyze_kostenplaatsen",
description: "Analyze which inkoopboekingen have/don't have kostenplaats",
inputSchema: {
from_date: string, // required
to_date: string, // required
limit: number // default 500
}
}
```
**Workflow:**
1. Haal alle inkoopfacturen op via `/inkoopfacturen`
2. Voor elke factuur → haal inkoopboeking op via `inkoopBoekingId`
3. Check `boekingsregels[*].kostenplaats`
4. Groepeer per leverancier
**Output:**
```json
{
"summary": {
"total": 360,
"with_kostenplaats": 12,
"without_kostenplaats": 348
},
"by_leverancier": [
{
"leverancier_id": "8dd629b2-...",
"naam": "Lulu Press",
"count": 45,
"with_kostenplaats": 0,
"without_kostenplaats": 45,
"suggested_kostenplaats": "Soulbatical"
},
...
],
"unknown_leveranciers": [
{ "id": "xxx", "naam": "Onbekend", "count": 12 }
]
}
```
### Stap 2: Bulk Update Tool - `bulk_set_kostenplaatsen`
**Doel:** Update alle boekingen van een leverancier met de juiste kostenplaats
**Implementatie:**
```typescript
{
name: "bulk_set_kostenplaatsen",
description: "Set kostenplaats for all boekingen of a leverancier",
inputSchema: {
leverancier_id: string, // required
kostenplaats_id: string, // required
from_date: string, // required
to_date: string, // required
dry_run: boolean // default true
}
}
```
**Workflow:**
1. Vind alle inkoopfacturen van de leverancier
2. Voor elke factuur → haal inkoopboeking op
3. Check of kostenplaats al is gezet
4. Als dry_run=false → update via `set_inkoopboeking_kostenplaats`
5. Return rapport met updates
**Output:**
```json
{
"leverancier": "Lulu Press",
"kostenplaats": "Soulbatical",
"dry_run": true,
"boekingen": {
"total": 45,
"already_set": 3,
"to_update": 42,
"updated": 0 // 42 als dry_run=false
},
"details": [
{ "boeking_id": "xxx", "factuurnummer": "LULU-123", "status": "would_update" }
]
}
```
### Stap 3: Config Uitbreiden - Meer Leveranciers
Voeg ontbrekende leveranciers toe aan `booking-rules.json`:
- Sunny@Work → ?
- Stape → Soulbatical (marketing tool)
- Google Workspace → Holding
- Microsoft → Platformen
- etc.
---
## Technische Details
### API Flow
```
┌────────────────────┐ ┌─────────────────────┐
│ /inkoopfacturen │────▶│ inkoopBoekingId │
│ (list met OData) │ │ │
└────────────────────┘ └──────────┬──────────┘
│
▼
┌─────────────────────┐
│ /inkoopboekingen/id │
│ (get detail) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ boekingsregels[*] │
│ .kostenplaats │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ PUT /inkoopboekingen│
│ (update kostenplaats│
└─────────────────────┘
```
### Rate Limiting
- Max 10 requests/seconde naar SnelStart API
- Bij 360 facturen + 360 boekingen = ~720 requests
- Geschatte tijd: ~2 minuten voor volledige analyse
### Error Handling
- Skip boekingen die al kostenplaats hebben
- Log errors per boeking, ga door met rest
- Return partial results bij timeout
---
## Implementatie Volgorde
1. **[ ] analyze_kostenplaatsen tool** - read-only, veilig
2. **[ ] Test analyse op januari 2025** - kleine dataset
3. **[ ] bulk_set_kostenplaatsen tool** - met dry_run default
4. **[ ] Test dry_run op Lulu** - bekende leverancier
5. **[ ] Uitbreiden booking-rules.json** - meer leveranciers
6. **[ ] Bulk update per leverancier** - met bevestiging
---
## Risico's & Mitigatie
| Risico | Impact | Mitigatie |
|--------|--------|-----------|
| Verkeerde kostenplaats | Boekhouding fout | dry_run eerst, per leverancier |
| API rate limit | Timeout | Batch per maand, pauzes |
| Boeking al door accountant gewijzigd | Conflict | Check `gewijzigdDoorAccountant` flag |
| Leverancier niet in mapping | Niet geupdate | Rapport "unknown_leveranciers" |
---
## Geschatte Doorlooptijd
- Stap 1 (analyze tool): 30 min implementatie
- Stap 2 (bulk tool): 45 min implementatie
- Stap 3 (config): 15 min per leverancier
- Testing: 30 min
- Uitvoering (360 boekingen): 15 min per run
**Totaal: ~2 uur implementatie + 1 uur uitvoering**