From 0362836a631c897d48badad35f02b478c2b681d1 Mon Sep 17 00:00:00 2001 From: Antoine Van Elstraete Date: Wed, 11 Mar 2026 20:04:47 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20compute=5Ffrais=5Freels=20supporte=20la?= =?UTF-8?q?=20majoration=20+20%=20=C3=A9lectrique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/travel_calc.py | 9 ++++++--- tests/test_travel_calc.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/app/business/travel_calc.py b/app/business/travel_calc.py index b4ac628..8a01ad6 100644 --- a/app/business/travel_calc.py +++ b/app/business/travel_calc.py @@ -32,16 +32,19 @@ def compute_co2_grams(km_by_vehicle: dict[str, int], vehicles: dict) -> float: return total -def compute_frais_reels(total_km_moteur: float, tranches: list[dict]) -> float: +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: - return total_km_moteur * tranche["taux"] + tranche.get("forfait", 0) + result = total_km_moteur * tranche["taux"] + tranche.get("forfait", 0) + return result * 1.2 if electric else result last = tranches[-1] - return total_km_moteur * last["taux"] + last.get("forfait", 0) + result = total_km_moteur * last["taux"] + last.get("forfait", 0) + return result * 1.2 if electric else result diff --git a/tests/test_travel_calc.py b/tests/test_travel_calc.py index df9c3b0..5284c73 100644 --- a/tests/test_travel_calc.py +++ b/tests/test_travel_calc.py @@ -16,10 +16,16 @@ JOURNEYS = { "velo_seul": {"distances": {"velo": 24}}, } +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": 3000, "taux": 0.548, "forfait": 0}, - {"km_max": 6000, "taux": 0.316, "forfait": 699}, - {"km_max": 0, "taux": 0.364, "forfait": 0}, + {"km_max": 5000, "taux": 0.636, "forfait": 0}, + {"km_max": 20000, "taux": 0.357, "forfait": 1395}, + {"km_max": 0, "taux": 0.427, "forfait": 0}, ] @@ -61,14 +67,24 @@ def test_compute_co2_velo(): def test_frais_reels_tranche1(): result = compute_frais_reels(2000, TRANCHES_CV5) - assert abs(result - 1096.0) < 0.01 + assert abs(result - 1272.0) < 0.01 # 2000 × 0.636 def test_frais_reels_tranche2(): - result = compute_frais_reels(4000, TRANCHES_CV5) - assert abs(result - 1963.0) < 0.01 + 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(7000, TRANCHES_CV5) - assert abs(result - 2548.0) < 0.01 + result = compute_frais_reels(25000, TRANCHES_CV5) + assert abs(result - 10675.0) < 0.01 # 25000 × 0.427 + + +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