From db717826c8d674e0754626b313b69450fc0869f6 Mon Sep 17 00:00:00 2001
From: Jean-Marie Place <jean-marie.place@univ-lille.fr>
Date: Fri, 13 Aug 2021 12:18:22 +0200
Subject: [PATCH] =?UTF-8?q?adaptation=20export=20feuille=20de=20pr=C3=A9pa?=
 =?UTF-8?q?ration=20jury?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/scodoc/sco_excel.py     |  29 ++++--
 app/scodoc/sco_prepajury.py | 185 ++++++++++++++++++------------------
 2 files changed, 115 insertions(+), 99 deletions(-)

diff --git a/app/scodoc/sco_excel.py b/app/scodoc/sco_excel.py
index 19439b06..06e2ad70 100644
--- a/app/scodoc/sco_excel.py
+++ b/app/scodoc/sco_excel.py
@@ -136,8 +136,13 @@ class ScoExcelBook:
         self.sheets = []  # list of sheets
 
     def create_sheet(self, sheet_name="feuille", default_style=None):
+        """Crée une nouvelle feuille dans ce classeur
+        sheet_name -- le nom de la feuille
+        default_style -- le style par défaut
+        """
         sheet = ScoExcelSheet(sheet_name, default_style)
         self.sheets.append(sheet)
+        return sheet
 
     def generate(self):
         """génération d'un stream binaire représentant la totalité du classeur.
@@ -161,6 +166,8 @@ def excel_make_style(
     halign=None,
     valign=None,
     format_number=None,
+    font_name="Arial",
+    size=10,
 ):
     """Contruit un style.
     Les couleurs peuvent être spécfiées soit par une valeur de COLORS,
@@ -169,30 +176,32 @@ def excel_make_style(
     bgcolor -- la couleur de fond
     halign -- alignement horizontal ("left", "right", "center")
     valign -- alignement vertical ("top", "bottom", "center")
-    format_number -- formattage du contenu ("general", "@", ...)
+    format_number -- formattage du contenu ("General", "@", ...)
+    font_name -- police
+    size -- taille de police
     """
     style = {}
-    font = Font(name="Arial", bold=bold, italic=italic, color=color.value)
+    font = Font(name=font_name, bold=bold, italic=italic, color=color.value, size=size)
     style["font"] = font
     if bgcolor:
-        style["fill"] = PatternFill(fill_type="solid", bgColor=bgcolor.value)
+        style["fill"] = PatternFill(fill_type="solid", fgColor=bgcolor.value)
     if halign or valign:
         al = Alignment()
         if halign:
-            al.horz = {
+            al.horizontal = {
                 "left": "left",
                 "right": "right",
                 "center": "center",
             }[halign]
         if valign:
-            al.vert = {
+            al.vertical = {
                 "top": "top",
                 "bottom": "bottom",
                 "center": "center",
             }[valign]
         style["alignment"] = al
     if format_number is None:
-        style["format_number"] = "general"
+        style["format_number"] = "General"
     else:
         style["format_number"] = format_number
     return style
@@ -244,9 +253,11 @@ class ScoExcelSheet:
     def make_cell(self, value: any = None, style=None):
         """Construit une cellule.
         value -- contenu de la cellule (texte ou numérique)
-        style -- style par défaut de la feuille si non spécifié
+        style -- style par défaut (dictionnaire cf. excel_make_style) de la feuille si non spécifié
         """
         cell = WriteOnlyCell(self.ws, value or "")
+        # if style is not None and "fill" in style:
+        #     toto()
         if style is None:
             style = self.default_style
         if "font" in style:
@@ -261,7 +272,7 @@ class ScoExcelSheet:
             cell.alignment = style["alignment"]
         return cell
 
-    def make_row(self, values: list, style):
+    def make_row(self, values: list, style=None):
         return [self.make_cell(value, style) for value in values]
 
     def append_single_cell_row(self, value: any, style=None):
@@ -437,7 +448,7 @@ def excel_feuille_saisie(e, titreannee, description, lines):
     }
     style_notes = {
         "font": font_bold,
-        "number_format": "general",
+        "number_format": "General",
         "fill": fill_light_yellow,
         "border": border_top,
     }
diff --git a/app/scodoc/sco_prepajury.py b/app/scodoc/sco_prepajury.py
index 3d2398da..46a22005 100644
--- a/app/scodoc/sco_prepajury.py
+++ b/app/scodoc/sco_prepajury.py
@@ -40,6 +40,7 @@ from app.scodoc import sco_codes_parcours
 from app.scodoc import VERSION
 from app.scodoc import sco_etud
 from app.scodoc import sco_preferences
+from app.scodoc.sco_excel import ScoExcelSheet
 
 
 def feuille_preparation_jury(context, formsemestre_id, REQUEST):
@@ -59,7 +60,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
     prev_ue_acro = {}  # ue_code_s : acronyme (à afficher)
     prev_moy = {}  # moyennes gen sem prec
     moy_ue = scu.DictDefault(defaultvalue={})  # ue_acro : moyennes { etudid : moy ue }
-    ue_acro = {}  #  ue_code_s : acronyme (à afficher)
+    ue_acro = {}  # ue_code_s : acronyme (à afficher)
     moy = {}  # moyennes gen
     moy_inter = {}  # moyenne gen. sur les 2 derniers semestres
     code = {}  # decision existantes s'il y en a
@@ -129,9 +130,9 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
                     main_partition_id, ""
                 )
         # absences:
-        nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
-        nbabs[etudid] = nbabs
-        nbabsjust[etudid] = nbabs - nbabsjust
+        e_nbabs, e_nbabsjust = sco_abs.get_abs_count(etudid, sem)
+        nbabs[etudid] = e_nbabs
+        nbabsjust[etudid] = e_nbabs - e_nbabsjust
 
     # Codes des UE "semestre précédent":
     ue_prev_codes = list(prev_moy_ue.keys())
@@ -153,10 +154,26 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
         if prev_moy:  # si qq chose dans precedent
             sp = "S%s" % (sid - 1)
 
-    L = sco_excel.ScoExcelSheet(sheet_name="Prepa Jury %s" % sn)
-    L.append(["Feuille préparation Jury %s" % scu.unescape_html(sem["titreannee"])])
-    L.append([])  # empty line
+    ws = sco_excel.ScoExcelSheet(sheet_name="Prepa Jury %s" % sn)
+    # génération des styles
+    style_bold = sco_excel.excel_make_style(size=10, bold=True)
+    style_center = sco_excel.excel_make_style(halign="center")
+    style_boldcenter = sco_excel.excel_make_style(bold=True, halign="center")
+    style_moy = sco_excel.excel_make_style(
+        bold=True, halign="center", bgcolor=sco_excel.COLORS.LIGHT_YELLOW
+    )
+    style_note = sco_excel.excel_make_style(halign="right", format_number="General")
+    style_note_bold = sco_excel.excel_make_style(
+        halign="right", bold=True, format_number="General"
+    )
 
+    # Première ligne
+    ws.append_single_cell_row(
+        "Feuille préparation Jury %s" % scu.unescape_html(sem["titreannee"]), style_bold
+    )
+    ws.append_blank_row()
+
+    # Ligne de titre
     titles = ["Rang"]
     if sco_preferences.get_preference("prepa_jury_nip"):
         titles.append("NIP")
@@ -174,7 +191,6 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
         "Parcours",
         "Groupe",
     ]
-
     if prev_moy:  # si qq chose dans precedent
         titles += [prev_ue_acro[x][1] for x in ue_prev_codes] + [
             "Moy %s" % sp,
@@ -189,15 +205,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
     if autorisations:
         titles.append("Autorisations")
     #    titles.append('Assidu')
-    L.append(titles)
-    style_bold = sco_excel.excel_make_style(bold=True)
-    style_center = sco_excel.excel_make_style(halign="center")
-    style_boldcenter = sco_excel.excel_make_style(bold=True, halign="center")
-    style_moy = sco_excel.excel_make_style(
-        bold=True, halign="center", bgcolor="lightyellow"
-    )
-    style_note = sco_excel.excel_make_style(halign="right")
-    style_note_bold = sco_excel.excel_make_style(halign="right", bold=True)
+    ws.append_row(ws.make_row(titles, style_boldcenter))
     if prev_moy:
         tit_prev_moy = "Moy " + sp
         col_prev_moy = titles.index(tit_prev_moy)
@@ -205,9 +213,6 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
     col_moy = titles.index(tit_moy)
     col_abs = titles.index("Abs")
 
-    L.set_style(style_bold, li=0)
-    L.set_style(style_boldcenter, li=2)
-
     def fmt(x):
         "reduit les notes a deux chiffres"
         x = scu.fmt_note(x, keep_numeric=False)
@@ -218,101 +223,101 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
 
     i = 1  # numero etudiant
     for etudid in etudids:
+        cells = []
         etud = nt.identdict[etudid]
-        l = [str(i)]
+        cells.append(ws.make_cell(str(i)))
         if sco_preferences.get_preference("prepa_jury_nip"):
-            l.append(etud["code_nip"])
+            cells.append(ws.make_cell(etud["code_nip"]))
         if sco_preferences.get_preference("prepa_jury_ine"):
-            l.append(etud["code_ine"])
-        l += [
-            etudid,
-            etud["civilite_str"],
-            sco_etud.format_nom(etud["nom"]),
-            sco_etud.format_prenom(etud["prenom"]),
-            etud["date_naissance"],
-            etud["bac"],
-            etud["specialite"],
-            etud["classement"],
-            parcours[etudid],
-            groupestd[etudid],
-        ]
-        co = len(l)
+            cells.append(ws.make_cell(["code_ine"]))
+        cells += ws.make_row(
+            [
+                etudid,
+                etud["civilite_str"],
+                sco_etud.format_nom(etud["nom"]),
+                sco_etud.format_prenom(etud["prenom"]),
+                etud["date_naissance"],
+                etud["bac"],
+                etud["specialite"],
+                etud["classement"],
+                parcours[etudid],
+                groupestd[etudid],
+            ]
+        )
+        co = len(cells)
         if prev_moy:
             for ue_acro in ue_prev_codes:
-                l.append(fmt(prev_moy_ue.get(ue_acro, {}).get(etudid, "")))
-                L.set_style(style_note, li=i + 2, co=co)
+                cells.append(
+                    ws.make_cell(
+                        fmt(prev_moy_ue.get(ue_acro, {}).get(etudid, "")), style_note
+                    )
+                )
                 co += 1
-            l.append(fmt(prev_moy.get(etudid, "")))
-            l.append(prev_code.get(etudid, ""))
-            #            L.set_style(style_bold, li=i+2, co=col_prev_moy+1) # moy gen prev
-            #            L.set_style(style_moy,  li=i+2, co=col_prev_moy+2) # decision prev
-            L.set_style(style_bold, li=i + 2, co=col_prev_moy)  # moy gen prev
-            L.set_style(style_moy, li=i + 2, co=col_prev_moy + 1)  # decision prev
+            cells.append(
+                ws.make_cell(fmt(prev_moy.get(etudid, "")), style_bold)
+            )  # moy gen prev
+            cells.append(
+                ws.make_cell(fmt(prev_code.get(etudid, "")), style_moy)
+            )  # decision prev
             co += 2
 
         for ue_acro in ue_codes:
-            l.append(fmt(moy_ue.get(ue_acro, {}).get(etudid, "")))
-            L.set_style(style_note, li=i + 2, co=co)
+            cells.append(
+                ws.make_cell(fmt(moy_ue.get(ue_acro, {}).get(etudid, "")), style_note)
+            )
             co += 1
-        l.append(fmt(moy.get(etudid, "")))
-        #        L.set_style(style_note_bold, li=i+2, co=col_moy+1) # moy gen
-        L.set_style(style_note_bold, li=i + 2, co=col_moy)  # moy gen
+        cells.append(ws.make_cell(fmt(moy.get(etudid, "")), style_note_bold))  # moy gen
         co += 1
         if moy_inter:
-            l.append(fmt(moy_inter.get(etudid, "")))
-            L.set_style(style_note, li=i + 2, co=co)
-        l.append(fmt(str(nbabs.get(etudid, ""))))
-        l.append(fmt(str(nbabsjust.get(etudid, ""))))
+            cells.append(ws.make_cell(fmt(moy_inter.get(etudid, "")), style_note))
+        cells.append(ws.make_cell(str(nbabs.get(etudid, "")), style_center))
+        cells.append(ws.make_cell(str(nbabsjust.get(etudid, "")), style_center))
         if code:
-            l.append(code.get(etudid, ""))
-        if autorisations:
-            l.append(autorisations.get(etudid, ""))
+            cells.append(ws.make_cell(code.get(etudid, ""), style_moy))
+        cells.append(ws.make_cell(autorisations.get(etudid, ""), style_moy))
         #        l.append(assidu.get(etudid, ''))
-        L.append(l)
+        ws.append_row(cells)
         i += 1
-        L.set_style(style_center, li=i + 1, co=col_abs)  # absences
-        L.set_style(style_center, li=i + 1, co=col_abs + 1)  # absences injustifiées
-        L.set_style(style_moy, li=i + 1, co=col_abs + 2)  # décision semestre
-        L.set_style(style_center, li=i + 1, co=col_abs + 3)  # Autorisations
     #
-    L.append([""])
+    ws.append_blank_row()
     # Explications des codes
     codes = list(sco_codes_parcours.CODES_EXPL.keys())
     codes.sort()
-    L.append(["Explication des codes"])
+    ws.append_single_cell_row("Explication des codes")
     for code in codes:
-        L.append(["", "", "", code, sco_codes_parcours.CODES_EXPL[code]])
-    L.append(
-        [
-            "",
-            "",
-            "",
-            "ADM+",
-            "indique que le semestre a déjà servi à en compenser un autre",
-        ]
+        ws.append_row(
+            ws.make_row(["", "", "", code, sco_codes_parcours.CODES_EXPL[code]])
+        )
+    ws.append_row(
+        ws.make_row(
+            [
+                "",
+                "",
+                "",
+                "ADM+",
+                "indique que le semestre a déjà servi à en compenser un autre",
+            ]
+        )
     )
     # UE : Correspondances acronyme et titre complet
-    L.append([""])
-    L.append(["Titre des UE"])
+    ws.append_blank_row()
+    ws.append_single_cell_row("Titre des UE")
     if prev_moy:
         for ue in ntp.get_ues(filter_sport=True):
-            L.append(["", "", "", ue["acronyme"], ue["titre"]])
+            ws.append_row(ws.make_row(["", "", "", ue["acronyme"], ue["titre"]]))
     for ue in nt.get_ues(filter_sport=True):
-        L.append(["", "", "", ue["acronyme"], ue["titre"]])
+        ws.append_row(ws.make_row(["", "", "", ue["acronyme"], ue["titre"]]))
     #
-    L.append([""])
-    L.append(
-        [
-            "Préparé par %s le %s sur %s pour %s"
-            % (
-                VERSION.SCONAME,
-                time.strftime("%d/%m/%Y"),
-                REQUEST.BASE0,
-                REQUEST.AUTHENTICATED_USER,
-            )
-        ]
+    ws.append_blank_row()
+    ws.append_single_cell_row(
+        "Préparé par %s le %s sur %s pour %s"
+        % (
+            VERSION.SCONAME,
+            time.strftime("%d/%m/%Y"),
+            REQUEST.BASE0,
+            REQUEST.AUTHENTICATED_USER,
+        )
     )
+    xls = ws.generate_standalone()
 
-    xls = L.gen_workbook()
-
-    return sco_excel.send_excel_file(REQUEST, xls, f"PrepaJury{sn}{scu.XLSX_SUFFIX}")
+    return sco_excel.send_excel_file(REQUEST, xls, "PrepaJury%s.xlsx" % sn)