From f9b50bb290eb1d898fcb2b8ea73214c3d7271f37 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet <emmanuel.viennet@gmail.com>
Date: Sat, 25 Jun 2022 03:52:28 +0200
Subject: [PATCH] =?UTF-8?q?Jury=20BUT:=20g=C3=A9n=C3=A9ration=20des=20auto?=
 =?UTF-8?q?risations=20d'inscription?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/but/jury_but.py              | 42 +++++++++++++++++++++++++-------
 app/models/validations.py        | 41 ++++++++++++++++++++++++++++++-
 app/scodoc/sco_codes_parcours.py |  6 +++++
 3 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 8ab3a213f..fb255f0d2 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -67,6 +67,7 @@ from app import db
 from app import log
 from app.comp.res_but import ResultatsSemestreBUT
 from app.comp import res_sem
+from app.models import formsemestre
 
 from app.models.but_refcomp import (
     ApcAnneeParcours,
@@ -75,7 +76,7 @@ from app.models.but_refcomp import (
     ApcParcours,
     ApcParcoursNiveauCompetence,
 )
-from app.models import Scolog
+from app.models import Scolog, ScolarAutorisationInscription
 from app.models.but_validations import (
     ApcValidationAnnee,
     ApcValidationRCUE,
@@ -87,7 +88,7 @@ from app.models.formsemestre import FormSemestre, FormSemestreInscription
 from app.models.ues import UniteEns
 from app.models.validations import ScolarFormSemestreValidation
 from app.scodoc import sco_codes_parcours as sco_codes
-from app.scodoc.sco_codes_parcours import UE_STANDARD
+from app.scodoc.sco_codes_parcours import RED, UE_STANDARD
 from app.scodoc import sco_utils as scu
 from app.scodoc.sco_exceptions import ScoException, ScoValueError
 
@@ -457,13 +458,19 @@ class DecisionsProposeesAnnee(DecisionsProposees):
             d[dec_rcue.rcue.ue_2.id] = dec_rcue
         return d
 
-    # def lookup_ue(self, ue_id: int) -> UniteEns:
-    #     "check that ue_id belongs to our UE, if not returns None"
-    #     ues = [ue for ue in self.ues_impair + self.ues_pair if ue.id == ue_id]
-    #     assert len(ues) < 2
-    #     if len(ues):
-    #         return ues[0]
-    #     return None
+    def next_annee_semestre_id(self, code: str) -> int:
+        """L'indice du semestre dans lequel l'étudiant est autorisé à
+        poursuivre l'année suivante. None si aucun."""
+        if self.formsemestre_pair is None:
+            return None  # seulement sur année
+        if code == RED:
+            return self.formsemestre_pair.semestre_id - 1
+        elif (
+            code in sco_codes.BUT_CODES_PASSAGE
+            and self.formsemestre_pair.semestre_id < sco_codes.ParcoursBUT.NB_SEM
+        ):
+            return self.formsemestre_pair.semestre_id + 1
+        return None
 
     def record_form(self, form: dict):
         """Enregistre les codes de jury en base
@@ -529,6 +536,23 @@ class DecisionsProposeesAnnee(DecisionsProposees):
                 msg=f"Validation année BUT{self.annee_but}: {code}",
             )
             db.session.add(self.validation)
+        # --- Autorisation d'inscription dans semestre suivant ?
+        if self.formsemestre_pair is not None:
+            if code is None:
+                ScolarAutorisationInscription.delete_autorisation_etud(
+                    etudid=self.etud.id,
+                    origin_formsemestre_id=self.formsemestre_pair.id,
+                )
+            else:
+                next_semestre_id = self.next_annee_semestre_id(code)
+                if next_semestre_id is not None:
+                    ScolarAutorisationInscription.autorise_etud(
+                        self.etud.id,
+                        self.formsemestre_pair.formation.formation_code,
+                        self.formsemestre_pair.id,
+                        next_semestre_id,
+                    )
+
         self.recorded = True
 
     def record_all(self):
diff --git a/app/models/validations.py b/app/models/validations.py
index 00d170729..42d7ba0d6 100644
--- a/app/models/validations.py
+++ b/app/models/validations.py
@@ -6,6 +6,7 @@
 from app import db
 from app.models import SHORT_STR_LEN
 from app.models import CODE_STR_LEN
+from app.models.events import Scolog
 
 
 class ScolarFormSemestreValidation(db.Model):
@@ -69,7 +70,7 @@ class ScolarAutorisationInscription(db.Model):
         db.ForeignKey("identite.id", ondelete="CASCADE"),
     )
     formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
-    # semestre ou on peut s'inscrire:
+    # Indice du semestre où on peut s'inscrire:
     semestre_id = db.Column(db.Integer)
     date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
     origin_formsemestre_id = db.Column(
@@ -77,6 +78,44 @@ class ScolarAutorisationInscription(db.Model):
         db.ForeignKey("notes_formsemestre.id"),
     )
 
+    @classmethod
+    def autorise_etud(
+        cls,
+        etudid: int,
+        formation_code: str,
+        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)
+        autorisation = cls(
+            etudid=etudid,
+            formation_code=formation_code,
+            origin_formsemestre_id=origin_formsemestre_id,
+            semestre_id=semestre_id,
+        )
+        db.session.add(autorisation)
+        Scolog.logdb("autorise_etud", etudid=etudid, msg=f"passage vers S{semestre_id}")
+
+    @classmethod
+    def delete_autorisation_etud(
+        cls,
+        etudid: int,
+        origin_formsemestre_id: int,
+    ):
+        """Efface les autorisations de cette étudiant venant du sem. origine"""
+        autorisations = cls.query.filter_by(
+            etudid=etudid, origin_formsemestre_id=origin_formsemestre_id
+        )
+        for autorisation in autorisations:
+            db.session.delete(autorisation)
+            Scolog.logdb(
+                "autorise_etud",
+                etudid=etudid,
+                msg=f"annule passage vers S{autorisation.semestre_id}",
+            )
+        db.session.flush()
+
 
 class ScolarEvent(db.Model):
     """Evenement dans le parcours scolaire d'un étudiant"""
diff --git a/app/scodoc/sco_codes_parcours.py b/app/scodoc/sco_codes_parcours.py
index d4479939b..6b4dd946d 100644
--- a/app/scodoc/sco_codes_parcours.py
+++ b/app/scodoc/sco_codes_parcours.py
@@ -196,6 +196,12 @@ CODES_RCUE = {ADM, AJ, CMP}
 BUT_BARRE_UE8 = 8.0 - NOTES_TOLERANCE
 BUT_BARRE_UE = BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE
 BUT_RCUE_SUFFISANT = 8.0 - NOTES_TOLERANCE
+BUT_CODES_PASSAGE = {
+    ADM,
+    ADJ,
+    PASD,
+    PAS1NCI,
+}
 
 
 def code_semestre_validant(code: str) -> bool:
-- 
GitLab