# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Emmanuel Viennet emmanuel.viennet@viennet.net # ############################################################################## """Feuille excel pour préparation des jurys classiques (non BUT) """ import time from flask import abort from app.but import jury_but from app.but.cursus_but import EtudCursusBUT from app.but.prepajury_desc import ParcoursDesc, FormsemestreDesc from app.models import ( FormSemestre, ApcParcours, Formation, ) import app.scodoc.sco_utils as scu from app.but.prepajury_xl import ScoExcelBook class Element: def __init__(self, etudiant): self.etudiant = etudiant self.note = None self.resultat = None self.format = 0 def set_note(self, note): self.note = note def set_res(self, res): self.resultat = res def get_res(self): return self.resultat def get_note(self): return self.note class ElementUE(Element): def __init__(self, etudiant): super().__init__(etudiant) self.status = None def set_status(self, status): self.status = status class ElementNiveau(Element): def __init__(self, etudiant, competence_id): super().__init__(etudiant) self.competence_id = competence_id self.validation = None self.ues = {} def get_elem(self, periode=None): if periode is None: return self return self.ues.get(periode, None) def compute(self, rcue): self.set_note(rcue.moy_rcue) class ElementFormsemestre(Element): def __init__(self, etudiant, formsemestre_desc: FormsemestreDesc = None): super().__init__(etudiant) self.formsemestre_desc = formsemestre_desc self.formsemestre_id = formsemestre_desc.formsemestre_id self.deca = None self.ues = {} def get_elem(self, competence_id=None): if competence_id is None: return self return self.ues.get(competence_id, None) class ElementAnnee(Element): def __init__(self, etudiant): super().__init__(etudiant) self.formsemestres = {} self.niveaux = {} self.last = None self.deca = None def get_elem(self, competence_id=None, periode=None): if competence_id is None and periode is None: return self elif competence_id is None: return self.formsemestres.get(periode, None) elif competence_id in self.niveaux: return self.niveaux[competence_id].get_elem(periode) else: return None def set_periode(self, periode, formsemestre_desc): self.formsemestres[periode] = formsemestre_desc def set_niveau(self, competence_id, elem_niveau): self.niveaux[competence_id] = elem_niveau def add_validation(self, validation): competence_id = validation.ue1.niveau_competence.competence_id self.niveaux[competence_id].set_res(validation.code) def create_structure(self): self.last = self.formsemestres.get(2, self.formsemestres.get(1, None)) if self.last is not None: self.deca = jury_but.DecisionsProposeesAnnee( self.etudiant.ident, self.last.formsemestre_desc.formsemestre ) for niveau in self.deca.niveaux_competences: competence_id = niveau.competence_id elem_niveau = ElementNiveau(self.etudiant, competence_id) self.niveaux[competence_id] = elem_niveau for ue in self.deca.ues_impair: competence_id = ue.niveau_competence.competence_id periode = 1 elem_ue = ElementUE(self.etudiant) self.niveaux[competence_id].ues[periode] = elem_ue self.formsemestres[periode].ues[competence_id] = elem_ue for ue in self.deca.ues_pair: competence_id = ue.niveau_competence.competence_id periode = 2 elem_ue = ElementUE(self.etudiant) self.niveaux[competence_id].ues[periode] = elem_ue self.formsemestres[periode].ues[competence_id] = elem_ue def compute(self): if self.last is not None: self.set_res(self.deca.code_valide) self.set_note( self.last.formsemestre_desc.get_resultats().get_etud_moy_gen( self.etudiant.ident.id ) ) class EtudiantJury: """ Structure: ident formation parcour cursus inscriptions* current_formsemestre absences_tot absences_just Annees* nb_rcues note resultat niveaux* note resultat ues* note resultat DUT resultat BUT resultat """ annee_periode = { 1: ("BUT1", 1), 2: ("BUT1", 2), 3: ("BUT2", 1), 4: ("BUT2", 2), 5: ("BUT3", 1), 6: ("BUT3", 2), } def __init__(self, ident, contexte: "_Compilation"): self.ident = ident self.contexte = contexte self.formation = contexte.formation self.current_formsemestre = contexte.formsemestre self.current_formsemestre_id = contexte.formsemestre.formsemestre_id self.current_formsemestre_desc = contexte.get_semestredesc( self.current_formsemestre_id ) self.nbabs, self.nbabsjust = self.current_formsemestre.get_abs_count(ident.id) self.cursus: EtudCursusBUT = EtudCursusBUT(ident, self.formation) self.parcour = self.cursus.inscriptions[-1].parcour # donnes propres à l étudiant (à remplir par fill_in) self.history = [] # description historique de l etudiant self.formsemestres = [] # liste historique des formsemestres self.formsemestre_by_semestre = ( {} ) # semetre_id -> dernier FormSemestreDesc pour chaque semestre self.formsemestre_by_annee = ( {} ) # annee -> dernier FormSemestreDesc pour chaque semestre self.annees = {} self.DUT = None # Résultat au DUT self.BUT = None # Résultat au BUT def get_elem(self, annee=None, competence_id=None, periode=None): if annee is None: return self if annee in self.annees: return self.annees[annee].get_elem(competence_id, periode) return None def get_desc(self, annee=None, competence_id=None, periode=None): return self.parcour.get_desc(annee, competence_id, periode) def compute_history(self): # calcul historique for inscription in sorted( self.cursus.inscriptions, key=lambda x: x.formsemestre.date_debut ): formsemestre = inscription.formsemestre semestre_id = None # if formsemestre.formation == self.formation: if formsemestre.formation.is_apc(): formsemestre_id = formsemestre.formsemestre_id formsemestre_desc = self.contexte.get_semestredesc(formsemestre_id) semestre_id = formsemestre.semestre_id self.formsemestres.append(formsemestre) annee, periode = EtudiantJury.annee_periode[semestre_id] self.formsemestre_by_semestre[semestre_id] = formsemestre_desc self.formsemestre_by_annee[annee] = formsemestre_desc etat = inscription.etat Sx = f"S{semestre_id}" if etat != "I": Sx += " (Dem)" if etat == "D" else f"({etat})" self.history.append(Sx) def create_structure(self): for annee, formsemestre_desc in self.formsemestre_by_annee.items(): elem_annee = ElementAnnee(self) self.annees[annee] = elem_annee for semestre_id, formsemestre_desc in self.formsemestre_by_semestre.items(): annee, periode = EtudiantJury.annee_periode[semestre_id] elem_formsemestre = ElementFormsemestre(self.ident, formsemestre_desc) self.annees[annee].set_periode(periode, elem_formsemestre) for annee in self.annees: self.annees[annee].create_structure() def compute(self): for annee in self.annees: self.annees[annee].compute() for ( competence_id, validations, ) in self.cursus.validation_par_competence_et_annee.items(): for annee, validation in validations.items(): self.annees[annee].add_validation(validation) def fill_in(self): """ Creation des donnees propres à l'étudiant """ self.compute_history() # self.create_structure() # self.compute() # for ( # competence_id, # validations_par_competence, # ) in self.cursus.validation_par_competence_et_annee.items(): # for annee, validation in validations_par_competence.items(): # elem_annee = self.annees[annee] # elem_formsemestre = elem_annee.formsemestres.get( # periode, ElementFormsemestre(self, formsemestre_desc) # ) # resultats = formsemestre_desc.get_resultats() # ues = resultats.etud_ues(self.ident.etudid) # for ue in ues: # niveau_id = ue.niveau_competence_id # competence_id = ue.niveau_competence.competence_id # status = resultats.get_etud_ue_status(self.ident.etudid, ue.id) # if competence_id not in self.annees[annee].niveaux: # elem_niveau = ElementNiveau(self, validation) # self.annees[annee].niveaux[competence_id] = elem_niveau # else: # elem_niveau = self.annees[annee].niveaux[competence_id] # elem_ue = ElementUE(self, status) # elem_niveau.ues[periode] = elem_ue # # # # for ( # competence_id, # validation, # ) in self.cursus.validation_par_competence_et_annee.items(): # self.elements_par_competence_annee_et_periode[competence_id] = {} # for annee in validation: # self.elements_par_competence_annee_et_periode[competence_id][ # annee # ] = [] # self.deca_by_semestre[semestre_idx] = jury_but.DecisionsProposeesAnnee( # self.ident, self.formsemestre_by_semestre[semestre_idx] # ) # # niveau.add_ue_status(semestre_idx, status) # if annee in self.deca: # for rcue in self.deca[annee].rcues_annee: # ue_id1 = rcue.ue_1.id # self.notes_ues[ue_id1] = rcue.moy_ue_1 # ue_id2 = rcue.ue_2.id # self.notes_ues[ue_id2] = rcue.moy_ue_2 # rcue_id = rcue.ue_1.niveau_competence_id # self.notes_rcues[rcue_id] = rcue.moy_rcue def get_note(self, annee, competence_id=None, periode=None): elem: Element = self.get_elem(annee, competence_id, periode) if elem: return elem.get_note() return "-" def get_res(self, annee, competence_id=None, periode=None): elem: Element = self.get_elem(annee, competence_id, periode) if elem: return elem.get_res() return "-" def get_data(self): result = [ self.ident.id, self.ident.code_nip, self.ident.civilite, self.ident.nom, self.ident.prenom, self.ident.etat_civil_pv(with_paragraph=False), self.parcour.code, ", ".join(self.history), ] return result class _Compilation: """ structure: semestres: formsemestre_id -> FormSemestreDesc parcours: parcour_code -> ParcoursDesc formation """ def __init__(self, formsemestre: FormSemestre): self.semestres = {} self.parcours = {} formsemestre_id = formsemestre.formsemestre_id self.formation: Formation = formsemestre.formation self.formsemestre = formsemestre self.add_semestre(formsemestre_id, formsemestre) self.current_semestre = self.semestres[formsemestre_id] # inventaire des semestres et parcours for ident in ( self.semestres[formsemestre_id].get_resultats().get_inscrits(order_by="moy") ): etudiant: EtudiantJury = EtudiantJury( ident, self ) # initialise etudiant.cursus et etudiant.parcour for inscription in etudiant.cursus.inscriptions: formsemestre = inscription.formsemestre if ( formsemestre.formation.referentiel_competence == self.formation.referentiel_competence ): self.add_semestre(formsemestre.formsemestre_id, formsemestre) scodocParcour = etudiant.parcour if scodocParcour is None: parcourCode = "TC" else: parcourCode = scodocParcour.code if parcourCode in self.parcours: parcoursDesc = self.parcours[parcourCode] else: parcoursDesc = ParcoursDesc(self.formation, scodocParcour) self.parcours[parcourCode] = parcoursDesc parcoursDesc.add_etudiant(etudiant) etudiant.fill_in() def get_semestredesc(self, formsemestre_id): return self.semestres.get(formsemestre_id, None) def add_semestre(self, formsemestre_id, formsemestre=None): if formsemestre_id not in self.semestres: self.semestres[formsemestre_id] = FormsemestreDesc( formsemestre_id, formsemestre ) def add_parcours(self, scodoc_parcour: ApcParcours, etudiant: EtudiantJury): parcour_code = scodoc_parcour.get("code", "TC") if parcour_code not in self.parcours: self.parcours[parcour_code] = ParcoursDesc(self.formation, scodoc_parcour) self.parcours[parcour_code].add(etudiant) def computes_decision(self): pass def make_excel(self, filename: str): workbook = ScoExcelBook() for parcoursCode, parcours in self.parcours.items(): parcours.generate(workbook) mime, suffix = scu.get_mime_suffix("xlsx") xls = workbook.generate() return scu.send_file(xls, filename=filename, mime=mime, suffix=suffix) def feuille_preparation_jury_but(formsemestre_id): if not isinstance(formsemestre_id, int): abort(404) formsemestre = FormSemestre.get_formsemestre(formsemestre_id) # res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) """Feuille excel pour préparation des jurys adaptée pour le BUT.""" # breakpoint() compilation = _Compilation(formsemestre) # compilation.computes_decision() filename = scu.sanitize_filename( f"""{'jury'}-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}""" ) return compilation.make_excel(filename)