BUT: assoc. modules <-> App. Critiques

This commit is contained in:
Emmanuel Viennet 2022-05-02 14:39:06 +02:00
parent f537cd2e48
commit 96248ccfd3
6 changed files with 145 additions and 29 deletions

View File

@ -286,6 +286,21 @@ class ApcNiveau(db.Model, XMLModel):
) )
app_critiques_modules = db.Table(
"apc_modules_acs",
db.Column(
"module_id",
db.ForeignKey("notes_modules.id", ondelete="CASCADE"),
primary_key=True,
),
db.Column(
"app_crit_id",
db.ForeignKey("apc_app_critique.id"),
primary_key=True,
),
)
class ApcAppCritique(db.Model, XMLModel): class ApcAppCritique(db.Model, XMLModel):
"Apprentissage Critique BUT" "Apprentissage Critique BUT"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
@ -293,12 +308,31 @@ class ApcAppCritique(db.Model, XMLModel):
code = db.Column(db.Text(), nullable=False, index=True) code = db.Column(db.Text(), nullable=False, index=True)
libelle = db.Column(db.Text()) libelle = db.Column(db.Text())
modules = db.relationship( # modules = db.relationship(
"Module", # "Module",
secondary="apc_modules_acs", # secondary="apc_modules_acs",
lazy="dynamic", # lazy="dynamic",
backref=db.backref("app_critiques", lazy="dynamic"), # backref=db.backref("app_critiques", lazy="dynamic"),
) # )
@classmethod
def app_critiques_ref_comp(
cls,
ref_comp: ApcReferentielCompetences,
annee: str,
competence: ApcCompetence = None,
) -> flask_sqlalchemy.BaseQuery:
"Liste les AC de tous les parcours de ref_comp pour l'année indiquée"
assert annee in {"BUT1", "BUT2", "BUT3"}
query = cls.query.filter(
ApcAppCritique.niveau_id == ApcNiveau.id,
ApcNiveau.competence_id == ApcCompetence.id,
ApcNiveau.annee == annee,
ApcCompetence.referentiel_id == ref_comp.id,
)
if competence is not None:
query = query.filter(ApcNiveau.competence == competence)
return query
def to_dict(self) -> dict: def to_dict(self) -> dict:
return {"libelle": self.libelle} return {"libelle": self.libelle}
@ -314,13 +348,6 @@ class ApcAppCritique(db.Model, XMLModel):
return [m for m in self.modules if m.module_type == ModuleType.SAE] return [m for m in self.modules if m.module_type == ModuleType.SAE]
ApcAppCritiqueModules = db.Table(
"apc_modules_acs",
db.Column("module_id", db.ForeignKey("notes_modules.id")),
db.Column("app_crit_id", db.ForeignKey("apc_app_critique.id")),
)
parcours_modules = db.Table( parcours_modules = db.Table(
"parcours_modules", "parcours_modules",
db.Column( db.Column(
@ -350,11 +377,6 @@ class ApcParcours(db.Model, XMLModel):
lazy="dynamic", lazy="dynamic",
cascade="all, delete-orphan", cascade="all, delete-orphan",
) )
# modules = db.relationship(
# "Module",
# secondary=parcours_modules,
# back_populates="parcours",
# )
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__name__} {self.code}>" return f"<{self.__class__.__name__} {self.code}>"

View File

@ -3,7 +3,7 @@
from app import db from app import db
from app.models import APO_CODE_STR_LEN from app.models import APO_CODE_STR_LEN
from app.models.but_refcomp import parcours_modules from app.models.but_refcomp import app_critiques_modules, parcours_modules
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
from app.scodoc.sco_codes_parcours import UE_SPORT from app.scodoc.sco_codes_parcours import UE_SPORT
from app.scodoc.sco_utils import ModuleType from app.scodoc.sco_utils import ModuleType
@ -50,7 +50,13 @@ class Module(db.Model):
"ApcParcours", "ApcParcours",
secondary=parcours_modules, secondary=parcours_modules,
lazy="subquery", lazy="subquery",
# cascade="all, delete", backref=db.backref("modules", lazy=True),
)
app_critiques = db.relationship(
"ApcAppCritique",
secondary=app_critiques_modules,
lazy="subquery",
backref=db.backref("modules", lazy=True), backref=db.backref("modules", lazy=True),
) )

View File

@ -127,7 +127,7 @@ def html_edit_formation_apc(
formation=formation, formation=formation,
titre=f"Ressources du S{semestre_idx}", titre=f"Ressources du S{semestre_idx}",
create_element_msg="créer une nouvelle ressource", create_element_msg="créer une nouvelle ressource",
matiere_parent=matiere_parent, # matiere_parent=matiere_parent,
modules=ressources_in_sem, modules=ressources_in_sem,
module_type=ModuleType.RESSOURCE, module_type=ModuleType.RESSOURCE,
editable=editable, editable=editable,
@ -143,7 +143,7 @@ def html_edit_formation_apc(
formation=formation, formation=formation,
titre=f"Situations d'Apprentissage et d'Évaluation (SAÉs) S{semestre_idx}", titre=f"Situations d'Apprentissage et d'Évaluation (SAÉs) S{semestre_idx}",
create_element_msg="créer une nouvelle SAÉ", create_element_msg="créer une nouvelle SAÉ",
matiere_parent=matiere_parent, # matiere_parent=matiere_parent,
modules=saes_in_sem, modules=saes_in_sem,
module_type=ModuleType.SAE, module_type=ModuleType.SAE,
editable=editable, editable=editable,

View File

@ -39,7 +39,7 @@ from app.models import APO_CODE_STR_LEN
from app.models import Formation, Matiere, Module, UniteEns from app.models import Formation, Matiere, Module, UniteEns
from app.models import FormSemestre, ModuleImpl from app.models import FormSemestre, ModuleImpl
from app.models import ScolarNews from app.models import ScolarNews
from app.models.but_refcomp import ApcParcours from app.models.but_refcomp import ApcAppCritique, 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
@ -272,6 +272,7 @@ def module_edit(
# --- Détermination de la formation # --- Détermination de la formation
orig_semestre_idx = None orig_semestre_idx = None
ue = None
if create: if create:
if matiere_id: if matiere_id:
matiere = Matiere.query.get_or_404(matiere_id) matiere = Matiere.query.get_or_404(matiere_id)
@ -286,6 +287,7 @@ def module_edit(
if not module_id: if not module_id:
raise ValueError("missing module_id !") raise ValueError("missing module_id !")
module = models.Module.query.get_or_404(module_id) module = models.Module.query.get_or_404(module_id)
ue = module.ue
module_dict = module.to_dict() module_dict = module.to_dict()
formation = module.formation formation = module.formation
unlocked = not module_is_locked(module_id) unlocked = not module_is_locked(module_id)
@ -633,8 +635,9 @@ def module_edit(
}, },
), ),
] ]
# Choix des parcours
if is_apc: if is_apc:
# Choix des parcours
ref_comp = formation.referentiel_competence ref_comp = formation.referentiel_competence
if ref_comp: if ref_comp:
descr += [ descr += [
@ -656,13 +659,54 @@ def module_edit(
module_dict["parcours"] = [ module_dict["parcours"] = [
str(parcour.id) for parcour in module.parcours str(parcour.id) for parcour in module.parcours
] ]
module_dict["app_critiques"] = [
str(app_crit.id) for app_crit in module.app_critiques
]
# Choix des Apprentissages Critiques
if ue is not None:
annee = f"BUT{orig_semestre_idx//2 + 1}"
app_critiques = ApcAppCritique.app_critiques_ref_comp(ref_comp, annee)
descr += (
[
(
"app_critiques",
{
"title": "Apprentissages Critiques",
"input_type": "checkbox",
"vertical": True,
"dom_id": "tf_module_app_critiques",
"labels": [
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.",
},
)
]
if (ue.niveau_competence is not None)
else [
(
"app_critiques",
{
"input_type": "separator",
"title": f"""<span class="fontred">{scu.EMO_WARNING }
L'UE {ue.acronyme} {ue.titre}
n'est pas associée à un niveau de compétences
</span>""",
},
)
]
)
else: else:
descr += [ descr += [
( (
"parcours", "parcours",
{ {
"input_type": "separator", "input_type": "separator",
"title": f"""<span class="fontred">Pas de parcours: "title": f"""<span class="fontred">{scu.EMO_WARNING }
Pas de parcours:
<a class="stdlink" href="{ url_for('notes.refcomp_assoc_formation', <a class="stdlink" href="{ url_for('notes.refcomp_assoc_formation',
scodoc_dept=g.scodoc_dept, formation_id=formation.id) scodoc_dept=g.scodoc_dept, formation_id=formation.id)
}">associer un référentiel de compétence</a> }">associer un référentiel de compétence</a>
@ -748,10 +792,17 @@ def module_edit(
# #
do_module_edit(tf[2]) do_module_edit(tf[2])
# Modifie les parcours # Modifie les parcours
module.parcours = [ if "parcours" in tf[2]:
ApcParcours.query.get(int(parcour_id_str)) module.parcours = [
for parcour_id_str in tf[2]["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 = [
ApcAppCritique.query.get(int(ac_id_str))
for ac_id_str in tf[2]["app_critiques"]
]
db.session.add(module) db.session.add(module)
db.session.commit() db.session.commit()
return flask.redirect( return flask.redirect(

View File

@ -2271,6 +2271,10 @@ tr#tf_module_parcours>td {
background-color: rgb(229, 229, 229); background-color: rgb(229, 229, 229);
} }
tr#tf_module_app_critiques>td {
background-color: rgb(194, 209, 228);
}
/* tableau recap notes */ /* tableau recap notes */
table.notes_recapcomplet { table.notes_recapcomplet {
border: 2px solid blue; border: 2px solid blue;

View File

@ -47,6 +47,23 @@ def upgrade():
), ),
sa.PrimaryKeyConstraint("parcours_id", "module_id"), sa.PrimaryKeyConstraint("parcours_id", "module_id"),
) )
op.alter_column(
"apc_modules_acs", "module_id", existing_type=sa.INTEGER(), nullable=False
)
op.alter_column(
"apc_modules_acs", "app_crit_id", existing_type=sa.INTEGER(), nullable=False
)
op.drop_constraint(
"apc_modules_acs_module_id_fkey", "apc_modules_acs", type_="foreignkey"
)
op.create_foreign_key(
"apc_modules_acs_module_id_fkey",
"apc_modules_acs",
"notes_modules",
["module_id"],
["id"],
ondelete="CASCADE",
)
# ### end Alembic commands ### # ### end Alembic commands ###
@ -57,4 +74,20 @@ def downgrade():
) )
op.drop_column("notes_ue", "niveau_competence_id") op.drop_column("notes_ue", "niveau_competence_id")
op.drop_table("parcours_modules") op.drop_table("parcours_modules")
op.drop_constraint(
"apc_modules_acs_module_id_fkey", "apc_modules_acs", type_="foreignkey"
)
op.create_foreign_key(
"apc_modules_acs_module_id_fkey",
"apc_modules_acs",
"notes_modules",
["module_id"],
["id"],
)
op.alter_column(
"apc_modules_acs", "app_crit_id", existing_type=sa.INTEGER(), nullable=True
)
op.alter_column(
"apc_modules_acs", "module_id", existing_type=sa.INTEGER(), nullable=True
)
# ### end Alembic commands ### # ### end Alembic commands ###