ScoDoc-Lille/app/but/prepajury_desc.py
2023-05-26 07:20:42 +02:00

357 lines
13 KiB
Python

import openpyxl
from openpyxl.worksheet.worksheet import Worksheet
from app.but.prepajury_cells import Sco_Cell, base_signature, set_cell, Merge_Engine
from app.but.prepajury_xl_format import (
SCO_COLORS,
FMT,
SCO_FONTSIZE,
SCO_VALIGN,
SCO_HALIGN,
SCO_BORDERTHICKNESS,
Sco_Style,
)
from app.models import ApcCompetence, ApcParcours
from app.but.prepajury_xl import ScoExcelBook, ScoExcelSheet
def parite(semestre_idx):
return (semestre_idx + 1) % 2
listeAnnees = ["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,
},
}
class _Header:
def __init__(self):
self.lines: list[list[Sco_Cell]] = []
self.presets = [None, None, None, None]
self.signatures = [
base_signature,
base_signature,
base_signature,
base_signature,
]
def setLabelOnce(self, rang: int, label: str):
self.presets[rang] = label
def setSignatures(self, rangs: list[int], signature: int):
for rang in rangs:
self.signatures[rang] = signature
def add_column(
self,
label0=None,
label1=None,
label2=None,
label3=None,
labels: list[str] = None,
):
if labels is None:
labels = [label0, label1, label2, label3]
cells: list(Sco_Cell) = [
Sco_Cell(preset or label, signature=signature)
for label, preset, signature in zip(labels, self.presets, self.signatures)
]
self.presets = [None, None, None, None]
self.lines.append(cells)
def extend(self, header):
self.lines.extend(header.lines)
def write(self, worksheet: ScoExcelSheet):
column = 1
for items in self.lines:
items[0].copy(worksheet.ws.cell(1, column))
items[1].copy(worksheet.ws.cell(2, column))
items[2].copy(worksheet.ws.cell(3, column))
items[3].copy(worksheet.ws.cell(4, column))
column += 1
class NiveauDesc:
def __init__(self, scodocNiveau):
self.fromScodoc = scodocNiveau
self.ues = {}
self.ue = [None, None]
for scodocUe in scodocNiveau.ues:
self.ues[(scodocUe.formation_id, scodocUe.semestre_idx)] = scodocUe
if not scodocUe.is_external:
self.ue[parite(scodocUe.semestre_idx)] = scodocUe
def generate_header(self, header):
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,
)
header.setLabelOnce(1, self.fromScodoc.competence.titre)
header.setSignatures([1], rcue_signature)
header.setSignatures([2, 3], ue_signature)
for ue in self.ue:
if ue is None:
header.setLabelOnce(2, "XXX")
header.add_column(label3="Note")
header.add_column(label3="Res.")
else:
header.setLabelOnce(2, ue.acronyme)
header.add_column(label3="Note")
header.add_column(label3="Res.")
header.setSignatures([1, 2, 3], rcue_signature)
header.add_column(label2="RCUE", label3="Note")
header.add_column(label3="Res.")
return header
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 (formation_id, semestre_idx) in self.ues:
# identifier les ues cocernées
ues[semestre_idx % 2] = 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 AnneeDesc:
def __init__(self, codeAnnee):
self.codeAnnee = codeAnnee
self.niveaux = {}
def addNiveau(self, niveaux):
for niveau in niveaux:
self.niveaux[niveau.fromScodoc.id] = niveau
def generate_blank_niveau(self, header):
header.setlabel(1, "-")
for _ in range(3):
header.add_column()
def generate_header(self, ws: Worksheet, column: int):
start = column
but_signature = FMT.FILL_BGCOLOR.write(
signature=base_signature, value=header_colors[self.codeAnnee]["BUT"].value
)
but_style = FMT.style(but_signature)
set_cell(
ws,
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),
],
)
but_style.apply(ws.cell(1, column))
# for niveau in self.niveaux.values():
# column = niveau.generate_header(ws, column)
# for i in range(len(self.niveaux), 6):
# column = self.generate_blank_niveau(ws, column)
ws.cell(2, column).value = "Année"
# cell_format(ws.cell(2, column), but_signature, [(FMT.FONT_BOLD, True)])
ws.cell(3, column).value = "Nb"
ws.cell(4, column).value = "RCUE"
column += 1
ws.cell(2, column).value = "Année"
ws.cell(4, column).value = "Moy."
column += 1
if self.codeAnnee == "BUT2":
ws.cell(3, column).value = "DUT"
ws.cell(3, column).value = "Rés."
if self.codeAnnee == "BUT3":
ws.cell(3, column).value = "BUT"
ws.cell(3, column).value = "Rés."
# ws.merge_cells(start_column=start, end_column=column, start_row=1, end_row=1)
return column
class ParcoursDesc:
signature_header = FMT.compose(
[
(FMT.FILL_BGCOLOR, SCO_COLORS.LIGHT_YELLOW.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_LEFT_STYLE, SCO_BORDERTHICKNESS.BORDER_THIN.value),
(FMT.BORDER_RIGHT_STYLE, SCO_BORDERTHICKNESS.BORDER_THIN.value),
(FMT.BORDER_TOP_STYLE, SCO_BORDERTHICKNESS.BORDER_THIN.value),
(FMT.BORDER_BOTTOM_STYLE, SCO_BORDERTHICKNESS.BORDER_THIN.value),
(FMT.BORDER_LEFT_COLOR, SCO_COLORS.BLACK.value),
(FMT.BORDER_RIGHT_COLOR, SCO_COLORS.BLACK.value),
(FMT.BORDER_TOP_COLOR, SCO_COLORS.BLACK.value),
(FMT.BORDER_RIGHT_COLOR, SCO_COLORS.BLACK.value),
],
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 listeAnnees:
anneeDesc = AnneeDesc(codeAnnee)
for competence_id, competence in self.competences.items():
anneeDesc.addNiveau(competence.getNiveaux(codeAnnee))
self.annees[codeAnnee] = anneeDesc
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.getData())
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: Worksheet, description: tuple, row: int, column: int
) -> int:
title, content_list = description
style = FMT.style(self.signature_header)
ws.cell(row, column).value = title
style.apply(ws.cell(row, column))
merge_h = Merge_Engine(ws=ws, start_row=row, start_column=column)
merge_v = Merge_Engine(ws=ws, start_row=row, start_column=column)
if content_list is None:
merge_v.close(end_row=4)
column += 1
else:
first = column
for content in content_list:
column = self.handle_description(ws, content, row + 1, column)
merge_h.close(end_column=column - 1)
# left_medium = FMT.compose(
# self.signature_header,
# [
# (FMT.BORDER_LEFT_STYLE, SCO_BORDERTHICKNESS.BORDER_MEDIUM.value),
# (FMT.BORDER_LEFT_COLOR, SCO_COLORS.BLACK.value),
# ],
# )
# right_medium = FMT.compose(
# self.signature_header,
# [
# (FMT.BORDER_RIGHT_STYLE, SCO_BORDERTHICKNESS.BORDER_MEDIUM.value),
# (FMT.BORDER_RIGHT_COLOR, SCO_COLORS.BLACK.value),
# ],
# )
# top_medium = FMT.compose(
# self.signature_header,
# [
# (FMT.BORDER_TOP_STYLE, SCO_BORDERTHICKNESS.BORDER_MEDIUM.value),
# (FMT.BORDER_TOP_COLOR, SCO_COLORS.BLACK.value),
# ],
# )
# FMT.get_style(FMT.ALL, left_medium).apply(ws.cell(1, 1))
# FMT.get_style(FMT.ALL, top_medium).apply(ws.cell(1, 1))
# FMT.get_style(FMT.ALL, right_medium).apply(ws.cell(1, 1))
# FMT.get_style(FMT.ALL, left_medium).apply(ws.cell(2, 1))
# FMT.get_style(FMT.ALL, right_medium).apply(ws.cell(2, column - 1))
# FMT.get_style(FMT.ALL, right_medium).apply(ws.cell(3, column - 1))
# FMT.get_style(FMT.ALL, right_medium).apply(ws.cell(4, column - 1))
# merge_h.close(end_column=column)
return column
def generate_etudiant_header(self, ws: Worksheet) -> 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: Worksheet):
column: int = self.generate_etudiant_header(ws)
for codeAnnee in listeAnnees:
column = self.annees[codeAnnee].generate_header(ws, column)
def generate(self, workbook: ScoExcelBook):
header = _Header()
if self.fromScodoc:
sheet_name = self.fromScodoc.code
else:
sheet_name = "TC"
worksheet: ScoExcelSheet = workbook.create_sheet(sheet_name)
self.generate_header(worksheet.ws)