Préf. pour envoi d’une notification mail à chaque (de)inscription

This commit is contained in:
ilona 2024-08-22 16:42:38 +02:00
parent 4bfd0858a8
commit 6a48d5bbcf
5 changed files with 79 additions and 22 deletions

View File

@ -23,7 +23,7 @@ from sqlalchemy.sql import text
from sqlalchemy import func from sqlalchemy import func
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app import db, log from app import db, email, log
from app.auth.models import User from app.auth.models import User
from app import models from app import models
from app.models import APO_CODE_STR_LEN, CODE_STR_LEN, SHORT_STR_LEN from app.models import APO_CODE_STR_LEN, CODE_STR_LEN, SHORT_STR_LEN
@ -1093,9 +1093,58 @@ class FormSemestre(models.ScoDocModel):
msg=f"inscription en semestre {self.titre_annee()}", msg=f"inscription en semestre {self.titre_annee()}",
commit=True, commit=True,
) )
log(
f"inscrit_etudiant: {etud.nomprenom} ({etud.id}) au semestre {self.titre_annee()}"
)
# Notification mail
self._notify_inscription(etud)
sco_cache.invalidate_formsemestre(formsemestre_id=self.id) sco_cache.invalidate_formsemestre(formsemestre_id=self.id)
return inscr return inscr
def desinscrit_etudiant(self, etud: Identite):
"Désinscrit l'étudiant du semestre (et notifie le cas échéant)"
inscr_sem = FormSemestreInscription.query.filter_by(
etudid=etud.id, formsemestre_id=self.id
).first()
if not inscr_sem:
raise ScoValueError(
f"{etud.nomprenom} ({etud.id}) n'est pas inscrit au semestre !"
)
db.session.delete(inscr_sem)
Scolog.logdb(
method="desinscrit_etudiant",
etudid=etud.id,
msg=f"désinscription semestre {self.titre_annee()}",
commit=True,
)
log(
f"desinscrit_etudiant: {etud.nomprenom} ({etud.id}) au semestre {self.titre_annee()}"
)
self._notify_inscription(etud, action="désinscrit")
sco_cache.invalidate_formsemestre(formsemestre_id=self.id)
def _notify_inscription(self, etud: Identite, action="inscrit") -> None:
"Notifie inscription d'un étudiant: envoie un mail selon paramétrage"
destinations = (
sco_preferences.get_preference("emails_notifications_inscriptions", self.id)
or ""
)
destinations = [x.strip() for x in destinations.split(",")]
destinations = [x for x in destinations if x]
if not destinations:
return
txt = f"""{etud.nom_prenom()}
s'est {action}{etud.e}
en {self.titre_annee()}"""
subject = f"""Inscription de {etud.nom_prenom()} en {self.titre_annee()}"""
# build mail
log(f"_notify_inscription: sending notification to {destinations}")
log(f"_notify_inscription: subject: {subject}")
log(txt)
email.send_email(
"[ScoDoc] " + subject, email.get_from_addr(), destinations, txt
)
def get_partitions_list( def get_partitions_list(
self, with_default=True, only_listed=False self, with_default=True, only_listed=False
) -> list[Partition]: ) -> list[Partition]:

View File

@ -51,7 +51,6 @@ import app.scodoc.sco_utils as scu
from app import log from app import log
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_validation from app.scodoc import sco_formsemestre_validation

View File

@ -182,12 +182,11 @@ def do_formsemestre_desinscription(
if check_has_dec_jury: if check_has_dec_jury:
check_if_has_decision_jury(formsemestre, [etudid]) check_if_has_decision_jury(formsemestre, [etudid])
insem = do_formsemestre_inscription_list( inscr_sem = FormSemestreInscription.query.filter_by(
args={"formsemestre_id": formsemestre_id, "etudid": etudid} etudid=etudid, formsemestre_id=formsemestre_id
) ).first()
if not insem: if not inscr_sem:
raise ScoValueError(f"{etud.nomprenom} n'est pas inscrit au semestre !") raise ScoValueError(f"{etud.nomprenom} n'est pas inscrit au semestre !")
insem = insem[0]
# -- desinscription de tous les modules # -- desinscription de tous les modules
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -211,10 +210,8 @@ def do_formsemestre_desinscription(
Partition.formsemestre_remove_etud(formsemestre_id, etud) Partition.formsemestre_remove_etud(formsemestre_id, etud)
# -- désincription du semestre # -- désincription du semestre
do_formsemestre_inscription_delete( formsemestre.desinscrit_etudiant(etud)
insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id
)
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
# --- Semestre extérieur # --- Semestre extérieur
if formsemestre.modalite == "EXT": if formsemestre.modalite == "EXT":
if 0 == len(formsemestre.inscriptions): if 0 == len(formsemestre.inscriptions):
@ -226,13 +223,6 @@ def do_formsemestre_desinscription(
db.session.commit() db.session.commit()
flash(f"Semestre extérieur supprimé: {formsemestre.titre_annee()}") flash(f"Semestre extérieur supprimé: {formsemestre.titre_annee()}")
Scolog.logdb(
method="formsemestre_desinscription",
etudid=etudid,
msg=f"desinscription semestre {formsemestre_id}",
commit=True,
)
def do_formsemestre_inscription_with_modules( def do_formsemestre_inscription_with_modules(
formsemestre_id, formsemestre_id,

View File

@ -369,10 +369,23 @@ class BasePreferences:
"emails_notifications", "emails_notifications",
{ {
"initvalue": "", "initvalue": "",
"title": "e-mails à qui notifier les opérations", "title": "e-mail(s) à qui notifier les opérations",
"size": 70, "size": 70,
"explanation": """adresses séparées par des virgules; notifie les opérations "explanation": """optionnel; adresses séparées par des virgules;
(saisies de notes, etc). notifie les opérations (saisies de notes, etc).
""",
"category": "general",
"only_global": False, # peut être spécifique à un semestre
},
),
(
"emails_notifications_inscriptions",
{
"initvalue": "",
"title": "e-mail(s) à qui notifier les inscriptions d'étudiants",
"size": 70,
"explanation": """optionnel; adresses séparées par des virgules;
notifie les inscriptions/désincriptions de chaque individu.
""", """,
"category": "general", "category": "general",
"only_global": False, # peut être spécifique à un semestre "only_global": False, # peut être spécifique à un semestre
@ -2321,6 +2334,7 @@ class BasePreferences:
<option value="create">Spécifier valeur pour ce <option value="create">Spécifier valeur pour ce
semestre seulement</option> semestre seulement</option>
</select> </select>
<span class="pref-comment">{descr["comment"]}</span>
""" """
descr["explanation"] = menu_global descr["explanation"] = menu_global
@ -2385,7 +2399,6 @@ class SemPreferences:
def edit(self, categories=[]): def edit(self, categories=[]):
"""Dialog to edit semestre preferences in given categories""" """Dialog to edit semestre preferences in given categories"""
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_formsemestre
if not self.formsemestre_id: if not self.formsemestre_id:
raise ScoValueError( raise ScoValueError(

View File

@ -3320,6 +3320,12 @@ li.tf-msg {
padding-bottom: 5px; padding-bottom: 5px;
} }
.pref-comment {
font-style: italic;
font-size: small;
color: var(--sco-color-explication);
}
div.formsemestre-warning-box { div.formsemestre-warning-box {
background-color: yellow; background-color: yellow;
border-radius: 4px; border-radius: 4px;