forked from ScoDoc/ScoDoc
Import notes toutes évaluations d'un module
This commit is contained in:
parent
10623e568b
commit
4de2d63861
@ -830,7 +830,7 @@ def check_etud_duplicate_code(args, code_name, edit=True):
|
||||
dest_endpoint = "notes.index_html"
|
||||
parameters = {}
|
||||
|
||||
err_page = f"""<h3><h3>Code étudiant ({code_name}) dupliqué !</h3>
|
||||
err_page = f"""<h3>Code étudiant ({code_name}) dupliqué !</h3>
|
||||
<p class="help">Le {code_name} {args[code_name]} est déjà utilisé: un seul étudiant peut avoir
|
||||
ce code. Vérifier votre valeur ou supprimer l'autre étudiant avec cette valeur.
|
||||
</p>
|
||||
@ -845,7 +845,7 @@ def check_etud_duplicate_code(args, code_name, edit=True):
|
||||
|
||||
log(f"*** error: code {code_name} duplique: {args[code_name]}")
|
||||
|
||||
raise ScoGenError(err_page)
|
||||
raise ScoGenError(err_page, safe=True)
|
||||
|
||||
|
||||
def make_etud_args(
|
||||
|
@ -508,24 +508,26 @@ def excel_simple_table(
|
||||
return ws.generate()
|
||||
|
||||
|
||||
def excel_bytes_to_list(bytes_content):
|
||||
def excel_bytes_to_list(bytes_content) -> tuple[list, list[list]]:
|
||||
"Lecture d'un flux xlsx"
|
||||
try:
|
||||
filelike = io.BytesIO(bytes_content)
|
||||
return _excel_to_list(filelike)
|
||||
except Exception as exc:
|
||||
raise ScoValueError(
|
||||
"""Le fichier xlsx attendu n'est pas lisible !
|
||||
"""Le fichier xlsx attendu n'est pas lisible ! (1)
|
||||
Peut-être avez-vous fourni un fichier au mauvais format (txt, xls, ..)
|
||||
"""
|
||||
) from exc
|
||||
return _excel_to_list(filelike)
|
||||
|
||||
|
||||
def excel_file_to_list(filename):
|
||||
def excel_file_to_list(filelike) -> tuple[list, list[list]]:
|
||||
"Lecture d'un flux xlsx"
|
||||
try:
|
||||
return _excel_to_list(filename)
|
||||
return _excel_to_list(filelike)
|
||||
except Exception as exc:
|
||||
raise ScoValueError(
|
||||
"""Le fichier xlsx attendu n'est pas lisible !
|
||||
"""Le fichier xlsx attendu n'est pas lisible ! (2)
|
||||
Peut-être avez-vous fourni un fichier au mauvais format (txt, xls, ...)
|
||||
"""
|
||||
) from exc
|
||||
@ -611,7 +613,7 @@ def excel_workbook_to_list(filelike):
|
||||
workbook = _open_workbook(filelike)
|
||||
except Exception as exc:
|
||||
raise ScoValueError(
|
||||
"""Le fichier xlsx attendu n'est pas lisible !
|
||||
"""Le fichier xlsx attendu n'est pas lisible ! (3)
|
||||
Peut-être avez-vous fourni un fichier au mauvais format (txt, xls, ...)
|
||||
"""
|
||||
) from exc
|
||||
|
@ -200,11 +200,11 @@ class ScoNoReferentielCompetences(ScoValueError):
|
||||
super().__init__(msg)
|
||||
|
||||
|
||||
class ScoGenError(ScoException):
|
||||
class ScoGenError(ScoValueError):
|
||||
"exception avec affichage d'une page explicative ad-hoc"
|
||||
|
||||
def __init__(self, msg=""):
|
||||
super().__init__(msg)
|
||||
def __init__(self, msg="", safe=False):
|
||||
super().__init__(msg, safe=safe)
|
||||
|
||||
|
||||
class AccessDenied(ScoGenError):
|
||||
|
@ -478,8 +478,17 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
<a class="stdlink" style="margin-left:2em;" href="{
|
||||
url_for("notes.moduleimpl_evaluation_renumber",
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
|
||||
}">Trier par date</a>
|
||||
}" title="Ordonner les évaluations par date">Trier par date</a>
|
||||
"""
|
||||
bot_table_links = (
|
||||
top_table_links
|
||||
+ f"""
|
||||
<a class="stdlink" style="margin-left:2em;" href="{
|
||||
url_for("notes.moduleimpl_import_notes",
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
|
||||
}" title="Charger toutles les notes via tableur">Importer les notes</a>
|
||||
"""
|
||||
)
|
||||
if nb_evaluations > 0:
|
||||
H.append(
|
||||
'<div class="moduleimpl_evaluations_top_links">'
|
||||
@ -514,7 +523,9 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
if sem_locked:
|
||||
H.append(f"""{scu.icontag("lock32_img")} semestre verrouillé""")
|
||||
elif can_edit_evals:
|
||||
H.append(top_table_links)
|
||||
H.append(
|
||||
f"""<div class="moduleimpl_evaluations_table_bot">{bot_table_links}</div>"""
|
||||
)
|
||||
|
||||
H.append(
|
||||
f"""</td></tr>
|
||||
|
@ -34,7 +34,7 @@ saisie_notes_tableur (formulaire)
|
||||
## Notes d'un semestre
|
||||
|
||||
formsemestre_import_notes (formulaire, import_notes.j2)
|
||||
-> feuille_import_notes (génération de l'excel)
|
||||
-> formsemestre_feuille_import_notes (génération de l'excel)
|
||||
-> formsemestre_import_notes
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ from openpyxl.styles.numbers import FORMAT_GENERAL
|
||||
from flask import g, render_template, request, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
from app.models import Evaluation, FormSemestre, Identite, ScolarNews
|
||||
from app.models import Evaluation, FormSemestre, Identite, ModuleImpl, ScolarNews
|
||||
from app.scodoc.sco_excel import COLORS, ScoExcelSheet
|
||||
from app.scodoc import (
|
||||
html_sco_header,
|
||||
@ -61,7 +61,7 @@ from app.scodoc import (
|
||||
sco_saisie_notes,
|
||||
sco_users,
|
||||
)
|
||||
from app.scodoc.sco_exceptions import AccessDenied, InvalidNoteValue
|
||||
from app.scodoc.sco_exceptions import AccessDenied, InvalidNoteValue, ScoValueError
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
from app.views import ScoData
|
||||
@ -435,12 +435,27 @@ def feuille_saisie_notes(
|
||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||
|
||||
|
||||
def excel_feuille_import(formsemestre: FormSemestre) -> AnyStr:
|
||||
"""Génère feuille pour import toutes notes dans ce semestre,
|
||||
def excel_feuille_import(
|
||||
formsemestre: FormSemestre | None = None, modimpl: ModuleImpl | None = None
|
||||
) -> AnyStr:
|
||||
"""Génère feuille pour import toutes notes dans ce semestre ou ce module,
|
||||
avec une colonne par évaluation.
|
||||
Return excel data
|
||||
"""
|
||||
evaluations = formsemestre.get_evaluations()
|
||||
if not (formsemestre or modimpl):
|
||||
raise ScoValueError("excel_feuille_import: missing argument")
|
||||
evaluations = (
|
||||
formsemestre.get_evaluations() if formsemestre else modimpl.evaluations.all()
|
||||
)
|
||||
if formsemestre is None:
|
||||
if not evaluations:
|
||||
raise ScoValueError(
|
||||
"pas d'évaluations dans ce module",
|
||||
dest_url=url_for(
|
||||
"notes.moduleimpl_status, scodoc_dept=g.scodoc_dept, moduleimpl_id=modipl.id"
|
||||
),
|
||||
)
|
||||
formsemestre = evaluations[0].moduleimpl.formsemestre
|
||||
etudiants = formsemestre.get_inscrits(include_demdef=True, order=True)
|
||||
rows = [{"etud": etud} for etud in etudiants]
|
||||
# Liste les étudiants et leur note à chaque évaluation
|
||||
@ -543,14 +558,16 @@ def generate_excel_import_notes(
|
||||
|
||||
|
||||
def do_evaluations_upload_xls(
|
||||
notefile,
|
||||
notefile="",
|
||||
comment: str = "",
|
||||
evaluation: Evaluation | None = None,
|
||||
formsemestre: FormSemestre | None = None,
|
||||
modimpl: ModuleImpl | None = None,
|
||||
) -> tuple[bool, str]:
|
||||
"""
|
||||
Soumission d'un fichier XLS (evaluation_id, notefile)
|
||||
soit dans le formsemestre (import multi-eval)
|
||||
soit dans toules les évaluations du modimpl
|
||||
soit dans une seule évaluation
|
||||
return:
|
||||
ok: bool
|
||||
@ -563,7 +580,11 @@ def do_evaluations_upload_xls(
|
||||
|
||||
# Lecture des évaluations ids
|
||||
row_title_idx, evaluations, evaluations_col_idx = _get_sheet_evaluations(
|
||||
rows, evaluation=evaluation, formsemestre=formsemestre, diag=diag
|
||||
rows,
|
||||
evaluation=evaluation,
|
||||
formsemestre=formsemestre,
|
||||
modimpl=modimpl,
|
||||
diag=diag,
|
||||
)
|
||||
|
||||
# Vérification des permissions (admin, resp. formation, responsable_id, ens)
|
||||
@ -591,12 +612,26 @@ def do_evaluations_upload_xls(
|
||||
modules_str = ", ".join(
|
||||
[evaluation.moduleimpl.module.code for evaluation in evaluations]
|
||||
)
|
||||
status_url = url_for(
|
||||
status_url = (
|
||||
url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre.id,
|
||||
)
|
||||
obj_id = formsemestre.id
|
||||
if formsemestre
|
||||
else (
|
||||
url_for(
|
||||
"notes.moduleimpl_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
moduleimpl_id=modimpl.id,
|
||||
)
|
||||
if modimpl
|
||||
else ""
|
||||
)
|
||||
)
|
||||
obj_id = (
|
||||
formsemestre.id if formsemestre else (modimpl.id if modimpl else None)
|
||||
)
|
||||
else:
|
||||
modules_str = (
|
||||
evaluation.moduleimpl.module.titre or evaluation.moduleimpl.module.code
|
||||
@ -862,6 +897,7 @@ def _get_sheet_evaluations(
|
||||
rows: list[list[str]],
|
||||
evaluation: Evaluation | None = None,
|
||||
formsemestre: FormSemestre | None = None,
|
||||
modimpl: ModuleImpl | None = None,
|
||||
diag: list[str] = None,
|
||||
) -> tuple[int, list[Evaluation], dict[int, int]]:
|
||||
"""
|
||||
@ -869,7 +905,8 @@ def _get_sheet_evaluations(
|
||||
diag: liste dans laquelle accumuler les messages d'erreur
|
||||
evaluation (optionnel): l'évaluation que l'on cherche à remplir (pour feuille mono-évaluation)
|
||||
formsemestre (optionnel): le formsemestre dans lequel sont les évaluations à remplir
|
||||
formsemestre ou evaluation doivent être indiqués.
|
||||
modimpl (optionel): le moduleimpl dans lequel sont les évaluations à remplir
|
||||
formsemestre ou evaluation ou modimpl doivent être indiqués.
|
||||
|
||||
Résultat:
|
||||
row_title_idx: l'indice (à partir de 0) de la ligne TITRE (après laquelle commencent les notes)
|
||||
@ -896,7 +933,15 @@ def _get_sheet_evaluations(
|
||||
if evaluation is None:
|
||||
diag.append(f"""Erreur: l'évaluation {evaluation_id} n'existe pas""")
|
||||
raise InvalidNoteValue()
|
||||
if evaluation.moduleimpl.formsemestre_id != formsemestre.id:
|
||||
if (
|
||||
formsemestre
|
||||
and evaluation.moduleimpl.formsemestre_id != formsemestre.id
|
||||
):
|
||||
diag.append(
|
||||
f"""Erreur: l'évaluation {evaluation_id} n'existe pas dans ce semestre"""
|
||||
)
|
||||
raise InvalidNoteValue()
|
||||
if modimpl and evaluation.moduleimpl.id != modimpl.id:
|
||||
diag.append(
|
||||
f"""Erreur: l'évaluation {evaluation_id} n'existe pas dans ce semestre"""
|
||||
)
|
||||
@ -1014,7 +1059,7 @@ def saisie_notes_tableur(evaluation_id: int, group_ids=()):
|
||||
args = scu.get_request_args()
|
||||
evaluation = Evaluation.get_evaluation(args["evaluation_id"])
|
||||
ok, diagnostic_msg = do_evaluations_upload_xls(
|
||||
args["notefile"], evaluation=evaluation, comment=args["comment"]
|
||||
notefile=args["notefile"], evaluation=evaluation, comment=args["comment"]
|
||||
)
|
||||
if ok:
|
||||
H.append(
|
||||
@ -1124,16 +1169,23 @@ def saisie_notes_tableur(evaluation_id: int, group_ids=()):
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def formsemestre_import_notes(formsemestre: FormSemestre, notefile, comment: str):
|
||||
"""Importation de notes dans plusieurs évaluations du semestre"""
|
||||
def formsemestre_import_notes(
|
||||
formsemestre: FormSemestre | None = None,
|
||||
modimpl: ModuleImpl | None = None,
|
||||
notefile="",
|
||||
comment: str = "",
|
||||
):
|
||||
"""Importation de notes dans plusieurs évaluations
|
||||
du formsemestre ou du modimpl"""
|
||||
ok, diagnostic_msg = do_evaluations_upload_xls(
|
||||
notefile, formsemestre=formsemestre, comment=comment
|
||||
notefile=notefile, formsemestre=formsemestre, modimpl=modimpl, comment=comment
|
||||
)
|
||||
return render_template(
|
||||
"formsemestre/import_notes_after.j2",
|
||||
comment=comment,
|
||||
ok=ok,
|
||||
diagnostic_msg=diagnostic_msg,
|
||||
sco=ScoData(formsemestre=formsemestre),
|
||||
modimpl=modimpl,
|
||||
sco=ScoData(formsemestre=formsemestre or modimpl.formsemestre),
|
||||
title="Importation des notes",
|
||||
)
|
||||
|
@ -2168,6 +2168,11 @@ span.moduleimpl_abs_link {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.moduleimpl_evaluations_table_bot {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
table.moduleimpl_evaluations {
|
||||
width: 100%;
|
||||
border-spacing: 0px;
|
||||
|
@ -12,11 +12,27 @@ div.vspace {
|
||||
|
||||
|
||||
{% block app_content %}
|
||||
<h2>Import de notes dans les évaluations du semestre</h2>
|
||||
<h2>Import de notes dans les évaluations du
|
||||
{% if modimpl %}
|
||||
module
|
||||
{% else %}
|
||||
semestre
|
||||
{% endif %}
|
||||
</h2>
|
||||
|
||||
{% if modimpl %}
|
||||
<div class="help">
|
||||
Cette page permet d'importer des notes dans tout ou partie des évaluations du module.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Il y a <a class="stdlink" href="{{
|
||||
url_for('notes.moduleimpl_status', scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id )
|
||||
}}">{{ evaluations | length }} évaluations définies dans le module {{modimpl.module.code}}</a>.
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="help">
|
||||
Cette page permet d'importer des notes dans tout ou partie des évaluations du semestre.
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -24,12 +40,15 @@ Cette page permet d'importer des notes dans tout ou partie des évaluations du s
|
||||
url_for('notes.evaluations_recap', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )
|
||||
}}">{{ evaluations | length }} évaluations</a> définies dans ce semestre.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="saisienote_etape1">
|
||||
<span class="titredivsaisienote">Étape 1 : </span>
|
||||
<ul>
|
||||
<li><a class="stdlink" href="{{
|
||||
url_for( 'notes.feuille_import_notes', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )
|
||||
url_for( 'notes.moduleimpl_feuille_import_notes', scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id )
|
||||
if modimpl else
|
||||
url_for( 'notes.formsemestre_feuille_import_notes', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )
|
||||
}}" id="lnk_feuille_saisie">
|
||||
obtenir le fichier tableur à remplir
|
||||
</a>
|
||||
|
@ -18,7 +18,13 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h2>Import de notes dans les évaluations du semestre</h2>
|
||||
<h2>Import de notes dans les évaluations du
|
||||
{% if modimpl %}
|
||||
module
|
||||
{% else %}
|
||||
semestre
|
||||
{% endif %}
|
||||
</h2>
|
||||
|
||||
<div class="scobox {{ 'success' if ok else 'failure' }}">
|
||||
<div class="scobox-title">
|
||||
@ -36,6 +42,23 @@
|
||||
<div class="scobox">
|
||||
|
||||
<ul>
|
||||
{% if modimpl %}
|
||||
<li><a class="stdlink"
|
||||
href="{{url_for('notes.moduleimpl_status',
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id,
|
||||
)}}">
|
||||
{{modimpl.module.type_name()}} {{modimpl.module.code}} {{modimpl.module.titre_str()}}
|
||||
</a>
|
||||
</li>
|
||||
<li><a class="stdlink"
|
||||
href="{{url_for('notes.evaluation_listenotes',
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id,
|
||||
)}}">
|
||||
Lister les notes de {{modimpl.module.code}}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li><a class="stdlink"
|
||||
href="{{url_for('notes.formsemestre_recapcomplet',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=sco.formsemestre.id,
|
||||
@ -43,12 +66,14 @@
|
||||
Tableau de <em>toutes</em> les notes du semestre
|
||||
</a>
|
||||
</li>
|
||||
{% if sco.formsemestre %}
|
||||
<li><a class="stdlink"
|
||||
href="{{url_for('notes.formsemestre_import_notes',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=sco.formsemestre.id)}}">
|
||||
Importer d'autres notes
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1842,19 +1842,57 @@ sco_publish(
|
||||
@bp.route("/formsemestre_import_notes/<int:formsemestre_id>", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView) # controle contextuel
|
||||
def formsemestre_import_notes(formsemestre_id: int):
|
||||
"""Import via excel des notes de toutes les évals d'un semestre"""
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
dest_url = url_for(
|
||||
def formsemestre_import_notes(formsemestre_id: int | None = None):
|
||||
"Import via excel des notes de toutes les évals d'un semestre."
|
||||
return _formsemestre_or_modimpl_import_notes(formsemestre_id=formsemestre_id)
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/moduleimpl_import_notes/<int:moduleimpl_id>",
|
||||
methods=["GET", "POST"],
|
||||
)
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView) # controle contextuel
|
||||
def moduleimpl_import_notes(moduleimpl_id: int | None = None):
|
||||
"Import via excel des notes de toutes les évals d'un module."
|
||||
return _formsemestre_or_modimpl_import_notes(moduleimpl_id=moduleimpl_id)
|
||||
|
||||
|
||||
def _formsemestre_or_modimpl_import_notes(
|
||||
formsemestre_id: int | None = None, moduleimpl_id: int | None = None
|
||||
):
|
||||
"""Import via excel des notes de toutes les évals d'un semestre.
|
||||
Ou, si moduleimpl_import_notes, toutes les évals de ce module.
|
||||
"""
|
||||
formsemestre = (
|
||||
FormSemestre.get_formsemestre(formsemestre_id)
|
||||
if formsemestre_id is not None
|
||||
else None
|
||||
)
|
||||
modimpl = (
|
||||
ModuleImpl.get_modimpl(moduleimpl_id) if moduleimpl_id is not None else None
|
||||
)
|
||||
if not (formsemestre or modimpl):
|
||||
raise ScoValueError("paramètre manquant")
|
||||
dest_url = (
|
||||
url_for(
|
||||
"notes.moduleimpl_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
moduleimpl_id=modimpl.id,
|
||||
)
|
||||
if modimpl
|
||||
else url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre.id,
|
||||
)
|
||||
if not formsemestre.est_chef_or_diretud():
|
||||
)
|
||||
if formsemestre and not formsemestre.est_chef_or_diretud():
|
||||
raise ScoPermissionDenied("opération non autorisée", dest_url=dest_url)
|
||||
if modimpl and not modimpl.can_edit_notes(current_user):
|
||||
raise ScoPermissionDenied("opération non autorisée", dest_url=dest_url)
|
||||
|
||||
class ImportForm(FlaskForm):
|
||||
evaluation_id = HiddenField("formsemestre_id", default=formsemestre.id)
|
||||
notefile = FileField(
|
||||
"Fichier d'import",
|
||||
validators=[
|
||||
@ -1872,30 +1910,51 @@ def formsemestre_import_notes(formsemestre_id: int):
|
||||
comment = form.comment.data
|
||||
#
|
||||
return sco_saisie_excel.formsemestre_import_notes(
|
||||
formsemestre, notefile, comment
|
||||
formsemestre=formsemestre,
|
||||
modimpl=modimpl,
|
||||
notefile=notefile,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"formsemestre/import_notes.j2",
|
||||
evaluations=formsemestre.get_evaluations(),
|
||||
evaluations=(
|
||||
formsemestre.get_evaluations()
|
||||
if formsemestre
|
||||
else modimpl.evaluations.all()
|
||||
),
|
||||
form=form,
|
||||
formsemestre=formsemestre,
|
||||
modimpl=modimpl,
|
||||
title="Importation des notes",
|
||||
sco=ScoData(formsemestre=formsemestre),
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/feuille_import_notes/<int:formsemestre_id>")
|
||||
@bp.route("/formsemestre_feuille_import_notes/<int:formsemestre_id>")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def feuille_import_notes(formsemestre_id: int):
|
||||
def formsemestre_feuille_import_notes(formsemestre_id: int):
|
||||
"""Feuille excel pour importer les notes de toutes les évaluations du semestre"""
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
xls = sco_saisie_excel.excel_feuille_import(formsemestre)
|
||||
xls = sco_saisie_excel.excel_feuille_import(formsemestre=formsemestre)
|
||||
filename = scu.sanitize_filename(formsemestre.titre_annee())
|
||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||
|
||||
|
||||
@bp.route("/moduleimpl_feuille_import_notes/<int:moduleimpl_id>")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def moduleimpl_feuille_import_notes(moduleimpl_id: int):
|
||||
"""Feuille excel pour importer les notes de toutes les évaluations du modimpl"""
|
||||
modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
|
||||
xls = sco_saisie_excel.excel_feuille_import(modimpl=modimpl)
|
||||
filename = scu.sanitize_filename(
|
||||
f"{modimpl.module.code} {modimpl.formsemestre.annee_scolaire_str()}"
|
||||
)
|
||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||
|
||||
|
||||
# --- Bulletins
|
||||
@bp.route("/formsemestre_bulletins_pdf")
|
||||
@scodoc
|
||||
|
Loading…
Reference in New Issue
Block a user