BUT: dispenses d'UE capitalisées. Voir #537.
This commit is contained in:
parent
02ec55ca18
commit
c8c05ecd77
@ -33,7 +33,10 @@ import pandas as pd
|
|||||||
from app import db
|
from app import db
|
||||||
from app import models
|
from app import models
|
||||||
from app.models import (
|
from app.models import (
|
||||||
|
DispenseUE,
|
||||||
FormSemestre,
|
FormSemestre,
|
||||||
|
FormSemestreInscription,
|
||||||
|
Identite,
|
||||||
Module,
|
Module,
|
||||||
ModuleImpl,
|
ModuleImpl,
|
||||||
ModuleUECoef,
|
ModuleUECoef,
|
||||||
@ -215,6 +218,31 @@ def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def load_dispense_ues(
|
||||||
|
formsemestre: FormSemestre, etudids: pd.Index, ues: list[UniteEns]
|
||||||
|
) -> set[tuple[int, int]]:
|
||||||
|
"""Construit l'ensemble des
|
||||||
|
etudids = modimpl_inscr_df.index, # les etudids
|
||||||
|
ue_ids : modimpl_coefs_df.index, # les UE du formsemestre sans les UE bonus sport
|
||||||
|
|
||||||
|
Résultat: set de (etudid, ue_id).
|
||||||
|
"""
|
||||||
|
dispense_ues = set()
|
||||||
|
ue_sem_by_code = {ue.ue_code: ue for ue in ues}
|
||||||
|
# Prend toutes les dispenses obtenues par des étudiants de ce formsemestre,
|
||||||
|
# puis filtre sur inscrits et code d'UE UE
|
||||||
|
for dispense_ue in DispenseUE.query.join(
|
||||||
|
Identite, FormSemestreInscription
|
||||||
|
).filter_by(formsemestre_id=formsemestre.id):
|
||||||
|
if dispense_ue.etudid in etudids:
|
||||||
|
# UE dans le semestre avec même code ?
|
||||||
|
ue = ue_sem_by_code.get(dispense_ue.ue.ue_code)
|
||||||
|
if ue is not None:
|
||||||
|
dispense_ues.add((dispense_ue.etudid, ue.id))
|
||||||
|
|
||||||
|
return dispense_ues
|
||||||
|
|
||||||
|
|
||||||
def compute_ue_moys_apc(
|
def compute_ue_moys_apc(
|
||||||
sem_cube: np.array,
|
sem_cube: np.array,
|
||||||
etuds: list,
|
etuds: list,
|
||||||
|
@ -72,7 +72,7 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
modimpl.module.ue.type != UE_SPORT
|
modimpl.module.ue.type != UE_SPORT
|
||||||
for modimpl in self.formsemestre.modimpls_sorted
|
for modimpl in self.formsemestre.modimpls_sorted
|
||||||
]
|
]
|
||||||
self.dispense_ues = DispenseUE.load_formsemestre_dispense_ues_set(
|
self.dispense_ues = moy_ue.load_dispense_ues(
|
||||||
self.formsemestre, self.modimpl_inscr_df.index, self.ues
|
self.formsemestre, self.modimpl_inscr_df.index, self.ues
|
||||||
)
|
)
|
||||||
self.etud_moy_ue = moy_ue.compute_ue_moys_apc(
|
self.etud_moy_ue = moy_ue.compute_ue_moys_apc(
|
||||||
|
@ -65,10 +65,6 @@ class Identite(db.Model):
|
|||||||
passive_deletes=True,
|
passive_deletes=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Relations avec les assiduites et les justificatifs
|
|
||||||
assiduites = db.relationship("Assiduite", backref="etudiant", lazy="dynamic")
|
|
||||||
justificatifs = db.relationship("Justificatif", backref="etudiant", lazy="dynamic")
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (
|
return (
|
||||||
f"<Etud {self.id}/{self.departement.acronym} {self.nom!r} {self.prenom!r}>"
|
f"<Etud {self.id}/{self.departement.acronym} {self.nom!r} {self.prenom!r}>"
|
||||||
|
@ -256,23 +256,12 @@ class UniteEns(db.Model):
|
|||||||
|
|
||||||
class DispenseUE(db.Model):
|
class DispenseUE(db.Model):
|
||||||
"""Dispense d'UE
|
"""Dispense d'UE
|
||||||
Utilisé en APC (BUT) pour indiquer les étudiants redoublants avec une UE capitalisée
|
Utilisé en PCC (BUT) pour indiquer les étudiants redoublants avec une UE capitalisée
|
||||||
qu'ils ne refont pas.
|
qu'ils ne refont pas.
|
||||||
La dispense d'UE n'est PAS une validation:
|
|
||||||
- elle n'est pas affectée par les décisions de jury (pas effacée)
|
|
||||||
- elle est associée à un formsemestre
|
|
||||||
- elle ne permet pas la délivrance d'ECTS ou du diplôme.
|
|
||||||
|
|
||||||
On utilise cette dispense et non une "inscription" par souci d'efficacité:
|
|
||||||
en général, la grande majorité des étudiants suivront toutes les UEs de leur parcours,
|
|
||||||
la dispense étant une exception.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "ue_id", "etudid"),)
|
__table_args__ = (db.UniqueConstraint("ue_id", "etudid"),)
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
formsemestre_id = formsemestre_id = db.Column(
|
|
||||||
db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True
|
|
||||||
)
|
|
||||||
ue_id = db.Column(
|
ue_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey(UniteEns.id, ondelete="CASCADE"),
|
db.ForeignKey(UniteEns.id, ondelete="CASCADE"),
|
||||||
@ -291,25 +280,3 @@ class DispenseUE(db.Model):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"""<{self.__class__.__name__} {self.id} etud={
|
return f"""<{self.__class__.__name__} {self.id} etud={
|
||||||
repr(self.etud)} ue={repr(self.ue)}>"""
|
repr(self.etud)} ue={repr(self.ue)}>"""
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def load_formsemestre_dispense_ues_set(
|
|
||||||
cls, formsemestre: "FormSemestre", etudids: pd.Index, ues: list[UniteEns]
|
|
||||||
) -> set[tuple[int, int]]:
|
|
||||||
"""Construit l'ensemble des
|
|
||||||
etudids = modimpl_inscr_df.index, # les etudids
|
|
||||||
ue_ids : modimpl_coefs_df.index, # les UE du formsemestre sans les UE bonus sport
|
|
||||||
|
|
||||||
Résultat: set de (etudid, ue_id).
|
|
||||||
"""
|
|
||||||
# Prend toutes les dispenses obtenues par des étudiants de ce formsemestre,
|
|
||||||
# puis filtre sur inscrits et ues
|
|
||||||
ue_ids = {ue.id for ue in ues}
|
|
||||||
dispense_ues = {
|
|
||||||
(dispense_ue.etudid, dispense_ue.ue_id)
|
|
||||||
for dispense_ue in DispenseUE.query.filter_by(
|
|
||||||
formsemestre_id=formsemestre.id
|
|
||||||
)
|
|
||||||
if dispense_ue.etudid in etudids and dispense_ue.ue_id in ue_ids
|
|
||||||
}
|
|
||||||
return dispense_ues
|
|
||||||
|
@ -36,7 +36,7 @@ from flask_login import current_user
|
|||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
|
|
||||||
from app.models import Evaluation, ModuleImpl, ScolarNews
|
from app.models import ModuleImpl, ScolarNews
|
||||||
from app.models.evaluations import evaluation_enrich_dict, check_evaluation_args
|
from app.models.evaluations import evaluation_enrich_dict, check_evaluation_args
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
|
@ -400,9 +400,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
|||||||
# Etudiants "dispensés" d'une UE (capitalisée)
|
# Etudiants "dispensés" d'une UE (capitalisée)
|
||||||
ues_cap_info = get_etuds_with_capitalized_ue(formsemestre_id)
|
ues_cap_info = get_etuds_with_capitalized_ue(formsemestre_id)
|
||||||
if ues_cap_info:
|
if ues_cap_info:
|
||||||
H.append(
|
H.append('<h3>Étudiants avec UEs capitalisées:</h3><ul class="ue_inscr_list">')
|
||||||
'<h3>Étudiants avec UEs capitalisées (ADM):</h3><ul class="ue_inscr_list">'
|
|
||||||
)
|
|
||||||
ues = [
|
ues = [
|
||||||
sco_edit_ue.ue_list({"ue_id": ue_id})[0] for ue_id in ues_cap_info.keys()
|
sco_edit_ue.ue_list({"ue_id": ue_id})[0] for ue_id in ues_cap_info.keys()
|
||||||
]
|
]
|
||||||
@ -470,8 +468,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
|||||||
if can_change:
|
if can_change:
|
||||||
H.append(
|
H.append(
|
||||||
f"""<div><a class="stdlink" href="{
|
f"""<div><a class="stdlink" href="{
|
||||||
url_for("notes.etud_inscrit_ue",
|
url_for("notes.etud_inscrit_ue", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"],
|
||||||
scodoc_dept=g.scodoc_dept, etudid=etud["etudid"],
|
|
||||||
formsemestre_id=formsemestre_id, ue_id=ue["ue_id"])
|
formsemestre_id=formsemestre_id, ue_id=ue["ue_id"])
|
||||||
}">inscrire à {"" if is_apc else "tous les modules de"} cette UE</a></div>
|
}">inscrire à {"" if is_apc else "tous les modules de"} cette UE</a></div>
|
||||||
"""
|
"""
|
||||||
|
@ -1621,24 +1621,10 @@ def etud_desinscrit_ue(etudid, formsemestre_id, ue_id):
|
|||||||
ue = UniteEns.query.get_or_404(ue_id)
|
ue = UniteEns.query.get_or_404(ue_id)
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
if ue.formation.is_apc():
|
if ue.formation.is_apc():
|
||||||
if (
|
if DispenseUE.query.filter_by(etudid=etudid, ue_id=ue_id).count() == 0:
|
||||||
DispenseUE.query.filter_by(
|
disp = DispenseUE(ue_id=ue_id, etudid=etudid)
|
||||||
formsemestre_id=formsemestre_id, etudid=etudid, ue_id=ue_id
|
|
||||||
).count()
|
|
||||||
== 0
|
|
||||||
):
|
|
||||||
disp = DispenseUE(
|
|
||||||
formsemestre_id=formsemestre_id, ue_id=ue_id, etudid=etudid
|
|
||||||
)
|
|
||||||
db.session.add(disp)
|
db.session.add(disp)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
log(f"etud_desinscrit_ue {etud} {ue}")
|
|
||||||
Scolog.logdb(
|
|
||||||
method="etud_desinscrit_ue",
|
|
||||||
etudid=etud.id,
|
|
||||||
msg=f"Désinscription de l'UE {ue.acronyme} de {formsemestre.titre_annee()}",
|
|
||||||
commit=True,
|
|
||||||
)
|
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
||||||
else:
|
else:
|
||||||
sco_moduleimpl_inscriptions.do_etud_desinscrit_ue_classic(
|
sco_moduleimpl_inscriptions.do_etud_desinscrit_ue_classic(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.4.34"
|
SCOVERSION = "9.4.7"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -123,13 +123,7 @@ def test_ue_moy(test_client):
|
|||||||
modimpl.module.ue.type != UE_SPORT for modimpl in formsemestre.modimpls_sorted
|
modimpl.module.ue.type != UE_SPORT for modimpl in formsemestre.modimpls_sorted
|
||||||
]
|
]
|
||||||
etud_moy_ue = moy_ue.compute_ue_moys_apc(
|
etud_moy_ue = moy_ue.compute_ue_moys_apc(
|
||||||
sem_cube,
|
sem_cube, etuds, modimpls, modimpl_inscr_df, modimpl_coefs_df, modimpl_mask
|
||||||
etuds,
|
|
||||||
modimpls,
|
|
||||||
modimpl_inscr_df,
|
|
||||||
modimpl_coefs_df,
|
|
||||||
modimpl_mask,
|
|
||||||
set(),
|
|
||||||
)
|
)
|
||||||
assert etud_moy_ue[ue1.id][etudid] == n1
|
assert etud_moy_ue[ue1.id][etudid] == n1
|
||||||
assert etud_moy_ue[ue2.id][etudid] == n1
|
assert etud_moy_ue[ue2.id][etudid] == n1
|
||||||
|
Loading…
Reference in New Issue
Block a user