From 4cbd62882f82c619dd39e2dfbaf42fccd1bf0f2b Mon Sep 17 00:00:00 2001 From: Antoine Van Elstraete Date: Wed, 11 Mar 2026 16:31:13 +0100 Subject: [PATCH] feat: TOML config loader for vehicles, journeys, and tax scales Co-Authored-By: Claude Sonnet 4.6 --- app/config_loader.py | 27 +++++++++++++++++++ config.toml | 52 +++++++++++++++++++++++++++++++++++++ pytest.ini | 3 +++ tests/test_config_loader.py | 30 +++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 app/config_loader.py create mode 100644 config.toml create mode 100644 pytest.ini create mode 100644 tests/test_config_loader.py diff --git a/app/config_loader.py b/app/config_loader.py new file mode 100644 index 0000000..3d50b31 --- /dev/null +++ b/app/config_loader.py @@ -0,0 +1,27 @@ +from flask import current_app + + +def get_vehicles(): + return current_app.config.get("TOML", {}).get("vehicles", {}) + + +def get_journeys(): + return current_app.config.get("TOML", {}).get("journeys", {}) + + +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 <= 5: + key = "cv_5" + elif cv <= 7: + key = "cv_6_7" + elif cv <= 9: + key = "cv_8_9" + else: + key = "cv_10_11" + return year_data.get(key, {}).get("tranches", []) + + +def day_types_without_journey(): + return {"TT", "MALADE", "CONGE", "RTT", "FERIE"} diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..9d408b8 --- /dev/null +++ b/config.toml @@ -0,0 +1,52 @@ +[vehicles.voiture] +name = "Peugeot 308" +fuel = "diesel" +co2_per_km = 142 +cv = 5 + +[vehicles.velo] +name = "Vélo" +fuel = "none" +co2_per_km = 0 + +[journeys.voiture_seule] +name = "Voiture seule" +distances = { voiture = 25 } + +[journeys.voiture_velo] +name = "Voiture + Vélo" +distances = { voiture = 14, velo = 8 } + +[journeys.velo_seul] +name = "Vélo seul" +distances = { velo = 24 } + +[[bareme_kilometrique.2025.cv_5.tranches]] +km_max = 3000 +taux = 0.548 +forfait = 0 + +[[bareme_kilometrique.2025.cv_5.tranches]] +km_max = 6000 +taux = 0.316 +forfait = 699 + +[[bareme_kilometrique.2025.cv_5.tranches]] +km_max = 0 +taux = 0.364 +forfait = 0 + +[[bareme_kilometrique.2025.cv_6_7.tranches]] +km_max = 3000 +taux = 0.655 +forfait = 0 + +[[bareme_kilometrique.2025.cv_6_7.tranches]] +km_max = 6000 +taux = 0.374 +forfait = 836 + +[[bareme_kilometrique.2025.cv_6_7.tranches]] +km_max = 0 +taux = 0.435 +forfait = 0 diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..4584de7 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tests +pythonpath = . diff --git a/tests/test_config_loader.py b/tests/test_config_loader.py new file mode 100644 index 0000000..057b25d --- /dev/null +++ b/tests/test_config_loader.py @@ -0,0 +1,30 @@ +def test_get_vehicles_returns_configured_vehicles(app): + with app.app_context(): + from app.config_loader import get_vehicles + vehicles = get_vehicles() + assert "voiture" in vehicles + assert vehicles["voiture"]["co2_per_km"] == 142 + + +def test_get_journeys_returns_profiles(app): + with app.app_context(): + from app.config_loader import get_journeys + journeys = get_journeys() + assert "voiture_seule" in journeys + assert journeys["voiture_seule"]["distances"]["voiture"] == 25 + + +def test_get_bareme_returns_tranches(app): + with app.app_context(): + from app.config_loader import get_bareme + tranches = get_bareme(2025, 5) + assert len(tranches) == 3 + assert tranches[0]["taux"] == 0.548 + + +def test_day_types_without_journey(app): + with app.app_context(): + from app.config_loader import day_types_without_journey + types = day_types_without_journey() + assert "TT" in types + assert "WORK" not in types