Bulletins et PV: champs décisions jury BUT
This commit is contained in:
parent
8e463e5971
commit
bf27fcbdc6
@ -326,10 +326,7 @@ class BulletinBUT:
|
||||
semestre_infos["ECTS"] = {"acquis": ects_acquis, "total": ects_tot}
|
||||
if sco_preferences.get_preference("bul_show_decision", formsemestre.id):
|
||||
semestre_infos.update(
|
||||
sco_bulletins_json.dict_decision_jury(etud.id, formsemestre.id)
|
||||
)
|
||||
semestre_infos.update(
|
||||
but_validations.dict_decision_jury(etud, formsemestre)
|
||||
sco_bulletins_json.dict_decision_jury(etud, formsemestre)
|
||||
)
|
||||
if etat_inscription == scu.INSCRIT:
|
||||
# moyenne des moyennes générales du semestre
|
||||
|
@ -67,7 +67,7 @@ class ApcValidationRCUE(db.Model):
|
||||
return self.ue2.niveau_competence
|
||||
|
||||
def to_dict_bul(self) -> dict:
|
||||
"Export dict pour bulletins"
|
||||
"Export dict pour bulletins: le code et le niveau de compétence"
|
||||
return {"code": self.code, "niveau": self.niveau().to_dict_bul()}
|
||||
|
||||
|
||||
@ -309,7 +309,9 @@ class ApcValidationAnnee(db.Model):
|
||||
|
||||
def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict:
|
||||
"""
|
||||
Un dict avec les décisions de jury BUT enregistrées.
|
||||
Un dict avec les décisions de jury BUT enregistrées:
|
||||
- decision_rcue : list[dict]
|
||||
- decision_annee : dict
|
||||
Ne reprend pas les décisions d'UE, non spécifiques au BUT.
|
||||
"""
|
||||
decisions = {}
|
||||
|
@ -434,7 +434,7 @@ def _get_etud_etat_html(etat: str) -> str:
|
||||
elif etat == scu.DEF: # "DEF"
|
||||
return ' <font color="red">(DEFAILLANT)</font> '
|
||||
else:
|
||||
return ' <font color="red">(%s)</font> ' % etat
|
||||
return f' <font color="red">({etat})</font> '
|
||||
|
||||
|
||||
def _sort_mod_by_matiere(modlist, nt, etudid):
|
||||
@ -707,6 +707,7 @@ def etud_descr_situation_semestre(
|
||||
descr_decisions_ue : ' UE acquises: UE1, UE2', ou vide si pas de dec. ou si pas show_uevalid
|
||||
descr_mention : 'Mention Bien', ou vide si pas de mention ou si pas show_mention
|
||||
"""
|
||||
# Fonction utilisée par tous les bulletins (APC ou classiques)
|
||||
cnx = ndb.GetDBConnexion()
|
||||
infos = scu.DictDefault(defaultvalue="")
|
||||
|
||||
@ -728,8 +729,7 @@ def etud_descr_situation_semestre(
|
||||
# il y a eu une erreur qui a laissé un event 'inscription'
|
||||
# on l'efface:
|
||||
log(
|
||||
"etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid=%s !"
|
||||
% etudid
|
||||
f"etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid={etudid} !"
|
||||
)
|
||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||
else:
|
||||
@ -738,8 +738,7 @@ def etud_descr_situation_semestre(
|
||||
# assert date_dem == None, 'plusieurs démissions !'
|
||||
if date_dem: # cela ne peut pas arriver sauf bug (signale a Evry 2013?)
|
||||
log(
|
||||
"etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid=%s !"
|
||||
% etudid
|
||||
f"etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid={etudid} !"
|
||||
)
|
||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||
else:
|
||||
@ -747,8 +746,7 @@ def etud_descr_situation_semestre(
|
||||
elif event_type == "DEFAILLANCE":
|
||||
if date_def:
|
||||
log(
|
||||
"etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid=%s !"
|
||||
% etudid
|
||||
f"etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid={etudid} !"
|
||||
)
|
||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||
else:
|
||||
@ -756,10 +754,10 @@ def etud_descr_situation_semestre(
|
||||
if show_date_inscr:
|
||||
if not date_inscr:
|
||||
infos["date_inscription"] = ""
|
||||
infos["descr_inscription"] = "Pas inscrit%s." % ne
|
||||
infos["descr_inscription"] = f"Pas inscrit{ne}."
|
||||
else:
|
||||
infos["date_inscription"] = date_inscr
|
||||
infos["descr_inscription"] = "Inscrit%s le %s." % (ne, date_inscr)
|
||||
infos["descr_inscription"] = f"Inscrit{ne} le {date_inscr}."
|
||||
else:
|
||||
infos["date_inscription"] = ""
|
||||
infos["descr_inscription"] = ""
|
||||
@ -767,15 +765,15 @@ def etud_descr_situation_semestre(
|
||||
infos["situation"] = infos["descr_inscription"]
|
||||
|
||||
if date_dem:
|
||||
infos["descr_demission"] = "Démission le %s." % date_dem
|
||||
infos["descr_demission"] = f"Démission le {date_dem}."
|
||||
infos["date_demission"] = date_dem
|
||||
infos["descr_decision_jury"] = "Démission"
|
||||
infos["situation"] += " " + infos["descr_demission"]
|
||||
return infos, None # ne donne pas les dec. de jury pour les demissionnaires
|
||||
if date_def:
|
||||
infos["descr_defaillance"] = "Défaillant%s" % ne
|
||||
infos["descr_defaillance"] = f"Défaillant{ne}"
|
||||
infos["date_defaillance"] = date_def
|
||||
infos["descr_decision_jury"] = "Défaillant%s" % ne
|
||||
infos["descr_decision_jury"] = f"Défaillant{ne}"
|
||||
infos["situation"] += " " + infos["descr_defaillance"]
|
||||
|
||||
dpv = sco_pvjury.dict_pvjury(formsemestre_id, etudids=[etudid])
|
||||
@ -798,6 +796,7 @@ def etud_descr_situation_semestre(
|
||||
dec = infos["descr_decision_jury"]
|
||||
else:
|
||||
infos["descr_decision_jury"] = ""
|
||||
infos["decision_jury"] = ""
|
||||
|
||||
if pv["decisions_ue_descr"] and show_uevalid:
|
||||
infos["decisions_ue"] = pv["decisions_ue_descr"]
|
||||
@ -809,14 +808,31 @@ def etud_descr_situation_semestre(
|
||||
|
||||
infos["mention"] = pv["mention"]
|
||||
if pv["mention"] and show_mention:
|
||||
dec += "Mention " + pv["mention"] + ". "
|
||||
dec += f"Mention {pv['mention']}."
|
||||
|
||||
# Décisions APC / BUT
|
||||
if pv.get("decision_annee", {}):
|
||||
infos["descr_decision_annee"] = "Décision année: " + pv.get(
|
||||
"decision_annee", {}
|
||||
).get("code", "")
|
||||
else:
|
||||
infos["descr_decision_annee"] = ""
|
||||
if pv.get("decision_rcue", []):
|
||||
infos["descr_decisions_rcue"] = "Niveaux de compétences: " + ", ".join(
|
||||
[
|
||||
f"""{dec_rcue["niveau"]["competence"]["titre"]} {dec_rcue["niveau"]["ordre"]}: {dec_rcue["code"]}"""
|
||||
for dec_rcue in pv.get("decision_rcue", [])
|
||||
]
|
||||
)
|
||||
else:
|
||||
infos["descr_decisions_rcue"] = ""
|
||||
|
||||
infos["situation"] += " " + dec
|
||||
if not pv["validation_parcours"]: # parcours non terminé
|
||||
if pv["autorisations_descr"]:
|
||||
infos["situation"] += (
|
||||
" Autorisé à s'inscrire en %s." % pv["autorisations_descr"]
|
||||
)
|
||||
infos[
|
||||
"situation"
|
||||
] += f" Autorisé à s'inscrire en {pv['autorisations_descr']}."
|
||||
else:
|
||||
infos["situation"] += " Diplôme obtenu."
|
||||
return infos, dpv
|
||||
|
@ -25,7 +25,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""Génération du bulletin en format JSON (beta, non completement testé)
|
||||
"""Génération du bulletin en format JSON
|
||||
|
||||
"""
|
||||
import datetime
|
||||
@ -33,8 +33,9 @@ import json
|
||||
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.models import but_validations
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.formsemestre import FormSemestre
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -139,7 +140,7 @@ def formsemestre_bulletinetud_published_dict(
|
||||
|
||||
etat_inscription = etud.inscription_etat(formsemestre.id)
|
||||
if etat_inscription != scu.INSCRIT:
|
||||
d.update(dict_decision_jury(etudid, formsemestre_id, with_decisions=True))
|
||||
d.update(dict_decision_jury(etud, formsemestre, with_decisions=True))
|
||||
return d
|
||||
|
||||
# Groupes:
|
||||
@ -343,9 +344,7 @@ def formsemestre_bulletinetud_published_dict(
|
||||
d["absences"] = dict(nbabs=nbabs, nbabsjust=nbabsjust)
|
||||
|
||||
# --- Decision Jury
|
||||
d.update(
|
||||
dict_decision_jury(etudid, formsemestre_id, with_decisions=xml_with_decisions)
|
||||
)
|
||||
d.update(dict_decision_jury(etud, formsemestre, with_decisions=xml_with_decisions))
|
||||
# --- Appreciations
|
||||
cnx = ndb.GetDBConnexion()
|
||||
apprecs = sco_etud.appreciations_list(
|
||||
@ -364,7 +363,9 @@ def formsemestre_bulletinetud_published_dict(
|
||||
return d
|
||||
|
||||
|
||||
def dict_decision_jury(etudid, formsemestre_id, with_decisions=False) -> dict:
|
||||
def dict_decision_jury(
|
||||
etud: Identite, formsemestre: FormSemestre, with_decisions: bool = False
|
||||
) -> dict:
|
||||
"""dict avec decision pour bulletins json
|
||||
- decision : décision semestre
|
||||
- decision_ue : list des décisions UE
|
||||
@ -372,6 +373,8 @@ def dict_decision_jury(etudid, formsemestre_id, with_decisions=False) -> dict:
|
||||
|
||||
with_decision donne les décision même si bul_show_decision est faux.
|
||||
|
||||
Si formation APC, indique aussi validations année et RCUEs
|
||||
|
||||
Exemple:
|
||||
{
|
||||
'autorisation_inscription': [{'semestre_id': 4}],
|
||||
@ -397,14 +400,14 @@ def dict_decision_jury(etudid, formsemestre_id, with_decisions=False) -> dict:
|
||||
|
||||
d = {}
|
||||
if (
|
||||
sco_preferences.get_preference("bul_show_decision", formsemestre_id)
|
||||
sco_preferences.get_preference("bul_show_decision", formsemestre.id)
|
||||
or with_decisions
|
||||
):
|
||||
infos, dpv = sco_bulletins.etud_descr_situation_semestre(
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
etud.id,
|
||||
formsemestre.id,
|
||||
show_uevalid=sco_preferences.get_preference(
|
||||
"bul_show_uevalid", formsemestre_id
|
||||
"bul_show_uevalid", formsemestre.id
|
||||
),
|
||||
)
|
||||
d["situation"] = infos["situation"]
|
||||
@ -456,4 +459,7 @@ def dict_decision_jury(etudid, formsemestre_id, with_decisions=False) -> dict:
|
||||
)
|
||||
else:
|
||||
d["decision"] = dict(code="", etat="DEM")
|
||||
# Ajout jury BUT:
|
||||
if formsemestre.formation.is_apc():
|
||||
d.update(but_validations.dict_decision_jury(etud, formsemestre))
|
||||
return d
|
||||
|
@ -140,12 +140,15 @@ def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"):
|
||||
text = (field or "") % scu.WrapDict(
|
||||
cdict
|
||||
) # note that None values are mapped to empty strings
|
||||
except:
|
||||
except: # pylint: disable=bare-except
|
||||
log(
|
||||
f"""process_field: invalid format. field={field!r}
|
||||
values={pprint.pformat(cdict)}
|
||||
"""
|
||||
)
|
||||
# ne sera pas visible si lien vers pdf:
|
||||
scu.flash_once(f"Attention: format PDF invalide (champs {field}")
|
||||
raise ValueError
|
||||
text = (
|
||||
"<para><i>format invalide !</i></para><para>"
|
||||
+ traceback.format_exc()
|
||||
|
@ -55,6 +55,7 @@ from reportlab.lib import styles
|
||||
|
||||
from flask import g
|
||||
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_utils import CONFIG
|
||||
from app import log
|
||||
from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
|
||||
@ -67,7 +68,7 @@ PAGE_WIDTH = defaultPageSize[0]
|
||||
DEFAULT_PDF_FOOTER_TEMPLATE = CONFIG.DEFAULT_PDF_FOOTER_TEMPLATE
|
||||
|
||||
|
||||
def SU(s):
|
||||
def SU(s: str) -> str:
|
||||
"convert s from string to string suitable for ReportLab"
|
||||
if not s:
|
||||
return ""
|
||||
@ -145,9 +146,9 @@ def makeParas(txt, style, suppress_empty=False):
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
except Exception as e:
|
||||
except Exception as exc:
|
||||
log(traceback.format_exc())
|
||||
log("Invalid pdf para format: %s" % txt)
|
||||
log(f"Invalid pdf para format: {txt}")
|
||||
try:
|
||||
result = [
|
||||
Paragraph(
|
||||
@ -155,13 +156,14 @@ def makeParas(txt, style, suppress_empty=False):
|
||||
style,
|
||||
)
|
||||
]
|
||||
except ValueError as e: # probleme font ? essaye sans style
|
||||
except ValueError as exc2: # probleme font ? essaye sans style
|
||||
# recupere font en cause ?
|
||||
m = re.match(r".*family/bold/italic for (.*)", e.args[0], re.DOTALL)
|
||||
if m:
|
||||
message = f"police non disponible: {m[1]}"
|
||||
else:
|
||||
message = "format invalide"
|
||||
scu.flash_once(f"problème génération PDF: {message}")
|
||||
return [
|
||||
Paragraph(
|
||||
SU(f'<font color="red"><b>Erreur: {message}</b></font>'),
|
||||
|
@ -57,7 +57,13 @@ from flask import g, request
|
||||
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import FormSemestre, UniteEns, ScolarAutorisationInscription
|
||||
from app.models import (
|
||||
FormSemestre,
|
||||
UniteEns,
|
||||
ScolarAutorisationInscription,
|
||||
but_validations,
|
||||
)
|
||||
from app.models.etudiants import Identite
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -81,8 +87,8 @@ from app.scodoc.sco_pdf import PDFLOCK
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
|
||||
|
||||
def _descr_decisions_ues(nt, etudid, decisions_ue, decision_sem):
|
||||
"""Liste des UE validées dans ce semestre"""
|
||||
def _descr_decisions_ues(nt, etudid, decisions_ue, decision_sem) -> list[dict]:
|
||||
"""Liste des UE validées dans ce semestre (incluant les UE capitalisées)"""
|
||||
if not decisions_ue:
|
||||
return []
|
||||
uelist = []
|
||||
@ -93,14 +99,17 @@ def _descr_decisions_ues(nt, etudid, decisions_ue, decision_sem):
|
||||
decisions_ue[ue_id]["code"] == sco_codes_parcours.ADM
|
||||
or (
|
||||
# XXX ceci devrait dépendre du parcours et non pas être une option ! #sco8
|
||||
scu.CONFIG.CAPITALIZE_ALL_UES
|
||||
decision_sem
|
||||
and scu.CONFIG.CAPITALIZE_ALL_UES
|
||||
and sco_codes_parcours.code_semestre_validant(decision_sem["code"])
|
||||
)
|
||||
):
|
||||
ue = sco_edit_ue.ue_list(args={"ue_id": ue_id})[0]
|
||||
uelist.append(ue)
|
||||
except:
|
||||
log("descr_decisions_ues: ue_id=%s decisions_ue=%s" % (ue_id, decisions_ue))
|
||||
log(
|
||||
f"Exception in descr_decisions_ues: ue_id={ue_id} decisions_ue={decisions_ue}"
|
||||
)
|
||||
# Les UE capitalisées dans d'autres semestres:
|
||||
if etudid in nt.validations.ue_capitalisees.index:
|
||||
for ue_id in nt.validations.ue_capitalisees.loc[[etudid]]["ue_id"]:
|
||||
@ -230,8 +239,11 @@ def dict_pvjury(
|
||||
L = []
|
||||
D = {} # même chose que L, mais { etudid : dec }
|
||||
for etudid in etudids:
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
|
||||
# etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
etud: Identite = Identite.query.get(etudid)
|
||||
Se = sco_cursus.get_situation_etud_cursus(
|
||||
etud.to_dict_scodoc7(), formsemestre_id
|
||||
)
|
||||
semestre_non_terminal = semestre_non_terminal or Se.semestre_non_terminal
|
||||
d = {}
|
||||
d["identite"] = nt.identdict[etudid]
|
||||
@ -240,6 +252,8 @@ def dict_pvjury(
|
||||
) # I|D|DEF (inscription ou démission ou défaillant)
|
||||
d["decision_sem"] = nt.get_etud_decision_sem(etudid)
|
||||
d["decisions_ue"] = nt.get_etud_decision_ues(etudid)
|
||||
if formsemestre.formation.is_apc():
|
||||
d.update(but_validations.dict_decision_jury(etud, formsemestre))
|
||||
d["last_formsemestre_id"] = Se.get_semestres()[
|
||||
-1
|
||||
] # id du dernier semestre (chronologiquement) dans lequel il a été inscrit
|
||||
@ -305,12 +319,7 @@ def dict_pvjury(
|
||||
d["decision_sem"]["compense_formsemestre_id"]
|
||||
)
|
||||
obs.append(
|
||||
"%s compense %s (%s)"
|
||||
% (
|
||||
sem["sem_id_txt"],
|
||||
compensed["sem_id_txt"],
|
||||
compensed["anneescolaire"],
|
||||
)
|
||||
f"""{sem["sem_id_txt"]} compense {compensed["sem_id_txt"]} ({compensed["anneescolaire"]})"""
|
||||
)
|
||||
|
||||
d["observation"] = ", ".join(obs)
|
||||
|
@ -664,6 +664,15 @@ def flash_errors(form):
|
||||
# see https://getbootstrap.com/docs/4.0/components/alerts/
|
||||
|
||||
|
||||
def flash_once(message: str):
|
||||
"""Flash the message, but only once per request"""
|
||||
if not hasattr(g, "sco_flashed_once"):
|
||||
g.sco_flashed_once = set()
|
||||
if not message in g.sco_flashed_once:
|
||||
flash(message)
|
||||
g.sco_flashed_once.add(message)
|
||||
|
||||
|
||||
def sendCSVFile(data, filename): # DEPRECATED utiliser send_file
|
||||
"""publication fichier CSV."""
|
||||
return send_file(data, filename=filename, mime=CSV_MIMETYPE, attached=True)
|
||||
|
@ -2552,9 +2552,8 @@ def formsemestre_validation_suppress_etud(
|
||||
)
|
||||
if not dialog_confirmed:
|
||||
d = sco_bulletins_json.dict_decision_jury(
|
||||
etudid, formsemestre_id, with_decisions=True
|
||||
etud, formsemestre, with_decisions=True
|
||||
)
|
||||
d.update(but_validations.dict_decision_jury(etud, formsemestre))
|
||||
|
||||
descr_ues = [f"{u['acronyme']}: {u['code']}" for u in d.get("decision_ue", [])]
|
||||
dec_annee = d.get("decision_annee")
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.3.16"
|
||||
SCOVERSION = "9.3.17"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user