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(
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,

View File

@ -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:

View File

@ -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(),
)

View File

@ -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)

View File

@ -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"""<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;">
<a href="{url_for("notes.pvjury_page_but",
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, fmt="xlsx")}"
@ -126,7 +127,7 @@ def pvjury_table_but(
for etudid in etudids:
if not etudid in formsemestre_etudids:
continue # garde fou
etud: Identite = Identite.query.get(etudid)
etud = Identite.get_etud(etudid)
try:
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
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
) -> 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)

View File

@ -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

View File

@ -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(

View File

@ -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"""<div class="scovalueerror"><p>Coefficient de l'UE capitalisée {ue.acronyme}
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"])
coef_ue = ue_capitalized.ects
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(
f"""L'UE capitalisée {ue_capitalized.acronyme}
du semestre {orig_sem.titre_annee()}

View File

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

View File

@ -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")

View File

@ -72,13 +72,22 @@ class Identite(db.Model):
)
@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
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):

View File

@ -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)"""

View File

@ -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)
# ------------------------------------------------------------------------------------------------------------------

View File

@ -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
)

View File

@ -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)

View File

@ -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

View File

@ -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(

View File

@ -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})"

View File

@ -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)

View File

@ -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")

View File

@ -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)

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"
from app.scodoc import sco_bulletins
etud: Identite = Identite.query.get_or_404(etudid)
etud = Identite.get_etud(etudid)
fragments = []
bookmarks = {}
filigrannes = {}

View File

@ -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()

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
(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:

View File

@ -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(

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
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:

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)
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')

View File

@ -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)

View File

@ -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()

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 }
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:

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]
# --- 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))

View File

@ -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"""<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.
"""
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
)

View File

@ -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()

View File

@ -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 = """<h3>aucun étudiant sans notes</h3>"""
else:
flash(
f"""{Identite.query.get_or_404(etudid).nomprenom}
f"""{Identite.get_etud(etudid).nomprenom}
a déjà des notes"""
)
return redirect(

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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_

View File

@ -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

View File

@ -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)

View File

@ -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
)

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 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"""<a class="discretelink" href="{
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
}">{etud.nomprenom}</a>"""

View File

@ -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,

View File

@ -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:

View File

@ -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 = []

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -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()

View File

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

View File

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

View File

@ -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

View File

@ -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(

View File

@ -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",

View File

@ -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()

View File

@ -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"<p>Confirmer la suppression de la photo de {etud.nom_disp()} ?</p>",
@ -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()

View File

@ -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"}),

View File

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

View File

@ -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)

View File

@ -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

View File

@ -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")

View File

@ -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)