[scodoc-devel] [SVN] Scolar : [1663] Fix: calcul des elements annuels exports Apogee

eviennet at lipn.univ-paris13.fr eviennet at lipn.univ-paris13.fr
Dim 9 Juil 13:11:44 CEST 2017


Une pièce jointe HTML a été nettoyée...
URL: https://listes.univ-paris13.fr/pipermail/scodoc-devel/attachments/20170709/ef9d0e7f/attachment.htm 
-------------- section suivante --------------
Modified: branches/ScoDoc7/sco_apogee_csv.py
===================================================================
--- branches/ScoDoc7/sco_apogee_csv.py	2017-07-08 13:52:23 UTC (rev 1662)
+++ branches/ScoDoc7/sco_apogee_csv.py	2017-07-09 11:11:44 UTC (rev 1663)
@@ -237,10 +237,10 @@
             for col_id in apo_data.col_ids[4:]:
                 code = apo_data.cols[col_id]['Code'] # 'V1RT'
                 el = sco_elts.get(code, None) # {'R': 'ADM', 'J': '', 'B': 20, 'N': '12.14'}
-                if el is None:
-                    autre_sem = self.autre_semestre_de_etape(context, apo_data)
-                    for sem in apo_data.sems_etape:
-                        el = self.search_elt_in_sem(context, code, sem, autre_sem)
+                if el is None: # pas déjà trouvé
+                    cur_sem, autre_sem = self.etud_semestres_de_etape(context, apo_data)
+                    for sem in apo_data.sems_etape:                        
+                        el = self.search_elt_in_sem(context, code, sem, cur_sem, autre_sem)
                         if el != None:
                             sco_elts[code] = el
                             break
@@ -258,7 +258,7 @@
         codes = set([ apo_data.cols[col_id].code for col_id in apo_data.col_ids ])        
         return codes - set(sco_elts)
     
-    def search_elt_in_sem(self, context, code, sem, autre_sem):
+    def search_elt_in_sem(self, context, code, sem, cur_sem, autre_sem):
         """
         VET code jury etape
         ELP élément pédagogique: UE, module
@@ -271,6 +271,7 @@
         Args:
            code (str): code apo de l'element cherché
            sem (dict): semestre dans lequel on cherche l'élément
+           cur_sem (dict): semestre "courant" pour résultats annuels (VET)
            autre_sem (dict): autre semestre utilisé pour calculé les résultats annuels (VET)
         
         Returns:
@@ -296,7 +297,7 @@
         # Element etape (annuel ou non):
         if sco_formsemestre.sem_has_etape(sem, code) or (code in sem['elt_annee_apo'].split(',')):
             if self.export_res_etape:
-                return self.comp_elt_annuel(context, nt, decision, etudid, sem, autre_sem)
+                return self.comp_elt_annuel(context, etudid, cur_sem, autre_sem)
             else:
                 return VOID_APO_RES
 
@@ -350,14 +351,10 @@
             note_str =  _apo_fmt_note(note)
         return dict( N=note_str, B=20, J='', R=decision_apo, M='' )
 
-    def comp_elt_annuel(self, context, nt, decision, etudid, sem, autre_sem):
+    def comp_elt_annuel(self, context, etudid, cur_sem, autre_sem):
         """Calcul resultat annuel (VET) à partir du semestre courant
         et de l'autre (le suivant ou le précédent complétant l'année scolaire)
         """
-        if not autre_sem:
-            # formations monosemestre, ou code VET semestriel,
-            # ou jury intermediaire et etudiant non redoublant...
-            return self.comp_elt_semestre(context, nt, decision, etudid)
         # Code annuel:
         #  - Note: moyenne des moyennes générales des deux semestres (pas vraiment de sens, mais faute de mieux)
         #    on pourrait aussi bien prendre seulement la note du dernier semestre (S2 ou S4). Paramétrable ?
@@ -366,19 +363,30 @@
         #      si l'autre n'est pas validé ou est DEF ou DEM, code de l'autre
         #
         #    XXX cette règle est discutable, à valider
-        decision_apo = code_scodoc_to_apo(decision['code'])
+        
+        #print 'comp_elt_annuel cur_sem=%s autre_sem=%s' % (cur_sem['formsemestre_id'], autre_sem['formsemestre_id'])
+        cur_nt = context._getNotesCache().get_NotesTable(context, cur_sem['formsemestre_id'])
+        cur_decision = cur_nt.get_etud_decision_sem(etudid)
+        if not autre_sem:
+            # formations monosemestre, ou code VET semestriel,
+            # ou jury intermediaire et etudiant non redoublant...
+            return self.comp_elt_semestre(context, cur_nt, cur_decision, etudid)
+        
+        decision_apo = code_scodoc_to_apo(cur_decision['code'])
+        
         autre_nt = context._getNotesCache().get_NotesTable(context, autre_sem['formsemestre_id'])
         autre_decision = autre_nt.get_etud_decision_sem(etudid)
         if not autre_decision:
             # pas de decision dans l'autre => pas de résultat annuel
-            return dict( N='', B=20, J='', R='' )
+            return VOID_APO_RES
         autre_decision_apo = code_scodoc_to_apo(autre_decision['code'])
         if ((autre_decision_apo == 'DEF' or autre_decision['code'] == 'DEM' or autre_decision['code'] == DEF)
-            or (decision_apo == 'DEF' or decision['code'] == 'DEM' or decision['code'] == DEF)):
+            or (decision_apo == 'DEF' or cur_decision['code'] == 'DEM' or cur_decision['code'] == DEF)):
             note_str = '0,01' # note non nulle pour les démissionnaires
         else:
-            note = nt.get_etud_moy_gen(etudid)
+            note = cur_nt.get_etud_moy_gen(etudid)
             autre_note = autre_nt.get_etud_moy_gen(etudid)
+            #print 'note=%s autre_note=%s' % (note, autre_note)
             try:
                 moy_annuelle = (note + autre_note) / 2
             except:
@@ -392,7 +400,7 @@
 
         return dict( N=note_str, B=20, J='', R=decision_apo_annuelle, M='' )
        
-    def autre_semestre_de_etape(self, context, apo_data):
+    def etud_semestres_de_etape(self, context, apo_data):
         """
         Lorsqu'on a une formation semestrialisée mais avec un code étape annuel,
         il faut considérer les deux semestres ((S1,S2) ou (S3,S4)) pour calculer
@@ -400,10 +408,10 @@
 
         Pour les jurys intermediaires (janvier, S1 ou S3):  (S2 ou S4) de la même étape lors d'une année précédente ?
 
-        Renvoie cet autre semestre, ou None s'il n'y en a pas.
+        Renvoie le semestre "courant" et l'autre semestre, ou None s'il n'y en a pas.
         """
         if apo_data.cur_semestre_id <= 0:
-            return None # non pertinent pour sessions sans semestres
+            return None, None # non pertinent pour sessions sans semestres
         if apo_data.jury_intermediaire: # jury de janvier
             # Le semestre suivant: exemple 2 si on est en jury de S1
             autre_semestre_id = apo_data.cur_semestre_id + 1
@@ -414,12 +422,14 @@
         # L'autre semestre DOIT être antérieur au courant indiqué par apo_data
         if apo_data.periode is not None:
             if apo_data.periode == 1:
+                courant_annee_debut = apo_data.annee_scolaire
                 courant_mois_debut = 9 # periode = 1 (sept-jan) 
             elif apo_data.periode == 2:
+                courant_annee_debut = apo_data.annee_scolaire + 1
                 courant_mois_debut = 1 # ou 2 (fev-jul)
             else:
                 raise ValueError('invalid pediode value !') # bug ?
-            courant_date_debut = '%d-%2d-01' % (apo_data.annee_scolaire, courant_mois_debut)
+            courant_date_debut = '%d-%02d-01' % (courant_annee_debut, courant_mois_debut)
         else:
             courant_date_debut = '9999-99-99'
         
@@ -434,18 +444,42 @@
                 if sem['date_debut_iso'] < courant_date_debut: # on demande juste qu'il ait démarré avant
                     autres_sems.append(sem)
         if not autres_sems:
-            return None
+            autre_sem = None
         elif len(autres_sems) == 1:
-            return autres_sems[0]
+            autre_sem = autres_sems[0]
         else:
+            autre_sem = None
             for sem in autres_sems:
                 nt = context._getNotesCache().get_NotesTable(context, sem['formsemestre_id'])
                 decision = nt.get_etud_decision_sem(self.etud['etudid'])
                 if decision:
-                    return sem                
-            return autres_sems[0] # aucun avec decison, prend le plus recent
+                    autre_sem = sem
+                    break
+            if autre_sem is None:
+                autre_sem = autres_sems[0] # aucun avec decision, prend le plus recent
 
+        # Cherche le semestre "courant":
+        cur_sems = [ sem for sem in self.etud['sems']
+                     if ((sem['semestre_id'] == apo_data.cur_semestre_id)
+                         and (apo_data.etape_apogee in sem['etapes'])
+                         and (sco_formsemestre.sem_in_annee_scolaire(context, sem, apo_data.annee_scolaire))) ]
+        if not cur_sems:
+            cur_sem = None
+        else:
+            # prend le plus recent avec decision
+            cur_sem = None
+            for sem in cur_sems:
+                nt = context._getNotesCache().get_NotesTable(context, sem['formsemestre_id'])
+                decision = nt.get_etud_decision_sem(self.etud['etudid'])
+                if decision:
+                    cur_sem = sem
+                    break
+            if cur_sem is None:
+                cur_sem = cur_sems[0] # aucun avec decison, prend le plus recent
 
+        return cur_sem, autre_sem
+
+
 class ApoData:
     def __init__(self, data, periode=None,
                  export_res_etape = True,

Modified: branches/ScoDoc7/sco_formsemestre.py
===================================================================
--- branches/ScoDoc7/sco_formsemestre.py	2017-07-08 13:52:23 UTC (rev 1662)
+++ branches/ScoDoc7/sco_formsemestre.py	2017-07-09 11:11:44 UTC (rev 1663)
@@ -197,7 +197,7 @@
 
 def sem_in_annee_scolaire(context, sem, year=False, REQUEST=None):
     """n'utilise que la date de debut, pivot au 1er aout
-    si annee non specifiée, année scoalire courante
+    si annee non specifiée, année scolaire courante
     """
     if not year:
         year = AnneeScolaire(REQUEST)


Plus d'informations sur la liste de diffusion scodoc-devel