diff --git a/README.md b/README.md index d068465..38711fd 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,8 @@ Seul `data/config.example.json` est versionné. ```json { - "heures_jour": 7.8, + "heures_semaine": 39.0, + "jours_par_semaine": 5, "log_level": "DEBUG", "allowed_email_domain": "exemple.fr", "mail_from": "no-reply@exemple.fr", @@ -91,7 +92,8 @@ Seul `data/config.example.json` est versionné. } ``` -- `heures_jour` — `7.8` = 7h48 = 39h ÷ 5 jours. Modifier cette valeur recentre tous les calculs. +- `heures_semaine` — heures hebdomadaires visées (ex: `39.0`). +- `jours_par_semaine` — nombre de jours travaillés dans la semaine (ex: `5`). Le quota quotidien est calculé : `heures_semaine ÷ jours_par_semaine` (39h / 5 = 7h48/jour). - `log_level` — `DEBUG`, `INFO`, `WARNING` ou `ERROR`. Contrôle la verbosité des logs (`docker logs`). - `allowed_email_domain` — seules les adresses de ce domaine peuvent se connecter. - `mail_from` — adresse expéditrice des emails de connexion. diff --git a/app/models.py b/app/models.py index 1f5e8fb..5f785ff 100644 --- a/app/models.py +++ b/app/models.py @@ -10,7 +10,8 @@ DATA_DIR = Path("/data") CONFIG_FILE = DATA_DIR / "config.json" DEFAULT_CONFIG = { - "heures_jour": 7.8, # 7h48 = 39h/semaine + "heures_semaine": 39.0, # heures hebdomadaires visées + "jours_par_semaine": 5, # jours travaillés dans la semaine — heures_jour en est dérivé "log_level": "DEBUG", # DEBUG, INFO, WARNING ou ERROR "allowed_email_domain": "", # ex: "sdv.fr" — seules ces adresses peuvent se connecter "base_url": "", # ex: "https://pointeuse.sdv.fr" — utilisée pour les liens emails (anti open-redirect via Host header) @@ -89,7 +90,16 @@ def load_or_create_secret() -> bytes: def heures_jour_min() -> int: - return int(float(load_config().get("heures_jour", 7.8)) * 60) + """Minutes attendues par jour, dérivées d'`heures_semaine` et `jours_par_semaine`. + + Rétrocompat : si `heures_semaine` est absent mais `heures_jour` présent, + on utilise l'ancienne clé. + """ + cfg = load_config() + jours = int(cfg.get("jours_par_semaine", 5)) or 5 + if "heures_semaine" in cfg: + return int(float(cfg["heures_semaine"]) * 60 / jours) + return int(float(cfg.get("heures_jour", 7.8)) * 60) # ── Pointages ───────────────────────────────────────────────────────────────── diff --git a/app/stats.py b/app/stats.py index 36306f5..c9c3ec3 100644 --- a/app/stats.py +++ b/app/stats.py @@ -2,7 +2,9 @@ import statistics as _st from datetime import datetime, timedelta, date as _date -from models import load_week_pointages, load_conges, list_all_weeks, load_config, load_plages +from models import ( + load_week_pointages, load_conges, list_all_weeks, load_plages, heures_jour_min, +) from calcul import hhmm_to_minutes, minutes_to_hhmm, heures_travaillees, heures_dues MOIS_FR = [ @@ -58,8 +60,7 @@ def _compliance_over(all_days: list[tuple], cg_set: set, plages: dict) -> dict: def compute_all_stats(user_id: str = "") -> dict: all_weeks = sorted(list_all_weeks(user_id)) conges = load_conges(user_id) - cfg = load_config() - h_jour = int(float(cfg.get("heures_jour", 7.8)) * 60) + h_jour = heures_jour_min() plages = load_plages(user_id) cg_set = {(c["date"], c["type"]) for c in conges} diff --git a/app/tests/conftest.py b/app/tests/conftest.py index bbaab9d..a6148a0 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -17,7 +17,7 @@ import models _TMP = Path(tempfile.mkdtemp()) models.DATA_DIR = _TMP models.CONFIG_FILE = models.DATA_DIR / "config.json" -models.CONFIG_FILE.write_text('{"heures_jour": 7.8, "allowed_email_domain": "x.fr"}') +models.CONFIG_FILE.write_text('{"heures_semaine": 39.0, "jours_par_semaine": 5, "allowed_email_domain": "x.fr"}') class FrozenDatetime(dt_module.datetime): diff --git a/data/config.example.json b/data/config.example.json index 94d25a3..faa566d 100644 --- a/data/config.example.json +++ b/data/config.example.json @@ -1,5 +1,6 @@ { - "heures_jour": 7.8, + "heures_semaine": 39.0, + "jours_par_semaine": 5, "log_level": "DEBUG", "allowed_email_domain": "exemple.fr", "base_url": "",