diff --git a/app/but/jury_but.py b/app/but/jury_but.py index 8ab3a213ff..fb255f0d22 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 00d170729f..42d7ba0d65 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 d4479939b5..6b4dd946d9 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: