Modif fiche etudiant: affichage ECTS validés. Close #434

This commit is contained in:
Emmanuel Viennet 2022-07-19 10:28:22 +02:00
parent 157423edaf
commit e7db835c4b
4 changed files with 49 additions and 44 deletions

View File

@ -32,7 +32,7 @@ class ValidationsSemestre(ResultatsCache):
{ etudid : { 'code' : None|ATT|..., 'assidu' : 0|1 }}""" { etudid : { 'code' : None|ATT|..., 'assidu' : 0|1 }}"""
self.decisions_jury_ues = {} self.decisions_jury_ues = {}
"""Décisions sur des UEs dans ce semestre: """Décisions sur des UEs dans ce semestre:
{ etudid : { ue_id : { 'code' : Note|ADM|CMP, 'event_date' }}} { etudid : { ue_id : { 'code' : Note|ADM|CMP, 'event_date': "d/m/y", "ects" : x}}}
""" """
self.ue_capitalisees: pd.DataFrame = None self.ue_capitalisees: pd.DataFrame = None
"""DataFrame, index etudid """DataFrame, index etudid

View File

@ -177,7 +177,7 @@ class ResultatsSemestre(ResultatsCache):
Rappel: l'étudiant est inscrit à des modimpls et non à des UEs. Rappel: l'étudiant est inscrit à des modimpls et non à des UEs.
- En BUT: on considère que l'étudiant va (ou non) valider toutes les UEs des modules - En BUT: on considère que l'étudiant va (ou non) valider toutes les UEs des modules
du parcours. XXX notion à implémenter, pour l'instant toutes les UE du semestre. du parcours.
- En classique: toutes les UEs des modimpls auxquels l'étudiant est inscrit sont - En classique: toutes les UEs des modimpls auxquels l'étudiant est inscrit sont
susceptibles d'être validées. susceptibles d'être validées.
@ -185,24 +185,23 @@ class ResultatsSemestre(ResultatsCache):
Les UE "bonus" (sport) ne sont jamais "validables". Les UE "bonus" (sport) ne sont jamais "validables".
""" """
if self.is_apc: if self.is_apc:
# TODO: introduire la notion de parcours (#sco93) return list(self.etud_ues(etudid))
return self.formsemestre.query_ues().filter(UniteEns.type != UE_SPORT).all() # Formations classiques:
else: # restreint aux UE auxquelles l'étudiant est inscrit (dans l'un des modimpls)
# restreint aux UE auxquelles l'étudiant est inscrit (dans l'un des modimpls) ues = {
ues = { modimpl.module.ue
modimpl.module.ue for modimpl in self.formsemestre.modimpls_sorted
for modimpl in self.formsemestre.modimpls_sorted if self.modimpl_inscr_df[modimpl.id][etudid]
if self.modimpl_inscr_df[modimpl.id][etudid] }
} ues = sorted(list(ues), key=lambda x: x.numero or 0)
ues = sorted(list(ues), key=lambda x: x.numero or 0) return ues
return ues
def modimpls_in_ue(self, ue: UniteEns, etudid, with_bonus=True) -> list[ModuleImpl]: def modimpls_in_ue(self, ue: UniteEns, etudid, with_bonus=True) -> list[ModuleImpl]:
"""Liste des modimpl de cette UE auxquels l'étudiant est inscrit. """Liste des modimpl de cette UE auxquels l'étudiant est inscrit.
Utile en formations classiques, surchargée pour le BUT. Utile en formations classiques, surchargée pour le BUT.
Inclus modules bonus le cas échéant. Inclus modules bonus le cas échéant.
""" """
# sert pour l'affichage ou non de l'UE sur le bulletin # Utilisée pour l'affichage ou non de l'UE sur le bulletin
# Méthode surchargée en BUT # Méthode surchargée en BUT
modimpls = [ modimpls = [
modimpl modimpl
@ -325,6 +324,8 @@ class ResultatsSemestre(ResultatsCache):
"formsemestre_id": None, "formsemestre_id": None,
"capitalized_ue_id": None, "capitalized_ue_id": None,
"ects_pot": 0.0, "ects_pot": 0.0,
"ects": 0.0,
"ects_ue": ue.ects,
} }
if not ue_id in self.etud_moy_ue: if not ue_id in self.etud_moy_ue:
return None return None
@ -379,6 +380,12 @@ class ResultatsSemestre(ResultatsCache):
"is_external": ue_cap["is_external"] if is_capitalized else ue.is_external, "is_external": ue_cap["is_external"] if is_capitalized else ue.is_external,
"coef_ue": coef_ue, "coef_ue": coef_ue,
"ects_pot": ue.ects or 0.0, "ects_pot": ue.ects or 0.0,
"ects": self.validations.decisions_jury_ues.get(etudid, {})
.get(ue.id, {})
.get("ects", 0.0)
if self.validations.decisions_jury_ues
else 0.0,
"ects_ue": ue.ects,
"cur_moy_ue": cur_moy_ue, "cur_moy_ue": cur_moy_ue,
"moy": moy_ue, "moy": moy_ue,
"event_date": ue_cap["event_date"] if is_capitalized else None, "event_date": ue_cap["event_date"] if is_capitalized else None,

View File

@ -333,7 +333,7 @@ class NotesTableCompat(ResultatsSemestre):
def get_etud_mod_moy(self, moduleimpl_id: int, etudid: int) -> float: def get_etud_mod_moy(self, moduleimpl_id: int, etudid: int) -> float:
"""La moyenne de l'étudiant dans le moduleimpl """La moyenne de l'étudiant dans le moduleimpl
En APC, il s'agira d'une moyenne indicative sans valeur. En APC, il s'agira d'une moyenne indicative sans valeur.
Result: valeur float (peut être naN) ou chaîne "NI" (non inscrit ou DEM) Result: valeur float (peut être NaN) ou chaîne "NI" (non inscrit ou DEM)
""" """
raise NotImplementedError() # virtual method raise NotImplementedError() # virtual method
@ -351,24 +351,25 @@ class NotesTableCompat(ResultatsSemestre):
ects_pot : (float) nb de crédits ECTS qui seraient validés ects_pot : (float) nb de crédits ECTS qui seraient validés
(sous réserve de validation par le jury) (sous réserve de validation par le jury)
ects_pot_fond: (float) nb d'ECTS issus d'UE fondamentales (non électives) ects_pot_fond: (float) nb d'ECTS issus d'UE fondamentales (non électives)
ects_total: (float) total des ECTS validables
Ce sont les ECTS des UE au dessus de la barre (10/20 en principe), avant le jury (donc non Les ects_pot sont les ECTS des UE au dessus de la barre (10/20 en principe),
encore enregistrées). avant le jury (donc non encore enregistrés).
""" """
# was nt.get_etud_moy_infos # was nt.get_etud_moy_infos
# XXX pour compat nt, à remplacer ultérieurement # XXX pour compat nt, à remplacer ultérieurement
ues = self.get_etud_ue_validables(etudid) ues = self.get_etud_ue_validables(etudid)
ects_pot = 0.0 ects_pot = 0.0
ects_total = 0.0
for ue in ues: for ue in ues:
if ( if ue.id in self.etud_moy_ue and ue.ects is not None:
ue.id in self.etud_moy_ue ects_total += ue.ects
and ue.ects is not None if self.etud_moy_ue[ue.id][etudid] > self.parcours.NOTES_BARRE_VALID_UE:
and self.etud_moy_ue[ue.id][etudid] > self.parcours.NOTES_BARRE_VALID_UE ects_pot += ue.ects
):
ects_pot += ue.ects
return { return {
"ects_pot": ects_pot, "ects_pot": ects_pot,
"ects_pot_fond": 0.0, # not implemented (anciennemment pour école ingé) "ects_pot_fond": 0.0, # not implemented (anciennemment pour école ingé)
"ects_total": ects_total,
} }
def get_evals_in_mod(self, moduleimpl_id: int) -> list[dict]: def get_evals_in_mod(self, moduleimpl_id: int) -> list[dict]:

View File

@ -679,18 +679,12 @@ def formsemestre_recap_parcours_table(
class_ue = "ue" class_ue = "ue"
if ue_status and ue_status["is_external"]: # validation externe if ue_status and ue_status["is_external"]: # validation externe
explanation_ue.append("UE externe.") explanation_ue.append("UE externe.")
# log('x'*12+' EXTERNAL %s' % notes_table.fmt_note(moy_ue)) XXXXXXX
# log('UE=%s' % pprint.pformat(ue))
# log('explanation_ue=%s\n'%explanation_ue)
if ue_status and ue_status["is_capitalized"]: if ue_status and ue_status["is_capitalized"]:
class_ue += " ue_capitalized" class_ue += " ue_capitalized"
explanation_ue.append( explanation_ue.append(
"Capitalisée le %s." % (ue_status["event_date"] or "?") "Capitalisée le %s." % (ue_status["event_date"] or "?")
) )
# log('x'*12+' CAPITALIZED %s' % notes_table.fmt_note(moy_ue))
# log('UE=%s' % pprint.pformat(ue))
# log('UE_STATUS=%s' % pprint.pformat(ue_status)) XXXXXX
# log('')
H.append( H.append(
'<td class="%s" title="%s">%s</td>' '<td class="%s" title="%s">%s</td>'
@ -712,27 +706,30 @@ def formsemestre_recap_parcours_table(
sco_preferences.get_preference("bul_show_ects", sem["formsemestre_id"]) sco_preferences.get_preference("bul_show_ects", sem["formsemestre_id"])
or nt.parcours.ECTS_ONLY or nt.parcours.ECTS_ONLY
): ):
etud_ects_infos = nt.get_etud_ects_pot(etudid) etud_ects_infos = nt.get_etud_ects_pot(etudid) # ECTS potentiels
H.append( H.append(
'<tr class="%s rcp_l2 sem_%s">' % (class_sem, sem["formsemestre_id"]) f"""<tr class="{class_sem} rcp_l2 sem_{sem["formsemestre_id"]}">
<td class="rcp_type_sem" style="background-color:{bgcolor};">&nbsp;</td>
<td></td>"""
) )
# Total ECTS (affiché sous la moyenne générale)
H.append( H.append(
'<td class="rcp_type_sem" style="background-color:%s;">&nbsp;</td><td></td>' f"""<td class="sem_ects_tit"><a title="crédit acquis">ECTS:</a></td>
% (bgcolor) <td class="sem_ects">{pv.get("sum_ects",0):2.2g} / {etud_ects_infos["ects_total"]:2.2g}</td>
<td class="rcp_abs"></td>
"""
) )
# total ECTS (affiché sous la moyenne générale)
H.append(
'<td class="sem_ects_tit"><a title="crédit potentiels">ECTS:</a></td><td class="sem_ects">%g</td>'
% (etud_ects_infos["ects_pot"])
)
H.append('<td class="rcp_abs"></td>')
# ECTS validables dans chaque UE # ECTS validables dans chaque UE
for ue in ues: for ue in ues:
ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"])
H.append( if ue_status:
'<td class="ue">%g</td>' ects = ue_status["ects"]
% (ue_status["ects_pot"] if ue_status else "") ects_pot = ue_status["ects_pot"]
) H.append(
f"""<td class="ue" title="{ects:2.2g}/{ects_pot:2.2g} ECTS">{ects:2.2g}</td>"""
)
else:
H.append(f"""<td class="ue"></td>""")
H.append("<td></td></tr>") H.append("<td></td></tr>")
H.append("</table>") H.append("</table>")