forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -52,7 +52,7 @@ class ScoDocModel(db.Model):
|
||||
def create_from_dict(cls, data: dict) -> "ScoDocModel":
|
||||
"""Create a new instance of the model with attributes given in dict.
|
||||
The instance is added to the session (but not flushed nor committed).
|
||||
Use only relevant arributes for the given model and ignore others.
|
||||
Use only relevant attributes for the given model and ignore others.
|
||||
"""
|
||||
if data:
|
||||
args = cls.convert_dict_fields(cls.filter_model_attributes(data))
|
||||
|
@ -742,6 +742,7 @@ def check_etud_duplicate_code(args, code_name, edit=True):
|
||||
Raises ScoGenError si problème.
|
||||
"""
|
||||
etudid = args.get("etudid", None)
|
||||
assert (not edit) or (etudid is not None) # si edit, etudid doit être spécifié
|
||||
if not args.get(code_name, None):
|
||||
return
|
||||
etuds = Identite.query.filter_by(
|
||||
@ -749,9 +750,7 @@ def check_etud_duplicate_code(args, code_name, edit=True):
|
||||
).all()
|
||||
duplicate = False
|
||||
if edit:
|
||||
duplicate = (len(etuds) > 1) or (
|
||||
(len(etuds) == 1) and etuds[0].id != args["etudid"]
|
||||
)
|
||||
duplicate = (len(etuds) > 1) or ((len(etuds) == 1) and etuds[0].id != etudid)
|
||||
else:
|
||||
duplicate = len(etuds) > 0
|
||||
if duplicate:
|
||||
|
@ -3,12 +3,13 @@
|
||||
"""
|
||||
import pandas as pd
|
||||
from flask import abort, g
|
||||
from flask_login import current_user
|
||||
from flask_sqlalchemy.query import Query
|
||||
|
||||
from app import db
|
||||
from app.auth.models import User
|
||||
from app.comp import df_cache
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import APO_CODE_STR_LEN, ScoDocModel
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.evaluations import Evaluation
|
||||
from app.models.modules import Module
|
||||
@ -17,7 +18,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
|
||||
class ModuleImpl(db.Model):
|
||||
class ModuleImpl(ScoDocModel):
|
||||
"""Mise en oeuvre d'un module pour une annee/semestre"""
|
||||
|
||||
__tablename__ = "notes_moduleimpl"
|
||||
@ -52,7 +53,6 @@ class ModuleImpl(db.Model):
|
||||
secondary="notes_modules_enseignants",
|
||||
lazy="dynamic",
|
||||
backref="moduleimpl",
|
||||
viewonly=True,
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
@ -85,7 +85,7 @@ class ModuleImpl(db.Model):
|
||||
|
||||
@classmethod
|
||||
def get_modimpl(cls, moduleimpl_id: int | str, dept_id: int = None) -> "ModuleImpl":
|
||||
"""FormSemestre ou 404, cherche uniquement dans le département spécifié ou le courant."""
|
||||
"""ModuleImpl ou 404, cherche uniquement dans le département spécifié ou le courant."""
|
||||
from app.models.formsemestre import FormSemestre
|
||||
|
||||
if not isinstance(moduleimpl_id, int):
|
||||
@ -187,7 +187,7 @@ class ModuleImpl(db.Model):
|
||||
return allow_ens and user.id in (ens.id for ens in self.enseignants)
|
||||
return True
|
||||
|
||||
def can_change_ens_by(self, user: User, raise_exc=False) -> bool:
|
||||
def can_change_responsable(self, user: User, raise_exc=False) -> bool:
|
||||
"""Check if user can modify module resp.
|
||||
If raise_exc, raises exception (AccessDenied or ScoLockedSemError) if not.
|
||||
= Admin, et dir des etud. (si option l'y autorise)
|
||||
@ -208,6 +208,27 @@ class ModuleImpl(db.Model):
|
||||
raise AccessDenied(f"Modification impossible pour {user}")
|
||||
return False
|
||||
|
||||
def can_change_ens(self, user: User | None = None, raise_exc=True) -> bool:
|
||||
"""check if user can modify ens list (raise exception if not)"
|
||||
if user is None, current user.
|
||||
"""
|
||||
user = current_user if user is None else user
|
||||
if not self.formsemestre.etat:
|
||||
if raise_exc:
|
||||
raise ScoLockedSemError("Modification impossible: semestre verrouille")
|
||||
return False
|
||||
# -- check access
|
||||
# admin, resp. module ou resp. semestre
|
||||
if (
|
||||
user.id != self.responsable_id
|
||||
and not user.has_permission(Permission.EditFormSemestre)
|
||||
and user.id not in (u.id for u in self.formsemestre.responsables)
|
||||
):
|
||||
if raise_exc:
|
||||
raise AccessDenied(f"Modification impossible pour {user}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def est_inscrit(self, etud: Identite) -> bool:
|
||||
"""
|
||||
Vérifie si l'étudiant est bien inscrit au moduleimpl (même si DEM ou DEF au semestre).
|
||||
|
@ -33,7 +33,7 @@ from flask import g, request
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db
|
||||
from app.models import Evaluation, GroupDescr, ModuleImpl, Partition
|
||||
from app.models import Evaluation, GroupDescr, Identite, ModuleImpl, Partition
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
@ -160,26 +160,31 @@ def sidebar(etudid: int = None):
|
||||
etudid = request.form.get("etudid", None)
|
||||
|
||||
if etudid is not None:
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
params.update(etud)
|
||||
params["fiche_url"] = url_for(
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)
|
||||
etud = Identite.get_etud(etudid)
|
||||
# compte les absences du semestre en cours
|
||||
H.append(
|
||||
"""<h2 id="insidebar-etud"><a href="%(fiche_url)s" class="sidebar">
|
||||
<font color="#FF0000">%(civilite_str)s %(nom_disp)s</font></a>
|
||||
f"""<h2 id="insidebar-etud"><a href="{
|
||||
url_for(
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)
|
||||
}" class="sidebar">
|
||||
<font color="#FF0000">{etud.civilite_str} {etud.nom_disp()}</font></a>
|
||||
</h2>
|
||||
<b>Absences</b>"""
|
||||
% params
|
||||
)
|
||||
if etud["cursem"]:
|
||||
cur_sem = etud["cursem"]
|
||||
nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, cur_sem)
|
||||
inscription = etud.inscription_courante()
|
||||
if inscription:
|
||||
formsemestre = inscription.formsemestre
|
||||
nbabs, nbabsjust = sco_assiduites.formsemestre_get_assiduites_count(
|
||||
etudid, formsemestre
|
||||
)
|
||||
nbabsnj = nbabs - nbabsjust
|
||||
H.append(
|
||||
f"""<span title="absences du { cur_sem["date_debut"] } au {
|
||||
cur_sem["date_fin"] }">({
|
||||
f"""<span title="absences du {
|
||||
formsemestre.date_debut.strftime("%d/%m/%Y")
|
||||
} au {
|
||||
formsemestre.date_fin.strftime("%d/%m/%Y")
|
||||
}">({
|
||||
sco_preferences.get_preference("assi_metrique", None)})
|
||||
<br>{ nbabsjust } J., { nbabsnj } N.J.</span>"""
|
||||
)
|
||||
@ -189,10 +194,12 @@ def sidebar(etudid: int = None):
|
||||
cur_formsemestre_id = retreive_formsemestre_from_request()
|
||||
H.append(
|
||||
f"""
|
||||
<li><a href="{ url_for('assiduites.ajout_assiduite_etud',
|
||||
<li><a href="{
|
||||
url_for('assiduites.ajout_assiduite_etud',
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">Ajouter</a></li>
|
||||
<li><a href="{ url_for('assiduites.ajout_justificatif_etud',
|
||||
<li><a href="{
|
||||
url_for('assiduites.ajout_justificatif_etud',
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid,
|
||||
formsemestre_id=cur_formsemestre_id,
|
||||
)
|
||||
@ -201,7 +208,8 @@ def sidebar(etudid: int = None):
|
||||
)
|
||||
if sco_preferences.get_preference("handle_billets_abs"):
|
||||
H.append(
|
||||
f"""<li><a href="{ url_for('absences.billets_etud',
|
||||
f"""<li><a href="{
|
||||
url_for('absences.billets_etud',
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">Billets</a></li>"""
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -268,7 +268,7 @@ def abs_notification_message(
|
||||
"""
|
||||
from app.scodoc import sco_bulletins
|
||||
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
etud = Identite.get_etud(etudid)
|
||||
|
||||
# Variables accessibles dans les balises du template: %(nom_variable)s :
|
||||
values = sco_bulletins.make_context_dict(formsemestre, etud)
|
||||
@ -287,7 +287,7 @@ def abs_notification_message(
|
||||
log("abs_notification_message: empty template, not sending message")
|
||||
return None
|
||||
|
||||
subject = f"""[ScoDoc] Trop d'absences pour {etud["nomprenom"]}"""
|
||||
subject = f"""[ScoDoc] Trop d'absences pour {etud.nomprenom}"""
|
||||
msg = Message(subject, sender=email.get_from_addr(formsemestre.departement.acronym))
|
||||
msg.body = txt
|
||||
return msg
|
||||
|
@ -138,21 +138,18 @@ def etud_upload_file_form(etudid):
|
||||
"""Page with a form to choose and upload a file, with a description."""
|
||||
# check permission
|
||||
if not can_edit_etud_archive(current_user):
|
||||
raise AccessDenied("opération non autorisée pour %s" % current_user)
|
||||
etuds = sco_etud.get_etud_info(filled=True)
|
||||
if not etuds:
|
||||
raise ScoValueError("étudiant inexistant")
|
||||
etud = etuds[0]
|
||||
raise AccessDenied(f"opération non autorisée pour {current_user}")
|
||||
etud = Identite.get_etud(etudid)
|
||||
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Chargement d'un document associé à %(nomprenom)s" % etud,
|
||||
page_title=f"Chargement d'un document associé à {etud.nomprenom}",
|
||||
),
|
||||
"""<h2>Chargement d'un document associé à %(nomprenom)s</h2>
|
||||
"""
|
||||
% etud,
|
||||
"""<p>Le fichier ne doit pas dépasser %sMo.</p>
|
||||
"""
|
||||
% (scu.CONFIG.ETUD_MAX_FILE_SIZE // (1024 * 1024)),
|
||||
f"""<h2>Chargement d'un document associé à {etud.nomprenom}</h2>
|
||||
|
||||
<p>Le fichier ne doit pas dépasser {
|
||||
scu.CONFIG.ETUD_MAX_FILE_SIZE // (1024 * 1024)}Mo.</p>
|
||||
""",
|
||||
]
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
@ -176,20 +173,13 @@ def etud_upload_file_form(etudid):
|
||||
if tf[0] == 0:
|
||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
else:
|
||||
return flask.redirect(etud.url_fiche())
|
||||
data = tf[2]["datafile"].read()
|
||||
descr = tf[2]["description"]
|
||||
filename = tf[2]["datafile"].filename
|
||||
etud_archive_id = etud["etudid"]
|
||||
_store_etud_file_to_new_archive(
|
||||
etud_archive_id, data, filename, description=descr
|
||||
)
|
||||
return flask.redirect(
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
etud_archive_id = (etudid,)
|
||||
_store_etud_file_to_new_archive(etud_archive_id, data, filename, description=descr)
|
||||
return flask.redirect(etud.url_fiche())
|
||||
|
||||
|
||||
def _store_etud_file_to_new_archive(
|
||||
@ -209,23 +199,20 @@ def etud_delete_archive(etudid, archive_name, dialog_confirmed=False):
|
||||
# check permission
|
||||
if not can_edit_etud_archive(current_user):
|
||||
raise AccessDenied(f"opération non autorisée pour {current_user}")
|
||||
etuds = sco_etud.get_etud_info(filled=True)
|
||||
if not etuds:
|
||||
raise ScoValueError("étudiant inexistant")
|
||||
etud = etuds[0]
|
||||
etud_archive_id = etud["etudid"]
|
||||
etud = Identite.get_etud(etudid)
|
||||
etud_archive_id = etudid
|
||||
archive_id = ETUDS_ARCHIVER.get_id_from_name(
|
||||
etud_archive_id, archive_name, dept_id=etud["dept_id"]
|
||||
etud_archive_id, archive_name, dept_id=etud.dept_id
|
||||
)
|
||||
if not dialog_confirmed:
|
||||
return scu.confirm_dialog(
|
||||
"""<h2>Confirmer la suppression des fichiers ?</h2>
|
||||
<p>Fichier associé le %s à l'étudiant %s</p>
|
||||
<p>La suppression sera définitive.</p>"""
|
||||
% (
|
||||
ETUDS_ARCHIVER.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M"),
|
||||
etud["nomprenom"],
|
||||
),
|
||||
f"""<h2>Confirmer la suppression des fichiers ?</h2>
|
||||
<p>Fichier associé le {
|
||||
ETUDS_ARCHIVER.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M")
|
||||
} à l'étudiant {etud.nomprenom}
|
||||
</p>
|
||||
<p>La suppression sera définitive.</p>
|
||||
""",
|
||||
dest_url="",
|
||||
cancel_url=url_for(
|
||||
"scolar.fiche_etud",
|
||||
@ -236,22 +223,17 @@ def etud_delete_archive(etudid, archive_name, dialog_confirmed=False):
|
||||
parameters={"etudid": etudid, "archive_name": archive_name},
|
||||
)
|
||||
|
||||
ETUDS_ARCHIVER.delete_archive(archive_id, dept_id=etud["dept_id"])
|
||||
ETUDS_ARCHIVER.delete_archive(archive_id, dept_id=etud.dept_id)
|
||||
flash("Archive supprimée")
|
||||
return flask.redirect(
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
return flask.redirect(etud.url_fiche())
|
||||
|
||||
|
||||
def etud_get_archived_file(etudid, archive_name, filename):
|
||||
"""Send file to client."""
|
||||
etuds = sco_etud.get_etud_info(etudid=etudid, filled=True)
|
||||
if not etuds:
|
||||
raise ScoValueError("étudiant inexistant")
|
||||
etud = etuds[0]
|
||||
etud_archive_id = etud["etudid"]
|
||||
etud = Identite.get_etud(etudid)
|
||||
etud_archive_id = etud.id
|
||||
return ETUDS_ARCHIVER.get_archived_file(
|
||||
etud_archive_id, archive_name, filename, dept_id=etud["dept_id"]
|
||||
etud_archive_id, archive_name, filename, dept_id=etud.dept_id
|
||||
)
|
||||
|
||||
|
||||
|
@ -1273,29 +1273,24 @@ def do_formsemestre_clone(
|
||||
log(f"created formsemestre {formsemestre_id}")
|
||||
formsemestre: FormSemestre = db.session.get(FormSemestre, formsemestre_id)
|
||||
# 2- create moduleimpls
|
||||
mods_orig = sco_moduleimpl.moduleimpl_list(formsemestre_id=orig_formsemestre_id)
|
||||
for mod_orig in mods_orig:
|
||||
args = mod_orig.copy()
|
||||
modimpl_orig: ModuleImpl
|
||||
for modimpl_orig in formsemestre_orig.modimpls:
|
||||
args = modimpl_orig.to_dict(with_module=False)
|
||||
args["formsemestre_id"] = formsemestre_id
|
||||
mid = sco_moduleimpl.do_moduleimpl_create(args)
|
||||
# copy notes_modules_enseignants
|
||||
ens = sco_moduleimpl.do_ens_list(
|
||||
args={"moduleimpl_id": mod_orig["moduleimpl_id"]}
|
||||
)
|
||||
for e in ens:
|
||||
args = e.copy()
|
||||
args["moduleimpl_id"] = mid
|
||||
sco_moduleimpl.do_ens_create(args)
|
||||
modimpl_new = ModuleImpl.create_from_dict(args)
|
||||
db.session.flush()
|
||||
# copy enseignants
|
||||
for ens in modimpl_orig.enseignants:
|
||||
modimpl_new.enseignants.append(ens)
|
||||
db.session.add(modimpl_new)
|
||||
# optionally, copy evaluations
|
||||
if clone_evaluations:
|
||||
for e in Evaluation.query.filter_by(
|
||||
moduleimpl_id=mod_orig["moduleimpl_id"]
|
||||
):
|
||||
for e in Evaluation.query.filter_by(moduleimpl_id=modimpl_orig.id):
|
||||
# copie en enlevant la date
|
||||
new_eval = e.clone(
|
||||
not_copying=("date_debut", "date_fin", "moduleimpl_id")
|
||||
)
|
||||
new_eval.moduleimpl_id = mid
|
||||
new_eval.moduleimpl_id = modimpl_new.id
|
||||
# Copie les poids APC de l'évaluation
|
||||
new_eval.set_ue_poids_dict(e.get_ue_poids_dict())
|
||||
db.session.commit()
|
||||
|
@ -37,7 +37,6 @@ from app.models import Formation
|
||||
from app.scodoc import scolog
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_cache
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_exceptions import ScoValueError, AccessDenied
|
||||
@ -362,45 +361,3 @@ def do_ens_create(args):
|
||||
cnx = ndb.GetDBConnexion()
|
||||
r = _modules_enseignantsEditor.create(cnx, args)
|
||||
return r
|
||||
|
||||
|
||||
def can_change_module_resp(moduleimpl_id):
|
||||
"""Check if current user can modify module resp. (raise exception if not).
|
||||
= Admin, et dir des etud. (si option l'y autorise)
|
||||
"""
|
||||
M = moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
|
||||
# -- check lock
|
||||
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
# -- check access
|
||||
# admin ou resp. semestre avec flag resp_can_change_resp
|
||||
if not current_user.has_permission(Permission.EditFormSemestre) and (
|
||||
(current_user.id not in sem["responsables"]) or (not sem["resp_can_change_ens"])
|
||||
):
|
||||
raise AccessDenied(f"Modification impossible pour {current_user}")
|
||||
return M, sem
|
||||
|
||||
|
||||
def can_change_ens(moduleimpl_id, raise_exc=True):
|
||||
"check if current user can modify ens list (raise exception if not)"
|
||||
M = moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
|
||||
# -- check lock
|
||||
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
|
||||
if not sem["etat"]:
|
||||
if raise_exc:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
else:
|
||||
return False
|
||||
# -- check access
|
||||
# admin, resp. module ou resp. semestre
|
||||
if (
|
||||
current_user.id != M["responsable_id"]
|
||||
and not current_user.has_permission(Permission.EditFormSemestre)
|
||||
and (current_user.id not in sem["responsables"])
|
||||
):
|
||||
if raise_exc:
|
||||
raise AccessDenied("Modification impossible pour %s" % current_user)
|
||||
else:
|
||||
return False
|
||||
return M, sem
|
||||
|
@ -244,7 +244,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
<span class="blacktt">({module_resp.user_name})</span>
|
||||
""",
|
||||
]
|
||||
if modimpl.can_change_ens_by(current_user):
|
||||
if modimpl.can_change_responsable(current_user):
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{url_for("notes.edit_moduleimpl_resp",
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id)
|
||||
@ -253,14 +253,15 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
H.append("""</td><td>""")
|
||||
H.append(", ".join([u.get_nomprenom() for u in modimpl.enseignants]))
|
||||
H.append("""</td><td>""")
|
||||
try:
|
||||
sco_moduleimpl.can_change_ens(moduleimpl_id)
|
||||
if modimpl.can_change_ens(raise_exc=False):
|
||||
H.append(
|
||||
"""<a class="stdlink" href="edit_enseignants_form?moduleimpl_id=%s">modifier les enseignants</a>"""
|
||||
% moduleimpl_id
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.edit_enseignants_form",
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id
|
||||
)
|
||||
except:
|
||||
pass
|
||||
}">modifier les enseignants</a>"""
|
||||
)
|
||||
|
||||
H.append("""</td></tr>""")
|
||||
|
||||
# 2ieme ligne: Semestre, Coef
|
||||
|
@ -961,12 +961,15 @@ def formsemestre_custommenu_edit(formsemestre_id):
|
||||
@scodoc7func
|
||||
def edit_enseignants_form(moduleimpl_id):
|
||||
"modif liste enseignants/moduleimpl"
|
||||
M, sem = sco_moduleimpl.can_change_ens(moduleimpl_id)
|
||||
modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
|
||||
modimpl.can_change_ens(raise_exc=True)
|
||||
# --
|
||||
header = html_sco_header.html_sem_header(
|
||||
'Enseignants du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>'
|
||||
% (moduleimpl_id, M["module"]["titre"]),
|
||||
page_title="Enseignants du module %s" % M["module"]["titre"],
|
||||
f"""Enseignants du <a href="{
|
||||
url_for("notes.moduleimpl_status",
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
|
||||
}">module {modimpl.module.titre or modimpl.module.code}</a>""",
|
||||
page_title=f"Enseignants du module {modimpl.module.titre or modimpl.module.code}",
|
||||
javascripts=["libjs/AutoSuggest.js"],
|
||||
cssstyles=["css/autosuggest_inquisitor.css"],
|
||||
bodyOnLoad="init_tf_form('')",
|
||||
@ -981,21 +984,18 @@ def edit_enseignants_form(moduleimpl_id):
|
||||
allowed_user_names = list(uid2display.values())
|
||||
|
||||
H = [
|
||||
"<ul><li><b>%s</b> (responsable)</li>"
|
||||
% uid2display.get(M["responsable_id"], M["responsable_id"])
|
||||
f"""<ul><li><b>{
|
||||
uid2display.get(modimpl.responsable_id, modimpl.responsable_id)
|
||||
}</b> (responsable)</li>"""
|
||||
]
|
||||
for ens in M["ens"]:
|
||||
u = db.session.get(User, ens["ens_id"])
|
||||
if u:
|
||||
nom = u.get_nomcomplet()
|
||||
else:
|
||||
nom = "? (compte inconnu)"
|
||||
u: User
|
||||
for u in modimpl.enseignants:
|
||||
H.append(
|
||||
f"""
|
||||
<li>{nom} (<a class="stdlink" href="{
|
||||
<li>{u.get_nomcomplet()} (<a class="stdlink" href="{
|
||||
url_for('notes.edit_enseignants_form_delete',
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id,
|
||||
ens_id=ens["ens_id"])
|
||||
ens_id=u.id)
|
||||
}">supprimer</a>)
|
||||
</li>"""
|
||||
)
|
||||
@ -1006,7 +1006,7 @@ def edit_enseignants_form(moduleimpl_id):
|
||||
<p class="help">Pour changer le responsable du module, passez par la
|
||||
page "<a class="stdlink" href="{
|
||||
url_for("notes.formsemestre_editwithmodules", scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=M["formsemestre_id"])
|
||||
formsemestre_id=modimpl.formsemestre_id)
|
||||
}">Modification du semestre</a>",
|
||||
accessible uniquement au responsable de la formation (chef de département)
|
||||
</p>
|
||||
@ -1061,8 +1061,8 @@ def edit_enseignants_form(moduleimpl_id):
|
||||
else:
|
||||
# et qu'il n'est pas deja:
|
||||
if (
|
||||
ens_id in [x["ens_id"] for x in M["ens"]]
|
||||
or ens_id == M["responsable_id"]
|
||||
ens_id in (x.id for x in modimpl.enseignants)
|
||||
or ens_id == modimpl.responsable_id
|
||||
):
|
||||
H.append(
|
||||
f"""<p class="help">Enseignant {ens_id} déjà dans la liste !</p>"""
|
||||
@ -1090,7 +1090,7 @@ def edit_moduleimpl_resp(moduleimpl_id: int):
|
||||
Accessible par Admin et dir des etud si flag resp_can_change_ens
|
||||
"""
|
||||
modimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id)
|
||||
modimpl.can_change_ens_by(current_user, raise_exc=True) # access control
|
||||
modimpl.can_change_responsable(current_user, raise_exc=True) # access control
|
||||
H = [
|
||||
html_sco_header.html_sem_header(
|
||||
f"""Modification du responsable du <a href="{
|
||||
@ -1372,22 +1372,17 @@ def edit_enseignants_form_delete(moduleimpl_id, ens_id: int):
|
||||
|
||||
ens_id: user.id
|
||||
"""
|
||||
M, _ = sco_moduleimpl.can_change_ens(moduleimpl_id)
|
||||
modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
|
||||
modimpl.can_change_ens(raise_exc=True)
|
||||
# search ens_id
|
||||
ok = False
|
||||
for ens in M["ens"]:
|
||||
if ens["ens_id"] == ens_id:
|
||||
ok = True
|
||||
ens: User | None = None
|
||||
for ens in modimpl.enseignants:
|
||||
if ens.id == ens_id:
|
||||
break
|
||||
if not ok:
|
||||
if ens is None:
|
||||
raise ScoValueError(f"invalid ens_id ({ens_id})")
|
||||
ndb.SimpleQuery(
|
||||
"""DELETE FROM notes_modules_enseignants
|
||||
WHERE moduleimpl_id = %(moduleimpl_id)s
|
||||
AND ens_id = %(ens_id)s
|
||||
""",
|
||||
{"moduleimpl_id": moduleimpl_id, "ens_id": ens_id},
|
||||
)
|
||||
modimpl.enseignants.remove(ens)
|
||||
db.session.commit()
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"notes.edit_enseignants_form",
|
||||
@ -1399,18 +1394,6 @@ def edit_enseignants_form_delete(moduleimpl_id, ens_id: int):
|
||||
|
||||
# --- Gestion des inscriptions aux semestres
|
||||
|
||||
# Ancienne API, pas certain de la publier en ScoDoc8
|
||||
# sco_publish(
|
||||
# "/do_formsemestre_inscription_create",
|
||||
# sco_formsemestre_inscriptions.do_formsemestre_inscription_create,
|
||||
# Permission.EtudInscrit,
|
||||
# )
|
||||
# sco_publish(
|
||||
# "/do_formsemestre_inscription_edit",
|
||||
# sco_formsemestre_inscriptions.do_formsemestre_inscription_edit,
|
||||
# Permission.EtudInscrit,
|
||||
# )
|
||||
|
||||
sco_publish(
|
||||
"/do_formsemestre_inscription_list",
|
||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_list,
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.6.92"
|
||||
SCOVERSION = "9.6.93"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user