def compute_km_for_entry( journey_profile_id: str | None, journeys: dict, motor_vehicle_id: str | None = None, ) -> dict[str, int]: """ Retourne un dict {vehicle_id: km} pour un profil de trajet donné. La clé générique 'moteur' est remplacée par motor_vehicle_id si fourni. Retourne {} si pas de profil (TT, CONGE, etc.). """ if not journey_profile_id: return {} profile = journeys.get(journey_profile_id, {}) distances = dict(profile.get("distances", {})) if "moteur" in distances: motor_km = distances.pop("moteur") if motor_vehicle_id: distances[motor_vehicle_id] = motor_km # Si pas de motor_vehicle_id, la distance moteur est ignorée return distances def compute_co2_grams(km_by_vehicle: dict[str, int], vehicles: dict) -> float: """Calcule le CO2 total en grammes pour un dict {vehicle_id: km}.""" total = 0.0 for vehicle_id, km in km_by_vehicle.items(): vehicle = vehicles.get(vehicle_id, {}) co2 = vehicle.get("co2_per_km", 0) total += km * co2 return total 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