From cbe039ff75ef19dedfa96def1e3111afce3e8baf Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 20 Mar 2023 11:17:38 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Rationalise=20acc=C3=A8s=20Etudiant=20et=20?= =?UTF-8?q?FormSemestre,=20avec=20contr=C3=B4le=20syst=C3=A9matique=20du?= =?UTF-8?q?=20d=C3=A9partement.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/billets_absences.py | 5 +---- app/but/bulletin_but_xml_compat.py | 7 +++--- app/but/jury_but_pv.py | 7 +++--- app/but/jury_but_results.py | 2 +- app/but/jury_but_validation_auto.py | 2 +- app/but/jury_but_view.py | 2 +- app/comp/res_classic.py | 2 +- app/comp/res_common.py | 2 +- app/models/but_validations.py | 2 +- app/models/etudiants.py | 13 +++++++++-- app/models/formsemestre.py | 9 ++++++++ app/pe/pe_jurype.py | 2 +- app/pe/pe_semestretag.py | 2 +- app/scodoc/sco_abs_billets.py | 2 +- app/scodoc/sco_abs_notification.py | 2 +- app/scodoc/sco_abs_views.py | 4 ++-- app/scodoc/sco_apogee_csv.py | 4 ++-- app/scodoc/sco_archives.py | 2 +- app/scodoc/sco_bulletins.py | 2 +- app/scodoc/sco_bulletins_json.py | 4 ++-- app/scodoc/sco_bulletins_pdf.py | 2 +- app/scodoc/sco_bulletins_xml.py | 4 ++-- app/scodoc/sco_cost_formation.py | 2 +- app/scodoc/sco_cursus.py | 4 ++-- app/scodoc/sco_cursus_dut.py | 2 +- app/scodoc/sco_etape_apogee.py | 2 +- app/scodoc/sco_evaluation_edit.py | 2 +- app/scodoc/sco_evaluations.py | 6 +++--- app/scodoc/sco_export_results.py | 2 +- app/scodoc/sco_formsemestre_edit.py | 2 +- app/scodoc/sco_formsemestre_exterieurs.py | 6 +++--- app/scodoc/sco_formsemestre_inscriptions.py | 16 ++++++-------- app/scodoc/sco_formsemestre_status.py | 8 +++---- app/scodoc/sco_formsemestre_validation.py | 13 ++++++----- app/scodoc/sco_groups.py | 10 ++++----- app/scodoc/sco_liste_notes.py | 6 ++++-- app/scodoc/sco_moduleimpl_inscriptions.py | 4 ++-- app/scodoc/sco_page_etud.py | 2 +- app/scodoc/sco_photos.py | 2 +- app/scodoc/sco_prepajury.py | 2 +- app/scodoc/sco_pv_dict.py | 2 +- app/scodoc/sco_pv_forms.py | 4 ++-- app/scodoc/sco_pv_lettres_inviduelles.py | 4 ++-- app/scodoc/sco_recapcomplet.py | 10 ++++----- app/scodoc/sco_report.py | 8 +++---- app/scodoc/sco_saisie_notes.py | 4 ++-- app/scodoc/sco_ue_external.py | 2 +- app/tables/list_etuds.py | 2 +- app/tables/recap.py | 2 +- app/views/__init__.py | 4 ++-- app/views/absences.py | 2 +- app/views/notes.py | 24 +++++++++------------ app/views/scodoc.py | 2 +- app/views/scolar.py | 16 +++++--------- sco_version.py | 2 +- scodoc.py | 10 ++++----- tests/bench/notes_table.py | 2 +- tests/unit/test_but_ues.py | 2 +- tests/unit/test_sco_basic.py | 2 +- 59 files changed, 141 insertions(+), 137 deletions(-) diff --git a/app/api/billets_absences.py b/app/api/billets_absences.py index 7ed0f119..44e6b3a3 100644 --- a/app/api/billets_absences.py +++ b/app/api/billets_absences.py @@ -49,10 +49,7 @@ def billets_absence_create(): return json_error( 404, message="Paramètre manquant: etudid, abs_begin, abs_end requis" ) - query = Identite.query.filter_by(etudid=etudid) - if g.scodoc_dept: - query = query.filter_by(dept_id=g.scodoc_dept_id) - etud = query.first_or_404() + etud = Identite.get_etud(etudid) billet = BilletAbsence( etudid=etud.id, abs_begin=abs_begin, diff --git a/app/but/bulletin_but_xml_compat.py b/app/but/bulletin_but_xml_compat.py index 74f5409c..0bb1b902 100644 --- a/app/but/bulletin_but_xml_compat.py +++ b/app/but/bulletin_but_xml_compat.py @@ -65,11 +65,10 @@ def bulletin_but_xml_compat( from app.scodoc import sco_bulletins log( - "bulletin_but_xml_compat( formsemestre_id=%s, etudid=%s )" - % (formsemestre_id, etudid) + f"bulletin_but_xml_compat( formsemestre_id={formsemestre_id}, etudid={etudid} )" ) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) - etud: Identite = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) results = bulletin_but.ResultatsSemestreBUT(formsemestre) nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT] # etat_inscription = etud.inscription_etat(formsemestre.id) diff --git a/app/but/jury_but_pv.py b/app/but/jury_but_pv.py index ea9e66bb..e3119b27 100644 --- a/app/but/jury_but_pv.py +++ b/app/but/jury_but_pv.py @@ -46,7 +46,7 @@ def pvjury_page_but(formsemestre_id: int, fmt="html"): """Page récapitulant les décisions de jury BUT formsemestre peut être pair ou impair """ - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) assert formsemestre.formation.is_apc() title = "Procès-verbal de jury BUT" if fmt == "html": @@ -65,7 +65,8 @@ def pvjury_page_but(formsemestre_id: int, fmt="html"): columns_ids=titles.keys(), html_caption=title, html_class="pvjury_table_but table_leftalign", - html_title=f"""
{title} + html_title=f"""
{title} dict: """Résultats de jury d'un étudiant sur un semestre pair de BUT""" - etud: Identite = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) dec_etud = dpv["decisions_dict"][etudid] if formsemestre.formation.is_apc(): deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) diff --git a/app/but/jury_but_validation_auto.py b/app/but/jury_but_validation_auto.py index 674389b5..deae9b59 100644 --- a/app/but/jury_but_validation_auto.py +++ b/app/but/jury_but_validation_auto.py @@ -36,7 +36,7 @@ def formsemestre_validation_auto_but( nb_etud_modif = 0 with sco_cache.DeferredSemCacheManager(): for etudid in formsemestre.etuds_inscriptions: - etud: Identite = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) nb_etud_modif += deca.record_all( no_overwrite=no_overwrite, only_validantes=only_adm diff --git a/app/but/jury_but_view.py b/app/but/jury_but_view.py index 60bfa793..0a20e933 100644 --- a/app/but/jury_but_view.py +++ b/app/but/jury_but_view.py @@ -519,7 +519,7 @@ def infos_fiche_etud_html(etudid: int) -> str: """Section html pour fiche etudiant provisoire pour BUT 2022 """ - etud: Identite = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) inscriptions = ( FormSemestreInscription.query.join(FormSemestreInscription.formsemestre) .filter( diff --git a/app/comp/res_classic.py b/app/comp/res_classic.py index 27ec5cc3..268ea0fb 100644 --- a/app/comp/res_classic.py +++ b/app/comp/res_classic.py @@ -230,7 +230,7 @@ class ResultatsSemestreClassic(NotesTableCompat): f"""* oups: calcul coef UE impossible\nformsemestre_id='{self.formsemestre.id }'\netudid='{etudid}'\nue={ue}""" ) - etud: Identite = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) raise ScoValueError( f"""

Coefficient de l'UE capitalisée {ue.acronyme} impossible à déterminer pour l'étudiant "Identite": """Étudiant à partir de l'etudid ou du code_nip, soit passés en argument soit retrouvés directement dans la requête web. Erreur 404 si inexistant. """ args = make_etud_args(etudid=etudid, code_nip=code_nip) - return Identite.query.filter_by(**args).first_or_404() + return cls.query.filter_by(**args).first_or_404() + + @classmethod + def get_etud(cls, etudid: int) -> "Identite": + """Etudiant ou 404, cherche uniquement dans le département courant""" + if g.scodoc_dept: + return cls.query.filter_by( + id=etudid, dept_id=g.scodoc_dept_id + ).first_or_404() + return cls.query.filter_by(id=etudid).first_or_404() @classmethod def create_etud(cls, **args): diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index 6b832a88..d48b6b15 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -159,6 +159,15 @@ class FormSemestre(db.Model): def __repr__(self): return f"<{self.__class__.__name__} {self.id} {self.titre_annee()}>" + @classmethod + def get_formsemestre(cls, formsemestre_id: int) -> "FormSemestre": + """ "FormSemestre ou 404, cherche uniquement dans le département courant""" + if g.scodoc_dept: + return cls.query.filter_by( + id=formsemestre_id, dept_id=g.scodoc_dept_id + ).first_or_404() + return cls.query.filter_by(id=formsemestre_id).first_or_404() + def sort_key(self) -> tuple: """clé pour tris par ordre alphabétique (pour avoir le plus récent d'abord, sort avec reverse=True)""" diff --git a/app/pe/pe_jurype.py b/app/pe/pe_jurype.py index f55623d3..a18626d6 100644 --- a/app/pe/pe_jurype.py +++ b/app/pe/pe_jurype.py @@ -1135,7 +1135,7 @@ class JuryPE(object): # ------------------------------------------------------------------------------------------------------------------ def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat: """Charge la table des notes d'un formsemestre""" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) return res_sem.load_formsemestre_results(formsemestre) # ------------------------------------------------------------------------------------------------------------------ diff --git a/app/pe/pe_semestretag.py b/app/pe/pe_semestretag.py index 2db20732..037fdad7 100644 --- a/app/pe/pe_semestretag.py +++ b/app/pe/pe_semestretag.py @@ -277,7 +277,7 @@ class SemestreTag(pe_tagtable.TableTag): fid_prec = fids_prec[0] # Lecture des notes de ce semestre # le tableau de note du semestre considéré: - formsemestre_prec = FormSemestre.query.get_or_404(fid_prec) + formsemestre_prec = FormSemestre.get_formsemestre(fid_prec) nt_prec: NotesTableCompat = res_sem.load_formsemestre_results( formsemestre_prec ) diff --git a/app/scodoc/sco_abs_billets.py b/app/scodoc/sco_abs_billets.py index 5f52e8f7..cdee2373 100644 --- a/app/scodoc/sco_abs_billets.py +++ b/app/scodoc/sco_abs_billets.py @@ -65,7 +65,7 @@ def table_billets_etud( etudid: int = None, etat: bool = None, with_links=True ) -> GenTable: """Page avec table billets.""" - etud = Identite.query.get_or_404(etudid) if etudid is not None else None + etud = Identite.get_etud(etudid) if etudid is not None else None billets = query_billets_etud(etudid, etat) return table_billets(billets, etud=etud, with_links=with_links) diff --git a/app/scodoc/sco_abs_notification.py b/app/scodoc/sco_abs_notification.py index c5d23845..c01aa491 100644 --- a/app/scodoc/sco_abs_notification.py +++ b/app/scodoc/sco_abs_notification.py @@ -272,7 +272,7 @@ def retreive_current_formsemestre(etudid: int, cur_date) -> Optional[FormSemestr if not r: return None # s'il y a plusieurs semestres, prend le premier (rarissime et non significatif): - formsemestre = FormSemestre.query.get(r[0]["formsemestre_id"]) + formsemestre = FormSemestre.get_formsemestre(r[0]["formsemestre_id"]) return formsemestre diff --git a/app/scodoc/sco_abs_views.py b/app/scodoc/sco_abs_views.py index bb585930..f3473bf5 100644 --- a/app/scodoc/sco_abs_views.py +++ b/app/scodoc/sco_abs_views.py @@ -119,7 +119,7 @@ def doSignaleAbsence( if moduleimpl_id and moduleimpl_id != "NULL": mod = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] formsemestre_id = mod["formsemestre_id"] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ues = nt.get_ues_stat_dict() for ue in ues: @@ -187,7 +187,7 @@ def SignaleAbsenceEtud(): # etudid implied menu_module = "" else: formsemestre_id = etud["cursem"]["formsemestre_id"] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ues = nt.get_ues_stat_dict() require_module = sco_preferences.get_preference( diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 28a02a69..a19dca83 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -293,7 +293,7 @@ class ApoEtud(dict): """ # futur: #WIP - # etud: Identite = Identite.query.filter_by(code_nip=self["nip"]).first() + # etud: Identite = Identite.query.filter_by(code_nip=self["nip"], dept_id=g.scodoc_dept_id).first() # self.etud = etud etuds = sco_etud.get_etud_info(code_nip=self["nip"], filled=True) if not etuds: @@ -478,7 +478,7 @@ class ApoEtud(dict): # pas de code semestre en APC ! return dict(N="", B=20, J="", R="", M="") if decision is None: - etud = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) nomprenom = etud.nomprenom if etud else "(inconnu)" raise ScoValueError( f"decision absente pour l'étudiant {nomprenom} ({etudid})" diff --git a/app/scodoc/sco_archives.py b/app/scodoc/sco_archives.py index c95add7d..fce36c22 100644 --- a/app/scodoc/sco_archives.py +++ b/app/scodoc/sco_archives.py @@ -318,7 +318,7 @@ def do_formsemestre_archive( gen_formsemestre_recapcomplet_json, ) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) sem_archive_id = formsemestre_id archive_id = PVArchive.create_obj_archive(sem_archive_id, description) diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index 1db285ea..82191269 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -147,7 +147,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"): raise ValueError("invalid version code !") prefs = sco_preferences.SemPreferences(formsemestre_id) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) if not nt.get_etud_etat(etudid): raise ScoValueError("Étudiant non inscrit à ce semestre") diff --git a/app/scodoc/sco_bulletins_json.py b/app/scodoc/sco_bulletins_json.py index 2239a21b..f7181487 100644 --- a/app/scodoc/sco_bulletins_json.py +++ b/app/scodoc/sco_bulletins_json.py @@ -105,9 +105,9 @@ def formsemestre_bulletinetud_published_dict( version = version[:-4] # enlève le "_mat" with_matieres = True - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) prefs = sco_preferences.SemPreferences(formsemestre_id) - etud = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) sem = sco_formsemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) diff --git a/app/scodoc/sco_bulletins_pdf.py b/app/scodoc/sco_bulletins_pdf.py index f99b2f99..314aff5d 100644 --- a/app/scodoc/sco_bulletins_pdf.py +++ b/app/scodoc/sco_bulletins_pdf.py @@ -256,7 +256,7 @@ def get_etud_bulletins_pdf(etudid, version="selectedevals"): "Bulletins pdf de tous les semestres de l'étudiant, et filename" from app.scodoc import sco_bulletins - etud: Identite = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) fragments = [] bookmarks = {} filigrannes = {} diff --git a/app/scodoc/sco_bulletins_xml.py b/app/scodoc/sco_bulletins_xml.py index 923181d2..e2ad7661 100644 --- a/app/scodoc/sco_bulletins_xml.py +++ b/app/scodoc/sco_bulletins_xml.py @@ -84,7 +84,7 @@ def make_xml_formsemestre_bulletinetud( log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid)) sem = sco_formsemestre.get_formsemestre(formsemestre_id) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if formsemestre.formation.is_apc(): return bulletin_but_xml_compat( formsemestre_id, @@ -156,7 +156,7 @@ def make_xml_formsemestre_bulletinetud( pid = partition["partition_id"] partitions_etud_groups[pid] = sco_groups.get_etud_groups_in_partition(pid) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ues = nt.get_ues_stat_dict() modimpls = nt.get_modimpls_dict() diff --git a/app/scodoc/sco_cost_formation.py b/app/scodoc/sco_cost_formation.py index 334d3a0a..87937b5e 100644 --- a/app/scodoc/sco_cost_formation.py +++ b/app/scodoc/sco_cost_formation.py @@ -55,7 +55,7 @@ def formsemestre_table_estim_cost( peut conduire à une sur-estimation du coût s'il y a des modules optionnels (dans ce cas, retoucher le tableau excel exporté). """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) rows = [] for modimpl in formsemestre.modimpls: diff --git a/app/scodoc/sco_cursus.py b/app/scodoc/sco_cursus.py index d4d996de..53def6f9 100644 --- a/app/scodoc/sco_cursus.py +++ b/app/scodoc/sco_cursus.py @@ -42,7 +42,7 @@ def get_situation_etud_cursus( etud: dict, formsemestre_id: int ) -> sco_cursus_dut.SituationEtudCursus: """renvoie une instance de SituationEtudCursus (ou sous-classe spécialisée)""" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) if formsemestre.formation.is_apc(): @@ -110,7 +110,7 @@ def list_formsemestre_utilisateurs_uecap(formsemestre_id): """Liste des formsemestres pouvant utiliser une UE capitalisee de ce semestre (et qui doivent donc etre sortis du cache si l'on modifie ce semestre): meme code formation, meme semestre_id, date posterieure""" - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) cursor = db.session.execute( text( diff --git a/app/scodoc/sco_cursus_dut.py b/app/scodoc/sco_cursus_dut.py index babaede7..3cf2897f 100644 --- a/app/scodoc/sco_cursus_dut.py +++ b/app/scodoc/sco_cursus_dut.py @@ -890,7 +890,7 @@ def formsemestre_validate_ues(formsemestre_id, etudid, code_etat_sem, assiduite) """ valid_semestre = code_etat_sem in CODES_SEM_VALIDES cnx = ndb.GetDBConnexion() - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ue_ids = [x["ue_id"] for x in nt.get_ues_stat_dict(filter_sport=True)] for ue_id in ue_ids: diff --git a/app/scodoc/sco_etape_apogee.py b/app/scodoc/sco_etape_apogee.py index 2be38c6d..ef60acca 100644 --- a/app/scodoc/sco_etape_apogee.py +++ b/app/scodoc/sco_etape_apogee.py @@ -381,7 +381,7 @@ print apo_csv_list_stored_archives() groups_infos = sco_groups_view.DisplayedGroupsInfos( [sco_groups.get_default_group(formsemestre_id)], formsemestre_id=formsemestre_id) -formsemestre = FormSemestre.query.get_or_404(formsemestre_id) +formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) # s = SemSet('NSS29902') diff --git a/app/scodoc/sco_evaluation_edit.py b/app/scodoc/sco_evaluation_edit.py index 6c418519..fd15fbf2 100644 --- a/app/scodoc/sco_evaluation_edit.py +++ b/app/scodoc/sco_evaluation_edit.py @@ -78,7 +78,7 @@ def evaluation_create_form( ] mod = modimpl_o["module"] formsemestre_id = modimpl_o["formsemestre_id"] - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = modimpl.formsemestre sem_ues = formsemestre.query_ues(with_sport=False).all() is_malus = mod["module_type"] == ModuleType.MALUS is_apc = mod["module_type"] in (ModuleType.RESSOURCE, ModuleType.SAE) diff --git a/app/scodoc/sco_evaluations.py b/app/scodoc/sco_evaluations.py index 9bfcfd4c..4626509f 100644 --- a/app/scodoc/sco_evaluations.py +++ b/app/scodoc/sco_evaluations.py @@ -379,7 +379,7 @@ def _eval_etat(evals): def do_evaluation_etat_in_sem(formsemestre_id): """-> nb_eval_completes, nb_evals_en_cours, nb_evals_vides, date derniere modif, attente""" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) evals = nt.get_evaluations_etats() etat = _eval_etat(evals) @@ -399,7 +399,7 @@ def do_evaluation_etat_in_mod(nt, moduleimpl_id): def formsemestre_evaluations_cal(formsemestre_id): """Page avec calendrier de toutes les evaluations de ce semestre""" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) evals = nt.get_evaluations_etats() @@ -534,7 +534,7 @@ def formsemestre_evaluations_delai_correction(formsemestre_id, format="html"): N'indique pas les évaluations de rattrapage ni celles des modules de bonus/malus. """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) evals = nt.get_evaluations_etats() diff --git a/app/scodoc/sco_export_results.py b/app/scodoc/sco_export_results.py index d4e9a378..01c6c536 100644 --- a/app/scodoc/sco_export_results.py +++ b/app/scodoc/sco_export_results.py @@ -77,7 +77,7 @@ def _build_results_table(start_date=None, end_date=None, types_parcours=[]): {} ) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud } for formsemestre_id in formsemestre_ids_parcours: - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() for etudid in etudids: diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index cdb8277a..266e364c 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -942,7 +942,7 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N mod = sco_edit_module.module_list({"module_id": module_id})[0] # --- Association des parcours if formsemestre is None: - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if "parcours" in tf[2]: formsemestre.parcours = [ ApcParcours.query.get(int(parcour_id_str)) diff --git a/app/scodoc/sco_formsemestre_exterieurs.py b/app/scodoc/sco_formsemestre_exterieurs.py index 404105ac..67f05d62 100644 --- a/app/scodoc/sco_formsemestre_exterieurs.py +++ b/app/scodoc/sco_formsemestre_exterieurs.py @@ -65,7 +65,7 @@ def formsemestre_ext_create(etudid, sem_params): # Check args _ = Formation.query.get_or_404(sem_params["formation_id"]) if etudid: - _ = Identite.query.get_or_404(etudid) + _ = Identite.get_etud(etudid) # Create formsemestre sem_params["modalite"] = "EXT" @@ -85,7 +85,7 @@ def formsemestre_ext_create(etudid, sem_params): def formsemestre_ext_create_form(etudid, formsemestre_id): """Formulaire création/inscription à un semestre extérieur""" - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) H = [ html_sco_header.sco_header(), f"""

Enregistrement d'une inscription antérieure dans un autre @@ -236,7 +236,7 @@ def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid): mais pas enregistrée. """ formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) ues = formsemestre.formation.ues.filter(UniteEns.type != UE_SPORT).order_by( UniteEns.semestre_idx, UniteEns.numero ) diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index 79f7f006..c12fa73a 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -149,9 +149,7 @@ def do_formsemestre_demission( event_date_iso = ndb.DateDMYtoISO(event_date) except ValueError as exc: raise ScoValueError("format de date invalide") from exc - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) # check lock formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id @@ -201,8 +199,8 @@ def do_formsemestre_desinscription(etudid, formsemestre_id): """ from app.scodoc import sco_formsemestre_edit - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) - etud = Identite.query.get_or_404(etudid) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) + etud = Identite.get_etud(etudid) # -- check lock if not formsemestre.etat: raise ScoValueError("désinscription impossible: semestre verrouille") @@ -282,7 +280,7 @@ def do_formsemestre_inscription_with_modules( group_ids = group_ids or [] if isinstance(group_ids, int): group_ids = [group_ids] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) # inscription au semestre args = {"formsemestre_id": formsemestre_id, "etudid": etudid} if etat is not None: @@ -418,7 +416,7 @@ def formsemestre_inscription_with_modules( if multiple_ok: multiple_ok = int(multiple_ok) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - etud: Identite = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) if etud.dept_id != formsemestre.dept_id: raise ScoValueError("l'étudiant n'est pas dans ce département") H = [ @@ -530,7 +528,7 @@ def formsemestre_inscription_option(etudid, formsemestre_id): raise ScoValueError("Modification impossible: semestre verrouille") etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) footer = html_sco_header.sco_footer() @@ -848,7 +846,7 @@ def list_inscrits_ailleurs(formsemestre_id): Pour chacun, donne la liste des semestres. { etudid : [ liste de sems ] } """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index 534c5afc..38bc79d6 100644 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -539,7 +539,7 @@ def formsemestre_page_title(formsemestre_id=None): except ValueError: log(f"formsemestre_id: invalid type {formsemestre_id:r}") return "" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) return render_template( "formsemestre_page_title.j2", @@ -1394,7 +1394,7 @@ def formsemestre_warning_etuds_sans_note( if nb_sans_notes < 5: # peu d'étudiants, affiche leurs noms etuds: list[Identite] = sorted( - [Identite.query.get(etudid) for etudid in etudids_sans_notes], + [Identite.get_etud(etudid) for etudid in etudids_sans_notes], key=lambda e: e.sort_key, ) noms = ", ".join( @@ -1437,7 +1437,7 @@ def formsemestre_note_etuds_sans_notes( if etudid: etudids_sans_notes = etudids_sans_notes.intersection({etudid}) etuds: list[Identite] = sorted( - [Identite.query.get_or_404(eid) for eid in etudids_sans_notes], + [Identite.get_etud(eid) for eid in etudids_sans_notes], key=lambda e: e.sort_key, ) if request.method == "POST": @@ -1458,7 +1458,7 @@ def formsemestre_note_etuds_sans_notes( message = """

aucun étudiant sans notes

""" else: flash( - f"""{Identite.query.get_or_404(etudid).nomprenom} + f"""{Identite.get_etud(etudid).nomprenom} a déjà des notes""" ) return redirect( diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index c5806fd2..6f0f3e7a 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -80,9 +80,8 @@ def formsemestre_validation_etud_form( formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() if not etudid and etud_index is None: @@ -136,7 +135,7 @@ def formsemestre_validation_etud_form( # Navigation suivant/precedent if etud_index_prev is not None: - etud_prev = Identite.query.get(T[etud_index_prev][-1]) + etud_prev = Identite.get_etud(T[etud_index_prev][-1]) url_prev = url_for( "notes.formsemestre_validation_etud_form", scodoc_dept=g.scodoc_dept, @@ -146,7 +145,7 @@ def formsemestre_validation_etud_form( else: url_prev = None if etud_index_next is not None: - etud_next = Identite.query.get(T[etud_index_next][-1]) + etud_next = Identite.get_etud(T[etud_index_next][-1]) url_next = url_for( "notes.formsemestre_validation_etud_form", scodoc_dept=g.scodoc_dept, @@ -934,7 +933,7 @@ def do_formsemestre_validation_auto(formsemestre_id): "Saisie automatisee des decisions d'un semestre" sem = sco_formsemestre.get_formsemestre(formsemestre_id) next_semestre_id = sem["semestre_id"] + 1 - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() nb_valid = 0 @@ -1201,7 +1200,7 @@ def do_formsemestre_validate_previous_ue( Si le coefficient est spécifié, modifie le coefficient de cette UE (utile seulement pour les semestres extérieurs). """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ue: UniteEns = UniteEns.query.get_or_404(ue_id) diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py index 36d6946c..8b1da28a 100644 --- a/app/scodoc/sco_groups.py +++ b/app/scodoc/sco_groups.py @@ -549,7 +549,7 @@ def XMLgetGroupsInPartition(partition_id): # was XMLgetGroupesTD t0 = time.time() partition = get_partition(partition_id) formsemestre_id = partition["formsemestre_id"] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) etuds_set = {ins.etudid for ins in formsemestre.inscriptions} groups = get_partition_groups(partition) @@ -745,6 +745,7 @@ def setGroups( log(msg) return xml_error(msg, code=403) formsemestre_id = partition["formsemestre_id"] + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if not sco_permissions_check.can_change_groups(formsemestre_id): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") log("***setGroups: partition_id=%s" % partition_id) @@ -821,7 +822,6 @@ def setGroups( change_etud_group_in_partition(etudid, group.id, partition) # Update parcours - formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre.update_inscriptions_parcours_from_groups() data = ( @@ -952,7 +952,7 @@ def edit_partition_form(formsemestre_id=None): # ad-hoc form if not sco_permissions_check.can_change_groups(formsemestre_id): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) partitions = get_partitions_list(formsemestre_id) arrow_up, arrow_down, arrow_none = get_arrow_icons_tags() suppricon = scu.icontag( @@ -1136,7 +1136,7 @@ def partition_delete(partition_id, force=False, redirect=1, dialog_confirmed=Fal formsemestre_id = partition["formsemestre_id"] if not sco_permissions_check.can_change_groups(formsemestre_id): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if not partition["partition_name"] and not force: raise ValueError("cannot suppress this partition") @@ -1404,7 +1404,7 @@ def groups_auto_repartition(partition_id=None): if not partition["groups_editable"]: raise AccessDenied("Partition non éditable") formsemestre_id = partition["formsemestre_id"] - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) # renvoie sur page édition groupes dest_url = url_for( "scolar.affect_groups", scodoc_dept=g.scodoc_dept, partition_id=partition_id diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py index ac3f94aa..c5443680 100644 --- a/app/scodoc/sco_liste_notes.py +++ b/app/scodoc/sco_liste_notes.py @@ -322,7 +322,9 @@ def _make_table_notes( for etudid, etat in etudid_etats: css_row_class = None # infos identite etudiant - etud = Identite.query.get(etudid) + etud: Identite = Identite.query.filter_by( + id=etudid, dept_id=g.scodoc_dept_id + ).first() if etud is None: continue @@ -825,7 +827,7 @@ def _add_moymod_column( ): """Ajoute la colonne moymod à rows""" col_id = "moymod" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) inscrits = formsemestre.etudids_actifs diff --git a/app/scodoc/sco_moduleimpl_inscriptions.py b/app/scodoc/sco_moduleimpl_inscriptions.py index 06c7ffb1..196051b0 100644 --- a/app/scodoc/sco_moduleimpl_inscriptions.py +++ b/app/scodoc/sco_moduleimpl_inscriptions.py @@ -264,7 +264,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id): """ authuser = current_user - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) is_apc = formsemestre.formation.is_apc() inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( @@ -678,7 +678,7 @@ def get_etuds_with_capitalized_ue(formsemestre_id: int) -> list[dict]: returns { ue_id : [ { infos } ] } """ ues_cap_info = collections.defaultdict(list) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( diff --git a/app/scodoc/sco_page_etud.py b/app/scodoc/sco_page_etud.py index 218d459d..6ac2b4bc 100644 --- a/app/scodoc/sco_page_etud.py +++ b/app/scodoc/sco_page_etud.py @@ -172,7 +172,7 @@ def ficheEtud(etudid=None): raise ScoValueError("Étudiant inexistant !") etud_ = etuds[0] # transition: etud_ à éliminer et remplacer par etud etudid = etud_["etudid"] - etud = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) sco_etud.fill_etuds_info([etud_]) # info = etud_ diff --git a/app/scodoc/sco_photos.py b/app/scodoc/sco_photos.py index cdf0e9fb..b1e73dcb 100644 --- a/app/scodoc/sco_photos.py +++ b/app/scodoc/sco_photos.py @@ -144,7 +144,7 @@ def get_photo_image(etudid=None, size="small"): if not etudid: filename = UNKNOWN_IMAGE_PATH else: - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) filename = photo_pathname(etud.photo_filename, size=size) if not filename: filename = UNKNOWN_IMAGE_PATH diff --git a/app/scodoc/sco_prepajury.py b/app/scodoc/sco_prepajury.py index 9ec0a95b..fc369efc 100644 --- a/app/scodoc/sco_prepajury.py +++ b/app/scodoc/sco_prepajury.py @@ -55,7 +55,7 @@ def feuille_preparation_jury(formsemestre_id): """Feuille excel pour préparation des jurys classiques. Non adaptée pour le BUT. """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etuds: Identite = nt.get_inscrits(order_by="moy") # tri par moy gen sem = sco_formsemestre.get_formsemestre(formsemestre_id) diff --git a/app/scodoc/sco_pv_dict.py b/app/scodoc/sco_pv_dict.py index d597f12b..c48aa5f0 100644 --- a/app/scodoc/sco_pv_dict.py +++ b/app/scodoc/sco_pv_dict.py @@ -99,7 +99,7 @@ def dict_pvjury( decisions = [] D = {} # même chose que decisions, mais { etudid : dec } for etudid in etudids: - etud: Identite = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) Se = sco_cursus.get_situation_etud_cursus( etud.to_dict_scodoc7(), formsemestre_id ) diff --git a/app/scodoc/sco_pv_forms.py b/app/scodoc/sco_pv_forms.py index 13fe41c6..5b7be89e 100644 --- a/app/scodoc/sco_pv_forms.py +++ b/app/scodoc/sco_pv_forms.py @@ -211,7 +211,7 @@ def formsemestre_pvjury(formsemestre_id, format="html", publish=True): En classique: table spécifique avec les deux semestres pour le DUT En APC/BUT: renvoie vers table recap, en mode jury. """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) is_apc = formsemestre.formation.is_apc() if format == "html" and is_apc: return redirect( @@ -331,7 +331,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid groups_infos = None if etudid: # PV pour ce seul étudiant: - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) etuddescr = f"""
{etud.nomprenom}""" diff --git a/app/scodoc/sco_pv_lettres_inviduelles.py b/app/scodoc/sco_pv_lettres_inviduelles.py index 66868bcb..997645ca 100644 --- a/app/scodoc/sco_pv_lettres_inviduelles.py +++ b/app/scodoc/sco_pv_lettres_inviduelles.py @@ -93,7 +93,7 @@ def pdf_lettres_individuelles( or decision.get("decision_rcue") or decision.get("decisions_ue") ): # decision prise - etud: Identite = Identite.query.get(decision["identite"]["etudid"]) + etud = Identite.get_etud(decision["identite"]["etudid"]) params["nomEtud"] = etud.nomprenom # backward compat bookmarks[npages + 1] = scu.suppress_accents(etud.nomprenom) try: @@ -179,7 +179,7 @@ def pdf_lettre_individuelle(sem, decision, etud: Identite, params, signature=Non """ # formsemestre_id = sem["formsemestre_id"] - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) situation_etud: SituationEtudCursus = decision["Se"] titre_jury, titre_jury_court = jury_titres( formsemestre, diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index 022b470c..af91313f 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -85,7 +85,7 @@ def formsemestre_recapcomplet( """ if not isinstance(formsemestre_id, int): abort(404) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) file_formats = {"csv", "json", "xls", "xlsx", "xlsall", "xml"} supported_formats = file_formats | {"html", "evals"} if tabformat not in supported_formats: @@ -323,7 +323,7 @@ def gen_formsemestre_recapcomplet_xml( force_publishing=True, ) -> str: "XML export: liste tous les bulletins XML." - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() if not T: @@ -370,7 +370,7 @@ def gen_formsemestre_recapcomplet_json( :param force_publishing: donne les bulletins même si non "publiés sur portail" :returns: dict """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) is_apc = formsemestre.formation.is_apc() if xml_nodate: @@ -390,13 +390,13 @@ def gen_formsemestre_recapcomplet_json( "bulletins": [], } bulletins = js_data["bulletins"] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() for t in T: etudid = t[-1] if is_apc: - etud = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) bulletins_sem = bulletin_but.BulletinBUT(formsemestre) bul = bulletins_sem.bulletin_etud(etud, formsemestre) else: diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py index 4cb0d7ca..70bc7afe 100644 --- a/app/scodoc/sco_report.py +++ b/app/scodoc/sco_report.py @@ -83,7 +83,7 @@ def formsemestre_etuds_stats(sem: dict, only_primo=False): etuds = [] for t in T: etudid = t[-1] - etudiant: Identite = Identite.query.get(etudid) + etudiant = Identite.get_etud(etudid) etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud["annee_admission"] = etud["annee"] # plus explicite decision = nt.get_etud_decision_sem(etudid) @@ -452,7 +452,7 @@ def table_suivi_cohorte( logt("table_suivi_cohorte: start") # 1-- Liste des semestres posterieurs dans lesquels ont été les etudiants de sem - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() @@ -978,7 +978,7 @@ def _descr_etud_set(etudids): def _count_dem_reo(formsemestre_id, etudids): "count nb of demissions and reorientation in this etud set" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) dems = set() @@ -1096,7 +1096,7 @@ def tsp_etud_list( """ # log('tsp_etud_list(%s, bac="%s")' % (formsemestre_id,bac)) sem = sco_formsemestre.get_formsemestre(formsemestre_id) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() etuds = [] diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py index b8a2de08..641f4caa 100644 --- a/app/scodoc/sco_saisie_notes.py +++ b/app/scodoc/sco_saisie_notes.py @@ -949,7 +949,7 @@ def has_existing_decision(M, E, etudid): Si oui, return True """ formsemestre_id = M["formsemestre_id"] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) if nt.get_etud_decision_sem(etudid): return True @@ -1109,7 +1109,7 @@ def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int): for etudid in etudids: # infos identite etudiant e = sco_etud.etudident_list(cnx, {"etudid": etudid})[0] - etud: Identite = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) # TODO: refactor et eliminer etudident_list. e["etud"] = etud # utilisé seulement pour le tri -- a refactorer sco_etud.format_etud_ident(e) diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py index b259f9e4..55d2e289 100644 --- a/app/scodoc/sco_ue_external.py +++ b/app/scodoc/sco_ue_external.py @@ -87,7 +87,7 @@ def external_ue_create( puis un moduleimpl. Return: moduleimpl_id """ - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) log(f"creating external UE in {formsemestre}: {acronyme}") # Contrôle d'accès: diff --git a/app/tables/list_etuds.py b/app/tables/list_etuds.py index 175cf072..c559e932 100644 --- a/app/tables/list_etuds.py +++ b/app/tables/list_etuds.py @@ -106,7 +106,7 @@ class RowEtud(tb.Row): def etuds_sorted_from_ids(etudids) -> list[Identite]: "Liste triée d'etuds à partir d'une collections d'etudids" - etuds = [Identite.query.get_or_404(etudid) for etudid in etudids] + etuds = [Identite.get_etud(etudid) for etudid in etudids] return sorted(etuds, key=lambda etud: etud.sort_key) diff --git a/app/tables/recap.py b/app/tables/recap.py index c50a65af..989629ae 100644 --- a/app/tables/recap.py +++ b/app/tables/recap.py @@ -94,7 +94,7 @@ class TableRecap(tb.Table): self.set_groups(groups) for etudid in res.formsemestre.etuds_inscriptions: - etud = Identite.query.get(etudid) + etud = Identite.get_etud(etudid) row = self.row_class(self, etud) self.add_row(row) row.add_etud_cols() diff --git a/app/views/__init__.py b/app/views/__init__.py index d76a1894..3de17f33 100644 --- a/app/views/__init__.py +++ b/app/views/__init__.py @@ -64,7 +64,7 @@ class ScoData: elif request.method == "POST": etudid = request.form.get("etudid", None) if etudid is not None: - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) self.etud = etud if etud is not None: # Infos sur l'étudiant courant @@ -87,7 +87,7 @@ class ScoData: sco_formsemestre_status.retreive_formsemestre_from_request() ) if formsemestre_id is not None: - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if formsemestre is None: self.sem = None self.sem_menu_bar = None diff --git a/app/views/absences.py b/app/views/absences.py index 44018d47..340752e7 100644 --- a/app/views/absences.py +++ b/app/views/absences.py @@ -363,7 +363,7 @@ def SignaleAbsenceGrHebdo( ) formsemestre_id = groups_infos.formsemestre_id - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if formsemestre.dept_id != g.scodoc_dept_id: abort(404, "groupes inexistants dans ce département") require_module = sco_preferences.get_preference( diff --git a/app/views/notes.py b/app/views/notes.py index 26207eab..38325274 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -282,9 +282,7 @@ def formsemestre_bulletinetud( formsemestre_id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() if etudid: - etud = models.Identite.query.filter_by( - etudid=etudid, dept_id=formsemestre.dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) elif code_nip: etud = models.Identite.query.filter_by( code_nip=str(code_nip), dept_id=formsemestre.dept_id @@ -1307,7 +1305,7 @@ def view_module_abs(moduleimpl_id, format="html"): @scodoc def delete_ue_expr(formsemestre_id: int, ue_id: int): """Efface une expression de calcul d'UE""" - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if not formsemestre.can_be_edited_by(current_user): raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") expr = FormSemestreUEComputationExpr.query.filter_by( @@ -1587,9 +1585,9 @@ def etud_desinscrit_ue(etudid, formsemestre_id, ue_id): - En classique: désinscrit l'etudiant de tous les modules de cette UE dans ce semestre. - En APC: dispense de l'UE indiquée. """ - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) ue = UniteEns.query.get_or_404(ue_id) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) if ue.formation.is_apc(): if ( DispenseUE.query.filter_by( @@ -1638,7 +1636,7 @@ def etud_inscrit_ue(etudid, formsemestre_id, ue_id): formsemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) ue = UniteEns.query.get_or_404(ue_id) if ue.formation.is_apc(): for disp in DispenseUE.query.filter_by( @@ -2045,7 +2043,7 @@ def formsemestre_bulletins_mailetuds( (inscrit non démissionnaire ni défaillant et ayant un mail renseigné dans ScoDoc) """ prefer_mail_perso = int(prefer_mail_perso) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) inscriptions = [ inscription for inscription in formsemestre.inscriptions @@ -2330,9 +2328,7 @@ def formsemestre_validation_but( formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) nb_etuds = formsemestre.etuds.count() # la route ne donne pas le type d'etudid pour pouvoir construire des URLs # provisoires avec NEXT et PREV @@ -2573,7 +2569,7 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None): ) ) - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) form = jury_but_forms.FormSemestreValidationAutoBUTForm() if request.method == "POST": if not form.cancel.data: @@ -2740,7 +2736,7 @@ def formsemestre_validation_suppress_etud( formsemestre_id=formsemestre_id, ) ) - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) if formsemestre.formation.is_apc(): next_url = url_for( "scolar.ficheEtud", @@ -2864,7 +2860,7 @@ def formsemestre_jury_but_erase( mode_jury=1, ) else: - etud: Identite = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) etuds = [etud] dest_url = url_for( "notes.formsemestre_validation_but", diff --git a/app/views/scodoc.py b/app/views/scodoc.py index ec616768..6f231f91 100644 --- a/app/views/scodoc.py +++ b/app/views/scodoc.py @@ -227,7 +227,7 @@ def get_etud_dept(): """ if "etudid" in request.args: # zero ou une réponse: - etuds = [Identite.query.get(request.args["etudid"])] + etuds = [Identite.get_etud(request.args["etudid"])] elif "code_nip" in request.args: # il peut y avoir plusieurs réponses si l'étudiant est passé par plusieurs départements etuds = Identite.query.filter_by(code_nip=request.args["code_nip"]).all() diff --git a/app/views/scolar.py b/app/views/scolar.py index 38c33ae8..8f46df0e 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -695,7 +695,7 @@ sco_publish( @scodoc7func def doAddAnnotation(etudid, comment): "ajoute annotation sur etudiant" - etud = Identite.query.get_or_404(etudid) # check existence + _ = Identite.get_etud(etudid) # check existence if comment: cnx = ndb.GetDBConnexion() sco_etud.etud_annotations_create( @@ -746,7 +746,7 @@ def doSuppressAnnotation(etudid, annotation_id): @scodoc7func def form_change_coordonnees(etudid): "edit coordonnees etudiant" - etud = Identite.query.get_or_404(etudid) + etud = Identite.get_etud(etudid) cnx = ndb.GetDBConnexion() adrs = sco_etud.adresse_list(cnx, {"etudid": etudid}) if adrs: @@ -1064,9 +1064,7 @@ def form_change_photo(etudid=None): @scodoc7func def form_suppress_photo(etudid=None, dialog_confirmed=False): """Formulaire suppression photo étudiant""" - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) if not dialog_confirmed: return scu.confirm_dialog( f"

Confirmer la suppression de la photo de {etud.nom_disp()} ?

", @@ -1120,9 +1118,7 @@ def _form_dem_of_def( operation_method: str = "", ): "Formulaire démission ou défaillance Etudiant" - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() @@ -1265,9 +1261,7 @@ def _do_cancel_dem_or_def( event_type="DEMISSION", ): "Annule une démission ou une défaillance" - etud: Identite = Identite.query.filter_by( - id=etudid, dept_id=g.scodoc_dept_id - ).first_or_404() + etud = Identite.get_etud(etudid) formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() diff --git a/sco_version.py b/sco_version.py index e5f606a7..f2afe9a7 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.4.67" +SCOVERSION = "9.4.68" SCONAME = "ScoDoc" diff --git a/scodoc.py b/scodoc.py index 71f77d5b..1640f907 100755 --- a/scodoc.py +++ b/scodoc.py @@ -18,6 +18,7 @@ from flask_login import login_user, logout_user, current_user import psycopg2 import sqlalchemy +import app as mapp from app import create_app, cli, db from app import initialize_scodoc_database from app import clear_scodoc_cache @@ -514,17 +515,16 @@ def localize_logo(logo: str = None, dept: str = None): # migrate-scodoc7-dept-l @click.argument("zipfile", type=click.File("rb")) def photos_import_files(formsemestre_id: int, xlsfile: str, zipfile: str): """Import des photos d'étudiants à partir d'une liste excel et d'un zip avec les images.""" - import app as mapp from app.scodoc import sco_trombino, sco_photos from app.auth.models import get_super_admin - sem = mapp.models.formsemestre.FormSemestre.query.get(formsemestre_id) - if not sem: - sys.stderr.write("photos-import-files: numéro de semestre invalide\n") + formsemestre = FormSemestre.query.get(formsemestre_id) + if not formsemestre: + sys.stderr.write("photos-import-files: formsemestre_id invalide\n") return 2 with app.test_request_context(): - mapp.set_sco_dept(sem.departement.acronym) + mapp.set_sco_dept(formsemestre.departement.acronym) admin_user = get_super_admin() login_user(admin_user) diff --git a/tests/bench/notes_table.py b/tests/bench/notes_table.py index 7af261b3..b5a39d72 100644 --- a/tests/bench/notes_table.py +++ b/tests/bench/notes_table.py @@ -48,7 +48,7 @@ def bench_notes_table(dept: str, formsemestre_ids: list[int]) -> float: tot_time = 0.0 for formsemestre_id in formsemestre_ids: print(f"building sem {formsemestre_id}...") - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) t0 = time.time() nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) tot_time += time.time() - t0 diff --git a/tests/unit/test_but_ues.py b/tests/unit/test_but_ues.py index 5105039a..ae850b53 100644 --- a/tests/unit/test_but_ues.py +++ b/tests/unit/test_but_ues.py @@ -29,7 +29,7 @@ def test_ue_moy(test_client): ue3, ) = setup.build_modules_with_evaluations(ue_coefs=ue_coefs, nb_mods=nb_mods) assert len(evaluation_ids) == nb_mods - formsemestre = FormSemestre.query.get(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) evaluation1 = Evaluation.query.get(evaluation_ids[0]) evaluation2 = Evaluation.query.get(evaluation_ids[1]) etud = G.create_etud(nom="test") diff --git a/tests/unit/test_sco_basic.py b/tests/unit/test_sco_basic.py index 0030d036..770fbf4e 100644 --- a/tests/unit/test_sco_basic.py +++ b/tests/unit/test_sco_basic.py @@ -239,7 +239,7 @@ def run_sco_basic(verbose=False) -> FormSemestre: # ---- Suppression d'un étudiant, vérification inscription # (permet de tester les cascades) - etud = Identite.query.get(etuds[0]["etudid"]) + etud = Identite.get_etud(etuds[0]["etudid"]) assert etud is not None etudid = etud.id db.session.delete(etud) From f2de6ab80c666183764ba830aa7b189f9053aa9c Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 20 Mar 2023 11:46:32 +0100 Subject: [PATCH 2/5] Supprime message sur page login --- app/auth/routes.py | 2 -- app/templates/auth/login.j2 | 4 ---- 2 files changed, 6 deletions(-) diff --git a/app/auth/routes.py b/app/auth/routes.py index 8fedf302..235b9e5b 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -47,12 +47,10 @@ def _login_form(): current_app.logger.info("login: success (%s)", form.user_name.data) return form.redirect("scodoc.index") - message = request.args.get("message", "") return render_template( "auth/login.j2", title=_("Sign In"), form=form, - message=message, is_cas_enabled=ScoDocSiteConfig.is_cas_enabled(), ) diff --git a/app/templates/auth/login.j2 b/app/templates/auth/login.j2 index a974fdf3..43e5675a 100644 --- a/app/templates/auth/login.j2 +++ b/app/templates/auth/login.j2 @@ -4,10 +4,6 @@ {% block app_content %} -{% if message %} - -{% endif %} -

Connexion

From 44978896104a8457bb6276b323ef5b43695576da Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 20 Mar 2023 11:48:37 +0100 Subject: [PATCH 3/5] Fix typo in user_name check --- app/auth/models.py | 2 +- app/views/users.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/auth/models.py b/app/auth/models.py index 8743850d..37bbf986 100644 --- a/app/auth/models.py +++ b/app/auth/models.py @@ -296,7 +296,7 @@ class User(UserMixin, db.Model): self.user_name = data["user_name"] if "password" in data: self.set_password(data["password"]) - if not invalid_user_name(self.user_name): + if invalid_user_name(self.user_name): raise ValueError(f"invalid user_name: {self.user_name}") # Roles: roles_string is "Ens_RT, Secr_RT, ..." if "roles_string" in data: diff --git a/app/views/users.py b/app/views/users.py index e6400882..31c6bf45 100644 --- a/app/views/users.py +++ b/app/views/users.py @@ -337,8 +337,9 @@ def create_user_form(user_name=None, edit=0, all_roles=True): "title": "Pseudo (login)", "size": 20, "allow_null": False, - "explanation": "nom utilisé pour la connexion. Doit être unique parmi tous les utilisateurs." - "Lettres ou chiffres uniquement.", + "explanation": """nom utilisé pour la connexion. + Doit être unique parmi tous les utilisateurs. + Lettres ou chiffres uniquement.""", }, ), ("formsemestre_id", {"input_type": "hidden"}), From 7de4be3c59d4fb7ceca31e12b21a8d0407e835f3 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 20 Mar 2023 12:16:38 +0100 Subject: [PATCH 4/5] Modifie message d'erreur html --- app/templates/sco_value_error.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/sco_value_error.j2 b/app/templates/sco_value_error.j2 index 94b60310..840d3802 100644 --- a/app/templates/sco_value_error.j2 +++ b/app/templates/sco_value_error.j2 @@ -5,7 +5,7 @@

Erreur !

-{{ exc | safe }} +{{ exc }}

{% if g.scodoc_dept %} From 738de9d5ed90edb2d731ba6d6d647039ed8916da Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 20 Mar 2023 12:17:28 +0100 Subject: [PATCH 5/5] =?UTF-8?q?V=C3=A9rification=20acronymes=20dept?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/departements.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/models/departements.py b/app/models/departements.py index 8c5df10c..6f3f7759 100644 --- a/app/models/departements.py +++ b/app/models/departements.py @@ -2,12 +2,15 @@ """ScoDoc models : departements """ +import re from app import db from app.models import SHORT_STR_LEN from app.models.preferences import ScoPreference from app.scodoc.sco_exceptions import ScoValueError +VALID_DEPT_EXP = re.compile(r"^[\w@\\\-\.]+$") + class Departement(db.Model): """Un département ScoDoc""" @@ -60,6 +63,15 @@ class Departement(db.Model): } return data + @classmethod + def invalid_dept_acronym(cls, dept_acronym: str) -> bool: + "Check that dept_acronym is invalid" + return ( + not dept_acronym + or (len(dept_acronym) >= SHORT_STR_LEN) + or not VALID_DEPT_EXP.match(dept_acronym) + ) + @classmethod def from_acronym(cls, acronym): dept = cls.query.filter_by(acronym=acronym).first_or_404() @@ -70,6 +82,8 @@ def create_dept(acronym: str, visible=True) -> Departement: "Create new departement" from app.models import ScoPreference + if Departement.invalid_dept_acronym(acronym): + raise ScoValueError("acronyme departement invalide") existing = Departement.query.filter_by(acronym=acronym).count() if existing: raise ScoValueError(f"acronyme {acronym} déjà existant")