From f74713ac0973e0ebc947ff4435bb9f944df3a06d Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet <emmanuel.viennet@gmail.com>
Date: Sun, 19 Feb 2023 13:28:59 +0100
Subject: [PATCH] Fix: enregistrement autorisations d'inscriptions auto sur
 sem. BUT impairs

---
 app/but/jury_but.py          | 33 +++++++++++++++++++--------------
 app/but/jury_but_view.py     |  3 +++
 app/models/validations.py    |  3 +--
 tests/unit/yaml_setup_but.py |  6 ++++--
 4 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 9fe5ed937..942a5aa7d 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -649,12 +649,14 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         """Les indices des semestres dans lequels l'étudiant est autorisé
         à poursuivre après le semestre courant.
         """
-        ids = set()
         # La poursuite d'études dans un semestre pair d’une même année
-        # est de droit pour tout étudiant:
-        if (self.formsemestre.semestre_id % 2) and sco_codes.CursusBUT.NB_SEM:
-            ids.add(self.formsemestre.semestre_id + 1)
-
+        # est de droit pour tout étudiant.
+        # Pas de redoublements directs de S_impair vers S_impair
+        # (pourront être traités manuellement)
+        if (
+            self.formsemestre.semestre_id % 2
+        ) and self.formsemestre.semestre_id < sco_codes.CursusBUT.NB_SEM:
+            return {self.formsemestre.semestre_id + 1}
         # La poursuite d’études dans un semestre impair est possible si
         # et seulement si l’étudiant a obtenu :
         #  - la moyenne à plus de la moitié des regroupements cohérents d’UE ;
@@ -664,10 +666,11 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         # ScoDoc ne contraint donc pas à la respecter strictement.
         # Si le code est dans BUT_CODES_PASSAGE (ADM, ADJ, PASD, PAS1NCI, ATJ),
         # autorise à passer dans le semestre suivant
+        ids = set()
         if (
             self.jury_annuel
             and code in sco_codes.BUT_CODES_PASSAGE
-            and self.formsemestre_pair.semestre_id < sco_codes.CursusBUT.NB_SEM
+            and self.formsemestre.semestre_id < sco_codes.CursusBUT.NB_SEM
         ):
             ids.add(self.formsemestre.semestre_id + 1)
 
@@ -723,6 +726,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
             for dec_rcue, code in codes_rcues:
                 dec_rcue.record(code)
             self.record(code_annee)
+            self.record_autorisation_inscription(code_annee)
             self.record_all()
 
         db.session.commit()
@@ -755,15 +759,21 @@ class DecisionsProposeesAnnee(DecisionsProposees):
                     code=code,
                 )
                 db.session.add(self.validation)
-                db.session.commit()
                 log(f"Recording {self}: {code}")
                 Scolog.logdb(
                     method="jury_but",
                     etudid=self.etud.id,
                     msg=f"Validation année BUT{self.annee_but}: {code}",
                 )
+        self.recorded = True
+        self.invalidate_formsemestre_cache()
+        return True
 
-        # --- Autorisation d'inscription dans semestre suivant ?
+    def record_autorisation_inscription(self, code: str):
+        """Autorisation d'inscription dans semestre suivant"""
+        if self.inscription_etat != scu.INSCRIT:
+            # les dem et DEF ne continuent jamais
+            return
         ScolarAutorisationInscription.delete_autorisation_etud(
             etudid=self.etud.id,
             origin_formsemestre_id=self.formsemestre.id,
@@ -776,11 +786,6 @@ class DecisionsProposeesAnnee(DecisionsProposees):
                 next_semestre_id,
             )
 
-        db.session.commit()
-        self.recorded = True
-        self.invalidate_formsemestre_cache()
-        return True
-
     def invalidate_formsemestre_cache(self):
         "invalide le résultats des deux formsemestres"
         if self.formsemestre_impair is not None:
@@ -859,7 +864,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
                 not only_validantes
             ) or code in sco_codes.CODES_ANNEE_BUT_VALIDES_DE_DROIT:
                 modif |= self.record(code, no_overwrite=no_overwrite)
-
+            self.record_autorisation_inscription(code)
         return modif
 
     def erase(self, only_one_sem=False):
diff --git a/app/but/jury_but_view.py b/app/but/jury_but_view.py
index 4a4f974ad..60bfa7931 100644
--- a/app/but/jury_but_view.py
+++ b/app/but/jury_but_view.py
@@ -328,6 +328,9 @@ def jury_but_semestriel(
                     if not formsemestre.semestre_id + 1 in (
                         a.semestre_id for a in autorisations_passage
                     ):
+                        ScolarAutorisationInscription.delete_autorisation_etud(
+                            etud.id, formsemestre.id
+                        )
                         ScolarAutorisationInscription.autorise_etud(
                             etud.id,
                             formsemestre.formation.formation_code,
diff --git a/app/models/validations.py b/app/models/validations.py
index 20a4bb587..6f1482381 100644
--- a/app/models/validations.py
+++ b/app/models/validations.py
@@ -112,8 +112,7 @@ class ScolarAutorisationInscription(db.Model):
         origin_formsemestre_id: int,
         semestre_id: int,
     ):
-        """Enregistre une autorisation, remplace celle émanant du même semestre si elle existe."""
-        cls.delete_autorisation_etud(etudid, origin_formsemestre_id)
+        """Ajoute une autorisation"""
         autorisation = cls(
             etudid=etudid,
             formation_code=formation_code,
diff --git a/tests/unit/yaml_setup_but.py b/tests/unit/yaml_setup_but.py
index 25633326c..516fd7358 100644
--- a/tests/unit/yaml_setup_but.py
+++ b/tests/unit/yaml_setup_but.py
@@ -29,7 +29,7 @@ from app.models import (
     UniteEns,
 )
 from app.scodoc import sco_utils as scu
-from app.scodoc import sco_pvjury
+from app.scodoc import sco_dict_pv_jury
 
 
 def setup_formation_referentiel(formation: Formation, refcomp_infos: dict):
@@ -241,6 +241,8 @@ def but_compare_decisions_annee(deca: DecisionsProposeesAnnee, deca_att: dict):
     if code_manuel is not None:
         assert code_manuel in deca.codes
         deca.record(code_manuel)
+        deca.record_autorisation_inscription(code_manuel)
+        db.session.commit()
         assert deca.recorded
 
 
@@ -306,7 +308,7 @@ def but_test_jury(formsemestre: FormSemestre, doc: dict):
                 but_compare_decisions_annee(deca, deca_att)
             if "autorisations_inscription" in doc_formsemestre["attendu"]:
                 if dpv is None:  # lazy load
-                    dpv = sco_pvjury.dict_pvjury(formsemestre.id)
+                    dpv = sco_dict_pv_jury.dict_pvjury(formsemestre.id)
                 check_autorisations_inscription(
                     etud, dpv, doc_formsemestre["attendu"]["autorisations_inscription"]
                 )
-- 
GitLab