From fb0a79d6760273421a4a4b75e345d52635cfbd90 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sat, 12 Feb 2022 22:57:46 +0100 Subject: [PATCH] -nt + fix ue_status --- app/comp/res_common.py | 26 ++++++++-------- app/models/etudiants.py | 8 +++++ app/models/formsemestre.py | 10 ++++-- app/models/notes.py | 34 +++++++++++++++++++-- app/scodoc/notes_table.py | 17 +++++++---- app/scodoc/sco_apogee_csv.py | 2 +- app/scodoc/sco_bulletins_json.py | 2 +- app/scodoc/sco_bulletins_pdf.py | 24 +++++++++------ app/scodoc/sco_bulletins_xml.py | 2 +- app/scodoc/sco_formsemestre_inscriptions.py | 4 +-- app/scodoc/sco_formsemestre_validation.py | 34 ++++++++++----------- app/scodoc/sco_moduleimpl_inscriptions.py | 10 +++--- app/scodoc/sco_parcours_dut.py | 9 ++---- app/scodoc/sco_poursuite_dut.py | 21 ++++++++----- app/scodoc/sco_prepajury.py | 14 +++------ app/scodoc/sco_pvjury.py | 6 ++-- app/scodoc/sco_recapcomplet.py | 10 +++--- app/views/absences.py | 8 ++--- 18 files changed, 142 insertions(+), 99 deletions(-) diff --git a/app/comp/res_common.py b/app/comp/res_common.py index fb064f48..006cbe6b 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -183,7 +183,7 @@ class ResultatsSemestre(ResultatsCache): sum_coefs_ue = 0.0 for ue in self.formsemestre.query_ues(): ue_cap = self.get_etud_ue_status(etudid, ue.id) - if ue_cap["is_capitalized"]: + if ue_cap and ue_cap["is_capitalized"]: recompute_mg = True coef = ue_cap["coef_ue"] if not np.isnan(ue_cap["moy"]): @@ -338,13 +338,12 @@ class NotesTableCompat(ResultatsSemestre): return self.formsemestre.get_infos_dict() @cached_property - def inscrlist(self) -> list[dict]: # utilisé par PE seulement + def inscrlist(self) -> list[dict]: # utilisé par PE """Liste des inscrits au semestre (avec DEM et DEF), sous forme de dict etud, classée dans l'ordre alphabétique de noms. """ - etuds = self.formsemestre.get_inscrits(include_demdef=True) - etuds.sort(key=lambda e: e.sort_key) + etuds = self.formsemestre.get_inscrits(include_demdef=True, sorted=True) return [e.to_dict_scodoc7() for e in etuds] @cached_property @@ -419,12 +418,12 @@ class NotesTableCompat(ResultatsSemestre): Return: True|False, message explicatif """ - return self.parcours.check_barre_ues( - [ - self.get_etud_ue_status(etudid, ue.id) - for ue in self.formsemestre.query_ues() - ] - ) + ue_status_list = [] + for ue in self.formsemestre.query_ues(): + ue_status = self.get_etud_ue_status(etudid, ue.id) + if ue_status: + ue_status_list.append(ue_status) + return self.parcours.check_barre_ues(ue_status_list) def get_etud_decision_ues(self, etudid: int) -> dict: """Decisions du jury pour les UE de cet etudiant, ou None s'il n'y en pas eu. @@ -622,8 +621,11 @@ class NotesTableCompat(ResultatsSemestre): ue_is_cap = {} for ue in ues: ue_status = self.get_etud_ue_status(etudid, ue.id) - moy_ues.append(ue_status["moy"]) - ue_is_cap[ue.id] = ue_status["is_capitalized"] + if ue_status: + moy_ues.append(ue_status["moy"]) + ue_is_cap[ue.id] = ue_status["is_capitalized"] + else: + moy_ues.append("?") t = [moy_gen] + list(moy_ues) # Moyennes modules: for modimpl in self.formsemestre.modimpls_sorted: diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 72e2088f..d919ee97 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -14,6 +14,7 @@ from app import models from app.scodoc import notesdb as ndb from app.scodoc.sco_bac import Baccalaureat +import app.scodoc.sco_utils as scu class Identite(db.Model): @@ -74,6 +75,13 @@ class Identite(db.Model): """ return {"M": "M.", "F": "Mme", "X": ""}[self.civilite] + def sex_nom(self, no_accents=False) -> str: + "'M. DUPONTÉ', ou si no_accents, 'M. DUPONTE'" + s = f"{self.civilite_str} {(self.nom_usuel or self.nom).upper()}" + if no_accents: + return scu.suppress_accents(s) + return s + def nom_disp(self) -> str: "Nom à afficher" if self.nom_usuel: diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index d874a3ad..2d6006c2 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -363,15 +363,19 @@ class FormSemestre(db.Model): etudid, self.date_debut.isoformat(), self.date_fin.isoformat() ) - def get_inscrits(self, include_demdef=False) -> list[Identite]: + def get_inscrits(self, include_demdef=False, sorted=False) -> list[Identite]: """Liste des étudiants inscrits à ce semestre Si include_demdef, tous les étudiants, avec les démissionnaires et défaillants. + Si sorted, tri par clé sort_key """ if include_demdef: - return [ins.etud for ins in self.inscriptions] + etuds = [ins.etud for ins in self.inscriptions] else: - return [ins.etud for ins in self.inscriptions if ins.etat == scu.INSCRIT] + etuds = [ins.etud for ins in self.inscriptions if ins.etat == scu.INSCRIT] + if sorted: + etuds.sort(key=lambda e: e.sort_key) + return etuds @cached_property def etudids_actifs(self) -> set: diff --git a/app/models/notes.py b/app/models/notes.py index 7e558357..239d7bb4 100644 --- a/app/models/notes.py +++ b/app/models/notes.py @@ -4,8 +4,9 @@ """ from app import db -from app.models import SHORT_STR_LEN -from app.models import CODE_STR_LEN + +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu class BulAppreciations(db.Model): @@ -67,3 +68,32 @@ class NotesNotesLog(db.Model): comment = db.Column(db.Text) # texte libre date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) uid = db.Column(db.Integer, db.ForeignKey("user.id")) + + +def etud_has_notes_attente(etudid, formsemestre_id): + """Vrai si cet etudiant a au moins une note en attente dans ce semestre. + (ne compte que les notes en attente dans des évaluation avec coef. non nul). + """ + # XXX ancienne méthode de notes_table à ré-écrire + cnx = ndb.GetDBConnexion() + cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) + cursor.execute( + """SELECT n.* + FROM notes_notes n, notes_evaluation e, notes_moduleimpl m, + notes_moduleimpl_inscription i + WHERE n.etudid = %(etudid)s + and n.value = %(code_attente)s + and n.evaluation_id = e.id + and e.moduleimpl_id = m.id + and m.formsemestre_id = %(formsemestre_id)s + and e.coefficient != 0 + and m.id = i.moduleimpl_id + and i.etudid=%(etudid)s + """, + { + "formsemestre_id": formsemestre_id, + "etudid": etudid, + "code_attente": scu.NOTES_ATTENTE, + }, + ) + return len(cursor.fetchall()) > 0 diff --git a/app/scodoc/notes_table.py b/app/scodoc/notes_table.py index d014d9fa..7fc03ce8 100644 --- a/app/scodoc/notes_table.py +++ b/app/scodoc/notes_table.py @@ -954,9 +954,12 @@ class NotesTable: Return: True|False, message explicatif """ - return self.parcours.check_barre_ues( - [self.get_etud_ue_status(etudid, ue["ue_id"]) for ue in self._ues] - ) + ue_status_list = [] + for ue in self._ues: + ue_status = self.get_etud_ue_status(etudid, ue["ue_id"]) + if ue_status: + ue_status_list.append(ue_status) + return self.parcours.check_barre_ues(ue_status_list) def get_table_moyennes_triees(self): return self.T @@ -1160,9 +1163,11 @@ class NotesTable: nt_cap = sco_cache.NotesTableCache.get( ue_cap["formsemestre_id"] ) # > UE capitalisees par un etud - moy_ue_cap = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"])[ - "moy" - ] + ue_cap_status = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"]) + if ue_cap_status: + moy_ue_cap = ue_cap_status["moy"] + else: + moy_ue_cap = "" ue_cap["moy_ue"] = moy_ue_cap if ( isinstance(moy_ue_cap, float) diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 4cae1772..904b939a 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -419,7 +419,7 @@ class ApoEtud(dict): ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) code_decision_ue = decisions_ue[ue["ue_id"]]["code"] return dict( - N=_apo_fmt_note(ue_status["moy"]), + N=_apo_fmt_note(ue_status["moy"] if ue_status else ""), B=20, J="", R=ScoDocSiteConfig.get_code_apo(code_decision_ue), diff --git a/app/scodoc/sco_bulletins_json.py b/app/scodoc/sco_bulletins_json.py index dbf4a8dc..ee57b60e 100644 --- a/app/scodoc/sco_bulletins_json.py +++ b/app/scodoc/sco_bulletins_json.py @@ -209,7 +209,7 @@ def formsemestre_bulletinetud_published_dict( acronyme=scu.quote_xml_attr(ue["acronyme"]), titre=scu.quote_xml_attr(ue["titre"]), note=dict( - value=scu.fmt_note(ue_status["cur_moy_ue"]), + value=scu.fmt_note(ue_status["cur_moy_ue"] if ue_status else ""), min=scu.fmt_note(ue["min"]), max=scu.fmt_note(ue["max"]), moy=scu.fmt_note( diff --git a/app/scodoc/sco_bulletins_pdf.py b/app/scodoc/sco_bulletins_pdf.py index 2195d1ee..fa599fa5 100644 --- a/app/scodoc/sco_bulletins_pdf.py +++ b/app/scodoc/sco_bulletins_pdf.py @@ -56,19 +56,24 @@ import time import traceback from pydoc import html -from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate +from reportlab.platypus.doctemplate import BaseDocTemplate from flask import g, request -import app.scodoc.sco_utils as scu from app import log, ScoValueError +from app.comp import res_sem +from app.comp.res_common import NotesTableCompat +from app.models import FormSemestre + from app.scodoc import sco_cache from app.scodoc import sco_formsemestre from app.scodoc import sco_pdf from app.scodoc import sco_preferences from app.scodoc import sco_etud -import sco_version from app.scodoc.sco_logos import find_logo +import app.scodoc.sco_utils as scu + +import sco_version def pdfassemblebulletins( @@ -178,22 +183,21 @@ def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"): if cached: return cached[1], cached[0] fragments = [] - sem = sco_formsemestre.get_formsemestre(formsemestre_id) # Make each bulletin - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids, get_sexnom + formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) bookmarks = {} filigrannes = {} i = 1 - for etudid in nt.get_etudids(): + for etud in formsemestre.get_inscrits(include_demdef=True, sorted=True): frag, filigranne = sco_bulletins.do_formsemestre_bulletinetud( formsemestre_id, - etudid, + etud.id, format="pdfpart", version=version, ) fragments += frag filigrannes[i] = filigranne - bookmarks[i] = scu.suppress_accents(nt.get_sexnom(etudid)) + bookmarks[i] = etud.sex_nom(no_accents=True) i = i + 1 # infos = {"DeptName": sco_preferences.get_preference("DeptName", formsemestre_id)} @@ -206,7 +210,7 @@ def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"): pdfdoc = pdfassemblebulletins( formsemestre_id, fragments, - sem["titremois"], + formsemestre.titre_mois(), infos, bookmarks, filigranne=filigrannes, @@ -216,7 +220,7 @@ def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"): sco_pdf.PDFLOCK.release() # dt = time.strftime("%Y-%m-%d") - filename = "bul-%s-%s.pdf" % (sem["titre_num"], dt) + filename = "bul-%s-%s.pdf" % (formsemestre.titre_num(), dt) filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "") # fill cache sco_cache.SemBulletinsPDFCache.set( diff --git a/app/scodoc/sco_bulletins_xml.py b/app/scodoc/sco_bulletins_xml.py index 8133501b..015867e3 100644 --- a/app/scodoc/sco_bulletins_xml.py +++ b/app/scodoc/sco_bulletins_xml.py @@ -217,7 +217,7 @@ def make_xml_formsemestre_bulletinetud( ) doc.append(x_ue) if ue["type"] != sco_codes_parcours.UE_SPORT: - v = ue_status["cur_moy_ue"] + v = ue_status["cur_moy_ue"] if ue_status else "" else: v = nt.bonus[etudid] if nt.bonus is not None else 0.0 x_ue.append( diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index 48d24f51..6ecfa32f 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -475,7 +475,7 @@ def formsemestre_inscription_option(etudid, formsemestre_id): raise ScoValueError("Modification impossible: semestre verrouille") etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_ue_status + nt = sco_cache.NotesTableCache.get(formsemestre_id) F = html_sco_header.sco_footer() H = [ @@ -527,7 +527,7 @@ def formsemestre_inscription_option(etudid, formsemestre_id): if ue["type"] != UE_STANDARD: ue_descr += " %s" % UE_TYPE_NAME[ue["type"]] ue_status = nt.get_etud_ue_status(etudid, ue_id) - if ue_status["is_capitalized"]: + if ue_status and ue_status["is_capitalized"]: sem_origin = sco_formsemestre.get_formsemestre(ue_status["formsemestre_id"]) ue_descr += ' (capitalisée le %s)' % ( sem_origin["formsemestre_id"], diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 7148ad16..f755bb11 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -31,7 +31,6 @@ import time import flask from flask import url_for, g, request -from app.api.sco_api import formsemestre import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu @@ -40,6 +39,7 @@ from app import log from app.comp import res_sem from app.comp.res_common import NotesTableCompat from app.models import FormSemestre +from app.models.notes import etud_has_notes_attente from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.scolog import logdb @@ -53,9 +53,7 @@ from app.scodoc import sco_cache from app.scodoc import sco_edit_ue from app.scodoc import sco_etud from app.scodoc import sco_formsemestre -from app.scodoc import sco_formsemestre_edit from app.scodoc import sco_formsemestre_inscriptions -from app.scodoc import sco_formsemestre_status from app.scodoc import sco_parcours_dut from app.scodoc.sco_parcours_dut import etud_est_inscrit_ue from app.scodoc import sco_photos @@ -72,9 +70,8 @@ def formsemestre_validation_etud_form( sortcol=None, readonly=True, ): - nt = sco_cache.NotesTableCache.get( - formsemestre_id - ) # > get_table_moyennes_triees, get_etud_decision_sem + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() if not etudid and etud_index is None: raise ValueError("formsemestre_validation_etud_form: missing argument etudid") @@ -202,7 +199,7 @@ def formsemestre_validation_etud_form( decision_jury = Se.nt.get_etud_decision_sem(etudid) # Bloque si note en attente - if nt.etud_has_notes_attente(etudid): + if etud_has_notes_attente(etudid, formsemestre_id): H.append( tf_error_message( f"""Impossible de statuer sur cet étudiant: il a des notes en @@ -550,7 +547,6 @@ def formsemestre_recap_parcours_table( formsemestre = FormSemestre.query.get(sem["formsemestre_id"]) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) - # nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"]) if is_cur: type_sem = "*" # now unused class_sem = "sem_courant" @@ -649,7 +645,7 @@ def formsemestre_recap_parcours_table( else: code = "" ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) - moy_ue = ue_status["moy"] + moy_ue = ue_status["moy"] if ue_status else "" explanation_ue = [] # list of strings if code == ADM: class_ue = "ue_adm" @@ -657,12 +653,12 @@ def formsemestre_recap_parcours_table( class_ue = "ue_cmp" else: class_ue = "ue" - if ue_status["is_external"]: # validation externe + if ue_status and ue_status["is_external"]: # validation externe explanation_ue.append("UE externe.") # log('x'*12+' EXTERNAL %s' % notes_table.fmt_note(moy_ue)) XXXXXXX # log('UE=%s' % pprint.pformat(ue)) # log('explanation_ue=%s\n'%explanation_ue) - if ue_status["is_capitalized"]: + if ue_status and ue_status["is_capitalized"]: class_ue += " ue_capitalized" explanation_ue.append( "Capitalisée le %s." % (ue_status["event_date"] or "?") @@ -709,7 +705,10 @@ def formsemestre_recap_parcours_table( # ECTS validables dans chaque UE for ue in ues: ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) - H.append('%g' % (ue_status["ects_pot"])) + H.append( + '%g' + % (ue_status["ects_pot"] if ue_status else "") + ) H.append("") H.append("") @@ -878,9 +877,8 @@ def do_formsemestre_validation_auto(formsemestre_id): "Saisie automatisee des decisions d'un semestre" sem = sco_formsemestre.get_formsemestre(formsemestre_id) next_semestre_id = sem["semestre_id"] + 1 - nt = sco_cache.NotesTableCache.get( - formsemestre_id - ) # > get_etudids, get_etud_decision_sem, + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) etudids = nt.get_etudids() nb_valid = 0 conflicts = [] # liste des etudiants avec decision differente déjà saisie @@ -899,7 +897,7 @@ def do_formsemestre_validation_auto(formsemestre_id): ) and Se.barre_moy_ok and Se.barres_ue_ok - and not nt.etud_has_notes_attente(etudid) + and not etud_has_notes_attente(etudid, formsemestre_id) ): # check: s'il existe une decision ou autorisation et qu'elles sont differentes, # warning (et ne fait rien) @@ -1133,9 +1131,11 @@ def do_formsemestre_validate_previous_ue( Si le coefficient est spécifié, modifie le coefficient de cette UE (utile seulement pour les semestres extérieurs). """ + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) + sem = sco_formsemestre.get_formsemestre(formsemestre_id) cnx = ndb.GetDBConnexion() - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_ue_status if ue_coefficient != None: sco_formsemestre.do_formsemestre_uecoef_edit_or_create( cnx, formsemestre_id, ue_id, ue_coefficient diff --git a/app/scodoc/sco_moduleimpl_inscriptions.py b/app/scodoc/sco_moduleimpl_inscriptions.py index 0778a006..98380555 100644 --- a/app/scodoc/sco_moduleimpl_inscriptions.py +++ b/app/scodoc/sco_moduleimpl_inscriptions.py @@ -479,21 +479,19 @@ def get_etuds_with_capitalized_ue(formsemestre_id): returns { ue_id : [ { infos } ] } """ UECaps = scu.DictDefault(defaultvalue=[]) - nt = sco_cache.NotesTableCache.get( - formsemestre_id - ) # > get_ues_stat_dict, get_etud_ue_status + nt = sco_cache.NotesTableCache.get(formsemestre_id) inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( args={"formsemestre_id": formsemestre_id} ) ues = nt.get_ues_stat_dict() for ue in ues: for etud in inscrits: - status = nt.get_etud_ue_status(etud["etudid"], ue["ue_id"]) - if status["was_capitalized"]: + ue_status = nt.get_etud_ue_status(etud["etudid"], ue["ue_id"]) + if ue_status and ue_status["was_capitalized"]: UECaps[ue["ue_id"]].append( { "etudid": etud["etudid"], - "ue_status": status, + "ue_status": ue_status, "is_ins": is_inscrit_ue( etud["etudid"], formsemestre_id, ue["ue_id"] ), diff --git a/app/scodoc/sco_parcours_dut.py b/app/scodoc/sco_parcours_dut.py index 4214b70b..1969dbbc 100644 --- a/app/scodoc/sco_parcours_dut.py +++ b/app/scodoc/sco_parcours_dut.py @@ -111,9 +111,6 @@ class DecisionSem(object): def SituationEtudParcours(etud, formsemestre_id): """renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)""" - # nt = sco_cache.NotesTableCache.get( - # formsemestre_id - # ) # > get_etud_decision_sem, get_etud_moy_gen, get_ues_stat_dict, get_etud_ue_status, etud_check_conditions_ues formsemestre = FormSemestre.query.get_or_404(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) parcours = nt.parcours @@ -924,9 +921,6 @@ def formsemestre_validate_ues(formsemestre_id, etudid, code_etat_sem, assiduite) """ valid_semestre = CODES_SEM_VALIDES.get(code_etat_sem, False) cnx = ndb.GetDBConnexion() - # nt = sco_cache.NotesTableCache.get( - # formsemestre_id - # ) # > get_ues_stat_dict, get_etud_ue_status formsemestre = FormSemestre.query.get_or_404(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) ue_ids = [x["ue_id"] for x in nt.get_ues_stat_dict(filter_sport=True)] @@ -1005,7 +999,8 @@ def do_formsemestre_validate_ue( if code == ADM: if moy_ue is None: # stocke la moyenne d'UE capitalisée: - moy_ue = nt.get_etud_ue_status(etudid, ue_id)["moy"] + ue_status = nt.get_etud_ue_status(etudid, ue_id) + moy_ue = ue_status["moy"] if ue_status else "" args["moy_ue"] = moy_ue log("formsemestre_validate_ue: create %s" % args) if code != None: diff --git a/app/scodoc/sco_poursuite_dut.py b/app/scodoc/sco_poursuite_dut.py index 60dfa2ab..a98014cd 100644 --- a/app/scodoc/sco_poursuite_dut.py +++ b/app/scodoc/sco_poursuite_dut.py @@ -62,13 +62,20 @@ def etud_get_poursuite_info(sem, etud): dec = nt.get_etud_decision_sem(etudid) # Moyennes et rangs des UE ues = nt.get_ues_stat_dict(filter_sport=True) - moy_ues = [ - ( - ue["acronyme"], - scu.fmt_note(nt.get_etud_ue_status(etudid, ue["ue_id"])["moy"]), - ) - for ue in ues - ] + moy_ues = [] + for ue in ues: + ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) + if ue_status: + moy_ues.append( + ( + ue["acronyme"], + scu.fmt_note( + nt.get_etud_ue_status(etudid, ue["ue_id"])["moy"] + ), + ) + ) + else: + moy_ues.append((ue["acronyme"], "")) rg_ues = [ ("rang_" + ue["acronyme"], nt.ue_rangs[ue["ue_id"]][0][etudid]) for ue in ues diff --git a/app/scodoc/sco_prepajury.py b/app/scodoc/sco_prepajury.py index 2032841b..1a683737 100644 --- a/app/scodoc/sco_prepajury.py +++ b/app/scodoc/sco_prepajury.py @@ -50,9 +50,7 @@ from app.scodoc.sco_excel import ScoExcelSheet def feuille_preparation_jury(formsemestre_id): "Feuille excel pour preparation des jurys" - nt = sco_cache.NotesTableCache.get( - formsemestre_id - ) # > get_etudids, get_etud_moy_gen, get_ues_stat_dict, get_etud_ue_status, get_etud_decision_sem, identdict, + nt = sco_cache.NotesTableCache.get(formsemestre_id) etudids = nt.get_etudids(sorted=True) # tri par moy gen sem = sco_formsemestre.get_formsemestre(formsemestre_id) @@ -83,16 +81,13 @@ def feuille_preparation_jury(formsemestre_id): etud = info[0] Se = sco_parcours_dut.SituationEtudParcours(etud, formsemestre_id) if Se.prev: - ntp = sco_cache.NotesTableCache.get( - Se.prev["formsemestre_id"] - ) # > get_ues_stat_dict, get_etud_ue_status, get_etud_moy_gen, get_etud_decision_sem + ntp = sco_cache.NotesTableCache.get(Se.prev["formsemestre_id"]) for ue in ntp.get_ues_stat_dict(filter_sport=True): ue_status = ntp.get_etud_ue_status(etudid, ue["ue_id"]) ue_code_s = ( ue["ue_code"] + "_%s" % ntp.sem["semestre_id"] ) # code indentifiant l'UE - prev_moy_ue[ue_code_s][etudid] = ue_status["moy"] - # prev_ue_acro[ue_code_s] = (ue['numero'], ue['acronyme']) + prev_moy_ue[ue_code_s][etudid] = ue_status["moy"] if ue_status else "" prev_ue_acro[ue_code_s] = (ue["numero"], ue["acronyme"], ue["titre"]) prev_moy[etudid] = ntp.get_etud_moy_gen(etudid) prev_decision = ntp.get_etud_decision_sem(etudid) @@ -105,8 +100,7 @@ def feuille_preparation_jury(formsemestre_id): for ue in nt.get_ues_stat_dict(filter_sport=True): ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) ue_code_s = ue["ue_code"] + "_%s" % nt.sem["semestre_id"] - moy_ue[ue_code_s][etudid] = ue_status["moy"] - # ue_acro[ue_code_s] = (ue['numero'], ue['acronyme']) + moy_ue[ue_code_s][etudid] = ue_status["moy"] if ue_status else "" ue_acro[ue_code_s] = (ue["numero"], ue["acronyme"], ue["titre"]) if Se.prev: diff --git a/app/scodoc/sco_pvjury.py b/app/scodoc/sco_pvjury.py index 78ec1439..0ed6ebd6 100644 --- a/app/scodoc/sco_pvjury.py +++ b/app/scodoc/sco_pvjury.py @@ -105,7 +105,7 @@ def _descr_decisions_ues(nt, etudid, decisions_ue, decision_sem): for ue_id in nt.validations.ue_capitalisees.loc[[etudid]]["ue_id"]: try: uelist.append(nt.get_etud_ue_status(etudid, ue_id)["ue"]) - except KeyError: + except (KeyError, TypeError): pass uelist.sort(key=itemgetter("numero")) @@ -162,13 +162,13 @@ def _comp_ects_by_ue_code(nt, decision_ues): return ects_by_ue_code -def _comp_ects_capitalises_by_ue_code(nt, etudid): +def _comp_ects_capitalises_by_ue_code(nt: NotesTableCompat, etudid: int): """Calcul somme des ECTS des UE capitalisees""" ues = nt.get_ues_stat_dict() ects_by_ue_code = {} for ue in ues: ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) - if ue_status["is_capitalized"]: + if ue_status and ue_status["is_capitalized"]: ects_val = float(ue_status["ue"]["ects"] or 0.0) ects_by_ue_code[ue["ue_code"]] = ects_val diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index 90ca8968..ee7006d9 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -50,7 +50,6 @@ from app.scodoc import sco_bulletins_json from app.scodoc import sco_bulletins_xml from app.scodoc import sco_bulletins, sco_excel from app.scodoc import sco_codes_parcours -from app.scodoc import sco_cache from app.scodoc import sco_evaluations from app.scodoc import sco_evaluation_db from app.scodoc import sco_formations @@ -307,8 +306,6 @@ def make_formsemestre_recapcomplet( )[0] parcours = formsemestre.formation.get_parcours() - # nt = sco_cache.NotesTableCache.get(formsemestre_id) # sco91 - # sco92 : nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) modimpls = formsemestre.modimpls_sorted ues = nt.get_ues_stat_dict() # incluant le(s) UE de sport @@ -891,8 +888,8 @@ def _formsemestre_recapcomplet_xml( force_publishing=True, ): "XML export: liste tous les bulletins XML." - - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_table_moyennes_triees + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() if not T: return "", "", "xml" @@ -962,7 +959,8 @@ def _formsemestre_recapcomplet_json( "bulletins": [], } bulletins = J["bulletins"] - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_table_moyennes_triees + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) T = nt.get_table_moyennes_triees() for t in T: etudid = t[-1] diff --git a/app/views/absences.py b/app/views/absences.py index 07f4bfdb..4122d5bd 100644 --- a/app/views/absences.py +++ b/app/views/absences.py @@ -729,12 +729,10 @@ def _gen_form_saisie_groupe( # UE capitalisee dans semestre courant ? cap = [] if etud["cursem"]: - nt = sco_cache.NotesTableCache.get( - etud["cursem"]["formsemestre_id"] - ) # > get_ues_stat_dict, get_etud_ue_status + nt = sco_cache.NotesTableCache.get(etud["cursem"]["formsemestre_id"]) for ue in nt.get_ues_stat_dict(): - status = nt.get_etud_ue_status(etudid, ue["ue_id"]) - if status["is_capitalized"]: + ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"]) + if ue_status and ue_status["is_capitalized"]: cap.append(ue["acronyme"]) if cap: capstr = ' (%s cap.)' % ", ".join(cap)