# 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 (0–5 000 / 5 001–20 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 001–20 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 : 0–3 000 / 3 001–6 000 / >6 000 (au lieu de 0–5 000 / 5 001–20 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 |