quelques annotations
This commit is contained in:
parent
720e891f23
commit
c5c7e9135b
@ -205,6 +205,19 @@ class Identite(db.Model):
|
|||||||
d.update(adresse.to_dict(convert_nulls_to_str=True))
|
d.update(adresse.to_dict(convert_nulls_to_str=True))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def inscriptions(self) -> list["FormSemestreInscription"]:
|
||||||
|
"Liste des inscriptions à des formsemestres, triée, la plus récente en tête"
|
||||||
|
from app.models.formsemestre import FormSemestre, FormSemestreInscription
|
||||||
|
|
||||||
|
return (
|
||||||
|
FormSemestreInscription.query.join(FormSemestreInscription.formsemestre)
|
||||||
|
.filter(
|
||||||
|
FormSemestreInscription.etudid == self.id,
|
||||||
|
)
|
||||||
|
.order_by(desc(FormSemestre.date_debut))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
def inscription_courante(self):
|
def inscription_courante(self):
|
||||||
"""La première inscription à un formsemestre _actuellement_ en cours.
|
"""La première inscription à un formsemestre _actuellement_ en cours.
|
||||||
None s'il n'y en a pas (ou plus, ou pas encore).
|
None s'il n'y en a pas (ou plus, ou pas encore).
|
||||||
@ -216,7 +229,7 @@ class Identite(db.Model):
|
|||||||
]
|
]
|
||||||
return r[0] if r else None
|
return r[0] if r else None
|
||||||
|
|
||||||
def inscriptions_courantes(self) -> list: # -> list[FormSemestreInscription]:
|
def inscriptions_courantes(self) -> list["FormSemestreInscription"]:
|
||||||
"""Liste des inscriptions à des semestres _courants_
|
"""Liste des inscriptions à des semestres _courants_
|
||||||
(il est rare qu'il y en ai plus d'une, mais c'est possible).
|
(il est rare qu'il y en ai plus d'une, mais c'est possible).
|
||||||
Triées par date de début de semestre décroissante (le plus récent en premier).
|
Triées par date de début de semestre décroissante (le plus récent en premier).
|
||||||
@ -244,18 +257,6 @@ class Identite(db.Model):
|
|||||||
]
|
]
|
||||||
return r[0] if r else None
|
return r[0] if r else None
|
||||||
|
|
||||||
def inscription_etat(self, formsemestre_id):
|
|
||||||
"""État de l'inscription de cet étudiant au semestre:
|
|
||||||
False si pas inscrit, ou scu.INSCRIT, DEMISSION, DEF
|
|
||||||
"""
|
|
||||||
# voir si ce n'est pas trop lent:
|
|
||||||
ins = models.FormSemestreInscription.query.filter_by(
|
|
||||||
etudid=self.id, formsemestre_id=formsemestre_id
|
|
||||||
).first()
|
|
||||||
if ins:
|
|
||||||
return ins.etat
|
|
||||||
return False
|
|
||||||
|
|
||||||
def inscription_descr(self) -> dict:
|
def inscription_descr(self) -> dict:
|
||||||
"""Description de l'état d'inscription"""
|
"""Description de l'état d'inscription"""
|
||||||
inscription_courante = self.inscription_courante()
|
inscription_courante = self.inscription_courante()
|
||||||
@ -294,6 +295,18 @@ class Identite(db.Model):
|
|||||||
"situation": situation,
|
"situation": situation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def inscription_etat(self, formsemestre_id):
|
||||||
|
"""État de l'inscription de cet étudiant au semestre:
|
||||||
|
False si pas inscrit, ou scu.INSCRIT, DEMISSION, DEF
|
||||||
|
"""
|
||||||
|
# voir si ce n'est pas trop lent:
|
||||||
|
ins = models.FormSemestreInscription.query.filter_by(
|
||||||
|
etudid=self.id, formsemestre_id=formsemestre_id
|
||||||
|
).first()
|
||||||
|
if ins:
|
||||||
|
return ins.etat
|
||||||
|
return False
|
||||||
|
|
||||||
def descr_situation_etud(self) -> str:
|
def descr_situation_etud(self) -> str:
|
||||||
"""Chaîne décrivant la situation _actuelle_ de l'étudiant.
|
"""Chaîne décrivant la situation _actuelle_ de l'étudiant.
|
||||||
Exemple:
|
Exemple:
|
||||||
|
@ -487,6 +487,19 @@ class FormSemestre(db.Model):
|
|||||||
etudid, self.date_debut.isoformat(), self.date_fin.isoformat()
|
etudid, self.date_debut.isoformat(), self.date_fin.isoformat()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_codes_apogee(self, category=None) -> set[str]:
|
||||||
|
"""Les codes Apogée (codés en base comme "VRT1,VRT2")
|
||||||
|
category: None: tous, "etapes": étapes associées, "sem: code semestre", "annee": code annuel
|
||||||
|
"""
|
||||||
|
codes = set()
|
||||||
|
if category is None or category == "etapes":
|
||||||
|
codes |= {e.etape_apo for e in self.etapes if e}
|
||||||
|
if (category is None or category == "sem") and self.elt_sem_apo:
|
||||||
|
codes |= {x.strip() for x in self.elt_sem_apo.split(",") if x}
|
||||||
|
if (category is None or category == "annee") and self.elt_annee_apo:
|
||||||
|
codes |= {x.strip() for x in self.elt_annee_apo.split(",") if x}
|
||||||
|
return codes
|
||||||
|
|
||||||
def get_inscrits(self, include_demdef=False, order=False) -> list[Identite]:
|
def get_inscrits(self, include_demdef=False, order=False) -> list[Identite]:
|
||||||
"""Liste des étudiants inscrits à ce semestre
|
"""Liste des étudiants inscrits à ce semestre
|
||||||
Si include_demdef, tous les étudiants, avec les démissionnaires
|
Si include_demdef, tous les étudiants, avec les démissionnaires
|
||||||
|
@ -178,7 +178,7 @@ class Module(db.Model):
|
|||||||
def get_codes_apogee(self) -> set[str]:
|
def get_codes_apogee(self) -> set[str]:
|
||||||
"""Les codes Apogée (codés en base comme "VRT1,VRT2")"""
|
"""Les codes Apogée (codés en base comme "VRT1,VRT2")"""
|
||||||
if self.code_apogee:
|
if self.code_apogee:
|
||||||
return {x.strip() for x in self.code_apogee.split(",")}
|
return {x.strip() for x in self.code_apogee.split(",") if x}
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,5 +124,5 @@ class UniteEns(db.Model):
|
|||||||
def get_codes_apogee(self) -> set[str]:
|
def get_codes_apogee(self) -> set[str]:
|
||||||
"""Les codes Apogée (codés en base comme "VRT1,VRT2")"""
|
"""Les codes Apogée (codés en base comme "VRT1,VRT2")"""
|
||||||
if self.code_apogee:
|
if self.code_apogee:
|
||||||
return {x.strip() for x in self.code_apogee.split(",")}
|
return {x.strip() for x in self.code_apogee.split(",") if x}
|
||||||
return set()
|
return set()
|
||||||
|
@ -258,11 +258,16 @@ class ApoEtud(dict):
|
|||||||
self["nom"] = nom
|
self["nom"] = nom
|
||||||
self["prenom"] = prenom
|
self["prenom"] = prenom
|
||||||
self["naissance"] = naissance
|
self["naissance"] = naissance
|
||||||
self.cols = cols # { col_id : value } colid = 'apoL_c0001'
|
self.cols = cols
|
||||||
|
"{ col_id : value } colid = 'apoL_c0001'"
|
||||||
|
self.col_elts = {}
|
||||||
|
"{'V1RT': {'R': 'ADM', 'J': '', 'B': 20, 'N': '12.14'}}"
|
||||||
self.new_cols = {} # { col_id : value to record in csv }
|
self.new_cols = {} # { col_id : value to record in csv }
|
||||||
self.etud = None # etud ScoDoc
|
self.etud: Identite = None
|
||||||
|
"etudiant ScoDoc associé"
|
||||||
self.etat = None # ETUD_OK, ...
|
self.etat = None # ETUD_OK, ...
|
||||||
self.is_NAR = False # set to True si NARé dans un semestre
|
self.is_NAR = False
|
||||||
|
"True si NARé dans un semestre"
|
||||||
self.log = []
|
self.log = []
|
||||||
self.has_logged_no_decision = False
|
self.has_logged_no_decision = False
|
||||||
self.export_res_etape = export_res_etape # VET, ...
|
self.export_res_etape = export_res_etape # VET, ...
|
||||||
@ -276,7 +281,7 @@ class ApoEtud(dict):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "ApoEtud( nom='%s', nip='%s' )" % (self["nom"], self["nip"])
|
return f"""ApoEtud( nom='{self["nom"]}', nip='{self["nip"]}' )"""
|
||||||
|
|
||||||
def lookup_scodoc(self, etape_formsemestre_ids):
|
def lookup_scodoc(self, etape_formsemestre_ids):
|
||||||
"""Cherche l'étudiant ScoDoc associé à cet étudiant Apogée.
|
"""Cherche l'étudiant ScoDoc associé à cet étudiant Apogée.
|
||||||
@ -284,6 +289,10 @@ class ApoEtud(dict):
|
|||||||
met .etud à None.
|
met .etud à None.
|
||||||
Sinon, cherche le semestre, et met l'état à ETUD_OK ou ETUD_NON_INSCRIT.
|
Sinon, cherche le semestre, et met l'état à ETUD_OK ou ETUD_NON_INSCRIT.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# futur: #WIP
|
||||||
|
# etud: Identite = Identite.query.filter_by(code_nip=self["nip"]).first()
|
||||||
|
# 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:
|
||||||
# pas dans ScoDoc
|
# pas dans ScoDoc
|
||||||
@ -291,13 +300,16 @@ class ApoEtud(dict):
|
|||||||
self.log.append("non inscrit dans ScoDoc")
|
self.log.append("non inscrit dans ScoDoc")
|
||||||
self.etat = ETUD_ORPHELIN
|
self.etat = ETUD_ORPHELIN
|
||||||
else:
|
else:
|
||||||
|
# futur: #WIP
|
||||||
|
# formsemestre_ids = {
|
||||||
|
# ins.formsemestre_id for ins in etud.formsemestre_inscriptions
|
||||||
|
# }
|
||||||
|
# in_formsemestre_ids = formsemestre_ids.intersection(etape_formsemestre_ids)
|
||||||
self.etud = etuds[0]
|
self.etud = etuds[0]
|
||||||
# cherche le semestre ScoDoc correspondant à l'un de ceux de l'etape:
|
# cherche le semestre ScoDoc correspondant à l'un de ceux de l'etape:
|
||||||
formsemestre_ids = {s["formsemestre_id"] for s in self.etud["sems"]}
|
formsemestre_ids = {s["formsemestre_id"] for s in self.etud["sems"]}
|
||||||
self.in_formsemestre_ids = formsemestre_ids.intersection(
|
in_formsemestre_ids = formsemestre_ids.intersection(etape_formsemestre_ids)
|
||||||
etape_formsemestre_ids
|
if not in_formsemestre_ids:
|
||||||
)
|
|
||||||
if not self.in_formsemestre_ids:
|
|
||||||
self.log.append(
|
self.log.append(
|
||||||
"connu dans ScoDoc, mais pas inscrit dans un semestre de cette étape"
|
"connu dans ScoDoc, mais pas inscrit dans un semestre de cette étape"
|
||||||
)
|
)
|
||||||
@ -305,7 +317,7 @@ class ApoEtud(dict):
|
|||||||
else:
|
else:
|
||||||
self.etat = ETUD_OK
|
self.etat = ETUD_OK
|
||||||
|
|
||||||
def associate_sco(self, apo_data):
|
def associate_sco(self, apo_data: "ApoData"):
|
||||||
"""Recherche les valeurs des éléments Apogée pour cet étudiant
|
"""Recherche les valeurs des éléments Apogée pour cet étudiant
|
||||||
Set .new_cols
|
Set .new_cols
|
||||||
"""
|
"""
|
||||||
@ -327,7 +339,7 @@ class ApoEtud(dict):
|
|||||||
cur_sem, autre_sem = self.etud_semestres_de_etape(apo_data)
|
cur_sem, autre_sem = self.etud_semestres_de_etape(apo_data)
|
||||||
for sem in apo_data.sems_etape:
|
for sem in apo_data.sems_etape:
|
||||||
el = self.search_elt_in_sem(code, sem, cur_sem, autre_sem)
|
el = self.search_elt_in_sem(code, sem, cur_sem, autre_sem)
|
||||||
if el != None:
|
if el is not None:
|
||||||
sco_elts[code] = el
|
sco_elts[code] = el
|
||||||
break
|
break
|
||||||
self.col_elts[code] = el
|
self.col_elts[code] = el
|
||||||
@ -338,15 +350,15 @@ class ApoEtud(dict):
|
|||||||
self.new_cols[col_id] = sco_elts[code][
|
self.new_cols[col_id] = sco_elts[code][
|
||||||
apo_data.cols[col_id]["Type Rés."]
|
apo_data.cols[col_id]["Type Rés."]
|
||||||
]
|
]
|
||||||
except KeyError:
|
except KeyError as exc:
|
||||||
log(
|
log(
|
||||||
"associate_sco: missing key, etud=%s\ncode='%s'\netape='%s'"
|
f"associate_sco: missing key, etud={self}\ncode='{code}'\netape='{apo_data.etape_apogee}'"
|
||||||
% (self, code, apo_data.etape_apogee)
|
|
||||||
)
|
)
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
"""L'élément %s n'a pas de résultat: peut-être une erreur dans les codes sur le programme pédagogique (vérifier qu'il est bien associé à une UE ou semestre)?"""
|
f"""L'élément {code} n'a pas de résultat: peut-être une erreur
|
||||||
% code
|
dans les codes sur le programme pédagogique
|
||||||
)
|
(vérifier qu'il est bien associé à une UE ou semestre)?"""
|
||||||
|
) from exc
|
||||||
# recopie les 4 premieres colonnes (nom, ..., naissance):
|
# recopie les 4 premieres colonnes (nom, ..., naissance):
|
||||||
for col_id in apo_data.col_ids[:4]:
|
for col_id in apo_data.col_ids[:4]:
|
||||||
self.new_cols[col_id] = self.cols[col_id]
|
self.new_cols[col_id] = self.cols[col_id]
|
||||||
@ -356,7 +368,7 @@ class ApoEtud(dict):
|
|||||||
# codes = set([apo_data.cols[col_id].code for col_id in apo_data.col_ids])
|
# codes = set([apo_data.cols[col_id].code for col_id in apo_data.col_ids])
|
||||||
# return codes - set(sco_elts)
|
# return codes - set(sco_elts)
|
||||||
|
|
||||||
def search_elt_in_sem(self, code, sem, cur_sem, autre_sem):
|
def search_elt_in_sem(self, code, sem, cur_sem, autre_sem) -> dict:
|
||||||
"""
|
"""
|
||||||
VET code jury etape
|
VET code jury etape
|
||||||
ELP élément pédagogique: UE, module
|
ELP élément pédagogique: UE, module
|
||||||
@ -820,10 +832,8 @@ class ApoData(object):
|
|||||||
elts[col["Code"]] = ApoElt([col])
|
elts[col["Code"]] = ApoElt([col])
|
||||||
return elts # { code apo : ApoElt }
|
return elts # { code apo : ApoElt }
|
||||||
|
|
||||||
def apo_read_etuds(self, f):
|
def apo_read_etuds(self, f) -> list[ApoEtud]:
|
||||||
"""Lecture des etudiants (et resultats) du fichier CSV Apogée
|
"""Lecture des etudiants (et resultats) du fichier CSV Apogée"""
|
||||||
-> liste de dicts
|
|
||||||
"""
|
|
||||||
L = []
|
L = []
|
||||||
while True:
|
while True:
|
||||||
line = f.readline()
|
line = f.readline()
|
||||||
@ -958,8 +968,11 @@ class ApoData(object):
|
|||||||
"""
|
"""
|
||||||
codes_by_sem = {}
|
codes_by_sem = {}
|
||||||
for sem in self.sems_etape:
|
for sem in self.sems_etape:
|
||||||
formsemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(
|
||||||
# L'ensemble des codes apo associés aux modules:
|
sem["formsemestre_id"]
|
||||||
|
)
|
||||||
|
# L'ensemble des codes apo associés aux éléments:
|
||||||
|
codes_semestre = formsemestre.get_codes_apogee()
|
||||||
codes_modules = set().union(
|
codes_modules = set().union(
|
||||||
*[
|
*[
|
||||||
modimpl.module.get_codes_apogee()
|
modimpl.module.get_codes_apogee()
|
||||||
@ -976,12 +989,8 @@ class ApoData(object):
|
|||||||
codes_by_sem[sem["formsemestre_id"]] = s
|
codes_by_sem[sem["formsemestre_id"]] = s
|
||||||
for col_id in self.col_ids[4:]:
|
for col_id in self.col_ids[4:]:
|
||||||
code = self.cols[col_id]["Code"] # 'V1RT'
|
code = self.cols[col_id]["Code"] # 'V1RT'
|
||||||
# associé à l'étape, l'année ou les semestre:
|
# associé à l'étape, l'année ou le semestre:
|
||||||
if (
|
if code in codes_semestre:
|
||||||
sco_formsemestre.sem_has_etape(sem, code)
|
|
||||||
or (code in {x.strip() for x in sem["elt_sem_apo"].split(",")})
|
|
||||||
or (code in {x.strip() for x in sem["elt_annee_apo"].split(",")})
|
|
||||||
):
|
|
||||||
s.add(code)
|
s.add(code)
|
||||||
continue
|
continue
|
||||||
# associé à une UE:
|
# associé à une UE:
|
||||||
|
@ -109,7 +109,7 @@ class DecisionSem(object):
|
|||||||
# log('%s: %s %s %s %s %s' % (self.codechoice,code_etat,new_code_prev,formsemestre_id_utilise_pour_compenser,devenir,assiduite) )
|
# log('%s: %s %s %s %s %s' % (self.codechoice,code_etat,new_code_prev,formsemestre_id_utilise_pour_compenser,devenir,assiduite) )
|
||||||
|
|
||||||
|
|
||||||
def SituationEtudParcours(etud, formsemestre_id):
|
def SituationEtudParcours(etud: dict, formsemestre_id: int):
|
||||||
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)"""
|
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)"""
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
@ -124,7 +124,7 @@ def SituationEtudParcours(etud, formsemestre_id):
|
|||||||
class SituationEtudParcoursGeneric(object):
|
class SituationEtudParcoursGeneric(object):
|
||||||
"Semestre dans un parcours"
|
"Semestre dans un parcours"
|
||||||
|
|
||||||
def __init__(self, etud, formsemestre_id, nt):
|
def __init__(self, etud: dict, formsemestre_id: int, nt: NotesTableCompat):
|
||||||
"""
|
"""
|
||||||
etud: dict filled by fill_etuds_info()
|
etud: dict filled by fill_etuds_info()
|
||||||
"""
|
"""
|
||||||
@ -132,7 +132,7 @@ class SituationEtudParcoursGeneric(object):
|
|||||||
self.etudid = etud["etudid"]
|
self.etudid = etud["etudid"]
|
||||||
self.formsemestre_id = formsemestre_id
|
self.formsemestre_id = formsemestre_id
|
||||||
self.sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
self.sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
self.nt = nt
|
self.nt: NotesTableCompat = nt
|
||||||
self.formation = self.nt.formsemestre.formation
|
self.formation = self.nt.formsemestre.formation
|
||||||
self.parcours = self.nt.parcours
|
self.parcours = self.nt.parcours
|
||||||
# Ce semestre est-il le dernier de la formation ? (e.g. semestre 4 du DUT)
|
# Ce semestre est-il le dernier de la formation ? (e.g. semestre 4 du DUT)
|
||||||
|
Loading…
Reference in New Issue
Block a user