Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into table

This commit is contained in:
Emmanuel Viennet 2023-03-20 17:18:09 +01:00
commit 92a7105336
65 changed files with 160 additions and 147 deletions

View File

@ -49,10 +49,7 @@ def billets_absence_create():
return json_error( return json_error(
404, message="Paramètre manquant: etudid, abs_begin, abs_end requis" 404, message="Paramètre manquant: etudid, abs_begin, abs_end requis"
) )
query = Identite.query.filter_by(etudid=etudid) etud = Identite.get_etud(etudid)
if g.scodoc_dept:
query = query.filter_by(dept_id=g.scodoc_dept_id)
etud = query.first_or_404()
billet = BilletAbsence( billet = BilletAbsence(
etudid=etud.id, etudid=etud.id,
abs_begin=abs_begin, abs_begin=abs_begin,

View File

@ -296,7 +296,7 @@ class User(UserMixin, db.Model):
self.user_name = data["user_name"] self.user_name = data["user_name"]
if "password" in data: if "password" in data:
self.set_password(data["password"]) 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}") raise ValueError(f"invalid user_name: {self.user_name}")
# Roles: roles_string is "Ens_RT, Secr_RT, ..." # Roles: roles_string is "Ens_RT, Secr_RT, ..."
if "roles_string" in data: if "roles_string" in data:

View File

@ -47,12 +47,10 @@ def _login_form():
current_app.logger.info("login: success (%s)", form.user_name.data) current_app.logger.info("login: success (%s)", form.user_name.data)
return form.redirect("scodoc.index") return form.redirect("scodoc.index")
message = request.args.get("message", "")
return render_template( return render_template(
"auth/login.j2", "auth/login.j2",
title=_("Sign In"), title=_("Sign In"),
form=form, form=form,
message=message,
is_cas_enabled=ScoDocSiteConfig.is_cas_enabled(), is_cas_enabled=ScoDocSiteConfig.is_cas_enabled(),
) )

View File

@ -65,11 +65,10 @@ def bulletin_but_xml_compat(
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
log( log(
"bulletin_but_xml_compat( formsemestre_id=%s, etudid=%s )" f"bulletin_but_xml_compat( formsemestre_id={formsemestre_id}, etudid={etudid} )"
% (formsemestre_id, etudid)
) )
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) etud = Identite.get_etud(etudid)
etud: Identite = Identite.query.get_or_404(etudid) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
results = bulletin_but.ResultatsSemestreBUT(formsemestre) results = bulletin_but.ResultatsSemestreBUT(formsemestre)
nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT] nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT]
# etat_inscription = etud.inscription_etat(formsemestre.id) # etat_inscription = etud.inscription_etat(formsemestre.id)

View File

@ -46,7 +46,7 @@ def pvjury_page_but(formsemestre_id: int, fmt="html"):
"""Page récapitulant les décisions de jury BUT """Page récapitulant les décisions de jury BUT
formsemestre peut être pair ou impair 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() assert formsemestre.formation.is_apc()
title = "Procès-verbal de jury BUT" title = "Procès-verbal de jury BUT"
if fmt == "html": if fmt == "html":
@ -65,7 +65,8 @@ def pvjury_page_but(formsemestre_id: int, fmt="html"):
columns_ids=titles.keys(), columns_ids=titles.keys(),
html_caption=title, html_caption=title,
html_class="pvjury_table_but table_leftalign", html_class="pvjury_table_but table_leftalign",
html_title=f"""<div style="margin-bottom: 8px;"><span style="font-size: 120%; font-weight: bold;">{title}</span> html_title=f"""<div style="margin-bottom: 8px;"><span
style="font-size: 120%; font-weight: bold;">{title}</span>
<span style="padding-left: 20px;"> <span style="padding-left: 20px;">
<a href="{url_for("notes.pvjury_page_but", <a href="{url_for("notes.pvjury_page_but",
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, fmt="xlsx")}" scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, fmt="xlsx")}"
@ -126,7 +127,7 @@ def pvjury_table_but(
for etudid in etudids: for etudid in etudids:
if not etudid in formsemestre_etudids: if not etudid in formsemestre_etudids:
continue # garde fou continue # garde fou
etud: Identite = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
try: try:
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
if deca.annee_but != annee_but: # wtf ? if deca.annee_but != annee_but: # wtf ?

View File

@ -31,7 +31,7 @@ def _get_jury_but_etud_result(
formsemestre: FormSemestre, dpv: dict, etudid: int formsemestre: FormSemestre, dpv: dict, etudid: int
) -> dict: ) -> dict:
"""Résultats de jury d'un étudiant sur un semestre pair de BUT""" """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] dec_etud = dpv["decisions_dict"][etudid]
if formsemestre.formation.is_apc(): if formsemestre.formation.is_apc():
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)

View File

@ -36,7 +36,7 @@ def formsemestre_validation_auto_but(
nb_etud_modif = 0 nb_etud_modif = 0
with sco_cache.DeferredSemCacheManager(): with sco_cache.DeferredSemCacheManager():
for etudid in formsemestre.etuds_inscriptions: for etudid in formsemestre.etuds_inscriptions:
etud: Identite = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
nb_etud_modif += deca.record_all( nb_etud_modif += deca.record_all(
no_overwrite=no_overwrite, only_validantes=only_adm no_overwrite=no_overwrite, only_validantes=only_adm

View File

@ -519,7 +519,7 @@ def infos_fiche_etud_html(etudid: int) -> str:
"""Section html pour fiche etudiant """Section html pour fiche etudiant
provisoire pour BUT 2022 provisoire pour BUT 2022
""" """
etud: Identite = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
inscriptions = ( inscriptions = (
FormSemestreInscription.query.join(FormSemestreInscription.formsemestre) FormSemestreInscription.query.join(FormSemestreInscription.formsemestre)
.filter( .filter(

View File

@ -230,7 +230,7 @@ class ResultatsSemestreClassic(NotesTableCompat):
f"""* oups: calcul coef UE impossible\nformsemestre_id='{self.formsemestre.id f"""* oups: calcul coef UE impossible\nformsemestre_id='{self.formsemestre.id
}'\netudid='{etudid}'\nue={ue}""" }'\netudid='{etudid}'\nue={ue}"""
) )
etud: Identite = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
raise ScoValueError( raise ScoValueError(
f"""<div class="scovalueerror"><p>Coefficient de l'UE capitalisée {ue.acronyme} f"""<div class="scovalueerror"><p>Coefficient de l'UE capitalisée {ue.acronyme}
impossible à déterminer pour l'étudiant <a href="{ impossible à déterminer pour l'étudiant <a href="{

View File

@ -391,7 +391,7 @@ class ResultatsSemestre(ResultatsCache):
ue_capitalized = UniteEns.query.get(ue_cap["ue_id"]) ue_capitalized = UniteEns.query.get(ue_cap["ue_id"])
coef_ue = ue_capitalized.ects coef_ue = ue_capitalized.ects
if coef_ue is None: if coef_ue is None:
orig_sem = FormSemestre.query.get(ue_cap["formsemestre_id"]) orig_sem = FormSemestre.get_formsemestre(ue_cap["formsemestre_id"])
raise ScoValueError( raise ScoValueError(
f"""L'UE capitalisée {ue_capitalized.acronyme} f"""L'UE capitalisée {ue_capitalized.acronyme}
du semestre {orig_sem.titre_annee()} du semestre {orig_sem.titre_annee()}

View File

@ -290,7 +290,7 @@ class RegroupementCoherentUE:
# rcues = [] # rcues = []
# for ue_id, formsemestre_id in cursor: # for ue_id, formsemestre_id in cursor:
# other_ue = UniteEns.query.get(ue_id) # other_ue = UniteEns.query.get(ue_id)
# other_formsemestre = FormSemestre.query.get(formsemestre_id) # other_formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
# rcues.append( # rcues.append(
# RegroupementCoherentUE( # RegroupementCoherentUE(
# etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat # etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat

View File

@ -2,12 +2,15 @@
"""ScoDoc models : departements """ScoDoc models : departements
""" """
import re
from app import db from app import db
from app.models import SHORT_STR_LEN from app.models import SHORT_STR_LEN
from app.models.preferences import ScoPreference from app.models.preferences import ScoPreference
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
VALID_DEPT_EXP = re.compile(r"^[\w@\\\-\.]+$")
class Departement(db.Model): class Departement(db.Model):
"""Un département ScoDoc""" """Un département ScoDoc"""
@ -60,6 +63,15 @@ class Departement(db.Model):
} }
return data 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 @classmethod
def from_acronym(cls, acronym): def from_acronym(cls, acronym):
dept = cls.query.filter_by(acronym=acronym).first_or_404() 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" "Create new departement"
from app.models import ScoPreference from app.models import ScoPreference
if Departement.invalid_dept_acronym(acronym):
raise ScoValueError("acronyme departement invalide")
existing = Departement.query.filter_by(acronym=acronym).count() existing = Departement.query.filter_by(acronym=acronym).count()
if existing: if existing:
raise ScoValueError(f"acronyme {acronym} déjà existant") raise ScoValueError(f"acronyme {acronym} déjà existant")

View File

@ -72,13 +72,22 @@ class Identite(db.Model):
) )
@classmethod @classmethod
def from_request(cls, etudid=None, code_nip=None): def from_request(cls, etudid=None, code_nip=None) -> "Identite":
"""Étudiant à partir de l'etudid ou du code_nip, soit """Étudiant à partir de l'etudid ou du code_nip, soit
passés en argument soit retrouvés directement dans la requête web. passés en argument soit retrouvés directement dans la requête web.
Erreur 404 si inexistant. Erreur 404 si inexistant.
""" """
args = make_etud_args(etudid=etudid, code_nip=code_nip) 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 @classmethod
def create_etud(cls, **args): def create_etud(cls, **args):

View File

@ -159,6 +159,15 @@ class FormSemestre(db.Model):
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__name__} {self.id} {self.titre_annee()}>" 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: def sort_key(self) -> tuple:
"""clé pour tris par ordre alphabétique """clé pour tris par ordre alphabétique
(pour avoir le plus récent d'abord, sort avec reverse=True)""" (pour avoir le plus récent d'abord, sort avec reverse=True)"""

View File

@ -1135,7 +1135,7 @@ class JuryPE(object):
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat: def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat:
"""Charge la table des notes d'un formsemestre""" """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) return res_sem.load_formsemestre_results(formsemestre)
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------

View File

@ -277,7 +277,7 @@ class SemestreTag(pe_tagtable.TableTag):
fid_prec = fids_prec[0] fid_prec = fids_prec[0]
# Lecture des notes de ce semestre # Lecture des notes de ce semestre
# le tableau de note du semestre considéré: # 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( nt_prec: NotesTableCompat = res_sem.load_formsemestre_results(
formsemestre_prec formsemestre_prec
) )

View File

@ -65,7 +65,7 @@ def table_billets_etud(
etudid: int = None, etat: bool = None, with_links=True etudid: int = None, etat: bool = None, with_links=True
) -> GenTable: ) -> GenTable:
"""Page avec table billets.""" """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) billets = query_billets_etud(etudid, etat)
return table_billets(billets, etud=etud, with_links=with_links) return table_billets(billets, etud=etud, with_links=with_links)

View File

@ -272,7 +272,7 @@ def retreive_current_formsemestre(etudid: int, cur_date) -> Optional[FormSemestr
if not r: if not r:
return None return None
# s'il y a plusieurs semestres, prend le premier (rarissime et non significatif): # 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 return formsemestre

View File

@ -119,7 +119,7 @@ def doSignaleAbsence(
if moduleimpl_id and moduleimpl_id != "NULL": if moduleimpl_id and moduleimpl_id != "NULL":
mod = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] mod = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = mod["formsemestre_id"] 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
ues = nt.get_ues_stat_dict() ues = nt.get_ues_stat_dict()
for ue in ues: for ue in ues:
@ -187,7 +187,7 @@ def SignaleAbsenceEtud(): # etudid implied
menu_module = "" menu_module = ""
else: else:
formsemestre_id = etud["cursem"]["formsemestre_id"] 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
ues = nt.get_ues_stat_dict() ues = nt.get_ues_stat_dict()
require_module = sco_preferences.get_preference( require_module = sco_preferences.get_preference(

View File

@ -293,7 +293,7 @@ class ApoEtud(dict):
""" """
# futur: #WIP # 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 # self.etud = etud
etuds = sco_etud.get_etud_info(code_nip=self["nip"], filled=True) etuds = sco_etud.get_etud_info(code_nip=self["nip"], filled=True)
if not etuds: if not etuds:
@ -478,7 +478,7 @@ class ApoEtud(dict):
# pas de code semestre en APC ! # pas de code semestre en APC !
return dict(N="", B=20, J="", R="", M="") return dict(N="", B=20, J="", R="", M="")
if decision is None: if decision is None:
etud = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
nomprenom = etud.nomprenom if etud else "(inconnu)" nomprenom = etud.nomprenom if etud else "(inconnu)"
raise ScoValueError( raise ScoValueError(
f"decision absente pour l'étudiant {nomprenom} ({etudid})" f"decision absente pour l'étudiant {nomprenom} ({etudid})"

View File

@ -318,7 +318,7 @@ def do_formsemestre_archive(
gen_formsemestre_recapcomplet_json, 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) res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
sem_archive_id = formsemestre_id sem_archive_id = formsemestre_id
archive_id = PVArchive.create_obj_archive(sem_archive_id, description) archive_id = PVArchive.create_obj_archive(sem_archive_id, description)

View File

@ -147,7 +147,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
prefs = sco_preferences.SemPreferences(formsemestre_id) 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if not nt.get_etud_etat(etudid): if not nt.get_etud_etat(etudid):
raise ScoValueError("Étudiant non inscrit à ce semestre") raise ScoValueError("Étudiant non inscrit à ce semestre")

View File

@ -105,9 +105,9 @@ def formsemestre_bulletinetud_published_dict(
version = version[:-4] # enlève le "_mat" version = version[:-4] # enlève le "_mat"
with_matieres = True with_matieres = True
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
prefs = sco_preferences.SemPreferences(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) sem = sco_formsemestre.get_formsemestre(formsemestre_id)
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)

View File

@ -256,7 +256,7 @@ def get_etud_bulletins_pdf(etudid, version="selectedevals"):
"Bulletins pdf de tous les semestres de l'étudiant, et filename" "Bulletins pdf de tous les semestres de l'étudiant, et filename"
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
etud: Identite = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
fragments = [] fragments = []
bookmarks = {} bookmarks = {}
filigrannes = {} filigrannes = {}

View File

@ -84,7 +84,7 @@ def make_xml_formsemestre_bulletinetud(
log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid)) log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid))
sem = sco_formsemestre.get_formsemestre(formsemestre_id) 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(): if formsemestre.formation.is_apc():
return bulletin_but_xml_compat( return bulletin_but_xml_compat(
formsemestre_id, formsemestre_id,
@ -156,7 +156,7 @@ def make_xml_formsemestre_bulletinetud(
pid = partition["partition_id"] pid = partition["partition_id"]
partitions_etud_groups[pid] = sco_groups.get_etud_groups_in_partition(pid) 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
ues = nt.get_ues_stat_dict() ues = nt.get_ues_stat_dict()
modimpls = nt.get_modimpls_dict() modimpls = nt.get_modimpls_dict()

View File

@ -55,7 +55,7 @@ def formsemestre_table_estim_cost(
peut conduire à une sur-estimation du coût s'il y a des modules optionnels peut conduire à une sur-estimation du coût s'il y a des modules optionnels
(dans ce cas, retoucher le tableau excel exporté). (dans ce cas, retoucher le tableau excel exporté).
""" """
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
rows = [] rows = []
for modimpl in formsemestre.modimpls: for modimpl in formsemestre.modimpls:

View File

@ -42,7 +42,7 @@ def get_situation_etud_cursus(
etud: dict, formsemestre_id: int etud: dict, formsemestre_id: int
) -> sco_cursus_dut.SituationEtudCursus: ) -> sco_cursus_dut.SituationEtudCursus:
"""renvoie une instance de SituationEtudCursus (ou sous-classe spécialisée)""" """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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if formsemestre.formation.is_apc(): 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 """Liste des formsemestres pouvant utiliser une UE capitalisee de ce semestre
(et qui doivent donc etre sortis du cache si l'on modifie ce (et qui doivent donc etre sortis du cache si l'on modifie ce
semestre): meme code formation, meme semestre_id, date posterieure""" 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( cursor = db.session.execute(
text( text(

View File

@ -890,7 +890,7 @@ def formsemestre_validate_ues(formsemestre_id, etudid, code_etat_sem, assiduite)
""" """
valid_semestre = code_etat_sem in CODES_SEM_VALIDES valid_semestre = code_etat_sem in CODES_SEM_VALIDES
cnx = ndb.GetDBConnexion() 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
ue_ids = [x["ue_id"] for x in nt.get_ues_stat_dict(filter_sport=True)] ue_ids = [x["ue_id"] for x in nt.get_ues_stat_dict(filter_sport=True)]
for ue_id in ue_ids: for ue_id in ue_ids:

View File

@ -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) 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
# #
s = SemSet('NSS29902') s = SemSet('NSS29902')

View File

@ -78,7 +78,7 @@ def evaluation_create_form(
] ]
mod = modimpl_o["module"] mod = modimpl_o["module"]
formsemestre_id = modimpl_o["formsemestre_id"] formsemestre_id = modimpl_o["formsemestre_id"]
formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre = modimpl.formsemestre
sem_ues = formsemestre.query_ues(with_sport=False).all() sem_ues = formsemestre.query_ues(with_sport=False).all()
is_malus = mod["module_type"] == ModuleType.MALUS is_malus = mod["module_type"] == ModuleType.MALUS
is_apc = mod["module_type"] in (ModuleType.RESSOURCE, ModuleType.SAE) is_apc = mod["module_type"] in (ModuleType.RESSOURCE, ModuleType.SAE)

View File

@ -379,7 +379,7 @@ def _eval_etat(evals):
def do_evaluation_etat_in_sem(formsemestre_id): def do_evaluation_etat_in_sem(formsemestre_id):
"""-> nb_eval_completes, nb_evals_en_cours, nb_evals_vides, """-> nb_eval_completes, nb_evals_en_cours, nb_evals_vides,
date derniere modif, attente""" 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
evals = nt.get_evaluations_etats() evals = nt.get_evaluations_etats()
etat = _eval_etat(evals) etat = _eval_etat(evals)
@ -399,7 +399,7 @@ def do_evaluation_etat_in_mod(nt, moduleimpl_id):
def formsemestre_evaluations_cal(formsemestre_id): def formsemestre_evaluations_cal(formsemestre_id):
"""Page avec calendrier de toutes les evaluations de ce semestre""" """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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
evals = nt.get_evaluations_etats() 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. 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
evals = nt.get_evaluations_etats() evals = nt.get_evaluations_etats()

View File

@ -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 } ) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
for formsemestre_id in formsemestre_ids_parcours: 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etudids = nt.get_etudids() etudids = nt.get_etudids()
for etudid in etudids: for etudid in etudids:

View File

@ -942,7 +942,7 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N
mod = sco_edit_module.module_list({"module_id": module_id})[0] mod = sco_edit_module.module_list({"module_id": module_id})[0]
# --- Association des parcours # --- Association des parcours
if formsemestre is None: if formsemestre is None:
formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
if "parcours" in tf[2]: if "parcours" in tf[2]:
formsemestre.parcours = [ formsemestre.parcours = [
ApcParcours.query.get(int(parcour_id_str)) ApcParcours.query.get(int(parcour_id_str))

View File

@ -65,7 +65,7 @@ def formsemestre_ext_create(etudid, sem_params):
# Check args # Check args
_ = Formation.query.get_or_404(sem_params["formation_id"]) _ = Formation.query.get_or_404(sem_params["formation_id"])
if etudid: if etudid:
_ = Identite.query.get_or_404(etudid) _ = Identite.get_etud(etudid)
# Create formsemestre # Create formsemestre
sem_params["modalite"] = "EXT" sem_params["modalite"] = "EXT"
@ -85,7 +85,7 @@ def formsemestre_ext_create(etudid, sem_params):
def formsemestre_ext_create_form(etudid, formsemestre_id): def formsemestre_ext_create_form(etudid, formsemestre_id):
"""Formulaire création/inscription à un semestre extérieur""" """Formulaire création/inscription à un semestre extérieur"""
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
H = [ H = [
html_sco_header.sco_header(), html_sco_header.sco_header(),
f"""<h2>Enregistrement d'une inscription antérieure dans un autre f"""<h2>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. mais pas enregistrée.
""" """
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) 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( ues = formsemestre.formation.ues.filter(UniteEns.type != UE_SPORT).order_by(
UniteEns.semestre_idx, UniteEns.numero UniteEns.semestre_idx, UniteEns.numero
) )

View File

@ -149,9 +149,7 @@ def do_formsemestre_demission(
event_date_iso = ndb.DateDMYtoISO(event_date) event_date_iso = ndb.DateDMYtoISO(event_date)
except ValueError as exc: except ValueError as exc:
raise ScoValueError("format de date invalide") from exc raise ScoValueError("format de date invalide") from exc
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
# check lock # check lock
formsemestre: FormSemestre = FormSemestre.query.filter_by( formsemestre: FormSemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id 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 from app.scodoc import sco_formsemestre_edit
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
# -- check lock # -- check lock
if not formsemestre.etat: if not formsemestre.etat:
raise ScoValueError("désinscription impossible: semestre verrouille") raise ScoValueError("désinscription impossible: semestre verrouille")
@ -282,7 +280,7 @@ def do_formsemestre_inscription_with_modules(
group_ids = group_ids or [] group_ids = group_ids or []
if isinstance(group_ids, int): if isinstance(group_ids, int):
group_ids = [group_ids] group_ids = [group_ids]
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
# inscription au semestre # inscription au semestre
args = {"formsemestre_id": formsemestre_id, "etudid": etudid} args = {"formsemestre_id": formsemestre_id, "etudid": etudid}
if etat is not None: if etat is not None:
@ -418,7 +416,7 @@ def formsemestre_inscription_with_modules(
if multiple_ok: if multiple_ok:
multiple_ok = int(multiple_ok) multiple_ok = int(multiple_ok)
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) 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: if etud.dept_id != formsemestre.dept_id:
raise ScoValueError("l'étudiant n'est pas dans ce département") raise ScoValueError("l'étudiant n'est pas dans ce département")
H = [ H = [
@ -530,7 +528,7 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
footer = html_sco_header.sco_footer() footer = html_sco_header.sco_footer()
@ -848,7 +846,7 @@ def list_inscrits_ailleurs(formsemestre_id):
Pour chacun, donne la liste des semestres. Pour chacun, donne la liste des semestres.
{ etudid : [ liste de sems ] } { 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etudids = nt.get_etudids() etudids = nt.get_etudids()

View File

@ -539,7 +539,7 @@ def formsemestre_page_title(formsemestre_id=None):
except ValueError: except ValueError:
log(f"formsemestre_id: invalid type {formsemestre_id:r}") log(f"formsemestre_id: invalid type {formsemestre_id:r}")
return "" return ""
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
return render_template( return render_template(
"formsemestre_page_title.j2", "formsemestre_page_title.j2",
@ -1394,7 +1394,7 @@ def formsemestre_warning_etuds_sans_note(
if nb_sans_notes < 5: if nb_sans_notes < 5:
# peu d'étudiants, affiche leurs noms # peu d'étudiants, affiche leurs noms
etuds: list[Identite] = sorted( 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, key=lambda e: e.sort_key,
) )
noms = ", ".join( noms = ", ".join(
@ -1437,7 +1437,7 @@ def formsemestre_note_etuds_sans_notes(
if etudid: if etudid:
etudids_sans_notes = etudids_sans_notes.intersection({etudid}) etudids_sans_notes = etudids_sans_notes.intersection({etudid})
etuds: list[Identite] = sorted( 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, key=lambda e: e.sort_key,
) )
if request.method == "POST": if request.method == "POST":
@ -1458,7 +1458,7 @@ def formsemestre_note_etuds_sans_notes(
message = """<h3>aucun étudiant sans notes</h3>""" message = """<h3>aucun étudiant sans notes</h3>"""
else: else:
flash( flash(
f"""{Identite.query.get_or_404(etudid).nomprenom} f"""{Identite.get_etud(etudid).nomprenom}
a déjà des notes""" a déjà des notes"""
) )
return redirect( return redirect(

View File

@ -80,9 +80,8 @@ def formsemestre_validation_etud_form(
formsemestre: FormSemestre = FormSemestre.query.filter_by( formsemestre: FormSemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
if not etudid and etud_index is None: if not etudid and etud_index is None:
@ -136,7 +135,7 @@ def formsemestre_validation_etud_form(
# Navigation suivant/precedent # Navigation suivant/precedent
if etud_index_prev is not None: 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( url_prev = url_for(
"notes.formsemestre_validation_etud_form", "notes.formsemestre_validation_etud_form",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
@ -146,7 +145,7 @@ def formsemestre_validation_etud_form(
else: else:
url_prev = None url_prev = None
if etud_index_next is not 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( url_next = url_for(
"notes.formsemestre_validation_etud_form", "notes.formsemestre_validation_etud_form",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
@ -934,7 +933,7 @@ def do_formsemestre_validation_auto(formsemestre_id):
"Saisie automatisee des decisions d'un semestre" "Saisie automatisee des decisions d'un semestre"
sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem = sco_formsemestre.get_formsemestre(formsemestre_id)
next_semestre_id = sem["semestre_id"] + 1 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etudids = nt.get_etudids() etudids = nt.get_etudids()
nb_valid = 0 nb_valid = 0
@ -1201,7 +1200,7 @@ def do_formsemestre_validate_previous_ue(
Si le coefficient est spécifié, modifie le coefficient de Si le coefficient est spécifié, modifie le coefficient de
cette UE (utile seulement pour les semestres extérieurs). 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
ue: UniteEns = UniteEns.query.get_or_404(ue_id) ue: UniteEns = UniteEns.query.get_or_404(ue_id)

View File

@ -549,7 +549,7 @@ def XMLgetGroupsInPartition(partition_id): # was XMLgetGroupesTD
t0 = time.time() t0 = time.time()
partition = get_partition(partition_id) partition = get_partition(partition_id)
formsemestre_id = partition["formsemestre_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} etuds_set = {ins.etudid for ins in formsemestre.inscriptions}
groups = get_partition_groups(partition) groups = get_partition_groups(partition)
@ -745,6 +745,7 @@ def setGroups(
log(msg) log(msg)
return xml_error(msg, code=403) return xml_error(msg, code=403)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
if not sco_permissions_check.can_change_groups(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 !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
log("***setGroups: partition_id=%s" % partition_id) log("***setGroups: partition_id=%s" % partition_id)
@ -821,7 +822,6 @@ def setGroups(
change_etud_group_in_partition(etudid, group.id, partition) change_etud_group_in_partition(etudid, group.id, partition)
# Update parcours # Update parcours
formsemestre = FormSemestre.query.get(formsemestre_id)
formsemestre.update_inscriptions_parcours_from_groups() formsemestre.update_inscriptions_parcours_from_groups()
data = ( data = (
@ -952,7 +952,7 @@ def edit_partition_form(formsemestre_id=None):
# ad-hoc form # ad-hoc form
if not sco_permissions_check.can_change_groups(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 !") 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) partitions = get_partitions_list(formsemestre_id)
arrow_up, arrow_down, arrow_none = get_arrow_icons_tags() arrow_up, arrow_down, arrow_none = get_arrow_icons_tags()
suppricon = scu.icontag( suppricon = scu.icontag(
@ -1136,7 +1136,7 @@ def partition_delete(partition_id, force=False, redirect=1, dialog_confirmed=Fal
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not sco_permissions_check.can_change_groups(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 !") 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: if not partition["partition_name"] and not force:
raise ValueError("cannot suppress this partition") raise ValueError("cannot suppress this partition")
@ -1404,7 +1404,7 @@ def groups_auto_repartition(partition_id=None):
if not partition["groups_editable"]: if not partition["groups_editable"]:
raise AccessDenied("Partition non éditable") raise AccessDenied("Partition non éditable")
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
# renvoie sur page édition groupes # renvoie sur page édition groupes
dest_url = url_for( dest_url = url_for(
"scolar.affect_groups", scodoc_dept=g.scodoc_dept, partition_id=partition_id "scolar.affect_groups", scodoc_dept=g.scodoc_dept, partition_id=partition_id

View File

@ -322,7 +322,9 @@ def _make_table_notes(
for etudid, etat in etudid_etats: for etudid, etat in etudid_etats:
css_row_class = None css_row_class = None
# infos identite etudiant # 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: if etud is None:
continue continue
@ -825,7 +827,7 @@ def _add_moymod_column(
): ):
"""Ajoute la colonne moymod à rows""" """Ajoute la colonne moymod à rows"""
col_id = "moymod" 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
inscrits = formsemestre.etudids_actifs inscrits = formsemestre.etudids_actifs

View File

@ -264,7 +264,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
""" """
authuser = current_user 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) res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
is_apc = formsemestre.formation.is_apc() is_apc = formsemestre.formation.is_apc()
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( 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 } ] } returns { ue_id : [ { infos } ] }
""" """
ues_cap_info = collections.defaultdict(list) 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(

View File

@ -172,7 +172,7 @@ def ficheEtud(etudid=None):
raise ScoValueError("Étudiant inexistant !") raise ScoValueError("Étudiant inexistant !")
etud_ = etuds[0] # transition: etud_ à éliminer et remplacer par etud etud_ = etuds[0] # transition: etud_ à éliminer et remplacer par etud
etudid = etud_["etudid"] etudid = etud_["etudid"]
etud = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
sco_etud.fill_etuds_info([etud_]) sco_etud.fill_etuds_info([etud_])
# #
info = etud_ info = etud_

View File

@ -144,7 +144,7 @@ def get_photo_image(etudid=None, size="small"):
if not etudid: if not etudid:
filename = UNKNOWN_IMAGE_PATH filename = UNKNOWN_IMAGE_PATH
else: else:
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
filename = photo_pathname(etud.photo_filename, size=size) filename = photo_pathname(etud.photo_filename, size=size)
if not filename: if not filename:
filename = UNKNOWN_IMAGE_PATH filename = UNKNOWN_IMAGE_PATH

View File

@ -55,7 +55,7 @@ def feuille_preparation_jury(formsemestre_id):
"""Feuille excel pour préparation des jurys classiques. """Feuille excel pour préparation des jurys classiques.
Non adaptée pour le BUT. 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etuds: Identite = nt.get_inscrits(order_by="moy") # tri par moy gen etuds: Identite = nt.get_inscrits(order_by="moy") # tri par moy gen
sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem = sco_formsemestre.get_formsemestre(formsemestre_id)

View File

@ -99,7 +99,7 @@ def dict_pvjury(
decisions = [] decisions = []
D = {} # même chose que decisions, mais { etudid : dec } D = {} # même chose que decisions, mais { etudid : dec }
for etudid in etudids: for etudid in etudids:
etud: Identite = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
Se = sco_cursus.get_situation_etud_cursus( Se = sco_cursus.get_situation_etud_cursus(
etud.to_dict_scodoc7(), formsemestre_id etud.to_dict_scodoc7(), formsemestre_id
) )

View File

@ -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 classique: table spécifique avec les deux semestres pour le DUT
En APC/BUT: renvoie vers table recap, en mode jury. 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() is_apc = formsemestre.formation.is_apc()
if format == "html" and is_apc: if format == "html" and is_apc:
return redirect( return redirect(
@ -331,7 +331,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid
groups_infos = None groups_infos = None
if etudid: if etudid:
# PV pour ce seul étudiant: # PV pour ce seul étudiant:
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
etuddescr = f"""<a class="discretelink" href="{ etuddescr = f"""<a class="discretelink" href="{
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid) url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
}">{etud.nomprenom}</a>""" }">{etud.nomprenom}</a>"""

View File

@ -93,7 +93,7 @@ def pdf_lettres_individuelles(
or decision.get("decision_rcue") or decision.get("decision_rcue")
or decision.get("decisions_ue") or decision.get("decisions_ue")
): # decision prise ): # decision prise
etud: Identite = Identite.query.get(decision["identite"]["etudid"]) etud = Identite.get_etud(decision["identite"]["etudid"])
params["nomEtud"] = etud.nomprenom # backward compat params["nomEtud"] = etud.nomprenom # backward compat
bookmarks[npages + 1] = scu.suppress_accents(etud.nomprenom) bookmarks[npages + 1] = scu.suppress_accents(etud.nomprenom)
try: try:
@ -179,7 +179,7 @@ def pdf_lettre_individuelle(sem, decision, etud: Identite, params, signature=Non
""" """
# #
formsemestre_id = sem["formsemestre_id"] formsemestre_id = sem["formsemestre_id"]
formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
situation_etud: SituationEtudCursus = decision["Se"] situation_etud: SituationEtudCursus = decision["Se"]
titre_jury, titre_jury_court = jury_titres( titre_jury, titre_jury_court = jury_titres(
formsemestre, formsemestre,

View File

@ -85,7 +85,7 @@ def formsemestre_recapcomplet(
""" """
if not isinstance(formsemestre_id, int): if not isinstance(formsemestre_id, int):
abort(404) abort(404)
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
file_formats = {"csv", "json", "xls", "xlsx", "xlsall", "xml"} file_formats = {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
supported_formats = file_formats | {"html", "evals"} supported_formats = file_formats | {"html", "evals"}
if tabformat not in supported_formats: if tabformat not in supported_formats:
@ -323,7 +323,7 @@ def gen_formsemestre_recapcomplet_xml(
force_publishing=True, force_publishing=True,
) -> str: ) -> str:
"XML export: liste tous les bulletins XML." "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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
if not T: 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" :param force_publishing: donne les bulletins même si non "publiés sur portail"
:returns: dict :returns: dict
""" """
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
is_apc = formsemestre.formation.is_apc() is_apc = formsemestre.formation.is_apc()
if xml_nodate: if xml_nodate:
@ -390,13 +390,13 @@ def gen_formsemestre_recapcomplet_json(
"bulletins": [], "bulletins": [],
} }
bulletins = js_data["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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
for t in T: for t in T:
etudid = t[-1] etudid = t[-1]
if is_apc: if is_apc:
etud = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
bulletins_sem = bulletin_but.BulletinBUT(formsemestre) bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
bul = bulletins_sem.bulletin_etud(etud, formsemestre) bul = bulletins_sem.bulletin_etud(etud, formsemestre)
else: else:

View File

@ -83,7 +83,7 @@ def formsemestre_etuds_stats(sem: dict, only_primo=False):
etuds = [] etuds = []
for t in T: for t in T:
etudid = t[-1] 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 = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
etud["annee_admission"] = etud["annee"] # plus explicite etud["annee_admission"] = etud["annee"] # plus explicite
decision = nt.get_etud_decision_sem(etudid) decision = nt.get_etud_decision_sem(etudid)
@ -452,7 +452,7 @@ def table_suivi_cohorte(
logt("table_suivi_cohorte: start") logt("table_suivi_cohorte: start")
# 1-- Liste des semestres posterieurs dans lesquels ont été les etudiants de sem # 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etudids = nt.get_etudids() etudids = nt.get_etudids()
@ -978,7 +978,7 @@ def _descr_etud_set(etudids):
def _count_dem_reo(formsemestre_id, etudids): def _count_dem_reo(formsemestre_id, etudids):
"count nb of demissions and reorientation in this etud set" "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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
dems = set() dems = set()
@ -1096,7 +1096,7 @@ def tsp_etud_list(
""" """
# log('tsp_etud_list(%s, bac="%s")' % (formsemestre_id,bac)) # log('tsp_etud_list(%s, bac="%s")' % (formsemestre_id,bac))
sem = sco_formsemestre.get_formsemestre(formsemestre_id) 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etudids = nt.get_etudids() etudids = nt.get_etudids()
etuds = [] etuds = []

View File

@ -949,7 +949,7 @@ def has_existing_decision(M, E, etudid):
Si oui, return True Si oui, return True
""" """
formsemestre_id = M["formsemestre_id"] 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) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if nt.get_etud_decision_sem(etudid): if nt.get_etud_decision_sem(etudid):
return True return True
@ -1109,7 +1109,7 @@ def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int):
for etudid in etudids: for etudid in etudids:
# infos identite etudiant # infos identite etudiant
e = sco_etud.etudident_list(cnx, {"etudid": etudid})[0] 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. # TODO: refactor et eliminer etudident_list.
e["etud"] = etud # utilisé seulement pour le tri -- a refactorer e["etud"] = etud # utilisé seulement pour le tri -- a refactorer
sco_etud.format_etud_ident(e) sco_etud.format_etud_ident(e)

View File

@ -87,7 +87,7 @@ def external_ue_create(
puis un moduleimpl. puis un moduleimpl.
Return: moduleimpl_id 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}") log(f"creating external UE in {formsemestre}: {acronyme}")
# Contrôle d'accès: # Contrôle d'accès:

View File

@ -106,7 +106,7 @@ class RowEtud(tb.Row):
def etuds_sorted_from_ids(etudids) -> list[Identite]: def etuds_sorted_from_ids(etudids) -> list[Identite]:
"Liste triée d'etuds à partir d'une collections d'etudids" "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) return sorted(etuds, key=lambda etud: etud.sort_key)

View File

@ -94,7 +94,7 @@ class TableRecap(tb.Table):
self.set_groups(groups) self.set_groups(groups)
for etudid in res.formsemestre.etuds_inscriptions: for etudid in res.formsemestre.etuds_inscriptions:
etud = Identite.query.get(etudid) etud = Identite.get_etud(etudid)
row = self.row_class(self, etud) row = self.row_class(self, etud)
self.add_row(row) self.add_row(row)
row.add_etud_cols() row.add_etud_cols()

View File

@ -4,10 +4,6 @@
{% block app_content %} {% block app_content %}
{% if message %}
<div class="alert alert-danger" role="alert">{{ message }}</div>
{% endif %}
<h1>Connexion</h1> <h1>Connexion</h1>
<div class="row"> <div class="row">

View File

@ -5,7 +5,7 @@
<h2>Erreur !</h2> <h2>Erreur !</h2>
{{ exc | safe }} {{ exc }}
<p> <p>
{% if g.scodoc_dept %} {% if g.scodoc_dept %}

View File

@ -64,7 +64,7 @@ class ScoData:
elif request.method == "POST": elif request.method == "POST":
etudid = request.form.get("etudid", None) etudid = request.form.get("etudid", None)
if etudid is not None: if etudid is not None:
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
self.etud = etud self.etud = etud
if etud is not None: if etud is not None:
# Infos sur l'étudiant courant # Infos sur l'étudiant courant
@ -87,7 +87,7 @@ class ScoData:
sco_formsemestre_status.retreive_formsemestre_from_request() sco_formsemestre_status.retreive_formsemestre_from_request()
) )
if formsemestre_id is not None: if formsemestre_id is not None:
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
if formsemestre is None: if formsemestre is None:
self.sem = None self.sem = None
self.sem_menu_bar = None self.sem_menu_bar = None

View File

@ -363,7 +363,7 @@ def SignaleAbsenceGrHebdo(
) )
formsemestre_id = groups_infos.formsemestre_id 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: if formsemestre.dept_id != g.scodoc_dept_id:
abort(404, "groupes inexistants dans ce département") abort(404, "groupes inexistants dans ce département")
require_module = sco_preferences.get_preference( require_module = sco_preferences.get_preference(

View File

@ -282,9 +282,7 @@ def formsemestre_bulletinetud(
formsemestre_id=formsemestre_id, dept_id=g.scodoc_dept_id formsemestre_id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()
if etudid: if etudid:
etud = models.Identite.query.filter_by( etud = Identite.get_etud(etudid)
etudid=etudid, dept_id=formsemestre.dept_id
).first_or_404()
elif code_nip: elif code_nip:
etud = models.Identite.query.filter_by( etud = models.Identite.query.filter_by(
code_nip=str(code_nip), dept_id=formsemestre.dept_id code_nip=str(code_nip), dept_id=formsemestre.dept_id
@ -1307,7 +1305,7 @@ def view_module_abs(moduleimpl_id, format="html"):
@scodoc @scodoc
def delete_ue_expr(formsemestre_id: int, ue_id: int): def delete_ue_expr(formsemestre_id: int, ue_id: int):
"""Efface une expression de calcul d'UE""" """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): if not formsemestre.can_be_edited_by(current_user):
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
expr = FormSemestreUEComputationExpr.query.filter_by( 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 classique: désinscrit l'etudiant de tous les modules de cette UE dans ce semestre.
- En APC: dispense de l'UE indiquée. - 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) 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 ue.formation.is_apc():
if ( if (
DispenseUE.query.filter_by( DispenseUE.query.filter_by(
@ -1638,7 +1636,7 @@ def etud_inscrit_ue(etudid, formsemestre_id, ue_id):
formsemestre = FormSemestre.query.filter_by( formsemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
ue = UniteEns.query.get_or_404(ue_id) ue = UniteEns.query.get_or_404(ue_id)
if ue.formation.is_apc(): if ue.formation.is_apc():
for disp in DispenseUE.query.filter_by( 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) (inscrit non démissionnaire ni défaillant et ayant un mail renseigné dans ScoDoc)
""" """
prefer_mail_perso = int(prefer_mail_perso) prefer_mail_perso = int(prefer_mail_perso)
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
inscriptions = [ inscriptions = [
inscription inscription
for inscription in formsemestre.inscriptions for inscription in formsemestre.inscriptions
@ -2330,9 +2328,7 @@ def formsemestre_validation_but(
formsemestre: FormSemestre = FormSemestre.query.filter_by( formsemestre: FormSemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
nb_etuds = formsemestre.etuds.count() nb_etuds = formsemestre.etuds.count()
# la route ne donne pas le type d'etudid pour pouvoir construire des URLs # la route ne donne pas le type d'etudid pour pouvoir construire des URLs
# provisoires avec NEXT et PREV # 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() form = jury_but_forms.FormSemestreValidationAutoBUTForm()
if request.method == "POST": if request.method == "POST":
if not form.cancel.data: if not form.cancel.data:
@ -2740,7 +2736,7 @@ def formsemestre_validation_suppress_etud(
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
) )
) )
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
if formsemestre.formation.is_apc(): if formsemestre.formation.is_apc():
next_url = url_for( next_url = url_for(
"scolar.ficheEtud", "scolar.ficheEtud",
@ -2864,7 +2860,7 @@ def formsemestre_jury_but_erase(
mode_jury=1, mode_jury=1,
) )
else: else:
etud: Identite = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
etuds = [etud] etuds = [etud]
dest_url = url_for( dest_url = url_for(
"notes.formsemestre_validation_but", "notes.formsemestre_validation_but",

View File

@ -227,7 +227,7 @@ def get_etud_dept():
""" """
if "etudid" in request.args: if "etudid" in request.args:
# zero ou une réponse: # 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: elif "code_nip" in request.args:
# il peut y avoir plusieurs réponses si l'étudiant est passé par plusieurs départements # 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() etuds = Identite.query.filter_by(code_nip=request.args["code_nip"]).all()

View File

@ -695,7 +695,7 @@ sco_publish(
@scodoc7func @scodoc7func
def doAddAnnotation(etudid, comment): def doAddAnnotation(etudid, comment):
"ajoute annotation sur etudiant" "ajoute annotation sur etudiant"
etud = Identite.query.get_or_404(etudid) # check existence _ = Identite.get_etud(etudid) # check existence
if comment: if comment:
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
sco_etud.etud_annotations_create( sco_etud.etud_annotations_create(
@ -746,7 +746,7 @@ def doSuppressAnnotation(etudid, annotation_id):
@scodoc7func @scodoc7func
def form_change_coordonnees(etudid): def form_change_coordonnees(etudid):
"edit coordonnees etudiant" "edit coordonnees etudiant"
etud = Identite.query.get_or_404(etudid) etud = Identite.get_etud(etudid)
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
adrs = sco_etud.adresse_list(cnx, {"etudid": etudid}) adrs = sco_etud.adresse_list(cnx, {"etudid": etudid})
if adrs: if adrs:
@ -1064,9 +1064,7 @@ def form_change_photo(etudid=None):
@scodoc7func @scodoc7func
def form_suppress_photo(etudid=None, dialog_confirmed=False): def form_suppress_photo(etudid=None, dialog_confirmed=False):
"""Formulaire suppression photo étudiant""" """Formulaire suppression photo étudiant"""
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
if not dialog_confirmed: if not dialog_confirmed:
return scu.confirm_dialog( return scu.confirm_dialog(
f"<p>Confirmer la suppression de la photo de {etud.nom_disp()} ?</p>", f"<p>Confirmer la suppression de la photo de {etud.nom_disp()} ?</p>",
@ -1120,9 +1118,7 @@ def _form_dem_of_def(
operation_method: str = "", operation_method: str = "",
): ):
"Formulaire démission ou défaillance Etudiant" "Formulaire démission ou défaillance Etudiant"
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
formsemestre: FormSemestre = FormSemestre.query.filter_by( formsemestre: FormSemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()
@ -1265,9 +1261,7 @@ def _do_cancel_dem_or_def(
event_type="DEMISSION", event_type="DEMISSION",
): ):
"Annule une démission ou une défaillance" "Annule une démission ou une défaillance"
etud: Identite = Identite.query.filter_by( etud = Identite.get_etud(etudid)
id=etudid, dept_id=g.scodoc_dept_id
).first_or_404()
formsemestre: FormSemestre = FormSemestre.query.filter_by( formsemestre: FormSemestre = FormSemestre.query.filter_by(
id=formsemestre_id, dept_id=g.scodoc_dept_id id=formsemestre_id, dept_id=g.scodoc_dept_id
).first_or_404() ).first_or_404()

View File

@ -337,8 +337,9 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
"title": "Pseudo (login)", "title": "Pseudo (login)",
"size": 20, "size": 20,
"allow_null": False, "allow_null": False,
"explanation": "nom utilisé pour la connexion. Doit être unique parmi tous les utilisateurs." "explanation": """nom utilisé pour la connexion.
"Lettres ou chiffres uniquement.", Doit être unique parmi tous les utilisateurs.
Lettres ou chiffres uniquement.""",
}, },
), ),
("formsemestre_id", {"input_type": "hidden"}), ("formsemestre_id", {"input_type": "hidden"}),

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.4.67" SCOVERSION = "9.4.68"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"

View File

@ -18,6 +18,7 @@ from flask_login import login_user, logout_user, current_user
import psycopg2 import psycopg2
import sqlalchemy import sqlalchemy
import app as mapp
from app import create_app, cli, db from app import create_app, cli, db
from app import initialize_scodoc_database from app import initialize_scodoc_database
from app import clear_scodoc_cache 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")) @click.argument("zipfile", type=click.File("rb"))
def photos_import_files(formsemestre_id: int, xlsfile: str, zipfile: str): 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 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.scodoc import sco_trombino, sco_photos
from app.auth.models import get_super_admin from app.auth.models import get_super_admin
sem = mapp.models.formsemestre.FormSemestre.query.get(formsemestre_id) formsemestre = FormSemestre.query.get(formsemestre_id)
if not sem: if not formsemestre:
sys.stderr.write("photos-import-files: numéro de semestre invalide\n") sys.stderr.write("photos-import-files: formsemestre_id invalide\n")
return 2 return 2
with app.test_request_context(): with app.test_request_context():
mapp.set_sco_dept(sem.departement.acronym) mapp.set_sco_dept(formsemestre.departement.acronym)
admin_user = get_super_admin() admin_user = get_super_admin()
login_user(admin_user) login_user(admin_user)

View File

@ -48,7 +48,7 @@ def bench_notes_table(dept: str, formsemestre_ids: list[int]) -> float:
tot_time = 0.0 tot_time = 0.0
for formsemestre_id in formsemestre_ids: for formsemestre_id in formsemestre_ids:
print(f"building sem {formsemestre_id}...") print(f"building sem {formsemestre_id}...")
formsemestre = FormSemestre.query.get(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
t0 = time.time() t0 = time.time()
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
tot_time += time.time() - t0 tot_time += time.time() - t0

View File

@ -29,7 +29,7 @@ def test_ue_moy(test_client):
ue3, ue3,
) = setup.build_modules_with_evaluations(ue_coefs=ue_coefs, nb_mods=nb_mods) ) = setup.build_modules_with_evaluations(ue_coefs=ue_coefs, nb_mods=nb_mods)
assert len(evaluation_ids) == 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]) evaluation1 = Evaluation.query.get(evaluation_ids[0])
evaluation2 = Evaluation.query.get(evaluation_ids[1]) evaluation2 = Evaluation.query.get(evaluation_ids[1])
etud = G.create_etud(nom="test") etud = G.create_etud(nom="test")

View File

@ -239,7 +239,7 @@ def run_sco_basic(verbose=False) -> FormSemestre:
# ---- Suppression d'un étudiant, vérification inscription # ---- Suppression d'un étudiant, vérification inscription
# (permet de tester les cascades) # (permet de tester les cascades)
etud = Identite.query.get(etuds[0]["etudid"]) etud = Identite.get_etud(etuds[0]["etudid"])
assert etud is not None assert etud is not None
etudid = etud.id etudid = etud.id
db.session.delete(etud) db.session.delete(etud)