forked from ScoDoc/ScoDoc
update
This commit is contained in:
parent
a65e9f9e08
commit
82e3de02f6
@ -190,6 +190,7 @@ def create_app(config_class=DevConfig):
|
|||||||
|
|
||||||
app.register_error_handler(ScoGenError, handle_sco_value_error)
|
app.register_error_handler(ScoGenError, handle_sco_value_error)
|
||||||
app.register_error_handler(ScoValueError, handle_sco_value_error)
|
app.register_error_handler(ScoValueError, handle_sco_value_error)
|
||||||
|
|
||||||
app.register_error_handler(AccessDenied, handle_access_denied)
|
app.register_error_handler(AccessDenied, handle_access_denied)
|
||||||
app.register_error_handler(500, internal_server_error)
|
app.register_error_handler(500, internal_server_error)
|
||||||
app.register_error_handler(503, postgresql_server_error)
|
app.register_error_handler(503, postgresql_server_error)
|
||||||
|
@ -11,7 +11,7 @@ from time import time
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import cracklib # pylint: disable=import-error
|
import cracklib # pylint: disable=import-error
|
||||||
from flask import current_app, url_for, g
|
from flask import current_app, g
|
||||||
from flask_login import UserMixin, AnonymousUserMixin
|
from flask_login import UserMixin, AnonymousUserMixin
|
||||||
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
@ -136,6 +136,7 @@ class User(UserMixin, db.Model):
|
|||||||
return check_password_hash(self.password_hash, password)
|
return check_password_hash(self.password_hash, password)
|
||||||
|
|
||||||
def get_reset_password_token(self, expires_in=600):
|
def get_reset_password_token(self, expires_in=600):
|
||||||
|
"Un token pour réinitialiser son mot de passe"
|
||||||
return jwt.encode(
|
return jwt.encode(
|
||||||
{"reset_password": self.id, "exp": time() + expires_in},
|
{"reset_password": self.id, "exp": time() + expires_in},
|
||||||
current_app.config["SECRET_KEY"],
|
current_app.config["SECRET_KEY"],
|
||||||
@ -144,15 +145,17 @@ class User(UserMixin, db.Model):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def verify_reset_password_token(token):
|
def verify_reset_password_token(token):
|
||||||
|
"Vérification du token de reéinitialisation du mot de passe"
|
||||||
try:
|
try:
|
||||||
id = jwt.decode(
|
user_id = jwt.decode(
|
||||||
token, current_app.config["SECRET_KEY"], algorithms=["HS256"]
|
token, current_app.config["SECRET_KEY"], algorithms=["HS256"]
|
||||||
)["reset_password"]
|
)["reset_password"]
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
return User.query.get(id)
|
return User.query.get(user_id)
|
||||||
|
|
||||||
def to_dict(self, include_email=True):
|
def to_dict(self, include_email=True):
|
||||||
|
"""l'utilisateur comme un dict, avec des champs supplémentaires"""
|
||||||
data = {
|
data = {
|
||||||
"date_expiration": self.date_expiration.isoformat() + "Z"
|
"date_expiration": self.date_expiration.isoformat() + "Z"
|
||||||
if self.date_expiration
|
if self.date_expiration
|
||||||
@ -472,5 +475,5 @@ def get_super_admin():
|
|||||||
|
|
||||||
|
|
||||||
@login.user_loader
|
@login.user_loader
|
||||||
def load_user(id):
|
def load_user(uid):
|
||||||
return User.query.get(int(id))
|
return User.query.get(int(uid))
|
||||||
|
@ -72,7 +72,7 @@ def bulletin_but_xml_compat(
|
|||||||
etud = Identite.query.get_or_404(etudid)
|
etud = Identite.query.get_or_404(etudid)
|
||||||
results = bulletin_but.ResultatsSemestreBUT(sem)
|
results = bulletin_but.ResultatsSemestreBUT(sem)
|
||||||
nb_inscrits = len(results.etuds)
|
nb_inscrits = len(results.etuds)
|
||||||
if sem.bul_hide_xml or force_publishing:
|
if (not sem.bul_hide_xml) or force_publishing:
|
||||||
published = "1"
|
published = "1"
|
||||||
else:
|
else:
|
||||||
published = "0"
|
published = "0"
|
||||||
|
@ -245,7 +245,7 @@ class DeptForm(FlaskForm):
|
|||||||
|
|
||||||
|
|
||||||
def _make_dept_id_name():
|
def _make_dept_id_name():
|
||||||
"""Cette section assute que tous les départements sont traités (y compris ceux qu'ont pas de logo au départ)
|
"""Cette section assure que tous les départements sont traités (y compris ceux qu'ont pas de logo au départ)
|
||||||
et détermine l'ordre d'affichage des DeptForm (GLOBAL d'abord, puis par ordre alpha de nom de département)
|
et détermine l'ordre d'affichage des DeptForm (GLOBAL d'abord, puis par ordre alpha de nom de département)
|
||||||
-> [ (None, None), (dept_id, dept_name)... ]"""
|
-> [ (None, None), (dept_id, dept_name)... ]"""
|
||||||
depts = [(None, GLOBAL)]
|
depts = [(None, GLOBAL)]
|
||||||
|
@ -31,16 +31,10 @@ Formulaires création département
|
|||||||
|
|
||||||
from flask import flash, url_for, redirect, render_template
|
from flask import flash, url_for, redirect, render_template
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import SelectField, SubmitField, FormField, validators, FieldList
|
from wtforms import SubmitField, validators
|
||||||
from wtforms.fields.simple import StringField, HiddenField
|
from wtforms.fields.simple import StringField, BooleanField
|
||||||
|
|
||||||
from app import AccessDenied
|
|
||||||
from app.models import Departement
|
|
||||||
from app.models import ScoPreference
|
|
||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
from app.scodoc import sco_utils as scu
|
|
||||||
|
|
||||||
from flask_login import current_user
|
|
||||||
|
|
||||||
|
|
||||||
class CreateDeptForm(FlaskForm):
|
class CreateDeptForm(FlaskForm):
|
||||||
@ -60,5 +54,9 @@ class CreateDeptForm(FlaskForm):
|
|||||||
validators.DataRequired("acronyme du département requis"),
|
validators.DataRequired("acronyme du département requis"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
visible = BooleanField(
|
||||||
|
"Visible sur page d'accueil",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
submit = SubmitField("Valider")
|
submit = SubmitField("Valider")
|
||||||
cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})
|
cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})
|
||||||
|
@ -49,11 +49,11 @@ class Departement(db.Model):
|
|||||||
return dept
|
return dept
|
||||||
|
|
||||||
|
|
||||||
def create_dept(acronym: str) -> Departement:
|
def create_dept(acronym: str, visible=True) -> Departement:
|
||||||
"Create new departement"
|
"Create new departement"
|
||||||
from app.models import ScoPreference
|
from app.models import ScoPreference
|
||||||
|
|
||||||
departement = Departement(acronym=acronym)
|
departement = Departement(acronym=acronym, visible=visible)
|
||||||
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
|
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
|
||||||
db.session.add(p1)
|
db.session.add(p1)
|
||||||
db.session.add(departement)
|
db.session.add(departement)
|
||||||
|
@ -78,7 +78,8 @@ def html_edit_formation_apc(
|
|||||||
alt="supprimer",
|
alt="supprimer",
|
||||||
),
|
),
|
||||||
"delete_disabled": scu.icontag(
|
"delete_disabled": scu.icontag(
|
||||||
"delete_small_dis_img", title="Suppression impossible (module utilisé)"
|
"delete_small_dis_img",
|
||||||
|
title="Suppression impossible (utilisé dans des semestres)",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +30,18 @@
|
|||||||
"""
|
"""
|
||||||
import flask
|
import flask
|
||||||
from flask import g, url_for, request
|
from flask import g, url_for, request
|
||||||
|
from app.models.formations import Matiere
|
||||||
|
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app import log
|
from app import log
|
||||||
from app.models import Formation
|
from app.models import Formation
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
|
from app.scodoc.sco_exceptions import (
|
||||||
|
ScoValueError,
|
||||||
|
ScoLockedFormError,
|
||||||
|
ScoNonEmptyFormationObject,
|
||||||
|
)
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
_matiereEditor = ndb.EditableTable(
|
_matiereEditor = ndb.EditableTable(
|
||||||
@ -156,6 +161,16 @@ associé.
|
|||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
|
|
||||||
|
|
||||||
|
def can_delete_matiere(matiere: Matiere) -> tuple[bool, str]:
|
||||||
|
"True si la matiere n'est pas utilisée dans des formsemestre"
|
||||||
|
locked = matiere_is_locked(matiere.id)
|
||||||
|
if locked:
|
||||||
|
return False
|
||||||
|
if any(m.modimpls.all() for m in matiere.modules):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def do_matiere_delete(oid):
|
def do_matiere_delete(oid):
|
||||||
"delete matiere and attached modules"
|
"delete matiere and attached modules"
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
@ -165,17 +180,16 @@ def do_matiere_delete(oid):
|
|||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# check
|
# check
|
||||||
mat = matiere_list({"matiere_id": oid})[0]
|
matiere = Matiere.query.get_or_404(oid)
|
||||||
|
mat = matiere_list({"matiere_id": oid})[0] # compat sco7
|
||||||
ue = sco_edit_ue.ue_list({"ue_id": mat["ue_id"]})[0]
|
ue = sco_edit_ue.ue_list({"ue_id": mat["ue_id"]})[0]
|
||||||
locked = matiere_is_locked(mat["matiere_id"])
|
if not can_delete_matiere(matiere):
|
||||||
if locked:
|
# il y a au moins un modimpl dans un module de cette matière
|
||||||
log("do_matiere_delete: mat=%s" % mat)
|
raise ScoNonEmptyFormationObject("Matière", matiere.titre)
|
||||||
log("do_matiere_delete: ue=%s" % ue)
|
|
||||||
log("do_matiere_delete: locked sems: %s" % locked)
|
log("do_matiere_delete: matiere_id=%s" % matiere.id)
|
||||||
raise ScoLockedFormError()
|
|
||||||
log("do_matiere_delete: matiere_id=%s" % oid)
|
|
||||||
# delete all modules in this matiere
|
# delete all modules in this matiere
|
||||||
mods = sco_edit_module.module_list({"matiere_id": oid})
|
mods = sco_edit_module.module_list({"matiere_id": matiere.id})
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
sco_edit_module.do_module_delete(mod["module_id"])
|
sco_edit_module.do_module_delete(mod["module_id"])
|
||||||
_matiereEditor.delete(cnx, oid)
|
_matiereEditor.delete(cnx, oid)
|
||||||
@ -194,11 +208,25 @@ def matiere_delete(matiere_id=None):
|
|||||||
"""Delete matière"""
|
"""Delete matière"""
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
|
|
||||||
M = matiere_list(args={"matiere_id": matiere_id})[0]
|
matiere = Matiere.query.get_or_404(matiere_id)
|
||||||
UE = sco_edit_ue.ue_list(args={"ue_id": M["ue_id"]})[0]
|
if not can_delete_matiere(matiere):
|
||||||
|
# il y a au moins un modimpl dans un module de cette matière
|
||||||
|
raise ScoNonEmptyFormationObject(
|
||||||
|
"Matière",
|
||||||
|
matiere.titre,
|
||||||
|
dest_url=url_for(
|
||||||
|
"notes.ue_table",
|
||||||
|
formation_id=matiere.ue.formation_id,
|
||||||
|
semestre_idx=matiere.ue.semestre_idx,
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
mat = matiere_list(args={"matiere_id": matiere_id})[0]
|
||||||
|
UE = sco_edit_ue.ue_list(args={"ue_id": mat["ue_id"]})[0]
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(page_title="Suppression d'une matière"),
|
html_sco_header.sco_header(page_title="Suppression d'une matière"),
|
||||||
"<h2>Suppression de la matière %(titre)s" % M,
|
"<h2>Suppression de la matière %(titre)s" % mat,
|
||||||
" dans l'UE (%(acronyme)s))</h2>" % UE,
|
" dans l'UE (%(acronyme)s))</h2>" % UE,
|
||||||
]
|
]
|
||||||
dest_url = url_for(
|
dest_url = url_for(
|
||||||
@ -210,7 +238,7 @@ def matiere_delete(matiere_id=None):
|
|||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
(("matiere_id", {"input_type": "hidden"}),),
|
(("matiere_id", {"input_type": "hidden"}),),
|
||||||
initvalues=M,
|
initvalues=mat,
|
||||||
submitlabel="Confirmer la suppression",
|
submitlabel="Confirmer la suppression",
|
||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
|
@ -43,7 +43,12 @@ from app import models
|
|||||||
from app.models import Formation
|
from app.models import Formation
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError
|
from app.scodoc.sco_exceptions import (
|
||||||
|
ScoValueError,
|
||||||
|
ScoLockedFormError,
|
||||||
|
ScoGenError,
|
||||||
|
ScoNonEmptyFormationObject,
|
||||||
|
)
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc import sco_edit_matiere
|
from app.scodoc import sco_edit_matiere
|
||||||
@ -330,20 +335,37 @@ def module_create(matiere_id=None, module_type=None, semestre_id=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def can_delete_module(module):
|
||||||
|
"True si le module n'est pas utilisée dans des formsemestre"
|
||||||
|
return len(module.modimpls.all()) == 0
|
||||||
|
|
||||||
|
|
||||||
def do_module_delete(oid):
|
def do_module_delete(oid):
|
||||||
"delete module"
|
"delete module"
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
|
|
||||||
mod = module_list({"module_id": oid})[0]
|
module = Module.query.get_or_404(oid)
|
||||||
if module_is_locked(mod["module_id"]):
|
mod = module_list({"module_id": oid})[0] # sco7
|
||||||
|
if module_is_locked(module.id):
|
||||||
raise ScoLockedFormError()
|
raise ScoLockedFormError()
|
||||||
|
if not can_delete_module(module):
|
||||||
|
raise ScoNonEmptyFormationObject(
|
||||||
|
"Module",
|
||||||
|
msg=module.titre,
|
||||||
|
dest_url=url_for(
|
||||||
|
"notes.ue_table",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=module.formation_id,
|
||||||
|
semestre_idx=module.ue.semestre_idx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# S'il y a des moduleimpls, on ne peut pas detruire le module !
|
# S'il y a des moduleimpls, on ne peut pas detruire le module !
|
||||||
mods = sco_moduleimpl.moduleimpl_list(module_id=oid)
|
mods = sco_moduleimpl.moduleimpl_list(module_id=oid)
|
||||||
if mods:
|
if mods:
|
||||||
err_page = f"""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>
|
err_page = f"""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>
|
||||||
<p class="help">Il faut d'abord supprimer le semestre. Mais il est peut être préférable de
|
<p class="help">Il faut d'abord supprimer le semestre (ou en retirer ce module). Mais il est peut être préférable de
|
||||||
laisser ce programme intact et d'en créer une nouvelle version pour la modifier.
|
laisser ce programme intact et d'en créer une nouvelle version pour la modifier sans affecter les semestres déjà en place.
|
||||||
</p>
|
</p>
|
||||||
<a href="{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept,
|
<a href="{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=mod["formation_id"])}">reprendre</a>
|
formation_id=mod["formation_id"])}">reprendre</a>
|
||||||
@ -365,12 +387,21 @@ def do_module_delete(oid):
|
|||||||
|
|
||||||
def module_delete(module_id=None):
|
def module_delete(module_id=None):
|
||||||
"""Delete a module"""
|
"""Delete a module"""
|
||||||
if not module_id:
|
module = Module.query.get_or_404(module_id)
|
||||||
raise ScoValueError("invalid module !")
|
mod = module_list(args={"module_id": module_id})[0] # sco7
|
||||||
modules = module_list(args={"module_id": module_id})
|
|
||||||
if not modules:
|
if not can_delete_module(module):
|
||||||
raise ScoValueError("Module inexistant !")
|
raise ScoNonEmptyFormationObject(
|
||||||
mod = modules[0]
|
"Module",
|
||||||
|
msg=module.titre,
|
||||||
|
dest_url=url_for(
|
||||||
|
"notes.ue_table",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=module.formation_id,
|
||||||
|
semestre_idx=module.ue.semestre_idx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(page_title="Suppression d'un module"),
|
html_sco_header.sco_header(page_title="Suppression d'un module"),
|
||||||
"""<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % mod,
|
"""<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % mod,
|
||||||
|
@ -42,7 +42,12 @@ from app import log
|
|||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
|
from app.scodoc.sco_exceptions import (
|
||||||
|
ScoGenError,
|
||||||
|
ScoValueError,
|
||||||
|
ScoLockedFormError,
|
||||||
|
ScoNonEmptyFormationObject,
|
||||||
|
)
|
||||||
|
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
@ -130,64 +135,83 @@ def do_ue_create(args):
|
|||||||
return ue_id
|
return ue_id
|
||||||
|
|
||||||
|
|
||||||
|
def can_delete_ue(ue: UniteEns) -> bool:
|
||||||
|
"""True si l'UE n'est pas utilisée dans des formsemestre
|
||||||
|
et n'a pas de module rattachés
|
||||||
|
"""
|
||||||
|
# "pas un seul module de cette UE n'a de modimpl...""
|
||||||
|
return (not len(ue.modules.all())) and not any(m.modimpls.all() for m in ue.modules)
|
||||||
|
|
||||||
|
|
||||||
def do_ue_delete(ue_id, delete_validations=False, force=False):
|
def do_ue_delete(ue_id, delete_validations=False, force=False):
|
||||||
"delete UE and attached matieres (but not modules)"
|
"delete UE and attached matieres (but not modules)"
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc import sco_parcours_dut
|
from app.scodoc import sco_parcours_dut
|
||||||
|
|
||||||
|
ue = UniteEns.query.get_or_404(ue_id)
|
||||||
|
if not can_delete_ue(ue):
|
||||||
|
raise ScoNonEmptyFormationObject(
|
||||||
|
"UE",
|
||||||
|
msg=ue.titre,
|
||||||
|
dest_url=url_for(
|
||||||
|
"notes.ue_table",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=ue.formation_id,
|
||||||
|
semestre_idx=ue.semestre_idx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
log("do_ue_delete: ue_id=%s, delete_validations=%s" % (ue_id, delete_validations))
|
log("do_ue_delete: ue_id=%s, delete_validations=%s" % (ue.id, delete_validations))
|
||||||
# check
|
# check
|
||||||
ue = ue_list({"ue_id": ue_id})
|
# if ue_is_locked(ue.id):
|
||||||
if not ue:
|
# raise ScoLockedFormError()
|
||||||
raise ScoValueError("UE inexistante !")
|
|
||||||
ue = ue[0]
|
|
||||||
if ue_is_locked(ue["ue_id"]):
|
|
||||||
raise ScoLockedFormError()
|
|
||||||
# Il y a-t-il des etudiants ayant validé cette UE ?
|
# Il y a-t-il des etudiants ayant validé cette UE ?
|
||||||
# si oui, propose de supprimer les validations
|
# si oui, propose de supprimer les validations
|
||||||
validations = sco_parcours_dut.scolar_formsemestre_validation_list(
|
validations = sco_parcours_dut.scolar_formsemestre_validation_list(
|
||||||
cnx, args={"ue_id": ue_id}
|
cnx, args={"ue_id": ue.id}
|
||||||
)
|
)
|
||||||
if validations and not delete_validations and not force:
|
if validations and not delete_validations and not force:
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
"<p>%d étudiants ont validé l'UE %s (%s)</p><p>Si vous supprimez cette UE, ces validations vont être supprimées !</p>"
|
"<p>%d étudiants ont validé l'UE %s (%s)</p><p>Si vous supprimez cette UE, ces validations vont être supprimées !</p>"
|
||||||
% (len(validations), ue["acronyme"], ue["titre"]),
|
% (len(validations), ue.acronyme, ue.titre),
|
||||||
dest_url="",
|
dest_url="",
|
||||||
target_variable="delete_validations",
|
target_variable="delete_validations",
|
||||||
cancel_url=url_for(
|
cancel_url=url_for(
|
||||||
"notes.ue_table",
|
"notes.ue_table",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=str(ue["formation_id"]),
|
formation_id=ue.formation_id,
|
||||||
|
semestre_idx=ue.semestre_idx,
|
||||||
),
|
),
|
||||||
parameters={"ue_id": ue_id, "dialog_confirmed": 1},
|
parameters={"ue_id": ue.id, "dialog_confirmed": 1},
|
||||||
)
|
)
|
||||||
if delete_validations:
|
if delete_validations:
|
||||||
log("deleting all validations of UE %s" % ue_id)
|
log("deleting all validations of UE %s" % ue.id)
|
||||||
ndb.SimpleQuery(
|
ndb.SimpleQuery(
|
||||||
"DELETE FROM scolar_formsemestre_validation WHERE ue_id=%(ue_id)s",
|
"DELETE FROM scolar_formsemestre_validation WHERE ue_id=%(ue_id)s",
|
||||||
{"ue_id": ue_id},
|
{"ue_id": ue.id},
|
||||||
)
|
)
|
||||||
|
|
||||||
# delete all matiere in this UE
|
# delete all matiere in this UE
|
||||||
mats = sco_edit_matiere.matiere_list({"ue_id": ue_id})
|
mats = sco_edit_matiere.matiere_list({"ue_id": ue.id})
|
||||||
for mat in mats:
|
for mat in mats:
|
||||||
sco_edit_matiere.do_matiere_delete(mat["matiere_id"])
|
sco_edit_matiere.do_matiere_delete(mat["matiere_id"])
|
||||||
# delete uecoef and events
|
# delete uecoef and events
|
||||||
ndb.SimpleQuery(
|
ndb.SimpleQuery(
|
||||||
"DELETE FROM notes_formsemestre_uecoef WHERE ue_id=%(ue_id)s",
|
"DELETE FROM notes_formsemestre_uecoef WHERE ue_id=%(ue_id)s",
|
||||||
{"ue_id": ue_id},
|
{"ue_id": ue.id},
|
||||||
)
|
)
|
||||||
ndb.SimpleQuery("DELETE FROM scolar_events WHERE ue_id=%(ue_id)s", {"ue_id": ue_id})
|
ndb.SimpleQuery("DELETE FROM scolar_events WHERE ue_id=%(ue_id)s", {"ue_id": ue.id})
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
_ueEditor.delete(cnx, ue_id)
|
_ueEditor.delete(cnx, ue.id)
|
||||||
# > UE delete + supr. validations associées etudiants (cas compliqué, mais rarement utilisé: acceptable de tout invalider ?):
|
# > UE delete + supr. validations associées etudiants (cas compliqué, mais rarement
|
||||||
|
# utilisé: acceptable de tout invalider):
|
||||||
sco_cache.invalidate_formsemestre()
|
sco_cache.invalidate_formsemestre()
|
||||||
# news
|
# news
|
||||||
F = sco_formations.formation_list(args={"formation_id": ue["formation_id"]})[0]
|
F = sco_formations.formation_list(args={"formation_id": ue.formation_id})[0]
|
||||||
sco_news.add(
|
sco_news.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=sco_news.NEWS_FORM,
|
||||||
object=ue["formation_id"],
|
object=ue.formation_id,
|
||||||
text="Modification de la formation %(acronyme)s" % F,
|
text="Modification de la formation %(acronyme)s" % F,
|
||||||
max_frequency=3,
|
max_frequency=3,
|
||||||
)
|
)
|
||||||
@ -197,11 +221,11 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
|
|||||||
url_for(
|
url_for(
|
||||||
"notes.ue_table",
|
"notes.ue_table",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=ue["formation_id"],
|
formation_id=ue.formation_id,
|
||||||
|
semestre_idx=ue.semestre_idx,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def ue_create(formation_id=None):
|
def ue_create(formation_id=None):
|
||||||
@ -211,8 +235,6 @@ def ue_create(formation_id=None):
|
|||||||
|
|
||||||
def ue_edit(ue_id=None, create=False, formation_id=None):
|
def ue_edit(ue_id=None, create=False, formation_id=None):
|
||||||
"""Modification ou création d'une UE"""
|
"""Modification ou création d'une UE"""
|
||||||
from app.scodoc import sco_formations
|
|
||||||
|
|
||||||
create = int(create)
|
create = int(create)
|
||||||
if not create:
|
if not create:
|
||||||
U = ue_list(args={"ue_id": ue_id})
|
U = ue_list(args={"ue_id": ue_id})
|
||||||
@ -444,24 +466,38 @@ def next_ue_numero(formation_id, semestre_id=None):
|
|||||||
|
|
||||||
def ue_delete(ue_id=None, delete_validations=False, dialog_confirmed=False):
|
def ue_delete(ue_id=None, delete_validations=False, dialog_confirmed=False):
|
||||||
"""Delete an UE"""
|
"""Delete an UE"""
|
||||||
ues = ue_list(args={"ue_id": ue_id})
|
ue = UniteEns.query.get_or_404(ue_id)
|
||||||
if not ues:
|
if ue.modules.all():
|
||||||
raise ScoValueError("UE inexistante !")
|
raise ScoValueError(
|
||||||
ue = ues[0]
|
f"""Suppression de l'UE {ue.titre} impossible car
|
||||||
|
des modules (ou SAÉ ou ressources) lui sont rattachés."""
|
||||||
if not dialog_confirmed:
|
)
|
||||||
return scu.confirm_dialog(
|
if not can_delete_ue(ue):
|
||||||
"<h2>Suppression de l'UE %(titre)s (%(acronyme)s))</h2>" % ue,
|
raise ScoNonEmptyFormationObject(
|
||||||
dest_url="",
|
"UE",
|
||||||
parameters={"ue_id": ue_id},
|
msg=ue.titre,
|
||||||
cancel_url=url_for(
|
dest_url=url_for(
|
||||||
"notes.ue_table",
|
"notes.ue_table",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=str(ue["formation_id"]),
|
formation_id=ue.formation_id,
|
||||||
|
semestre_idx=ue.semestre_idx,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
return do_ue_delete(ue_id, delete_validations=delete_validations)
|
if not dialog_confirmed:
|
||||||
|
return scu.confirm_dialog(
|
||||||
|
f"<h2>Suppression de l'UE {ue.titre} ({ue.acronyme})</h2>",
|
||||||
|
dest_url="",
|
||||||
|
parameters={"ue_id": ue.id},
|
||||||
|
cancel_url=url_for(
|
||||||
|
"notes.ue_table",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=ue.formation_id,
|
||||||
|
semestre_idx=ue.semestre_idx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return do_ue_delete(ue.id, delete_validations=delete_validations)
|
||||||
|
|
||||||
|
|
||||||
def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
||||||
@ -1010,12 +1046,14 @@ def _ue_table_modules(
|
|||||||
H.append(arrow_none)
|
H.append(arrow_none)
|
||||||
im += 1
|
im += 1
|
||||||
if mod["nb_moduleimpls"] == 0 and editable:
|
if mod["nb_moduleimpls"] == 0 and editable:
|
||||||
H.append(
|
icon = delete_icon
|
||||||
'<a class="smallbutton" href="module_delete?module_id=%s">%s</a>'
|
|
||||||
% (mod["module_id"], delete_icon)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
H.append(delete_disabled_icon)
|
icon = delete_disabled_icon
|
||||||
|
H.append(
|
||||||
|
'<a class="smallbutton" href="module_delete?module_id=%s">%s</a>'
|
||||||
|
% (mod["module_id"], icon)
|
||||||
|
)
|
||||||
|
|
||||||
H.append("</span>")
|
H.append("</span>")
|
||||||
|
|
||||||
mod_editable = (
|
mod_editable = (
|
||||||
|
@ -52,7 +52,7 @@ class InvalidNoteValue(ScoException):
|
|||||||
# Exception qui stoque dest_url, utilisee dans Zope standard_error_message
|
# Exception qui stoque dest_url, utilisee dans Zope standard_error_message
|
||||||
class ScoValueError(ScoException):
|
class ScoValueError(ScoException):
|
||||||
def __init__(self, msg, dest_url=None):
|
def __init__(self, msg, dest_url=None):
|
||||||
ScoException.__init__(self, msg)
|
super().__init__(msg)
|
||||||
self.dest_url = dest_url
|
self.dest_url = dest_url
|
||||||
|
|
||||||
|
|
||||||
@ -72,20 +72,35 @@ class ScoConfigurationError(ScoValueError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ScoLockedFormError(ScoException):
|
class ScoLockedFormError(ScoValueError):
|
||||||
def __init__(self, msg=""):
|
"Modification d'une formation verrouillée"
|
||||||
|
|
||||||
|
def __init__(self, msg="", dest_url=None):
|
||||||
msg = (
|
msg = (
|
||||||
"Cette formation est verrouillée (car il y a un semestre verrouillé qui s'y réfère). "
|
"Cette formation est verrouillée (car il y a un semestre verrouillé qui s'y réfère). "
|
||||||
+ str(msg)
|
+ str(msg)
|
||||||
)
|
)
|
||||||
ScoException.__init__(self, msg)
|
super().__init__(msg=msg, dest_url=dest_url)
|
||||||
|
|
||||||
|
|
||||||
|
class ScoNonEmptyFormationObject(ScoValueError):
|
||||||
|
"""On ne peut pas supprimer un module/matiere ou UE si des formsemestre s'y réfèrent"""
|
||||||
|
|
||||||
|
def __init__(self, type_objet="objet'", msg="", dest_url=None):
|
||||||
|
msg = f"""<h3>{type_objet} "{msg}" utilisé dans des semestres: suppression impossible.</h3>
|
||||||
|
<p class="help">Il faut d'abord supprimer le semestre (ou en retirer ce {type_objet}).
|
||||||
|
Mais il est peut-être préférable de laisser ce programme intact et d'en créer une
|
||||||
|
nouvelle version pour la modifier sans affecter les semestres déjà en place.
|
||||||
|
</p>
|
||||||
|
"""
|
||||||
|
super().__init__(msg=msg, dest_url=dest_url)
|
||||||
|
|
||||||
|
|
||||||
class ScoGenError(ScoException):
|
class ScoGenError(ScoException):
|
||||||
"exception avec affichage d'une page explicative ad-hoc"
|
"exception avec affichage d'une page explicative ad-hoc"
|
||||||
|
|
||||||
def __init__(self, msg=""):
|
def __init__(self, msg=""):
|
||||||
ScoException.__init__(self, msg)
|
super().__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
class AccessDenied(ScoGenError):
|
class AccessDenied(ScoGenError):
|
||||||
@ -101,7 +116,7 @@ class APIInvalidParams(Exception):
|
|||||||
status_code = 400
|
status_code = 400
|
||||||
|
|
||||||
def __init__(self, message, status_code=None, payload=None):
|
def __init__(self, message, status_code=None, payload=None):
|
||||||
Exception.__init__(self)
|
super().__init__()
|
||||||
self.message = message
|
self.message = message
|
||||||
if status_code is not None:
|
if status_code is not None:
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
|
@ -198,10 +198,13 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
NB_SEM = parcours.NB_SEM
|
NB_SEM = parcours.NB_SEM
|
||||||
else:
|
else:
|
||||||
NB_SEM = 10 # fallback, max 10 semestres
|
NB_SEM = 10 # fallback, max 10 semestres
|
||||||
semestre_id_list = [-1] + list(range(1, NB_SEM + 1))
|
if NB_SEM == 1:
|
||||||
|
semestre_id_list = [-1]
|
||||||
|
else:
|
||||||
|
semestre_id_list = [-1] + list(range(1, NB_SEM + 1))
|
||||||
semestre_id_labels = []
|
semestre_id_labels = []
|
||||||
for sid in semestre_id_list:
|
for sid in semestre_id_list:
|
||||||
if sid == "-1":
|
if sid == -1:
|
||||||
semestre_id_labels.append("pas de semestres")
|
semestre_id_labels.append("pas de semestres")
|
||||||
else:
|
else:
|
||||||
semestre_id_labels.append(f"S{sid}")
|
semestre_id_labels.append(f"S{sid}")
|
||||||
@ -329,6 +332,8 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"labels": modalites_titles,
|
"labels": modalites_titles,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
]
|
||||||
|
modform.append(
|
||||||
(
|
(
|
||||||
"semestre_id",
|
"semestre_id",
|
||||||
{
|
{
|
||||||
@ -338,7 +343,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"labels": semestre_id_labels,
|
"labels": semestre_id_labels,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
)
|
||||||
etapes = sco_portal_apogee.get_etapes_apogee_dept()
|
etapes = sco_portal_apogee.get_etapes_apogee_dept()
|
||||||
# Propose les etapes renvoyées par le portail
|
# Propose les etapes renvoyées par le portail
|
||||||
# et ajoute les étapes du semestre qui ne sont pas dans la liste (soit la liste a changé, soit l'étape a été ajoutée manuellement)
|
# et ajoute les étapes du semestre qui ne sont pas dans la liste (soit la liste a changé, soit l'étape a été ajoutée manuellement)
|
||||||
|
@ -93,6 +93,7 @@ MODULE_TYPE_NAMES = {
|
|||||||
ModuleType.MALUS: "Malus",
|
ModuleType.MALUS: "Malus",
|
||||||
ModuleType.RESSOURCE: "Ressource",
|
ModuleType.RESSOURCE: "Ressource",
|
||||||
ModuleType.SAE: "SAÉ",
|
ModuleType.SAE: "SAÉ",
|
||||||
|
None: "Module",
|
||||||
}
|
}
|
||||||
|
|
||||||
MALUS_MAX = 20.0
|
MALUS_MAX = 20.0
|
||||||
|
@ -24,13 +24,10 @@
|
|||||||
{{icons.arrow_none|safe}}
|
{{icons.arrow_none|safe}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% if editable and not ue.modules.count() %}
|
|
||||||
<a class="smallbutton" href="{{ url_for('notes.ue_delete',
|
<a class="smallbutton" href="{{ url_for('notes.ue_delete',
|
||||||
scodoc_dept=g.scodoc_dept, ue_id=ue.id)
|
scodoc_dept=g.scodoc_dept, ue_id=ue.id)
|
||||||
}}">{{icons.delete|safe}}</a>
|
}}">{% if editable and not ue.modules.count() %}{{icons.delete|safe}}{% else %}{{icons.delete_disabled|safe}}{% endif %}</a>
|
||||||
{% else %}
|
|
||||||
{{icons.delete_disabled|safe}}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<b>{{ue.acronyme}}</b> <a class="discretelink" href="{{
|
<b>{{ue.acronyme}}</b> <a class="discretelink" href="{{
|
||||||
url_for('notes.ue_infos', scodoc_dept=g.scodoc_dept, ue_id=ue.id)}}"
|
url_for('notes.ue_infos', scodoc_dept=g.scodoc_dept, ue_id=ue.id)}}"
|
||||||
|
@ -8,10 +8,9 @@
|
|||||||
|
|
||||||
{{ exc | safe }}
|
{{ exc | safe }}
|
||||||
|
|
||||||
<p class="footer">
|
<p>
|
||||||
{% if g.scodoc_dept %}
|
{% if g.scodoc_dept %}
|
||||||
<a href="{{ exc.dest_url or url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}">retour page d'accueil
|
<a href="{{ exc.dest_url or url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}">continuer</a>
|
||||||
departement {{ g.scodoc_dept }}</a>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ exc.dest_url or url_for('scodoc.index') }}">retour page d'accueil</a>
|
<a href="{{ exc.dest_url or url_for('scodoc.index') }}">retour page d'accueil</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -13,11 +13,21 @@
|
|||||||
|
|
||||||
<ul class="main">
|
<ul class="main">
|
||||||
{% for dept in depts %}
|
{% for dept in depts %}
|
||||||
|
{% if dept.visible or current_user.is_administrator() %}
|
||||||
<li>
|
<li>
|
||||||
<a class="stdlink {{'link_accessible' if current_user.has_permission(Permission.ScoView, dept=dept.acronym) else 'link_unauthorized'}}"
|
<a class="stdlink {{'link_accessible' if current_user.has_permission(Permission.ScoView, dept=dept.acronym) else 'link_unauthorized'}}"
|
||||||
href="{{url_for('scolar.index_html', scodoc_dept=dept.acronym)}}">Département
|
href="{{url_for('scolar.index_html', scodoc_dept=dept.acronym)}}">Département
|
||||||
{{dept.preferences.filter_by(name="DeptName").first().value}}</a>
|
{{dept.preferences.filter_by(name="DeptName").first().value}}</a>
|
||||||
|
{% if current_user.is_administrator() %}
|
||||||
|
<span class="dept_visibility">
|
||||||
|
{% if dept.visible %}visible{% else %}caché aux utilisateurs{% endif %}
|
||||||
|
<a href="{{ url_for('scodoc.toggle_dept_vis', dept_id=dept.id) }}">
|
||||||
|
{% if dept.visible %}cacher{% else %}rendre visible{% endif %}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>
|
<li>
|
||||||
<b>Aucun département défini !</b>
|
<b>Aucun département défini !</b>
|
||||||
|
@ -53,6 +53,7 @@ from wtforms.fields.simple import BooleanField, StringField, TextAreaField, Hidd
|
|||||||
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
|
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
|
||||||
|
|
||||||
import app
|
import app
|
||||||
|
from app import db
|
||||||
from app.forms.main import config_forms
|
from app.forms.main import config_forms
|
||||||
from app.forms.main.create_dept import CreateDeptForm
|
from app.forms.main.create_dept import CreateDeptForm
|
||||||
from app.models import Departement, Identite
|
from app.models import Departement, Identite
|
||||||
@ -82,9 +83,7 @@ from PIL import Image as PILImage
|
|||||||
@bp.route("/ScoDoc/index")
|
@bp.route("/ScoDoc/index")
|
||||||
def index():
|
def index():
|
||||||
"Page d'accueil: liste des départements"
|
"Page d'accueil: liste des départements"
|
||||||
depts = (
|
depts = Departement.query.filter_by().order_by(Departement.acronym).all()
|
||||||
Departement.query.filter_by(visible=True).order_by(Departement.acronym).all()
|
|
||||||
)
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"scodoc.html",
|
"scodoc.html",
|
||||||
title=sco_version.SCONAME,
|
title=sco_version.SCONAME,
|
||||||
@ -108,7 +107,7 @@ def create_dept():
|
|||||||
if request.method == "POST" and form.cancel.data: # cancel button
|
if request.method == "POST" and form.cancel.data: # cancel button
|
||||||
return redirect(url_for("scodoc.index"))
|
return redirect(url_for("scodoc.index"))
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
departements.create_dept(form.acronym.data)
|
departements.create_dept(form.acronym.data, visible=form.visible.data)
|
||||||
flash(f"Département {form.acronym.data} créé.")
|
flash(f"Département {form.acronym.data} créé.")
|
||||||
return redirect(url_for("scodoc.index"))
|
return redirect(url_for("scodoc.index"))
|
||||||
return render_template(
|
return render_template(
|
||||||
@ -118,6 +117,17 @@ def create_dept():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/ScoDoc/toggle_dept_vis/<dept_id>", methods=["GET", "POST"])
|
||||||
|
@admin_required
|
||||||
|
def toggle_dept_vis(dept_id):
|
||||||
|
"""Cache ou rend visible un dept"""
|
||||||
|
dept = Departement.query.get_or_404(dept_id)
|
||||||
|
dept.visible = not dept.visible
|
||||||
|
db.session.add(dept)
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for("scodoc.index"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/ScoDoc/table_etud_in_accessible_depts", methods=["POST"])
|
@bp.route("/ScoDoc/table_etud_in_accessible_depts", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def table_etud_in_accessible_depts():
|
def table_etud_in_accessible_depts():
|
||||||
|
@ -152,7 +152,6 @@ def user_info(user_name, format="json"):
|
|||||||
def create_user_form(user_name=None, edit=0, all_roles=1):
|
def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||||
"form. création ou edition utilisateur"
|
"form. création ou edition utilisateur"
|
||||||
auth_dept = current_user.dept
|
auth_dept = current_user.dept
|
||||||
auth_username = current_user.user_name
|
|
||||||
from_mail = current_user.email
|
from_mail = current_user.email
|
||||||
initvalues = {}
|
initvalues = {}
|
||||||
edit = int(edit)
|
edit = int(edit)
|
||||||
@ -204,7 +203,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
|||||||
administrable_dept_acronyms = sorted(
|
administrable_dept_acronyms = sorted(
|
||||||
set(
|
set(
|
||||||
[
|
[
|
||||||
x.dept
|
x.dept or ""
|
||||||
for x in UserRole.query.filter_by(user=current_user)
|
for x in UserRole.query.filter_by(user=current_user)
|
||||||
if x.role.has_permission(Permission.ScoUsersAdmin) and x.dept
|
if x.role.has_permission(Permission.ScoUsersAdmin) and x.dept
|
||||||
]
|
]
|
||||||
@ -249,7 +248,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
|||||||
r.name + "_" + (dept or "") for (r, dept) in displayed_roles
|
r.name + "_" + (dept or "") for (r, dept) in displayed_roles
|
||||||
]
|
]
|
||||||
displayed_roles_labels = [f"{dept}: {r.name}" for (r, dept) in displayed_roles]
|
displayed_roles_labels = [f"{dept}: {r.name}" for (r, dept) in displayed_roles]
|
||||||
disabled_roles = {} # pour desactiver les roles que l'on ne peut pas editer
|
disabled_roles = {} # pour désactiver les roles que l'on ne peut pas éditer
|
||||||
for i in range(len(displayed_roles_strings)):
|
for i in range(len(displayed_roles_strings)):
|
||||||
if displayed_roles_strings[i] not in editable_roles_strings:
|
if displayed_roles_strings[i] not in editable_roles_strings:
|
||||||
disabled_roles[i] = True
|
disabled_roles[i] = True
|
||||||
@ -375,7 +374,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
|||||||
can_choose_dept = True
|
can_choose_dept = True
|
||||||
else:
|
else:
|
||||||
selectable_dept_acronyms = set(administrable_dept_acronyms)
|
selectable_dept_acronyms = set(administrable_dept_acronyms)
|
||||||
if edit: # ajoute dept actuel de l'utilisateur
|
if edit and the_user.dept is not None: # ajoute dept actuel de l'utilisateur
|
||||||
selectable_dept_acronyms |= {the_user.dept}
|
selectable_dept_acronyms |= {the_user.dept}
|
||||||
if len(selectable_dept_acronyms) > 1:
|
if len(selectable_dept_acronyms) > 1:
|
||||||
can_choose_dept = True
|
can_choose_dept = True
|
||||||
|
@ -274,22 +274,10 @@ def test_formations(test_client):
|
|||||||
# --- Suppression du module, matiere et ue test du semestre 2
|
# --- Suppression du module, matiere et ue test du semestre 2
|
||||||
|
|
||||||
# on doit d'abbord supprimer le semestre
|
# on doit d'abbord supprimer le semestre
|
||||||
|
|
||||||
# sco_formsemestre_edit.formsemestre_delete( formsemestre_id=sem2["formsemestre_id"])
|
|
||||||
# sco_formsemestre_edit.formsemestre_createwithmodules( formsemestre_id=sem2["formsemestre_id"])
|
|
||||||
|
|
||||||
# RIEN NE SE PASSE AVEC CES FONCTIONS
|
|
||||||
|
|
||||||
sco_formsemestre_edit.do_formsemestre_delete(
|
sco_formsemestre_edit.do_formsemestre_delete(
|
||||||
formsemestre_id=sem2["formsemestre_id"]
|
formsemestre_id=sem2["formsemestre_id"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# sco_edit_module.module_delete( module_id=modt["module_id"])
|
|
||||||
# sco_edit_matiere.matiere_delete( matiere_id=matt["matiere_id"])
|
|
||||||
# sco_edit_ue.ue_delete( ue_id=uet["ue_id"])
|
|
||||||
|
|
||||||
# RIEN NE SE PASSE AVEC CES FONCTIONS
|
|
||||||
|
|
||||||
li_module = sco_edit_module.module_list()
|
li_module = sco_edit_module.module_list()
|
||||||
assert len(li_module) == 4
|
assert len(li_module) == 4
|
||||||
sco_edit_module.do_module_delete(oid=modt["module_id"]) # on supprime le semestre
|
sco_edit_module.do_module_delete(oid=modt["module_id"]) # on supprime le semestre
|
||||||
|
Loading…
Reference in New Issue
Block a user