Règle les heures hebdomadaires et le nombre de jours via la config globale
Le quota quotidien est désormais dérivé d'heures_semaine / jours_par_semaine
au lieu d'être saisi directement. Rétrocompatible avec les anciennes configs
qui utilisent encore heures_jour.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@ -77,7 +77,8 @@ Seul `data/config.example.json` est versionné.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"heures_jour": 7.8,
|
"heures_semaine": 39.0,
|
||||||
|
"jours_par_semaine": 5,
|
||||||
"log_level": "DEBUG",
|
"log_level": "DEBUG",
|
||||||
"allowed_email_domain": "exemple.fr",
|
"allowed_email_domain": "exemple.fr",
|
||||||
"mail_from": "no-reply@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`).
|
- `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.
|
- `allowed_email_domain` — seules les adresses de ce domaine peuvent se connecter.
|
||||||
- `mail_from` — adresse expéditrice des emails de connexion.
|
- `mail_from` — adresse expéditrice des emails de connexion.
|
||||||
|
|||||||
@ -10,7 +10,8 @@ DATA_DIR = Path("/data")
|
|||||||
CONFIG_FILE = DATA_DIR / "config.json"
|
CONFIG_FILE = DATA_DIR / "config.json"
|
||||||
|
|
||||||
DEFAULT_CONFIG = {
|
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
|
"log_level": "DEBUG", # DEBUG, INFO, WARNING ou ERROR
|
||||||
"allowed_email_domain": "", # ex: "sdv.fr" — seules ces adresses peuvent se connecter
|
"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)
|
"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:
|
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 ─────────────────────────────────────────────────────────────────
|
# ── Pointages ─────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@ -2,7 +2,9 @@
|
|||||||
import statistics as _st
|
import statistics as _st
|
||||||
from datetime import datetime, timedelta, date as _date
|
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
|
from calcul import hhmm_to_minutes, minutes_to_hhmm, heures_travaillees, heures_dues
|
||||||
|
|
||||||
MOIS_FR = [
|
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:
|
def compute_all_stats(user_id: str = "") -> dict:
|
||||||
all_weeks = sorted(list_all_weeks(user_id))
|
all_weeks = sorted(list_all_weeks(user_id))
|
||||||
conges = load_conges(user_id)
|
conges = load_conges(user_id)
|
||||||
cfg = load_config()
|
h_jour = heures_jour_min()
|
||||||
h_jour = int(float(cfg.get("heures_jour", 7.8)) * 60)
|
|
||||||
plages = load_plages(user_id)
|
plages = load_plages(user_id)
|
||||||
cg_set = {(c["date"], c["type"]) for c in conges}
|
cg_set = {(c["date"], c["type"]) for c in conges}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import models
|
|||||||
_TMP = Path(tempfile.mkdtemp())
|
_TMP = Path(tempfile.mkdtemp())
|
||||||
models.DATA_DIR = _TMP
|
models.DATA_DIR = _TMP
|
||||||
models.CONFIG_FILE = models.DATA_DIR / "config.json"
|
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):
|
class FrozenDatetime(dt_module.datetime):
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"heures_jour": 7.8,
|
"heures_semaine": 39.0,
|
||||||
|
"jours_par_semaine": 5,
|
||||||
"log_level": "DEBUG",
|
"log_level": "DEBUG",
|
||||||
"allowed_email_domain": "exemple.fr",
|
"allowed_email_domain": "exemple.fr",
|
||||||
"base_url": "",
|
"base_url": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user