Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
5 changed files with 80 additions and 56 deletions
Showing only changes of commit e6d61fcd8a - Show all commits

View File

@ -209,7 +209,7 @@ class ResultatsSemestre(ResultatsCache):
"last_modif" : datetime.datetime | None, # saisie de note la plus récente "last_modif" : datetime.datetime | None, # saisie de note la plus récente
"nb_notes" : int, # nb notes d'étudiants inscrits "nb_notes" : int, # nb notes d'étudiants inscrits
}, },
"evaluatiuon_id" : int, "evaluation_id" : int,
"jour" : datetime.datetime, # e.date_debut or datetime.datetime(1900, 1, 1) "jour" : datetime.datetime, # e.date_debut or datetime.datetime(1900, 1, 1)
"publish_incomplete" : bool, "publish_incomplete" : bool,
} }
@ -435,6 +435,21 @@ class ResultatsSemestre(ResultatsCache):
def get_etud_ue_status(self, etudid: int, ue_id: int) -> dict: def get_etud_ue_status(self, etudid: int, ue_id: int) -> dict:
"""L'état de l'UE pour cet étudiant. """L'état de l'UE pour cet étudiant.
Result: dict, ou None si l'UE n'est pas dans ce semestre. Result: dict, ou None si l'UE n'est pas dans ce semestre.
{
"is_capitalized": # vrai si la version capitalisée est celle prise en compte (meilleure)
"was_capitalized":# si elle a été capitalisée (meilleure ou pas)
"is_external": # si UE externe
"coef_ue": 0.0,
"cur_moy_ue": 0.0, # moyenne de l'UE courante
"moy": 0.0, # moyenne prise en compte
"event_date": # date de la capiltalisation éventuelle (ou None)
"ue": ue_dict, # l'UE, comme un dict
"formsemestre_id": None,
"capitalized_ue_id": None, # l'id de l'UE capitalisée, ou None
"ects_pot": 0.0, # deprecated (les ECTS liés à cette UE)
"ects": 0.0, # les ECTS acquis grace à cette UE
"ects_ue": # les ECTS liés à cette UE
}
""" """
ue: UniteEns = db.session.get(UniteEns, ue_id) ue: UniteEns = db.session.get(UniteEns, ue_id)
ue_dict = ue.to_dict() ue_dict = ue.to_dict()
@ -512,11 +527,13 @@ 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, {}) "ects": (
.get(ue.id, {}) self.validations.decisions_jury_ues.get(etudid, {})
.get("ects", 0.0) .get(ue.id, {})
if self.validations.decisions_jury_ues .get("ects", 0.0)
else 0.0, if self.validations.decisions_jury_ues
else 0.0
),
"ects_ue": ue.ects, "ects_ue": ue.ects,
"cur_moy_ue": cur_moy_ue, "cur_moy_ue": cur_moy_ue,
"moy": moy_ue, "moy": moy_ue,

View File

@ -125,7 +125,7 @@ class Identite(models.ScoDocModel):
) )
# Champs "protégés" par ViewEtudData (RGPD) # Champs "protégés" par ViewEtudData (RGPD)
protected_attrs = {"boursier"} protected_attrs = {"boursier", "nationalite"}
def __repr__(self): def __repr__(self):
return ( return (

View File

@ -44,7 +44,6 @@ from app.models import Evaluation, FormSemestre, ModuleImpl
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ModuleType from app.scodoc.sco_utils import ModuleType
import app.scodoc.notesdb as ndb
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_cal from app.scodoc import sco_cal
@ -114,9 +113,9 @@ def do_evaluation_etat(
nb_neutre, nb_neutre,
nb_att, nb_att,
moy, median, mini, maxi : # notes, en chaine, sur 20 moy, median, mini, maxi : # notes, en chaine, sur 20
last_modif: datetime, last_modif: datetime, *
gr_complets, gr_incomplets, gr_complets, gr_incomplets,
evalcomplete evalcomplete *
} }
evalcomplete est vrai si l'eval est complete (tous les inscrits evalcomplete est vrai si l'eval est complete (tous les inscrits
à ce module ont des notes) à ce module ont des notes)
@ -519,9 +518,9 @@ def formsemestre_evaluations_delai_correction(formsemestre_id, fmt="html"):
{ {
"date_first_complete": date_first_complete, "date_first_complete": date_first_complete,
"delai_correction": delai_correction, "delai_correction": delai_correction,
"jour": e.date_debut.strftime("%d/%m/%Y") "jour": (
if e.date_debut e.date_debut.strftime("%d/%m/%Y") if e.date_debut else "sans date"
else "sans date", ),
"_jour_target": url_for( "_jour_target": url_for(
"notes.evaluation_listenotes", "notes.evaluation_listenotes",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,

View File

@ -514,10 +514,11 @@ def groups_table(
"paiementinscription_str": "Paiement", "paiementinscription_str": "Paiement",
"etudarchive": "Fichiers", "etudarchive": "Fichiers",
"annotations_str": "Annotations", "annotations_str": "Annotations",
"bourse_str": "Boursier", "bourse_str": "Boursier", # requière ViewEtudData
"etape": "Etape", "etape": "Etape",
"semestre_groupe": "Semestre-Groupe", # pour Moodle "semestre_groupe": "Semestre-Groupe", # pour Moodle
"annee": "annee_admission", "annee": "annee_admission",
"nationalite": "nationalite", # requière ViewEtudData
} }
# ajoute colonnes pour groupes # ajoute colonnes pour groupes
@ -559,53 +560,61 @@ def groups_table(
moodle_sem_name = groups_infos.formsemestre["session_id"] moodle_sem_name = groups_infos.formsemestre["session_id"]
moodle_groupenames = set() moodle_groupenames = set()
# ajoute liens # ajoute liens
for etud in groups_infos.members: for etud_info in groups_infos.members:
if etud["email"]: if etud_info["email"]:
etud["_email_target"] = "mailto:" + etud["email"] etud_info["_email_target"] = "mailto:" + etud_info["email"]
else: else:
etud["_email_target"] = "" etud_info["_email_target"] = ""
if etud["emailperso"]: if etud_info["emailperso"]:
etud["_emailperso_target"] = "mailto:" + etud["emailperso"] etud_info["_emailperso_target"] = "mailto:" + etud_info["emailperso"]
else: else:
etud["_emailperso_target"] = "" etud_info["_emailperso_target"] = ""
fiche_url = url_for( fiche_url = url_for(
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"] "scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud_info["etudid"]
) )
etud["_nom_disp_target"] = fiche_url etud_info["_nom_disp_target"] = fiche_url
etud["_nom_disp_order"] = etud_sort_key(etud) etud_info["_nom_disp_order"] = etud_sort_key(etud_info)
etud["_prenom_target"] = fiche_url etud_info["_prenom_target"] = fiche_url
etud["_nom_disp_td_attrs"] = 'id="%s" class="etudinfo"' % (etud["etudid"]) etud_info["_nom_disp_td_attrs"] = 'id="%s" class="etudinfo"' % (
etud["bourse_str"] = "oui" if etud["boursier"] else "non" etud_info["etudid"]
if etud["etat"] == "D": )
etud["_css_row_class"] = "etuddem" etud_info["bourse_str"] = "oui" if etud_info["boursier"] else "non"
if etud_info["etat"] == "D":
etud_info["_css_row_class"] = "etuddem"
# et groupes: # et groupes:
for partition_id in etud["partitions"]: for partition_id in etud_info["partitions"]:
etud[partition_id] = etud["partitions"][partition_id]["group_name"] etud_info[partition_id] = etud_info["partitions"][partition_id][
"group_name"
]
# Ajoute colonne pour moodle: semestre_groupe, de la forme # Ajoute colonne pour moodle: semestre_groupe, de la forme
# RT-DUT-FI-S3-2021-PARTITION-GROUPE # RT-DUT-FI-S3-2021-PARTITION-GROUPE
moodle_groupename = [] moodle_groupename = []
if groups_infos.selected_partitions: if groups_infos.selected_partitions:
# il y a des groupes selectionnes, utilise leurs partitions # il y a des groupes selectionnes, utilise leurs partitions
for partition_id in groups_infos.selected_partitions: for partition_id in groups_infos.selected_partitions:
if partition_id in etud["partitions"]: if partition_id in etud_info["partitions"]:
moodle_groupename.append( moodle_groupename.append(
partitions_name[partition_id] partitions_name[partition_id]
+ "-" + "-"
+ etud["partitions"][partition_id]["group_name"] + etud_info["partitions"][partition_id]["group_name"]
) )
else: else:
# pas de groupes sélectionnés: prend le premier s'il y en a un # pas de groupes sélectionnés: prend le premier s'il y en a un
moodle_groupename = ["tous"] moodle_groupename = ["tous"]
if etud["partitions"]: if etud_info["partitions"]:
for p in etud["partitions"].items(): # partitions is an OrderedDict for p in etud_info[
"partitions"
].items(): # partitions is an OrderedDict
moodle_groupename = [ moodle_groupename = [
partitions_name[p[0]] + "-" + p[1]["group_name"] partitions_name[p[0]] + "-" + p[1]["group_name"]
] ]
break break
moodle_groupenames |= set(moodle_groupename) moodle_groupenames |= set(moodle_groupename)
etud["semestre_groupe"] = moodle_sem_name + "-" + "+".join(moodle_groupename) etud_info["semestre_groupe"] = (
moodle_sem_name + "-" + "+".join(moodle_groupename)
)
if groups_infos.nbdem > 1: if groups_infos.nbdem > 1:
s = "s" s = "s"
@ -714,9 +723,11 @@ def groups_table(
}); });
</script> </script>
""", """,
"""<span class="warning_unauthorized">accès aux données personnelles interdit</span>""" (
if not can_view_etud_data """<span class="warning_unauthorized">accès aux données personnelles interdit</span>"""
else "", if not can_view_etud_data
else ""
),
] ]
) )
H.append("</div></form>") H.append("</div></form>")
@ -768,13 +779,7 @@ def groups_table(
return "".join(H) return "".join(H)
elif ( elif fmt in {"pdf", "xml", "json", "xls", "moodlecsv"}:
fmt == "pdf"
or fmt == "xml"
or fmt == "json"
or fmt == "xls"
or fmt == "moodlecsv"
):
if fmt == "moodlecsv": if fmt == "moodlecsv":
fmt = "csv" fmt = "csv"
return tab.make_page(fmt=fmt) return tab.make_page(fmt=fmt)
@ -789,7 +794,7 @@ def groups_table(
with_paiement=with_paiement, with_paiement=with_paiement,
server_name=request.url_root, server_name=request.url_root,
) )
filename = "liste_%s" % groups_infos.groups_filename filename = f"liste_{groups_infos.groups_filename}"
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) return scu.send_file(xls, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)
elif fmt == "allxls": elif fmt == "allxls":
if not can_view_etud_data: if not can_view_etud_data:
@ -823,6 +828,7 @@ def groups_table(
"fax", "fax",
"date_naissance", "date_naissance",
"lieu_naissance", "lieu_naissance",
"nationalite",
"bac", "bac",
"specialite", "specialite",
"annee_bac", "annee_bac",
@ -845,16 +851,16 @@ def groups_table(
# remplis infos lycee si on a que le code lycée # remplis infos lycee si on a que le code lycée
# et ajoute infos inscription # et ajoute infos inscription
for m in groups_infos.members: for m in groups_infos.members:
etud = sco_etud.get_etud_info(m["etudid"], filled=True)[0] etud_info = sco_etud.get_etud_info(m["etudid"], filled=True)[0]
m.update(etud) m.update(etud_info)
sco_etud.etud_add_lycee_infos(etud) sco_etud.etud_add_lycee_infos(etud_info)
# et ajoute le parcours # et ajoute le parcours
Se = sco_cursus.get_situation_etud_cursus( Se = sco_cursus.get_situation_etud_cursus(
etud, groups_infos.formsemestre_id etud_info, groups_infos.formsemestre_id
) )
m["parcours"] = Se.get_cursus_descr() m["parcours"] = Se.get_cursus_descr()
m["code_cursus"], _ = sco_report.get_code_cursus_etud( m["code_cursus"], _ = sco_report.get_code_cursus_etud(
etud["etudid"], sems=etud["sems"] etud_info["etudid"], sems=etud_info["sems"]
) )
rows = [[m.get(k, "") for k in keys] for m in groups_infos.members] rows = [[m.get(k, "") for k in keys] for m in groups_infos.members]
title = "etudiants_%s" % groups_infos.groups_filename title = "etudiants_%s" % groups_infos.groups_filename
@ -905,9 +911,11 @@ def tab_absences_html(groups_infos, etat=None):
% groups_infos.groups_query_args, % groups_infos.groups_query_args,
"""<li><a class="stdlink" href="trombino?%s&fmt=pdflist">Liste d'appel avec photos</a></li>""" """<li><a class="stdlink" href="trombino?%s&fmt=pdflist">Liste d'appel avec photos</a></li>"""
% groups_infos.groups_query_args, % groups_infos.groups_query_args,
f"""<li><a class="stdlink" href="groups_export_annotations?{groups_infos.groups_query_args}">Liste des annotations</a></li>""" (
if authuser.has_permission(Permission.ViewEtudData) f"""<li><a class="stdlink" href="groups_export_annotations?{groups_infos.groups_query_args}">Liste des annotations</a></li>"""
else """<li class="unauthorized" title="non autorisé">Liste des annotations</li>""", if authuser.has_permission(Permission.ViewEtudData)
else """<li class="unauthorized" title="non autorisé">Liste des annotations</li>"""
),
"</ul>", "</ul>",
] ]
) )

View File

@ -617,7 +617,7 @@ def _list_but_ue_inscriptions(res: NotesTableCompat, read_only: bool = True) ->
<p>L'inscription ou désinscription aux UEs du BUT n'affecte pas les inscriptions aux modules <p>L'inscription ou désinscription aux UEs du BUT n'affecte pas les inscriptions aux modules
mais permet de "dispenser" un étudiant de suivre certaines UEs de son parcours. mais permet de "dispenser" un étudiant de suivre certaines UEs de son parcours.
</p> </p>
<p>Il peut s'agit d'étudiants redoublants ayant déjà acquis l'UE, ou d'une UE <p>Il peut s'agir d'étudiants redoublants ayant déjà acquis l'UE, ou d'une UE
présente dans le semestre mais pas dans le parcours de l'étudiant, ou bien d'autres présente dans le semestre mais pas dans le parcours de l'étudiant, ou bien d'autres
cas particuliers. cas particuliers.
</p> </p>