Refactoring: cursus Classic/ECTS/BUT

This commit is contained in:
Emmanuel Viennet 2022-07-07 16:24:52 +02:00
parent 7c340c798a
commit 81e7914620
21 changed files with 312 additions and 228 deletions

56
app/but/cursus_but.py Normal file
View File

@ -0,0 +1,56 @@
##############################################################################
# ScoDoc
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
# See LICENSE
##############################################################################
"""Cursus en BUT
Classe raccordant avec ScoDoc 7:
ScoDoc 7 utilisait sco_cursus_dut.SituationEtudCursus
Ce module définit une classe SituationEtudCursusBUT
avec la même interface.
"""
from typing import Union
from flask import g, url_for
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,
ApcCompetence,
ApcNiveau,
ApcParcours,
ApcParcoursNiveauCompetence,
)
from app.models import Scolog, ScolarAutorisationInscription
from app.models.but_validations import (
ApcValidationAnnee,
ApcValidationRCUE,
RegroupementCoherentUE,
)
from app.models.etudiants import Identite
from app.models.formations import Formation
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 RED, UE_STANDARD
from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import ScoException, ScoValueError
from app.scodoc import sco_cursus_dut
class SituationEtudCursusBUT(sco_cursus_dut.SituationEtudCursus):
def __init__(self, etud: dict, formsemestre_id: int, res: ResultatsSemestreBUT):
self.semestre_non_terminal = bool
self.formation

View File

@ -57,6 +57,11 @@ class ScolarFormSemestreValidation(db.Model):
def __repr__(self): def __repr__(self):
return f"{self.__class__.__name__}({self.formsemestre_id}, {self.etudid}, code={self.code}, ue={self.ue}, moy_ue={self.moy_ue})" return f"{self.__class__.__name__}({self.formsemestre_id}, {self.etudid}, code={self.code}, ue={self.ue}, moy_ue={self.moy_ue})"
def to_dict(self) -> dict:
d = dict(self.__dict__)
d.pop("_sa_instance_state", None)
return d
class ScolarAutorisationInscription(db.Model): class ScolarAutorisationInscription(db.Model):
"""Autorisation d'inscription dans un semestre""" """Autorisation d'inscription dans un semestre"""
@ -78,6 +83,11 @@ class ScolarAutorisationInscription(db.Model):
db.ForeignKey("notes_formsemestre.id"), db.ForeignKey("notes_formsemestre.id"),
) )
def to_dict(self) -> dict:
d = dict(self.__dict__)
d.pop("_sa_instance_state", None)
return d
@classmethod @classmethod
def autorise_etud( def autorise_etud(
cls, cls,
@ -146,3 +156,8 @@ class ScolarEvent(db.Model):
db.Integer, db.Integer,
db.ForeignKey("notes_formsemestre.id"), db.ForeignKey("notes_formsemestre.id"),
) )
def to_dict(self) -> dict:
d = dict(self.__dict__)
d.pop("_sa_instance_state", None)
return d

View File

@ -54,22 +54,22 @@ from app.scodoc.sco_codes_parcours import (
ue_is_fondamentale, ue_is_fondamentale,
ue_is_professionnelle, ue_is_professionnelle,
) )
from app.scodoc.sco_parcours_dut import formsemestre_get_etud_capitalisation from app.scodoc import sco_cache
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_cache from app.scodoc.sco_cursus import formsemestre_get_etud_capitalisation
from app.scodoc import sco_cursus_dut
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_etud
def comp_ranks(T): def comp_ranks(T):
@ -1175,7 +1175,7 @@ class NotesTable:
): ):
if not cnx: if not cnx:
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
sco_parcours_dut.do_formsemestre_validate_ue( sco_cursus_dut.do_formsemestre_validate_ue(
cnx, cnx,
nt_cap, nt_cap,
ue_cap["formsemestre_id"], ue_cap["formsemestre_id"],

View File

@ -112,8 +112,8 @@ from app.scodoc.sco_codes_parcours import (
NAR, NAR,
RAT, RAT,
) )
from app.scodoc import sco_cursus
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_etud from app.scodoc import sco_etud
APO_PORTAL_ENCODING = ( APO_PORTAL_ENCODING = (
@ -413,7 +413,7 @@ class ApoEtud(dict):
export_res_etape = self.export_res_etape export_res_etape = self.export_res_etape
if (not export_res_etape) and cur_sem: if (not export_res_etape) and cur_sem:
# exporte toujours le résultat de l'étape si l'étudiant est diplômé # exporte toujours le résultat de l'étape si l'étudiant est diplômé
Se = sco_parcours_dut.SituationEtudParcours( Se = sco_cursus.get_situation_etud_cursus(
self.etud, cur_sem["formsemestre_id"] self.etud, cur_sem["formsemestre_id"]
) )
export_res_etape = Se.all_other_validated() export_res_etape = Se.all_other_validated()

View File

@ -231,7 +231,7 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
"""expire cache pour un semestre (ou tous si formsemestre_id non spécifié). """expire cache pour un semestre (ou tous si formsemestre_id non spécifié).
Si pdfonly, n'expire que les bulletins pdf cachés. Si pdfonly, n'expire que les bulletins pdf cachés.
""" """
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus
if getattr(g, "defer_cache_invalidation", False): if getattr(g, "defer_cache_invalidation", False):
g.sem_to_invalidate.add(formsemestre_id) g.sem_to_invalidate.add(formsemestre_id)
@ -252,7 +252,7 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
else: else:
formsemestre_ids = [ formsemestre_ids = [
formsemestre_id formsemestre_id
] + sco_parcours_dut.list_formsemestre_utilisateurs_uecap(formsemestre_id) ] + sco_cursus.list_formsemestre_utilisateurs_uecap(formsemestre_id)
log(f"----- invalidate_formsemestre: clearing {formsemestre_ids} -----") log(f"----- invalidate_formsemestre: clearing {formsemestre_ids} -----")
if not pdfonly: if not pdfonly:

134
app/scodoc/sco_cursus.py Normal file
View File

@ -0,0 +1,134 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Gestion des cursus (jurys suivant la formation)
"""
from app.but import cursus_but
from app.scodoc import sco_cursus_dut
from app.comp.res_compat import NotesTableCompat
from app.comp import res_sem
from app.models import FormSemestre
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formations
import app.scodoc.notesdb as ndb
# SituationEtudParcours -> get_situation_etud_cursus
def get_situation_etud_cursus(
etud: dict, formsemestre_id: int
) -> sco_cursus_dut.SituationEtudCursus:
"""renvoie une instance de SituationEtudCursus (ou sous-classe spécialisée)"""
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if formsemestre.formation.is_apc():
return cursus_but.SituationEtudCursusBUT(etud, formsemestre_id, nt)
parcours = nt.parcours
if parcours.ECTS_ONLY:
return sco_cursus_dut.SituationEtudCursusECTS(etud, formsemestre_id, nt)
return sco_cursus_dut.SituationEtudCursusClassic(etud, formsemestre_id, nt)
def formsemestre_get_etud_capitalisation(
formation_id: int, semestre_idx: int, date_debut, etudid: int
) -> list[dict]:
"""Liste des UE capitalisées (ADM) correspondant au semestre sem et à l'étudiant.
Recherche dans les semestres de la même formation (code) avec le même
semestre_id et une date de début antérieure à celle du semestre mentionné.
Et aussi les UE externes validées.
Resultat: [ { 'formsemestre_id' :
'ue_id' : ue_id dans le semestre origine
'ue_code' :
'moy_ue' :
'event_date' :
'is_external'
} ]
"""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""
SELECT DISTINCT SFV.*, ue.ue_code
FROM notes_ue ue, notes_formations nf,
notes_formations nf2, scolar_formsemestre_validation SFV, notes_formsemestre sem
WHERE ue.formation_id = nf.id
and nf.formation_code = nf2.formation_code
and nf2.id=%(formation_id)s
and SFV.ue_id = ue.id
and SFV.code = 'ADM'
and SFV.etudid = %(etudid)s
and ( (sem.id = SFV.formsemestre_id
and sem.date_debut < %(date_debut)s
and sem.semestre_id = %(semestre_id)s )
or (
((SFV.formsemestre_id is NULL) OR (SFV.is_external)) -- les UE externes ou "anterieures"
AND (SFV.semestre_id is NULL OR SFV.semestre_id=%(semestre_id)s)
) )
""",
{
"etudid": etudid,
"formation_id": formation_id,
"semestre_id": semestre_idx,
"date_debut": date_debut,
},
)
return cursor.dictfetchall()
def list_formsemestre_utilisateurs_uecap(formsemestre_id):
"""Liste des formsemestres pouvant utiliser une UE capitalisee de ce semestre
(et qui doivent donc etre sortis du cache si l'on modifie ce
semestre): meme code formation, meme semestre_id, date posterieure"""
cnx = ndb.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT sem.id
FROM notes_formsemestre sem, notes_formations F
WHERE sem.formation_id = F.id
and F.formation_code = %(formation_code)s
and sem.semestre_id = %(semestre_id)s
and sem.date_debut >= %(date_debut)s
and sem.id != %(formsemestre_id)s;
""",
{
"formation_code": F["formation_code"],
"semestre_id": sem["semestre_id"],
"formsemestre_id": formsemestre_id,
"date_debut": ndb.DateDMYtoISO(sem["date_debut"]),
},
)
return [x[0] for x in cursor.fetchall()]

View File

@ -28,9 +28,10 @@
"""Semestres: gestion parcours DUT (Arreté du 13 août 2005) """Semestres: gestion parcours DUT (Arreté du 13 août 2005)
""" """
from app import db
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre, UniteEns from app.models import FormSemestre, UniteEns, ScolarAutorisationInscription
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
@ -105,27 +106,14 @@ class DecisionSem(object):
) )
) )
) )
# xxx debug
# log('%s: %s %s %s %s %s' % (self.codechoice,code_etat,new_code_prev,formsemestre_id_utilise_pour_compenser,devenir,assiduite) )
def SituationEtudParcours(etud: dict, formsemestre_id: int): class SituationEtudCursus:
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)""" "Semestre dans un cursus"
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) pass
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
# if formsemestre.formation.is_apc():
# return SituationEtudParcoursBUT(etud, formsemestre_id, nt)
parcours = nt.parcours
#
if parcours.ECTS_ONLY:
return SituationEtudParcoursECTS(etud, formsemestre_id, nt)
else:
return SituationEtudParcoursGeneric(etud, formsemestre_id, nt)
class SituationEtudParcoursGeneric: class SituationEtudCursusClassic(SituationEtudCursus):
"Semestre dans un parcours" "Semestre dans un parcours"
def __init__(self, etud: dict, formsemestre_id: int, nt: NotesTableCompat): def __init__(self, etud: dict, formsemestre_id: int, nt: NotesTableCompat):
@ -454,8 +442,7 @@ class SituationEtudParcoursGeneric:
break break
if not cur or cur["formsemestre_id"] != self.formsemestre_id: if not cur or cur["formsemestre_id"] != self.formsemestre_id:
log( log(
"*** SituationEtudParcours: search_prev: cur not found (formsemestre_id=%s, etudid=%s)" f"*** SituationEtudCursus: search_prev: cur not found (formsemestre_id={self.formsemestre_id}, etudid={self.etudid})"
% (self.formsemestre_id, self.etudid)
) )
return None # pas de semestre courant !!! return None # pas de semestre courant !!!
# Cherche semestre antérieur de même formation (code) et semestre_id precedent # Cherche semestre antérieur de même formation (code) et semestre_id precedent
@ -633,31 +620,27 @@ class SituationEtudParcoursGeneric:
formsemestre_id=self.prev["formsemestre_id"] formsemestre_id=self.prev["formsemestre_id"]
) # > modif decisions jury (sem, UE) ) # > modif decisions jury (sem, UE)
# -- supprime autorisations venant de ce formsemestre
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
try: try:
cursor.execute( # -- Supprime autorisations venant de ce formsemestre
"""delete from scolar_autorisation_inscription autorisations = ScolarAutorisationInscription.query.filter_by(
where etudid = %(etudid)s and origin_formsemestre_id=%(origin_formsemestre_id)s etudid=self.etudid, origin_formsemestre_id=self.formsemestre_id
""",
{"etudid": self.etudid, "origin_formsemestre_id": self.formsemestre_id},
) )
for autorisation in autorisations:
# -- enregistre autorisations inscription db.session.delete(autorisation)
db.session.flush()
# -- Enregistre autorisations inscription
next_semestre_ids = self.get_next_semestre_ids(decision.devenir) next_semestre_ids = self.get_next_semestre_ids(decision.devenir)
for next_semestre_id in next_semestre_ids: for next_semestre_id in next_semestre_ids:
_scolar_autorisation_inscription_editor.create( autorisation = ScolarAutorisationInscription(
cnx, etudid=self.etudid,
{ formation_code=self.formation.formation_code,
"etudid": self.etudid, semestre_id=next_semestre_id,
"formation_code": self.formation.formation_code, origin_formsemestre_id=self.formsemestre_id,
"semestre_id": next_semestre_id,
"origin_formsemestre_id": self.formsemestre_id,
},
) )
cnx.commit() db.session.add(autorisation)
db.session.commit()
except: except:
cnx.rollback() cnx.session.rollback()
raise raise
sco_cache.invalidate_formsemestre( sco_cache.invalidate_formsemestre(
formsemestre_id=self.formsemestre_id formsemestre_id=self.formsemestre_id
@ -673,11 +656,11 @@ class SituationEtudParcoursGeneric:
) # > modif decision jury ) # > modif decision jury
class SituationEtudParcoursECTS(SituationEtudParcoursGeneric): class SituationEtudCursusECTS(SituationEtudCursusClassic):
"""Gestion parcours basés sur ECTS""" """Gestion parcours basés sur ECTS"""
def __init__(self, etud, formsemestre_id, nt): def __init__(self, etud, formsemestre_id, nt):
SituationEtudParcoursGeneric.__init__(self, etud, formsemestre_id, nt) SituationEtudCursusClassic.__init__(self, etud, formsemestre_id, nt)
def could_be_compensated(self): def could_be_compensated(self):
return False # jamais de compensations dans ce parcours return False # jamais de compensations dans ce parcours
@ -1032,102 +1015,3 @@ def etud_est_inscrit_ue(cnx, etudid, formsemestre_id, ue_id):
) )
return len(cursor.fetchall()) return len(cursor.fetchall())
_scolar_autorisation_inscription_editor = ndb.EditableTable(
"scolar_autorisation_inscription",
"autorisation_inscription_id",
("etudid", "formation_code", "semestre_id", "date", "origin_formsemestre_id"),
output_formators={"date": ndb.DateISOtoDMY},
input_formators={"date": ndb.DateDMYtoISO},
)
scolar_autorisation_inscription_list = _scolar_autorisation_inscription_editor.list
def formsemestre_get_autorisation_inscription(etudid, origin_formsemestre_id):
"""Liste des autorisations d'inscription pour cet étudiant
émanant du semestre indiqué.
"""
cnx = ndb.GetDBConnexion()
return scolar_autorisation_inscription_list(
cnx, {"origin_formsemestre_id": origin_formsemestre_id, "etudid": etudid}
)
def formsemestre_get_etud_capitalisation(
formation_id: int, semestre_idx: int, date_debut, etudid: int
) -> list[dict]:
"""Liste des UE capitalisées (ADM) correspondant au semestre sem et à l'étudiant.
Recherche dans les semestres de la même formation (code) avec le même
semestre_id et une date de début antérieure à celle du semestre mentionné.
Et aussi les UE externes validées.
Resultat: [ { 'formsemestre_id' :
'ue_id' : ue_id dans le semestre origine
'ue_code' :
'moy_ue' :
'event_date' :
'is_external'
} ]
"""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""
SELECT DISTINCT SFV.*, ue.ue_code
FROM notes_ue ue, notes_formations nf,
notes_formations nf2, scolar_formsemestre_validation SFV, notes_formsemestre sem
WHERE ue.formation_id = nf.id
and nf.formation_code = nf2.formation_code
and nf2.id=%(formation_id)s
and SFV.ue_id = ue.id
and SFV.code = 'ADM'
and SFV.etudid = %(etudid)s
and ( (sem.id = SFV.formsemestre_id
and sem.date_debut < %(date_debut)s
and sem.semestre_id = %(semestre_id)s )
or (
((SFV.formsemestre_id is NULL) OR (SFV.is_external)) -- les UE externes ou "anterieures"
AND (SFV.semestre_id is NULL OR SFV.semestre_id=%(semestre_id)s)
) )
""",
{
"etudid": etudid,
"formation_id": formation_id,
"semestre_id": semestre_idx,
"date_debut": date_debut,
},
)
return cursor.dictfetchall()
def list_formsemestre_utilisateurs_uecap(formsemestre_id):
"""Liste des formsemestres pouvant utiliser une UE capitalisee de ce semestre
(et qui doivent donc etre sortis du cache si l'on modifie ce
semestre): meme code formation, meme semestre_id, date posterieure"""
cnx = ndb.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT sem.id
FROM notes_formsemestre sem, notes_formations F
WHERE sem.formation_id = F.id
and F.formation_code = %(formation_code)s
and sem.semestre_id = %(semestre_id)s
and sem.date_debut >= %(date_debut)s
and sem.id != %(formsemestre_id)s;
""",
{
"formation_code": F["formation_code"],
"semestre_id": sem["semestre_id"],
"formsemestre_id": formsemestre_id,
"date_debut": ndb.DateDMYtoISO(sem["date_debut"]),
},
)
return [x[0] for x in cursor.fetchall()]

View File

@ -140,7 +140,7 @@ def do_ue_create(args):
def do_ue_delete(ue_id, delete_validations=False, force=False): def do_ue_delete(ue_id, delete_validations=False, force=False):
"delete UE and attached matieres (but not modules)" "delete UE and attached matieres (but not modules)"
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
ue = UniteEns.query.get_or_404(ue_id) ue = UniteEns.query.get_or_404(ue_id)
formation = ue.formation formation = ue.formation
@ -164,7 +164,7 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
# raise ScoLockedFormError() # raise ScoLockedFormError()
# Il y a-t-il des etudiants ayant validé cette UE ? # Il y a-t-il des etudiants ayant validé cette UE ?
# si oui, propose de supprimer les validations # si oui, propose de supprimer les validations
validations = sco_parcours_dut.scolar_formsemestre_validation_list( validations = sco_cursus_dut.scolar_formsemestre_validation_list(
cnx, args={"ue_id": ue.id} cnx, args={"ue_id": ue.id}
) )
if validations and not delete_validations and not force: if validations and not delete_validations and not force:

View File

@ -60,7 +60,7 @@ from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups_copy from app.scodoc import sco_groups_copy
from app.scodoc import sco_modalites from app.scodoc import sco_modalites
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_portal_apogee from app.scodoc import sco_portal_apogee
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
@ -1362,14 +1362,14 @@ def _reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new)
if e["ue_id"]: if e["ue_id"]:
e["ue_id"] = ues_old2new[e["ue_id"]] e["ue_id"] = ues_old2new[e["ue_id"]]
sco_etud.scolar_events_edit(cnx, e) sco_etud.scolar_events_edit(cnx, e)
validations = sco_parcours_dut.scolar_formsemestre_validation_list( validations = sco_cursus_dut.scolar_formsemestre_validation_list(
cnx, args={"formsemestre_id": formsemestre_id} cnx, args={"formsemestre_id": formsemestre_id}
) )
for e in validations: for e in validations:
if e["ue_id"]: if e["ue_id"]:
e["ue_id"] = ues_old2new[e["ue_id"]] e["ue_id"] = ues_old2new[e["ue_id"]]
# log('e=%s' % e ) # log('e=%s' % e )
sco_parcours_dut.scolar_formsemestre_validation_edit(cnx, e) sco_cursus_dut.scolar_formsemestre_validation_edit(cnx, e)
def formsemestre_delete(formsemestre_id): def formsemestre_delete(formsemestre_id):

View File

@ -51,7 +51,7 @@ from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_validation from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
from app.scodoc import sco_etud from app.scodoc import sco_etud
@ -450,7 +450,7 @@ def _list_ue_with_coef_and_validations(sem, etudid):
else: else:
ue["uecoef"] = {} ue["uecoef"] = {}
# add validation # add validation
validation = sco_parcours_dut.scolar_formsemestre_validation_list( validation = sco_cursus_dut.scolar_formsemestre_validation_list(
cnx, cnx,
args={ args={
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,

View File

@ -59,8 +59,9 @@ from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus
from app.scodoc.sco_parcours_dut import etud_est_inscrit_ue from app.scodoc import sco_cursus_dut
from app.scodoc.sco_cursus_dut import etud_est_inscrit_ue
from app.scodoc import sco_photos from app.scodoc import sco_photos
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_pvjury from app.scodoc import sco_pvjury
@ -108,7 +109,7 @@ def formsemestre_validation_etud_form(
check = True check = True
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
if not Se.sem["etat"]: if not Se.sem["etat"]:
raise ScoValueError("validation: semestre verrouille") raise ScoValueError("validation: semestre verrouille")
@ -274,15 +275,12 @@ def formsemestre_validation_etud_form(
ass = "non assidu" ass = "non assidu"
H.append("<p>Décision existante du %(event_date)s: %(code)s" % decision_jury) H.append("<p>Décision existante du %(event_date)s: %(code)s" % decision_jury)
H.append(" (%s)" % ass) H.append(" (%s)" % ass)
auts = sco_parcours_dut.formsemestre_get_autorisation_inscription( autorisations = ScolarAutorisationInscription.query.filter_by(
etudid, formsemestre_id etudid=etudid, origin_formsemestre_id=formsemestre_id
) ).all()
if auts: if autorisations:
H.append(". Autorisé%s à s'inscrire en " % etud["ne"]) H.append(". Autorisé%s à s'inscrire en " % etud["ne"])
alist = [] H.append(", ".join([f"S{aut.semestre_id}" for aut in autorisations]) + ".")
for aut in auts:
alist.append(str(aut["semestre_id"]))
H.append(", ".join(["S%s" % x for x in alist]) + ".")
H.append("</p>") H.append("</p>")
# Cas particulier pour ATJ: corriger precedent avant de continuer # Cas particulier pour ATJ: corriger precedent avant de continuer
@ -382,7 +380,7 @@ def formsemestre_validation_etud(
): ):
"""Enregistre validation""" """Enregistre validation"""
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
# retrouve la decision correspondant au code: # retrouve la decision correspondant au code:
choices = Se.get_possible_choices(assiduite=True) choices = Se.get_possible_choices(assiduite=True)
choices += Se.get_possible_choices(assiduite=False) choices += Se.get_possible_choices(assiduite=False)
@ -415,7 +413,7 @@ def formsemestre_validation_etud_manu(
if assidu: if assidu:
assidu = True assidu = True
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
if code_etat in Se.parcours.UNUSED_CODES: if code_etat in Se.parcours.UNUSED_CODES:
raise ScoValueError("code decision invalide dans ce parcours") raise ScoValueError("code decision invalide dans ce parcours")
# Si code ADC, extrait le semestre utilisé: # Si code ADC, extrait le semestre utilisé:
@ -430,7 +428,7 @@ def formsemestre_validation_etud_manu(
formsemestre_id_utilise_pour_compenser = None formsemestre_id_utilise_pour_compenser = None
# Construit le choix correspondant: # Construit le choix correspondant:
choice = sco_parcours_dut.DecisionSem( choice = sco_cursus_dut.DecisionSem(
code_etat=code_etat, code_etat=code_etat,
new_code_prev=new_code_prev, new_code_prev=new_code_prev,
devenir=devenir, devenir=devenir,
@ -910,7 +908,7 @@ def do_formsemestre_validation_auto(formsemestre_id):
conflicts = [] # liste des etudiants avec decision differente déjà saisie conflicts = [] # liste des etudiants avec decision differente déjà saisie
for etudid in etudids: for etudid in etudids:
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": formsemestre_id} {"etudid": etudid, "formsemestre_id": formsemestre_id}
)[0] )[0]
@ -932,15 +930,13 @@ def do_formsemestre_validation_auto(formsemestre_id):
if decision_sem and decision_sem["code"] != ADM: if decision_sem and decision_sem["code"] != ADM:
ok = False ok = False
conflicts.append(etud) conflicts.append(etud)
autorisations = sco_parcours_dut.formsemestre_get_autorisation_inscription( autorisations = ScolarAutorisationInscription.query.filter_by(
etudid, formsemestre_id etudid=etudid, origin_formsemestre_id=formsemestre_id
) ).all()
if ( if len(autorisations) != 0:
len(autorisations) != 0
): # accepte le cas ou il n'y a pas d'autorisation : BUG 23/6/7, A RETIRER ENSUITE
if ( if (
len(autorisations) != 1 len(autorisations) > 1
or autorisations[0]["semestre_id"] != next_semestre_id or autorisations[0].semestre_id != next_semestre_id
): ):
if ok: if ok:
conflicts.append(etud) conflicts.append(etud)
@ -1176,7 +1172,7 @@ def do_formsemestre_validate_previous_ue(
) )
else: else:
sco_formsemestre.do_formsemestre_uecoef_delete(cnx, formsemestre_id, ue_id) sco_formsemestre.do_formsemestre_uecoef_delete(cnx, formsemestre_id, ue_id)
sco_parcours_dut.do_formsemestre_validate_ue( sco_cursus_dut.do_formsemestre_validate_ue(
cnx, cnx,
nt, nt,
formsemestre_id, # "importe" cette UE dans le semestre (new 3/2015) formsemestre_id, # "importe" cette UE dans le semestre (new 3/2015)

View File

@ -56,8 +56,9 @@ import app.scodoc.notesdb as ndb
from app import log, cache from app import log, cache
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_cursus
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_xml from app.scodoc import sco_xml
@ -1489,13 +1490,13 @@ def _get_prev_moy(etudid, formsemestre_id):
"""Donne la derniere moyenne generale calculee pour cette étudiant, """Donne la derniere moyenne generale calculee pour cette étudiant,
ou 0 si on n'en trouve pas (nouvel inscrit,...). ou 0 si on n'en trouve pas (nouvel inscrit,...).
""" """
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
info = sco_etud.get_etud_info(etudid=etudid, filled=True) info = sco_etud.get_etud_info(etudid=etudid, filled=True)
if not info: if not info:
raise ScoValueError("etudiant invalide: etudid=%s" % etudid) raise ScoValueError("etudiant invalide: etudid=%s" % etudid)
etud = info[0] etud = info[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
if Se.prev: if Se.prev:
prev_sem = FormSemestre.query.get(Se.prev["formsemestre_id"]) prev_sem = FormSemestre.query.get(Se.prev["formsemestre_id"])
nt: NotesTableCompat = res_sem.load_formsemestre_results(prev_sem) nt: NotesTableCompat = res_sem.load_formsemestre_results(prev_sem)

View File

@ -49,7 +49,7 @@ from app.scodoc import sco_excel
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus
from app.scodoc import sco_portal_apogee from app.scodoc import sco_portal_apogee
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_etud from app.scodoc import sco_etud
@ -776,7 +776,7 @@ def groups_table(
m.update(etud) m.update(etud)
sco_etud.etud_add_lycee_infos(etud) sco_etud.etud_add_lycee_infos(etud)
# et ajoute le parcours # et ajoute le parcours
Se = sco_parcours_dut.SituationEtudParcours( Se = sco_cursus.get_situation_etud_cursus(
etud, groups_infos.formsemestre_id etud, groups_infos.formsemestre_id
) )
m["parcours"] = Se.get_parcours_descr() m["parcours"] = Se.get_parcours_descr()

View File

@ -39,7 +39,7 @@ from app.models import ModuleImpl
from app.models.evaluations import Evaluation from app.models.evaluations import Evaluation
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_exceptions import ScoInvalidIdType from app.scodoc.sco_exceptions import ScoInvalidIdType
from app.scodoc.sco_parcours_dut import formsemestre_has_decisions from app.scodoc.sco_cursus_dut import formsemestre_has_decisions
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc import html_sco_header from app.scodoc import html_sco_header

View File

@ -46,7 +46,7 @@ from app.scodoc import sco_codes_parcours
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_status from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_photos from app.scodoc import sco_photos
from app.scodoc import sco_users from app.scodoc import sco_users
@ -269,7 +269,7 @@ def ficheEtud(etudid=None):
sem_info[sem["formsemestre_id"]] = grlink sem_info[sem["formsemestre_id"]] = grlink
if info["sems"]: if info["sems"]:
Se = sco_parcours_dut.SituationEtudParcours(etud, info["last_formsemestre_id"]) Se = sco_cursus.get_situation_etud_cursus(etud, info["last_formsemestre_id"])
info["liste_inscriptions"] = formsemestre_recap_parcours_table( info["liste_inscriptions"] = formsemestre_recap_parcours_table(
Se, Se,
etudid, etudid,

View File

@ -24,14 +24,14 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True):
seul le directeur des études peut saisir des notes (et il ne devrait pas). seul le directeur des études peut saisir des notes (et il ne devrait pas).
""" """
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
if not sem["etat"]: if not sem["etat"]:
return False # semestre verrouillé return False # semestre verrouillé
if sco_parcours_dut.formsemestre_has_decisions(sem["formsemestre_id"]): if sco_cursus_dut.formsemestre_has_decisions(sem["formsemestre_id"]):
# il y a des décisions de jury dans ce semestre ! # il y a des décisions de jury dans ce semestre !
return ( return (
authuser.has_permission(Permission.ScoEditAllNotes) authuser.has_permission(Permission.ScoEditAllNotes)

View File

@ -37,14 +37,14 @@ from flask_login import current_user
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre, Identite from app.models import FormSemestre, Identite, ScolarAutorisationInscription
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_excel from app.scodoc import sco_excel
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import sco_version import sco_version
@ -78,7 +78,7 @@ def feuille_preparation_jury(formsemestre_id):
nbabs = {} nbabs = {}
nbabsjust = {} nbabsjust = {}
for etud in etuds: for etud in etuds:
Se = sco_parcours_dut.SituationEtudParcours( Se = sco_cursus.get_situation_etud_cursus(
etud.to_dict_scodoc7(), formsemestre_id etud.to_dict_scodoc7(), formsemestre_id
) )
if Se.prev: if Se.prev:
@ -119,10 +119,11 @@ def feuille_preparation_jury(formsemestre_id):
if decision["compense_formsemestre_id"]: if decision["compense_formsemestre_id"]:
code[etud.id] += "+" # indique qu'il a servi a compenser code[etud.id] += "+" # indique qu'il a servi a compenser
assidu[etud.id] = {False: "Non", True: "Oui"}.get(decision["assidu"], "") assidu[etud.id] = {False: "Non", True: "Oui"}.get(decision["assidu"], "")
aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription(
etud.id, formsemestre_id autorisations = ScolarAutorisationInscription.query.filter_by(
) etudid=etud.id, origin_formsemestre_id=formsemestre_id
autorisations[etud.id] = ", ".join(["S%s" % x["semestre_id"] for x in aut_list]) ).all()
autorisations[etud.id] = ", ".join(["S{x.semestre_id}" for x in autorisations])
# parcours: # parcours:
parcours[etud.id] = Se.get_parcours_descr() parcours[etud.id] = Se.get_parcours_descr()
# groupe principal (td) # groupe principal (td)

View File

@ -57,24 +57,24 @@ from flask import g, request
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre, UniteEns from app.models import FormSemestre, UniteEns, ScolarAutorisationInscription
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app import log from app import log
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_cache from app.scodoc import sco_cursus
from app.scodoc import sco_cursus_dut
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_groups_view from app.scodoc import sco_groups_view
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_pdf from app.scodoc import sco_pdf
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_pvpdf from app.scodoc import sco_pvpdf
from app.scodoc import sco_etud
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
from app.scodoc.sco_pdf import PDFLOCK from app.scodoc.sco_pdf import PDFLOCK
@ -138,12 +138,9 @@ def _descr_decision_sem_abbrev(etat, decision_sem):
return decision return decision
def descr_autorisations(autorisations): def descr_autorisations(autorisations: list[ScolarAutorisationInscription]) -> str:
"résumé textuel des autorisations d'inscription (-> 'S1, S3' )" "résumé textuel des autorisations d'inscription (-> 'S1, S3' )"
alist = [] return ", ".join([f"S{a.semestre_id}" for a in autorisations])
for aut in autorisations:
alist.append("S" + str(aut["semestre_id"]))
return ", ".join(alist)
def _comp_ects_by_ue_code(nt, decision_ues): def _comp_ects_by_ue_code(nt, decision_ues):
@ -234,7 +231,7 @@ def dict_pvjury(
D = {} # même chose que L, mais { etudid : dec } D = {} # même chose que L, mais { etudid : dec }
for etudid in etudids: for etudid in etudids:
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
semestre_non_terminal = semestre_non_terminal or Se.semestre_non_terminal semestre_non_terminal = semestre_non_terminal or Se.semestre_non_terminal
d = {} d = {}
d["identite"] = nt.identdict[etudid] d["identite"] = nt.identdict[etudid]
@ -280,17 +277,18 @@ def dict_pvjury(
else: else:
d["decision_sem_descr"] = _descr_decision_sem(d["etat"], d["decision_sem"]) d["decision_sem_descr"] = _descr_decision_sem(d["etat"], d["decision_sem"])
d["autorisations"] = sco_parcours_dut.formsemestre_get_autorisation_inscription( autorisations = ScolarAutorisationInscription.query.filter_by(
etudid, formsemestre_id etudid=etudid, origin_formsemestre_id=formsemestre_id
) ).all()
d["autorisations_descr"] = descr_autorisations(d["autorisations"]) d["autorisations"] = [a.to_dict() for a in autorisations]
d["autorisations_descr"] = descr_autorisations(autorisations)
d["validation_parcours"] = Se.parcours_validated() d["validation_parcours"] = Se.parcours_validated()
d["parcours"] = Se.get_parcours_descr(filter_futur=True) d["parcours"] = Se.get_parcours_descr(filter_futur=True)
if with_parcours_decisions: if with_parcours_decisions:
d["parcours_decisions"] = Se.get_parcours_decisions() d["parcours_decisions"] = Se.get_parcours_decisions()
# Observations sur les compensations: # Observations sur les compensations:
compensators = sco_parcours_dut.scolar_formsemestre_validation_list( compensators = sco_cursus_dut.scolar_formsemestre_validation_list(
cnx, args={"compense_formsemestre_id": formsemestre_id, "etudid": etudid} cnx, args={"compense_formsemestre_id": formsemestre_id, "etudid": etudid}
) )
obs = [] obs = []

View File

@ -50,7 +50,7 @@ from app.scodoc import sco_formsemestre
from app.scodoc import sco_pdf from app.scodoc import sco_pdf
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc.sco_logos import find_logo from app.scodoc.sco_logos import find_logo
from app.scodoc.sco_parcours_dut import SituationEtudParcours from app.scodoc.sco_cursus_dut import SituationEtudCursus
from app.scodoc.sco_pdf import SU from app.scodoc.sco_pdf import SU
import sco_version import sco_version
@ -428,7 +428,7 @@ def pdf_lettre_individuelle(sem, decision, etud, params, signature=None):
""" """
# #
formsemestre_id = sem["formsemestre_id"] formsemestre_id = sem["formsemestre_id"]
Se: SituationEtudParcours = decision["Se"] Se: SituationEtudCursus = decision["Se"]
t, s = _descr_jury(sem, Se.parcours_validated() or not Se.semestre_non_terminal) t, s = _descr_jury(sem, Se.parcours_validated() or not Se.semestre_non_terminal)
objects = [] objects = []
style = reportlab.lib.styles.ParagraphStyle({}) style = reportlab.lib.styles.ParagraphStyle({})

View File

@ -41,7 +41,7 @@ import pydot
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre, ScolarAutorisationInscription
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.models import FormationModalite from app.models import FormationModalite
@ -51,7 +51,6 @@ from app.scodoc import sco_codes_parcours
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
import sco_version import sco_version
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
@ -81,10 +80,10 @@ def formsemestre_etuds_stats(sem, only_primo=False):
if "codedecision" not in etud: if "codedecision" not in etud:
etud["codedecision"] = "(nd)" # pas de decision jury etud["codedecision"] = "(nd)" # pas de decision jury
# Ajout devenir (autorisations inscriptions), utile pour stats passage # Ajout devenir (autorisations inscriptions), utile pour stats passage
aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription( aut_list = ScolarAutorisationInscription.query.filter_by(
etudid, sem["formsemestre_id"] etudid=etudid, origin_formsemestre_id=sem["formsemestre_id"]
) ).all()
autorisations = ["S%s" % x["semestre_id"] for x in aut_list] autorisations = [f"S{a.semestre_id}" for a in aut_list]
autorisations.sort() autorisations.sort()
autorisations_str = ", ".join(autorisations) autorisations_str = ", ".join(autorisations)
etud["devenir"] = autorisations_str etud["devenir"] = autorisations_str

View File

@ -20,6 +20,7 @@ from config import TestConfig
from tests.unit import sco_fake_gen from tests.unit import sco_fake_gen
import app import app
from app import db
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre
@ -31,8 +32,7 @@ from app.scodoc import sco_codes_parcours
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_db from app.scodoc import sco_evaluation_db
from app.scodoc import sco_formsemestre_validation from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_parcours_dut from app.scodoc import sco_cursus_dut
from app.scodoc import sco_cache
from app.scodoc import sco_saisie_notes from app.scodoc import sco_saisie_notes
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
@ -194,20 +194,20 @@ def run_sco_basic(verbose=False):
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance # --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
# on n'a pas encore saisi de décisions # on n'a pas encore saisi de décisions
assert not sco_parcours_dut.formsemestre_has_decisions(formsemestre_id) assert not sco_cursus_dut.formsemestre_has_decisions(formsemestre_id)
# Saisie d'un décision AJ, non assidu # Saisie d'un décision AJ, non assidu
etudid = etuds[-1]["etudid"] etudid = etuds[-1]["etudid"]
sco_parcours_dut.formsemestre_validate_ues( sco_cursus_dut.formsemestre_validate_ues(
formsemestre_id, etudid, sco_codes_parcours.AJ, False formsemestre_id, etudid, sco_codes_parcours.AJ, False
) )
assert sco_parcours_dut.formsemestre_has_decisions( assert sco_cursus_dut.formsemestre_has_decisions(
formsemestre_id formsemestre_id
), "décisions manquantes" ), "décisions manquantes"
# Suppression de la décision # Suppression de la décision
sco_formsemestre_validation.formsemestre_validation_suppress_etud( sco_formsemestre_validation.formsemestre_validation_suppress_etud(
formsemestre_id, etudid formsemestre_id, etudid
) )
assert not sco_parcours_dut.formsemestre_has_decisions( assert not sco_cursus_dut.formsemestre_has_decisions(
formsemestre_id formsemestre_id
), "décisions non effacées" ), "décisions non effacées"