""" Routes pour gérer la liste des emails qui reçoivent les alertes de stock bas, et la planification de l'email récapitulatif périodique. """ from fastapi import APIRouter, Depends, Form from fastapi.requests import Request from fastapi.responses import RedirectResponse from sqlmodel import Session, select from app.database import get_session from app.models import DestinataireAlerte from app.scheduler import ( EXEMPLES_CRON, definir_expression_cron, obtenir_expression_cron, prochaine_execution, valider_expression_cron, ) from app.templates_engine import templates router = APIRouter() def _contexte_planification(session: Session, **kwargs) -> dict: contexte = { "expression_cron": obtenir_expression_cron(session), "exemples_cron": EXEMPLES_CRON, "prochaine_execution": prochaine_execution(), "erreur_cron": None, } contexte.update(kwargs) return contexte @router.get("/destinataires") def lister_destinataires(request: Request, q: str = "", session: Session = Depends(get_session)): """Affiche la liste des emails configurés pour recevoir les alertes, filtrée par ?q=... si fourni (même comportement que /materiels, pour rester cohérent si la liste grandit), ainsi que la planification de l'email récapitulatif périodique.""" tous = session.exec(select(DestinataireAlerte)).all() destinataires = [d for d in tous if q.lower() in d.email.lower()] if q else tous return templates.TemplateResponse( request, "destinataires.html", {"destinataires": destinataires, "q": q, **_contexte_planification(session)}, ) @router.post("/destinataires") def ajouter_destinataire(email: str = Form(...), session: Session = Depends(get_session)): """Ajoute un email à la liste des destinataires des alertes.""" session.add(DestinataireAlerte(email=email)) session.commit() return RedirectResponse(url="/destinataires", status_code=303) @router.post("/destinataires/{destinataire_id}/supprimer") def supprimer_destinataire(destinataire_id: int, session: Session = Depends(get_session)): """Retire un email de la liste des destinataires.""" destinataire = session.get(DestinataireAlerte, destinataire_id) if destinataire: session.delete(destinataire) session.commit() return RedirectResponse(url="/destinataires", status_code=303) @router.post("/destinataires/planification") def modifier_planification( request: Request, expression_cron: str = Form(...), session: Session = Depends(get_session) ): """Change l'horaire de l'email récapitulatif périodique et reprogramme la tâche immédiatement (pas besoin de redémarrer le serveur). Pas de redirection en cas d'expression cron invalide : on réaffiche la page avec un message d'erreur et la valeur saisie, pour ne pas la perdre (contrairement au reste du formulaire, elle n'est pas enregistrée tant qu'elle n'est pas valide). """ expression_cron = expression_cron.strip() if not valider_expression_cron(expression_cron): tous = session.exec(select(DestinataireAlerte)).all() return templates.TemplateResponse( request, "destinataires.html", { "destinataires": tous, "q": "", **_contexte_planification( session, expression_cron=expression_cron, erreur_cron=( f"Expression cron invalide : « {expression_cron} ». " "Format attendu : minute heure jour mois jour_semaine " "(ex: 0 9 * * mon)." ), ), }, ) definir_expression_cron(session, expression_cron) return RedirectResponse(url="/destinataires", status_code=303)