diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index f58a38b72..57e5b92fb 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -13,6 +13,7 @@ import datetime from functools import cached_property +from flask_login import current_user import flask_sqlalchemy from flask import flash, g from sqlalchemy import and_, or_ @@ -20,6 +21,7 @@ from sqlalchemy.sql import text import app.scodoc.sco_utils as scu from app import db, log +from app.auth.models import User from app.models import APO_CODE_STR_LEN, CODE_STR_LEN, SHORT_STR_LEN from app.models.but_refcomp import ( ApcAnneeParcours, @@ -535,10 +537,32 @@ class FormSemestre(db.Model): else: return ", ".join([u.get_nomcomplet() for u in self.responsables]) - def est_responsable(self, user): + def est_responsable(self, user: User): "True si l'user est l'un des responsables du semestre" return user.id in [u.id for u in self.responsables] + def est_chef_or_diretud(self, user: User = None): + "Vrai si utilisateur (par def. current) est admin, chef dept ou responsable du semestre" + user = user or current_user + return user.has_permission(Permission.ScoImplement) or self.est_responsable( + user + ) + + def can_edit_jury(self, user: User = None): + """Vrai si utilisateur (par def. current) peut saisir decision de jury + dans ce semestre: vérifie permission et verrouillage. + """ + user = user or current_user + return self.etat and self.est_chef_or_diretud(user) + + def can_edit_pv(self, user: User = None): + "Vrai si utilisateur (par def. current) peut editer un PV de jury de ce semestre" + user = user or current_user + # Autorise les secrétariats, repérés via la permission ScoEtudChangeAdr + return self.est_chef_or_diretud(user) or user.has_permission( + Permission.ScoEtudChangeAdr + ) + def annee_scolaire(self) -> int: """L'année de début de l'année scolaire. Par exemple, 2022 si le semestre va de septembre 2022 à février 2023.""" diff --git a/app/scodoc/html_sco_header.py b/app/scodoc/html_sco_header.py index e4d330a78..e31162e3d 100644 --- a/app/scodoc/html_sco_header.py +++ b/app/scodoc/html_sco_header.py @@ -251,7 +251,7 @@ def sco_header( #gtrcontent {{ margin-left: {params["margin_left"]}; height: 100%%; - margin-bottom: 10px; + margin-bottom: 16px; }} """ diff --git a/app/scodoc/sco_archives.py b/app/scodoc/sco_archives.py index 5d0955543..2fe04513d 100644 --- a/app/scodoc/sco_archives.py +++ b/app/scodoc/sco_archives.py @@ -47,7 +47,7 @@ qui est une description (humaine, format libre) de l'archive. """ -import chardet +from typing import Union import datetime import glob import json @@ -56,10 +56,11 @@ import os import re import shutil import time -from typing import Union + +import chardet import flask -from flask import g, request +from flask import flash, g, request, url_for from flask_login import current_user import app.scodoc.sco_utils as scu @@ -70,9 +71,7 @@ from app.comp import res_sem from app.comp.res_compat import NotesTableCompat from app.models import Departement, FormSemestre from app.scodoc.TrivialFormulator import TrivialFormulator -from app.scodoc.sco_exceptions import ( - AccessDenied, -) +from app.scodoc.sco_exceptions import AccessDenied, ScoPermissionDenied from app.scodoc import html_sco_header from app.scodoc import sco_bulletins_pdf from app.scodoc import sco_formsemestre @@ -314,7 +313,7 @@ def do_formsemestre_archive( """ from app.scodoc.sco_recapcomplet import ( gen_formsemestre_recapcomplet_excel, - gen_formsemestre_recapcomplet_html, + gen_formsemestre_recapcomplet_html_table, gen_formsemestre_recapcomplet_json, ) @@ -338,7 +337,7 @@ def do_formsemestre_archive( if data: PVArchive.store(archive_id, "Tableau_moyennes" + scu.XLSX_SUFFIX, data) # Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes) - table_html = gen_formsemestre_recapcomplet_html( + table_html, _ = gen_formsemestre_recapcomplet_html_table( formsemestre, res, include_evaluations=True ) if table_html: @@ -416,8 +415,15 @@ def formsemestre_archive(formsemestre_id, group_ids=[]): """Make and store new archive for this formsemestre. (all students or only selected groups) """ - if not sco_permissions_check.can_edit_pv(formsemestre_id): - raise AccessDenied("opération non autorisée pour %s" % str(current_user)) + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_pv(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) + ) sem = sco_formsemestre.get_formsemestre(formsemestre_id) if not group_ids: @@ -579,26 +585,38 @@ def formsemestre_list_archives(formsemestre_id): def formsemestre_get_archived_file(formsemestre_id, archive_name, filename): """Send file to client.""" - sem = sco_formsemestre.get_formsemestre(formsemestre_id) - sem_archive_id = formsemestre_id + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + sem_archive_id = formsemestre.id return PVArchive.get_archived_file(sem_archive_id, archive_name, filename) def formsemestre_delete_archive(formsemestre_id, archive_name, dialog_confirmed=False): """Delete an archive""" - if not sco_permissions_check.can_edit_pv(formsemestre_id): - raise AccessDenied("opération non autorisée pour %s" % str(current_user)) - sem = sco_formsemestre.get_formsemestre(formsemestre_id) + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_pv(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) + ) sem_archive_id = formsemestre_id archive_id = PVArchive.get_id_from_name(sem_archive_id, archive_name) - dest_url = "formsemestre_list_archives?formsemestre_id=%s" % (formsemestre_id) + dest_url = url_for( + "notes.formsemestre_list_archives", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) if not dialog_confirmed: return scu.confirm_dialog( - """
La suppression sera définitive.
""" - % PVArchive.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M"), + f"""La suppression sera définitive.
+ """, dest_url="", cancel_url=dest_url, parameters={ @@ -608,4 +626,5 @@ def formsemestre_delete_archive(formsemestre_id, archive_name, dialog_confirmed= ) PVArchive.delete_archive(archive_id) - return flask.redirect(dest_url + "&head_message=Archive%20supprimée") + flash("Archive supprimée") + return flask.redirect(dest_url) diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index 392a20bd2..4be4c11d1 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -1208,7 +1208,7 @@ def make_menu_autres_operations( "formsemestre_id": formsemestre.id, "etudid": etud.id, }, - "enabled": sco_permissions_check.can_validate_sem(formsemestre.id), + "enabled": formsemestre.can_edit_jury(), }, { "title": "Enregistrer note d'une UE externe", @@ -1217,7 +1217,7 @@ def make_menu_autres_operations( "formsemestre_id": formsemestre.id, "etudid": etud.id, }, - "enabled": sco_permissions_check.can_validate_sem(formsemestre.id) + "enabled": formsemestre.can_edit_jury() and not formsemestre.formation.is_apc(), }, { @@ -1227,7 +1227,7 @@ def make_menu_autres_operations( "formsemestre_id": formsemestre.id, "etudid": etud.id, }, - "enabled": sco_permissions_check.can_validate_sem(formsemestre.id), + "enabled": formsemestre.can_edit_jury(), }, { "title": "Éditer PV jury", diff --git a/app/scodoc/sco_exceptions.py b/app/scodoc/sco_exceptions.py index 501964708..77c9a0779 100644 --- a/app/scodoc/sco_exceptions.py +++ b/app/scodoc/sco_exceptions.py @@ -27,22 +27,21 @@ """Exception handling """ +from flask_login import current_user # --- Exceptions -MSGPERMDENIED = "l'utilisateur %s n'a pas le droit d'effectuer cette operation" - - class ScoException(Exception): - pass + "super classe de toutes les exceptions ScoDoc." class InvalidNoteValue(ScoException): - pass + "Valeur note invalide. Usage interne saisie note." class ScoValueError(ScoException): "Exception avec page d'erreur utilisateur, et qui stoque dest_url" - + # mal nommée: super classe de toutes les exceptions avec page + # d'erreur gentille. def __init__(self, msg, dest_url=None): super().__init__(msg) self.dest_url = dest_url @@ -53,7 +52,9 @@ class ScoPermissionDenied(ScoValueError): def __init__(self, msg=None, dest_url=None): if msg is None: - msg = "Opération non autorisée !" + msg = f"""Opération non autorisée pour { + current_user.get_nomcomplet() if current_user else "?" + }. Pas la permission, ou objet verrouillé.""" super().__init__(msg, dest_url=dest_url) diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index 0e699868c..5a5f8d5af 100644 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -431,17 +431,18 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: }, { "title": "Saisie des décisions du jury", - "endpoint": "notes.formsemestre_saisie_jury", + "endpoint": "notes.formsemestre_recapcomplet", "args": { "formsemestre_id": formsemestre_id, + "mode_jury": 1, }, - "enabled": sco_permissions_check.can_validate_sem(formsemestre_id), + "enabled": formsemestre.can_edit_jury(), }, { "title": "Éditer les PV et archiver les résultats", "endpoint": "notes.formsemestre_archive", "args": {"formsemestre_id": formsemestre_id}, - "enabled": sco_permissions_check.can_edit_pv(formsemestre_id), + "enabled": formsemestre.can_edit_pv(), }, { "title": "Documents archivés", diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 3d2a7835a..e84d5bc61 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -72,9 +72,9 @@ def formsemestre_validation_etud_form( etudid=None, # one of etudid or etud_index is required etud_index=None, check=0, # opt: si true, propose juste une relecture du parcours - desturl=None, + dest_url=None, sortcol=None, - readonly=True, + read_only=True, ): """Formulaire de validation des décisions de jury""" formsemestre: FormSemestre = FormSemestre.query.filter_by( @@ -111,7 +111,7 @@ def formsemestre_validation_etud_form( etud_index_prev = etud_index - 1 if etud_index_prev < 0: etud_index_prev = None - if readonly: + if read_only: check = True etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] @@ -216,13 +216,13 @@ def formsemestre_validation_etud_form( H.append( formsemestre_recap_parcours_table( - Se, etudid, with_links=(check and not readonly) + Se, etudid, with_links=(check and not read_only) ) ) if check: - if not desturl: - desturl = url_tableau - H.append(f'') + if not dest_url: + dest_url = url_tableau + H.append(f'') return "\n".join(H + footer) @@ -342,8 +342,8 @@ def formsemestre_validation_etud_form( """ % (etudid, formsemestre_id) ) - if desturl: - H.append('' % desturl) + if dest_url: + H.append('' % dest_url) if sortcol: H.append('' % sortcol) diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py index a17b74faa..78c6c10c6 100644 --- a/app/scodoc/sco_permissions.py +++ b/app/scodoc/sco_permissions.py @@ -55,10 +55,6 @@ _SCO_PERMISSIONS = ( ), # 27 à 39 ... réservé pour "entreprises" (1 << 40, "ScoEtudChangePhoto", "Modifier la photo d'un étudiant"), - # Api scodoc9 - # XXX à revoir - # (1 << 42, "APIEditAllNotes", "API: Modifier toutes les notes"), - # (1 << 43, "APIAbsChange", "API: Saisir des absences"), ) diff --git a/app/scodoc/sco_permissions_check.py b/app/scodoc/sco_permissions_check.py index c0a72952b..224881bf8 100644 --- a/app/scodoc/sco_permissions_check.py +++ b/app/scodoc/sco_permissions_check.py @@ -101,30 +101,7 @@ def can_edit_suivi(): return current_user.has_permission(Permission.ScoEtudChangeAdr) -def can_validate_sem(formsemestre_id): - "Vrai si utilisateur peut saisir decision de jury dans ce semestre" - from app.scodoc import sco_formsemestre - - sem = sco_formsemestre.get_formsemestre(formsemestre_id) - if not sem["etat"]: - return False # semestre verrouillé - - return is_chef_or_diretud(sem) - - -def can_edit_pv(formsemestre_id): - "Vrai si utilisateur peut editer un PV de jury de ce semestre" - from app.scodoc import sco_formsemestre - - sem = sco_formsemestre.get_formsemestre(formsemestre_id) - if is_chef_or_diretud(sem): - return True - # Autorise les secrétariats, repérés via la permission ScoEtudChangeAdr - # (ceci nous évite d'ajouter une permission Zope aux installations existantes) - return current_user.has_permission(Permission.ScoEtudChangeAdr) - - -def is_chef_or_diretud(sem): +def is_chef_or_diretud(sem): # remplacé par formsemestre.est_chef_or_diretud "Vrai si utilisateur est admin, chef dept ou responsable du semestre" if ( current_user.has_permission(Permission.ScoImplement) diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index e0c8c0a35..5c86d9ffc 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -1243,7 +1243,7 @@ class BasePreferences(object): { "initvalue": 0, "title": "Afficher toutes les évaluations sur les bulletins", - "explanation": "y compris incomplètes ou futures (déconseillé, risque de publier des notes non définitives)", + "explanation": "y compris incomplètes ou futures (déconseillé, risque de publier des notes non définitives; n'affecte pas le calcul des moyennes)", "input_type": "boolcheckbox", "category": "bul", "labels": ["non", "oui"], diff --git a/app/scodoc/sco_pvjury.py b/app/scodoc/sco_pvjury.py index 416c985ba..b8a85c625 100644 --- a/app/scodoc/sco_pvjury.py +++ b/app/scodoc/sco_pvjury.py @@ -516,18 +516,18 @@ def pvjury_table( def formsemestre_pvjury(formsemestre_id, format="html", publish=True): """Page récapitulant les décisions de jury""" - - # Bretelle provisoire pour BUT 9.3.0 - # XXX TODO formsemestre = FormSemestre.query.get_or_404(formsemestre_id) is_apc = formsemestre.formation.is_apc() - if format == "html" and is_apc and formsemestre.semestre_id % 2 == 0: - from app.tables import jury_recap - - return jury_recap.formsemestre_saisie_jury_but( - formsemestre, read_only=True, mode="recap" + if format == "html" and is_apc: + return redirect( + url_for( + "notes.formsemestre_recapcomplet", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + mode_jury=1, + ) ) - # /XXX + footer = html_sco_header.sco_footer() dpv = dict_pvjury(formsemestre_id, with_prev=True) diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index 602289db4..85ca00421 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -51,7 +51,6 @@ from app.scodoc import sco_evaluations from app.scodoc.sco_exceptions import ScoValueError from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre_status -from app.scodoc import sco_permissions_check from app.scodoc import sco_preferences from app.tables.recap import TableRecap from app.tables.jury_recap import TableJury @@ -95,17 +94,26 @@ def formsemestre_recapcomplet( mode_jury = int(mode_jury) xml_with_decisions = int(xml_with_decisions) force_publishing = int(force_publishing) - - data = _do_formsemestre_recapcomplet( - formsemestre_id, - format=tabformat, - mode_jury=mode_jury, - xml_with_decisions=xml_with_decisions, - force_publishing=force_publishing, - selected_etudid=selected_etudid, + filename = scu.sanitize_filename( + f"""recap-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}""" ) if is_file: - return data + return _formsemestre_recapcomplet_to_file( + formsemestre, + tabformat=tabformat, + filename=filename, + xml_with_decisions=xml_with_decisions, + force_publishing=force_publishing, + ) + + table_html, table = _formsemestre_recapcomplet_to_html( + formsemestre, + filename=filename, + mode_jury=mode_jury, + tabformat=tabformat, + selected_etudid=selected_etudid, + ) + H = [ html_sco_header.sco_header( page_title=f"{formsemestre.sem_modalite()}: " @@ -131,64 +139,90 @@ def formsemestre_recapcomplet( H.append( '") - + H.append(f'') H.append( - f""" (cliquer sur un nom pour afficher son bulletin ou (cliquer sur un nom pour afficher son bulletin ou + ici avoir le classeur papier) + """ ) - H.append(data) + + H.append(table_html) # La table if len(formsemestre.inscriptions) > 0: - H.append("") + H.append("""") + if formsemestre.can_edit_jury(): if mode_jury: H.append( - f"""
Calcul automatique des décisions du jury -
Effacer toutes les décisions de jury du semestre --
+ }">Effacer toutes les décisions de jury (BUT) du semestre + """ ) - else: - H.append( - f"""Saisie des décisions du jury""" - ) - H.append("") + H.append("utilise les coefficients d'UE pour calculer la moyenne générale.
""" ) + + if mode_jury and table and sum(table.freq_codes_annuels.values()) > 0: + H.append( + f""" +{code} | +{table.freq_codes_annuels[code]} | +{ + (100*table.freq_codes_annuels[code] / len(table)):2.1f}% + | +
Saisie des décisions du jury -
""" - ) - else: - H.append( - f""" - - - """ - ) - H.append( - f""" -{code} | -{table.freq_codes_annuels[code]} | -{ - (100*table.freq_codes_annuels[code] / len(table)):2.1f}% - | -
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) return sco_formsemestre_validation.formsemestre_validation_etud( @@ -2321,10 +2325,14 @@ def formsemestre_validation_etud_manu( sortcol=None, ): "Enregistre choix jury pour un étudiant" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) return sco_formsemestre_validation.formsemestre_validation_etud_manu( @@ -2364,7 +2372,7 @@ def formsemestre_validation_but( etudid = int(etudid) except ValueError: abort(404, "invalid etudid") - read_only = not sco_permissions_check.can_validate_sem(formsemestre_id) + read_only = not formsemestre.can_edit_jury() # --- Navigation prev_lnk = ( @@ -2391,9 +2399,13 @@ def formsemestre_validation_but( {prev_lnk}
Opération non autorisée pour {current_user}", + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( dest_url=url_for( "notes.formsemestre_status", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, - ), + ) ) + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) form = jury_but_forms.FormSemestreValidationAutoBUTForm() if request.method == "POST": @@ -2602,9 +2615,10 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None): flash(f"Décisions enregistrées ({nb_etud_modif} étudiants modifiés)") return redirect( url_for( - "notes.formsemestre_saisie_jury", + "notes.formsemestre_recapcomplet", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, + mode_jury=1, ) ) return render_template( @@ -2621,11 +2635,16 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None): @scodoc7func def formsemestre_validate_previous_ue(formsemestre_id, etudid=None): "Form. saisie UE validée hors ScoDoc" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) + return sco_formsemestre_validation.formsemestre_validate_previous_ue( formsemestre_id, etudid ) @@ -2645,11 +2664,16 @@ sco_publish( @scodoc7func def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid=None): "Form. edition UE semestre extérieur" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) + return sco_formsemestre_exterieurs.formsemestre_ext_edit_ue_validations( formsemestre_id, etudid ) @@ -2668,11 +2692,16 @@ sco_publish( @scodoc7func def etud_ue_suppress_validation(etudid, formsemestre_id, ue_id): """Suppress a validation (ue_id, etudid) and redirect to formsemestre""" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) + return sco_formsemestre_validation.etud_ue_suppress_validation( etudid, formsemestre_id, ue_id ) @@ -2684,14 +2713,18 @@ def etud_ue_suppress_validation(etudid, formsemestre_id, ue_id): @scodoc7func def formsemestre_validation_auto(formsemestre_id): "Formulaire saisie automatisee des decisions d'un semestre" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), - ) formsemestre: FormSemestre = FormSemestre.query.filter_by( id=formsemestre_id, dept_id=g.scodoc_dept_id ).first_or_404() + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) + ) + if formsemestre.formation.is_apc(): return redirect( url_for( @@ -2709,10 +2742,14 @@ def formsemestre_validation_auto(formsemestre_id): @scodoc7func def do_formsemestre_validation_auto(formsemestre_id): "Formulaire saisie automatisee des decisions d'un semestre" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user, - dest_url=scu.ScoURL(), + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + if not formsemestre.can_edit_jury(): + raise ScoPermissionDenied( + dest_url=url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) ) return sco_formsemestre_validation.do_formsemestre_validation_auto(formsemestre_id) @@ -2726,13 +2763,16 @@ def formsemestre_validation_suppress_etud( formsemestre_id, etudid, dialog_confirmed=False ): """Suppression des décisions de jury pour un étudiant.""" - if not sco_permissions_check.can_validate_sem(formsemestre_id): - return scu.confirm_dialog( - message="
Opération non autorisée pour %s" % current_user,
- dest_url=scu.ScoURL(),
+ formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
+ if not formsemestre.can_edit_jury():
+ raise ScoPermissionDenied(
+ dest_url=url_for(
+ "notes.formsemestre_status",
+ scodoc_dept=g.scodoc_dept,
+ formsemestre_id=formsemestre_id,
+ )
)
etud = Identite.query.get_or_404(etudid)
- formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
if formsemestre.formation.is_apc():
next_url = url_for(
"scolar.ficheEtud",
@@ -2800,15 +2840,8 @@ sco_publish("/pvjury_table_but", jury_but_pv.pvjury_table_but, Permission.ScoVie
@scodoc7func
def formsemestre_saisie_jury(formsemestre_id: int, selected_etudid: int = None):
"""Page de saisie: liste des étudiants et lien vers page jury
- en semestres pairs de BUT, table spécifique avec l'année
sinon, redirect vers page recap en mode jury
"""
- read_only = not sco_permissions_check.can_validate_sem(formsemestre_id)
- formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
- if formsemestre.formation.is_apc() and formsemestre.semestre_id % 2 == 0:
- return jury_recap.formsemestre_saisie_jury_but(
- formsemestre, read_only, selected_etudid=selected_etudid
- )
return redirect(
url_for(
"notes.formsemestre_recapcomplet",
@@ -2819,23 +2852,6 @@ def formsemestre_saisie_jury(formsemestre_id: int, selected_etudid: int = None):
)
-@bp.route("/formsemestre_jury_but_recap")
-@scodoc
-@permission_required(Permission.ScoView)
-@scodoc7func
-def formsemestre_jury_but_recap(formsemestre_id: int, selected_etudid: int = None):
- """Tableau affichage des codes"""
- read_only = not sco_permissions_check.can_validate_sem(formsemestre_id)
- formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
- if not (formsemestre.formation.is_apc() and formsemestre.semestre_id % 2 == 0):
- raise ScoValueError(
- "formsemestre_jury_but_recap: réservé aux semestres pairs de BUT"
- )
- return jury_recap.formsemestre_saisie_jury_but(
- formsemestre, read_only=read_only, selected_etudid=selected_etudid, mode="recap"
- )
-
-
@bp.route(
"/formsemestre_jury_but_erase/