')
- idx = 0
- for idx in range(len(self.formdescription)):
- (field, descr) = self.formdescription[idx]
+ for field, descr in self.formdescription:
if descr.get("readonly", False):
R.append(self._ReadOnlyElement(field, descr))
continue
@@ -408,7 +410,7 @@ class TF(object):
input_type = descr.get("input_type", "text")
item_dom_id = descr.get("dom_id", "")
if item_dom_id:
- item_dom_attr = ' id="%s"' % item_dom_id
+ item_dom_attr = f' id="{item_dom_id}"'
else:
item_dom_attr = ""
# choix du template
@@ -523,7 +525,6 @@ class TF(object):
else:
checked = ""
else: # boolcheckbox
- # open('/tmp/toto','a').write('GenForm: values[%s] = %s (%s)\n' % (field, values[field], type(values[field])))
if values[field] == "True":
v = True
elif values[field] == "False":
diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py
index db368edd..38126145 100644
--- a/app/scodoc/sco_edit_module.py
+++ b/app/scodoc/sco_edit_module.py
@@ -365,6 +365,7 @@ def module_edit(
"libjs/jQuery-tagEditor/jquery.tag-editor.min.js",
"libjs/jQuery-tagEditor/jquery.caret.min.js",
"js/module_tag_editor.js",
+ "js/module_edit.js",
],
),
f"""{title} """,
@@ -605,8 +606,7 @@ def module_edit(
"input_type": "menu",
"type": "int",
"title": parcours.SESSION_NAME.capitalize(),
- "explanation": "%s de début du module dans la formation standard"
- % parcours.SESSION_NAME,
+ "explanation": f"{parcours.SESSION_NAME} de début du module dans la formation standard",
"labels": [str(x) for x in semestres_indices],
"allowed_values": semestres_indices,
"enabled": unlocked,
@@ -619,7 +619,7 @@ def module_edit(
{
"title": "Code Apogée",
"size": 25,
- "explanation": """(optionnel) code élément pédagogique Apogée ou liste de codes ELP
+ "explanation": """(optionnel) code élément pédagogique Apogée ou liste de codes ELP
séparés par des virgules (ce code est propre à chaque établissement, se rapprocher
du référent Apogée).
""",
@@ -648,11 +648,15 @@ def module_edit(
"input_type": "checkbox",
"vertical": True,
"dom_id": "tf_module_parcours",
- "labels": [parcour.libelle for parcour in ref_comp.parcours],
+ "labels": [parcour.libelle for parcour in ref_comp.parcours]
+ + ["Tous (tronc commun)"],
"allowed_values": [
str(parcour.id) for parcour in ref_comp.parcours
- ],
- "explanation": "parcours dans lesquels est utilisé ce module.",
+ ]
+ + ["-1"],
+ "explanation": """Parcours dans lesquels est utilisé ce module.
+ Attention: si le module ne doit pas avoir les mêmes coefficients suivant le parcours,
+ il faut en créer plusieurs versions, car dans ScoDoc chaque module a ses coefficients.""",
},
)
]
@@ -677,12 +681,17 @@ def module_edit(
"vertical": True,
"dom_id": "tf_module_app_critiques",
"labels": [
- app_crit.libelle for app_crit in app_critiques
+ f"{app_crit.code} {app_crit.libelle}"
+ for app_crit in app_critiques
],
"allowed_values": [
str(app_crit.id) for app_crit in app_critiques
],
- "explanation": "apprentissages critiques liés à ce module.",
+ "html_data": [],
+ "explanation": """Apprentissages Critiques liés à ce module.
+ (si vous changez le semestre, revenez ensuite sur cette page
+ pour associer les AC.)
+ """,
},
)
]
@@ -693,7 +702,9 @@ def module_edit(
{
"input_type": "separator",
"title": f"""{scu.EMO_WARNING }
- L'UE {ue.acronyme} {ue.titre}
+ L'UE {ue.acronyme} {ue.titre}
n'est pas associée à un niveau de compétences
""",
},
@@ -727,9 +738,10 @@ def module_edit(
request.base_url,
scu.get_request_args(),
descr,
- html_foot_markup="""
""".format(
- module_id, ",".join(sco_tag_module.module_tag_list(module_id))
- )
+ html_foot_markup=f"""
+ """
if not create
else "",
initvalues=module_dict if module else {},
@@ -793,11 +805,14 @@ def module_edit(
#
do_module_edit(tf[2])
# Modifie les parcours
- if "parcours" in tf[2]:
- module.parcours = [
- ApcParcours.query.get(int(parcour_id_str))
- for parcour_id_str in tf[2]["parcours"]
- ]
+ if ("parcours" in tf[2]) and formation.referentiel_competence:
+ if "-1" in tf[2]["parcours"]: # "tous"
+ module.parcours = formation.referentiel_competence.parcours.all()
+ else:
+ module.parcours = [
+ ApcParcours.query.get(int(parcour_id_str))
+ for parcour_id_str in tf[2]["parcours"]
+ ]
# Modifie les AC
if "app_critiques" in tf[2]:
module.app_critiques = [
@@ -811,7 +826,7 @@ def module_edit(
"notes.ue_table",
scodoc_dept=g.scodoc_dept,
formation_id=formation.id,
- semestre_idx=tf[2]["semestre_id"],
+ semestre_idx=tf[2]["semestre_id"] if is_apc else 1,
)
)
diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py
index 3ccba772..1acf5b95 100644
--- a/app/scodoc/sco_formsemestre_edit.py
+++ b/app/scodoc/sco_formsemestre_edit.py
@@ -39,23 +39,21 @@ from app.models import Module, ModuleImpl, Evaluation, EvaluationUEPoids, UniteE
from app.models import ScolarNews
from app.models.formations import Formation
from app.models.formsemestre import FormSemestre
+from app.models.but_refcomp import ApcParcours
import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu
from app.scodoc import sco_cache
from app.scodoc import sco_groups
from app import log
-from app.scodoc.TrivialFormulator import TrivialFormulator, TF
+from app.scodoc.TrivialFormulator import TrivialFormulator
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_vdi import ApoEtapeVDI
from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_compute_moy
-from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
-from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud
-from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_db
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
@@ -119,12 +117,12 @@ def formsemestre_editwithmodules(formsemestre_id):
vals = scu.get_request_args()
if not vals.get("tf_submitted", False):
H.append(
- """Seuls les modules cochés font partie de ce semestre.
+ """
Seuls les modules cochés font partie de ce semestre.
Pour les retirer, les décocher et appuyer sur le bouton "modifier".
- Attention : s'il y a déjà des évaluations dans un module,
+
Attention : s'il y a déjà des évaluations dans un module,
il ne peut pas être supprimé !
- Les modules ont toujours un responsable.
+
Les modules ont toujours un responsable.
Par défaut, c'est le directeur des études.
Un semestre ne peut comporter qu'une seule UE "bonus
sport/culture"
@@ -153,7 +151,7 @@ def do_formsemestre_createwithmodules(edit=False):
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
if not current_user.has_permission(Permission.ScoImplement):
if not edit:
- # il faut ScoImplement pour creer un semestre
+ # il faut ScoImplement pour créer un semestre
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
else:
if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]:
@@ -175,6 +173,7 @@ def do_formsemestre_createwithmodules(edit=False):
formation = Formation.query.get(formation_id)
if formation is None:
raise ScoValueError("Formation inexistante !")
+ is_apc = formation.is_apc()
if not edit:
initvalues = {"titre": _default_sem_title(formation)}
semestre_id = int(vals["semestre_id"])
@@ -210,12 +209,12 @@ def do_formsemestre_createwithmodules(edit=False):
if NB_SEM == 1:
semestre_id_list = [-1]
else:
- if edit and formation.is_apc():
+ if edit and is_apc:
# en APC, ne permet pas de changer de semestre
semestre_id_list = [formsemestre.semestre_id]
else:
semestre_id_list = list(range(1, NB_SEM + 1))
- if not formation.is_apc():
+ if not is_apc:
# propose "pas de semestre" seulement en classique
semestre_id_list.insert(0, -1)
@@ -226,7 +225,7 @@ def do_formsemestre_createwithmodules(edit=False):
else:
semestre_id_labels.append(f"S{sid}")
# Liste des modules dans cette formation
- if formation.is_apc():
+ if is_apc:
modules = formation.modules.order_by(Module.module_type, Module.numero)
else:
modules = (
@@ -318,10 +317,10 @@ def do_formsemestre_createwithmodules(edit=False):
{
"size": 40,
"title": "Nom de ce semestre",
- "explanation": """n'indiquez pas les dates, ni le semestre, ni la modalité dans
+ "explanation": f"""n'indiquez pas les dates, ni le semestre, ni la modalité dans
le titre: ils seront automatiquement ajoutés """
- % _default_sem_title(formation),
+ value="remettre titre par défaut" onClick="document.tf.titre.value='{
+ _default_sem_title(formation)}';"/>""",
},
),
(
@@ -343,11 +342,9 @@ def do_formsemestre_createwithmodules(edit=False):
"allowed_values": semestre_id_list,
"labels": semestre_id_labels,
"explanation": "en BUT, on ne peut pas modifier le semestre après création"
- if formation.is_apc()
- else "",
- "attributes": ['onchange="change_semestre_id();"']
- if formation.is_apc()
+ if is_apc
else "",
+ "attributes": ['onchange="change_semestre_id();"'] if is_apc else "",
},
),
)
@@ -386,7 +383,7 @@ def do_formsemestre_createwithmodules(edit=False):
mf = mf_manual
for n in range(1, scu.EDIT_NB_ETAPES + 1):
- mf["title"] = "Etape Apogée (%d)" % n
+ mf["title"] = f"Etape Apogée ({n})"
modform.append(("etape_apo" + str(n), mf.copy()))
modform.append(
(
@@ -443,15 +440,19 @@ def do_formsemestre_createwithmodules(edit=False):
)
)
if edit:
- formtit = (
- """
- Modifier les coefficients des UE capitalisées
- Sélectionner les modules, leurs responsables et les étudiants à inscrire:
+ formtit = f"""
+ Modifier les coefficients des UE capitalisées
+ Sélectionner les modules, leurs responsables et les étudiants
+ à inscrire:
"""
- % formsemestre_id
- )
else:
- formtit = """Sélectionner les modules et leurs responsables Si vous avez des parcours (options), ne sélectionnez que les modules du tronc commun.
"""
+ formtit = """Sélectionner les modules et leurs responsables
+ Si vous avez des parcours (options), dans un premier
+ ne sélectionnez que les modules du tronc commun, puis après inscriptions,
+ revenez ajouter les modules de parcours en sélectionnant les groupes d'étudiants
+ à y inscrire.
+
"""
modform += [
(
@@ -531,12 +532,52 @@ def do_formsemestre_createwithmodules(edit=False):
"explanation": "empêcher le calcul des moyennes d'UE et générale.",
},
),
+ ]
+ # Choix des parcours
+ if is_apc:
+ ref_comp = formation.referentiel_competence
+ if ref_comp:
+ modform += [
+ (
+ "parcours",
+ {
+ "input_type": "checkbox",
+ "vertical": True,
+ "dom_id": "tf_module_parcours",
+ "labels": [parcour.libelle for parcour in ref_comp.parcours],
+ "allowed_values": [
+ str(parcour.id) for parcour in ref_comp.parcours
+ ],
+ "explanation": "Parcours proposés dans ce semestre.",
+ },
+ )
+ ]
+ if edit:
+ sem["parcours"] = [str(parcour.id) for parcour in formsemestre.parcours]
+ else:
+ modform += [
+ (
+ "parcours",
+ {
+ "input_type": "separator",
+ "title": f"""{scu.EMO_WARNING }
+ Pas de parcours:
+ vérifier la formation
+ """,
+ },
+ )
+ ]
+
+ # Choix des modules
+ modform += [
(
"sep",
{
"input_type": "separator",
"title": "",
- "template": "
%s",
},
),
]
@@ -544,8 +585,8 @@ def do_formsemestre_createwithmodules(edit=False):
nbmod = 0
for semestre_id in semestre_ids:
- if formation.is_apc():
- # pour restreindre l'édition aux module du semestre sélectionné
+ if is_apc:
+ # pour restreindre l'édition aux modules du semestre sélectionné
tr_class = f'class="sem{semestre_id}"'
else:
tr_class = ""
@@ -560,7 +601,7 @@ def do_formsemestre_createwithmodules(edit=False):
"sep",
{
"input_type": "separator",
- "title": "Semestre %s " % semestre_id,
+ "title": f"Semestre {semestre_id} ",
"template": templ_sep,
},
)
@@ -568,13 +609,13 @@ def do_formsemestre_createwithmodules(edit=False):
for mod in mods:
if mod["semestre_id"] == semestre_id and (
(not edit) # creation => tous modules
- or (not formation.is_apc()) # pas BUT, on peut mixer les semestres
+ or (not is_apc) # pas BUT, on peut mixer les semestres
or (semestre_id == formsemestre.semestre_id) # module du semestre
or (mod["module_id"] in module_ids_set) # module déjà présent
):
nbmod += 1
if edit:
- select_name = "%s!group_id" % mod["module_id"]
+ select_name = f"{mod['module_id']}!group_id"
def opt_selected(gid):
if gid == vals.get(select_name):
@@ -603,13 +644,16 @@ def do_formsemestre_createwithmodules(edit=False):
group["group_name"],
)
fcg += ""
- itemtemplate = (
- f"""%(label)s %(elem)s """
- + fcg
- + " "
- )
+ itemtemplate = f"""
+ %(label)s
+ %(elem)s
+ {fcg}
+ """
else:
- itemtemplate = f"""%(label)s %(elem)s """
+ itemtemplate = f"""
+ %(label)s
+ %(elem)s
+ """
modform.append(
(
"MI" + str(mod["module_id"]),
@@ -742,7 +786,8 @@ def do_formsemestre_createwithmodules(edit=False):
for module_id in tf[2]["tf-checked"]:
mod_resp_id = User.get_user_id_from_nomplogin(tf[2][module_id])
if mod_resp_id is None:
- # Si un module n'a pas de responsable (ou inconnu), l'affecte au 1er directeur des etudes:
+ # Si un module n'a pas de responsable (ou inconnu),
+ # l'affecte au 1er directeur des etudes:
mod_resp_id = tf[2]["responsable_id"]
tf[2][module_id] = mod_resp_id
@@ -763,7 +808,7 @@ def do_formsemestre_createwithmodules(edit=False):
module_ids_checked = [int(x[2:]) for x in tf[2]["tf-checked"]]
_formsemestre_check_ue_bonus_unicity(module_ids_checked)
if not edit:
- if formation.is_apc():
+ if is_apc:
_formsemestre_check_module_list(
module_ids_checked, tf[2]["semestre_id"]
)
@@ -777,14 +822,6 @@ def do_formsemestre_createwithmodules(edit=False):
"responsable_id": tf[2][f"MI{module_id}"],
}
_ = sco_moduleimpl.do_moduleimpl_create(modargs)
- flash("Nouveau semestre créé")
- return flask.redirect(
- url_for(
- "notes.formsemestre_status",
- scodoc_dept=g.scodoc_dept,
- formsemestre_id=formsemestre_id,
- )
- )
else:
# Modification du semestre:
# on doit creer les modules nouvellement selectionnés
@@ -794,7 +831,7 @@ def do_formsemestre_createwithmodules(edit=False):
module_ids_tocreate = [
x for x in module_ids_checked if not x in module_ids_existing
]
- if formation.is_apc():
+ if is_apc:
_formsemestre_check_module_list(
module_ids_tocreate, tf[2]["semestre_id"]
)
@@ -868,27 +905,46 @@ def do_formsemestre_createwithmodules(edit=False):
modargs, formsemestre_id=formsemestre_id
)
mod = sco_edit_module.module_list({"module_id": module_id})[0]
-
- if msg:
- msg_html = (
- '"
- )
- if ok:
- msg_html += "Modification effectuée
"
- else:
- msg_html += "Modification effectuée (mais modules cités non supprimés )
"
- msg_html += (
- 'retour au tableau de bord '
- % formsemestre_id
- )
- return msg_html
+ # --- Assocation des parcours
+ formsemestre = FormSemestre.query.get(formsemestre_id)
+ if "parcours" in tf[2]:
+ formsemestre.parcours = [
+ ApcParcours.query.get(int(parcour_id_str))
+ for parcour_id_str in tf[2]["parcours"]
+ ]
+ db.session.add(formsemestre)
+ db.session.commit()
+ # --- Fin
+ if edit:
+ if msg:
+ msg_html = (
+ '"
+ )
+ if ok:
+ msg_html += "Modification effectuée
"
else:
- return flask.redirect(
- "formsemestre_status?formsemestre_id=%s&head_message=Semestre modifié"
- % formsemestre_id
- )
+ msg_html += "Modification effectuée (mais modules cités non supprimés )
"
+ msg_html += (
+ 'retour au tableau de bord '
+ % formsemestre_id
+ )
+ return msg_html
+ else:
+ return flask.redirect(
+ "formsemestre_status?formsemestre_id=%s&head_message=Semestre modifié"
+ % formsemestre_id
+ )
+ else:
+ flash("Nouveau semestre créé")
+ return flask.redirect(
+ url_for(
+ "notes.formsemestre_status",
+ scodoc_dept=g.scodoc_dept,
+ formsemestre_id=formsemestre_id,
+ )
+ )
def _formsemestre_check_module_list(module_ids, semestre_idx):
diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py
index 299318ed..fbf16c3d 100644
--- a/app/scodoc/sco_formsemestre_status.py
+++ b/app/scodoc/sco_formsemestre_status.py
@@ -929,10 +929,18 @@ def formsemestre_status_head(formsemestre_id=None, page_title=None):
})"""
)
H.append("")
+ if sem.parcours:
+ H.append(
+ f"""
+ Parcours:
+ {', '.join(parcours.code for parcours in sem.parcours)}
+
+ """
+ )
evals = sco_evaluations.do_evaluation_etat_in_sem(formsemestre_id)
H.append(
- 'Evaluations: %(nb_evals_completes)s ok, %(nb_evals_en_cours)s en cours, %(nb_evals_vides)s vides'
+ ' Évaluations: %(nb_evals_completes)s ok, %(nb_evals_en_cours)s en cours, %(nb_evals_vides)s vides'
% evals
)
if evals["last_modif"]:
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index c9933ffb..1696009a 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -2206,7 +2206,7 @@ ul.notes_module_list {
list-style-type: none;
}
-div#ue_choix_niveau {
+div.ue_choix_niveau {
background-color: rgb(191, 242, 255);
border: 1px solid blue;
border-radius: 10px;
diff --git a/app/static/js/module_edit.js b/app/static/js/module_edit.js
new file mode 100644
index 00000000..9882fdff
--- /dev/null
+++ b/app/static/js/module_edit.js
@@ -0,0 +1,8 @@
+/* Page édition module */
+
+
+$(document).ready(function () {
+
+});
+
+
diff --git a/app/templates/but/refcomp_assoc.html b/app/templates/but/refcomp_assoc.html
index 9f8335be..9ba07dee 100644
--- a/app/templates/but/refcomp_assoc.html
+++ b/app/templates/but/refcomp_assoc.html
@@ -6,11 +6,25 @@
Associer un référentiel de compétences
-
-
- {{ wtf.quick_form(form) }}
+
+
+ Référentiel actuellement associé:
+ {% if formation.referentiel_competence is not none %}
+
{{ formation.referentiel_competence.specialite_long }}
+
supprimer
+ {% else %}
+
aucun
+ {% endif %}
+
+
+ {{ wtf.quick_form(form) }}
+
diff --git a/app/views/refcomp.py b/app/views/refcomp.py
index 27e5c83e..fb9e2eb1 100644
--- a/app/views/refcomp.py
+++ b/app/views/refcomp.py
@@ -160,6 +160,20 @@ def refcomp_assoc_formation(formation_id: int):
)
+@bp.route("/referentiel/comp/desassoc_formation/
", methods=["GET"])
+@scodoc
+@permission_required(Permission.ScoChangeFormation)
+def refcomp_desassoc_formation(formation_id: int):
+ """Désassocie la formation de son ref. de compétence"""
+ formation = Formation.query.get_or_404(formation_id)
+ formation.referentiel_competence = None
+ db.session.add(formation)
+ db.session.commit()
+ return redirect(
+ url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation.id)
+ )
+
+
@bp.route(
"/referentiel/comp/load", defaults={"formation_id": None}, methods=["GET", "POST"]
)
diff --git a/sco_version.py b/sco_version.py
index 3222274f..242844ed 100644
--- a/sco_version.py
+++ b/sco_version.py
@@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
-SCOVERSION = "9.2.22"
+SCOVERSION = "9.3a"
SCONAME = "ScoDoc"