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.
68 lines
2.3 KiB
Python
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)
|