forked from ScoDoc/ScoDoc
Assiduite: notifications mail. Fix #789
This commit is contained in:
parent
3ecbe5128e
commit
6c3d13b3e1
@ -559,7 +559,7 @@ def _create_singular(
|
|||||||
data: dict,
|
data: dict,
|
||||||
etud: Identite,
|
etud: Identite,
|
||||||
) -> tuple[int, object]:
|
) -> tuple[int, object]:
|
||||||
"""TODO: documenter"""
|
"""TODO @iziram: documenter"""
|
||||||
errors: list[str] = []
|
errors: list[str] = []
|
||||||
|
|
||||||
# -- vérifications de l'objet json --
|
# -- vérifications de l'objet json --
|
||||||
@ -630,6 +630,7 @@ def _create_singular(
|
|||||||
description=desc,
|
description=desc,
|
||||||
user_id=current_user.id,
|
user_id=current_user.id,
|
||||||
external_data=external_data,
|
external_data=external_data,
|
||||||
|
notify_mail=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
db.session.add(nouv_assiduite)
|
db.session.add(nouv_assiduite)
|
||||||
|
@ -7,6 +7,7 @@ from app import db, log
|
|||||||
from app.models import ModuleImpl, Scolog
|
from app.models import ModuleImpl, Scolog
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
|
from app.scodoc import sco_abs_notification
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_utils import (
|
from app.scodoc.sco_utils import (
|
||||||
EtatAssiduite,
|
EtatAssiduite,
|
||||||
@ -130,13 +131,14 @@ class Assiduite(db.Model):
|
|||||||
user_id: int = None,
|
user_id: int = None,
|
||||||
est_just: bool = False,
|
est_just: bool = False,
|
||||||
external_data: dict = None,
|
external_data: dict = None,
|
||||||
|
notify_mail=False,
|
||||||
) -> "Assiduite":
|
) -> "Assiduite":
|
||||||
"""Créer une nouvelle assiduité pour l'étudiant"""
|
"""Créer une nouvelle assiduité pour l'étudiant"""
|
||||||
# Vérification de non duplication des périodes
|
# Vérification de non duplication des périodes
|
||||||
assiduites: Query = etud.assiduites
|
assiduites: Query = etud.assiduites
|
||||||
if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite):
|
if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite):
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
"Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
"Duplication: la période rentre en conflit avec une plage enregistrée"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not est_just:
|
if not est_just:
|
||||||
@ -147,34 +149,24 @@ class Assiduite(db.Model):
|
|||||||
> 0
|
> 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
moduleimpl_id = None
|
||||||
if moduleimpl is not None:
|
if moduleimpl is not None:
|
||||||
# Vérification de l'existence du module pour l'étudiant
|
# Vérification de l'inscription de l'étudiant
|
||||||
if moduleimpl.est_inscrit(etud):
|
if moduleimpl.est_inscrit(etud):
|
||||||
nouv_assiduite = Assiduite(
|
moduleimpl_id = moduleimpl.id
|
||||||
date_debut=date_debut,
|
|
||||||
date_fin=date_fin,
|
|
||||||
etat=etat,
|
|
||||||
etudiant=etud,
|
|
||||||
moduleimpl_id=moduleimpl.id,
|
|
||||||
description=description,
|
|
||||||
entry_date=entry_date,
|
|
||||||
user_id=user_id,
|
|
||||||
est_just=est_just,
|
|
||||||
external_data=external_data,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
raise ScoValueError("L'étudiant n'est pas inscrit au module")
|
raise ScoValueError("L'étudiant n'est pas inscrit au module")
|
||||||
else:
|
|
||||||
nouv_assiduite = Assiduite(
|
nouv_assiduite = Assiduite(
|
||||||
date_debut=date_debut,
|
date_debut=date_debut,
|
||||||
date_fin=date_fin,
|
date_fin=date_fin,
|
||||||
etat=etat,
|
|
||||||
etudiant=etud,
|
|
||||||
description=description,
|
description=description,
|
||||||
entry_date=entry_date,
|
entry_date=entry_date,
|
||||||
user_id=user_id,
|
|
||||||
est_just=est_just,
|
est_just=est_just,
|
||||||
|
etat=etat,
|
||||||
|
etudiant=etud,
|
||||||
external_data=external_data,
|
external_data=external_data,
|
||||||
|
moduleimpl_id=moduleimpl_id,
|
||||||
|
user_id=user_id,
|
||||||
)
|
)
|
||||||
db.session.add(nouv_assiduite)
|
db.session.add(nouv_assiduite)
|
||||||
log(f"create_assiduite: {etud.id} {nouv_assiduite}")
|
log(f"create_assiduite: {etud.id} {nouv_assiduite}")
|
||||||
@ -183,6 +175,8 @@ class Assiduite(db.Model):
|
|||||||
etudid=etud.id,
|
etudid=etud.id,
|
||||||
msg=f"assiduité: {nouv_assiduite}",
|
msg=f"assiduité: {nouv_assiduite}",
|
||||||
)
|
)
|
||||||
|
if notify_mail and etat == EtatAssiduite.ABSENT:
|
||||||
|
sco_abs_notification.abs_notify(etud.id, nouv_assiduite.date_debut)
|
||||||
return nouv_assiduite
|
return nouv_assiduite
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,17 +40,17 @@ from flask_mail import Message
|
|||||||
from app import db
|
from app import db
|
||||||
from app import email
|
from app import email
|
||||||
from app import log
|
from app import log
|
||||||
|
from app.auth.models import User
|
||||||
from app.models.absences import AbsenceNotification
|
from app.models.absences import AbsenceNotification
|
||||||
from app.models.events import Scolog
|
from app.models.events import Scolog
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_users
|
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
def abs_notify(etudid, date):
|
def abs_notify(etudid: int, date: str | datetime.datetime):
|
||||||
"""Check if notifications are requested and send them
|
"""Check if notifications are requested and send them
|
||||||
Considère le nombre d'absence dans le semestre courant
|
Considère le nombre d'absence dans le semestre courant
|
||||||
(s'il n'y a pas de semestre courant, ne fait rien,
|
(s'il n'y a pas de semestre courant, ne fait rien,
|
||||||
@ -64,18 +64,28 @@ def abs_notify(etudid, date):
|
|||||||
|
|
||||||
nbabs, nbabsjust = sco_assiduites.get_assiduites_count_in_interval(
|
nbabs, nbabsjust = sco_assiduites.get_assiduites_count_in_interval(
|
||||||
etudid,
|
etudid,
|
||||||
formsemestre.date_debut.isoformat(),
|
metrique=scu.translate_assiduites_metric(
|
||||||
formsemestre.date_fin.isoformat(),
|
|
||||||
scu.translate_assiduites_metric(
|
|
||||||
sco_preferences.get_preference(
|
sco_preferences.get_preference(
|
||||||
"assi_metrique", formsemestre.formsemestre_id
|
"assi_metrique", formsemestre.formsemestre_id
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
date_debut=datetime.datetime.combine(
|
||||||
|
formsemestre.date_debut, datetime.datetime.min.time()
|
||||||
|
),
|
||||||
|
date_fin=datetime.datetime.combine(
|
||||||
|
formsemestre.date_fin, datetime.datetime.min.time()
|
||||||
|
),
|
||||||
)
|
)
|
||||||
do_abs_notify(formsemestre, etudid, date, nbabs, nbabsjust)
|
do_abs_notify(formsemestre, etudid, date, nbabs, nbabsjust)
|
||||||
|
|
||||||
|
|
||||||
def do_abs_notify(formsemestre: FormSemestre, etudid, date, nbabs, nbabsjust):
|
def do_abs_notify(
|
||||||
|
formsemestre: FormSemestre,
|
||||||
|
etudid: int,
|
||||||
|
date: str | datetime.datetime,
|
||||||
|
nbabs: int,
|
||||||
|
nbabsjust: int,
|
||||||
|
):
|
||||||
"""Given new counts of absences, check if notifications are requested and send them."""
|
"""Given new counts of absences, check if notifications are requested and send them."""
|
||||||
# prefs fallback to global pref if sem is None:
|
# prefs fallback to global pref if sem is None:
|
||||||
if formsemestre:
|
if formsemestre:
|
||||||
@ -138,8 +148,13 @@ def abs_notify_send(destinations, etudid, msg, nbabs, nbabsjust, formsemestre_id
|
|||||||
|
|
||||||
|
|
||||||
def abs_notify_get_destinations(
|
def abs_notify_get_destinations(
|
||||||
formsemestre: FormSemestre, prefs, etudid, date, nbabs, nbabsjust
|
formsemestre: FormSemestre,
|
||||||
) -> set:
|
prefs: dict,
|
||||||
|
etudid: int,
|
||||||
|
date: str | datetime.datetime,
|
||||||
|
nbabs: int,
|
||||||
|
nbabsjust: int,
|
||||||
|
) -> set[str]:
|
||||||
"""Returns set of destination emails to be notified"""
|
"""Returns set of destination emails to be notified"""
|
||||||
|
|
||||||
destinations = [] # list of email address to notify
|
destinations = [] # list of email address to notify
|
||||||
@ -165,9 +180,9 @@ def abs_notify_get_destinations(
|
|||||||
if prefs["abs_notify_respeval"]:
|
if prefs["abs_notify_respeval"]:
|
||||||
mods = mod_with_evals_at_date(date, etudid)
|
mods = mod_with_evals_at_date(date, etudid)
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
u = sco_users.user_info(mod["responsable_id"])
|
u: User = db.session.get(User, mod["responsable_id"])
|
||||||
if u["email"]:
|
if u is not None and u.is_active and u.email:
|
||||||
destinations.append(u["email"])
|
destinations.append(u.email)
|
||||||
|
|
||||||
# uniq
|
# uniq
|
||||||
destinations = set(destinations)
|
destinations = set(destinations)
|
||||||
@ -267,9 +282,11 @@ def abs_notification_message(
|
|||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
def retreive_current_formsemestre(etudid: int, cur_date) -> Optional[FormSemestre]:
|
def retreive_current_formsemestre(
|
||||||
|
etudid: int, cur_date: str | datetime.date
|
||||||
|
) -> Optional[FormSemestre]:
|
||||||
"""Get formsemestre dans lequel etudid est (ou était) inscrit a la date indiquée
|
"""Get formsemestre dans lequel etudid est (ou était) inscrit a la date indiquée
|
||||||
date est une chaine au format ISO (yyyy-mm-dd)
|
date est une chaine au format ISO (yyyy-mm-dd) ou un datetime.date
|
||||||
|
|
||||||
Result: FormSemestre ou None si pas inscrit à la date indiquée
|
Result: FormSemestre ou None si pas inscrit à la date indiquée
|
||||||
"""
|
"""
|
||||||
@ -287,10 +304,17 @@ def retreive_current_formsemestre(etudid: int, cur_date) -> Optional[FormSemestr
|
|||||||
return formsemestre
|
return formsemestre
|
||||||
|
|
||||||
|
|
||||||
def mod_with_evals_at_date(date_abs, etudid):
|
def mod_with_evals_at_date(
|
||||||
|
date_abs: str | datetime.datetime, etudid: int
|
||||||
|
) -> list[dict]:
|
||||||
"""Liste des moduleimpls avec des evaluations à la date indiquée"""
|
"""Liste des moduleimpls avec des evaluations à la date indiquée"""
|
||||||
req = """SELECT m.id AS moduleimpl_id, m.*
|
req = """
|
||||||
|
SELECT m.id AS moduleimpl_id, m.*
|
||||||
FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i
|
FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i
|
||||||
WHERE m.id = e.moduleimpl_id AND e.moduleimpl_id = i.moduleimpl_id
|
WHERE m.id = e.moduleimpl_id
|
||||||
AND i.etudid = %(etudid)s AND e.jour = %(date_abs)s"""
|
AND e.moduleimpl_id = i.moduleimpl_id
|
||||||
|
AND i.etudid = %(etudid)s
|
||||||
|
AND e.date_debut <= %(date_abs)s
|
||||||
|
AND e.date_fin >= %(date_abs)s
|
||||||
|
"""
|
||||||
return ndb.SimpleDictFetch(req, {"etudid": etudid, "date_abs": date_abs})
|
return ndb.SimpleDictFetch(req, {"etudid": etudid, "date_abs": date_abs})
|
||||||
|
Loading…
Reference in New Issue
Block a user