Element de passage dans apogée. Close #937

This commit is contained in:
Emmanuel Viennet 2024-06-26 21:26:51 +02:00
parent c2a248633f
commit 34aab0a46f
3 changed files with 54 additions and 19 deletions

View File

@ -221,7 +221,8 @@ class ApoEtud(dict):
except KeyError as exc:
raise ScoFormatError(
f"""Fichier Apogee invalide : ligne mal formatée ? <br>colonne <tt>{
col_id}</tt> non déclarée ?"""
col_id}</tt> non déclarée ?""",
safe=True,
) from exc
else:
try:
@ -326,9 +327,14 @@ class ApoEtud(dict):
self.log.append("export étape désactivé")
return VOID_APO_RES
# Element passage
res_passage = self.search_elt_passage(code, res)
if res_passage:
return res_passage
# Elements UE
res_ue = self.search_elt_ue(code, res)
if res_ue != {}:
if res_ue:
return res_ue
# Elements Modules
@ -403,6 +409,25 @@ class ApoEtud(dict):
return VOID_APO_RES
return {} # no UE result found for this code
def search_elt_passage(self, code: str, res: NotesTableCompat) -> dict:
"""Cherche un résultat de type "passage" pour ce code Apogée.
dict vide si pas de résultat trouvé pour ce code.
L'élement est rempli si:
- code est dans les codes passage du formsemestre (sem)
- autorisation d'inscription enregistre de sem vers sem d'indice suivant
"""
if res.formsemestre.semestre_id < 1:
return {}
next_semestre_id = res.formsemestre.semestre_id + 1
if code in res.formsemestre.get_codes_apogee(category="passage"):
if next_semestre_id in res.get_autorisations_inscription().get(
self.etud.id, set()
):
return dict(
N="", B=20, J="", R=ScoDocSiteConfig.get_code_apo("ADM"), M=""
)
return {}
def comp_elt_semestre(self, nt: NotesTableCompat, decision: dict, etudid: int):
"""Calcul résultat apo semestre.
Toujours vide pour en BUT/APC.
@ -703,7 +728,8 @@ class ApoData:
filename = self.orig_filename or e.filename
raise ScoFormatError(
f"""<h3>Erreur lecture du fichier Apogée <tt>{filename}</tt></h3>
<p>{e.args[0]}</p>"""
<p>{e.args[0]}</p>""",
safe=True,
) from e
self.etape_apogee = self.get_etape_apogee() # 'V1RT'
self.vdi_apogee = self.get_vdi_apogee() # '111'
@ -795,7 +821,9 @@ class ApoData:
self.sems_periode = None
def get_etape_apogee(self) -> str:
"""Le code etape: 'V1RT', donné par le code de l'élément VET"""
"""Le code etape: 'V1RT', donné par le code de l'élément VET.
Le VET doit être parmi les colonnes de la section XX-APO_COLONNES-XX
"""
for elt in self.apo_csv.apo_elts.values():
if elt.type_objet == "VET":
return elt.code
@ -860,7 +888,8 @@ class ApoData:
log(f"Colonnes presentes: {present}")
raise ScoFormatError(
f"""Fichier Apogee invalide<br>Colonnes declarees: <tt>{declared}</tt>
<br>Colonnes presentes: <tt>{present}</tt>"""
<br>Colonnes presentes: <tt>{present}</tt>""",
safe=True,
) from exc
# l'ensemble de tous les codes des elements apo des semestres:
sem_elems = reduce(set.union, list(self.get_codes_by_sem().values()), set())

View File

@ -299,11 +299,14 @@ class ApoCSVReadWrite:
for i, field in enumerate(fields):
cols[self.col_ids[i]] = field
except IndexError as exc:
raise
raise ScoFormatError(
f"Fichier Apogee incorrect (colonnes excédentaires ? (<tt>{i}/{field}</tt>))",
filename=self.get_filename(),
safe=True,
) from exc
# Ajoute colonnes vides manquantes, pratique si on a édité le fichier Apo à la main...
for i in range(len(fields), len(self.col_ids)):
cols[self.col_ids[i]] = ""
etud_tuples.append(
ApoEtudTuple(
nip=fields[0], # id etudiant
@ -337,6 +340,8 @@ class ApoCSVReadWrite:
fields = line.split(APO_SEP)
if len(fields) == 2:
k, v = fields
elif len(fields) == 1:
k, v = fields[0], ""
else:
log(f"Error read CSV: \nline={line}\nfields={fields}")
log(dir(f))

View File

@ -61,12 +61,12 @@ class ScoValueError(ScoException):
class ScoPermissionDenied(ScoValueError):
"""Permission non accordée (appli web)"""
def __init__(self, msg=None, dest_url=None):
def __init__(self, msg=None, dest_url=None, safe=False):
if msg is None:
msg = f"""Opération non autorisée pour {
current_user.get_nomcomplet() if current_user else "?"
}. Pas la permission, ou objet verrouillé."""
super().__init__(msg, dest_url=dest_url)
super().__init__(msg, dest_url=dest_url, safe=safe)
class ScoBugCatcher(ScoException):
@ -84,8 +84,8 @@ class InvalidEtudId(NoteProcessError):
class ScoFormatError(ScoValueError):
"Erreur lecture d'un fichier fourni par l'utilisateur"
def __init__(self, msg, filename="", dest_url=None):
super().__init__(msg, dest_url=dest_url)
def __init__(self, msg, filename="", dest_url=None, safe=False):
super().__init__(msg, dest_url=dest_url, safe=safe)
self.filename = filename
@ -95,15 +95,15 @@ class ScoInvalidParamError(ScoValueError):
(id strings, ...)
"""
def __init__(self, msg=None, dest_url=None):
def __init__(self, msg=None, dest_url=None, safe=False):
msg = msg or "Adresse invalide. Vérifiez vos signets."
super().__init__(msg, dest_url=dest_url)
super().__init__(msg, dest_url=dest_url, safe=safe)
class ScoPDFFormatError(ScoValueError):
"erreur génération PDF (templates platypus, ...)"
def __init__(self, msg, dest_url=None):
def __init__(self, msg, dest_url=None, safe=False):
super().__init__(
f"""Erreur dans un format pdf:
<p>{msg}</p>
@ -112,6 +112,7 @@ class ScoPDFFormatError(ScoValueError):
</p>
""",
dest_url=dest_url,
safe=safe,
)
@ -130,33 +131,33 @@ class ScoConfigurationError(ScoValueError):
class ScoLockedFormError(ScoValueError):
"Modification d'une formation verrouillée"
def __init__(self, msg="", dest_url=None):
def __init__(self, msg="", dest_url=None, safe=False):
msg = (
"Cette formation est verrouillée (car il y a un semestre verrouillé qui s'y réfère). "
+ str(msg)
)
super().__init__(msg=msg, dest_url=dest_url)
super().__init__(msg=msg, dest_url=dest_url, safe=safe)
class ScoLockedSemError(ScoValueError):
"Modification d'un formsemestre verrouillé"
def __init__(self, msg="", dest_url=None):
def __init__(self, msg="", dest_url=None, safe=False):
msg = "Ce semestre est verrouillé ! " + str(msg)
super().__init__(msg=msg, dest_url=dest_url)
super().__init__(msg=msg, dest_url=dest_url, safe=safe)
class ScoNonEmptyFormationObject(ScoValueError):
"""On ne peut pas supprimer un module/matiere ou UE si des formsemestre s'y réfèrent"""
def __init__(self, type_objet="objet'", msg="", dest_url=None):
def __init__(self, type_objet="objet'", msg="", dest_url=None, safe=False):
msg = f"""<h3>{type_objet} "{msg}" utilisé(e) dans des semestres: suppression impossible.</h3>
<p class="help">Il faut d'abord supprimer le semestre (ou en retirer ce {type_objet}).
Mais il est peut-être préférable de laisser ce programme intact et d'en créer une
nouvelle version pour la modifier sans affecter les semestres déjà en place.
</p>
"""
super().__init__(msg=msg, dest_url=dest_url)
super().__init__(msg=msg, dest_url=dest_url, safe=safe)
class ScoInvalidIdType(ScoValueError):