From 6a48d5bbcf114702929e5a7e1855b99547d877e8 Mon Sep 17 00:00:00 2001 From: ilona Date: Thu, 22 Aug 2024 16:42:38 +0200 Subject: [PATCH] =?UTF-8?q?Pr=C3=A9f.=20pour=20envoi=20d=E2=80=99une=20not?= =?UTF-8?q?ification=20mail=20=C3=A0=20chaque=20(de)inscription?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/formsemestre.py | 51 ++++++++++++++++++++- app/scodoc/sco_formsemestre_exterieurs.py | 1 - app/scodoc/sco_formsemestre_inscriptions.py | 22 +++------ app/scodoc/sco_preferences.py | 21 +++++++-- app/static/css/scodoc.css | 6 +++ 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index 34d34aad..9c73cf58 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -23,7 +23,7 @@ from sqlalchemy.sql import text from sqlalchemy import func 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 import models 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()}", 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) 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( self, with_default=True, only_listed=False ) -> list[Partition]: diff --git a/app/scodoc/sco_formsemestre_exterieurs.py b/app/scodoc/sco_formsemestre_exterieurs.py index 4ba6a47a..b4c49c21 100644 --- a/app/scodoc/sco_formsemestre_exterieurs.py +++ b/app/scodoc/sco_formsemestre_exterieurs.py @@ -51,7 +51,6 @@ import app.scodoc.sco_utils as scu from app import log from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message 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_inscriptions from app.scodoc import sco_formsemestre_validation diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index f77d1d85..a7650be2 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -182,12 +182,11 @@ def do_formsemestre_desinscription( if check_has_dec_jury: check_if_has_decision_jury(formsemestre, [etudid]) - insem = do_formsemestre_inscription_list( - args={"formsemestre_id": formsemestre_id, "etudid": etudid} - ) - if not insem: + inscr_sem = FormSemestreInscription.query.filter_by( + etudid=etudid, formsemestre_id=formsemestre_id + ).first() + if not inscr_sem: raise ScoValueError(f"{etud.nomprenom} n'est pas inscrit au semestre !") - insem = insem[0] # -- desinscription de tous les modules cnx = ndb.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) @@ -211,10 +210,8 @@ def do_formsemestre_desinscription( Partition.formsemestre_remove_etud(formsemestre_id, etud) # -- désincription du semestre - do_formsemestre_inscription_delete( - insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id - ) - sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id) + formsemestre.desinscrit_etudiant(etud) + # --- Semestre extérieur if formsemestre.modalite == "EXT": if 0 == len(formsemestre.inscriptions): @@ -226,13 +223,6 @@ def do_formsemestre_desinscription( db.session.commit() 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( formsemestre_id, diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index 6b940076..90d4cc43 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -369,10 +369,23 @@ class BasePreferences: "emails_notifications", { "initvalue": "", - "title": "e-mails à qui notifier les opérations", + "title": "e-mail(s) à qui notifier les opérations", "size": 70, - "explanation": """adresses séparées par des virgules; notifie les opérations - (saisies de notes, etc). + "explanation": """optionnel; adresses séparées par des virgules; + 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", "only_global": False, # peut être spécifique à un semestre @@ -2321,6 +2334,7 @@ class BasePreferences: + {descr["comment"]} """ descr["explanation"] = menu_global @@ -2385,7 +2399,6 @@ class SemPreferences: def edit(self, categories=[]): """Dialog to edit semestre preferences in given categories""" from app.scodoc import html_sco_header - from app.scodoc import sco_formsemestre if not self.formsemestre_id: raise ScoValueError( diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 783ac666..5b80c194 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -3320,6 +3320,12 @@ li.tf-msg { padding-bottom: 5px; } +.pref-comment { + font-style: italic; + font-size: small; + color: var(--sco-color-explication); +} + div.formsemestre-warning-box { background-color: yellow; border-radius: 4px;