diff --git a/app/forms/scolar/groups_form.py b/app/forms/scolar/groups_form.py
new file mode 100644
index 000000000..33a0d7521
--- /dev/null
+++ b/app/forms/scolar/groups_form.py
@@ -0,0 +1,56 @@
+"""
+Formulaire FlaskWTF pour les groupes
+"""
+
+from flask_wtf import FlaskForm
+from wtforms import StringField, SubmitField, validators
+
+
+class FeuilleAppelPreForm(FlaskForm):
+ """
+ Formulaire utiliser dans le téléchargement des feuilles d'émargement
+ """
+
+ def __init__(self, *args, **kwargs):
+ "Init form, adding a filed for our error messages"
+ super().__init__(*args, **kwargs)
+ self.ok = True
+ self.error_messages: list[str] = []
+
+ def set_error(self, err_msg, field=None):
+ "Set error message both in form and field"
+ self.ok = False
+ self.error_messages.append(err_msg)
+ if field:
+ field.errors.append(err_msg)
+
+ discipline = StringField(
+ "Discipline",
+ )
+
+ ens = StringField(
+ "Enseignant",
+ )
+
+ date = StringField(
+ "Date de la séance",
+ validators=[validators.Length(max=10)],
+ render_kw={
+ "class": "datepicker",
+ "size": 10,
+ "id": "date",
+ },
+ )
+
+ heure = StringField(
+ "Heure de début de la séance",
+ default="",
+ validators=[validators.Length(max=5)],
+ render_kw={
+ "class": "timepicker",
+ "size": 5,
+ "id": "heure",
+ },
+ )
+
+ submit = SubmitField("Télécharger la liste d'émargement")
diff --git a/app/scodoc/sco_excel.py b/app/scodoc/sco_excel.py
index dd15da8bd..f82a04f98 100644
--- a/app/scodoc/sco_excel.py
+++ b/app/scodoc/sco_excel.py
@@ -26,8 +26,8 @@
##############################################################################
-""" Excel file handling
-"""
+"""Excel file handling"""
+
import datetime
import io
import time
@@ -724,10 +724,7 @@ def excel_feuille_listeappel(
# ligne 3
cell_2 = ws.make_cell("Enseignant :", style2)
- cell_6 = ws.make_cell(f"Groupe {groupname}", style3)
- ws.append_row(
- [None, cell_2, ws.make_cell(edt_params.get("ens", ""), style3), cell_6]
- )
+ ws.append_row([None, cell_2, ws.make_cell(edt_params.get("ens", ""), style3)])
# ligne 4: Avertissement pour ne pas confondre avec listes notes + Date
cell_1 = ws.make_cell("Date :", style2)
@@ -745,10 +742,13 @@ def excel_feuille_listeappel(
]
)
+ # ligne 6: groupe
+ ws.append_row([None, ws.make_cell(f"Groupe {groupname}", style3)])
+
ws.append_blank_row()
ws.append_row([None, cell_2])
- # ligne 8: Entête (contruction dans une liste cells)
+ # ligne 9: Entête (contruction dans une liste cells)
cell_2 = ws.make_cell("Nom", style3)
cells = [None, cell_2]
letter_int += 1
diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py
index 86d7db499..40ff6d7cf 100644
--- a/app/scodoc/sco_groups_view.py
+++ b/app/scodoc/sco_groups_view.py
@@ -586,8 +586,8 @@ def groups_table(
etud_info["_nom_disp_order"] = etud_sort_key(etud_info)
etud_info["_prenom_target"] = fiche_url
- etud_info["_nom_disp_td_attrs"] = 'id="%s" class="etudinfo"' % (
- etud_info["etudid"]
+ etud_info["_nom_disp_td_attrs"] = (
+ 'id="%s" class="etudinfo"' % (etud_info["etudid"])
)
etud_info["bourse_str"] = "oui" if etud_info["boursier"] else "non"
if etud_info["etat"] == "D":
@@ -748,8 +748,6 @@ def groups_table(
tab.html(),
f"""
- - Feuille d'appel Excel
-
- Table Excel
- Fichier CSV pour Moodle (groupe sélectionné)
@@ -925,14 +923,21 @@ def tab_absences_html(groups_infos, etat=None):
"""
]
+ url_feuille_appel: str = url_for(
+ "scolar.formulaire_feuille_appel",
+ scodoc_dept=g.scodoc_dept,
+ formsemestre_id=groups_infos.formsemestre_id,
+ group_ids=group_ids,
+ )
+
H.extend(
[
"
Assiduité
",
*liens_abs,
"Feuilles
",
'',
- """- Feuille d'émargement %s (Excel)
"""
- % (groups_infos.base_url, groups_infos.groups_titles),
+ """- Feuille d'émargement %s (Excel)
"""
+ % (url_feuille_appel, groups_infos.groups_titles),
"""- Trombinoscope en PDF
"""
% groups_infos.groups_query_args,
"""- Trombinoscope en PDF (format "IUT de Tours", beta)
"""
diff --git a/app/templates/scolar/formulaire_feuille_appel.j2 b/app/templates/scolar/formulaire_feuille_appel.j2
new file mode 100644
index 000000000..40535103c
--- /dev/null
+++ b/app/templates/scolar/formulaire_feuille_appel.j2
@@ -0,0 +1,55 @@
+{% extends "sco_page.j2" %}
+{% import 'wtf.j2' as wtf %}
+
+
+{% block styles %}
+{{super()}}
+
+
+
+
+
+{% endblock %}
+
+{% block app_content %}
+
+Préparation de la feuille d'émargement : {{group_name}}
+
+
+
+{% endblock app_content %}
+{% block scripts %}
+{{super()}}
+{% include "sco_timepicker.j2" %}
+
+
+
+{% endblock scripts %}
\ No newline at end of file
diff --git a/app/views/__init__.py b/app/views/__init__.py
index 152a725c2..65d2b9e11 100644
--- a/app/views/__init__.py
+++ b/app/views/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*
-"""ScoDoc Flask views
-"""
+"""ScoDoc Flask views"""
+
import datetime
from functools import cached_property
@@ -148,6 +148,7 @@ from app.views import (
absences,
assiduites,
but_formation,
+ groups,
jury_validations,
notes_formsemestre,
notes,
diff --git a/app/views/groups.py b/app/views/groups.py
new file mode 100644
index 000000000..ae6bca0e7
--- /dev/null
+++ b/app/views/groups.py
@@ -0,0 +1,93 @@
+"""
+Nouvelles vues pour les groupes
+(aux normes ScoDoc9)
+"""
+
+from flask import render_template, request
+
+
+from app.decorators import (
+ scodoc,
+ permission_required,
+)
+from app.forms.scolar import groups_form
+from app.models import (
+ FormSemestre,
+)
+from app.scodoc.sco_excel import excel_feuille_listeappel
+from app.scodoc.sco_groups_view import DisplayedGroupsInfos, menu_groups_choice
+from app.scodoc.sco_permissions import Permission
+from app.scodoc import sco_utils as scu
+from app.views import ScoData
+from app.views import scolar_bp as bp
+
+
+@bp.route("/formulaire_feuille_appel", methods=["GET", "POST"])
+@scodoc
+@permission_required(Permission.ScoView)
+def formulaire_feuille_appel():
+ """Formulaire de feuille d'appel
+
+ GET : Affiche le formulaire de remplissage de la feuille d'appel
+ POST : Retourne la feuille d'appelle correspondante
+
+ QUERY
+ -----
+ formsemestre_id:
+ group_ids:>
+
+ """
+ formsemestre_id: int = request.args.get("formsemestre_id")
+ try:
+ formsemestre_id = int(formsemestre_id)
+ except ValueError:
+ formsemestre_id = None
+
+ formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id)
+
+ group_ids: list[int] = request.args.get("group_ids", "").split(",")
+
+ form: groups_form.FeuilleAppelPreForm = groups_form.FeuilleAppelPreForm(
+ request.form
+ )
+
+ groups_infos = DisplayedGroupsInfos(
+ group_ids,
+ formsemestre_id=formsemestre_id,
+ select_all_when_unspecified=True,
+ )
+
+ if request.method == "POST":
+ edt_params: dict = {
+ "date": form.date.data or "",
+ "heure": form.heure.data or "",
+ "discipline": form.discipline.data or "",
+ "ens": form.ens.data or "",
+ }
+
+ form_group_ids: list[str] = request.form.getlist("group_ids")
+ if form_group_ids:
+ groups_infos = DisplayedGroupsInfos(
+ form_group_ids,
+ formsemestre_id=formsemestre_id,
+ select_all_when_unspecified=True,
+ )
+
+ xls = excel_feuille_listeappel(
+ groups_infos.formsemestre,
+ groups_infos.groups_titles,
+ groups_infos.members,
+ partitions=groups_infos.partitions,
+ edt_params=edt_params,
+ )
+
+ filename = f"liste_{groups_infos.groups_filename}"
+ return scu.send_file(xls, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)
+
+ return render_template(
+ "scolar/formulaire_feuille_appel.j2",
+ sco_data=ScoData(formsemestre=formsemestre),
+ form=form,
+ group_name=groups_infos.groups_titles,
+ grp=menu_groups_choice(groups_infos),
+ )