Fix delete etud and delete dept

This commit is contained in:
Emmanuel Viennet 2023-10-26 16:15:29 +02:00
parent 5a41f9c1c3
commit c723cef66c
3 changed files with 50 additions and 49 deletions

View File

@ -405,6 +405,8 @@ def delete_dept(dept_id: int) -> str:
"delete from scolar_news where dept_id = %(dept_id)s", "delete from scolar_news where dept_id = %(dept_id)s",
"delete from notes_semset where dept_id = %(dept_id)s", "delete from notes_semset where dept_id = %(dept_id)s",
"delete from notes_formations where dept_id = %(dept_id)s", "delete from notes_formations where dept_id = %(dept_id)s",
"delete from itemsuivi_tags where dept_id = %(dept_id)s",
"delete from identite where dept_id = %(dept_id)s",
"delete from departement where id = %(dept_id)s", "delete from departement where id = %(dept_id)s",
"drop table tags_temp", "drop table tags_temp",
"drop table formations_temp", "drop table formations_temp",

View File

@ -385,11 +385,11 @@ class BasePreferences:
"size": 40, "size": 40,
"explanation": f"""adresse expéditeur pour tous les envois par mail "explanation": f"""adresse expéditeur pour tous les envois par mail
(bulletins, notifications, etc.). Si vide, utilise la config globale. (bulletins, notifications, etc.). Si vide, utilise la config globale.
Pour les comptes (mot de passe), voir la config globale accessible Pour les comptes (mot de passe), voir la config globale accessible
en tant qu'administrateur depuis la <a class="stdlink" href="{ en tant qu'administrateur depuis la <a class="stdlink" href="{
url_for("scodoc.index") url_for("scodoc.index")
}">page d'accueil</a>. }">page d'accueil</a>.
""", """,
"category": "misc", "category": "misc",
"only_global": True, "only_global": True,
@ -419,8 +419,8 @@ class BasePreferences:
{ {
"initvalue": 0, "initvalue": 0,
"title": "BUT: moyenne générale sans les UE sans notes", "title": "BUT: moyenne générale sans les UE sans notes",
"explanation": """La moyenne générale indicative BUT est basée sur les moyennes d'UE pondérées par leurs ECTS. "explanation": """La moyenne générale indicative BUT est basée sur les moyennes d'UE pondérées par leurs ECTS.
Si cette option est cochée, ne prend pas en compte les UEs sans notes. <b>Attention: changer ce réglage va modifier toutes Si cette option est cochée, ne prend pas en compte les UEs sans notes. <b>Attention: changer ce réglage va modifier toutes
les moyennes du semestre !</b>. Aucun effet dans les formations non BUT.""", les moyennes du semestre !</b>. Aucun effet dans les formations non BUT.""",
"input_type": "boolcheckbox", "input_type": "boolcheckbox",
"category": "apc", "category": "apc",
@ -583,16 +583,16 @@ class BasePreferences:
"initvalue": """ "initvalue": """
--- Ceci est un message de notification automatique issu de ScoDoc --- --- Ceci est un message de notification automatique issu de ScoDoc ---
L'étudiant %(nomprenom)s L'étudiant %(nomprenom)s
L'étudiant %(nomprenom)s L'étudiant %(nomprenom)s
L'étudiant %(nomprenom)s L'étudiant %(nomprenom)s
inscrit en %(inscription)s) inscrit en %(inscription)s)
inscrit en %(inscription)s) inscrit en %(inscription)s)
inscrit en %(inscription)s) inscrit en %(inscription)s)
a cumulé %(nbabsjust)s absences justifiées a cumulé %(nbabsjust)s absences justifiées
a cumulé %(nbabsjust)s absences justifiées a cumulé %(nbabsjust)s absences justifiées
a cumulé %(nbabsjust)s absences justifiées a cumulé %(nbabsjust)s absences justifiées
et %(nbabsnonjust)s absences NON justifiées. et %(nbabsnonjust)s absences NON justifiées.
Le compte a pu changer depuis cet envoi, voir la fiche sur %(url_ficheetud)s. Le compte a pu changer depuis cet envoi, voir la fiche sur %(url_ficheetud)s.
@ -626,10 +626,11 @@ class BasePreferences:
"forcer_module", "forcer_module",
{ {
"initvalue": 0, "initvalue": 0,
"title": "Forcer la déclaration du module.", "title": "Imposer la déclaration du module",
"input_type": "boolcheckbox", "input_type": "boolcheckbox",
"labels": ["non", "oui"], "labels": ["non", "oui"],
"category": "assi", "category": "assi",
"explanation": "toute saisie d'absence doit indiquer le module concerné",
}, },
), ),
# ( # (
@ -1047,17 +1048,17 @@ class BasePreferences:
( (
"PV_INTRO", "PV_INTRO",
{ {
"initvalue": """<bullet>-</bullet> "initvalue": """<bullet>-</bullet>
Vu l'arrêté du 3 août 2005 relatif au diplôme universitaire de technologie et notamment son article 4 et 6; Vu l'arrêté du 3 août 2005 relatif au diplôme universitaire de technologie et notamment son article 4 et 6;
</para> </para>
<para><bullet>-</bullet> <para><bullet>-</bullet>
<para><bullet>-</bullet> <para><bullet>-</bullet>
<para><bullet>-</bullet> <para><bullet>-</bullet>
vu l'arrêté n° %(Decnum)s du Président de l'%(UnivName)s; vu l'arrêté n° %(Decnum)s du Président de l'%(UnivName)s;
</para> </para>
<para><bullet>-</bullet> <para><bullet>-</bullet>
<para><bullet>-</bullet> <para><bullet>-</bullet>
<para><bullet>-</bullet> <para><bullet>-</bullet>
vu la délibération de la commission %(Type)s en date du %(Date)s présidée par le Chef du département; vu la délibération de la commission %(Type)s en date du %(Date)s présidée par le Chef du département;
""", """,
"title": """Paragraphe d'introduction sur le PV""", "title": """Paragraphe d'introduction sur le PV""",
@ -1206,9 +1207,9 @@ class BasePreferences:
<para spaceBefore="10mm" fontSize="14" leftindent="0"> <para spaceBefore="10mm" fontSize="14" leftindent="0">
Le jury de %(type_jury_abbrv)s du département %(DeptName)s Le jury de %(type_jury_abbrv)s du département %(DeptName)s
s'est réuni le %(date_jury)s. s'est réuni le %(date_jury)s.
s'est réuni le %(date_jury)s. s'est réuni le %(date_jury)s.
s'est réuni le %(date_jury)s. s'est réuni le %(date_jury)s.
</para> </para>
<para fontSize="14" leftindent="0">Les décisions vous concernant sont : <para fontSize="14" leftindent="0">Les décisions vous concernant sont :
</para> </para>

View File

@ -42,6 +42,7 @@ from flask_json import as_json
from flask_login import current_user from flask_login import current_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed from flask_wtf.file import FileField, FileAllowed
import sqlalchemy as sa
from wtforms import SubmitField from wtforms import SubmitField
import app import app
@ -1853,22 +1854,16 @@ def etud_copy_in_other_dept(etudid: int):
) )
@bp.route("/etudident_delete", methods=["GET", "POST"]) @bp.route("/etudident_delete/<int:etudid>", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.EtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def etudident_delete(etudid, dialog_confirmed=False): def etudident_delete(etudid: int = -1, dialog_confirmed=False):
"Delete a student" "Delete a student"
cnx = ndb.GetDBConnexion() etud = Identite.get_etud(etudid)
etuds = sco_etud.etudident_list(cnx, {"etudid": etudid})
if not etuds:
raise ScoValueError("Étudiant inexistant !")
else:
etud = etuds[0]
sco_etud.fill_etuds_info([etud])
if not dialog_confirmed: if not dialog_confirmed:
return scu.confirm_dialog( return scu.confirm_dialog(
"""<h2>Confirmer la suppression de l'étudiant <b>{e[nomprenom]}</b> ?</h2> f"""<h2>Confirmer la suppression de l'étudiant <b>{etud.nomprenom}</b> ?</h2>
</p> </p>
<p style="top-margin: 2ex; bottom-margin: 2ex;">Prenez le temps de vérifier <p style="top-margin: 2ex; bottom-margin: 2ex;">Prenez le temps de vérifier
que vous devez vraiment supprimer cet étudiant ! que vous devez vraiment supprimer cet étudiant !
@ -1877,16 +1872,13 @@ def etudident_delete(etudid, dialog_confirmed=False):
efface toute trace de l'étudiant: inscriptions, <b>notes</b>, absences... efface toute trace de l'étudiant: inscriptions, <b>notes</b>, absences...
dans <b>tous les semestres</b> qu'il a fréquenté. dans <b>tous les semestres</b> qu'il a fréquenté.
</p> </p>
<p>Dans la plupart des cas, vous avez seulement besoin de le <ul>désinscrire</ul> <p>Dans la plupart des cas, vous avez seulement besoin de le <b>désinscrire</b>
d'un semestre ? (dans ce cas passez par sa fiche, menu associé au semestre)</p> d'un semestre ! (pour cela, passez par sa fiche, menu associé au semestre)</p>
<p><a href="{fiche_url}">Vérifier la fiche de {e[nomprenom]}</a> <p><a class="stdlink" href="{url_for(
</p>""".format(
e=etud,
fiche_url=url_for(
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid "scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
), )}">Vérifier la fiche de {etud.nomprenom}</a>
), </p>""",
dest_url="", dest_url="",
cancel_url=url_for( cancel_url=url_for(
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid "scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
@ -1894,13 +1886,19 @@ def etudident_delete(etudid, dialog_confirmed=False):
OK="Supprimer définitivement cet étudiant", OK="Supprimer définitivement cet étudiant",
parameters={"etudid": etudid}, parameters={"etudid": etudid},
) )
log("etudident_delete: etudid=%(etudid)s nomprenom=%(nomprenom)s" % etud) log(f"etudident_delete: {etud}")
formsemestre_ids_to_inval = [
ins.formsemestre_id for ins in etud.formsemestre_inscriptions
]
# delete in all tables ! # delete in all tables !
# c'est l'ancienne façon de gérer les cascades dans notre pseudo-ORM :) # c'est l'ancienne façon de gérer les cascades dans notre pseudo-ORM :)
tables = [ tables = [
"notes_appreciations", "notes_appreciations",
"scolar_autorisation_inscription", "scolar_autorisation_inscription",
"scolar_formsemestre_validation", "scolar_formsemestre_validation",
"apc_validation_rcue",
"apc_validation_annee",
"scolar_events", "scolar_events",
"notes_notes_log", "notes_notes_log",
"notes_notes", "notes_notes",
@ -1914,14 +1912,14 @@ def etudident_delete(etudid, dialog_confirmed=False):
"absences_notifications", "absences_notifications",
"billet_absence", "billet_absence",
] ]
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
for table in tables: for table in tables:
cursor.execute("delete from %s where etudid=%%(etudid)s" % table, etud) db.session.execute(
cursor.execute("delete from identite where id=%(etudid)s", etud) sa.text(f"""delete from {table} where etudid=:etudid"""), {"etudid": etudid}
cnx.commit() )
db.session.delete(etud)
db.session.commit()
# Inval semestres où il était inscrit: # Inval semestres où il était inscrit:
to_inval = [s["formsemestre_id"] for s in etud["sems"]] for formsemestre_id in formsemestre_ids_to_inval:
for formsemestre_id in to_inval:
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id) sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
flash("Étudiant supprimé !") flash("Étudiant supprimé !")
return flask.redirect(scu.ScoURL()) return flask.redirect(scu.ScoURL())