IT-Stock/app/email_alerts.py
maxsoch 8bb5c9406a Initial scaffold: gestion de stock IT pour le département IT
App FastAPI + SQLite + SQLModel + Jinja2 pour gérer le stock de matériel
IT (catégories/sous-catégories/matériels), avec recherche par scan de
code-barres et alertes email de stock bas.
2026-07-14 18:38:59 +02:00

68 lines
2.3 KiB
Python

"""
Envoi des emails d'alerte de stock bas.
En local, si aucun SMTP_HOST n'est configuré (voir .env.example et
app/config.py), les alertes ne sont pas réellement envoyées : elles sont
juste affichées dans la console. Ça permet de développer et tester tout le
flux d'alerte sans avoir besoin d'un vrai serveur mail sous la main.
"""
import smtplib
from email.message import EmailMessage
from sqlmodel import Session, select
from app.config import settings
from app.models import DestinataireAlerte, Materiel
def verifier_et_alerter(materiel: Materiel, session: Session) -> None:
"""À appeler après toute modification de la quantité d'un matériel.
Envoie un email à tous les destinataires configurés si le stock vient
de passer sous le seuil d'alerte défini sur ce matériel.
"""
if materiel.seuil_alerte is None:
return
if materiel.quantite >= materiel.seuil_alerte:
return
destinataires = session.exec(select(DestinataireAlerte)).all()
if not destinataires:
return
sujet = f"[Stock IT] Stock bas : {materiel.nom}"
corps = (
f"Le stock de « {materiel.nom} » est passé sous le seuil d'alerte.\n\n"
f"Quantité actuelle : {materiel.quantite}\n"
f"Seuil d'alerte : {materiel.seuil_alerte}\n"
)
_envoyer_email(sujet, corps, [d.email for d in destinataires])
def _envoyer_email(sujet: str, corps: str, destinataires: list[str]) -> None:
if not settings.smtp_configured:
# Pas de SMTP configuré (typiquement en dev local) : on affiche
# l'email dans la console plutôt que de l'envoyer, pour pouvoir
# tester le déclenchement des alertes sans serveur mail réel.
print(
"--- [EMAIL SIMULÉ] ---\n"
f"À: {', '.join(destinataires)}\n"
f"Sujet: {sujet}\n\n"
f"{corps}"
"----------------------"
)
return
message = EmailMessage()
message["Subject"] = sujet
message["From"] = settings.smtp_from
message["To"] = ", ".join(destinataires)
message.set_content(corps)
with smtplib.SMTP(settings.smtp_host, settings.smtp_port) as smtp:
if settings.smtp_user and settings.smtp_password:
smtp.starttls()
smtp.login(settings.smtp_user, settings.smtp_password)
smtp.send_message(message)