From 34aab0a46fa2ae8841ae9c16ac877820d999c4ae Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet {e.args[0]} {e.args[0]} {msg}
colonne {
- col_id} non déclarée ?"""
+ col_id} 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"""Erreur lecture du fichier Apogée {filename}
-
Colonnes declarees: {declared}
-
Colonnes presentes: {present}"""
+
Colonnes presentes: {present}""",
+ 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())
diff --git a/app/scodoc/sco_apogee_reader.py b/app/scodoc/sco_apogee_reader.py
index 44ab7fa65..32c7f8728 100644
--- a/app/scodoc/sco_apogee_reader.py
+++ b/app/scodoc/sco_apogee_reader.py
@@ -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 ? ({i}/{field}))",
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))
diff --git a/app/scodoc/sco_exceptions.py b/app/scodoc/sco_exceptions.py
index 2e61608c3..53b1711c2 100644
--- a/app/scodoc/sco_exceptions.py
+++ b/app/scodoc/sco_exceptions.py
@@ -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:
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.
""" - super().__init__(msg=msg, dest_url=dest_url) + super().__init__(msg=msg, dest_url=dest_url, safe=safe) class ScoInvalidIdType(ScoValueError):