diff --git a/app/scodoc/sco_dept.py b/app/scodoc/sco_dept.py index 189a8715..eacfe043 100644 --- a/app/scodoc/sco_dept.py +++ b/app/scodoc/sco_dept.py @@ -405,6 +405,8 @@ def delete_dept(dept_id: int) -> str: "delete from scolar_news 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 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", "drop table tags_temp", "drop table formations_temp", diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index eb82de4c..cab6feae 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -385,11 +385,11 @@ class BasePreferences: "size": 40, "explanation": f"""adresse expéditeur pour tous les envois par mail (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 page d'accueil. - + """, "category": "misc", "only_global": True, @@ -419,8 +419,8 @@ class BasePreferences: { "initvalue": 0, "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. - Si cette option est cochée, ne prend pas en compte les UEs sans notes. Attention: changer ce réglage va modifier toutes + "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. Attention: changer ce réglage va modifier toutes les moyennes du semestre !. Aucun effet dans les formations non BUT.""", "input_type": "boolcheckbox", "category": "apc", @@ -583,16 +583,16 @@ class BasePreferences: "initvalue": """ --- Ceci est un message de notification automatique issu de ScoDoc --- - L'étudiant %(nomprenom)s - L'étudiant %(nomprenom)s - L'étudiant %(nomprenom)s - inscrit en %(inscription)s) - inscrit en %(inscription)s) - inscrit en %(inscription)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) - 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. Le compte a pu changer depuis cet envoi, voir la fiche sur %(url_ficheetud)s. @@ -626,10 +626,11 @@ class BasePreferences: "forcer_module", { "initvalue": 0, - "title": "Forcer la déclaration du module.", + "title": "Imposer la déclaration du module", "input_type": "boolcheckbox", "labels": ["non", "oui"], "category": "assi", + "explanation": "toute saisie d'absence doit indiquer le module concerné", }, ), # ( @@ -1047,17 +1048,17 @@ class BasePreferences: ( "PV_INTRO", { - "initvalue": """- + "initvalue": """- 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é n° %(Decnum)s du Président de l'%(UnivName)s; - - - - - - + - + - + - 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""", @@ -1206,9 +1207,9 @@ class BasePreferences: 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. Les décisions vous concernant sont : diff --git a/app/views/scolar.py b/app/views/scolar.py index 02cd2984..0388c4c2 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -42,6 +42,7 @@ from flask_json import as_json from flask_login import current_user from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileAllowed +import sqlalchemy as sa from wtforms import SubmitField 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/", methods=["GET", "POST"]) @scodoc @permission_required(Permission.EtudInscrit) @scodoc7func -def etudident_delete(etudid, dialog_confirmed=False): +def etudident_delete(etudid: int = -1, dialog_confirmed=False): "Delete a student" - cnx = ndb.GetDBConnexion() - 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]) + etud = Identite.get_etud(etudid) if not dialog_confirmed: return scu.confirm_dialog( - """

Confirmer la suppression de l'étudiant {e[nomprenom]} ?

+ f"""

Confirmer la suppression de l'étudiant {etud.nomprenom} ?

Prenez le temps de vérifier 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, notes, absences... dans tous les semestres qu'il a fréquenté.

-

Dans la plupart des cas, vous avez seulement besoin de le

    désinscrire
- d'un semestre ? (dans ce cas passez par sa fiche, menu associé au semestre)

+

Dans la plupart des cas, vous avez seulement besoin de le désinscrire + d'un semestre ! (pour cela, passez par sa fiche, menu associé au semestre)

-

Vérifier la fiche de {e[nomprenom]} -

""".format( - e=etud, - fiche_url=url_for( +

Vérifier la fiche de {etud.nomprenom} +

""", dest_url="", cancel_url=url_for( "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", 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 ! # c'est l'ancienne façon de gérer les cascades dans notre pseudo-ORM :) tables = [ "notes_appreciations", "scolar_autorisation_inscription", "scolar_formsemestre_validation", + "apc_validation_rcue", + "apc_validation_annee", "scolar_events", "notes_notes_log", "notes_notes", @@ -1914,14 +1912,14 @@ def etudident_delete(etudid, dialog_confirmed=False): "absences_notifications", "billet_absence", ] - cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) for table in tables: - cursor.execute("delete from %s where etudid=%%(etudid)s" % table, etud) - cursor.execute("delete from identite where id=%(etudid)s", etud) - cnx.commit() + db.session.execute( + sa.text(f"""delete from {table} where etudid=:etudid"""), {"etudid": etudid} + ) + db.session.delete(etud) + db.session.commit() # Inval semestres où il était inscrit: - to_inval = [s["formsemestre_id"] for s in etud["sems"]] - for formsemestre_id in to_inval: + for formsemestre_id in formsemestre_ids_to_inval: sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id) flash("Étudiant supprimé !") return flask.redirect(scu.ScoURL())