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["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;