1
0
forked from ScoDoc/ScoDoc

Edition coefs (nuls) + tests

This commit is contained in:
Emmanuel Viennet 2021-11-13 12:09:30 +01:00
parent 1488689bfb
commit f6b2297bd3
5 changed files with 150 additions and 98 deletions

View File

@ -143,11 +143,15 @@ class Module(db.Model):
def set_ue_coef_dict(self, ue_coef_dict: dict) -> None: def set_ue_coef_dict(self, ue_coef_dict: dict) -> None:
"""set coefs vers les UE (remplace existants) """set coefs vers les UE (remplace existants)
ue_coef_dict = { ue_id : coef } ue_coef_dict = { ue_id : coef }
Les coefs nuls (zéro) ne sont pas stockés: la relation est supprimée.
""" """
ue_coefs = [] ue_coefs = []
for ue_id, coef in ue_coef_dict.items(): for ue_id, coef in ue_coef_dict.items():
ue = UniteEns.query.get(ue_id) ue = UniteEns.query.get(ue_id)
ue_coefs.append(ModuleUECoef(module=self, ue=ue, coef=coef)) if coef == 0.0:
self.delete_ue_coef(ue)
else:
ue_coefs.append(ModuleUECoef(module=self, ue=ue, coef=coef))
self.ue_coefs = ue_coefs self.ue_coefs = ue_coefs
def update_ue_coef_dict(self, ue_coef_dict: dict): def update_ue_coef_dict(self, ue_coef_dict: dict):
@ -163,7 +167,12 @@ class Module(db.Model):
def delete_ue_coef(self, ue): def delete_ue_coef(self, ue):
"""delete coef""" """delete coef"""
ue_coef = ModuleUECoef.query.get((self.id, ue.id)) ue_coef = ModuleUECoef.query.get((self.id, ue.id))
db.session.delete(ue_coef) if ue_coef:
db.session.delete(ue_coef)
def ue_coefs_descr(self):
"""List of tuples [ (ue_acronyme, coef) ]"""
return [(c.ue.acronyme, c.coef) for c in self.ue_coefs]
class ModuleUECoef(db.Model): class ModuleUECoef(db.Model):

View File

@ -37,6 +37,7 @@ import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ModuleType from app.scodoc.sco_utils import ModuleType
from app import log from app import log
from app import models
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
@ -344,9 +345,8 @@ def module_edit(module_id=None):
raise ScoValueError("invalid module !") raise ScoValueError("invalid module !")
module = modules[0] module = modules[0]
unlocked = not module_is_locked(module_id) unlocked = not module_is_locked(module_id)
formation = sco_formations.formation_list( formation_id = module["formation_id"]
args={"formation_id": module["formation_id"]} formation = sco_formations.formation_list(args={"formation_id": formation_id})[0]
)[0]
parcours = sco_codes_parcours.get_parcours_from_code(formation["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(formation["type_parcours"])
is_apc = parcours.APC_SAE is_apc = parcours.APC_SAE
ues_matieres = ndb.SimpleDictFetch( ues_matieres = ndb.SimpleDictFetch(
@ -356,7 +356,7 @@ def module_edit(module_id=None):
AND ue.formation_id = %(formation_id)s AND ue.formation_id = %(formation_id)s
ORDER BY ue.numero, mat.numero ORDER BY ue.numero, mat.numero
""", """,
{"formation_id": module["formation_id"]}, {"formation_id": formation_id},
) )
mat_names = ["%s / %s" % (x["acronyme"], x["titre"]) for x in ues_matieres] mat_names = ["%s / %s" % (x["acronyme"], x["titre"]) for x in ues_matieres]
ue_mat_ids = ["%s!%s" % (x["ue_id"], x["matiere_id"]) for x in ues_matieres] ue_mat_ids = ["%s!%s" % (x["ue_id"], x["matiere_id"]) for x in ues_matieres]
@ -366,7 +366,7 @@ def module_edit(module_id=None):
dest_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(module["formation_id"]), formation_id=str(formation_id),
) )
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(
@ -387,56 +387,72 @@ def module_edit(module_id=None):
"""<div class="ue_warning"><span>Formation verrouillée, seuls certains éléments peuvent être modifiés</span></div>""" """<div class="ue_warning"><span>Formation verrouillée, seuls certains éléments peuvent être modifiés</span></div>"""
) )
tf = TrivialFormulator( descr = [
request.base_url,
scu.get_request_args(),
( (
"code",
{
"size": 10,
"explanation": "code du module (doit être unique dans la formation)",
"allow_null": False,
"validator": lambda val, field, formation_id=formation_id: check_module_code_unicity(
val, field, formation_id, module_id=module_id
),
},
),
("titre", {"size": 30, "explanation": "nom du module"}),
("abbrev", {"size": 20, "explanation": "nom abrégé (pour bulletins)"}),
(
"module_type",
{
"input_type": "menu",
"title": "Type",
"explanation": "",
"labels": [x.name.capitalize() for x in scu.ModuleType],
"allowed_values": [str(int(x)) for x in scu.ModuleType],
"enabled": unlocked,
},
),
(
"heures_cours",
{"size": 4, "type": "float", "explanation": "nombre d'heures de cours"},
),
(
"heures_td",
{
"size": 4,
"type": "float",
"explanation": "nombre d'heures de Travaux Dirigés",
},
),
(
"heures_tp",
{
"size": 4,
"type": "float",
"explanation": "nombre d'heures de Travaux Pratiques",
},
),
]
if is_apc:
a_module = models.Module.query.get(module_id)
coefs_descr = a_module.ue_coefs_descr()
if coefs_descr:
coefs_descr_txt = ", ".join(["%s: %s" % x for x in coefs_descr])
else:
coefs_descr_txt = """<span class="missing_value">non définis</span>"""
descr += [
( (
"code", "ue_coefs",
{ {
"size": 10, "readonly": True,
"explanation": "code du module (doit être unique dans la formation)", "title": "Coefficients vers les UE",
"allow_null": False, "default": coefs_descr_txt,
"validator": lambda val, field, formation_id=module[ "explanation": "passer par la page d'édition de la formation pour modifier les coefficients",
"formation_id"
]: check_module_code_unicity(
val, field, formation_id, module_id=module_id
),
}, },
), )
("titre", {"size": 30, "explanation": "nom du module"}), ]
("abbrev", {"size": 20, "explanation": "nom abrégé (pour bulletins)"}), else: # Module classique avec coef scalaire:
( descr += [
"module_type",
{
"input_type": "menu",
"title": "Type",
"explanation": "",
"labels": [x.name.capitalize() for x in scu.ModuleType],
"allowed_values": [str(int(x)) for x in scu.ModuleType],
"enabled": unlocked,
},
),
(
"heures_cours",
{"size": 4, "type": "float", "explanation": "nombre d'heures de cours"},
),
(
"heures_td",
{
"size": 4,
"type": "float",
"explanation": "nombre d'heures de Travaux Dirigés",
},
),
(
"heures_tp",
{
"size": 4,
"type": "float",
"explanation": "nombre d'heures de Travaux Pratiques",
},
),
( (
"coefficient", "coefficient",
{ {
@ -447,51 +463,57 @@ def module_edit(module_id=None):
"enabled": unlocked, "enabled": unlocked,
}, },
), ),
# ('ects', { 'size' : 4, 'type' : 'float', 'title' : 'ECTS', 'explanation' : 'nombre de crédits ECTS', 'enabled' : unlocked }), ]
("formation_id", {"input_type": "hidden"}), descr += [
("ue_id", {"input_type": "hidden"}), ("formation_id", {"input_type": "hidden"}),
("module_id", {"input_type": "hidden"}), ("ue_id", {"input_type": "hidden"}),
( ("module_id", {"input_type": "hidden"}),
"ue_matiere_id", (
{ "ue_matiere_id",
"input_type": "menu", {
"title": "Matière", "input_type": "menu",
"explanation": "un module appartient à une seule matière.", "title": "Matière",
"labels": mat_names, "explanation": "un module appartient à une seule matière.",
"allowed_values": ue_mat_ids, "labels": mat_names,
"enabled": unlocked, "allowed_values": ue_mat_ids,
}, "enabled": unlocked,
), },
(
"semestre_id",
{
"input_type": "menu",
"type": "int",
"title": parcours.SESSION_NAME.capitalize(),
"explanation": "%s de début du module dans la formation standard"
% parcours.SESSION_NAME,
"labels": [str(x) for x in semestres_indices],
"allowed_values": semestres_indices,
"enabled": unlocked,
},
),
(
"code_apogee",
{
"title": "Code Apogée",
"size": 25,
"explanation": "(optionnel) code élément pédagogique Apogée ou liste de codes ELP séparés par des virgules",
},
),
(
"numero",
{
"size": 2,
"explanation": "numéro (1,2,3,4...) pour ordre d'affichage",
"type": "int",
},
),
), ),
(
"semestre_id",
{
"input_type": "menu",
"type": "int",
"title": parcours.SESSION_NAME.capitalize(),
"explanation": "%s de début du module dans la formation standard"
% parcours.SESSION_NAME,
"labels": [str(x) for x in semestres_indices],
"allowed_values": semestres_indices,
"enabled": unlocked,
},
),
(
"code_apogee",
{
"title": "Code Apogée",
"size": 25,
"explanation": "(optionnel) code élément pédagogique Apogée ou liste de codes ELP séparés par des virgules",
},
),
(
"numero",
{
"size": 2,
"explanation": "numéro (1,2,3,4...) pour ordre d'affichage",
"type": "int",
},
),
]
tf = TrivialFormulator(
request.base_url,
scu.get_request_args(),
descr,
html_foot_markup="""<div style="width: 90%;"><span class="sco_tag_edit"><textarea data-module_id="{}" class="module_tag_editor">{}</textarea></span></div>""".format( html_foot_markup="""<div style="width: 90%;"><span class="sco_tag_edit"><textarea data-module_id="{}" class="module_tag_editor">{}</textarea></span></div>""".format(
module_id, ",".join(sco_tag_module.module_tag_list(module_id)) module_id, ",".join(sco_tag_module.module_tag_list(module_id))
), ),

View File

@ -453,6 +453,7 @@ def ue_table(formation_id=None, msg=""): # was ue_list
raise ScoValueError("invalid formation_id") raise ScoValueError("invalid formation_id")
F = F[0] F = F[0]
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
is_apc = parcours.APC_SAE
locked = sco_formations.formation_has_locked_sems(formation_id) locked = sco_formations.formation_has_locked_sems(formation_id)
ues = ue_list(args={"formation_id": formation_id, "is_external": False}) ues = ue_list(args={"formation_id": formation_id, "is_external": False})
@ -568,7 +569,18 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
) )
H.append("</div>") H.append("</div>")
# Formation APC (BUT) ?
if is_apc:
H.append(
f"""<div class="formation_apc_infos">
<div class="ue_list_tit">Formation par compétences (BUT)</div>
<ul>
<li><a class="stdlink" href="{
url_for('notes.edit_modules_ue_coefs', scodoc_dept=g.scodoc_dept, formation_id=formation_id)
}">éditer les coefficients des ressources et SAÉs</a></li>
</ul>
</div>"""
)
# Description des UE/matières/modules # Description des UE/matières/modules
H.append('<div class="formation_ue_list">') H.append('<div class="formation_ue_list">')
H.append('<div class="ue_list_tit">Programme pédagogique:</div>') H.append('<div class="ue_list_tit">Programme pédagogique:</div>')

View File

@ -1606,6 +1606,11 @@ div.ue_warning span {
font-weight: bold; font-weight: bold;
} }
span.missing_value {
font-weight: bold;
color: red;
}
/* tableau recap notes */ /* tableau recap notes */
table.notes_recapcomplet { table.notes_recapcomplet {
border: 2px solid blue; border: 2px solid blue;

View File

@ -105,3 +105,7 @@ def test_modules_coefs(test_client):
mod.delete_ue_coef(ue1) mod.delete_ue_coef(ue1)
db.session.commit() db.session.commit()
assert len(mod.ue_coefs) == 1 assert len(mod.ue_coefs) == 1
# Gestion des coefs nuls:
mod.set_ue_coef(ue2, 0.0)
db.session.commit()
assert len(mod.ue_coefs) == 0