forked from ScoDoc/ScoDoc
Parcours BUT / Ref. Compétences
+ association UE -> ApcNiveau + choix sur la page ue_edit + association Module <-> ensemble de ApcParcours + choix sur la page module_edit + association Module - ApcAppCritique ~ choix sur la page module_edit TODO: revoir pour présenter les AC du semestre et parcours sélectionnés (JS) + association FormSemestre <-> ApcParcours + choix sur la page formsemestre_editwithmodules
This commit is contained in:
parent
539041fd0d
commit
fd8116a772
@ -17,7 +17,13 @@ def form_ue_choix_niveau(ue: UniteEns) -> str:
|
|||||||
"""Form. HTML pour associer une UE à un niveau de compétence"""
|
"""Form. HTML pour associer une UE à un niveau de compétence"""
|
||||||
ref_comp = ue.formation.referentiel_competence
|
ref_comp = ue.formation.referentiel_competence
|
||||||
if ref_comp is None:
|
if ref_comp is None:
|
||||||
return """<div class="ue_choix_niveau">pas de référentiel de compétence</div>"""
|
return f"""<div class="ue_choix_niveau">
|
||||||
|
<div class="warning">Pas de référentiel de compétence associé à cette formation !</div>
|
||||||
|
<div><a class="stdlink" href="{ url_for('notes.refcomp_assoc_formation',
|
||||||
|
scodoc_dept=g.scodoc_dept, formation_id=ue.formation.id)
|
||||||
|
}">associer un référentiel de compétence</a>
|
||||||
|
</div>
|
||||||
|
</div>"""
|
||||||
annee = (ue.semestre_idx + 1) // 2 # 1, 2, 3
|
annee = (ue.semestre_idx + 1) // 2 # 1, 2, 3
|
||||||
niveaux_by_parcours = ref_comp.get_niveaux_by_parcours(annee)
|
niveaux_by_parcours = ref_comp.get_niveaux_by_parcours(annee)
|
||||||
|
|
||||||
@ -39,7 +45,7 @@ def form_ue_choix_niveau(ue: UniteEns) -> str:
|
|||||||
options.append("""</optgroup>""")
|
options.append("""</optgroup>""")
|
||||||
options_str = "\n".join(options)
|
options_str = "\n".join(options)
|
||||||
return f"""
|
return f"""
|
||||||
<div id="ue_choix_niveau">
|
<div class="ue_choix_niveau">
|
||||||
<form id="form_ue_choix_niveau">
|
<form id="form_ue_choix_niveau">
|
||||||
<b>Niveau de compétence associé:</b>
|
<b>Niveau de compétence associé:</b>
|
||||||
<select onchange="set_ue_niveau_competence();" data-setter="{
|
<select onchange="set_ue_niveau_competence();" data-setter="{
|
||||||
|
@ -13,7 +13,9 @@ from wtforms import SelectField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class FormationRefCompForm(FlaskForm):
|
class FormationRefCompForm(FlaskForm):
|
||||||
referentiel_competence = SelectField("Référentiels déjà chargés")
|
referentiel_competence = SelectField(
|
||||||
|
"Choisir parmi les référentiels déjà chargés :"
|
||||||
|
)
|
||||||
submit = SubmitField("Valider")
|
submit = SubmitField("Valider")
|
||||||
cancel = SubmitField("Annuler")
|
cancel = SubmitField("Annuler")
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
"""ScoDoc 9 models : Formation BUT 2021
|
"""ScoDoc 9 models : Formation BUT 2021
|
||||||
|
XXX inutilisé
|
||||||
"""
|
"""
|
||||||
from enum import unique
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
|
|
||||||
from app.scodoc.sco_utils import ModuleType
|
|
||||||
|
|
||||||
|
|
||||||
class APCFormation(db.Model):
|
class APCFormation(db.Model):
|
||||||
"""Formation par compétence"""
|
"""Formation par compétence"""
|
||||||
|
@ -83,7 +83,7 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
|||||||
formations = db.relationship("Formation", backref="referentiel_competence")
|
formations = db.relationship("Formation", backref="referentiel_competence")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<ApcReferentielCompetences {self.id} {self.specialite}>"
|
return f"<ApcReferentielCompetences {self.id} {self.specialite!r}>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
"""Représentation complète du ref. de comp.
|
"""Représentation complète du ref. de comp.
|
||||||
@ -191,7 +191,7 @@ class ApcCompetence(db.Model, XMLModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<ApcCompetence {self.id} {self.titre}>"
|
return f"<ApcCompetence {self.id} {self.titre!r}>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
@ -257,7 +257,8 @@ class ApcNiveau(db.Model, XMLModel):
|
|||||||
ues = db.relationship("UniteEns", back_populates="niveau_competence")
|
ues = db.relationship("UniteEns", back_populates="niveau_competence")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} ordre={self.ordre} annee={self.annee} {self.competence}>"
|
return f"""<{self.__class__.__name__} ordre={self.ordre!r} annee={
|
||||||
|
self.annee!r} {self.competence!r}>"""
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
@ -341,7 +342,7 @@ class ApcAppCritique(db.Model, XMLModel):
|
|||||||
return self.code + " - " + self.titre
|
return self.code + " - " + self.titre
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} {self.code}>"
|
return f"<{self.__class__.__name__} {self.code!r}>"
|
||||||
|
|
||||||
def get_saes(self):
|
def get_saes(self):
|
||||||
"""Liste des SAE associées"""
|
"""Liste des SAE associées"""
|
||||||
@ -362,6 +363,20 @@ parcours_modules = db.Table(
|
|||||||
)
|
)
|
||||||
"""Association parcours <-> modules (many-to-many)"""
|
"""Association parcours <-> modules (many-to-many)"""
|
||||||
|
|
||||||
|
parcours_formsemestre = db.Table(
|
||||||
|
"parcours_formsemestre",
|
||||||
|
db.Column(
|
||||||
|
"parcours_id", db.Integer, db.ForeignKey("apc_parcours.id"), primary_key=True
|
||||||
|
),
|
||||||
|
db.Column(
|
||||||
|
"formsemestre_id",
|
||||||
|
db.Integer,
|
||||||
|
db.ForeignKey("notes_formsemestre.id", ondelete="CASCADE"),
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
"""Association parcours <-> formsemestre (many-to-many)"""
|
||||||
|
|
||||||
|
|
||||||
class ApcParcours(db.Model, XMLModel):
|
class ApcParcours(db.Model, XMLModel):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
@ -379,7 +394,7 @@ class ApcParcours(db.Model, XMLModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} {self.code}>"
|
return f"<{self.__class__.__name__} {self.code!r}>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
@ -399,7 +414,7 @@ class ApcAnneeParcours(db.Model, XMLModel):
|
|||||||
"numéro de l'année: 1, 2, 3"
|
"numéro de l'année: 1, 2, 3"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} ordre={self.ordre} parcours={self.parcours.code}>"
|
return f"<{self.__class__.__name__} ordre={self.ordre!r} parcours={self.parcours.code!r}>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
@ -450,4 +465,4 @@ class ApcParcoursNiveauCompetence(db.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} {self.competence}<->{self.annee_parcours} niveau={self.niveau}>"
|
return f"<{self.__class__.__name__} {self.competence!r}<->{self.annee_parcours!r} niveau={self.niveau!r}>"
|
||||||
|
@ -515,21 +515,21 @@ class Admission(db.Model):
|
|||||||
|
|
||||||
def to_dict(self, no_nulls=False):
|
def to_dict(self, no_nulls=False):
|
||||||
"""Représentation dictionnaire,"""
|
"""Représentation dictionnaire,"""
|
||||||
e = dict(self.__dict__)
|
d = dict(self.__dict__)
|
||||||
e.pop("_sa_instance_state", None)
|
d.pop("_sa_instance_state", None)
|
||||||
if no_nulls:
|
if no_nulls:
|
||||||
for k in e:
|
for k in d.keys():
|
||||||
if e[k] is None:
|
if d[k] is None:
|
||||||
col_type = getattr(
|
col_type = getattr(
|
||||||
sqlalchemy.inspect(models.Admission).columns, "apb_groupe"
|
sqlalchemy.inspect(models.Admission).columns, "apb_groupe"
|
||||||
).expression.type
|
).expression.type
|
||||||
if isinstance(col_type, sqlalchemy.Text):
|
if isinstance(col_type, sqlalchemy.Text):
|
||||||
e[k] = ""
|
d[k] = ""
|
||||||
elif isinstance(col_type, sqlalchemy.Integer):
|
elif isinstance(col_type, sqlalchemy.Integer):
|
||||||
e[k] = 0
|
d[k] = 0
|
||||||
elif isinstance(col_type, sqlalchemy.Boolean):
|
elif isinstance(col_type, sqlalchemy.Boolean):
|
||||||
e[k] = False
|
d[k] = False
|
||||||
return e
|
return d
|
||||||
|
|
||||||
|
|
||||||
# Suivi scolarité / débouchés
|
# Suivi scolarité / débouchés
|
||||||
|
@ -45,7 +45,7 @@ class Formation(db.Model):
|
|||||||
modules = db.relationship("Module", lazy="dynamic", backref="formation")
|
modules = db.relationship("Module", lazy="dynamic", backref="formation")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme}')>"
|
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme!r}')>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
e = dict(self.__dict__)
|
e = dict(self.__dict__)
|
||||||
@ -168,7 +168,7 @@ class Matiere(db.Model):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"""<{self.__class__.__name__}(id={self.id}, ue_id={
|
return f"""<{self.__class__.__name__}(id={self.id}, ue_id={
|
||||||
self.ue_id}, titre='{self.titre}')>"""
|
self.ue_id}, titre='{self.titre!r}')>"""
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
"""as a dict, with the same conversions as in ScoDoc7"""
|
"""as a dict, with the same conversions as in ScoDoc7"""
|
||||||
|
@ -14,10 +14,12 @@ from app.models import SHORT_STR_LEN
|
|||||||
from app.models import CODE_STR_LEN
|
from app.models import CODE_STR_LEN
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.models.ues import UniteEns
|
from app.models.but_refcomp import parcours_formsemestre
|
||||||
|
from app.models.etudiants import Identite
|
||||||
from app.models.modules import Module
|
from app.models.modules import Module
|
||||||
from app.models.moduleimpls import ModuleImpl
|
from app.models.moduleimpls import ModuleImpl
|
||||||
from app.models.etudiants import Identite
|
from app.models.ues import UniteEns
|
||||||
|
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
@ -113,6 +115,14 @@ class FormSemestre(db.Model):
|
|||||||
# ne pas utiliser après migrate_scodoc7_dept_archives
|
# ne pas utiliser après migrate_scodoc7_dept_archives
|
||||||
scodoc7_id = db.Column(db.Text(), nullable=True)
|
scodoc7_id = db.Column(db.Text(), nullable=True)
|
||||||
|
|
||||||
|
# BUT
|
||||||
|
parcours = db.relationship(
|
||||||
|
"ApcParcours",
|
||||||
|
secondary=parcours_formsemestre,
|
||||||
|
lazy="subquery",
|
||||||
|
backref=db.backref("formsemestres", lazy=True),
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(FormSemestre, self).__init__(**kwargs)
|
super(FormSemestre, self).__init__(**kwargs)
|
||||||
if self.modalite is None:
|
if self.modalite is None:
|
||||||
|
@ -65,7 +65,7 @@ class Module(db.Model):
|
|||||||
super(Module, self).__init__(**kwargs)
|
super(Module, self).__init__(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Module{ModuleType(self.module_type or ModuleType.STANDARD).name} id={self.id} code={self.code}>"
|
return f"<Module{ModuleType(self.module_type or ModuleType.STANDARD).name} id={self.id} code={self.code!r}>"
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
e = dict(self.__dict__)
|
e = dict(self.__dict__)
|
||||||
|
@ -207,12 +207,16 @@ class TF(object):
|
|||||||
else:
|
else:
|
||||||
self.values[field] = 1
|
self.values[field] = 1
|
||||||
if field not in self.values:
|
if field not in self.values:
|
||||||
if "default" in descr: # first: default in form description
|
if (descr.get("input_type", None) == "checkbox") and self.submitted():
|
||||||
self.values[field] = descr["default"]
|
# aucune case cochée
|
||||||
else: # then: use initvalues dict
|
self.values[field] = []
|
||||||
self.values[field] = self.initvalues.get(field, "")
|
else:
|
||||||
if self.values[field] == None:
|
if "default" in descr: # first: default in form description
|
||||||
self.values[field] = ""
|
self.values[field] = descr["default"]
|
||||||
|
else: # then: use initvalues dict
|
||||||
|
self.values[field] = self.initvalues.get(field, "")
|
||||||
|
if self.values[field] is None:
|
||||||
|
self.values[field] = ""
|
||||||
|
|
||||||
# convert numbers, except ids
|
# convert numbers, except ids
|
||||||
if field.endswith("id") and self.values[field]:
|
if field.endswith("id") and self.values[field]:
|
||||||
@ -392,9 +396,7 @@ class TF(object):
|
|||||||
if self.top_buttons:
|
if self.top_buttons:
|
||||||
R.append(buttons_markup + "<p></p>")
|
R.append(buttons_markup + "<p></p>")
|
||||||
R.append('<table class="tf">')
|
R.append('<table class="tf">')
|
||||||
idx = 0
|
for field, descr in self.formdescription:
|
||||||
for idx in range(len(self.formdescription)):
|
|
||||||
(field, descr) = self.formdescription[idx]
|
|
||||||
if descr.get("readonly", False):
|
if descr.get("readonly", False):
|
||||||
R.append(self._ReadOnlyElement(field, descr))
|
R.append(self._ReadOnlyElement(field, descr))
|
||||||
continue
|
continue
|
||||||
@ -408,7 +410,7 @@ class TF(object):
|
|||||||
input_type = descr.get("input_type", "text")
|
input_type = descr.get("input_type", "text")
|
||||||
item_dom_id = descr.get("dom_id", "")
|
item_dom_id = descr.get("dom_id", "")
|
||||||
if item_dom_id:
|
if item_dom_id:
|
||||||
item_dom_attr = ' id="%s"' % item_dom_id
|
item_dom_attr = f' id="{item_dom_id}"'
|
||||||
else:
|
else:
|
||||||
item_dom_attr = ""
|
item_dom_attr = ""
|
||||||
# choix du template
|
# choix du template
|
||||||
@ -523,7 +525,6 @@ class TF(object):
|
|||||||
else:
|
else:
|
||||||
checked = ""
|
checked = ""
|
||||||
else: # boolcheckbox
|
else: # boolcheckbox
|
||||||
# open('/tmp/toto','a').write('GenForm: values[%s] = %s (%s)\n' % (field, values[field], type(values[field])))
|
|
||||||
if values[field] == "True":
|
if values[field] == "True":
|
||||||
v = True
|
v = True
|
||||||
elif values[field] == "False":
|
elif values[field] == "False":
|
||||||
|
@ -365,6 +365,7 @@ def module_edit(
|
|||||||
"libjs/jQuery-tagEditor/jquery.tag-editor.min.js",
|
"libjs/jQuery-tagEditor/jquery.tag-editor.min.js",
|
||||||
"libjs/jQuery-tagEditor/jquery.caret.min.js",
|
"libjs/jQuery-tagEditor/jquery.caret.min.js",
|
||||||
"js/module_tag_editor.js",
|
"js/module_tag_editor.js",
|
||||||
|
"js/module_edit.js",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
f"""<h2>{title}</h2>""",
|
f"""<h2>{title}</h2>""",
|
||||||
@ -605,8 +606,7 @@ def module_edit(
|
|||||||
"input_type": "menu",
|
"input_type": "menu",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"title": parcours.SESSION_NAME.capitalize(),
|
"title": parcours.SESSION_NAME.capitalize(),
|
||||||
"explanation": "%s de début du module dans la formation standard"
|
"explanation": f"{parcours.SESSION_NAME} de début du module dans la formation standard",
|
||||||
% parcours.SESSION_NAME,
|
|
||||||
"labels": [str(x) for x in semestres_indices],
|
"labels": [str(x) for x in semestres_indices],
|
||||||
"allowed_values": semestres_indices,
|
"allowed_values": semestres_indices,
|
||||||
"enabled": unlocked,
|
"enabled": unlocked,
|
||||||
@ -648,11 +648,15 @@ def module_edit(
|
|||||||
"input_type": "checkbox",
|
"input_type": "checkbox",
|
||||||
"vertical": True,
|
"vertical": True,
|
||||||
"dom_id": "tf_module_parcours",
|
"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": [
|
"allowed_values": [
|
||||||
str(parcour.id) for parcour in ref_comp.parcours
|
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.<br>
|
||||||
|
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,
|
"vertical": True,
|
||||||
"dom_id": "tf_module_app_critiques",
|
"dom_id": "tf_module_app_critiques",
|
||||||
"labels": [
|
"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": [
|
"allowed_values": [
|
||||||
str(app_crit.id) for app_crit in app_critiques
|
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",
|
"input_type": "separator",
|
||||||
"title": f"""<span class="fontred">{scu.EMO_WARNING }
|
"title": f"""<span class="fontred">{scu.EMO_WARNING }
|
||||||
L'UE {ue.acronyme} {ue.titre}
|
L'UE <a class="stdlink" href="{
|
||||||
|
url_for("notes.ue_edit", scodoc_dept=g.scodoc_dept, ue_id=ue.id)
|
||||||
|
}">{ue.acronyme} {ue.titre}</a>
|
||||||
n'est pas associée à un niveau de compétences
|
n'est pas associée à un niveau de compétences
|
||||||
</span>""",
|
</span>""",
|
||||||
},
|
},
|
||||||
@ -727,9 +738,10 @@ def module_edit(
|
|||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
descr,
|
descr,
|
||||||
html_foot_markup="""<div class="sco_tag_module_edit"><span class="sco_tag_edit"><textarea data-module_id="{}" class="module_tag_editor">{}</textarea></span></div>""".format(
|
html_foot_markup=f"""<div class="sco_tag_module_edit"><span
|
||||||
module_id, ",".join(sco_tag_module.module_tag_list(module_id))
|
class="sco_tag_edit"><textarea data-module_id="{module_id}" class="module_tag_editor"
|
||||||
)
|
>{','.join(sco_tag_module.module_tag_list(module_id))}</textarea></span></div>
|
||||||
|
"""
|
||||||
if not create
|
if not create
|
||||||
else "",
|
else "",
|
||||||
initvalues=module_dict if module else {},
|
initvalues=module_dict if module else {},
|
||||||
@ -793,11 +805,14 @@ def module_edit(
|
|||||||
#
|
#
|
||||||
do_module_edit(tf[2])
|
do_module_edit(tf[2])
|
||||||
# Modifie les parcours
|
# Modifie les parcours
|
||||||
if "parcours" in tf[2]:
|
if ("parcours" in tf[2]) and formation.referentiel_competence:
|
||||||
module.parcours = [
|
if "-1" in tf[2]["parcours"]: # "tous"
|
||||||
ApcParcours.query.get(int(parcour_id_str))
|
module.parcours = formation.referentiel_competence.parcours.all()
|
||||||
for parcour_id_str in tf[2]["parcours"]
|
else:
|
||||||
]
|
module.parcours = [
|
||||||
|
ApcParcours.query.get(int(parcour_id_str))
|
||||||
|
for parcour_id_str in tf[2]["parcours"]
|
||||||
|
]
|
||||||
# Modifie les AC
|
# Modifie les AC
|
||||||
if "app_critiques" in tf[2]:
|
if "app_critiques" in tf[2]:
|
||||||
module.app_critiques = [
|
module.app_critiques = [
|
||||||
@ -811,7 +826,7 @@ def module_edit(
|
|||||||
"notes.ue_table",
|
"notes.ue_table",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=formation.id,
|
formation_id=formation.id,
|
||||||
semestre_idx=tf[2]["semestre_id"],
|
semestre_idx=tf[2]["semestre_id"] if is_apc else 1,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,23 +39,21 @@ from app.models import Module, ModuleImpl, Evaluation, EvaluationUEPoids, UniteE
|
|||||||
from app.models import ScolarNews
|
from app.models import ScolarNews
|
||||||
from app.models.formations import Formation
|
from app.models.formations import Formation
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
|
from app.models.but_refcomp import ApcParcours
|
||||||
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.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app import log
|
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_exceptions import AccessDenied, ScoValueError
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
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_compute_moy
|
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_module
|
||||||
from app.scodoc import sco_edit_ue
|
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_evaluations
|
|
||||||
from app.scodoc import sco_evaluation_db
|
from app.scodoc import sco_evaluation_db
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
@ -153,7 +151,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
if not current_user.has_permission(Permission.ScoImplement):
|
if not current_user.has_permission(Permission.ScoImplement):
|
||||||
if not edit:
|
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")
|
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
|
||||||
else:
|
else:
|
||||||
if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]:
|
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)
|
formation = Formation.query.get(formation_id)
|
||||||
if formation is None:
|
if formation is None:
|
||||||
raise ScoValueError("Formation inexistante !")
|
raise ScoValueError("Formation inexistante !")
|
||||||
|
is_apc = formation.is_apc()
|
||||||
if not edit:
|
if not edit:
|
||||||
initvalues = {"titre": _default_sem_title(formation)}
|
initvalues = {"titre": _default_sem_title(formation)}
|
||||||
semestre_id = int(vals["semestre_id"])
|
semestre_id = int(vals["semestre_id"])
|
||||||
@ -210,12 +209,12 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
if NB_SEM == 1:
|
if NB_SEM == 1:
|
||||||
semestre_id_list = [-1]
|
semestre_id_list = [-1]
|
||||||
else:
|
else:
|
||||||
if edit and formation.is_apc():
|
if edit and is_apc:
|
||||||
# en APC, ne permet pas de changer de semestre
|
# en APC, ne permet pas de changer de semestre
|
||||||
semestre_id_list = [formsemestre.semestre_id]
|
semestre_id_list = [formsemestre.semestre_id]
|
||||||
else:
|
else:
|
||||||
semestre_id_list = list(range(1, NB_SEM + 1))
|
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
|
# propose "pas de semestre" seulement en classique
|
||||||
semestre_id_list.insert(0, -1)
|
semestre_id_list.insert(0, -1)
|
||||||
|
|
||||||
@ -226,7 +225,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
else:
|
else:
|
||||||
semestre_id_labels.append(f"S{sid}")
|
semestre_id_labels.append(f"S{sid}")
|
||||||
# Liste des modules dans cette formation
|
# Liste des modules dans cette formation
|
||||||
if formation.is_apc():
|
if is_apc:
|
||||||
modules = formation.modules.order_by(Module.module_type, Module.numero)
|
modules = formation.modules.order_by(Module.module_type, Module.numero)
|
||||||
else:
|
else:
|
||||||
modules = (
|
modules = (
|
||||||
@ -318,10 +317,10 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
{
|
{
|
||||||
"size": 40,
|
"size": 40,
|
||||||
"title": "Nom de ce semestre",
|
"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 <input type="button"
|
le titre: ils seront automatiquement ajoutés <input type="button"
|
||||||
value="remettre titre par défaut" onClick="document.tf.titre.value='%s';"/>"""
|
value="remettre titre par défaut" onClick="document.tf.titre.value='{
|
||||||
% _default_sem_title(formation),
|
_default_sem_title(formation)}';"/>""",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -343,11 +342,9 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"allowed_values": semestre_id_list,
|
"allowed_values": semestre_id_list,
|
||||||
"labels": semestre_id_labels,
|
"labels": semestre_id_labels,
|
||||||
"explanation": "en BUT, on ne peut pas modifier le semestre après création"
|
"explanation": "en BUT, on ne peut pas modifier le semestre après création"
|
||||||
if formation.is_apc()
|
if is_apc
|
||||||
else "",
|
|
||||||
"attributes": ['onchange="change_semestre_id();"']
|
|
||||||
if formation.is_apc()
|
|
||||||
else "",
|
else "",
|
||||||
|
"attributes": ['onchange="change_semestre_id();"'] if is_apc else "",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -386,7 +383,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
mf = mf_manual
|
mf = mf_manual
|
||||||
|
|
||||||
for n in range(1, scu.EDIT_NB_ETAPES + 1):
|
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(("etape_apo" + str(n), mf.copy()))
|
||||||
modform.append(
|
modform.append(
|
||||||
(
|
(
|
||||||
@ -443,15 +440,19 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
if edit:
|
if edit:
|
||||||
formtit = (
|
formtit = f"""
|
||||||
"""
|
<p><a href="formsemestre_edit_uecoefs?formsemestre_id={formsemestre_id}"
|
||||||
<p><a href="formsemestre_edit_uecoefs?formsemestre_id=%s">Modifier les coefficients des UE capitalisées</a></p>
|
>Modifier les coefficients des UE capitalisées</a></p>
|
||||||
<h3>Sélectionner les modules, leurs responsables et les étudiants à inscrire:</h3>
|
<h3>Sélectionner les modules, leurs responsables et les étudiants
|
||||||
|
à inscrire:</h3>
|
||||||
"""
|
"""
|
||||||
% formsemestre_id
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
formtit = """<h3>Sélectionner les modules et leurs responsables</h3><p class="help">Si vous avez des parcours (options), ne sélectionnez que les modules du tronc commun.</p>"""
|
formtit = """<h3>Sélectionner les modules et leurs responsables</h3>
|
||||||
|
<p class="help">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.
|
||||||
|
</p>"""
|
||||||
|
|
||||||
modform += [
|
modform += [
|
||||||
(
|
(
|
||||||
@ -531,12 +532,52 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"explanation": "empêcher le calcul des moyennes d'UE et générale.",
|
"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"""<span class="fontred">{scu.EMO_WARNING }
|
||||||
|
Pas de parcours:
|
||||||
|
<a class="stdlink" href="{ url_for('notes.ue_table',
|
||||||
|
scodoc_dept=g.scodoc_dept, formation_id=formation.id)
|
||||||
|
}">vérifier la formation</a>
|
||||||
|
</span>""",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Choix des modules
|
||||||
|
modform += [
|
||||||
(
|
(
|
||||||
"sep",
|
"sep",
|
||||||
{
|
{
|
||||||
"input_type": "separator",
|
"input_type": "separator",
|
||||||
"title": "",
|
"title": "",
|
||||||
"template": "</table>%s<table>" % formtit,
|
"template": f"</table>{formtit}<table>",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -544,8 +585,8 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
nbmod = 0
|
nbmod = 0
|
||||||
|
|
||||||
for semestre_id in semestre_ids:
|
for semestre_id in semestre_ids:
|
||||||
if formation.is_apc():
|
if is_apc:
|
||||||
# pour restreindre l'édition aux module du semestre sélectionné
|
# pour restreindre l'édition aux modules du semestre sélectionné
|
||||||
tr_class = f'class="sem{semestre_id}"'
|
tr_class = f'class="sem{semestre_id}"'
|
||||||
else:
|
else:
|
||||||
tr_class = ""
|
tr_class = ""
|
||||||
@ -560,7 +601,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"sep",
|
"sep",
|
||||||
{
|
{
|
||||||
"input_type": "separator",
|
"input_type": "separator",
|
||||||
"title": "<b>Semestre %s</b>" % semestre_id,
|
"title": f"<b>Semestre {semestre_id}</b>",
|
||||||
"template": templ_sep,
|
"template": templ_sep,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -568,13 +609,13 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
for mod in mods:
|
for mod in mods:
|
||||||
if mod["semestre_id"] == semestre_id and (
|
if mod["semestre_id"] == semestre_id and (
|
||||||
(not edit) # creation => tous modules
|
(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 (semestre_id == formsemestre.semestre_id) # module du semestre
|
||||||
or (mod["module_id"] in module_ids_set) # module déjà présent
|
or (mod["module_id"] in module_ids_set) # module déjà présent
|
||||||
):
|
):
|
||||||
nbmod += 1
|
nbmod += 1
|
||||||
if edit:
|
if edit:
|
||||||
select_name = "%s!group_id" % mod["module_id"]
|
select_name = f"{mod['module_id']}!group_id"
|
||||||
|
|
||||||
def opt_selected(gid):
|
def opt_selected(gid):
|
||||||
if gid == vals.get(select_name):
|
if gid == vals.get(select_name):
|
||||||
@ -603,13 +644,16 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
group["group_name"],
|
group["group_name"],
|
||||||
)
|
)
|
||||||
fcg += "</select>"
|
fcg += "</select>"
|
||||||
itemtemplate = (
|
itemtemplate = f"""<tr {tr_class}>
|
||||||
f"""<tr {tr_class}><td class="tf-fieldlabel">%(label)s</td><td class="tf-field">%(elem)s</td><td>"""
|
<td class="tf-fieldlabel">%(label)s</td>
|
||||||
+ fcg
|
<td class="tf-field">%(elem)s</td>
|
||||||
+ "</td></tr>"
|
<td>{fcg}</td>
|
||||||
)
|
</tr>"""
|
||||||
else:
|
else:
|
||||||
itemtemplate = f"""<tr {tr_class}><td class="tf-fieldlabel">%(label)s</td><td class="tf-field">%(elem)s</td></tr>"""
|
itemtemplate = f"""<tr {tr_class}>
|
||||||
|
<td class="tf-fieldlabel">%(label)s</td>
|
||||||
|
<td class="tf-field">%(elem)s</td>
|
||||||
|
</tr>"""
|
||||||
modform.append(
|
modform.append(
|
||||||
(
|
(
|
||||||
"MI" + str(mod["module_id"]),
|
"MI" + str(mod["module_id"]),
|
||||||
@ -742,7 +786,8 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
for module_id in tf[2]["tf-checked"]:
|
for module_id in tf[2]["tf-checked"]:
|
||||||
mod_resp_id = User.get_user_id_from_nomplogin(tf[2][module_id])
|
mod_resp_id = User.get_user_id_from_nomplogin(tf[2][module_id])
|
||||||
if mod_resp_id is None:
|
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"]
|
mod_resp_id = tf[2]["responsable_id"]
|
||||||
tf[2][module_id] = mod_resp_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"]]
|
module_ids_checked = [int(x[2:]) for x in tf[2]["tf-checked"]]
|
||||||
_formsemestre_check_ue_bonus_unicity(module_ids_checked)
|
_formsemestre_check_ue_bonus_unicity(module_ids_checked)
|
||||||
if not edit:
|
if not edit:
|
||||||
if formation.is_apc():
|
if is_apc:
|
||||||
_formsemestre_check_module_list(
|
_formsemestre_check_module_list(
|
||||||
module_ids_checked, tf[2]["semestre_id"]
|
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}"],
|
"responsable_id": tf[2][f"MI{module_id}"],
|
||||||
}
|
}
|
||||||
_ = sco_moduleimpl.do_moduleimpl_create(modargs)
|
_ = 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:
|
else:
|
||||||
# Modification du semestre:
|
# Modification du semestre:
|
||||||
# on doit creer les modules nouvellement selectionnés
|
# on doit creer les modules nouvellement selectionnés
|
||||||
@ -794,7 +831,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
module_ids_tocreate = [
|
module_ids_tocreate = [
|
||||||
x for x in module_ids_checked if not x in module_ids_existing
|
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(
|
_formsemestre_check_module_list(
|
||||||
module_ids_tocreate, tf[2]["semestre_id"]
|
module_ids_tocreate, tf[2]["semestre_id"]
|
||||||
)
|
)
|
||||||
@ -868,27 +905,46 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
modargs, formsemestre_id=formsemestre_id
|
modargs, formsemestre_id=formsemestre_id
|
||||||
)
|
)
|
||||||
mod = sco_edit_module.module_list({"module_id": module_id})[0]
|
mod = sco_edit_module.module_list({"module_id": module_id})[0]
|
||||||
|
# --- Assocation des parcours
|
||||||
if msg:
|
formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||||
msg_html = (
|
if "parcours" in tf[2]:
|
||||||
'<div class="ue_warning"><span>Attention !<ul><li>'
|
formsemestre.parcours = [
|
||||||
+ "</li><li>".join(msg)
|
ApcParcours.query.get(int(parcour_id_str))
|
||||||
+ "</li></ul></span></div>"
|
for parcour_id_str in tf[2]["parcours"]
|
||||||
)
|
]
|
||||||
if ok:
|
db.session.add(formsemestre)
|
||||||
msg_html += "<p>Modification effectuée</p>"
|
db.session.commit()
|
||||||
else:
|
# --- Fin
|
||||||
msg_html += "<p>Modification effectuée (<b>mais modules cités non supprimés</b>)</p>"
|
if edit:
|
||||||
msg_html += (
|
if msg:
|
||||||
'<a href="formsemestre_status?formsemestre_id=%s">retour au tableau de bord</a>'
|
msg_html = (
|
||||||
% formsemestre_id
|
'<div class="ue_warning"><span>Attention !<ul><li>'
|
||||||
)
|
+ "</li><li>".join(msg)
|
||||||
return msg_html
|
+ "</li></ul></span></div>"
|
||||||
|
)
|
||||||
|
if ok:
|
||||||
|
msg_html += "<p>Modification effectuée</p>"
|
||||||
else:
|
else:
|
||||||
return flask.redirect(
|
msg_html += "<p>Modification effectuée (<b>mais modules cités non supprimés</b>)</p>"
|
||||||
"formsemestre_status?formsemestre_id=%s&head_message=Semestre modifié"
|
msg_html += (
|
||||||
% formsemestre_id
|
'<a href="formsemestre_status?formsemestre_id=%s">retour au tableau de bord</a>'
|
||||||
)
|
% 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):
|
def _formsemestre_check_module_list(module_ids, semestre_idx):
|
||||||
|
@ -929,10 +929,18 @@ def formsemestre_status_head(formsemestre_id=None, page_title=None):
|
|||||||
}</tt></b>)"""
|
}</tt></b>)"""
|
||||||
)
|
)
|
||||||
H.append("</td></tr>")
|
H.append("</td></tr>")
|
||||||
|
if sem.parcours:
|
||||||
|
H.append(
|
||||||
|
f"""
|
||||||
|
<tr><td class="fichetitre2">Parcours: </td>
|
||||||
|
<td style="color: blue;">{', '.join(parcours.code for parcours in sem.parcours)}</td>
|
||||||
|
</tr>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
evals = sco_evaluations.do_evaluation_etat_in_sem(formsemestre_id)
|
evals = sco_evaluations.do_evaluation_etat_in_sem(formsemestre_id)
|
||||||
H.append(
|
H.append(
|
||||||
'<tr><td class="fichetitre2">Evaluations: </td><td> %(nb_evals_completes)s ok, %(nb_evals_en_cours)s en cours, %(nb_evals_vides)s vides'
|
'<tr><td class="fichetitre2">Évaluations: </td><td> %(nb_evals_completes)s ok, %(nb_evals_en_cours)s en cours, %(nb_evals_vides)s vides'
|
||||||
% evals
|
% evals
|
||||||
)
|
)
|
||||||
if evals["last_modif"]:
|
if evals["last_modif"]:
|
||||||
|
@ -2206,7 +2206,7 @@ ul.notes_module_list {
|
|||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#ue_choix_niveau {
|
div.ue_choix_niveau {
|
||||||
background-color: rgb(191, 242, 255);
|
background-color: rgb(191, 242, 255);
|
||||||
border: 1px solid blue;
|
border: 1px solid blue;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
8
app/static/js/module_edit.js
Normal file
8
app/static/js/module_edit.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* Page édition module */
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -6,11 +6,25 @@
|
|||||||
<h1>Associer un référentiel de compétences</h1>
|
<h1>Associer un référentiel de compétences</h1>
|
||||||
<div class="help">
|
<div class="help">
|
||||||
Association d'un référentiel de compétence à la formation
|
Association d'un référentiel de compétence à la formation
|
||||||
{{formation.titre}} ({{formation.acronyme}})
|
<a href="{{
|
||||||
|
url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id)
|
||||||
|
}}">{{formation.titre}} ({{formation.acronyme}})</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div style="margin-top: 20px; margin-bottom: 20px;">
|
||||||
<div class="col-md-4">
|
|
||||||
{{ wtf.quick_form(form) }}
|
Référentiel actuellement associé:
|
||||||
|
{% if formation.referentiel_competence is not none %}
|
||||||
|
<b>{{ formation.referentiel_competence.specialite_long }}</b>
|
||||||
|
<a href="{{
|
||||||
|
url_for('notes.refcomp_desassoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id)
|
||||||
|
}}" class="stdlink">supprimer</a>
|
||||||
|
{% else %}
|
||||||
|
<b>aucun</b>
|
||||||
|
{% endif %}
|
||||||
|
<div class="row" style="margin-top: 20px;">
|
||||||
|
<div class="col-md-4">
|
||||||
|
{{ wtf.quick_form(form) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -160,6 +160,20 @@ def refcomp_assoc_formation(formation_id: int):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/referentiel/comp/desassoc_formation/<int:formation_id>", 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(
|
@bp.route(
|
||||||
"/referentiel/comp/load", defaults={"formation_id": None}, methods=["GET", "POST"]
|
"/referentiel/comp/load", defaults={"formation_id": None}, methods=["GET", "POST"]
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.2.22"
|
SCOVERSION = "9.3a"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user