From d2784a4290fb28f2b2e1aa893f3648e5f1857299 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet <emmanuel.viennet@gmail.com>
Date: Mon, 28 Apr 2025 22:22:45 +0200
Subject: [PATCH] Fix: filtres par annee_naissance et primo.

---
 app/scodoc/sco_report.py | 109 +++++++++++++++++++++++++--------------
 1 file changed, 69 insertions(+), 40 deletions(-)

diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py
index 2e8901ef..cb3046fa 100644
--- a/app/scodoc/sco_report.py
+++ b/app/scodoc/sco_report.py
@@ -123,13 +123,18 @@ def formsemestre_etuds_stats(
         if e_dict["specialite"]:
             bs.append(e_dict["specialite"])
         e_dict["bac-specialite"] = " ".join(bs)
+        # Ajoute clé 'annee_naissance'
+        e_dict["annee_naissance"] = (
+            etud.date_naissance.year if etud.date_naissance else ""
+        )
+
         #
-        if (not only_primo) or is_primo_etud(e_dict, formsemestre):
+        if (not only_primo) or is_primo_etud(etud, formsemestre):
             etuds.append(e_dict)
     return etuds
 
 
-def is_primo_etud(etud: dict, formsemestre: FormSemestre):
+def _is_primo_etud_dict(e_dict: dict, formsemestre: FormSemestre):  # XXX
     """Determine si un (filled) etud a été inscrit avant ce semestre.
     Regarde la liste des semestres dans lesquels l'étudiant est inscrit.
     Si semestre pair, considère comme primo-entrants ceux qui étaient
@@ -138,17 +143,39 @@ def is_primo_etud(etud: dict, formsemestre: FormSemestre):
     debut_cur_iso = formsemestre.date_debut.isoformat()
     # si semestre impair et sem. précédent contigu, recule date debut
     if (
-        (len(etud["sems"]) > 1)
+        (len(e_dict["sems"]) > 1)
         and (formsemestre.semestre_id % 2 == 0)
-        and (etud["sems"][1]["semestre_id"] == (formsemestre.semestre_id - 1))
+        and (e_dict["sems"][1]["semestre_id"] == (formsemestre.semestre_id - 1))
     ):
-        debut_cur_iso = etud["sems"][1]["date_debut_iso"]
-    for s in etud["sems"]:  # le + recent d'abord
+        debut_cur_iso = e_dict["sems"][1]["date_debut_iso"]
+    for s in e_dict["sems"]:  # le + recent d'abord
         if s["date_debut_iso"] < debut_cur_iso:
             return False
     return True
 
 
+# Version moderne: instance de Identite
+def is_primo_etud(etud: Identite, formsemestre: FormSemestre):
+    """Determine si etud a été inscrit avant ce semestre.
+    Regarde la liste des semestres dans lesquels l'étudiant est inscrit.
+    Si semestre pair, considère comme primo-entrants ceux qui étaient
+    primo dans le précédent (S_{2n-1}).
+    """
+    inscriptions = etud.inscriptions()
+    debut_cur = formsemestre.date_debut
+    # si semestre impair et sem. précédent contigu, recule date debut
+    if (
+        (len(inscriptions) > 1)
+        and (formsemestre.semestre_id % 2 == 0)
+        and (inscriptions[1].formsemestre.semestre_id == (formsemestre.semestre_id - 1))
+    ):
+        debut_cur = inscriptions[1].formsemestre.date_debut
+    for ins in inscriptions:  # le + recent d'abord
+        if ins.formsemestre.date_debut < debut_cur:
+            return False
+    return True
+
+
 def _categories_and_results(etuds, category, result):
     categories = {}
     results = {}
@@ -486,37 +513,38 @@ def table_suivi_cohorte(
     civilites = set()
     statuts = set()
     for etudid in etudids:
-        etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
-        etud["annee_admission"] = etud["annee"]
-        bacspe = (etud["bac"] or "?") + " / " + (etud["specialite"] or "")
+        e_dict = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
+        e_dict["annee_admission"] = e_dict["annee"]
+        bacspe = (e_dict["bac"] or "?") + " / " + (e_dict["specialite"] or "")
         # sélection sur bac:
         if (
-            (not bac or (bac == etud["bac"]))
+            (not bac or (bac == e_dict["bac"]))
             and (not bacspecialite or (bacspecialite == bacspe))
-            and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
+            and (not annee_bac or (annee_bac == str(e_dict["annee_bac"])))
             and (
-                not annee_admission or (annee_admission == str(etud["annee_admission"]))
+                not annee_admission
+                or (annee_admission == str(e_dict["annee_admission"]))
             )
-            and (not civilite or (civilite == etud["civilite"]))
-            and (not statut or (statut == etud["statut"]))
-            and (not only_primo or is_primo_etud(etud, formsemestre))
+            and (not civilite or (civilite == e_dict["civilite"]))
+            and (not statut or (statut == e_dict["statut"]))
+            and (not only_primo or _is_primo_etud_dict(e_dict, formsemestre))
         ):
             orig_set.add(etudid)
             # semestres suivants:
-            for s in etud["sems"]:
+            for s in e_dict["sems"]:
                 if ndb.DateDMYtoISO(s["date_debut"]) > ndb.DateDMYtoISO(
                     sem["date_debut"]
                 ):
                     S[s["formsemestre_id"]] = s
-        if etud.get("bac", False):
-            bacs.add(etud["bac"])
+        if e_dict.get("bac", False):
+            bacs.add(e_dict["bac"])
             bacspecialites.add(bacspe)
-            annee_bacs.add(str(etud["annee_bac"]))
-        if etud["annee_admission"] is not None:
-            annee_admissions.add(str(etud["annee_admission"]))
-        civilites.add(etud["civilite"])
-        if etud["statut"]:  # ne montre pas les statuts non renseignés
-            statuts.add(etud["statut"])
+            annee_bacs.add(str(e_dict["annee_bac"]))
+        if e_dict["annee_admission"] is not None:
+            annee_admissions.add(str(e_dict["annee_admission"]))
+        civilites.add(e_dict["civilite"])
+        if e_dict["statut"]:  # ne montre pas les statuts non renseignés
+            statuts.add(e_dict["statut"])
     sems = list(S.values())
     # tri les semestres par date de debut
     for s in sems:
@@ -1194,30 +1222,31 @@ def tsp_etud_list(
     civilites = set()
     statuts = set()
     for etudid in etudids:
-        etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
-        etud["annee_admission"] = etud["annee"]  # plus explicite
-        bacspe = (etud["bac"] or "?") + " / " + (etud["specialite"] or "")
+        e_dict = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
+        e_dict["annee_admission"] = e_dict["annee"]  # plus explicite
+        bacspe = (e_dict["bac"] or "?") + " / " + (e_dict["specialite"] or "")
         # sélection sur bac, primo, ...:
         if (
-            (not bac or (bac == etud["bac"]))
+            (not bac or (bac == e_dict["bac"]))
             and (not bacspecialite or (bacspecialite == bacspe))
-            and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
+            and (not annee_bac or (annee_bac == str(e_dict["annee_bac"])))
             and (
-                not annee_admission or (annee_admission == str(etud["annee_admission"]))
+                not annee_admission
+                or (annee_admission == str(e_dict["annee_admission"]))
             )
-            and (not civilite or (civilite == etud["civilite"]))
-            and (not statut or (statut == etud["statut"]))
-            and (not only_primo or is_primo_etud(etud, formsemestre))
+            and (not civilite or (civilite == e_dict["civilite"]))
+            and (not statut or (statut == e_dict["statut"]))
+            and (not only_primo or _is_primo_etud_dict(e_dict, formsemestre))
         ):
-            etuds.append(etud)
+            etuds.append(e_dict)
 
-        bacs.add(etud["bac"])
+        bacs.add(e_dict["bac"])
         bacspecialites.add(bacspe)
-        annee_bacs.add(etud["annee_bac"])
-        annee_admissions.add(etud["annee_admission"])
-        civilites.add(etud["civilite"])
-        if etud["statut"]:  # ne montre pas les statuts non renseignés
-            statuts.add(etud["statut"])
+        annee_bacs.add(e_dict["annee_bac"])
+        annee_admissions.add(e_dict["annee_admission"])
+        civilites.add(e_dict["civilite"])
+        if e_dict["statut"]:  # ne montre pas les statuts non renseignés
+            statuts.add(e_dict["statut"])
     return etuds, bacs, bacspecialites, annee_bacs, annee_admissions, civilites, statuts
 
 
-- 
GitLab