diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py index f085a83f4cc7189c930a7b69a3604d76301e1d38..c8c4b7943117480a217276ca4f1a61f08a67685b 100644 --- a/app/scodoc/sco_assiduites.py +++ b/app/scodoc/sco_assiduites.py @@ -935,57 +935,35 @@ def get_assiduites_count_in_interval( return (nb_abs_nj, nb_abs_just, nb_abs) -def invalidate_assiduites_count(etudid: int, sem: dict): +def invalidate_assiduites_count(etudid: int, fs: FormSemestre): """Invalidate (clear) cached counts""" - date_debut = sem["date_debut_iso"] - date_fin = sem["date_fin_iso"] - key = str(etudid) + "_" + date_debut + "_" + date_fin + "_assiduites" + key = f"{etudid}_{fs.date_debut.isoformat()}_{fs.date_fin.isoformat()}_assiduites" sco_cache.AbsSemEtudCache.delete(key) -# Non utilisé -def invalidate_assiduites_count_sem(sem: dict): - """Invalidate (clear) cached abs counts for all the students of this semestre""" - inscriptions = ( - sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits( - sem["formsemestre_id"] - ) - ) - for ins in inscriptions: - invalidate_assiduites_count(ins["etudid"], sem) - - def invalidate_assiduites_etud_date(etudid: int, the_date: datetime): """Doit etre appelé à chaque modification des assiduites pour cet étudiant et cette date. Invalide cache absence et caches semestre """ - - # Semestres a cette date: - etud = sco_etud.get_etud_info(etudid=etudid, filled=True) - if len(etud) == 0: + etud = Identite.get_etud(etudid, accept_none=True) + if not etud: return - else: - etud = etud[0] - sems = [ - sem - for sem in etud["sems"] - if scu.is_iso_formated(sem["date_debut_iso"], True).replace(tzinfo=UTC) - <= the_date.replace(tzinfo=UTC) - and scu.is_iso_formated(sem["date_fin_iso"], True).replace(tzinfo=UTC) - >= the_date.replace(tzinfo=UTC) + the_day = the_date.replace(tzinfo=UTC).day + # Semestres de l'étudiant à cette date: + formsemestres = [ + ins.formsemestre + for ins in etud.formsemestre_inscriptions + if ins.formsemestre.date_debut <= the_day <= ins.formsemestre.date_fin ] - # Invalide les PDF et les absences: - for sem in sems: + for formsemestre in formsemestres: # Inval cache bulletin et/ou note_table # efface toujours le PDF car il affiche en général les absences - sco_cache.invalidate_formsemestre( - formsemestre_id=sem["formsemestre_id"], pdfonly=True - ) + sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id, pdfonly=True) # Inval cache compteurs absences: - invalidate_assiduites_count(etudid, sem) + invalidate_assiduites_count(etudid, formsemestre) def simple_invalidate_cache(obj: dict, etudid: str | int = None): diff --git a/app/scodoc/sco_cache.py b/app/scodoc/sco_cache.py index a64dd76146ee1c1d8e5956af60fe2e366a0efc8c..caf1187c825e07add95556db430fa070953ee6e9 100644 --- a/app/scodoc/sco_cache.py +++ b/app/scodoc/sco_cache.py @@ -193,7 +193,8 @@ class AbsSemEtudCache(ScoDocCache): C'est pourquoi il expire après timeout secondes. Le timeout evite aussi d'éliminer explicitement ces éléments cachés lors des suppressions d'étudiants ou de semestres. - Clé: etudid + "_" + date_debut + "_" + date_fin + + Clé: etudid + "_" + date_debut_iso + "_" + date_fin_iso Valeur: (nb_abs, nb_abs_just) """ @@ -225,8 +226,16 @@ class SemBulletinsPDFCache(ScoDocCache): class SemInscriptionsCache(ScoDocCache): """Cache les inscriptions à un semestre. Clé: formsemestre_id - Valeur: liste d'inscriptions - [ {'formsemestre_inscription_id': 'SI78677', 'etudid': '1234', 'formsemestre_id': 'SEM012', 'etat': 'I', 'etape': ''}, ... ] + Valeur: liste d'inscriptions. + Exemple: + [ {'formsemestre_inscription_id': '78677', + 'etudid': '1234', + 'formsemestre_id': '4567', + 'etat': 'I', + 'etape': '', + "parcour_id" : 4, + }, + ... ] """ prefix = "SI" diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index c0cec9ac517e23fa443f469b0d9db65e75c62dd4..77b9eb7c9df2ff23244c6b2de5d4a8d3bae48d0d 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -77,7 +77,7 @@ def do_formsemestre_inscription_list(*args, **kw): def do_formsemestre_inscription_listinscrits(formsemestre_id): """Liste les inscrits (état I) à ce semestre et cache le résultat. - Result: [ { "etudid":, "formsemestre_id": , "etat": , "etape": }] + Result: [ { "etudid":, "formsemestre_id": , "etat": , "etape": , "parcour_id":}] """ r = sco_cache.SemInscriptionsCache.get(formsemestre_id) if r is None: diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py index 1b77beeac33dc979b910ef98c0c0b0c83c16189d..f35cfa62bb6abb559d1b74fd2d7f11b294739dcd 100644 --- a/app/scodoc/sco_report.py +++ b/app/scodoc/sco_report.py @@ -75,7 +75,7 @@ def formsemestre_etuds_stats( formsemestre: FormSemestre, only_primo=False, groups_infos: sco_groups_view.DisplayedGroupsInfos | None = None, -): +) -> list[dict]: """Récupère liste d'etudiants avec etat et decision.""" nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = groups_infos.get_etudids() if groups_infos else set() @@ -90,17 +90,18 @@ def formsemestre_etuds_stats( etudid = t[-1] if etudids and etudid not in etudids: continue - etudiant = Identite.get_etud(etudid) - etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] - etud["annee_admission"] = etud["annee"] # plus explicite + etud = Identite.get_etud(etudid) + e_dict = etud.to_dict_scodoc7() + e_dict |= etud.admission.to_dict() + e_dict["annee_admission"] = etud.admission.annee # plus explicite decision = nt.get_etud_decision_sem(etudid) if decision: - etud["codedecision"] = decision["code"] - etud["etat"] = nt.get_etud_etat(etudid) - if etud["etat"] == "D": - etud["codedecision"] = "DEM" - if "codedecision" not in etud: - etud["codedecision"] = "(nd)" # pas de decision jury + e_dict["codedecision"] = decision["code"] + e_dict["etat"] = nt.get_etud_etat(etudid) + if e_dict["etat"] == "D": + e_dict["codedecision"] = "DEM" + if "codedecision" not in e_dict: + e_dict["codedecision"] = "(nd)" # pas de decision jury # Ajout devenir (autorisations inscriptions), utile pour stats passage aut_list = ScolarAutorisationInscription.query.filter_by( etudid=etudid, origin_formsemestre_id=formsemestre.id @@ -108,22 +109,22 @@ def formsemestre_etuds_stats( autorisations = [f"S{a.semestre_id}" for a in aut_list] autorisations.sort() autorisations_str = ", ".join(autorisations) - etud["devenir"] = autorisations_str + e_dict["devenir"] = autorisations_str # Décisions de jury BUT (APC) if jury_but_mode: - deca = jury_but.DecisionsProposeesAnnee(etudiant, formsemestre) - etud["nb_rcue_valides"] = deca.nb_rcue_valides - etud["decision_annee"] = deca.code_valide + deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) + e_dict["nb_rcue_valides"] = deca.nb_rcue_valides + e_dict["decision_annee"] = deca.code_valide # Ajout clé 'bac-specialite' bs = [] - if etud["bac"]: - bs.append(etud["bac"]) - if etud["specialite"]: - bs.append(etud["specialite"]) - etud["bac-specialite"] = " ".join(bs) + if e_dict["bac"]: + bs.append(e_dict["bac"]) + if e_dict["specialite"]: + bs.append(e_dict["specialite"]) + e_dict["bac-specialite"] = " ".join(bs) # - if (not only_primo) or is_primo_etud(etud, formsemestre): - etuds.append(etud) + if (not only_primo) or is_primo_etud(e_dict, formsemestre): + etuds.append(e_dict) return etuds diff --git a/app/views/assiduites.py b/app/views/assiduites.py index 70cf79dc4ad8f4fb29d88ed2f9863effff2012d1..70182f03defe3265dcfcff2f3226bd41f3dc43f4 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -1081,12 +1081,6 @@ def signal_assiduites_group(): if formsemestre.dept_id != g.scodoc_dept_id: abort(404, "groupes inexistants dans ce département") - # Récupération des étudiants des groupes - etuds = [ - sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0] - for m in groups_infos.members - ] - # --- Vérification de la date --- real_date = scu.is_iso_formated(date, True).date() @@ -1111,23 +1105,13 @@ def signal_assiduites_group(): titre="Choix de la date", ) - # --- Restriction en fonction du moduleimpl_id --- + # Si module préselectionné et aucun étudiant inscrit, le déselectionne if moduleimpl_id: - mod_inscrits = { - x["etudid"] - for x in sco_moduleimpl.do_moduleimpl_inscription_list( - moduleimpl_id=moduleimpl_id - ) - } - etuds_inscrits_module = [e for e in etuds if e["etudid"] in mod_inscrits] - if etuds_inscrits_module: - etuds = etuds_inscrits_module - else: - # Si aucun etudiant n'est inscrit au module choisi... + modimpl = ModuleImpl.get_modimpl(moduleimpl_id) + if not modimpl.inscriptions: moduleimpl_id = None # Récupération du nom des/du groupe(s) - if groups_infos.tous_les_etuds_du_sem: gr_tit = "en" else: @@ -1139,9 +1123,6 @@ def signal_assiduites_group(): grp + ' <span class="fontred">' + groups_infos.groups_titles + "</span>" ) - # Récupération du semestre en dictionnaire - sem = formsemestre.to_dict() - # Page HTML return render_template( "assiduites/pages/signal_assiduites_group.j2", @@ -1167,7 +1148,7 @@ def signal_assiduites_group(): nonworkdays=_non_work_days(), readonly="false", sco=ScoData(formsemestre=formsemestre), - sem=sem["titre_num"], + sem=formsemestre.titre_num(), timeline=_timeline(heures=",".join([f"'{s}'" for s in heures])), title="Saisie de l'assiduité", ) diff --git a/tests/unit/test_assiduites.py b/tests/unit/test_assiduites.py index 1ca1579cf7dba8a8319d8ba0231f076562a0e363..4046717175d99ced7092ff3aeb3d9685c05f5a5d 100644 --- a/tests/unit/test_assiduites.py +++ b/tests/unit/test_assiduites.py @@ -1724,7 +1724,7 @@ def test_cache_assiduites(test_client): assert scass.get_assiduites_count(etud.id, formsemestre2.to_dict()) == (2, 1, 3) # On invalide maintenant le cache - scass.invalidate_assiduites_count(etud.id, formsemestre1.to_dict()) + scass.invalidate_assiduites_count(etud.id, formsemestre1) # Premier semestre 3nj / 2j / 5t (Change car cache invalidé) assert scass.get_assiduites_count(etud.id, formsemestre1.to_dict()) == (3, 2, 5)