import openpyxl from openpyxl.worksheet.worksheet import Worksheet from app.but.prepajury_xl_format import ( SCO_COLORS, FMT, SCO_FONTSIZE, SCO_VALIGN, SCO_HALIGN, SCO_BORDERTHICKNESS, Sco_Style, HAIR_BLACK, SCO_NUMBER_FORMAT, ) from app.comp import res_sem from app.models import ApcCompetence, ApcParcours, FormSemestre from app.but.prepajury_xl import ( ScoExcelBook, ScoExcelSheet, base_signature, Frame_Engine, Merge_Engine, ) UNUSED = "XXX" liste_annees = ["BUT1", "BUT2", "BUT3"] header_colors = { "BUT1": { "BUT": SCO_COLORS.BUT1, "RCUE": SCO_COLORS.RCUE1, "UE": SCO_COLORS.UE1, }, "BUT2": { "BUT": SCO_COLORS.BUT2, "RCUE": SCO_COLORS.RCUE2, "UE": SCO_COLORS.UE2, }, "BUT3": { "BUT": SCO_COLORS.BUT3, "RCUE": SCO_COLORS.RCUE3, "UE": SCO_COLORS.UE3, }, } def periode(semestre_idx): return 1 + (semestre_idx + 1) % 2 class UeDesc: def __init__(self, scodocUe, competence_id, periode): self.fromScodoc = scodocUe self.competence_id = competence_id self.periode = periode class NiveauDesc: def __init__(self, scodocNiveau): self.fromScodoc = scodocNiveau self.ues = {1: None, 2: None} for scodocUe in scodocNiveau.ues: ue_desc = UeDesc( scodocUe, scodocNiveau.competence_id, periode(scodocUe.semestre_idx) ) self.ues[periode(scodocUe.semestre_idx)] = scodocUe if not scodocUe.is_external: self.ues[periode(scodocUe.semestre_idx)] = scodocUe def get_desc(self, periode=None): if periode is None: return self return self.ues.get(periode, None) def generate_data( self, ws: ScoExcelSheet, row: int, etudiant: "EtudiantJury", column: int ) -> int: for periode in [1, 2]: ue = self.ues[periode] if ue is None: ws.set_cell(row, column, UNUSED) ws.set_cell(row, column + 1, UNUSED) else: ws.set_cell( row, column, etudiant.get_note( self.fromScodoc.annee, self.fromScodoc.competence_id, periode ), base_signature, ) ws.set_cell( row, column + 1, etudiant.get_res( self.fromScodoc.annee, self.fromScodoc.competence_id, periode ), ) column += 2 ws.set_cell( row, column, etudiant.get_note(self.fromScodoc.annee, self.fromScodoc.competence_id), base_signature, ) ws.set_cell( row, column + 1, etudiant.get_res(self.fromScodoc.annee, self.fromScodoc.competence_id), ) return column + 2 @staticmethod def generate_blank_data(ws: ScoExcelSheet, row: int, column: int) -> int: ws.set_cell(row, column + 0, "UN1") ws.set_cell(row, column + 1, "UR1") ws.set_cell(row, column + 2, "UN2") ws.set_cell(row, column + 3, "UR2") ws.set_cell(row, column + 4, "R1") ws.set_cell(row, column + 5, "R2") column += 6 return column @staticmethod def generate_blank_header(ws: ScoExcelSheet, column: int, annee: str): rcue_signature = FMT.FILL_BGCOLOR.write( value=header_colors[annee]["RCUE"].value, signature=base_signature, ) ue_signature = FMT.FILL_BGCOLOR.write( value=header_colors[annee]["UE"].value, signature=base_signature, ) merge = ws.get_merge_engine(start_row=2, start_column=column) frame = ws.get_frame_engine( start_row=2, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN ) ws.set_cell(2, column, UNUSED, from_signature=rcue_signature) for ue in ["UE1", "UE2"]: frame_ue = ws.get_frame_engine( start_row=3, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN, color=SCO_COLORS.GREY, ) merge_ue = ws.get_merge_engine(start_row=3, start_column=column) ws.set_cell(3, column, UNUSED, ue_signature) ws.set_cell(4, column, "Note", ue_signature) ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True) column += 1 ws.set_cell(4, column, "Rés.", ue_signature) ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True) column += 1 merge_ue.close(end_row=3, end_column=column - 1) frame_ue.close(end_row=4, end_column=column - 1) merge_rcue = ws.get_merge_engine(start_row=3, start_column=column) ws.set_cell(3, column, UNUSED, rcue_signature) ws.set_cell(4, column, UNUSED, rcue_signature) ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True) column += 1 ws.set_cell(4, column, UNUSED, rcue_signature) ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True) column += 1 merge_rcue.close(end_row=3, end_column=column - 1) frame.close(end_row=4, end_column=column - 1) merge.close(end_row=2, end_column=column - 1) return column def generate_header(self, ws: ScoExcelSheet, column: int): rcue_signature = FMT.FILL_BGCOLOR.write( value=header_colors[self.fromScodoc.annee]["RCUE"].value, signature=base_signature, ) ue_signature = FMT.FILL_BGCOLOR.write( value=header_colors[self.fromScodoc.annee]["UE"].value, signature=base_signature, ) merge = ws.get_merge_engine(start_row=2, start_column=column) frame = ws.get_frame_engine( start_row=2, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN ) ws.set_cell( 2, column, self.fromScodoc.competence.titre, from_signature=rcue_signature ) for periode in [1, 2]: ue = self.ues[periode] frame_ue = ws.get_frame_engine( start_row=3, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN, color=SCO_COLORS.GREY, ) merge_ue = ws.get_merge_engine(start_row=3, start_column=column) if ue is None: ws.set_cell(3, column, "XXX", ue_signature) else: ws.set_cell(3, column, ue.acronyme, ue_signature) ws.set_cell(4, column, "Note", ue_signature) column += 1 ws.set_cell(4, column, "Rés.", ue_signature) column += 1 merge_ue.close(end_row=3, end_column=column - 1) frame_ue.close(end_row=4, end_column=column - 1) merge_rcue = ws.get_merge_engine(start_row=3, start_column=column) ws.set_cell(3, column, "Competence", rcue_signature) ws.set_cell(4, column, "Note", rcue_signature) column += 1 ws.set_cell(4, column, "Rés.", rcue_signature) column += 1 merge_rcue.close(end_row=3, end_column=column - 1) frame.close(end_row=4, end_column=column - 1) merge.close(end_row=2, end_column=column - 1) return column def get_ues(self, etudiant): """get list of candidates UEs for Niveau""" ues = [None, None] for inscription in etudiant.cursus.inscriptions: formation_id = inscription.formsemestre.formation_id semestre_idx = inscription.formsemestre.semestre_id if semestre_idx in self.ues: # identifier les ues cocernées ues[periode(semestre_idx)] = inscription.formsemestre return ues class CompetenceDesc: def __init__(self, scodocCompetence): self.fromScodoc: ApcCompetence = scodocCompetence self.niveaux = {} for scodocNiveau in scodocCompetence.niveaux.all(): self.niveaux[scodocNiveau.id] = NiveauDesc(scodocNiveau) def getNiveauDesc(self, niveau_id): return self.niveaux[niveau_id] def getNiveaux(self, codeAnnee): niveaux = [] for niveau_id, niveauDesc in self.niveaux.items(): if codeAnnee == niveauDesc.fromScodoc.annee: niveaux.append(niveauDesc) return niveaux class FormsemestreDesc: def __init__(self, formsemestre_id, formsemestre=None): self.formsemestre_id = formsemestre_id self.formsemestre = formsemestre self.resultats = None def get_desc(self, competence_id=None): if competence_id is None: return self return self.ues.get(competence_id, None) def get_formsemestre(self): if self.formsemestre is None: self.formsemestre = FormSemestre.get(self.formsemestre_id) return self.formsemestre def get_resultats(self): if self.resultats is None: self.resultats = res_sem.load_formsemestre_results(self.get_formsemestre()) return self.resultats class AnneeDesc: def __init__(self, codeAnnee): self.codeAnnee = codeAnnee self.niveaux = {} def get_desc(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_desc(periode) else: return None def addNiveau(self, niveaux): for niveau in niveaux: competence_id = niveau.fromScodoc.competence_id self.niveaux[competence_id] = niveau def generate_blank_niveau(self, ws: ScoExcelSheet, column: int): return column def generate_data( self, ws: ScoExcelSheet, row: int, etudiant: "EtudiantJury", column: int ) -> int: for niveau in self.niveaux.values(): column = niveau.generate_data(ws, row, etudiant, column) for i in range(len(self.niveaux), 6): column = NiveauDesc.generate_blank_data(ws, row, column) ws.set_cell(row, column + 0, "A1") ws.set_cell(row, column + 1, etudiant.get_note(self.codeAnnee), base_signature) ws.set_cell(row, column + 2, etudiant.get_res(self.codeAnnee)) column += 3 if self.codeAnnee == "BUT2": # ws.set_cell(row, column, etudiant.getDipl("BUT2")) column += 1 if self.codeAnnee == "BUT3": # ws.set_cell(row, column, etudiant.getDipl("BUT3")) column += 1 return column def generate_header(self, ws: ScoExcelSheet, column: int): start = column but_signature = FMT.FILL_BGCOLOR.write( signature=base_signature, value=header_colors[self.codeAnnee]["BUT"].value ) merge = ws.get_merge_engine(start_row=1, start_column=column) frame = ws.get_frame_engine( start_row=1, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THICK ) ws.set_cell( 1, column, text=self.codeAnnee, from_signature=but_signature, composition=[ (FMT.BORDER_LEFT_COLOR, SCO_COLORS.BLACK.value), (FMT.BORDER_LEFT_STYLE, SCO_BORDERTHICKNESS.BORDER_MEDIUM.value), ], ) for niveau in self.niveaux.values(): column = niveau.generate_header(ws, column) for i in range(len(self.niveaux), 6): column = NiveauDesc.generate_blank_header(ws, column, self.codeAnnee) merge_annee = ws.get_merge_engine(start_row=2, start_column=column) ws.set_cell(2, column, "Année", from_signature=but_signature) # cell_format(ws.cell(2, column), but_signature, [(FMT.FONT_BOLD, True)]) ws.set_cell(3, column, "Nb", from_signature=but_signature) ws.set_cell(4, column, "RCUE", from_signature=but_signature) column += 1 ws.set_cell(3, column, from_signature=but_signature) ws.set_cell(3, column, "Moy.", from_signature=but_signature) ws.set_cell(4, column, f"Sem", from_signature=but_signature) column += 1 ws.set_cell(3, column, from_signature=but_signature) ws.set_cell(4, column, "Rés.", from_signature=but_signature) column += 1 merge_annee.close(end_row=2, end_column=column - 1) if self.codeAnnee == "BUT2": ws.set_cell(2, column, "DUT", from_signature=but_signature) ws.set_cell(3, column, from_signature=but_signature) ws.set_cell(4, column, "Rés.", from_signature=but_signature) column += 1 if self.codeAnnee == "BUT3": ws.set_cell(2, column, "BUT", from_signature=but_signature) ws.set_cell(3, column, from_signature=but_signature) ws.set_cell(4, column, "Rés.", from_signature=but_signature) column += 1 frame.close(end_row=4, end_column=column - 1) merge.close(end_row=1, end_column=column - 1) return column class ParcoursDesc: signature_header = FMT.compose( [ (FMT.FILL_BGCOLOR, SCO_COLORS.LIGHT_YELLOW.value), (FMT.NUMBER_FORMAT, SCO_NUMBER_FORMAT.NUMBER_GENERAL.value), # (FMT.FONT_BOLD, True), # (FMT.FONT_SIZE, SCO_FONTSIZE.FONTSIZE_13.value), # (FMT.ALIGNMENT_VALIGN, SCO_VALIGN.VALIGN_CENTER.value), # (FMT.ALIGNMENT_HALIGN, SCO_HALIGN.HALIGN_CENTER.value), # (FMT.BORDER_RIGHT, HAIR_BLACK), # (FMT.BORDER_LEFT, HAIR_BLACK), # (FMT.BORDER_TOP, HAIR_BLACK), # (FMT.BORDER_BOTTOM, HAIR_BLACK), ], base_signature, ) def __init__(self, formation, scodocParcour: ApcParcours = None): self.fromScodoc: ApcParcours = scodocParcour # None pour le tronc commun 'TC' self.etudiants = [] self.competences = {} self.annees = {} if scodocParcour is None: for ( scodocCompetence ) in formation.referentiel_competence.get_competences_tronc_commun(): self.competences[scodocCompetence.id] = CompetenceDesc(scodocCompetence) else: query = formation.query_competences_parcour(scodocParcour) if not query is None: for scodocCompetence in query.all(): self.competences[scodocCompetence.id] = CompetenceDesc( scodocCompetence ) for codeAnnee in liste_annees: annee_desc = AnneeDesc(codeAnnee) for competence_id, competence in self.competences.items(): annee_desc.addNiveau(competence.getNiveaux(codeAnnee)) self.annees[codeAnnee] = annee_desc def get_desc(self, annee=None, competence_id=None, periode=None): if annee is None: return self if annee in self.annees: return self.annees[annee].get_desc(competence_id, periode) return None def add_etudiant(self, etudiant): if not etudiant in self.etudiants: self.etudiants.append(etudiant) def getNiveauDesc(self, competence_id, niveau_id): return self.competences[competence_id].getNiveauDesc(niveau_id) def getData(self): data = [] for etudiant in self.etudiants: data.append(etudiant.get_data()) return data def append_title_column(self, worksheet, cells, val1, val2, val3, val4): cells1, cells2, cells3, cells4 = cells cells1.append(worksheet.make_cell(val1)) cells2.append(worksheet.make_cell(val2)) cells3.append(worksheet.make_cell(val3)) cells4.append(worksheet.make_cell(val4)) def handle_description( self, ws: ScoExcelSheet, description: tuple, row: int, column: int ) -> int: title, content_list = description frame_thickness, frame_color = [ (SCO_BORDERTHICKNESS.BORDER_THICK, SCO_COLORS.BLACK), (SCO_BORDERTHICKNESS.BORDER_HAIR, SCO_COLORS.BLACK), (SCO_BORDERTHICKNESS.BORDER_HAIR, SCO_COLORS.BLACK), (SCO_BORDERTHICKNESS.NONE, SCO_COLORS.NONE), ][row - 1] frame = ws.get_frame_engine( start_row=row, start_column=column, thickness=frame_thickness, color=frame_color, ) ws.set_cell( row=row, column=column, text=title, from_signature=self.signature_header, ) merge_h = ws.get_merge_engine(start_row=row, start_column=column) merge_v = ws.get_merge_engine(start_row=row, start_column=column) if content_list is None: merge_v.close(end_row=4) column += 1 else: for content in content_list: column = self.handle_description(ws, content, row + 1, column) merge_h.close(end_column=column - 1) frame.close(4, column - 1) return column def generate_etudiant_header(self, ws: ScoExcelSheet) -> int: titles = ( "ETUDIANT", [ ("id", None), ("nip", None), ("Civ", None), ("nom", None), ("prenom", None), ("parcours", None), ("cursus", None), ( "absences", [ ("Tot.", None), ("Non", [("Just.", None)]), ], ), ], ) column = self.handle_description(ws, titles, 1, 1) return column def generate_header(self, ws: ScoExcelSheet): column: int = self.generate_etudiant_header(ws) for codeAnnee in liste_annees: column = self.annees[codeAnnee].generate_header(ws, column) def generate(self, workbook: ScoExcelBook): if self.fromScodoc: sheet_name = self.fromScodoc.code else: sheet_name = "TC" worksheet: ScoExcelSheet = workbook.create_sheet(sheet_name) self.generate_header(worksheet) self.generate_etudiants(worksheet) def generate_data( self, ws: ScoExcelSheet, row: int, column: int, etudiant: "EtudiantJury" ): for codeAnnee in liste_annees: column = self.annees[codeAnnee].generate_data(ws, row, etudiant, column) def generate_etudiants(self, ws: ScoExcelSheet): ligne = 5 for etudiant in self.etudiants: ws.set_cell(ligne, 1, etudiant.ident.id) ws.set_cell(ligne, 2, etudiant.ident.code_nip) ws.set_cell(ligne, 3, etudiant.ident.civilite) ws.set_cell(ligne, 4, etudiant.ident.nom) ws.set_cell(ligne, 5, etudiant.ident.prenom) if etudiant.parcour: ws.set_cell(ligne, 6, etudiant.parcour.code) else: ws.set_cell(ligne, 6, "-") cursus = ", ".join(etudiant.history) ws.set_cell(ligne, 7, cursus) ws.set_cell(ligne, 8, etudiant.nbabs) ws.set_cell(ligne, 9, etudiant.nbabs - etudiant.nbabsjust) # self.generate_data(ws, ligne, 10, etudiant) ligne = ligne + 1