chore: resolve final review findings
Co-authored-by: OpenAI/GPT-5.6-Terra <vibecoder@antoineve.me> Co-authored-by: DeepSeek/DeepSeek-v4-Pro <vibecoder@antoineve.me> Co-authored-by: DeepSeek/DeepSeek-v4-Flash <vibecoder@antoineve.me>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@ __pycache__/
|
||||
instance/
|
||||
.env
|
||||
*.db
|
||||
.ruff_cache/
|
||||
.pytest_cache/
|
||||
|
||||
@@ -14,9 +14,9 @@ Architecture et composants clés :
|
||||
"""
|
||||
|
||||
import os
|
||||
import tomllib
|
||||
|
||||
import sqlalchemy as sa
|
||||
import tomllib
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import statistics as _stats
|
||||
|
||||
|
||||
def minutes_to_str(minutes: int) -> str:
|
||||
"""
|
||||
Convertit une durée en minutes en une chaîne formatée lisible (ex: "7h45" ou "-1h15").
|
||||
@@ -58,9 +61,6 @@ def week_balance_minutes(actual_minutes: int, reference_minutes: int) -> int:
|
||||
return actual_minutes - reference_minutes
|
||||
|
||||
|
||||
import statistics as _stats
|
||||
|
||||
|
||||
def monthly_stats(entries: list) -> dict:
|
||||
"""
|
||||
Calcule la médiane journalière et la médiane hebdomadaire (semaines ISO) pour un groupe d'entrées.
|
||||
|
||||
@@ -8,15 +8,15 @@ Contrat TOML :
|
||||
1. Véhicules (`[vehicles]`) :
|
||||
- Chaque véhicule possède un identifiant unique (clé).
|
||||
- Attributs : `name` (nom d'affichage), `type` ("moteur" ou "velo"), `fuel` ("electric", "essence", etc.),
|
||||
et optionnellement `cv` (puissance fiscale pour le barème kilométrique).
|
||||
`co2_per_km` (émissions de CO2 en grammes par km), et optionnellement `cv` (puissance fiscale pour le barème kilométrique).
|
||||
2. Trajets (`[journeys]`) :
|
||||
- Profils de trajets prédéfinis (ex: "domicile-travail").
|
||||
- Profils de trajets prédéfinis (ex: "moteur_seul").
|
||||
- Attributs : `name` (nom d'affichage), `distances` (dictionnaire associant un type de véhicule à une distance en km).
|
||||
3. Barème kilométrique (`[bareme_kilometrique.YYYY]`) :
|
||||
- Organisé par année (ex: "2026") puis par puissance fiscale (`cv_3`, `cv_4`, `cv_5`, `cv_6`, `cv_7plus`).
|
||||
- Chaque catégorie contient une liste de `tranches` définissant les formules de calcul des frais réels.
|
||||
- Une tranche possède : `km_max` (limite supérieure de la tranche, `km_max = 0` signifie "pas de limite supérieure"),
|
||||
`coeff` (coefficient multiplicateur par km) et `fixe` (montant forfaitaire à ajouter).
|
||||
`taux` (coefficient multiplicateur par km) et `forfait` (montant forfaitaire à ajouter).
|
||||
4. Types de jours sans trajet :
|
||||
- Certains types de journées (Télétravail, Maladie, Congé, RTT, Férié) n'impliquent aucun déplacement physique.
|
||||
"""
|
||||
@@ -29,7 +29,7 @@ def get_vehicles():
|
||||
|
||||
Retourne:
|
||||
dict: Un dictionnaire des véhicules où la clé est l'identifiant du véhicule
|
||||
et la valeur est un dictionnaire contenant ses propriétés (name, type, fuel, cv).
|
||||
et la valeur est un dictionnaire contenant ses propriétés (name, type, fuel, co2_per_km, cv).
|
||||
Retourne un dictionnaire vide si aucune configuration n'est chargée.
|
||||
"""
|
||||
return current_app.config.get("TOML", {}).get("vehicles", {})
|
||||
@@ -95,7 +95,7 @@ def get_bareme(year: int, cv: int) -> list[dict]:
|
||||
|
||||
Retourne:
|
||||
list[dict]: Une liste de dictionnaires représentant les tranches applicables.
|
||||
Chaque tranche contient 'km_max' (0 si pas de limite), 'coeff' et 'fixe'.
|
||||
Chaque tranche contient 'km_max' (0 si pas de limite), 'taux' et 'forfait'.
|
||||
"""
|
||||
bareme = current_app.config.get("TOML", {}).get("bareme_kilometrique", {})
|
||||
year_data = bareme.get(str(year), {})
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
[tool.ruff]
|
||||
target-version = "py310"
|
||||
target-version = "py311"
|
||||
line-length = 100
|
||||
include = ["*.py"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E4", "E7", "E9", "F", "I"]
|
||||
|
||||
# Ces imports différés sont intentionnels : ils évitent des dépendances
|
||||
# circulaires ou préparent sys.path pour les scripts lancés directement.
|
||||
# Cet import différé est intentionnel : il prépare sys.path pour le script
|
||||
# lancé directement (imports des modules de l'app après insertion du parent).
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"app/business/time_calc.py" = ["E402"]
|
||||
"scripts/import_csv.py" = ["E402"]
|
||||
"tests/test_time_calc.py" = ["E402"]
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
|
||||
@@ -33,7 +33,7 @@ from app.models import TimeSlot, WorkEntry
|
||||
DAY_TYPES = {"WORK", "TT", "GARDE", "ASTREINTE", "FORMATION", "RTT", "CONGE", "MALADE", "FERIE"}
|
||||
|
||||
|
||||
def main(csv_path: str, config_path: str = None):
|
||||
def main(csv_path: str, config_path: str | None = None):
|
||||
"""Importe les données depuis un fichier CSV vers la base de données."""
|
||||
|
||||
# Créer l'application Flask avec la config
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
from datetime import date
|
||||
from datetime import time as dtime
|
||||
|
||||
from app.business.time_calc import (
|
||||
count_day_types,
|
||||
minutes_to_str,
|
||||
monthly_stats,
|
||||
week_balance_minutes,
|
||||
work_minutes_reference,
|
||||
)
|
||||
from app.models import TimeSlot, WorkEntry
|
||||
|
||||
|
||||
def test_minutes_to_str_basic():
|
||||
@@ -42,13 +48,6 @@ def test_week_balance_negative():
|
||||
assert week_balance_minutes(2200, 2325) == -125
|
||||
|
||||
|
||||
from datetime import date
|
||||
from datetime import time as dtime
|
||||
|
||||
from app.business.time_calc import count_day_types, monthly_stats
|
||||
from app.models import TimeSlot, WorkEntry
|
||||
|
||||
|
||||
def test_count_day_types_basic():
|
||||
entries = [
|
||||
WorkEntry(date=date(2025, 1, 2), day_type="WORK"),
|
||||
|
||||
Reference in New Issue
Block a user