Améliore PV jury BUT: col. UEs, largeurs en excel, divers.

This commit is contained in:
Emmanuel Viennet 2022-07-01 22:29:19 +02:00
parent dbf562b701
commit d23649d725
5 changed files with 74 additions and 16 deletions

View File

@ -689,7 +689,23 @@ class DecisionsProposeesAnnee(DecisionsProposees):
dec_rcue.descr_validation() dec_rcue.descr_validation()
for dec_rcue in self.decisions_rcue_by_niveau.values() for dec_rcue in self.decisions_rcue_by_niveau.values()
] ]
return line_sep.join([v for v in validations if v]) return line_sep.join(v for v in validations if v)
def descr_ues_validation(self, line_sep: str = "\n") -> str:
"""Description textuelle des UE validées (enregistrés)
pour PV jurys
"""
validations = []
for res in (self.res_impair, self.res_pair):
if res:
dec_ues = [
self.decisions_ues[ue.id]
for ue in res.ues
if ue.type == UE_STANDARD and ue.id in self.decisions_ues
]
valids = [dec_ue.descr_validation() for dec_ue in dec_ues]
validations.append(", ".join(v for v in valids if v))
return line_sep.join(validations)
class DecisionsProposeesRCUE(DecisionsProposees): class DecisionsProposeesRCUE(DecisionsProposees):
@ -900,7 +916,7 @@ class DecisionsProposeesUE(DecisionsProposees):
def descr_validation(self) -> str: def descr_validation(self) -> str:
"""Description validation niveau enregistrée, pour PV jury. """Description validation niveau enregistrée, pour PV jury.
Si l'UE est validé, done son acronyme, sinon chaine vide. Si l'UE est validée, donne son acronyme, sinon chaine vide.
""" """
if self.code_valide in sco_codes.CODES_UE_VALIDES: if self.code_valide in sco_codes.CODES_UE_VALIDES:
return f"{self.ue.acronyme}" return f"{self.ue.acronyme}"

View File

@ -44,7 +44,7 @@ def pvjury_table_but(formsemestre_id: int, format="html") -> list[dict]:
""" """
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
assert formsemestre.formation.is_apc() assert formsemestre.formation.is_apc()
title = "Jury BUT annuel" title = "Procès-verbal de jury BUT annuel"
if format == "html": if format == "html":
line_sep = "<br/>" line_sep = "<br/>"
@ -55,6 +55,7 @@ def pvjury_table_but(formsemestre_id: int, format="html") -> list[dict]:
titles = { titles = {
"nom": "Nom", "nom": "Nom",
"cursus": "Cursus", "cursus": "Cursus",
"ues": "UE validées",
"niveaux": "Niveaux de compétences validés", "niveaux": "Niveaux de compétences validés",
"decision_but": f"Décision BUT{annee_but}", "decision_but": f"Décision BUT{annee_but}",
"diplome": "Résultat au diplôme", "diplome": "Résultat au diplôme",
@ -76,7 +77,15 @@ def pvjury_table_but(formsemestre_id: int, format="html") -> list[dict]:
row = { row = {
"nom": etud.etat_civil_pv(line_sep=line_sep), "nom": etud.etat_civil_pv(line_sep=line_sep),
"_nom_order": etud.sort_key, "_nom_order": etud.sort_key,
"_nom_target_attrs": f'class="etudinfo" id="{etud.id}"',
"_nom_td_attrs": f'id="{etud.id}" class="etudinfo"',
"_nom_target": url_for(
"scolar.ficheEtud",
scodoc_dept=g.scodoc_dept,
etudid=etud.id,
),
"cursus": _descr_cursus_but(etud), "cursus": _descr_cursus_but(etud),
"ues": deca.descr_ues_validation(line_sep=line_sep) if deca else "-",
"niveaux": deca.descr_niveaux_validation(line_sep=line_sep) "niveaux": deca.descr_niveaux_validation(line_sep=line_sep)
if deca if deca
else "-", else "-",
@ -93,21 +102,36 @@ def pvjury_table_but(formsemestre_id: int, format="html") -> list[dict]:
xls_style_base["alignment"] = Alignment(wrapText=True, vertical="top") xls_style_base["alignment"] = Alignment(wrapText=True, vertical="top")
tab = GenTable( tab = GenTable(
columns_ids=titles.keys(), base_url=f"{request.base_url}?formsemestre_id={formsemestre_id}",
rows=rows,
titles=titles,
origin=f"Généré par {scu.sco_version.SCONAME} le {scu.timedate_human_repr()}",
caption=title, caption=title,
columns_ids=titles.keys(),
html_caption=title, html_caption=title,
html_class="pvjury_table_but table_leftalign", html_class="pvjury_table_but table_leftalign",
# html_class_ignore_default=True, html_title=f"""<div style="margin-bottom: 8px;"><span style="font-size: 120%; font-weight: bold;">{title}</span>
<span style="padding-left: 20px;">
<a href="{url_for("notes.pvjury_table_but",
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, format="xlsx")}"
class="stdlink">version excel</a></span></div>
""",
html_with_td_classes=True, html_with_td_classes=True,
xls_style_base=xls_style_base, origin=f"Généré par {scu.sco_version.SCONAME} le {scu.timedate_human_repr()}",
base_url=f"{request.base_url}?formsemestre_id={formsemestre_id}",
page_title=title, page_title=title,
html_title=f"<h2>{title}</h2>",
pdf_title=title, pdf_title=title,
preferences=sco_preferences.SemPreferences(), preferences=sco_preferences.SemPreferences(),
rows=rows,
table_id="formation_table_recap", table_id="formation_table_recap",
titles=titles,
xls_columns_width={
"nom": 32,
"cursus": 12,
"ues": 32,
"niveaux": 32,
"decision_but": 14,
"diplome": 17,
"devenir": 8,
"observations": 12,
},
xls_style_base=xls_style_base,
) )
return tab.make_page(format=format, javascripts=[]) return tab.make_page(format=format, javascripts=["js/etud_info.js"], init_qtip=True)

View File

@ -43,7 +43,7 @@ from app.scodoc import sco_logos, html_sco_header
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
from app.scodoc.sco_config_actions import LogoInsert from app.scodoc.sco_config_actions import LogoInsert
from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_logos import find_logo from app.scodoc.sco_logos import find_logo
@ -199,9 +199,12 @@ class LogoForm(FlaskForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
kwargs["meta"] = {"csrf": False} kwargs["meta"] = {"csrf": False}
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.logo = find_logo( logo = find_logo(
logoname=self.logo_id.data, dept_id=dept_key_to_id(self.dept_key.data) logoname=self.logo_id.data, dept_id=dept_key_to_id(self.dept_key.data)
).select() )
if logo is None:
raise ScoValueError("logo introuvable")
self.logo = logo.select()
self.description = None self.description = None
self.titre = None self.titre = None
self.can_delete = True self.can_delete = True

View File

@ -45,7 +45,7 @@ import random
from collections import OrderedDict from collections import OrderedDict
from xml.etree import ElementTree from xml.etree import ElementTree
import json import json
from openpyxl.utils import get_column_letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
from reportlab.lib.colors import Color from reportlab.lib.colors import Color
@ -128,6 +128,7 @@ class GenTable(object):
xls_sheet_name="feuille", xls_sheet_name="feuille",
xls_before_table=[], # liste de cellules a placer avant la table xls_before_table=[], # liste de cellules a placer avant la table
xls_style_base=None, # style excel pour les cellules xls_style_base=None, # style excel pour les cellules
xls_columns_width=None, # { col_id : largeur en "pixels excel" }
pdf_title="", # au dessus du tableau en pdf pdf_title="", # au dessus du tableau en pdf
pdf_table_style=None, pdf_table_style=None,
pdf_col_widths=None, pdf_col_widths=None,
@ -153,6 +154,7 @@ class GenTable(object):
self.pdf_link = pdf_link self.pdf_link = pdf_link
self.xls_link = xls_link self.xls_link = xls_link
self.xls_style_base = xls_style_base self.xls_style_base = xls_style_base
self.xls_columns_width = xls_columns_width or {}
self.xml_link = xml_link self.xml_link = xml_link
# HTML parameters: # HTML parameters:
if not table_id: # random id if not table_id: # random id
@ -508,6 +510,16 @@ class GenTable(object):
if self.origin: if self.origin:
sheet.append_blank_row() # empty line sheet.append_blank_row() # empty line
sheet.append_single_cell_row(self.origin, style_base) sheet.append_single_cell_row(self.origin, style_base)
# Largeurs des colonnes
columns_ids = list(self.columns_ids)
for col_id, width in self.xls_columns_width.items():
try:
idx = columns_ids.index(col_id)
col = get_column_letter(idx + 1)
sheet.set_column_dimension_width(col, width)
except ValueError:
pass
if wb is None: if wb is None:
return sheet.generate() return sheet.generate()

View File

@ -191,6 +191,9 @@ class Logo:
) )
self.mm = "Not initialized: call the select or create function before access" self.mm = "Not initialized: call the select or create function before access"
def __repr__(self) -> str:
return f"Logo(logoname='{self.logoname}', filename='{self.filename}')"
def _set_format(self, fmt): def _set_format(self, fmt):
self.suffix = fmt self.suffix = fmt
self.filepath = self.basepath + "." + fmt self.filepath = self.basepath + "." + fmt