forked from ScoDoc/ScoDoc
Compare commits
2 Commits
55b42509de
...
5a96e42b6d
Author | SHA1 | Date | |
---|---|---|---|
5a96e42b6d | |||
db39c89257 |
@ -410,7 +410,7 @@ class ScoExcelSheet:
|
||||
]
|
||||
else:
|
||||
return [
|
||||
self.make_cell(value, style, comment)
|
||||
self.make_cell(value, styles, comment)
|
||||
for value, comment in zip(values, comments)
|
||||
]
|
||||
|
||||
@ -443,7 +443,7 @@ class ScoExcelSheet:
|
||||
for row in self.rows:
|
||||
self.ws.append(row)
|
||||
|
||||
def generate(self, column_widths=None):
|
||||
def generate(self, column_widths=None, merged=[]):
|
||||
"""génération d'un classeur mono-feuille"""
|
||||
# this method makes sense for standalone worksheet (else call workbook.generate())
|
||||
if self.wb is None: # embeded sheet
|
||||
@ -452,12 +452,16 @@ class ScoExcelSheet:
|
||||
# construction d'un flux
|
||||
# https://openpyxl.readthedocs.io/en/stable/tutorial.html#saving-as-a-stream
|
||||
self.prepare()
|
||||
for tuple in merged:
|
||||
top, left, bottom, right = tuple
|
||||
self.ws.merge_cells(
|
||||
start_row=top, end_row=bottom, start_column=left, end_column=right
|
||||
)
|
||||
|
||||
# largeur des colonnes
|
||||
if column_widths:
|
||||
for k, v in column_widths.items():
|
||||
self.set_column_dimension_width(k, v)
|
||||
|
||||
if self.auto_filter is not None:
|
||||
self.ws.auto_filter.ref = self.auto_filter
|
||||
with NamedTemporaryFile() as tmp:
|
||||
|
@ -77,7 +77,6 @@ def make_alignment(halign=None, valign=None, orientation=None, style=None):
|
||||
if orientation:
|
||||
alignment.rota = orientation
|
||||
if alignment and style:
|
||||
breakpoint()
|
||||
style["alignment"] = alignment
|
||||
return alignment
|
||||
|
||||
|
@ -474,8 +474,6 @@ imports = {}
|
||||
def compute_sems(etud, formation_id, formation_titre, descripteurs, Se):
|
||||
inscriptions = {}
|
||||
rsems = Se.sems[:] # copy
|
||||
# breakpoint()
|
||||
# rsems.reverse()
|
||||
if formation_id not in imports:
|
||||
imports[formation_id] = {}
|
||||
for (
|
||||
|
@ -39,7 +39,7 @@ from flask import request
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db
|
||||
from app.but import bulletin_but, cursus_but
|
||||
from app.but import bulletin_but, cursus_but, jury_but
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import (
|
||||
@ -58,10 +58,12 @@ from app.scodoc import sco_cursus
|
||||
from app.scodoc import sco_preferences
|
||||
import app.scodoc.sco_utils as scu
|
||||
import sco_version
|
||||
from app.scodoc.sco_excel import excel_make_style, COLORS
|
||||
from app.scodoc.sco_excel import excel_make_style, COLORS, ScoExcelSheet
|
||||
from app.scodoc.sco_excel_add import make_pattern
|
||||
from app.scodoc.sco_portal_apogee import get_etud_apogee, query_apogee_portal
|
||||
from app.scodoc.sco_prepajury_formats import Formatter
|
||||
|
||||
from app.tables.jury_recap import TableJury
|
||||
from app.tables.recap import TableRecap
|
||||
|
||||
COLORS = {
|
||||
"ETUDIANT": ["FFFF99"],
|
||||
@ -384,6 +386,13 @@ class Export:
|
||||
self.formsemestre_id: int = formsemestre_id
|
||||
self.formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
self.nt: NotesTableCompat = res_sem.load_formsemestre_results(self.formsemestre)
|
||||
self.recap = TableJury(
|
||||
self.nt,
|
||||
convert_values=False,
|
||||
include_evaluations=False,
|
||||
mode_jury=True,
|
||||
read_only=True,
|
||||
)
|
||||
etud_groups = sco_groups.formsemestre_get_etud_groupnames(formsemestre_id)
|
||||
main_partition_id = sco_groups.formsemestre_get_main_partition(formsemestre_id)
|
||||
self.etuds = self.nt.get_inscrits(order_by="moy")
|
||||
@ -413,6 +422,14 @@ class Export:
|
||||
self.data_sems[sem_id]["formsemestre"] = formsemestre
|
||||
nt = res_sem.load_formsemestre_results(formsemestre)
|
||||
self.data_sems[sem_id]["nt"] = nt
|
||||
# self.data_sems[sem_id]["recap"] = TableJury(
|
||||
# nt,
|
||||
# convert_values=False,
|
||||
# include_evaluations=False,
|
||||
# mode_jury=True,
|
||||
# read_only=True,
|
||||
# )
|
||||
current_app.logger.info(f"Table semestre {sem_id} chargée.")
|
||||
|
||||
def load_formsemestre(self, etud, session):
|
||||
for sem in session.sems:
|
||||
@ -444,22 +461,55 @@ class Export:
|
||||
# sexe=quote_xml_attr(etud.civilite_str), # compat
|
||||
bulletins_sem = bulletin_but.BulletinBUT(self.formsemestre)
|
||||
self.data_etud[etud.id]["bulletin_but"] = bulletins_sem.bulletin_etud(etud)
|
||||
self.data_etud[etud.id]["cursus"] = cursus_but.EtudCursusBUT(
|
||||
etud, self.formsemestre.formation
|
||||
)
|
||||
# self.data_etud[etud.id]["bulletin_sem"] = bulletins_sem.bulletin_etud(etud)
|
||||
breakpoint()
|
||||
# self.data_etud[etud.id]["cursus"] = (
|
||||
# self.recap.row_by_id[etud.id].cells["code_cursus"].raw_content
|
||||
# )
|
||||
self.data_etud[etud.id]["bulletin_sem"] = bulletins_sem.bulletin_etud(etud)
|
||||
# self.data_etud[etud.id]["nbabs"] = (
|
||||
# self.recap.row_by_id[etud.id].cells["nbabs"].raw_content
|
||||
# )
|
||||
# self.data_etud[etud.id]["nbabsjust"] = (
|
||||
# self.recap.row_by_id[etud.id].cells["nbabsjust"].raw_content
|
||||
# )
|
||||
# self.data_etud[etud.id]["parcours"] = self.recap.row_by_id[etud.id].cells[].raw_content
|
||||
|
||||
def load_data(self):
|
||||
self.load_parcours()
|
||||
breakpoint()
|
||||
for etud in self.etuds:
|
||||
self.data_etud[etud.id] = {}
|
||||
self.data_etud[etud.id]["etud"] = etud
|
||||
self.data_etud[etud.id]["sems"] = {}
|
||||
self.load_etu(etud)
|
||||
session = sco_cursus.get_situation_etud_cursus(etud, self.formsemestre_id)
|
||||
breakpoint()
|
||||
self.data_etud[etud.id]["cursus"] = session.parcours
|
||||
nbabsinj, nbabsjust, nbabs = self.formsemestre.get_abs_count(etud.id)
|
||||
self.data_etud[etud.id]["abs_tot"] = nbabs
|
||||
self.data_etud[etud.id]["abs_just"] = nbabsjust
|
||||
self.data_etud[etud.id]["abs_non_just"] = nbabsinj
|
||||
cursus = " ".join(
|
||||
[
|
||||
f"S{ins.formsemestre.semestre_id}"
|
||||
for ins in reversed(etud.inscriptions())
|
||||
if ins.formsemestre.formation.formation_code
|
||||
== self.formsemestre.formation.formation_code
|
||||
]
|
||||
)
|
||||
self.data_etud[etud.id]["code_cursus"] = cursus
|
||||
self.data_etud[etud.id]["deca"] = [
|
||||
jury_but.DecisionsProposeesAnnee(etud, ins.formsemestre)
|
||||
for ins in reversed(etud.inscriptions())
|
||||
]
|
||||
self.data_etud[etud.id]["history"] = {
|
||||
1: None,
|
||||
2: None,
|
||||
3: None,
|
||||
4: None,
|
||||
5: None,
|
||||
6: None,
|
||||
}
|
||||
for deca in self.data_etud[etud.id]["deca"]:
|
||||
self.data_etud[etud.id]["history"][deca.formsemestre.semestre_id] = deca
|
||||
self.load_formsemestre(etud, session)
|
||||
|
||||
def build_formator(self):
|
||||
@ -504,21 +554,15 @@ class Export:
|
||||
styles[row_no].append(excel_make_style(bgcolor=color[level2]))
|
||||
compte += nbelt
|
||||
# current_app.logger.info(f" {row_no}, {left}, {nbelt} ")
|
||||
# sheet.ws.merge_cells(
|
||||
# start_row=row_no + 1,
|
||||
# end_row=row_no + 1,
|
||||
# start_column=left + 1,
|
||||
# end_column=left + nbelt + 1,
|
||||
# )
|
||||
return compte
|
||||
else:
|
||||
return 1
|
||||
|
||||
def header_append(self, raws, items, row_no):
|
||||
def header_append(self, rows, items, row_no):
|
||||
if row_no <= 4:
|
||||
if items is None:
|
||||
raws[row_no].append("")
|
||||
self.header_append(raws, None, row_no + 1)
|
||||
rows[row_no].append("")
|
||||
self.header_append(rows, None, row_no + 1)
|
||||
return 1
|
||||
else:
|
||||
compte = 0
|
||||
@ -526,35 +570,164 @@ class Export:
|
||||
if item != "COLOR":
|
||||
detail = items[item]
|
||||
if item[0] != "+":
|
||||
raws[row_no].append(item)
|
||||
rows[row_no].append(item)
|
||||
else:
|
||||
raws[row_no].append(item[1:])
|
||||
nbelt = self.header_append(raws, detail, row_no + 1)
|
||||
rows[row_no].append(item[1:])
|
||||
nbelt = self.header_append(rows, detail, row_no + 1)
|
||||
for _ in range(1, nbelt):
|
||||
raws[row_no].append("")
|
||||
rows[row_no].append("")
|
||||
compte += nbelt
|
||||
return compte
|
||||
else:
|
||||
return 1
|
||||
|
||||
def write_header(self, sheet):
|
||||
raws = [[], [], [], [], []]
|
||||
rows = [[], [], [], [], []]
|
||||
styles = [[], [], [], [], []]
|
||||
col_no = 0
|
||||
raw_no = 0
|
||||
self.header_format(styles, CATEGORIES, 0, 0, ["FFFF00"], 0)
|
||||
self.header_append(raws, CATEGORIES, 0)
|
||||
self.header_append(rows, CATEGORIES, 0)
|
||||
for i in range(0, 4):
|
||||
sheet.append_row(
|
||||
sheet.make_row(
|
||||
raws[i],
|
||||
rows[i],
|
||||
styles[i],
|
||||
# style=excel_make_style(
|
||||
# font_name="Calibri", size=12, bold=False, bgcolor="D0FFFF"
|
||||
# ),
|
||||
)
|
||||
)
|
||||
sheet.ws.merge_cells(start_row=9, end_row=8, start_column=1, end_column=10)
|
||||
|
||||
def merge_header(self, frames, element, top, left):
|
||||
if element is None or top >= 8:
|
||||
frames.append((top, left, 8, left))
|
||||
return left + 1
|
||||
else:
|
||||
tuples = []
|
||||
current = left
|
||||
for item in element:
|
||||
detail = element[item]
|
||||
next = self.merge_header(
|
||||
frames,
|
||||
detail,
|
||||
top + 1,
|
||||
current,
|
||||
)
|
||||
current = next
|
||||
frames.append((top, left, top, next - 1))
|
||||
return next
|
||||
|
||||
def translate_ue(self, code):
|
||||
return {
|
||||
"ADM": "VAL",
|
||||
"AJ": "AJ",
|
||||
"ADJ": "ADJI",
|
||||
"PASD": "PASD",
|
||||
"CMP": "COMP",
|
||||
}.get(code, f"<{code}>")
|
||||
|
||||
def translate_rcue(self, code):
|
||||
return {
|
||||
"ADM": "VAL",
|
||||
"AJ": "AJ",
|
||||
"ADJ": "ADJI",
|
||||
"PASD": "PASD",
|
||||
"CMP": "COMP",
|
||||
}.get(code, f"<{code}>")
|
||||
|
||||
def translate_ann(self, code):
|
||||
return {
|
||||
"ADM": "VAL",
|
||||
"AJ": "AJ",
|
||||
"ADJ": "ADJI",
|
||||
"PASD": "PASD",
|
||||
"ADSUP": "VALR",
|
||||
}.get(code, f"<{code}>")
|
||||
|
||||
def detail_competence(self, etud, semestre, comp_no):
|
||||
history = self.data_etud[etud.id]["history"][semestre]
|
||||
if semestre % 2 == 0:
|
||||
result = ["", "", "", ""]
|
||||
else:
|
||||
result = ["", ""]
|
||||
if history is not None and comp_no < len(history.niveaux_competences):
|
||||
niveau = history.niveaux_competences[comp_no]
|
||||
rcue = history.rcue_by_niveau[niveau.id]
|
||||
if semestre % 2 == 1:
|
||||
ue1 = rcue.ue_1
|
||||
val_ue1 = (
|
||||
None if ue1 is None else history.decisions_ues[ue1.id].validation
|
||||
)
|
||||
dec_ue1 = "" if val_ue1 is None else self.translate_ue(val_ue1.code)
|
||||
result = [rcue.moy_ue_1, dec_ue1]
|
||||
else:
|
||||
ue2 = rcue.ue_2
|
||||
val_ue2 = (
|
||||
None if ue2 is None else history.decisions_ues[ue2.id].validation
|
||||
)
|
||||
dec_ue2 = "" if val_ue2 is None else self.translate_ue(val_ue2.code)
|
||||
val_niv = history.decisions_rcue_by_niveau[niveau.id].validation
|
||||
dec_niv = "" if val_niv is None else self.translate_rcue(val_niv.code)
|
||||
result = [rcue.moy_ue_2, dec_ue2, rcue.moy_rcue, dec_niv]
|
||||
return result
|
||||
|
||||
def detail_annuel(self, etud, but):
|
||||
result = ["", "", ""] if but == 1 else ["", "", "", ""]
|
||||
history = self.data_etud[etud.id]["history"].get(but * 2, None)
|
||||
if history is not None:
|
||||
nb_rcue_valides = history.nb_rcue_valides
|
||||
moy_gen = self.calcul_moy_ann(etud, but)
|
||||
if history.validation:
|
||||
dec_ann = self.translate_ann(history.validation.code)
|
||||
else:
|
||||
dec_ann = ""
|
||||
result = [nb_rcue_valides, moy_gen, dec_ann]
|
||||
if but != 1:
|
||||
if dec_ann in {"ADM"}:
|
||||
result.append("ADM")
|
||||
else:
|
||||
result.append("AJ")
|
||||
return result
|
||||
|
||||
def calcul_moy_ann(self, etud, but):
|
||||
pass
|
||||
history = self.data_etud[etud.id]["history"].get(but * 2, None)
|
||||
nb_rcues = 0
|
||||
tot_rcues = 0.0
|
||||
for rcue in history.rcue_by_niveau.values():
|
||||
if rcue.moy_rcue is not None:
|
||||
tot_rcues += rcue.moy_rcue
|
||||
nb_rcues += 1
|
||||
if nb_rcues > 0:
|
||||
return tot_rcues / nb_rcues
|
||||
else:
|
||||
return ""
|
||||
|
||||
def display(self, sheet: ScoExcelSheet):
|
||||
for etud in self.etuds:
|
||||
values = [
|
||||
etud.id,
|
||||
etud.code_nip,
|
||||
etud.civilite,
|
||||
etud.nom,
|
||||
etud.prenom,
|
||||
""
|
||||
if self.data_etud[etud.id]["deca"][-1].parcour is None
|
||||
else self.data_etud[etud.id]["deca"][-1].parcour.code,
|
||||
self.data_etud[etud.id]["code_cursus"],
|
||||
self.data_etud[etud.id]["abs_tot"],
|
||||
self.data_etud[etud.id]["abs_non_just"],
|
||||
]
|
||||
for but in range(1, 4):
|
||||
sImpair = 2 * but - 1
|
||||
sPair = 2 * but
|
||||
for comp in range(0, 6):
|
||||
values += self.detail_competence(etud, sImpair, comp)
|
||||
values += self.detail_competence(etud, sPair, comp)
|
||||
values += self.detail_annuel(etud, but)
|
||||
row = sheet.make_row(values)
|
||||
sheet.append_row(row)
|
||||
|
||||
|
||||
def feuille_preparation_lille(formsemestre_id):
|
||||
@ -582,6 +755,9 @@ def feuille_preparation_lille(formsemestre_id):
|
||||
# "Feuille préparation Jury %s" % scu.unescape_html(sem["titreannee"]), style_bold
|
||||
# )
|
||||
sheet.append_blank_row()
|
||||
sheet.append_blank_row()
|
||||
sheet.append_blank_row()
|
||||
sheet.append_blank_row()
|
||||
export.write_header(sheet)
|
||||
|
||||
# Ligne de titre
|
||||
@ -698,8 +874,8 @@ def feuille_preparation_lille(formsemestre_id):
|
||||
# )
|
||||
# UE : Correspondances acronyme et titre complet
|
||||
|
||||
sheet.append_blank_row()
|
||||
|
||||
export.display(sheet)
|
||||
# export.merge_header(sheet, CATEGORIES["ETUDIANT"]["Absences"]["Tot."], 6, 8, 5)
|
||||
# sheet.append_single_cell_row("Titre des UE")
|
||||
# if prev_moy:
|
||||
# for ue in ntp.get_ues_stat_dict(filter_sport=True):
|
||||
@ -717,7 +893,9 @@ def feuille_preparation_lille(formsemestre_id):
|
||||
# current_user,
|
||||
# )
|
||||
# )
|
||||
xls = sheet.generate()
|
||||
merged = []
|
||||
export.merge_header(merged, CATEGORIES, 4, 1)
|
||||
xls = sheet.generate(merged=merged)
|
||||
flash("Feuille préparation jury générée")
|
||||
return scu.send_file(
|
||||
xls,
|
||||
|
Loading…
Reference in New Issue
Block a user