Files
tableau-de-bord/docs/plans/2026-03-11-bareme-kilometrique.md
Antoine Van Elstraete 859d94bfb1 fix: afficher les noms lisibles des types de jours et des véhicules
- Filtre Jinja2 day_type_fr (WORK→Travail, TT→Télétravail, etc.)
- Appliqué dans entry_list.html et dashboard.html
- Passage de vehicles au template dashboard pour afficher vehicle.name
- Mise à jour du test test_entry_list en conséquence
- Ajout du plan docs/plans/2026-03-11-bareme-kilometrique.md
2026-03-11 20:27:07 +01:00

323 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Barème kilométrique — Refonte complète
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Corriger le barème kilométrique pour qu'il corresponde au barème fiscal officiel : tranches correctes (05 000 / 5 00120 000 / >20 000 km), CV individuels (3 CV, 4 CV, 5 CV, 6 CV, 7 CV+), et support de la majoration +20 % pour les véhicules électriques.
**Architecture:** Le barème est stocké dans `config.toml`, chargé via `get_bareme()` dans `config_loader.py`, et utilisé par `compute_frais_reels()` dans `travel_calc.py`. La majoration électrique sera un paramètre booléen de `compute_frais_reels()`, passé depuis `reports.py` en lisant `vehicle["fuel"] == "electric"`.
**Tech Stack:** Python 3, Flask, TOML, pytest
---
## Contexte
### Barème officiel 2025 (voitures)
| Puissance | ≤ 5 000 km | 5 00120 000 km | > 20 000 km |
|-----------|-------------------|--------------------------|---------------|
| 3 CV max | d × 0,529 | (d × 0,316) + 1 065 | d × 0,370 |
| 4 CV | d × 0,606 | (d × 0,340) + 1 330 | d × 0,407 |
| 5 CV | d × 0,636 | (d × 0,357) + 1 395 | d × 0,427 |
| 6 CV | d × 0,665 | (d × 0,374) + 1 457 | d × 0,447 |
| 7 CV+ | d × 0,697 | (d × 0,394) + 1 515 | d × 0,470 |
**Électrique :** majoration de +20 % sur le montant final calculé.
### Problèmes actuels dans config.toml
- Tranches fausses : 03 000 / 3 0016 000 / >6 000 (au lieu de 05 000 / 5 00120 000 / >20 000)
- Groupes CV incorrects : `cv_5` regroupe tout ≤ 5 CV
- Taux incorrects
- Électrique absent
---
## Tâche 1 : Mettre à jour les tests de `compute_frais_reels`
**Fichier :** `tests/test_travel_calc.py`
### Étape 1 : Remplacer `TRANCHES_CV5` par les tranches officielles et ajouter `TRANCHES_CV3`
Remplacer dans `tests/test_travel_calc.py` les constantes de test :
```python
TRANCHES_CV3 = [
{"km_max": 5000, "taux": 0.529, "forfait": 0},
{"km_max": 20000, "taux": 0.316, "forfait": 1065},
{"km_max": 0, "taux": 0.370, "forfait": 0},
]
TRANCHES_CV5 = [
{"km_max": 5000, "taux": 0.636, "forfait": 0},
{"km_max": 20000, "taux": 0.357, "forfait": 1395},
{"km_max": 0, "taux": 0.427, "forfait": 0},
]
```
### Étape 2 : Remplacer les assertions existantes et ajouter les nouveaux tests
```python
# Remplacer les tests frais_reels existants :
def test_frais_reels_tranche1():
result = compute_frais_reels(2000, TRANCHES_CV5)
assert abs(result - 1272.0) < 0.01 # 2000 × 0.636
def test_frais_reels_tranche2():
result = compute_frais_reels(10000, TRANCHES_CV5)
assert abs(result - 4965.0) < 0.01 # 10000 × 0.357 + 1395
def test_frais_reels_tranche3():
result = compute_frais_reels(25000, TRANCHES_CV5)
assert abs(result - 10675.0) < 0.01 # 25000 × 0.427
# Ajouter les tests électrique :
def test_frais_reels_electrique_majoration_20_pct():
result = compute_frais_reels(2000, TRANCHES_CV3, electric=True)
assert abs(result - 1269.6) < 0.01 # 2000 × 0.529 × 1.2
def test_frais_reels_non_electrique_sans_majoration():
result = compute_frais_reels(2000, TRANCHES_CV3, electric=False)
assert abs(result - 1058.0) < 0.01 # 2000 × 0.529
```
### Étape 3 : Vérifier que les tests échouent
```bash
.venv/bin/python -m pytest tests/test_travel_calc.py -v
```
Attendu : `FAILED` sur les tests `test_frais_reels_*` (mauvaises valeurs et paramètre `electric` inexistant).
---
## Tâche 2 : Modifier `compute_frais_reels` pour supporter la majoration électrique
**Fichier :** `app/business/travel_calc.py`
### Étape 1 : Ajouter le paramètre `electric`
Modifier la signature et la logique de `compute_frais_reels` :
```python
def compute_frais_reels(total_km_moteur: float, tranches: list[dict], electric: bool = False) -> float:
"""
Calcule les frais réels fiscaux selon le barème kilométrique.
km_max = 0 signifie "pas de limite" (dernière tranche).
electric=True applique la majoration de 20 % pour véhicules électriques.
"""
if not tranches or total_km_moteur <= 0:
return 0.0
for tranche in tranches:
km_max = tranche["km_max"]
if km_max == 0 or total_km_moteur <= km_max:
result = total_km_moteur * tranche["taux"] + tranche.get("forfait", 0)
return result * 1.2 if electric else result
last = tranches[-1]
result = total_km_moteur * last["taux"] + last.get("forfait", 0)
return result * 1.2 if electric else result
```
### Étape 2 : Vérifier que les tests passent
```bash
.venv/bin/python -m pytest tests/test_travel_calc.py -v
```
Attendu : tous les tests `PASSED`.
### Étape 3 : Commit
```bash
git -c commit.gpgsign=false add tests/test_travel_calc.py app/business/travel_calc.py
git -c commit.gpgsign=false commit -m "feat: compute_frais_reels supporte la majoration +20% électrique"
```
---
## Tâche 3 : Modifier `get_bareme()` pour les CV individuels
**Fichier :** `app/config_loader.py`
### Étape 1 : Remplacer la logique de groupement des CV
Remplacer la fonction `get_bareme` :
```python
def get_bareme(year: int, cv: int) -> list[dict]:
bareme = current_app.config.get("TOML", {}).get("bareme_kilometrique", {})
year_data = bareme.get(str(year), {})
if cv <= 3:
key = "cv_3"
elif cv == 4:
key = "cv_4"
elif cv == 5:
key = "cv_5"
elif cv == 6:
key = "cv_6"
else:
key = "cv_7plus"
return year_data.get(key, {}).get("tranches", [])
```
### Étape 2 : Vérifier que les tests existants passent toujours
```bash
.venv/bin/python -m pytest -v
```
Attendu : tous `PASSED` (les tests de routes utilisent la DB en mémoire et le TOML de test — pas le vrai barème).
---
## Tâche 4 : Mettre à jour `reports.py` pour passer le flag électrique
**Fichier :** `app/routes/reports.py`
### Étape 1 : Lire le champ `fuel` du véhicule et le passer à `compute_frais_reels`
Remplacer le bloc `frais_reels` :
```python
frais_reels = {}
for vehicle_id, km in total_km.items():
vehicle = vehicles.get(vehicle_id, {})
cv = vehicle.get("cv")
if cv:
tranches = get_bareme(year, cv)
electric = vehicle.get("fuel") == "electric"
frais_reels[vehicle_id] = round(compute_frais_reels(km, tranches, electric=electric), 2)
```
### Étape 2 : Vérifier les tests de routes
```bash
.venv/bin/python -m pytest tests/test_routes.py -v
```
Attendu : tous `PASSED`.
### Étape 3 : Commit
```bash
git -c commit.gpgsign=false add app/config_loader.py app/routes/reports.py
git -c commit.gpgsign=false commit -m "feat: get_bareme par CV individuel, majoration électrique dans reports"
```
---
## Tâche 5 : Corriger le barème dans `config.toml`
**Fichier :** `config.toml`
### Étape 1 : Remplacer entièrement la section `bareme_kilometrique`
Supprimer toutes les lignes `[[bareme_kilometrique.*]]` existantes et les remplacer par :
```toml
# --- Barème kilométrique voitures 2025 (revenus 2024) ---
# Source : https://www.service-public.gouv.fr/particuliers/actualites/A14686
# Majoration +20% pour véhicules électriques gérée dans travel_calc.py
[[bareme_kilometrique.2025.cv_3.tranches]]
km_max = 5000
taux = 0.529
forfait = 0
[[bareme_kilometrique.2025.cv_3.tranches]]
km_max = 20000
taux = 0.316
forfait = 1065
[[bareme_kilometrique.2025.cv_3.tranches]]
km_max = 0
taux = 0.370
forfait = 0
[[bareme_kilometrique.2025.cv_4.tranches]]
km_max = 5000
taux = 0.606
forfait = 0
[[bareme_kilometrique.2025.cv_4.tranches]]
km_max = 20000
taux = 0.340
forfait = 1330
[[bareme_kilometrique.2025.cv_4.tranches]]
km_max = 0
taux = 0.407
forfait = 0
[[bareme_kilometrique.2025.cv_5.tranches]]
km_max = 5000
taux = 0.636
forfait = 0
[[bareme_kilometrique.2025.cv_5.tranches]]
km_max = 20000
taux = 0.357
forfait = 1395
[[bareme_kilometrique.2025.cv_5.tranches]]
km_max = 0
taux = 0.427
forfait = 0
[[bareme_kilometrique.2025.cv_6.tranches]]
km_max = 5000
taux = 0.665
forfait = 0
[[bareme_kilometrique.2025.cv_6.tranches]]
km_max = 20000
taux = 0.374
forfait = 1457
[[bareme_kilometrique.2025.cv_6.tranches]]
km_max = 0
taux = 0.447
forfait = 0
[[bareme_kilometrique.2025.cv_7plus.tranches]]
km_max = 5000
taux = 0.697
forfait = 0
[[bareme_kilometrique.2025.cv_7plus.tranches]]
km_max = 20000
taux = 0.394
forfait = 1515
[[bareme_kilometrique.2025.cv_7plus.tranches]]
km_max = 0
taux = 0.470
forfait = 0
```
### Étape 2 : Lancer le serveur et vérifier visuellement la page `/reports/`
```bash
.venv/bin/python run.py
```
Naviguer sur `http://localhost:5000/reports/` et vérifier que les frais réels sont calculés (pas d'erreur 500, valeurs cohérentes).
### Étape 3 : Commit final
```bash
git -c commit.gpgsign=false add config.toml
git -c commit.gpgsign=false commit -m "fix: barème kilométrique 2025 — tranches et CV corrects, toutes puissances"
```
---
## Récapitulatif des fichiers modifiés
| Fichier | Nature |
|---|---|
| `tests/test_travel_calc.py` | Mise à jour des tranches de test et nouvelles assertions électrique |
| `app/business/travel_calc.py` | Paramètre `electric` dans `compute_frais_reels` |
| `app/config_loader.py` | `get_bareme()` avec CV individuels (cv_3 à cv_7plus) |
| `app/routes/reports.py` | Passage du flag `electric` à `compute_frais_reels` |
| `config.toml` | Barème complet et correct avec toutes les puissances 2025 |