forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -88,7 +88,7 @@ class EtudiantsJuryPE:
|
|||||||
self.abandons_ids = {}
|
self.abandons_ids = {}
|
||||||
"""Les etudids des étudiants redoublants/réorientés"""
|
"""Les etudids des étudiants redoublants/réorientés"""
|
||||||
|
|
||||||
def find_etudiants(self, formsemestre_base: FormSemestre):
|
def find_etudiants(self):
|
||||||
"""Liste des étudiants à prendre en compte dans le jury PE, en les recherchant
|
"""Liste des étudiants à prendre en compte dans le jury PE, en les recherchant
|
||||||
de manière automatique par rapport à leur année de diplomation ``annee_diplome``.
|
de manière automatique par rapport à leur année de diplomation ``annee_diplome``.
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class EtudiantsJuryPE:
|
|||||||
self.identites[etudid] = Identite.get_etud(etudid)
|
self.identites[etudid] = Identite.get_etud(etudid)
|
||||||
|
|
||||||
# Analyse son cursus
|
# Analyse son cursus
|
||||||
self.analyse_etat_etudiant(etudid, cosemestres, formsemestre_base)
|
self.analyse_etat_etudiant(etudid, cosemestres)
|
||||||
|
|
||||||
# Analyse son parcours pour atteindre chaque semestre de la formation
|
# Analyse son parcours pour atteindre chaque semestre de la formation
|
||||||
self.structure_cursus_etudiant(etudid)
|
self.structure_cursus_etudiant(etudid)
|
||||||
@ -142,7 +142,7 @@ class EtudiantsJuryPE:
|
|||||||
assert nbre_abandons == len(self.abandons_ids)
|
assert nbre_abandons == len(self.abandons_ids)
|
||||||
|
|
||||||
pe_affichage.pe_print(
|
pe_affichage.pe_print(
|
||||||
f" => {nbre_abandons} étudiants non considérés (redoublement, réorientation, abandon"
|
f" => {nbre_abandons} étudiants traités mais non diplômés (redoublement, réorientation, abandon)"
|
||||||
)
|
)
|
||||||
# pe_affichage.pe_print(
|
# pe_affichage.pe_print(
|
||||||
# " => quelques étudiants futurs diplômés : "
|
# " => quelques étudiants futurs diplômés : "
|
||||||
@ -191,8 +191,7 @@ class EtudiantsJuryPE:
|
|||||||
def analyse_etat_etudiant(
|
def analyse_etat_etudiant(
|
||||||
self,
|
self,
|
||||||
etudid: int,
|
etudid: int,
|
||||||
cosemestres: dict[int, FormSemestre],
|
cosemestres: dict[int, FormSemestre]
|
||||||
formsemestre_base: FormSemestre,
|
|
||||||
):
|
):
|
||||||
"""Analyse le cursus d'un étudiant pouvant être :
|
"""Analyse le cursus d'un étudiant pouvant être :
|
||||||
|
|
||||||
@ -205,9 +204,10 @@ class EtudiantsJuryPE:
|
|||||||
* à insérer une entrée dans ``self.cursus`` pour mémoriser son identité,
|
* à insérer une entrée dans ``self.cursus`` pour mémoriser son identité,
|
||||||
avec son nom, prénom, etc...
|
avec son nom, prénom, etc...
|
||||||
* à analyser son parcours, pour déterminer s'il a démissionné, redoublé (autre année de diplôme)
|
* à analyser son parcours, pour déterminer s'il a démissionné, redoublé (autre année de diplôme)
|
||||||
ou a abandonné l'IUT en cours de route (cf. clé abandon). Un étudiant est considéré en abandon s'il n'est
|
ou a abandonné l'IUT en cours de route (cf. clé abandon). Un étudiant est considéré
|
||||||
inscrit à aucun cosemestres de rang supérieur ou égal (et donc de dates)
|
en abandon si connaissant son dernier semestre (par ex. un S3) il n'est pas systématiquement
|
||||||
à celui ayant servi à lancer le jury (`formsemestre_base`)
|
inscrit à l'un des S4, S5 ou S6 existants dans les cosemestres.
|
||||||
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
etudid: L'etudid d'un étudiant, à ajouter à ceux traiter par le jury
|
etudid: L'etudid d'un étudiant, à ajouter à ceux traiter par le jury
|
||||||
@ -251,7 +251,7 @@ class EtudiantsJuryPE:
|
|||||||
else:
|
else:
|
||||||
# Est-il réorienté ou a-t-il arrêté (volontairement) sa formation ?
|
# Est-il réorienté ou a-t-il arrêté (volontairement) sa formation ?
|
||||||
self.cursus[etudid]["abandon"] = arret_de_formation(
|
self.cursus[etudid]["abandon"] = arret_de_formation(
|
||||||
identite, cosemestres, formsemestre_base
|
identite, cosemestres
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_semestres_significatifs(self, etudid: int):
|
def get_semestres_significatifs(self, etudid: int):
|
||||||
@ -458,9 +458,7 @@ def get_semestres_apc(identite: Identite) -> list:
|
|||||||
return semestres_apc
|
return semestres_apc
|
||||||
|
|
||||||
|
|
||||||
def arret_de_formation(
|
def arret_de_formation(etud: Identite, cosemestres: dict[int, FormSemestre]) -> bool:
|
||||||
etud: Identite, cosemestres: dict[int, FormSemestre], formsemestre_base: FormSemestre
|
|
||||||
) -> bool:
|
|
||||||
"""Détermine si un étudiant a arrêté sa formation (volontairement ou non). Il peut s'agir :
|
"""Détermine si un étudiant a arrêté sa formation (volontairement ou non). Il peut s'agir :
|
||||||
|
|
||||||
* d'une réorientation à l'initiative du jury de semestre ou d'une démission
|
* d'une réorientation à l'initiative du jury de semestre ou d'une démission
|
||||||
@ -473,8 +471,7 @@ def arret_de_formation(
|
|||||||
Dans les cas, on considérera que l'étudiant a arrêté sa formation s'il n'est pas
|
Dans les cas, on considérera que l'étudiant a arrêté sa formation s'il n'est pas
|
||||||
dans l'un des "derniers" cosemestres (semestres conduisant à la même année de diplômation)
|
dans l'un des "derniers" cosemestres (semestres conduisant à la même année de diplômation)
|
||||||
connu dans Scodoc. Par "derniers" cosemestres, est fait le choix d'analyser tous les cosemestres
|
connu dans Scodoc. Par "derniers" cosemestres, est fait le choix d'analyser tous les cosemestres
|
||||||
de rang/semestre_id supérieur ou égal (et donc de dates) à celui du ``formsemestre_base`` ayant servi à lancer
|
de rang/semestre_id supérieur (et donc de dates) au dernier semestre dans lequel il a été inscrit.
|
||||||
le jury PE.
|
|
||||||
|
|
||||||
Par ex: au moment du jury PE en fin de S5 (pas de S6 renseigné dans Scodoc),
|
Par ex: au moment du jury PE en fin de S5 (pas de S6 renseigné dans Scodoc),
|
||||||
l'étudiant doit appartenir à une instance des S5 qui conduisent à la diplomation dans
|
l'étudiant doit appartenir à une instance des S5 qui conduisent à la diplomation dans
|
||||||
@ -501,7 +498,6 @@ def arret_de_formation(
|
|||||||
Est-il réorienté, démissionnaire ou a-t-il arrêté de son propre chef sa formation ?
|
Est-il réorienté, démissionnaire ou a-t-il arrêté de son propre chef sa formation ?
|
||||||
|
|
||||||
TODO:: A reprendre pour le cas des étudiants à l'étranger
|
TODO:: A reprendre pour le cas des étudiants à l'étranger
|
||||||
TODO:: A reprendre si BUT avec semestres décalés
|
|
||||||
"""
|
"""
|
||||||
# Les semestres APC de l'étudiant
|
# Les semestres APC de l'étudiant
|
||||||
semestres = get_semestres_apc(etud)
|
semestres = get_semestres_apc(etud)
|
||||||
@ -509,13 +505,17 @@ def arret_de_formation(
|
|||||||
if not semestres_apc:
|
if not semestres_apc:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Le dernier semestre de l'étudiant
|
||||||
|
dernier_formsemestre = semestres[0]
|
||||||
|
rang_dernier_semestre = dernier_formsemestre.semestre_id
|
||||||
|
|
||||||
# Les cosemestres de rang supérieur ou égal à celui de formsemestre, triés par rang,
|
# Les cosemestres de rang supérieur ou égal à celui de formsemestre, triés par rang,
|
||||||
# sous la forme ``{semestre_id: [liste des comestres associé à ce semestre_id]}``
|
# sous la forme ``{semestre_id: [liste des comestres associé à ce semestre_id]}``
|
||||||
cosemestres_tries_par_rang = pe_comp.tri_semestres_par_rang(cosemestres)
|
cosemestres_tries_par_rang = pe_comp.tri_semestres_par_rang(cosemestres)
|
||||||
|
|
||||||
cosemestres_superieurs = {}
|
cosemestres_superieurs = {}
|
||||||
for rang in cosemestres_tries_par_rang:
|
for rang in cosemestres_tries_par_rang:
|
||||||
if rang >= formsemestre_base.semestre_id:
|
if rang > rang_dernier_semestre:
|
||||||
cosemestres_superieurs[rang] = cosemestres_tries_par_rang[rang]
|
cosemestres_superieurs[rang] = cosemestres_tries_par_rang[rang]
|
||||||
|
|
||||||
# Si pas d'autres cosemestres postérieurs
|
# Si pas d'autres cosemestres postérieurs
|
||||||
@ -531,18 +531,24 @@ def arret_de_formation(
|
|||||||
etat_inscriptions[rang] = True
|
etat_inscriptions[rang] = True
|
||||||
|
|
||||||
# Vérifie qu'il n'y a pas de "trous" dans les rangs des cosemestres
|
# Vérifie qu'il n'y a pas de "trous" dans les rangs des cosemestres
|
||||||
rangs = etat_inscriptions.keys()
|
rangs = sorted(etat_inscriptions.keys())
|
||||||
if list(rangs) != list(range(min(rangs), max(rangs) + 1)):
|
if list(rangs) != list(range(min(rangs), max(rangs) + 1)):
|
||||||
difference = set(range(min(rangs), max(rangs) + 1)) - set(rangs)
|
difference = set(range(min(rangs), max(rangs) + 1)) - set(rangs)
|
||||||
affichage = ",".join([f"S{val}" for val in difference])
|
affichage = ",".join([f"S{val}" for val in difference])
|
||||||
raise ScoValueError(f"Il manque le(s) semestre(s) {affichage} au cursus de vos étudiants.")
|
raise ScoValueError(
|
||||||
|
f"Il manque le(s) semestre(s) {affichage} au cursus de {etud.etat_civil} ({etud.etudid})."
|
||||||
|
)
|
||||||
|
|
||||||
# Est-il inscrit à tous les semestres de rang supérieur ? Si non, est démissionnaire
|
# Est-il inscrit à tous les semestres de rang supérieur ? Si non, est démissionnaire
|
||||||
est_demissionnaire = sum(etat_inscriptions.values()) != len(rangs)
|
est_demissionnaire = sum(etat_inscriptions.values()) != len(rangs)
|
||||||
if est_demissionnaire:
|
if est_demissionnaire:
|
||||||
non_inscrit_a = [rang for rang in etat_inscriptions if not etat_inscriptions[rang]]
|
non_inscrit_a = [
|
||||||
|
rang for rang in etat_inscriptions if not etat_inscriptions[rang]
|
||||||
|
]
|
||||||
affichage = ",".join([f"S{val}" for val in non_inscrit_a])
|
affichage = ",".join([f"S{val}" for val in non_inscrit_a])
|
||||||
pe_affichage.pe_print(f"{etud.etat_civil} ({etud.etudid} considéré en abandon car non inscrit dans un (ou des) semestre(s) {affichage} amenant à diplômation")
|
pe_affichage.pe_print(
|
||||||
|
f"{etud.etat_civil} ({etud.etudid}) considéré en abandon car non inscrit dans un (ou des) semestre(s) {affichage} amenant à diplômation"
|
||||||
|
)
|
||||||
|
|
||||||
return est_demissionnaire
|
return est_demissionnaire
|
||||||
|
|
||||||
|
@ -70,14 +70,11 @@ class JuryPE(object):
|
|||||||
diplome : l'année d'obtention du diplome BUT et du jury de PE (généralement février XXXX)
|
diplome : l'année d'obtention du diplome BUT et du jury de PE (généralement février XXXX)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, diplome: int, formsemestre_base: FormSemestre):
|
def __init__(self, diplome: int):
|
||||||
pe_affichage.pe_start_log()
|
pe_affichage.pe_start_log()
|
||||||
self.diplome = diplome
|
self.diplome = diplome
|
||||||
"L'année du diplome"
|
"L'année du diplome"
|
||||||
|
|
||||||
self.formsemestre_base = formsemestre_base
|
|
||||||
"Le formsemestre ayant servi à lancer le jury PE (souvent un S3 ou un S5)"
|
|
||||||
|
|
||||||
self.nom_export_zip = f"Jury_PE_{self.diplome}"
|
self.nom_export_zip = f"Jury_PE_{self.diplome}"
|
||||||
"Nom du zip où ranger les fichiers générés"
|
"Nom du zip où ranger les fichiers générés"
|
||||||
|
|
||||||
@ -90,7 +87,7 @@ class JuryPE(object):
|
|||||||
self.diplome}"""
|
self.diplome}"""
|
||||||
)
|
)
|
||||||
self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants
|
self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants
|
||||||
self.etudiants.find_etudiants(formsemestre_base)
|
self.etudiants.find_etudiants()
|
||||||
self.diplomes_ids = self.etudiants.diplomes_ids
|
self.diplomes_ids = self.etudiants.diplomes_ids
|
||||||
|
|
||||||
self.zipdata = io.BytesIO()
|
self.zipdata = io.BytesIO()
|
||||||
|
@ -72,18 +72,20 @@ def pe_view_sem_recap(formsemestre_id: int):
|
|||||||
|
|
||||||
# Cosemestres diplomants
|
# Cosemestres diplomants
|
||||||
cosemestres = pe_comp.get_cosemestres_diplomants(annee_diplome)
|
cosemestres = pe_comp.get_cosemestres_diplomants(annee_diplome)
|
||||||
|
cosemestres_tries = pe_comp.tri_semestres_par_rang(cosemestres)
|
||||||
|
affichage_cosemestres_tries = {rang: ", ".join([sem.titre_annee() for sem in cosemestres_tries[rang]]) for rang in cosemestres_tries}
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return render_template(
|
return render_template(
|
||||||
"pe/pe_view_sem_recap.j2",
|
"pe/pe_view_sem_recap.j2",
|
||||||
annee_diplome=annee_diplome,
|
annee_diplome=annee_diplome,
|
||||||
formsemestre=formsemestre,
|
formsemestre=formsemestre,
|
||||||
sco=ScoData(formsemestre=formsemestre),
|
sco=ScoData(formsemestre=formsemestre),
|
||||||
cosemestres=cosemestres,
|
cosemestres=affichage_cosemestres_tries,
|
||||||
|
rangs_tries=sorted(affichage_cosemestres_tries.keys())
|
||||||
)
|
)
|
||||||
|
|
||||||
# request.method == "POST"
|
# request.method == "POST"
|
||||||
jury = pe_jury.JuryPE(annee_diplome, formsemestre)
|
jury = pe_jury.JuryPE(annee_diplome)
|
||||||
if not jury.diplomes_ids:
|
if not jury.diplomes_ids:
|
||||||
flash("aucun étudiant à considérer !")
|
flash("aucun étudiant à considérer !")
|
||||||
return redirect(
|
return redirect(
|
||||||
|
@ -43,12 +43,12 @@
|
|||||||
<h3>Avis de poursuites d'études de la promo {{ annee_diplome }}</h3>
|
<h3>Avis de poursuites d'études de la promo {{ annee_diplome }}</h3>
|
||||||
|
|
||||||
<div class="help">
|
<div class="help">
|
||||||
Seront (a minima) pris en compte les étudiants ayant été inscrits aux semestres suivants :
|
Seront pris en compte les étudiants ayant été inscrits à l'un des semestres suivants :
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{% for fid in cosemestres %}
|
{% for rang in rangs_tries %}
|
||||||
<li>
|
<li>
|
||||||
{{ cosemestres[fid].titre_annee() }}
|
<strong>Semestre {{rang}}</strong> : {{ cosemestres[rang] }}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
Reference in New Issue
Block a user