- 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
323 lines
9.3 KiB
Markdown
323 lines
9.3 KiB
Markdown
# 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 |
|