############################################################################## # ScoDoc # Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved. # See LICENSE ############################################################################## """Stockage des décisions de jury """ import pandas as pd from app import db from app.models import FormSemestre, ScolarFormSemestreValidation from app.comp.res_cache import ResultatsCache from app.scodoc import sco_cache from app.scodoc import sco_codes_parcours class ValidationsSemestre(ResultatsCache): """Les décisions de jury pour un semestre""" _cached_attrs = ( "decisions_jury", "decisions_jury_ues", "ue_capitalisees", ) def __init__(self, formsemestre: FormSemestre): super().__init__(formsemestre, sco_cache.ValidationsSemestreCache) self.decisions_jury = {} """Décisions prises dans ce semestre: { etudid : { 'code' : None|ATT|..., 'assidu' : 0|1 }}""" self.decisions_jury_ues = {} """Décisions sur des UEs dans ce semestre: { etudid : { ue_id : { 'code' : Note|ADM|CMP, 'event_date' }}} """ self.ue_capitalisees: pd.DataFrame = None """DataFrame, index etudid formsemestre_id : origine de l'UE capitalisée is_external : vrai si validation effectuée dans un semestre extérieur ue_id : dans le semestre origine (pas toujours de la même formation) ue_code : code de l'UE, moy_ue : note enregistrée, event_date : date de la validation (jury).""" if not self.load_cached(): self.compute() self.store() def compute(self): "Charge les résultats de jury et UEs capitalisées" self.ue_capitalisees = formsemestre_get_ue_capitalisees(self.formsemestre) self.comp_decisions_jury() def comp_decisions_jury(self): """Cherche les decisions du jury pour le semestre (pas les UE). Calcule les attributs: decisions_jury = { etudid : { 'code' : None|ATT|..., 'assidu' : 0|1 }} decision_jury_ues={ etudid : { ue_id : { 'code' : Note|ADM|CMP, 'event_date' }}} Si la décision n'a pas été prise, la clé etudid n'est pas présente. Si l'étudiant est défaillant, pas de décisions d'UE. """ # repris de NotesTable.comp_decisions_jury pour la compatibilité decisions_jury_q = ScolarFormSemestreValidation.query.filter_by( formsemestre_id=self.formsemestre.id ) decisions_jury = {} for decision in decisions_jury_q.filter( ScolarFormSemestreValidation.ue_id == None # slt dec. sem. ): decisions_jury[decision.etudid] = { "code": decision.code, "assidu": decision.assidu, "compense_formsemestre_id": decision.compense_formsemestre_id, "event_date": decision.event_date.strftime("%d/%m/%Y"), } self.decisions_jury = decisions_jury # UEs: decisions_jury_ues = {} for decision in decisions_jury_q.filter( ScolarFormSemestreValidation.ue_id != None # slt dec. sem. ): if decision.etudid not in decisions_jury_ues: decisions_jury_ues[decision.etudid] = {} # Calcul des ECTS associés à cette UE: if sco_codes_parcours.code_ue_validant(decision.code): ects = decision.ue.ects or 0.0 # 0 if None else: ects = 0.0 decisions_jury_ues[decision.etudid][decision.ue.id] = { "code": decision.code, "ects": ects, # 0. si UE non validée "event_date": decision.event_date.strftime("%d/%m/%Y"), } self.decisions_jury_ues = decisions_jury_ues def formsemestre_get_ue_capitalisees(formsemestre: FormSemestre) -> pd.DataFrame: """Liste des UE capitalisées (ADM) utilisables dans ce formsemestre Recherche dans les semestres des formations de même code, avec le même semestre_id et une date de début antérieure que celle du formsemestre. Prend aussi les UE externes validées. Attention: fonction très coûteuse, cacher le résultat. Résultat: DataFrame avec etudid (index) formsemestre_id : origine de l'UE capitalisée is_external : vrai si validation effectuée dans un semestre extérieur ue_id : dans le semestre origine (pas toujours de la même formation) ue_code : code de l'UE moy_ue : event_date : } ] """ query = """ SELECT DISTINCT SFV.*, ue.ue_code FROM notes_ue ue, notes_formations nf, notes_formations nf2, scolar_formsemestre_validation SFV, notes_formsemestre sem, notes_formsemestre_inscription ins WHERE ue.formation_id = nf.id and nf.formation_code = nf2.formation_code and nf2.id=%(formation_id)s and ins.etudid = SFV.etudid and ins.formsemestre_id = %(formsemestre_id)s and SFV.ue_id = ue.id and SFV.code = 'ADM' and ( (sem.id = SFV.formsemestre_id and sem.date_debut < %(date_debut)s and sem.semestre_id = %(semestre_id)s ) or ( ((SFV.formsemestre_id is NULL) OR (SFV.is_external)) -- les UE externes ou "anterieures" AND (SFV.semestre_id is NULL OR SFV.semestre_id=%(semestre_id)s) ) ) """ params = { "formation_id": formsemestre.formation.id, "formsemestre_id": formsemestre.id, "semestre_id": formsemestre.semestre_id, "date_debut": formsemestre.date_debut, } df = pd.read_sql_query(query, db.engine, params=params, index_col="etudid") return df