forked from ScoDoc/ScoDoc
Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into xp
This commit is contained in:
commit
e2141b6505
@ -502,12 +502,10 @@ def clear_scodoc_cache():
|
|||||||
|
|
||||||
|
|
||||||
# --------- Logging
|
# --------- Logging
|
||||||
def log(msg: str, silent_test=True):
|
def log(msg: str):
|
||||||
"""log a message.
|
"""log a message.
|
||||||
If Flask app, use configured logger, else stderr.
|
If Flask app, use configured logger, else stderr.
|
||||||
"""
|
"""
|
||||||
if silent_test and current_app and current_app.config["TESTING"]:
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
dept = getattr(g, "scodoc_dept", "")
|
dept = getattr(g, "scodoc_dept", "")
|
||||||
msg = f" ({dept}) {msg}"
|
msg = f" ({dept}) {msg}"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
"""ScoDoc 9 API : Absences
|
"""ScoDoc 9 API : Absences
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
"""ScoDoc 9 API : outils
|
"""ScoDoc 9 API : outils
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -361,7 +361,7 @@ class BulletinBUT:
|
|||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etat_inscription": etat_inscription,
|
"etat_inscription": etat_inscription,
|
||||||
"options": sco_preferences.bulletin_option_affichage(
|
"options": sco_preferences.bulletin_option_affichage(
|
||||||
formsemestre.id, self.prefs
|
formsemestre, self.prefs
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
if not published:
|
if not published:
|
||||||
@ -465,6 +465,7 @@ class BulletinBUT:
|
|||||||
"ressources": {},
|
"ressources": {},
|
||||||
"saes": {},
|
"saes": {},
|
||||||
"ues": {},
|
"ues": {},
|
||||||
|
"ues_capitalisees": {},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -91,9 +91,15 @@ from app.models.ues import UniteEns
|
|||||||
from app.models.validations import ScolarFormSemestreValidation
|
from app.models.validations import ScolarFormSemestreValidation
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_codes_parcours as sco_codes
|
from app.scodoc import sco_codes_parcours as sco_codes
|
||||||
from app.scodoc.sco_codes_parcours import CODES_UE_VALIDES, RED, UE_STANDARD
|
from app.scodoc.sco_codes_parcours import (
|
||||||
|
BUT_CODES_ORDERED,
|
||||||
|
CODES_RCUE_VALIDES,
|
||||||
|
CODES_UE_VALIDES,
|
||||||
|
RED,
|
||||||
|
UE_STANDARD,
|
||||||
|
)
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc.sco_exceptions import ScoException, ScoValueError
|
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
|
||||||
|
|
||||||
|
|
||||||
class NoRCUEError(ScoValueError):
|
class NoRCUEError(ScoValueError):
|
||||||
@ -170,7 +176,7 @@ class DecisionsProposees:
|
|||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"""<{self.__class__.__name__} valid={self.code_valide
|
return f"""<{self.__class__.__name__} valid={self.code_valide
|
||||||
} codes={self.codes} explanation={self.explanation}"""
|
} codes={self.codes} explanation={self.explanation}>"""
|
||||||
|
|
||||||
|
|
||||||
class DecisionsProposeesAnnee(DecisionsProposees):
|
class DecisionsProposeesAnnee(DecisionsProposees):
|
||||||
@ -205,6 +211,8 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
formsemestre: FormSemestre,
|
formsemestre: FormSemestre,
|
||||||
):
|
):
|
||||||
assert formsemestre.formation.is_apc()
|
assert formsemestre.formation.is_apc()
|
||||||
|
if formsemestre.formation.referentiel_competence is None:
|
||||||
|
raise ScoNoReferentielCompetences(formation=formsemestre.formation)
|
||||||
super().__init__(etud=etud)
|
super().__init__(etud=etud)
|
||||||
self.formsemestre = formsemestre
|
self.formsemestre = formsemestre
|
||||||
"le formsemestre utilisé pour construire ce deca"
|
"le formsemestre utilisé pour construire ce deca"
|
||||||
@ -348,8 +356,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
"vrai si l'année est réussie, tous niveaux validables ou validés par le jury"
|
"vrai si l'année est réussie, tous niveaux validables ou validés par le jury"
|
||||||
self.valide_moitie_rcue = self.nb_validables > (self.nb_competences // 2)
|
self.valide_moitie_rcue = self.nb_validables > (self.nb_competences // 2)
|
||||||
"Peut passer si plus de la moitié validables et tous > 8"
|
"Vrai si plus de la moitié des RCUE validables"
|
||||||
self.passage_de_droit = self.valide_moitie_rcue and (self.nb_rcues_under_8 == 0)
|
self.passage_de_droit = self.valide_moitie_rcue and (self.nb_rcues_under_8 == 0)
|
||||||
|
"Vrai si peut passer dans l'année BUT suivante: plus de la moitié validables et tous > 8"
|
||||||
# XXX TODO ajouter condition pour passage en S5
|
# XXX TODO ajouter condition pour passage en S5
|
||||||
|
|
||||||
# Enfin calcule les codes des UE:
|
# Enfin calcule les codes des UE:
|
||||||
@ -362,7 +371,6 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
"s" if plural else ""} sur {self.nb_competences}"""
|
"s" if plural else ""} sur {self.nb_competences}"""
|
||||||
if self.admis:
|
if self.admis:
|
||||||
self.codes = [sco_codes.ADM] + self.codes
|
self.codes = [sco_codes.ADM] + self.codes
|
||||||
self.explanation = expl_rcues
|
|
||||||
# elif not self.jury_annuel:
|
# elif not self.jury_annuel:
|
||||||
# self.codes = [] # pas de décision annuelle sur semestres impairs
|
# self.codes = [] # pas de décision annuelle sur semestres impairs
|
||||||
elif self.inscription_etat != scu.INSCRIT:
|
elif self.inscription_etat != scu.INSCRIT:
|
||||||
@ -378,9 +386,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
sco_codes.ABL,
|
sco_codes.ABL,
|
||||||
sco_codes.EXCLU,
|
sco_codes.EXCLU,
|
||||||
]
|
]
|
||||||
|
expl_rcues = ""
|
||||||
elif self.passage_de_droit:
|
elif self.passage_de_droit:
|
||||||
self.codes = [sco_codes.PASD, sco_codes.ADJ] + self.codes
|
self.codes = [sco_codes.PASD, sco_codes.ADJ] + self.codes
|
||||||
self.explanation = expl_rcues
|
|
||||||
elif self.valide_moitie_rcue: # mais au moins 1 rcue insuffisante
|
elif self.valide_moitie_rcue: # mais au moins 1 rcue insuffisante
|
||||||
self.codes = [
|
self.codes = [
|
||||||
sco_codes.RED,
|
sco_codes.RED,
|
||||||
@ -388,7 +396,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
sco_codes.PAS1NCI,
|
sco_codes.PAS1NCI,
|
||||||
sco_codes.ADJ,
|
sco_codes.ADJ,
|
||||||
] + self.codes
|
] + self.codes
|
||||||
self.explanation = expl_rcues + f" et {self.nb_rcues_under_8} < 8"
|
expl_rcues += f" et {self.nb_rcues_under_8} < 8"
|
||||||
else:
|
else:
|
||||||
self.codes = [
|
self.codes = [
|
||||||
sco_codes.RED,
|
sco_codes.RED,
|
||||||
@ -397,17 +405,21 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
sco_codes.ADJ,
|
sco_codes.ADJ,
|
||||||
sco_codes.PASD, # voir #488 (discutable, conventions locales)
|
sco_codes.PASD, # voir #488 (discutable, conventions locales)
|
||||||
] + self.codes
|
] + self.codes
|
||||||
self.explanation = (
|
expl_rcues += f""" et {self.nb_rcues_under_8} niveau{'x' if self.nb_rcues_under_8 > 1 else ''} < 8"""
|
||||||
expl_rcues
|
|
||||||
+ f""" et {self.nb_rcues_under_8}
|
|
||||||
niveau{'x' if self.nb_rcues_under_8 > 1 else ''} < 8"""
|
|
||||||
)
|
|
||||||
# Si l'un des semestres est extérieur, propose ADM
|
# Si l'un des semestres est extérieur, propose ADM
|
||||||
if (
|
if (
|
||||||
self.formsemestre_impair and self.formsemestre_impair.modalite == "EXT"
|
self.formsemestre_impair and self.formsemestre_impair.modalite == "EXT"
|
||||||
) or (self.formsemestre_pair and self.formsemestre_pair.modalite == "EXT"):
|
) or (self.formsemestre_pair and self.formsemestre_pair.modalite == "EXT"):
|
||||||
self.codes.insert(0, sco_codes.ADM)
|
self.codes.insert(0, sco_codes.ADM)
|
||||||
|
self.explanation = f"<div>{expl_rcues}</div>"
|
||||||
|
messages = self.descr_pb_coherence()
|
||||||
|
if messages:
|
||||||
|
self.explanation += (
|
||||||
|
'<div class="warning">'
|
||||||
|
+ '</div><div class="warning">'.join(messages)
|
||||||
|
+ "</div>"
|
||||||
|
)
|
||||||
#
|
#
|
||||||
|
|
||||||
def infos(self) -> str:
|
def infos(self) -> str:
|
||||||
@ -581,9 +593,10 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
|
|
||||||
def compute_decisions_niveaux(self) -> dict[int, "DecisionsProposeesRCUE"]:
|
def compute_decisions_niveaux(self) -> dict[int, "DecisionsProposeesRCUE"]:
|
||||||
"""Pour chaque niveau de compétence de cette année, construit
|
"""Pour chaque niveau de compétence de cette année, construit
|
||||||
le DecisionsProposeesRCUE,
|
le DecisionsProposeesRCUE, ou None s'il n'y en a pas
|
||||||
ou None s'il n'y en a pas
|
|
||||||
(ne devrait pas arriver car compute_rcues_annee vérifie déjà cela).
|
(ne devrait pas arriver car compute_rcues_annee vérifie déjà cela).
|
||||||
|
|
||||||
|
Appelé à la construction du deca, donc avant décisions manuelles.
|
||||||
Return: { niveau_id : DecisionsProposeesRCUE }
|
Return: { niveau_id : DecisionsProposeesRCUE }
|
||||||
"""
|
"""
|
||||||
# Retrouve le RCUE associé à chaque niveau
|
# Retrouve le RCUE associé à chaque niveau
|
||||||
@ -630,6 +643,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
|
|
||||||
def record_form(self, form: dict):
|
def record_form(self, form: dict):
|
||||||
"""Enregistre les codes de jury en base
|
"""Enregistre les codes de jury en base
|
||||||
|
à partir d'un dict représentant le formulaire jury BUT:
|
||||||
form dict:
|
form dict:
|
||||||
- 'code_ue_1896' : 'AJ' code pour l'UE id 1896
|
- 'code_ue_1896' : 'AJ' code pour l'UE id 1896
|
||||||
- 'code_rcue_6" : 'ADM' code pour le RCUE du niveau 6
|
- 'code_rcue_6" : 'ADM' code pour le RCUE du niveau 6
|
||||||
@ -639,32 +653,42 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
et qu'il n'y en a pas déjà, enregistre ceux par défaut.
|
et qu'il n'y en a pas déjà, enregistre ceux par défaut.
|
||||||
"""
|
"""
|
||||||
log("jury_but.DecisionsProposeesAnnee.record_form")
|
log("jury_but.DecisionsProposeesAnnee.record_form")
|
||||||
with sco_cache.DeferredSemCacheManager():
|
code_annee = None
|
||||||
for key in form:
|
codes_rcues = [] # [ (dec_rcue, code), ... ]
|
||||||
code = form[key]
|
codes_ues = [] # [ (dec_ue, code), ... ]
|
||||||
# Codes d'UE
|
for key in form:
|
||||||
m = re.match(r"^code_ue_(\d+)$", key)
|
code = form[key]
|
||||||
|
# Codes d'UE
|
||||||
|
m = re.match(r"^code_ue_(\d+)$", key)
|
||||||
|
if m:
|
||||||
|
ue_id = int(m.group(1))
|
||||||
|
dec_ue = self.decisions_ues.get(ue_id)
|
||||||
|
if not dec_ue:
|
||||||
|
raise ScoValueError(f"UE invalide ue_id={ue_id}")
|
||||||
|
codes_ues.append((dec_ue, code))
|
||||||
|
else:
|
||||||
|
# Codes de RCUE
|
||||||
|
m = re.match(r"^code_rcue_(\d+)$", key)
|
||||||
if m:
|
if m:
|
||||||
ue_id = int(m.group(1))
|
niveau_id = int(m.group(1))
|
||||||
dec_ue = self.decisions_ues.get(ue_id)
|
dec_rcue = self.decisions_rcue_by_niveau.get(niveau_id)
|
||||||
if not dec_ue:
|
if not dec_rcue:
|
||||||
raise ScoValueError(f"UE invalide ue_id={ue_id}")
|
raise ScoValueError(f"RCUE invalide niveau_id={niveau_id}")
|
||||||
dec_ue.record(code)
|
codes_rcues.append((dec_rcue, code))
|
||||||
else:
|
elif key == "code_annee":
|
||||||
# Codes de RCUE
|
# Code annuel
|
||||||
m = re.match(r"^code_rcue_(\d+)$", key)
|
code_annee = code
|
||||||
if m:
|
|
||||||
niveau_id = int(m.group(1))
|
|
||||||
dec_rcue = self.decisions_rcue_by_niveau.get(niveau_id)
|
|
||||||
if not dec_rcue:
|
|
||||||
raise ScoValueError(f"RCUE invalide niveau_id={niveau_id}")
|
|
||||||
dec_rcue.record(code)
|
|
||||||
elif key == "code_annee":
|
|
||||||
# Code annuel
|
|
||||||
self.record(code)
|
|
||||||
|
|
||||||
|
with sco_cache.DeferredSemCacheManager():
|
||||||
|
# Enregistre les codes, dans l'ordre UE, RCUE, Année
|
||||||
|
for dec_ue, code in codes_ues:
|
||||||
|
dec_ue.record(code)
|
||||||
|
for dec_rcue, code in codes_rcues:
|
||||||
|
dec_rcue.record(code)
|
||||||
|
self.record(code_annee)
|
||||||
self.record_all()
|
self.record_all()
|
||||||
db.session.commit()
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False):
|
def record(self, code: str, no_overwrite=False):
|
||||||
"""Enregistre le code de l'année, et au besoin l'autorisation d'inscription.
|
"""Enregistre le code de l'année, et au besoin l'autorisation d'inscription.
|
||||||
@ -682,7 +706,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
return # no change
|
return # no change
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
db.session.flush()
|
db.session.commit()
|
||||||
if code is None:
|
if code is None:
|
||||||
self.validation = None
|
self.validation = None
|
||||||
else:
|
else:
|
||||||
@ -693,12 +717,15 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
code=code,
|
code=code,
|
||||||
)
|
)
|
||||||
|
db.session.add(self.validation)
|
||||||
|
db.session.commit()
|
||||||
|
log(f"Recording {self}: {code}")
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
method="jury_but",
|
method="jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation année BUT{self.annee_but}: {code}",
|
msg=f"Validation année BUT{self.annee_but}: {code}",
|
||||||
)
|
)
|
||||||
db.session.add(self.validation)
|
|
||||||
# --- Autorisation d'inscription dans semestre suivant ?
|
# --- Autorisation d'inscription dans semestre suivant ?
|
||||||
if self.formsemestre_pair is not None:
|
if self.formsemestre_pair is not None:
|
||||||
if code is None:
|
if code is None:
|
||||||
@ -729,29 +756,49 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
if self.formsemestre_pair is not None:
|
if self.formsemestre_pair is not None:
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id)
|
||||||
|
|
||||||
def record_all(self):
|
def record_all(self, no_overwrite: bool = True):
|
||||||
"""Enregistre les codes qui n'ont pas été spécifiés par le formulaire,
|
"""Enregistre les codes qui n'ont pas été spécifiés par le formulaire,
|
||||||
et sont donc en mode "automatique"
|
et sont donc en mode "automatique".
|
||||||
|
- Si "à cheval", ne modifie pas les codes UE de l'année scolaire précédente.
|
||||||
|
- Pour les RCUE: n'enregistre que si la nouvelle décision est plus favorable que l'ancienne.
|
||||||
"""
|
"""
|
||||||
decisions = (
|
# Toujours valider dans l'ordre UE, RCUE, Année:
|
||||||
list(self.decisions_ues.values())
|
annee_scolaire = self.formsemestre.annee_scolaire()
|
||||||
+ list(self.decisions_rcue_by_niveau.values())
|
# UEs
|
||||||
+ [self]
|
for dec_ue in self.decisions_ues.values():
|
||||||
)
|
if (
|
||||||
for dec in decisions:
|
not dec_ue.recorded
|
||||||
if not dec.recorded:
|
) and dec_ue.formsemestre.annee_scolaire() == annee_scolaire:
|
||||||
# rappel: le code par défaut est en tête
|
# rappel: le code par défaut est en tête
|
||||||
code = dec.codes[0] if dec.codes else None
|
code = dec_ue.codes[0] if dec_ue.codes else None
|
||||||
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
||||||
dec.record(code, no_overwrite=True)
|
# (no_overwrite=True) sauf en mode test yaml
|
||||||
|
dec_ue.record(code, no_overwrite=no_overwrite)
|
||||||
|
# RCUE : enregistre seulement si pas déjà validé "mieux"
|
||||||
|
for dec_rcue in self.decisions_rcue_by_niveau.values():
|
||||||
|
code = dec_rcue.codes[0] if dec_rcue.codes else None
|
||||||
|
if (not dec_rcue.recorded) and (
|
||||||
|
(not dec_rcue.validation)
|
||||||
|
or BUT_CODES_ORDERED.get(dec_rcue.validation.code, 0)
|
||||||
|
< BUT_CODES_ORDERED.get(code, 0)
|
||||||
|
):
|
||||||
|
dec_rcue.record(code, no_overwrite=no_overwrite)
|
||||||
|
# Année:
|
||||||
|
if not self.recorded:
|
||||||
|
# rappel: le code par défaut est en tête
|
||||||
|
code = self.codes[0] if self.codes else None
|
||||||
|
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
||||||
|
# (no_overwrite=True) sauf en mode test yaml
|
||||||
|
self.record(code, no_overwrite=no_overwrite)
|
||||||
|
|
||||||
def erase(self, only_one_sem=False):
|
def erase(self, only_one_sem=False):
|
||||||
"""Efface les décisions de jury de cet étudiant
|
"""Efface les décisions de jury de cet étudiant
|
||||||
pour cette année: décisions d'UE, de RCUE, d'année,
|
pour cette année: décisions d'UE, de RCUE, d'année,
|
||||||
et autorisations d'inscription émises.
|
et autorisations d'inscription émises.
|
||||||
Efface même si étudiant DEM ou DEF.
|
Efface même si étudiant DEM ou DEF.
|
||||||
|
Si à cheval, n'efface que pour le semestre d'origine du deca.
|
||||||
"""
|
"""
|
||||||
if only_one_sem:
|
if only_one_sem or self.a_cheval:
|
||||||
# N'efface que les autorisations venant de ce semestre,
|
# N'efface que les autorisations venant de ce semestre,
|
||||||
# et les validations de ses UEs
|
# et les validations de ses UEs
|
||||||
ScolarAutorisationInscription.delete_autorisation_etud(
|
ScolarAutorisationInscription.delete_autorisation_etud(
|
||||||
@ -779,13 +826,23 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
)
|
)
|
||||||
for validation in validations:
|
for validation in validations:
|
||||||
|
db.session.delete(validation)
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
"jury_but",
|
"jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation année BUT{self.annee_but}: effacée",
|
msg=f"Validation année BUT{self.annee_but}: effacée",
|
||||||
)
|
)
|
||||||
db.session.delete(validation)
|
|
||||||
db.session.flush()
|
# Efface éventuelles validations de semestre
|
||||||
|
# (en principe inutilisées en BUT)
|
||||||
|
# et autres UEs (en cas de changement d'architecture de formation depuis le jury ?)
|
||||||
|
#
|
||||||
|
for validation in ScolarFormSemestreValidation.query.filter_by(
|
||||||
|
etudid=self.etud.id, formsemestre_id=self.formsemestre_id
|
||||||
|
):
|
||||||
|
db.session.delete(validation)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
self.invalidate_formsemestre_cache()
|
self.invalidate_formsemestre_cache()
|
||||||
|
|
||||||
def get_autorisations_passage(self) -> list[int]:
|
def get_autorisations_passage(self) -> list[int]:
|
||||||
@ -828,6 +885,27 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
validations.append(", ".join(v for v in valids if v))
|
validations.append(", ".join(v for v in valids if v))
|
||||||
return line_sep.join(validations)
|
return line_sep.join(validations)
|
||||||
|
|
||||||
|
def descr_pb_coherence(self) -> list[str]:
|
||||||
|
"""Description d'éventuels problèmes de cohérence entre
|
||||||
|
les décisions *enregistrées* d'UE et de RCUE.
|
||||||
|
Note: en principe, la cohérence RCUE/UE est assurée au moment de
|
||||||
|
l'enregistrement (record).
|
||||||
|
Mais la base peut avoir été modifiée par d'autres voies.
|
||||||
|
"""
|
||||||
|
messages = []
|
||||||
|
for dec_rcue in self.decisions_rcue_by_niveau.values():
|
||||||
|
if dec_rcue.code_valide in CODES_RCUE_VALIDES:
|
||||||
|
for ue in (dec_rcue.rcue.ue_1, dec_rcue.rcue.ue_2):
|
||||||
|
dec_ue = self.decisions_ues.get(ue.id)
|
||||||
|
if dec_ue:
|
||||||
|
if dec_ue.code_valide not in CODES_UE_VALIDES:
|
||||||
|
messages.append(
|
||||||
|
f"L'UE {ue.acronyme} n'est pas validée mais son RCUE l'est !"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.append(f"L'UE {ue.acronyme} n'a pas décision (???)")
|
||||||
|
return messages
|
||||||
|
|
||||||
|
|
||||||
def list_ue_parcour_etud(
|
def list_ue_parcour_etud(
|
||||||
formsemestre: FormSemestre, etud: Identite, res: ResultatsSemestreBUT
|
formsemestre: FormSemestre, etud: Identite, res: ResultatsSemestreBUT
|
||||||
@ -873,6 +951,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
inscription_etat: str = scu.INSCRIT,
|
inscription_etat: str = scu.INSCRIT,
|
||||||
):
|
):
|
||||||
super().__init__(etud=dec_prop_annee.etud)
|
super().__init__(etud=dec_prop_annee.etud)
|
||||||
|
self.deca = dec_prop_annee
|
||||||
self.rcue = rcue
|
self.rcue = rcue
|
||||||
if rcue is None: # RCUE non dispo, eg un seul semestre
|
if rcue is None: # RCUE non dispo, eg un seul semestre
|
||||||
self.codes = []
|
self.codes = []
|
||||||
@ -904,9 +983,30 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
or dec_prop_annee.formsemestre_pair.modalite == "EXT"
|
or dec_prop_annee.formsemestre_pair.modalite == "EXT"
|
||||||
):
|
):
|
||||||
self.codes.insert(0, sco_codes.ADM)
|
self.codes.insert(0, sco_codes.ADM)
|
||||||
|
# S'il y a une décision enregistrée: si elle est plus favorable que celle que l'on
|
||||||
|
# proposerait, la place en tête.
|
||||||
|
# Sinon, la place en seconde place
|
||||||
|
if self.code_valide and self.code_valide != self.codes[0]:
|
||||||
|
code_default = self.codes[0]
|
||||||
|
if self.code_valide in self.codes:
|
||||||
|
self.codes.remove(self.code_valide)
|
||||||
|
if sco_codes.BUT_CODES_ORDERED.get(
|
||||||
|
self.code_valide, 0
|
||||||
|
) > sco_codes.BUT_CODES_ORDERED.get(code_default, 0):
|
||||||
|
self.codes.insert(0, self.code_valide)
|
||||||
|
else:
|
||||||
|
self.codes.insert(1, self.code_valide)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"""<{self.__class__.__name__} rcue={self.rcue} valid={self.code_valide
|
||||||
|
} codes={self.codes} explanation={self.explanation}"""
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False):
|
def record(self, code: str, no_overwrite=False):
|
||||||
"""Enregistre le code"""
|
"""Enregistre le code RCUE.
|
||||||
|
Note:
|
||||||
|
- si le RCUE est ADJ, les UE non validées sont passées à ADJ
|
||||||
|
XXX on pourra imposer ici d'autres règles de cohérence
|
||||||
|
"""
|
||||||
if self.rcue is None:
|
if self.rcue is None:
|
||||||
return # pas de RCUE a enregistrer
|
return # pas de RCUE a enregistrer
|
||||||
if self.inscription_etat != scu.INSCRIT:
|
if self.inscription_etat != scu.INSCRIT:
|
||||||
@ -921,13 +1021,10 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
parcours_id = self.parcour.id if self.parcour is not None else None
|
parcours_id = self.parcour.id if self.parcour is not None else None
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
db.session.flush()
|
db.session.commit()
|
||||||
if code is None:
|
if code is None:
|
||||||
self.validation = None
|
self.validation = None
|
||||||
else:
|
else:
|
||||||
# log(
|
|
||||||
# f"RCUE.record(etudid={self.etud.id}, ue1_id={self.rcue.ue_1.id}, ue2_id={self.rcue.ue_2.id}, code={code} )"
|
|
||||||
# )
|
|
||||||
self.validation = ApcValidationRCUE(
|
self.validation = ApcValidationRCUE(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
formsemestre_id=self.rcue.formsemestre_2.id,
|
formsemestre_id=self.rcue.formsemestre_2.id,
|
||||||
@ -936,12 +1033,25 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
parcours_id=parcours_id,
|
parcours_id=parcours_id,
|
||||||
code=code,
|
code=code,
|
||||||
)
|
)
|
||||||
|
db.session.add(self.validation)
|
||||||
|
db.session.commit()
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
method="jury_but",
|
method="jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation {self.rcue}: {code}",
|
msg=f"Validation {self.rcue}: {code}",
|
||||||
|
commit=True,
|
||||||
)
|
)
|
||||||
db.session.add(self.validation)
|
log(f"rcue.record {self}: {code}")
|
||||||
|
|
||||||
|
# Modifie au besoin les codes d'UE
|
||||||
|
if code == "ADJ":
|
||||||
|
deca = self.deca
|
||||||
|
for ue_id in (self.rcue.ue_1.id, self.rcue.ue_2.id):
|
||||||
|
dec_ue = deca.decisions_ues.get(ue_id)
|
||||||
|
if dec_ue and dec_ue.code_valide not in CODES_UE_VALIDES:
|
||||||
|
log(f"rcue.record: force ADJ sur {dec_ue}")
|
||||||
|
dec_ue.record("ADJ")
|
||||||
|
|
||||||
if self.rcue.formsemestre_1 is not None:
|
if self.rcue.formsemestre_1 is not None:
|
||||||
sco_cache.invalidate_formsemestre(
|
sco_cache.invalidate_formsemestre(
|
||||||
formsemestre_id=self.rcue.formsemestre_1.id
|
formsemestre_id=self.rcue.formsemestre_1.id
|
||||||
@ -950,6 +1060,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
sco_cache.invalidate_formsemestre(
|
sco_cache.invalidate_formsemestre(
|
||||||
formsemestre_id=self.rcue.formsemestre_2.id
|
formsemestre_id=self.rcue.formsemestre_2.id
|
||||||
)
|
)
|
||||||
|
self.code_valide = code # mise à jour état
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
@ -957,6 +1068,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
# par prudence, on requete toutes les validations, en cas de doublons
|
# par prudence, on requete toutes les validations, en cas de doublons
|
||||||
validations = self.rcue.query_validations()
|
validations = self.rcue.query_validations()
|
||||||
for validation in validations:
|
for validation in validations:
|
||||||
|
log(f"DecisionsProposeesRCUE: deleting {validation}")
|
||||||
db.session.delete(validation)
|
db.session.delete(validation)
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
|
|
||||||
@ -1010,14 +1122,14 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
):
|
):
|
||||||
# Une UE peut être validée plusieurs fois en cas de redoublement (qu'elle soit capitalisée ou non)
|
# Une UE peut être validée plusieurs fois en cas de redoublement (qu'elle soit capitalisée ou non)
|
||||||
# mais ici on a restreint au formsemestre donc une seule (prend la première)
|
# mais ici on a restreint au formsemestre donc une seule (prend la première)
|
||||||
self.validation = ScolarFormSemestreValidation.query.filter_by(
|
validation = ScolarFormSemestreValidation.query.filter_by(
|
||||||
etudid=etud.id, formsemestre_id=formsemestre.id, ue_id=ue.id
|
etudid=etud.id, formsemestre_id=formsemestre.id, ue_id=ue.id
|
||||||
).first()
|
).first()
|
||||||
super().__init__(
|
super().__init__(
|
||||||
etud=etud,
|
etud=etud,
|
||||||
code_valide=self.validation.code if self.validation is not None else None,
|
code_valide=validation.code if validation is not None else None,
|
||||||
)
|
)
|
||||||
# log(f"built {self}")
|
self.validation = validation
|
||||||
self.formsemestre = formsemestre
|
self.formsemestre = formsemestre
|
||||||
self.ue: UniteEns = ue
|
self.ue: UniteEns = ue
|
||||||
self.rcue: RegroupementCoherentUE = None
|
self.rcue: RegroupementCoherentUE = None
|
||||||
@ -1056,11 +1168,11 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"""<{self.__class__.__name__} ue={self.ue.acronyme} valid={self.code_valide
|
return f"""<{self.__class__.__name__} ue={self.ue.acronyme} valid={self.code_valide
|
||||||
} codes={self.codes} explanation={self.explanation}"""
|
} codes={self.codes} explanation={self.explanation}>"""
|
||||||
|
|
||||||
def set_rcue(self, rcue: RegroupementCoherentUE):
|
def set_rcue(self, rcue: RegroupementCoherentUE):
|
||||||
"""Rattache cette UE à un RCUE. Cela peut modifier les codes
|
"""Rattache cette UE à un RCUE. Cela peut modifier les codes
|
||||||
proposés (si compensation)"""
|
proposés par compute_codes() (si compensation)"""
|
||||||
self.rcue = rcue
|
self.rcue = rcue
|
||||||
|
|
||||||
def compute_codes(self):
|
def compute_codes(self):
|
||||||
@ -1098,6 +1210,7 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
method="jury_but",
|
method="jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation UE {self.ue.id} {self.ue.acronyme}: effacée",
|
msg=f"Validation UE {self.ue.id} {self.ue.acronyme}: effacée",
|
||||||
|
commit=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.validation = ScolarFormSemestreValidation(
|
self.validation = ScolarFormSemestreValidation(
|
||||||
@ -1107,15 +1220,18 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
code=code,
|
code=code,
|
||||||
moy_ue=self.moy_ue,
|
moy_ue=self.moy_ue,
|
||||||
)
|
)
|
||||||
|
db.session.add(self.validation)
|
||||||
|
db.session.commit()
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
method="jury_but",
|
method="jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation UE {self.ue.id} {self.ue.acronyme}({self.moy_ue}): {code}",
|
msg=f"Validation UE {self.ue.id} {self.ue.acronyme}({self.moy_ue}): {code}",
|
||||||
|
commit=True,
|
||||||
)
|
)
|
||||||
db.session.add(self.validation)
|
|
||||||
log(f"DecisionsProposeesUE: recording {self.validation}")
|
log(f"DecisionsProposeesUE: recording {self.validation}")
|
||||||
|
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre.id)
|
||||||
|
self.code_valide = code # mise à jour
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
@ -1126,13 +1242,14 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
for validation in validations:
|
for validation in validations:
|
||||||
log(f"DecisionsProposeesUE: deleting {validation}")
|
log(f"DecisionsProposeesUE: deleting {validation}")
|
||||||
|
db.session.delete(validation)
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
method="jury_but",
|
method="jury_but",
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
msg=f"Validation UE {validation.ue.id} {validation.ue.acronyme}: effacée",
|
msg=f"Validation UE {validation.ue.id} {validation.ue.acronyme}: effacée",
|
||||||
)
|
)
|
||||||
db.session.delete(validation)
|
|
||||||
db.session.flush()
|
db.session.commit()
|
||||||
|
|
||||||
def descr_validation(self) -> str:
|
def descr_validation(self) -> str:
|
||||||
"""Description validation niveau enregistrée, pour PV jury.
|
"""Description validation niveau enregistrée, pour PV jury.
|
||||||
@ -1148,7 +1265,7 @@ class BUTCursusEtud: # WIP TODO
|
|||||||
|
|
||||||
def __init__(self, formsemestre: FormSemestre, etud: Identite):
|
def __init__(self, formsemestre: FormSemestre, etud: Identite):
|
||||||
if formsemestre.formation.referentiel_competence is None:
|
if formsemestre.formation.referentiel_competence is None:
|
||||||
raise ScoException("BUTCursusEtud: pas de référentiel de compétences")
|
raise ScoNoReferentielCompetences(formation=formsemestre.formation)
|
||||||
assert len(etud.formsemestre_inscriptions) > 0
|
assert len(etud.formsemestre_inscriptions) > 0
|
||||||
self.formsemestre = formsemestre
|
self.formsemestre = formsemestre
|
||||||
self.etud = etud
|
self.etud = etud
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ from app.scodoc.sco_codes_parcours import (
|
|||||||
from app.scodoc import sco_formsemestre_status
|
from app.scodoc import sco_formsemestre_status
|
||||||
from app.scodoc import sco_pvjury
|
from app.scodoc import sco_pvjury
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_saisie_jury_but(
|
def formsemestre_saisie_jury_but(
|
||||||
@ -63,14 +63,7 @@ def formsemestre_saisie_jury_but(
|
|||||||
# raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs")
|
# raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs")
|
||||||
|
|
||||||
if formsemestre2.formation.referentiel_competence is None:
|
if formsemestre2.formation.referentiel_competence is None:
|
||||||
raise ScoValueError(
|
raise ScoNoReferentielCompetences(formation=formsemestre2.formation)
|
||||||
"""
|
|
||||||
<p>Pas de référentiel de compétences associé à la formation !</p>
|
|
||||||
<p>Pour associer un référentiel, passer par le menu <b>Semestre /
|
|
||||||
Voir la formation... </b> et suivre le lien <em>"associer à un référentiel
|
|
||||||
de compétences"</em>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
rows, titles, column_ids, jury_stats = get_jury_but_table(
|
rows, titles, column_ids, jury_stats = get_jury_but_table(
|
||||||
formsemestre2, read_only=read_only, mode=mode
|
formsemestre2, read_only=read_only, mode=mode
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -15,12 +15,19 @@ from app.scodoc import sco_cache
|
|||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_validation_auto_but(formsemestre: FormSemestre, only_adm=True) -> int:
|
def formsemestre_validation_auto_but(
|
||||||
|
formsemestre: FormSemestre, only_adm: bool = True, no_overwrite: bool = True
|
||||||
|
) -> int:
|
||||||
"""Calcul automatique des décisions de jury sur une année BUT.
|
"""Calcul automatique des décisions de jury sur une année BUT.
|
||||||
|
Ne modifie jamais de décisions de l'année scolaire précédente, même
|
||||||
|
si on a des RCUE "à cheval".
|
||||||
Normalement, only_adm est True et on n'enregistre que les décisions ADM (de droit).
|
Normalement, only_adm est True et on n'enregistre que les décisions ADM (de droit).
|
||||||
Si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
Si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
||||||
(mode à n'utiliser que pour les tests)
|
(mode à n'utiliser que pour les tests)
|
||||||
|
|
||||||
|
Si no_overwrite est vrai (défaut), ne ré-écrit jamais les codes déjà enregistrés
|
||||||
|
(utiliser faux pour certains tests)
|
||||||
|
|
||||||
Returns: nombre d'étudiants "admis"
|
Returns: nombre d'étudiants "admis"
|
||||||
"""
|
"""
|
||||||
if not formsemestre.formation.is_apc():
|
if not formsemestre.formation.is_apc():
|
||||||
@ -33,7 +40,7 @@ def formsemestre_validation_auto_but(formsemestre: FormSemestre, only_adm=True)
|
|||||||
if deca.admis: # année réussie
|
if deca.admis: # année réussie
|
||||||
nb_admis += 1
|
nb_admis += 1
|
||||||
if deca.admis or not only_adm:
|
if deca.admis or not only_adm:
|
||||||
deca.record_all()
|
deca.record_all(no_overwrite=no_overwrite)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return nb_admis
|
return nb_admis
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ from app.models import (
|
|||||||
Identite,
|
Identite,
|
||||||
UniteEns,
|
UniteEns,
|
||||||
ScolarAutorisationInscription,
|
ScolarAutorisationInscription,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
)
|
)
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
@ -41,32 +42,21 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
Si pas read_only, menus sélection codes jury.
|
Si pas read_only, menus sélection codes jury.
|
||||||
"""
|
"""
|
||||||
H = []
|
H = []
|
||||||
if deca.code_valide and not read_only:
|
|
||||||
erase_span = f"""<a href="{
|
|
||||||
url_for("notes.formsemestre_jury_but_erase",
|
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=deca.formsemestre_id,
|
|
||||||
etudid=deca.etud.id)}" class="stdlink">effacer décisions</a>"""
|
|
||||||
else:
|
|
||||||
erase_span = ""
|
|
||||||
|
|
||||||
H.append("""<div class="but_section_annee">""")
|
H.append("""<div class="but_section_annee">""")
|
||||||
if deca.jury_annuel:
|
H.append(
|
||||||
H.append(
|
f"""
|
||||||
f"""
|
<div>
|
||||||
<div>
|
<b>Décision de jury pour l'année :</b> {
|
||||||
<b>Décision de jury pour l'année :</b> {
|
_gen_but_select("code_annee", deca.codes, deca.code_valide,
|
||||||
_gen_but_select("code_annee", deca.codes, deca.code_valide,
|
disabled=True, klass="manual")
|
||||||
disabled=True, klass="manual")
|
}
|
||||||
}
|
<span>({deca.code_valide or 'non'} enregistrée)</span>
|
||||||
<span>({'non ' if deca.code_valide is None else ''}enregistrée)</span>
|
</div>
|
||||||
<span>{erase_span}</span>
|
|
||||||
</div>
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
|
div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
|
||||||
else:
|
|
||||||
H.append("""<div><em>Pas de décision annuelle (sem. impair).</em></div>""")
|
|
||||||
div_explanation = ""
|
|
||||||
H.append("""</div>""")
|
H.append("""</div>""")
|
||||||
|
|
||||||
formsemestre_1 = deca.formsemestre_impair
|
formsemestre_1 = deca.formsemestre_impair
|
||||||
@ -119,8 +109,8 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
if ue.niveau_competence and ue.niveau_competence.id == niveau.id
|
if ue.niveau_competence and ue.niveau_competence.id == niveau.id
|
||||||
]
|
]
|
||||||
ue_pair = ues[0] if ues else None
|
ue_pair = ues[0] if ues else None
|
||||||
# Les UEs à afficher, toujours en readonly
|
# Les UEs à afficher,
|
||||||
# sur le formsemestre de l'année précédente du redoublant
|
# qui seront toujours en readonly sur le formsemestre de l'année précédente du redoublant
|
||||||
ues_ro = [
|
ues_ro = [
|
||||||
(
|
(
|
||||||
ue_impair,
|
ue_impair,
|
||||||
@ -143,6 +133,7 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
deca.decisions_ues[ue.id],
|
deca.decisions_ues[ue.id],
|
||||||
disabled=read_only or ue_read_only,
|
disabled=read_only or ue_read_only,
|
||||||
annee_prec=ue_read_only,
|
annee_prec=ue_read_only,
|
||||||
|
niveau_id=ue.niveau_competence.id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -161,6 +152,7 @@ def _gen_but_select(
|
|||||||
code_valide: str,
|
code_valide: str,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
klass: str = "",
|
klass: str = "",
|
||||||
|
data: dict = {},
|
||||||
) -> str:
|
) -> str:
|
||||||
"Le menu html select avec les codes"
|
"Le menu html select avec les codes"
|
||||||
# if disabled: # mauvaise idée car le disabled est traité en JS
|
# if disabled: # mauvaise idée car le disabled est traité en JS
|
||||||
@ -176,8 +168,11 @@ def _gen_but_select(
|
|||||||
)
|
)
|
||||||
return f"""<select required name="{name}"
|
return f"""<select required name="{name}"
|
||||||
class="but_code {klass}"
|
class="but_code {klass}"
|
||||||
|
data-orig_code="{code_valide or (codes[0] if codes else '')}"
|
||||||
|
data-orig_recorded="{code_valide or ''}"
|
||||||
onchange="change_menu_code(this);"
|
onchange="change_menu_code(this);"
|
||||||
{"disabled" if disabled else ""}
|
{"disabled" if disabled else ""}
|
||||||
|
{" ".join( f'data-{k}="{v}"' for (k,v) in data.items() )}
|
||||||
>{options_htm}</select>
|
>{options_htm}</select>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -187,6 +182,7 @@ def _gen_but_niveau_ue(
|
|||||||
dec_ue: DecisionsProposeesUE,
|
dec_ue: DecisionsProposeesUE,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
annee_prec: bool = False,
|
annee_prec: bool = False,
|
||||||
|
niveau_id: int = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
if dec_ue.ue_status and dec_ue.ue_status["is_capitalized"]:
|
if dec_ue.ue_status and dec_ue.ue_status["is_capitalized"]:
|
||||||
moy_ue_str = f"""<span class="ue_cap">{
|
moy_ue_str = f"""<span class="ue_cap">{
|
||||||
@ -207,7 +203,14 @@ def _gen_but_niveau_ue(
|
|||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
moy_ue_str = f"""<span>{scu.fmt_note(dec_ue.moy_ue)}</span>"""
|
moy_ue_str = f"""<span>{scu.fmt_note(dec_ue.moy_ue)}</span>"""
|
||||||
scoplement = ""
|
if dec_ue.code_valide:
|
||||||
|
scoplement = f"""<div class="scoplement">
|
||||||
|
Code {dec_ue.code_valide} enregistré le {dec_ue.validation.event_date.strftime("%d/%m/%Y")}
|
||||||
|
à {dec_ue.validation.event_date.strftime("%Hh%M")}
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
scoplement = ""
|
||||||
|
|
||||||
return f"""<div class="but_niveau_ue {
|
return f"""<div class="but_niveau_ue {
|
||||||
'recorded' if dec_ue.code_valide is not None else ''}
|
'recorded' if dec_ue.code_valide is not None else ''}
|
||||||
@ -221,7 +224,9 @@ def _gen_but_niveau_ue(
|
|||||||
<div class="but_code">{
|
<div class="but_code">{
|
||||||
_gen_but_select("code_ue_"+str(ue.id),
|
_gen_but_select("code_ue_"+str(ue.id),
|
||||||
dec_ue.codes,
|
dec_ue.codes,
|
||||||
dec_ue.code_valide, disabled=disabled
|
dec_ue.code_valide,
|
||||||
|
disabled=disabled,
|
||||||
|
klass=f"code_ue ue_rcue_{niveau_id}" if not disabled else ""
|
||||||
)
|
)
|
||||||
}</div>
|
}</div>
|
||||||
|
|
||||||
@ -245,21 +250,29 @@ def _gen_but_rcue(dec_rcue: DecisionsProposeesRCUE, niveau: ApcNiveau) -> str:
|
|||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Déjà enregistré ?
|
||||||
|
niveau_rcue_class = ""
|
||||||
|
if dec_rcue.code_valide is not None and dec_rcue.codes:
|
||||||
|
if dec_rcue.code_valide == dec_rcue.codes[0]:
|
||||||
|
niveau_rcue_class = "recorded"
|
||||||
|
else:
|
||||||
|
niveau_rcue_class = "recorded_different"
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
<div class="but_niveau_rcue
|
<div class="but_niveau_rcue {niveau_rcue_class}
|
||||||
{'recorded' if dec_rcue.code_valide is not None else ''}
|
|
||||||
">
|
">
|
||||||
<div class="but_note with_scoplement">
|
<div class="but_note with_scoplement">
|
||||||
<div>{scu.fmt_note(dec_rcue.rcue.moy_rcue)}</div>
|
<div>{scu.fmt_note(dec_rcue.rcue.moy_rcue)}</div>
|
||||||
{scoplement}
|
{scoplement}
|
||||||
</div>
|
</div>
|
||||||
<div class="but_code">
|
<div class="but_code">
|
||||||
<div>{_gen_but_select("code_rcue_"+str(niveau.id),
|
{_gen_but_select("code_rcue_"+str(niveau.id),
|
||||||
dec_rcue.codes,
|
dec_rcue.codes,
|
||||||
dec_rcue.code_valide,
|
dec_rcue.code_valide,
|
||||||
disabled=True, klass="manual"
|
disabled=True,
|
||||||
|
klass="manual code_rcue",
|
||||||
|
data = { "niveau_id" : str(niveau.id)}
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@ -278,17 +291,15 @@ def jury_but_semestriel(
|
|||||||
semestre_terminal = (
|
semestre_terminal = (
|
||||||
formsemestre.semestre_id >= formsemestre.formation.get_parcours().NB_SEM
|
formsemestre.semestre_id >= formsemestre.formation.get_parcours().NB_SEM
|
||||||
)
|
)
|
||||||
|
autorisations_passage = ScolarAutorisationInscription.query.filter_by(
|
||||||
|
etudid=etud.id,
|
||||||
|
origin_formsemestre_id=formsemestre.id,
|
||||||
|
).all()
|
||||||
# Par défaut: autorisé à passer dans le semestre suivant si sem. impair,
|
# Par défaut: autorisé à passer dans le semestre suivant si sem. impair,
|
||||||
# ou si décision déjà enregistrée:
|
# ou si décision déjà enregistrée:
|
||||||
est_autorise_a_passer = (formsemestre.semestre_id % 2) or (
|
est_autorise_a_passer = (formsemestre.semestre_id % 2) or (
|
||||||
formsemestre.semestre_id + 1
|
formsemestre.semestre_id + 1
|
||||||
) in (
|
) in (a.semestre_id for a in autorisations_passage)
|
||||||
a.semestre_id
|
|
||||||
for a in ScolarAutorisationInscription.query.filter_by(
|
|
||||||
etudid=etud.id,
|
|
||||||
origin_formsemestre_id=formsemestre.id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
decisions_ues = {
|
decisions_ues = {
|
||||||
ue.id: DecisionsProposeesUE(etud, formsemestre, ue, inscription_etat)
|
ue.id: DecisionsProposeesUE(etud, formsemestre, ue, inscription_etat)
|
||||||
for ue in ues
|
for ue in ues
|
||||||
@ -312,7 +323,9 @@ def jury_but_semestriel(
|
|||||||
flash("codes enregistrés")
|
flash("codes enregistrés")
|
||||||
if not semestre_terminal:
|
if not semestre_terminal:
|
||||||
if request.form.get("autorisation_passage"):
|
if request.form.get("autorisation_passage"):
|
||||||
if not est_autorise_a_passer:
|
if not formsemestre.semestre_id + 1 in (
|
||||||
|
a.semestre_id for a in autorisations_passage
|
||||||
|
):
|
||||||
ScolarAutorisationInscription.autorise_etud(
|
ScolarAutorisationInscription.autorise_etud(
|
||||||
etud.id,
|
etud.id,
|
||||||
formsemestre.formation.formation_code,
|
formsemestre.formation.formation_code,
|
||||||
@ -351,7 +364,7 @@ def jury_but_semestriel(
|
|||||||
warning = ""
|
warning = ""
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
html_sco_header.sco_header(
|
||||||
page_title="Validation BUT",
|
page_title=f"Validation BUT S{formsemestre.semestre_id}",
|
||||||
formsemestre_id=formsemestre.id,
|
formsemestre_id=formsemestre.id,
|
||||||
etudid=etud.id,
|
etudid=etud.id,
|
||||||
cssstyles=("css/jury_but.css",),
|
cssstyles=("css/jury_but.css",),
|
||||||
@ -372,25 +385,35 @@ def jury_but_semestriel(
|
|||||||
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
|
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>Jury sur un semestre BUT isolé</h3>
|
<h3>Jury sur un semestre BUT isolé (ne concerne que les UEs)</h3>
|
||||||
{warning}
|
{warning}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="post" id="jury_but">
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
if (not read_only) and any([dec.code_valide for dec in decisions_ues.values()]):
|
|
||||||
erase_span = f"""<a href="{
|
erase_span = ""
|
||||||
url_for("notes.formsemestre_jury_but_erase",
|
if not read_only:
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id,
|
# Requête toutes les validations (pas seulement celles du deca courant),
|
||||||
etudid=etud.id, only_one_sem=1)}" class="stdlink">effacer les décisions enregistrées</a>"""
|
# au cas où: changement d'architecture, saisie en mode classique, ...
|
||||||
else:
|
validations = ScolarFormSemestreValidation.query.filter_by(
|
||||||
erase_span = "Cet étudiant n'a aucune décision enregistrée pour ce semestre."
|
etudid=etud.id, formsemestre_id=formsemestre.id
|
||||||
|
).all()
|
||||||
|
if validations:
|
||||||
|
erase_span = f"""<a href="{
|
||||||
|
url_for("notes.formsemestre_jury_but_erase",
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id,
|
||||||
|
etudid=etud.id, only_one_sem=1)
|
||||||
|
}" class="stdlink">effacer les décisions enregistrées</a>"""
|
||||||
|
else:
|
||||||
|
erase_span = (
|
||||||
|
"Cet étudiant n'a aucune décision enregistrée pour ce semestre."
|
||||||
|
)
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
<div class="but_section_annee">
|
<div class="but_section_annee">
|
||||||
<span>{erase_span}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div><b>Unités d'enseignement de S{formsemestre.semestre_id}:</b></div>
|
<div><b>Unités d'enseignement de S{formsemestre.semestre_id}:</b></div>
|
||||||
"""
|
"""
|
||||||
@ -440,6 +463,9 @@ def jury_but_semestriel(
|
|||||||
<input type="checkbox" name="autorisation_passage" value="1" {
|
<input type="checkbox" name="autorisation_passage" value="1" {
|
||||||
"checked" if est_autorise_a_passer else ""}>
|
"checked" if est_autorise_a_passer else ""}>
|
||||||
<em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em>
|
<em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em>
|
||||||
|
{("(autorisations enregistrées: " + ' '.join(
|
||||||
|
'S' + str(a.semestre_id or '') for a in autorisations_passage) + ")"
|
||||||
|
) if autorisations_passage else ""}
|
||||||
</input>
|
</input>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@ -447,9 +473,10 @@ def jury_but_semestriel(
|
|||||||
else:
|
else:
|
||||||
H.append("""<div class="help">dernier semestre de la formation.</div>""")
|
H.append("""<div class="help">dernier semestre de la formation.</div>""")
|
||||||
H.append(
|
H.append(
|
||||||
"""
|
f"""
|
||||||
<div class="but_buttons">
|
<div class="but_buttons">
|
||||||
<input type="submit" value="Enregistrer ces décisions">
|
<span><input type="submit" value="Enregistrer ces décisions"></span>
|
||||||
|
<span>{erase_span}</span>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*
|
# -*- coding: UTF-8 -*
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
"""ScoDoc 9 models : Référentiel Compétence BUT 2021
|
"""ScoDoc 9 models : Référentiel Compétence BUT 2021
|
||||||
@ -14,7 +14,7 @@ import sqlalchemy
|
|||||||
from app import db
|
from app import db
|
||||||
|
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
|
||||||
|
|
||||||
|
|
||||||
# from https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns
|
# from https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns
|
||||||
@ -54,13 +54,15 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
|||||||
"Référentiel de compétence d'une spécialité"
|
"Référentiel de compétence d'une spécialité"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||||
annexe = db.Column(db.Text())
|
annexe = db.Column(db.Text()) # '1', '22', ...
|
||||||
specialite = db.Column(db.Text())
|
specialite = db.Column(db.Text()) # 'CJ', 'RT', 'INFO', ...
|
||||||
specialite_long = db.Column(db.Text())
|
specialite_long = db.Column(
|
||||||
type_titre = db.Column(db.Text())
|
db.Text()
|
||||||
type_structure = db.Column(db.Text())
|
) # 'Carrière Juridique', 'Réseaux et télécommunications', ...
|
||||||
|
type_titre = db.Column(db.Text()) # 'B.U.T.'
|
||||||
|
type_structure = db.Column(db.Text()) # 'type1', 'type2', ...
|
||||||
type_departement = db.Column(db.Text()) # "secondaire", "tertiaire"
|
type_departement = db.Column(db.Text()) # "secondaire", "tertiaire"
|
||||||
version_orebut = db.Column(db.Text())
|
version_orebut = db.Column(db.Text()) # '2021-12-11 00:00:00'
|
||||||
_xml_attribs = { # Orébut xml attrib : attribute
|
_xml_attribs = { # Orébut xml attrib : attribute
|
||||||
"type": "type_titre",
|
"type": "type_titre",
|
||||||
"version": "version_orebut",
|
"version": "version_orebut",
|
||||||
@ -322,9 +324,8 @@ class ApcNiveau(db.Model, XMLModel):
|
|||||||
if annee not in {1, 2, 3}:
|
if annee not in {1, 2, 3}:
|
||||||
raise ValueError("annee invalide pour un parcours BUT")
|
raise ValueError("annee invalide pour un parcours BUT")
|
||||||
if referentiel_competence is None:
|
if referentiel_competence is None:
|
||||||
raise ScoValueError(
|
raise ScoNoReferentielCompetences()
|
||||||
"Pas de référentiel de compétences associé à la formation !"
|
|
||||||
)
|
|
||||||
annee_formation = f"BUT{annee}"
|
annee_formation = f"BUT{annee}"
|
||||||
if parcour is None:
|
if parcour is None:
|
||||||
return ApcNiveau.query.filter(
|
return ApcNiveau.query.filter(
|
||||||
|
@ -68,7 +68,8 @@ class ApcValidationRCUE(db.Model):
|
|||||||
"description en HTML"
|
"description en HTML"
|
||||||
return f"""Décision sur RCUE {self.ue1.acronyme}/{self.ue2.acronyme}:
|
return f"""Décision sur RCUE {self.ue1.acronyme}/{self.ue2.acronyme}:
|
||||||
<b>{self.code}</b>
|
<b>{self.code}</b>
|
||||||
<em>enregistrée le {self.date.strftime("%d/%m/%Y")}</em>"""
|
<em>enregistrée le {self.date.strftime("%d/%m/%Y")}
|
||||||
|
à {self.date.strftime("%Hh%M")}</em>"""
|
||||||
|
|
||||||
def niveau(self) -> ApcNiveau:
|
def niveau(self) -> ApcNiveau:
|
||||||
"""Le niveau de compétence associé à cet RCUE."""
|
"""Le niveau de compétence associé à cet RCUE."""
|
||||||
@ -180,8 +181,9 @@ class RegroupementCoherentUE:
|
|||||||
return self.query_validations().count() > 0
|
return self.query_validations().count() > 0
|
||||||
|
|
||||||
def est_compensable(self):
|
def est_compensable(self):
|
||||||
"""Vrai si ce RCUE est validable par compensation
|
"""Vrai si ce RCUE est validable (uniquement) par compensation
|
||||||
c'est à dire que sa moyenne est > 10 avec une UE < 10
|
c'est à dire que sa moyenne est > 10 avec une UE < 10.
|
||||||
|
Note: si ADM, est_compensable est faux.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
(self.moy_rcue is not None)
|
(self.moy_rcue is not None)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*
|
# -*- coding: UTF-8 -*
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -56,9 +56,9 @@ class FormSemestre(db.Model):
|
|||||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||||
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
||||||
semestre_id = db.Column(db.Integer, nullable=False, default=1, server_default="1")
|
semestre_id = db.Column(db.Integer, nullable=False, default=1, server_default="1")
|
||||||
titre = db.Column(db.Text())
|
titre = db.Column(db.Text(), nullable=False)
|
||||||
date_debut = db.Column(db.Date())
|
date_debut = db.Column(db.Date(), nullable=False)
|
||||||
date_fin = db.Column(db.Date())
|
date_fin = db.Column(db.Date(), nullable=False)
|
||||||
etat = db.Column(
|
etat = db.Column(
|
||||||
db.Boolean(), nullable=False, default=True, server_default="true"
|
db.Boolean(), nullable=False, default=True, server_default="true"
|
||||||
) # False si verrouillé
|
) # False si verrouillé
|
||||||
@ -87,7 +87,10 @@ class FormSemestre(db.Model):
|
|||||||
)
|
)
|
||||||
# couleur fond bulletins HTML:
|
# couleur fond bulletins HTML:
|
||||||
bul_bgcolor = db.Column(
|
bul_bgcolor = db.Column(
|
||||||
db.String(SHORT_STR_LEN), default="white", server_default="white"
|
db.String(SHORT_STR_LEN),
|
||||||
|
default="white",
|
||||||
|
server_default="white",
|
||||||
|
nullable=False,
|
||||||
)
|
)
|
||||||
# autorise resp. a modifier semestre:
|
# autorise resp. a modifier semestre:
|
||||||
resp_can_edit = db.Column(
|
resp_can_edit = db.Column(
|
||||||
@ -114,6 +117,7 @@ class FormSemestre(db.Model):
|
|||||||
"ModuleImpl",
|
"ModuleImpl",
|
||||||
backref="formsemestre",
|
backref="formsemestre",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
)
|
)
|
||||||
etuds = db.relationship(
|
etuds = db.relationship(
|
||||||
"Identite",
|
"Identite",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*
|
# -*- coding: UTF-8 -*
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -20,14 +20,12 @@ class ModuleImpl(db.Model):
|
|||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
moduleimpl_id = db.synonym("id")
|
moduleimpl_id = db.synonym("id")
|
||||||
module_id = db.Column(
|
module_id = db.Column(db.Integer, db.ForeignKey("notes_modules.id"), nullable=False)
|
||||||
db.Integer,
|
|
||||||
db.ForeignKey("notes_modules.id"),
|
|
||||||
)
|
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("notes_formsemestre.id"),
|
db.ForeignKey("notes_formsemestre.id"),
|
||||||
index=True,
|
index=True,
|
||||||
|
nullable=False,
|
||||||
)
|
)
|
||||||
responsable_id = db.Column("responsable_id", db.Integer, db.ForeignKey("user.id"))
|
responsable_id = db.Column("responsable_id", db.Integer, db.ForeignKey("user.id"))
|
||||||
# formule de calcul moyenne:
|
# formule de calcul moyenne:
|
||||||
|
@ -37,7 +37,9 @@ class Module(db.Model):
|
|||||||
# Type: ModuleType.STANDARD, MALUS, RESSOURCE, SAE (enum)
|
# Type: ModuleType.STANDARD, MALUS, RESSOURCE, SAE (enum)
|
||||||
module_type = db.Column(db.Integer, nullable=False, default=0, server_default="0")
|
module_type = db.Column(db.Integer, nullable=False, default=0, server_default="0")
|
||||||
# Relations:
|
# Relations:
|
||||||
modimpls = db.relationship("ModuleImpl", backref="module", lazy="dynamic")
|
modimpls = db.relationship(
|
||||||
|
"ModuleImpl", backref="module", lazy="dynamic", cascade="all, delete-orphan"
|
||||||
|
)
|
||||||
ues_apc = db.relationship("UniteEns", secondary="module_ue_coef", viewonly=True)
|
ues_apc = db.relationship("UniteEns", secondary="module_ue_coef", viewonly=True)
|
||||||
tags = db.relationship(
|
tags = db.relationship(
|
||||||
"NotesTag",
|
"NotesTag",
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
|
from app import log
|
||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
from app.models import CODE_STR_LEN
|
from app.models import CODE_STR_LEN
|
||||||
from app.models.events import Scolog
|
from app.models.events import Scolog
|
||||||
@ -93,6 +94,10 @@ class ScolarAutorisationInscription(db.Model):
|
|||||||
db.ForeignKey("notes_formsemestre.id"),
|
db.ForeignKey("notes_formsemestre.id"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"""{self.__class__.__name__}(id={self.id}, etudid={
|
||||||
|
self.etudid}, semestre_id={self.semestre_id})"""
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"as a dict"
|
"as a dict"
|
||||||
d = dict(self.__dict__)
|
d = dict(self.__dict__)
|
||||||
@ -119,6 +124,7 @@ class ScolarAutorisationInscription(db.Model):
|
|||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
"autorise_etud", etudid=etudid, msg=f"Passage vers S{semestre_id}: autorisé"
|
"autorise_etud", etudid=etudid, msg=f"Passage vers S{semestre_id}: autorisé"
|
||||||
)
|
)
|
||||||
|
log(f"ScolarAutorisationInscription: recording {autorisation}")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_autorisation_etud(
|
def delete_autorisation_etud(
|
||||||
@ -132,6 +138,7 @@ class ScolarAutorisationInscription(db.Model):
|
|||||||
)
|
)
|
||||||
for autorisation in autorisations:
|
for autorisation in autorisations:
|
||||||
db.session.delete(autorisation)
|
db.session.delete(autorisation)
|
||||||
|
log(f"ScolarAutorisationInscription: deleting {autorisation}")
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
"autorise_etud",
|
"autorise_etud",
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -105,13 +105,13 @@ class BaseArchiver(object):
|
|||||||
try:
|
try:
|
||||||
scu.GSL.acquire()
|
scu.GSL.acquire()
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
log("creating directory %s" % path)
|
log(f"creating directory {path}")
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
finally:
|
finally:
|
||||||
scu.GSL.release()
|
scu.GSL.release()
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
|
|
||||||
def get_obj_dir(self, oid):
|
def get_obj_dir(self, oid: int):
|
||||||
"""
|
"""
|
||||||
:return: path to directory of archives for this object (eg formsemestre_id or etudid).
|
:return: path to directory of archives for this object (eg formsemestre_id or etudid).
|
||||||
If directory does not yet exist, create it.
|
If directory does not yet exist, create it.
|
||||||
@ -142,7 +142,7 @@ class BaseArchiver(object):
|
|||||||
dirs = glob.glob(base + "*")
|
dirs = glob.glob(base + "*")
|
||||||
return [os.path.split(x)[1] for x in dirs]
|
return [os.path.split(x)[1] for x in dirs]
|
||||||
|
|
||||||
def list_obj_archives(self, oid):
|
def list_obj_archives(self, oid: int):
|
||||||
"""Returns
|
"""Returns
|
||||||
:return: list of archive identifiers for this object (paths to non empty dirs)
|
:return: list of archive identifiers for this object (paths to non empty dirs)
|
||||||
"""
|
"""
|
||||||
@ -157,7 +157,7 @@ class BaseArchiver(object):
|
|||||||
dirs.sort()
|
dirs.sort()
|
||||||
return dirs
|
return dirs
|
||||||
|
|
||||||
def delete_archive(self, archive_id):
|
def delete_archive(self, archive_id: str):
|
||||||
"""Delete (forever) this archive"""
|
"""Delete (forever) this archive"""
|
||||||
self.initialize()
|
self.initialize()
|
||||||
try:
|
try:
|
||||||
@ -166,7 +166,7 @@ class BaseArchiver(object):
|
|||||||
finally:
|
finally:
|
||||||
scu.GSL.release()
|
scu.GSL.release()
|
||||||
|
|
||||||
def get_archive_date(self, archive_id):
|
def get_archive_date(self, archive_id: str):
|
||||||
"""Returns date (as a DateTime object) of an archive"""
|
"""Returns date (as a DateTime object) of an archive"""
|
||||||
return datetime.datetime(
|
return datetime.datetime(
|
||||||
*[int(x) for x in os.path.split(archive_id)[1].split("-")]
|
*[int(x) for x in os.path.split(archive_id)[1].split("-")]
|
||||||
@ -183,17 +183,17 @@ class BaseArchiver(object):
|
|||||||
files.sort()
|
files.sort()
|
||||||
return [f for f in files if f and f[0] != "_"]
|
return [f for f in files if f and f[0] != "_"]
|
||||||
|
|
||||||
def get_archive_name(self, archive_id):
|
def get_archive_name(self, archive_id: str):
|
||||||
"""name identifying archive, to be used in web URLs"""
|
"""name identifying archive, to be used in web URLs"""
|
||||||
return os.path.split(archive_id)[1]
|
return os.path.split(archive_id)[1]
|
||||||
|
|
||||||
def is_valid_archive_name(self, archive_name):
|
def is_valid_archive_name(self, archive_name: str):
|
||||||
"""check if name is valid."""
|
"""check if name is valid."""
|
||||||
return re.match(
|
return re.match(
|
||||||
"^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}$", archive_name
|
"^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}$", archive_name
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_id_from_name(self, oid, archive_name):
|
def get_id_from_name(self, oid, archive_name: str):
|
||||||
"""returns archive id (check that name is valid)"""
|
"""returns archive id (check that name is valid)"""
|
||||||
self.initialize()
|
self.initialize()
|
||||||
if not self.is_valid_archive_name(archive_name):
|
if not self.is_valid_archive_name(archive_name):
|
||||||
@ -206,7 +206,7 @@ class BaseArchiver(object):
|
|||||||
raise ScoValueError(f"Archive {archive_name} introuvable")
|
raise ScoValueError(f"Archive {archive_name} introuvable")
|
||||||
return archive_id
|
return archive_id
|
||||||
|
|
||||||
def get_archive_description(self, archive_id):
|
def get_archive_description(self, archive_id: str) -> str:
|
||||||
"""Return description of archive"""
|
"""Return description of archive"""
|
||||||
self.initialize()
|
self.initialize()
|
||||||
filename = os.path.join(archive_id, "_description.txt")
|
filename = os.path.join(archive_id, "_description.txt")
|
||||||
@ -247,7 +247,7 @@ class BaseArchiver(object):
|
|||||||
data = data.encode(scu.SCO_ENCODING)
|
data = data.encode(scu.SCO_ENCODING)
|
||||||
self.initialize()
|
self.initialize()
|
||||||
filename = scu.sanitize_filename(filename)
|
filename = scu.sanitize_filename(filename)
|
||||||
log("storing %s (%d bytes) in %s" % (filename, len(data), archive_id))
|
log(f"storing {filename} ({len(data)} bytes) in {archive_id}")
|
||||||
try:
|
try:
|
||||||
scu.GSL.acquire()
|
scu.GSL.acquire()
|
||||||
fname = os.path.join(archive_id, filename)
|
fname = os.path.join(archive_id, filename)
|
||||||
@ -261,16 +261,18 @@ class BaseArchiver(object):
|
|||||||
"""Retreive data"""
|
"""Retreive data"""
|
||||||
self.initialize()
|
self.initialize()
|
||||||
if not scu.is_valid_filename(filename):
|
if not scu.is_valid_filename(filename):
|
||||||
log('Archiver.get: invalid filename "%s"' % filename)
|
log(f"""Archiver.get: invalid filename '{filename}'""")
|
||||||
raise ScoValueError("archive introuvable (déjà supprimée ?)")
|
raise ScoValueError("archive introuvable (déjà supprimée ?)")
|
||||||
fname = os.path.join(archive_id, filename)
|
fname = os.path.join(archive_id, filename)
|
||||||
log("reading archive file %s" % fname)
|
log(f"reading archive file {fname}")
|
||||||
with open(fname, "rb") as f:
|
with open(fname, "rb") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_archived_file(self, oid, archive_name, filename):
|
def get_archived_file(self, oid, archive_name, filename):
|
||||||
"""Recupere donnees du fichier indiqué et envoie au client"""
|
"""Recupère les donnees du fichier indiqué et envoie au client.
|
||||||
|
Returns: Response
|
||||||
|
"""
|
||||||
archive_id = self.get_id_from_name(oid, archive_name)
|
archive_id = self.get_id_from_name(oid, archive_name)
|
||||||
data = self.get(archive_id, filename)
|
data = self.get(archive_id, filename)
|
||||||
mime = mimetypes.guess_type(filename)[0]
|
mime = mimetypes.guess_type(filename)[0]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -435,7 +435,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
plusminus = pluslink
|
plusminus = pluslink
|
||||||
try:
|
try:
|
||||||
ects_txt = str(int(ue["ects"]))
|
ects_txt = str(int(ue["ects"]))
|
||||||
except (ValueError, KeyError):
|
except (ValueError, KeyError, TypeError):
|
||||||
ects_txt = "-"
|
ects_txt = "-"
|
||||||
|
|
||||||
t = {
|
t = {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -205,6 +205,20 @@ BUT_CODES_PASSAGE = {
|
|||||||
PAS1NCI,
|
PAS1NCI,
|
||||||
ATJ,
|
ATJ,
|
||||||
}
|
}
|
||||||
|
# les codes, du plus "défavorable" à l'étudiant au plus favorable:
|
||||||
|
# (valeur par défaut 0)
|
||||||
|
BUT_CODES_ORDERED = {
|
||||||
|
"NAR": 0,
|
||||||
|
"DEF": 0,
|
||||||
|
"AJ": 10,
|
||||||
|
"ATJ": 20,
|
||||||
|
"CMP": 50,
|
||||||
|
"ADC": 50,
|
||||||
|
"PASD": 50,
|
||||||
|
"PAS1NCI": 60,
|
||||||
|
"ADJ": 100,
|
||||||
|
"ADM": 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def code_semestre_validant(code: str) -> bool:
|
def code_semestre_validant(code: str) -> bool:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# ScoDoc
|
# ScoDoc
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Gestion scolarite IUT
|
# Gestion scolarite IUT
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user