This commit is contained in:
Emmanuel Viennet 2023-09-05 21:27:14 +02:00
commit 6b43456a71
11 changed files with 170 additions and 110 deletions

View File

@ -601,9 +601,12 @@ def _create_singular(
moduleimpl_id = data.get("moduleimpl_id", False) moduleimpl_id = data.get("moduleimpl_id", False)
moduleimpl: ModuleImpl = None moduleimpl: ModuleImpl = None
if moduleimpl_id not in [False, None]: if moduleimpl_id not in [False, None, "", "-1"]:
if moduleimpl_id != "autre": if moduleimpl_id != "autre":
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first() try:
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
except ValueError:
moduleimpl = None
if moduleimpl is None: if moduleimpl is None:
errors.append("param 'moduleimpl_id': invalide") errors.append("param 'moduleimpl_id': invalide")
else: else:
@ -810,7 +813,7 @@ def _edit_singular(assiduite_unique, data):
moduleimpl: ModuleImpl = None moduleimpl: ModuleImpl = None
if moduleimpl_id is not False: if moduleimpl_id is not False:
if moduleimpl_id is not None: if moduleimpl_id not in [None, "", "-1"]:
if moduleimpl_id == "autre": if moduleimpl_id == "autre":
assiduite_unique.moduleimpl_id = None assiduite_unique.moduleimpl_id = None
external_data = ( external_data = (
@ -823,7 +826,13 @@ def _edit_singular(assiduite_unique, data):
assiduite_unique.external_data = external_data assiduite_unique.external_data = external_data
else: else:
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first() try:
moduleimpl = ModuleImpl.query.filter_by(
id=int(moduleimpl_id)
).first()
except ValueError:
moduleimpl = None
if moduleimpl is None: if moduleimpl is None:
errors.append("param 'moduleimpl_id': invalide") errors.append("param 'moduleimpl_id': invalide")
else: else:
@ -834,7 +843,7 @@ def _edit_singular(assiduite_unique, data):
else: else:
assiduite_unique.moduleimpl_id = moduleimpl_id assiduite_unique.moduleimpl_id = moduleimpl_id
else: else:
assiduite_unique.moduleimpl_id = moduleimpl_id assiduite_unique.moduleimpl_id = None
# Cas 3 : desc # Cas 3 : desc
desc = data.get("desc", False) desc = data.get("desc", False)

View File

@ -350,11 +350,15 @@ def compute_assiduites_justified(
if justificatifs is None: if justificatifs is None:
justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid).all() justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid).all()
justificatifs = [j for j in justificatifs if j.etat == EtatJustificatif.VALIDE]
assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid) assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid)
assiduites_justifiees: list[int] = [] assiduites_justifiees: list[int] = []
for assi in assiduites: for assi in assiduites:
if assi.etat == EtatAssiduite.PRESENT:
continue
if any( if any(
assi.date_debut >= j.date_debut and assi.date_fin <= j.date_fin assi.date_debut >= j.date_debut and assi.date_fin <= j.date_fin
for j in justificatifs for j in justificatifs

View File

@ -74,9 +74,11 @@ class Identite(db.Model):
) )
# Relations avec les assiduites et les justificatifs # Relations avec les assiduites et les justificatifs
assiduites = db.relationship("Assiduite", back_populates="etudiant", lazy="dynamic") assiduites = db.relationship(
"Assiduite", back_populates="etudiant", lazy="dynamic", cascade="all, delete"
)
justificatifs = db.relationship( justificatifs = db.relationship(
"Justificatif", back_populates="etudiant", lazy="dynamic" "Justificatif", back_populates="etudiant", lazy="dynamic", cascade="all, delete"
) )
def __repr__(self): def __repr__(self):

View File

@ -212,7 +212,7 @@ def get_assiduites_stats(
output: dict = {} output: dict = {}
calculator: CountCalculator = CountCalculator() calculator: CountCalculator = CountCalculator()
if "split" not in filtered: if filtered is None or "split" not in filtered:
calculator.compute_assiduites(assiduites) calculator.compute_assiduites(assiduites)
count: dict = calculator.to_dict() count: dict = calculator.to_dict()
@ -382,7 +382,10 @@ def justifies(justi: Justificatif, obj: bool = False) -> list[int] or Query:
def get_all_justified( def get_all_justified(
etudid: int, date_deb: datetime = None, date_fin: datetime = None etudid: int,
date_deb: datetime = None,
date_fin: datetime = None,
moduleimpl_id: int = None,
) -> Query: ) -> Query:
"""Retourne toutes les assiduités justifiées sur une période""" """Retourne toutes les assiduités justifiées sur une période"""
@ -393,7 +396,9 @@ def get_all_justified(
date_deb = scu.localize_datetime(date_deb) date_deb = scu.localize_datetime(date_deb)
date_fin = scu.localize_datetime(date_fin) date_fin = scu.localize_datetime(date_fin)
justified = Assiduite.query.filter_by(est_just=True, etudid=etudid) justified: Query = Assiduite.query.filter_by(est_just=True, etudid=etudid)
if moduleimpl_id is not None:
justified = justified.filter_by(moduleimpl_id=moduleimpl_id)
after = filter_by_date( after = filter_by_date(
justified, justified,
Assiduite, Assiduite,
@ -419,7 +424,7 @@ def get_assiduites_count(etudid: int, sem: dict) -> tuple[int, int]:
def formsemestre_get_assiduites_count( def formsemestre_get_assiduites_count(
etudid: int, formsemestre: FormSemestre etudid: int, formsemestre: FormSemestre, moduleimpl_id: int = None
) -> tuple[int, int]: ) -> tuple[int, int]:
"""Les comptes d'absences de cet étudiant dans ce semestre: """Les comptes d'absences de cet étudiant dans ce semestre:
tuple (nb abs non justifiées, nb abs justifiées) tuple (nb abs non justifiées, nb abs justifiées)
@ -428,9 +433,14 @@ def formsemestre_get_assiduites_count(
metrique = sco_preferences.get_preference("assi_metrique", formsemestre.id) metrique = sco_preferences.get_preference("assi_metrique", formsemestre.id)
return get_assiduites_count_in_interval( return get_assiduites_count_in_interval(
etudid, etudid,
date_debut=formsemestre.date_debut, date_debut=scu.localize_datetime(
date_fin=formsemestre.date_fin, datetime.combine(formsemestre.date_debut, time(8, 0))
),
date_fin=scu.localize_datetime(
datetime.combine(formsemestre.date_fin, time(18, 0))
),
metrique=scu.translate_assiduites_metric(metrique), metrique=scu.translate_assiduites_metric(metrique),
moduleimpl_id=moduleimpl_id,
) )
@ -441,6 +451,7 @@ def get_assiduites_count_in_interval(
metrique="demi", metrique="demi",
date_debut: datetime = None, date_debut: datetime = None,
date_fin: datetime = None, date_fin: datetime = None,
moduleimpl_id: int = None,
): ):
"""Les comptes d'absences de cet étudiant entre ces deux dates, incluses: """Les comptes d'absences de cet étudiant entre ces deux dates, incluses:
tuple (nb abs, nb abs justifiées) tuple (nb abs, nb abs justifiées)
@ -452,33 +463,39 @@ def get_assiduites_count_in_interval(
key = f"{etudid}_{date_debut_iso}_{date_fin_iso}{metrique}_assiduites" key = f"{etudid}_{date_debut_iso}_{date_fin_iso}{metrique}_assiduites"
r = sco_cache.AbsSemEtudCache.get(key) r = sco_cache.AbsSemEtudCache.get(key)
if not r: if not r or moduleimpl_id is not None:
date_debut: datetime = date_debut or datetime.fromisoformat(date_debut_iso) date_debut: datetime = date_debut or datetime.fromisoformat(date_debut_iso)
date_fin: datetime = date_fin or datetime.fromisoformat(date_fin_iso) date_fin: datetime = date_fin or datetime.fromisoformat(date_fin_iso)
assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid) assiduites: Query = Assiduite.query.filter_by(etudid=etudid)
assiduites = assiduites.filter(Assiduite.etat == scu.EtatAssiduite.ABSENT) assiduites = assiduites.filter(Assiduite.etat == scu.EtatAssiduite.ABSENT)
justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid) justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid)
assiduites = filter_by_date(assiduites, Assiduite, date_debut, date_fin) assiduites = filter_by_date(assiduites, Assiduite, date_debut, date_fin)
if moduleimpl_id is not None:
assiduites = assiduites.filter_by(moduleimpl_id=moduleimpl_id)
justificatifs = filter_by_date( justificatifs = filter_by_date(
justificatifs, Justificatif, date_debut, date_fin justificatifs, Justificatif, date_debut, date_fin
) )
calculator: CountCalculator = CountCalculator() calculator: CountCalculator = CountCalculator()
calculator.compute_assiduites(assiduites) calculator.compute_assiduites(assiduites)
nb_abs: dict = calculator.to_dict()[metrique] nb_abs: dict = calculator.to_dict()[metrique]
abs_just: list[Assiduite] = get_all_justified(etudid, date_debut, date_fin) abs_just: list[Assiduite] = get_all_justified(
etudid, date_debut, date_fin, moduleimpl_id
)
calculator.reset() calculator.reset()
calculator.compute_assiduites(abs_just) calculator.compute_assiduites(abs_just)
nb_abs_just: dict = calculator.to_dict()[metrique] nb_abs_just: dict = calculator.to_dict()[metrique]
r = (nb_abs, nb_abs_just) r = (nb_abs, nb_abs_just)
ans = sco_cache.AbsSemEtudCache.set(key, r) if moduleimpl_id is None:
if not ans: ans = sco_cache.AbsSemEtudCache.set(key, r)
log("warning: get_assiduites_count failed to cache") if not ans:
log("warning: get_assiduites_count failed to cache")
return r return r

View File

@ -237,7 +237,7 @@ def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
new_date: datetime.datetime = date new_date: datetime.datetime = date
if new_date.tzinfo is None: if new_date.tzinfo is None:
try: try:
new_date = timezone("Europe/Paris").localize(date) new_date = TIME_ZONE.localize(date)
except OverflowError: except OverflowError:
new_date = timezone("UTC").localize(date) new_date = timezone("UTC").localize(date)
return new_date return new_date

View File

@ -811,11 +811,8 @@ function numberTimeToDate(nb) {
* @param {boolean} clear vidage de l'objet "assiduites" ou non * @param {boolean} clear vidage de l'objet "assiduites" ou non
* @returns {object} l'objets Assiduités {<etudid:str> : [<assiduite>,]} * @returns {object} l'objets Assiduités {<etudid:str> : [<assiduite>,]}
*/ */
function getAssiduitesFromEtuds(clear, has_formsemestre = true, deb, fin) { function getAssiduitesFromEtuds(clear, deb, fin) {
const etudIds = Object.keys(etuds).join(","); const etudIds = Object.keys(etuds).join(",");
const formsemestre_id = has_formsemestre
? `formsemestre_id=${getFormSemestreId()}&`
: "";
const date_debut = deb ? deb : toIsoString(getPrevDate()); const date_debut = deb ? deb : toIsoString(getPrevDate());
const date_fin = fin ? fin : toIsoString(getNextDate()); const date_fin = fin ? fin : toIsoString(getNextDate());
@ -826,7 +823,7 @@ function getAssiduitesFromEtuds(clear, has_formsemestre = true, deb, fin) {
const url_api = const url_api =
getUrl() + getUrl() +
`/api/assiduites/group/query?date_debut=${date_debut}&${formsemestre_id}&date_fin=${date_fin}&etudids=${etudIds}`; `/api/assiduites/group/query?date_debut=${date_debut}&date_fin=${date_fin}&etudids=${etudIds}`;
sync_get(url_api, (data, status) => { sync_get(url_api, (data, status) => {
if (status === "success") { if (status === "success") {
const dataKeys = Object.keys(data); const dataKeys = Object.keys(data);
@ -924,14 +921,11 @@ function deleteAssiduite(assiduite_id) {
function hasModuleImpl(assiduite) { function hasModuleImpl(assiduite) {
if (assiduite.moduleimpl_id != null) return true; if (assiduite.moduleimpl_id != null) return true;
if ( return (
"external_data" in assiduite && assiduite.hasOwnProperty("external_data") &&
assiduite.external_data instanceof Object && assiduite.external_data != null &&
"module" in assiduite.external_data assiduite.external_data.hasOwnProperty("module")
) );
return true;
return false;
} }
/** /**
@ -1057,16 +1051,13 @@ function getAssiduiteValue(field) {
* Mise à jour des assiduités d'un étudiant * Mise à jour des assiduités d'un étudiant
* @param {String | Number} etudid identifiant de l'étudiant * @param {String | Number} etudid identifiant de l'étudiant
*/ */
function actualizeEtudAssiduite(etudid, has_formsemestre = true) { function actualizeEtudAssiduite(etudid) {
const formsemestre_id = has_formsemestre
? `formsemestre_id=${getFormSemestreId()}&`
: "";
const date_debut = toIsoString(getPrevDate()); const date_debut = toIsoString(getPrevDate());
const date_fin = toIsoString(getNextDate()); const date_fin = toIsoString(getNextDate());
const url_api = const url_api =
getUrl() + getUrl() +
`/api/assiduites/${etudid}/query?${formsemestre_id}date_debut=${date_debut}&date_fin=${date_fin}`; `/api/assiduites/${etudid}/query?date_debut=${date_debut}&date_fin=${date_fin}`;
sync_get(url_api, (data, status) => { sync_get(url_api, (data, status) => {
if (status === "success") { if (status === "success") {
assiduites[etudid] = data; assiduites[etudid] = data;
@ -1331,7 +1322,7 @@ function insertEtudRow(etud, index, output = false) {
* @param {String | Number} etudid l'identifiant de l'étudiant * @param {String | Number} etudid l'identifiant de l'étudiant
*/ */
function actualizeEtud(etudid) { function actualizeEtud(etudid) {
actualizeEtudAssiduite(etudid, !isSingleEtud()); actualizeEtudAssiduite(etudid);
//Actualize row //Actualize row
const etudHolder = document.querySelector(".etud_holder"); const etudHolder = document.querySelector(".etud_holder");
const ancient_row = document.getElementById(`etud_row_${etudid}`); const ancient_row = document.getElementById(`etud_row_${etudid}`);
@ -1412,10 +1403,10 @@ function setModuleImplId(assiduite, module = null) {
const moduleimpl = module == null ? getModuleImplId() : module; const moduleimpl = module == null ? getModuleImplId() : module;
if (moduleimpl === "autre") { if (moduleimpl === "autre") {
if ( if (
"external_data" in assiduite && assiduite.hasOwnProperty("external_data") &&
assiduite.external_data instanceof Object assiduite.external_data != null
) { ) {
if ("module" in assiduite.external_data) { if (assiduite.external_data.hasOwnProperty("module")) {
assiduite.external_data.module = "Autre"; assiduite.external_data.module = "Autre";
} else { } else {
assiduite["external_data"] = { module: "Autre" }; assiduite["external_data"] = { module: "Autre" };
@ -1427,10 +1418,10 @@ function setModuleImplId(assiduite, module = null) {
} else { } else {
assiduite["moduleimpl_id"] = moduleimpl; assiduite["moduleimpl_id"] = moduleimpl;
if ( if (
"external_data" in assiduite && assiduite.hasOwnProperty("external_data") &&
assiduite.external_data instanceof Object assiduite.external_data != null
) { ) {
if ("module" in assiduite.external_data) { if (assiduite.external_data.hasOwnProperty("module")) {
delete assiduite.external_data.module; delete assiduite.external_data.module;
} }
} }
@ -1482,9 +1473,9 @@ function getCurrentAssiduiteModuleImplId() {
let mod = currentAssiduites[0].moduleimpl_id; let mod = currentAssiduites[0].moduleimpl_id;
if ( if (
mod == null && mod == null &&
"external_data" in currentAssiduites[0] && currentAssiduites[0].hasOwnProperty("external_data") &&
currentAssiduites[0].external_data instanceof Object && currentAssiduites[0].external_data != null &&
"module" in currentAssiduites[0].external_data currentAssiduites[0].external_data.hasOwnProperty("module")
) { ) {
mod = currentAssiduites[0].external_data.module; mod = currentAssiduites[0].external_data.module;
} }
@ -1696,9 +1687,9 @@ function getModuleImpl(assiduite) {
if (id == null || id == undefined) { if (id == null || id == undefined) {
if ( if (
"external_data" in assiduite && assiduite.hasOwnProperty("external_data") &&
assiduite.external_data instanceof Object && assiduite.external_data != null &&
"module" in assiduite.external_data assiduite.external_data.hasOwnProperty("module")
) { ) {
return assiduite.external_data.module; return assiduite.external_data.module;
} else { } else {
@ -1724,10 +1715,12 @@ function getModuleImpl(assiduite) {
} }
function getUser(obj) { function getUser(obj) {
if ("external_data" in obj && obj.external_data != null) { if (
if ("enseignant" in obj.external_data) { obj.hasOwnProperty("external_data") &&
return obj.external_data.enseignant; obj.external_data != null &&
} obj.external_data.hasOwnProperty("enseignant")
) {
return obj.external_data.enseignant;
} }
return obj.user_id; return obj.user_id;

View File

@ -533,7 +533,7 @@
} }
if (get) { if (get) {
getAssiduitesFromEtuds(false, false, d_debut.format(), d_fin.format()) getAssiduitesFromEtuds(false, d_debut.format(), d_fin.format())
return 0x0; return 0x0;
} }

View File

@ -184,8 +184,11 @@
path, path,
(data) => { (data) => {
let module = data.moduleimpl_id; let module = data.moduleimpl_id;
if (
if (module == null && "external_data" in data && "module" in data.external_data) { module == null && data.hasOwnProperty("external_data") &&
data.external_data != null &&
data.external_data.hasOwnProperty('module')
) {
module = data.external_data.module.toLowerCase(); module = data.external_data.module.toLowerCase();
} }

View File

@ -1174,22 +1174,9 @@ def view_module_abs(moduleimpl_id, fmt="html"):
rows = [] rows = []
for etud in inscrits: for etud in inscrits:
# TODO-ASSIDUITE ne va pas car ne filtre pas sur le moduleimpl nb_abs, nb_abs_just = sco_assiduites.formsemestre_get_assiduites_count(
# nb_abs, nb_abs_just = sco_assiduites.formsemestre_get_assiduites_count(etud.id, modimpl.formsemestre) etud.id, modimpl.formsemestre, moduleimpl_id=modimpl.id
nb_abs, nb_abs_just = 0, 0 # XXX TODO-ASSIDUITE )
# nb_abs = sco_abs.count_abs(
# etudid=etud.id,
# debut=debut_sem,
# fin=fin_sem,
# moduleimpl_id=moduleimpl_id,
# )
# if nb_abs:
# nb_abs_just = sco_abs.count_abs_just(
# etudid=etud.id,
# debut=debut_sem,
# fin=fin_sem,
# moduleimpl_id=moduleimpl_id,
# )
rows.append( rows.append(
{ {
"nomprenom": etud.nomprenom, "nomprenom": etud.nomprenom,

View File

@ -13,8 +13,7 @@ import app.scodoc.sco_assiduites as scass
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app import db from app import db
from app.models import Assiduite, FormSemestre, Identite, Justificatif, ModuleImpl from app.models import Assiduite, FormSemestre, Identite, Justificatif, ModuleImpl
from app.models.assiduites import compute_assiduites_justified
# from app.scodoc import sco_abs_views, sco_formsemestre TODO-ASSIDUITE
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from tests.unit import sco_fake_gen from tests.unit import sco_fake_gen
@ -39,7 +38,6 @@ def test_bi_directional_enum(test_client):
assert BiInt.inverse()[1] == BiInt.A and BiInt.inverse()[2] == BiInt.B assert BiInt.inverse()[1] == BiInt.A and BiInt.inverse()[2] == BiInt.B
@pytest.mark.skip # XXX TODO-ASSIDUITE (issue #690)
def test_general(test_client): def test_general(test_client):
"""tests général du modèle assiduite""" """tests général du modèle assiduite"""
@ -80,11 +78,9 @@ def test_general(test_client):
date_fin="31/07/2024", date_fin="31/07/2024",
) )
formsemestre_1 = sco_formsemestre.get_formsemestre( formsemestre_1 = FormSemestre.get_formsemestre(formsemestre_id_1)
formsemestre_id_1 formsemestre_2 = FormSemestre.get_formsemestre(formsemestre_id_2)
) # Utiliser plutot FormSemestre de nos jours TODO-ASSIDUITE formsemestre_3 = FormSemestre.get_formsemestre(formsemestre_id_3)
formsemestre_2 = sco_formsemestre.get_formsemestre(formsemestre_id_2)
formsemestre_3 = sco_formsemestre.get_formsemestre(formsemestre_id_3)
# Création des modulesimpls (4, 2 par semestre) # Création des modulesimpls (4, 2 par semestre)
@ -137,7 +133,7 @@ def test_general(test_client):
etud_faux_dict = g_fake.create_etud(code_nip=None, prenom="etudfaux") etud_faux_dict = g_fake.create_etud(code_nip=None, prenom="etudfaux")
etud_faux = Identite.query.filter_by(id=etud_faux_dict["id"]).first() etud_faux = Identite.query.filter_by(id=etud_faux_dict["id"]).first()
# verif_migration_abs_assiduites() // Test à revoir TODO-ASSIDUITE # verif_migration_abs_assiduites() // Test à revoir TODO-ASSIDUITE (issue #696)
ajouter_assiduites(etuds, moduleimpls, etud_faux) ajouter_assiduites(etuds, moduleimpls, etud_faux)
justificatifs: list[Justificatif] = ajouter_justificatifs(etuds[0]) justificatifs: list[Justificatif] = ajouter_justificatifs(etuds[0])
@ -145,11 +141,14 @@ def test_general(test_client):
etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3) etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3)
) )
verifier_filtrage_justificatifs(etuds[0], justificatifs) verifier_filtrage_justificatifs(etuds[0], justificatifs)
essais_cache(etuds[0].etudid, (formsemestre_1, formsemestre_2), moduleimpls)
editer_supprimer_assiduites(etuds, moduleimpls) editer_supprimer_assiduites(etuds, moduleimpls)
editer_supprimer_justificatif(etuds[0]) editer_supprimer_justificatif(etuds[0])
@pytest.mark.skip # XXX TODO-ASSIDUITE (issue #696) # XXX TODO-ASSIDUITE (issue #696)
def verif_migration_abs_assiduites(): def verif_migration_abs_assiduites():
"""Vérification que le script de migration fonctionne correctement""" """Vérification que le script de migration fonctionne correctement"""
downgrade_module(assiduites=True, justificatifs=True) downgrade_module(assiduites=True, justificatifs=True)
@ -476,11 +475,11 @@ def _get_justi(
).first() ).first()
def essais_cache(etudid): def essais_cache(etudid, sems: tuple[FormSemestre], moduleimpls: list[ModuleImpl]):
"""Vérification des fonctionnalités du cache""" """Vérification des fonctionnalités du cache"""
date_deb: str = "2023-01-01T07:00" date_deb: str = "2022-09-01T07:00"
date_fin: str = "2023-03-31T19:00" date_fin: str = "2023-01-31T19:00"
assiduites_count_no_cache = scass.get_assiduites_count_in_interval( assiduites_count_no_cache = scass.get_assiduites_count_in_interval(
etudid, date_deb, date_fin etudid, date_deb, date_fin
@ -490,8 +489,36 @@ def essais_cache(etudid):
) )
assert ( assert (
assiduites_count_cache == assiduites_count_no_cache == (34, 15) assiduites_count_cache == assiduites_count_no_cache == (2, 1)
), "Erreur cache" ), "Erreur cache classique"
assert scass.formsemestre_get_assiduites_count(etudid, sems[0]) == (
2,
1,
), "Erreur formsemestre_get_assiduites_count (sans module) A"
assert scass.formsemestre_get_assiduites_count(etudid, sems[1]) == (
0,
0,
), "Erreur formsemestre_get_assiduites_count (sans module) B"
assert scass.formsemestre_get_assiduites_count(
etudid, sems[0], moduleimpl_id=moduleimpls[0].id
) == (
1,
1,
), "Erreur formsemestre_get_assiduites_count (avec module) A"
assert scass.formsemestre_get_assiduites_count(
etudid, sems[0], moduleimpl_id=moduleimpls[1].id
) == (
1,
0,
), "Erreur formsemestre_get_assiduites_count (avec module) A"
assert scass.formsemestre_get_assiduites_count(
etudid, sems[0], moduleimpl_id=moduleimpls[2].id
) == (
0,
0,
), "Erreur formsemestre_get_assiduites_count (avec module) A"
def ajouter_justificatifs(etud): def ajouter_justificatifs(etud):
@ -543,6 +570,8 @@ def ajouter_justificatifs(etud):
db.session.commit() db.session.commit()
justificatifs.append(just_obj) justificatifs.append(just_obj)
compute_assiduites_justified(etud.etudid, justificatifs)
# Vérification de la création des justificatifs # Vérification de la création des justificatifs
assert [ assert [
justi for justi in justificatifs if not isinstance(justi, Justificatif) justi for justi in justificatifs if not isinstance(justi, Justificatif)
@ -858,7 +887,7 @@ def ajouter_assiduites(
def verifier_comptage_et_filtrage_assiduites( def verifier_comptage_et_filtrage_assiduites(
etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[int] etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[FormSemestre]
): ):
""" """
Deuxième partie: Deuxième partie:
@ -931,9 +960,6 @@ def verifier_comptage_et_filtrage_assiduites(
), "Filtrage par 'Moduleimpl' mauvais" ), "Filtrage par 'Moduleimpl' mauvais"
# Formsemestre # Formsemestre
formsemestres = [
FormSemestre.query.filter_by(id=fms["id"]).first() for fms in formsemestres
]
assert ( assert (
scass.filter_by_formsemestre( scass.filter_by_formsemestre(
etu1.assiduites, Assiduite, formsemestres[0] etu1.assiduites, Assiduite, formsemestres[0]

View File

@ -23,15 +23,18 @@ import app
from app import db from app import db
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre, Assiduite, Justificatif
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
from app.scodoc import codes_cursus from app.scodoc import codes_cursus
from app.scodoc import sco_assiduites as scass
from app.scodoc import sco_evaluations 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_formsemestre_validation from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_cursus_dut from app.scodoc import sco_cursus_dut
from app.scodoc import sco_saisie_notes from app.scodoc import sco_saisie_notes
from app.scodoc.sco_utils import EtatAssiduite, EtatJustificatif, localize_datetime
from app.models.assiduites import compute_assiduites_justified
DEPT = TestConfig.DEPT_TEST DEPT = TestConfig.DEPT_TEST
@ -186,21 +189,10 @@ def run_sco_basic(verbose=False) -> FormSemestre:
# ----------------------- # -----------------------
etudid = etuds[0]["etudid"] etudid = etuds[0]["etudid"]
# XXX TODO-ASSIDUITE _signal_absences_justificatifs(etudid)
# _ = sco_abs_views.doSignaleAbsence( nbabs, nbabsjust = scass.get_assiduites_count(etudid, sem)
# "15/01/2020", "18/01/2020", demijournee=2, etudid=etudid assert nbabs == 6, f"incorrect nbabs ({nbabs})"
# ) assert nbabsjust == 2, f"incorrect nbabsjust ({nbabsjust})"
# _ = sco_abs_views.doJustifAbsence(
# "17/01/2020",
# "18/01/2020",
# demijournee=2,
# etudid=etudid,
# )
# nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
# assert nbabs == 6, f"incorrect nbabs ({nbabs})"
# assert nbabsjust == 2, f"incorrect nbabsjust ({nbabsjust})"
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance # --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
# on n'a pas encore saisi de décisions # on n'a pas encore saisi de décisions
@ -251,3 +243,30 @@ def run_sco_basic(verbose=False) -> FormSemestre:
) )
assert q.count() == 0 assert q.count() == 0
return formsemestre return formsemestre
def _signal_absences_justificatifs(etudid: int):
etud: Identite = Identite.query.get(etudid)
db.session.commit()
for i in range(15, 18):
db.session.add(
Assiduite.create_assiduite(
etud=etud,
date_debut=localize_datetime(datetime.datetime(2020, 1, i, 8, 0)),
date_fin=localize_datetime(datetime.datetime(2020, 1, i, 18, 0)),
etat=EtatAssiduite.ABSENT,
)
)
db.session.commit()
justif: Justificatif = Justificatif.create_justificatif(
etud=etud,
date_debut=localize_datetime(datetime.datetime(2020, 1, 17, 8, 0)),
date_fin=localize_datetime(datetime.datetime(2020, 1, 17, 18, 0)),
etat=EtatJustificatif.VALIDE,
)
db.session.add(justif)
compute_assiduites_justified(
etud.etudid,
[justif],
)
db.session.commit()