Fix bulletins legacy + refactoring

This commit is contained in:
Emmanuel Viennet 2021-02-01 16:23:11 +01:00
parent 0d0c391547
commit a4173e1877
10 changed files with 274 additions and 230 deletions

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "7.20a"
SCOVERSION = "7.21"
SCONAME = "ScoDoc"

View File

@ -392,7 +392,7 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
"version info"
H = [
"""<h2>Système de gestion scolarité</h2>
<p>&copy; Emmanuel Viennet 1997-2020</p>
<p>&copy; Emmanuel Viennet 1997-2021</p>
<p>Version %s (subversion %s)</p>
"""
% (SCOVERSION, get_svn_version(file_path))

View File

@ -28,6 +28,9 @@
"""Génération des bulletins de notes
"""
from types import StringType
import pprint
import urllib
from email.MIMEMultipart import ( # pylint: disable=no-name-in-module,import-error
MIMEMultipart,
)
@ -40,8 +43,13 @@ import time
import htmlutils
from reportlab.lib.colors import Color
from sco_utils import *
from notes_table import *
import sco_utils as scu
import notesdb as ndb
from notes_log import log
import scolars
from sco_permissions import ScoImplement, ScoEtudInscrit
from sco_exceptions import AccessDenied
import sco_codes_parcours
import sco_formsemestre
import sco_groups
import sco_pvjury
@ -114,7 +122,7 @@ def formsemestre_bulletinetud_dict(
context, formsemestre_id
) # > toutes notes
I = DictDefault(defaultvalue="")
I = scu.DictDefault(defaultvalue="")
I["etudid"] = etudid
I["formsemestre_id"] = formsemestre_id
I["sem"] = nt.sem
@ -182,7 +190,7 @@ def formsemestre_bulletinetud_dict(
if I["etud_etat"] == "D":
I["demission"] = "(Démission)"
I["filigranne"] = "Démission"
elif I["etud_etat"] == DEF:
elif I["etud_etat"] == sco_codes_parcours.DEF:
I["demission"] = "(Défaillant)"
I["filigranne"] = "Défaillant"
elif (prefs["bul_show_temporary"] and not I["decision_sem"]) or prefs[
@ -206,16 +214,16 @@ def formsemestre_bulletinetud_dict(
modimpls = nt.get_modimpls()
moy_gen = nt.get_etud_moy_gen(etudid)
I["nb_inscrits"] = len(nt.rangs)
I["moy_gen"] = fmt_note(moy_gen)
I["moy_min"] = fmt_note(nt.moy_min)
I["moy_max"] = fmt_note(nt.moy_max)
I["moy_gen"] = scu.fmt_note(moy_gen)
I["moy_min"] = scu.fmt_note(nt.moy_min)
I["moy_max"] = scu.fmt_note(nt.moy_max)
I["mention"] = ""
if dpv:
decision_sem = dpv["decisions"][0]["decision_sem"]
if decision_sem and sco_codes_parcours.code_semestre_validant(
decision_sem["code"]
):
I["mention"] = get_mention(moy_gen)
I["mention"] = scu.get_mention(moy_gen)
if dpv and dpv["decisions"][0]:
I["sum_ects"] = dpv["decisions"][0]["sum_ects"]
@ -223,7 +231,7 @@ def formsemestre_bulletinetud_dict(
else:
I["sum_ects"] = 0
I["sum_ects_capitalises"] = 0
I["moy_moy"] = fmt_note(nt.moy_moy) # moyenne des moyennes generales
I["moy_moy"] = scu.fmt_note(nt.moy_moy) # moyenne des moyennes generales
if type(moy_gen) != StringType and type(nt.moy_moy) != StringType:
I["moy_gen_bargraph_html"] = "&nbsp;" + htmlutils.horizontal_bargraph(
moy_gen * 5, nt.moy_moy * 5
@ -243,8 +251,8 @@ def formsemestre_bulletinetud_dict(
if nt.get_moduleimpls_attente():
# n'affiche pas le rang sur le bulletin s'il y a des
# notes en attente dans ce semestre
rang = RANG_ATTENTE_STR
rang_gr = DictDefault(defaultvalue=RANG_ATTENTE_STR)
rang = scu.RANG_ATTENTE_STR
rang_gr = scu.DictDefault(defaultvalue=scu.RANG_ATTENTE_STR)
I["rang"] = rang
I["rang_gr"] = rang_gr
I["gr_name"] = gr_name
@ -270,17 +278,17 @@ def formsemestre_bulletinetud_dict(
u = ue.copy()
ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"])
u["ue_status"] = ue_status # { 'moy', 'coef_ue', ...}
if ue["type"] != UE_SPORT:
u["cur_moy_ue_txt"] = fmt_note(ue_status["cur_moy_ue"])
if ue["type"] != sco_codes_parcours.UE_SPORT:
u["cur_moy_ue_txt"] = scu.fmt_note(ue_status["cur_moy_ue"])
else:
x = fmt_note(nt.bonus[etudid], keep_numeric=True)
x = scu.fmt_note(nt.bonus[etudid], keep_numeric=True)
if type(x) == StringType:
u["cur_moy_ue_txt"] = "pas de bonus"
else:
u["cur_moy_ue_txt"] = "bonus de %.3g points" % x
u["moy_ue_txt"] = fmt_note(ue_status["moy"])
u["moy_ue_txt"] = scu.fmt_note(ue_status["moy"])
if ue_status["coef_ue"] != None:
u["coef_ue_txt"] = fmt_coef(ue_status["coef_ue"])
u["coef_ue_txt"] = scu.fmt_coef(ue_status["coef_ue"])
else:
# C'est un bug:
log("u=" + pprint.pformat(u))
@ -292,7 +300,7 @@ def formsemestre_bulletinetud_dict(
and ue["ue_id"] in dpv["decisions"][0]["decisions_ue"]
):
u["ects"] = dpv["decisions"][0]["decisions_ue"][ue["ue_id"]]["ects"]
if ue["type"] == UE_ELECTIVE:
if ue["type"] == sco_codes_parcours.UE_ELECTIVE:
u["ects"] = (
"%g+" % u["ects"]
) # ajoute un "+" pour indiquer ECTS d'une UE élective
@ -316,7 +324,7 @@ def formsemestre_bulletinetud_dict(
sem_origin = sco_formsemestre.get_formsemestre(
context, ue_status["formsemestre_id"]
)
u["ue_descr_txt"] = "Capitalisée le %s" % DateISOtoDMY(
u["ue_descr_txt"] = "Capitalisée le %s" % ndb.DateISOtoDMY(
ue_status["event_date"]
)
u[
@ -334,7 +342,7 @@ def formsemestre_bulletinetud_dict(
context, ue_status["formsemestre_id"]
) # > toutes notes
u["modules_capitalized"], junk = _ue_mod_bulletin(
u["modules_capitalized"], _ = _ue_mod_bulletin(
context,
etudid,
formsemestre_id,
@ -347,10 +355,10 @@ def formsemestre_bulletinetud_dict(
_sort_mod_by_matiere(u["modules_capitalized"], nt_cap, etudid)
)
else:
if prefs["bul_show_ue_rangs"] and ue["type"] != UE_SPORT:
if prefs["bul_show_ue_rangs"] and ue["type"] != sco_codes_parcours.UE_SPORT:
if ue_attente: # nt.get_moduleimpls_attente():
u["ue_descr_txt"] = "%s/%s" % (
RANG_ATTENTE_STR,
scu.RANG_ATTENTE_STR,
nt.ue_rangs[ue["ue_id"]][1],
)
else:
@ -386,7 +394,7 @@ def _sort_mod_by_matiere(modlist, nt, etudid):
"titre": mod["mat"]["titre"],
"modules": mod,
"moy": moy,
"moy_txt": fmt_note(moy),
"moy_txt": scu.fmt_note(moy),
}
return matmod
@ -402,8 +410,8 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
)
if bul_show_abs_modules:
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
debut_sem = DateDMYtoISO(sem["date_debut"])
fin_sem = DateDMYtoISO(sem["date_fin"])
debut_sem = ndb.DateDMYtoISO(sem["date_debut"])
fin_sem = ndb.DateDMYtoISO(sem["date_fin"])
ue_modimpls = [mod for mod in modimpls if mod["module"]["ue_id"] == ue_id]
mods = [] # result
@ -414,7 +422,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
mod_moy = nt.get_etud_mod_moy(
modimpl["moduleimpl_id"], etudid
) # peut etre 'NI'
is_malus = mod["module"]["module_type"] == MODULE_MALUS
is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS
if bul_show_abs_modules:
mod_abs = [
context.Absences.CountAbs(
@ -430,25 +438,25 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
moduleimpl_id=modimpl["moduleimpl_id"],
),
]
mod["mod_abs_txt"] = fmt_abs(mod_abs)
mod["mod_abs_txt"] = scu.fmt_abs(mod_abs)
else:
mod["mod_abs_txt"] = ""
mod["mod_moy_txt"] = fmt_note(mod_moy)
mod["mod_moy_txt"] = scu.fmt_note(mod_moy)
if mod["mod_moy_txt"][:2] == "NA":
mod["mod_moy_txt"] = "-"
if is_malus:
if mod_moy > 0:
mod["mod_moy_txt"] = fmt_note(mod_moy)
mod["mod_moy_txt"] = scu.fmt_note(mod_moy)
mod["mod_coef_txt"] = "Malus"
elif mod_moy < 0:
mod["mod_moy_txt"] = fmt_note(-mod_moy)
mod["mod_moy_txt"] = scu.fmt_note(-mod_moy)
mod["mod_coef_txt"] = "Bonus"
else:
mod["mod_moy_txt"] = "-"
mod["mod_coef_txt"] = "-"
else:
mod["mod_coef_txt"] = fmt_coef(modimpl["module"]["coefficient"])
mod["mod_coef_txt"] = scu.fmt_coef(modimpl["module"]["coefficient"])
if mod["mod_moy_txt"] != "NI": # ne montre pas les modules 'non inscrit'
mods.append(mod)
if is_malus: # n'affiche pas les statistiques sur les modules malus
@ -464,7 +472,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
mod["stats"] = nt.get_mod_stats(modimpl["moduleimpl_id"])
mod["mod_descr_txt"] = "Module %s, coef. %s (%s)" % (
modimpl["module"]["titre"],
fmt_coef(modimpl["module"]["coefficient"]),
scu.fmt_coef(modimpl["module"]["coefficient"]),
context.Users.user_info(modimpl["responsable_id"])["nomcomplet"],
)
link_mod = (
@ -483,7 +491,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
mod_descr = "Module %s, coef. %s (%s)" % (
modimpl["module"]["titre"],
fmt_coef(modimpl["module"]["coefficient"]),
scu.fmt_coef(modimpl["module"]["coefficient"]),
context.Users.user_info(modimpl["responsable_id"])["nomcomplet"],
)
link_mod = (
@ -527,18 +535,18 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
if val == "NP":
e["note_txt"] = "nd"
e["note_html"] = '<span class="note_nd">nd</span>'
e["coef_txt"] = fmt_coef(e["coefficient"])
e["coef_txt"] = scu.fmt_coef(e["coefficient"])
else:
# (-0.15) s'affiche "bonus de 0.15"
if is_malus:
val = abs(val)
e["note_txt"] = fmt_note(val, note_max=e["note_max"])
e["note_txt"] = scu.fmt_note(val, note_max=e["note_max"])
e["note_html"] = e["note_txt"]
if is_malus:
e["coef_txt"] = ""
else:
e["coef_txt"] = fmt_coef(e["coefficient"])
if e["evaluation_type"] == EVALUATION_RATTRAPAGE:
e["coef_txt"] = scu.fmt_coef(e["coefficient"])
if e["evaluation_type"] == scu.EVALUATION_RATTRAPAGE:
e["coef_txt"] = "rat."
if e["etat"]["evalattente"]:
mod_attente = True # une eval en attente dans ce module
@ -569,12 +577,12 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
e["name"],
)
e["note_txt"] = e["note_html"] = ""
e["coef_txt"] = fmt_coef(e["coefficient"])
e["coef_txt"] = scu.fmt_coef(e["coefficient"])
# Classement
if bul_show_mod_rangs and mod["mod_moy_txt"] != "-" and not is_malus:
rg = nt.mod_rangs[modimpl["moduleimpl_id"]]
if mod_attente: # nt.get_moduleimpls_attente():
mod["mod_rang"] = RANG_ATTENTE_STR
mod["mod_rang"] = scu.RANG_ATTENTE_STR
else:
mod["mod_rang"] = rg[0][etudid]
mod["mod_eff"] = rg[1] # effectif dans ce module
@ -639,7 +647,7 @@ def etud_descr_situation_semestre(
descr_mention : 'Mention Bien', ou vide si pas de mention ou si pas show_mention
"""
cnx = context.GetDBConnexion()
infos = DictDefault(defaultvalue="")
infos = scu.DictDefault(defaultvalue="")
# --- Situation et décisions jury
@ -650,7 +658,6 @@ def etud_descr_situation_semestre(
date_inscr = None
date_dem = None
date_def = None
date_echec = None
for event in events:
event_type = event["event_type"]
if event_type == "INSCRIPTION":
@ -767,7 +774,7 @@ def formsemestre_bulletinetud(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
except:
return log_unknown_etud(context, REQUEST, format=format)
return scu.log_unknown_etud(context, REQUEST, format=format)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -889,7 +896,7 @@ def do_formsemestre_bulletinetud(
etud = I["etud"]
if format == "html":
htm, junk = sco_bulletins_generator.make_formsemestre_bulletinetud(
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
context, I, version=version, format="html", REQUEST=REQUEST
)
return htm, I["filigranne"]
@ -905,7 +912,7 @@ def do_formsemestre_bulletinetud(
)
if format == "pdf":
return (
sendPDFFile(REQUEST, bul, filename),
scu.sendPDFFile(REQUEST, bul, filename),
I["filigranne"],
) # unused ret. value
else:
@ -920,7 +927,7 @@ def do_formsemestre_bulletinetud(
if nohtml:
htm = "" # speed up if html version not needed
else:
htm, junk = sco_bulletins_generator.make_formsemestre_bulletinetud(
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
context, I, version=version, format="html", REQUEST=REQUEST
)
@ -964,7 +971,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
"""
etud = I["etud"]
webmaster = context.get_preference("bul_mail_contact_addr", formsemestre_id)
dept = unescape_html(context.get_preference("DeptName", formsemestre_id))
dept = scu.unescape_html(context.get_preference("DeptName", formsemestre_id))
copy_addr = context.get_preference("email_copy_bulletins", formsemestre_id)
intro_mail = context.get_preference("bul_intro_mail", formsemestre_id)
@ -983,7 +990,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
)
msg = MIMEMultipart()
subj = Header("Relevé de notes de %s" % etud["nomprenom"], SCO_ENCODING)
subj = Header("Relevé de notes de %s" % etud["nomprenom"], scu.SCO_ENCODING)
recipients = [recipient_addr]
msg["Subject"] = subj
msg["From"] = context.get_preference("email_from_addr", formsemestre_id)
@ -993,7 +1000,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
# Guarantees the message ends in a newline
msg.epilogue = ""
# Text
txt = MIMEText(hea, "plain", SCO_ENCODING)
txt = MIMEText(hea, "plain", scu.SCO_ENCODING)
# log('hea:\n' + hea)
msg.attach(txt)
# Attach pdf
@ -1157,7 +1164,7 @@ def _formsemestre_bulletinetud_header_html(
url
+ "?formsemestre_id=%s&amp;etudid=%s&amp;format=pdf&amp;version=%s"
% (formsemestre_id, etudid, version),
ICON_PDF,
scu.ICON_PDF,
)
)
H.append("""</tr></table>""")

View File

@ -28,12 +28,14 @@
"""Generation bulletins de notes: exemple minimal pour les programmeurs
"""
# Quelques modules ScoDoc utiles:
from sco_pdf import *
import VERSION
import sco_utils as scu
import sco_pdf
import sco_preferences
from notes_log import log
import sco_bulletins_generator
import sco_bulletins_standard
from reportlab.platypus import Paragraph
class BulletinGeneratorExample(sco_bulletins_standard.BulletinGeneratorStandard):
@ -59,7 +61,7 @@ class BulletinGeneratorExample(sco_bulletins_standard.BulletinGeneratorStandard)
assert format == "pdf" # garde fou
return [
Paragraph(
SU(
sco_pdf.SU(
"L'étudiant %(nomprenom)s a une moyenne générale de %(moy_gen)s"
% self.infos
),

View File

@ -28,9 +28,12 @@
"""Génération du bulletin en format JSON (beta, non completement testé)
"""
import datetime
import json
from notes_table import *
import sco_utils as scu
import notesdb as ndb
import scolars
import sco_formsemestre
import sco_groups
import sco_photos
@ -62,9 +65,9 @@ def make_json_formsemestre_bulletinetud(
)
if REQUEST:
REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE)
REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
return json.dumps(d, cls=ScoDocJSONEncoder, encoding=SCO_ENCODING)
return json.dumps(d, cls=scu.ScoDocJSONEncoder, encoding=scu.SCO_ENCODING)
# (fonction séparée: n'utilise pas formsemestre_bulletinetud_dict()
@ -119,14 +122,14 @@ def formsemestre_bulletinetud_published_dict(
etudid=etudid,
code_nip=etudinfo["code_nip"],
code_ine=etudinfo["code_ine"],
nom=quote_xml_attr(etudinfo["nom"]),
prenom=quote_xml_attr(etudinfo["prenom"]),
sexe=quote_xml_attr(etudinfo["sexe"]),
photo_url=quote_xml_attr(
nom=scu.quote_xml_attr(etudinfo["nom"]),
prenom=scu.quote_xml_attr(etudinfo["prenom"]),
sexe=scu.quote_xml_attr(etudinfo["sexe"]),
photo_url=scu.quote_xml_attr(
sco_photos.etud_photo_url(context, etudinfo, fast=True)
),
email=quote_xml_attr(etudinfo["email"]),
emailperso=quote_xml_attr(etudinfo["emailperso"]),
email=scu.quote_xml_attr(etudinfo["email"]),
emailperso=scu.quote_xml_attr(etudinfo["emailperso"]),
)
# Disponible pour publication ?
@ -150,7 +153,7 @@ def formsemestre_bulletinetud_published_dict(
ues = nt.get_ues()
modimpls = nt.get_modimpls()
nbetuds = len(nt.rangs)
mg = fmt_note(nt.get_etud_moy_gen(etudid))
mg = scu.fmt_note(nt.get_etud_moy_gen(etudid))
if (
nt.get_moduleimpls_attente()
or context.get_preference("bul_show_rangs", formsemestre_id) == 0
@ -168,9 +171,9 @@ def formsemestre_bulletinetud_published_dict(
d["note"] = dict(
value=mg,
min=fmt_note(nt.moy_min),
max=fmt_note(nt.moy_max),
moy=fmt_note(nt.moy_moy),
min=scu.fmt_note(nt.moy_min),
max=scu.fmt_note(nt.moy_max),
moy=scu.fmt_note(nt.moy_moy),
)
d["rang"] = dict(value=rang, ninscrits=nbetuds)
d["rang_group"] = []
@ -199,25 +202,27 @@ def formsemestre_bulletinetud_published_dict(
ects_txt = ""
u = dict(
id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
note=dict(
value=fmt_note(ue_status["cur_moy_ue"]),
min=fmt_note(ue["min"]),
max=fmt_note(ue["max"]),
value=scu.fmt_note(ue_status["cur_moy_ue"]),
min=scu.fmt_note(ue["min"]),
max=scu.fmt_note(ue["max"]),
),
rang=str(nt.ue_rangs[ue["ue_id"]][0][etudid]),
effectif=str(nt.ue_rangs[ue["ue_id"]][1]),
ects=ects_txt,
code_apogee=quote_xml_attr(ue["code_apogee"]),
code_apogee=scu.quote_xml_attr(ue["code_apogee"]),
)
d["ue"].append(u)
u["module"] = []
# Liste les modules de l'UE
ue_modimpls = [mod for mod in modimpls if mod["module"]["ue_id"] == ue["ue_id"]]
for modimpl in ue_modimpls:
mod_moy = fmt_note(nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid))
mod_moy = scu.fmt_note(
nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid)
)
if mod_moy == "NI": # ne mentionne pas les modules ou n'est pas inscrit
continue
mod = modimpl["module"]
@ -232,15 +237,15 @@ def formsemestre_bulletinetud_published_dict(
code=mod["code"],
coefficient=mod["coefficient"],
numero=mod["numero"],
titre=quote_xml_attr(mod["titre"]),
abbrev=quote_xml_attr(mod["abbrev"]),
titre=scu.quote_xml_attr(mod["titre"]),
abbrev=scu.quote_xml_attr(mod["abbrev"]),
# ects=ects, ects des modules maintenant inutilisés
note=dict(value=mod_moy),
code_apogee=quote_xml_attr(mod["code_apogee"]),
code_apogee=scu.quote_xml_attr(mod["code_apogee"]),
)
m["note"].update(modstat)
for k in ("min", "max", "moy"): # formatte toutes les notes
m["note"][k] = fmt_note(m["note"][k])
m["note"][k] = scu.fmt_note(m["note"][k])
u["module"].append(m)
if context.get_preference("bul_show_mod_rangs", formsemestre_id):
@ -258,19 +263,19 @@ def formsemestre_bulletinetud_published_dict(
val = e["notes"].get(etudid, {"value": "NP"})[
"value"
] # NA si etud demissionnaire
val = fmt_note(val, note_max=e["note_max"])
val = scu.fmt_note(val, note_max=e["note_max"])
m["evaluation"].append(
dict(
jour=DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=TimetoISO8601(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=TimetoISO8601(
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
evaluation_type=e["evaluation_type"],
description=quote_xml_attr(e["description"]),
description=scu.quote_xml_attr(e["description"]),
note=val,
)
)
@ -285,15 +290,17 @@ def formsemestre_bulletinetud_published_dict(
if e["evaluation_id"] not in complete_eval_ids:
m["evaluation"].append(
dict(
jour=DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=TimetoISO8601(
jour=ndb.DateDMYtoISO(
e["jour"], null_is_empty=True
),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=TimetoISO8601(
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
description=quote_xml_attr(e["description"]),
description=scu.quote_xml_attr(e["description"]),
incomplete="1",
)
)
@ -307,20 +314,18 @@ def formsemestre_bulletinetud_published_dict(
d["ue_capitalisee"].append(
dict(
id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
note=fmt_note(ue_status["moy"]),
coefficient_ue=fmt_note(ue_status["coef_ue"]),
date_capitalisation=DateDMYtoISO(ue_status["event_date"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
note=scu.fmt_note(ue_status["moy"]),
coefficient_ue=scu.fmt_note(ue_status["coef_ue"]),
date_capitalisation=ndb.DateDMYtoISO(ue_status["event_date"]),
ects=ects_txt,
)
)
# --- Absences
if context.get_preference("bul_show_abs", formsemestre_id):
debut_sem = DateDMYtoISO(sem["date_debut"])
fin_sem = DateDMYtoISO(sem["date_fin"])
AbsEtudSem = sco_abs.getAbsSemEtud(context, sem, etudid)
nbabs = AbsEtudSem.CountAbs()
nbabsjust = AbsEtudSem.CountAbsJust()
@ -339,7 +344,7 @@ def formsemestre_bulletinetud_published_dict(
format="xml",
show_uevalid=context.get_preference("bul_show_uevalid", formsemestre_id),
)
d["situation"] = quote_xml_attr(infos["situation"])
d["situation"] = scu.quote_xml_attr(infos["situation"])
if dpv:
decision = dpv["decisions"][0]
etat = decision["etat"]
@ -366,11 +371,11 @@ def formsemestre_bulletinetud_published_dict(
d["decision_ue"].append(
dict(
ue_id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
code=decision["decisions_ue"][ue_id]["code"],
ects=quote_xml_attr(ue["ects"] or ""),
ects=scu.quote_xml_attr(ue["ects"] or ""),
)
)
d["autorisation_inscription"] = []
@ -389,7 +394,10 @@ def formsemestre_bulletinetud_published_dict(
d["appreciation"] = []
for app in apprecs:
d["appreciation"].append(
dict(comment=quote_xml_attr(app["comment"]), date=DateDMYtoISO(app["date"]))
dict(
comment=scu.quote_xml_attr(app["comment"]),
date=ndb.DateDMYtoISO(app["date"]),
)
)
#

View File

@ -37,8 +37,13 @@
import traceback, re
import sco_utils as scu
from sco_permissions import ScoEtudInscrit
import sco_formsemestre
from sco_pdf import *
import sco_pdf
from sco_pdf import Color, Paragraph, Spacer, Table
from sco_pdf import blue, cm, mm
from sco_pdf import SU
import sco_preferences
from notes_log import log
import sco_bulletins_generator
@ -81,9 +86,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
def bul_table_html(self):
"""Génère la table centrale du bulletin de notes: chaine HTML"""
format = "html"
I = self.infos
authuser = self.authuser
formsemestre_id = self.infos["formsemestre_id"]
context = self.context
@ -98,8 +101,8 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
bgcolor = "background-color: rgb(255,255,240)"
linktmpl = '<span onclick="toggle_vis_ue(this);" class="toggle_ue">%s</span>'
minuslink = linktmpl % icontag("minus_img", border="0", alt="-")
pluslink = linktmpl % icontag("plus_img", border="0", alt="+")
minuslink = linktmpl % scu.icontag("minus_img", border="0", alt="-")
pluslink = linktmpl % scu.icontag("plus_img", border="0", alt="+")
H = ['<table class="notes_bulletin" style="background-color: %s;">' % bgcolor]
@ -131,8 +134,8 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
if context.get_preference("bul_show_minmax_mod", formsemestre_id):
rang_minmax = '%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>' % (
mod["mod_rang_txt"],
fmt_note(mod["stats"]["min"]),
fmt_note(mod["stats"]["max"]),
scu.fmt_note(mod["stats"]["min"]),
scu.fmt_note(mod["stats"]["max"]),
)
else:
rang_minmax = mod["mod_rang_txt"] # vide si pas option rang
@ -209,9 +212,9 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
moy_txt = (
'%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>'
% (
fmt_note(ue["cur_moy_ue_txt"]),
fmt_note(ue["min"]),
fmt_note(ue["max"]),
scu.fmt_note(ue["cur_moy_ue_txt"]),
scu.fmt_note(ue["min"]),
scu.fmt_note(ue["max"]),
)
)
else:
@ -441,7 +444,6 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
S = BulTableStyle()
P = [] # elems pour gen. pdf
formsemestre_id = I["formsemestre_id"]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
bul_show_abs_modules = context.get_preference(
"bul_show_abs_modules", formsemestre_id
)
@ -460,7 +462,7 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
]
if bul_show_abs_modules:
t.append("Abs (J. / N.J.)")
P.append(bold_paras(t))
P.append(sco_pdf.bold_paras(t))
def list_modules(ue_modules, ue_type=None):
"ajoute les lignes decrivant les modules d'une UE, avec eventuellement les évaluations de chacun"
@ -471,8 +473,8 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
if context.get_preference("bul_show_minmax_mod", formsemestre_id):
rang_minmax = '%s <font size="8">[%s, %s]</font>' % (
mod["mod_rang_txt"],
fmt_note(mod["stats"]["min"]),
fmt_note(mod["stats"]["max"]),
scu.fmt_note(mod["stats"]["min"]),
scu.fmt_note(mod["stats"]["max"]),
)
else:
rang_minmax = mod["mod_rang_txt"] # vide si pas option rang
@ -504,7 +506,7 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
t = [ue["acronyme"], ue["moy_ue_txt"], ue_descr, "", coef_ue]
if bul_show_abs_modules:
t.append("")
P.append(bold_paras(t))
P.append(sco_pdf.bold_paras(t))
coef_ue = ""
ue_descr = "(en cours, non prise en compte)"
S.ueline()
@ -523,7 +525,7 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
t = [ue["acronyme"], moy_txt, ue_descr, "", coef_ue]
if bul_show_abs_modules:
t.append("")
P.append(bold_paras(t))
P.append(sco_pdf.bold_paras(t))
S.ueline()
list_modules(ue["modules"], ue_type=ue_type)

View File

@ -50,13 +50,21 @@ Pour définir un nouveau type de bulletin:
Chaque semestre peut si nécessaire utiliser un type de bulletin différent.
"""
import htmlutils, time
import pprint, traceback
import htmlutils
import time
import pprint
import traceback
import re
import cStringIO
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from notes_table import *
import VERSION
import sco_utils as scu
from notes_log import log
import sco_formsemestre
import sco_bulletins
from sco_pdf import *
import sco_pdf
import os
@ -84,10 +92,10 @@ def pdfassemblebulletins(
report = cStringIO.StringIO() # in-memory document, no disk file
document = BaseDocTemplate(report)
document.addPageTemplates(
ScolarsPageTemplate(
sco_pdf.ScolarsPageTemplate(
document,
context=context,
author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION),
author="%s %s (E. Viennet)" % (VERSION.SCONAME, VERSION.SCOVERSION),
title="Bulletin %s" % bul_title,
subject="Bulletin de note",
server_name=server_name,
@ -117,7 +125,7 @@ def process_field(
If format = 'html', replaces <para> by <p>. HTML does not allow logos.
"""
try:
text = (field or "") % WrapDict(
text = (field or "") % scu.WrapDict(
cdict
) # note that None values are mapped to empty strings
except:
@ -135,9 +143,9 @@ def process_field(
return text
# --- PDF format:
# handle logos:
image_dir = SCODOC_LOGOS_DIR + "/logos_" + context.DeptId() + "/"
image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + context.DeptId() + "/"
if not os.path.exists(image_dir):
image_dir = SCODOC_LOGOS_DIR + "/" # use global logos
image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos
text = re.sub(
r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text
) # remove forbidden src attribute
@ -150,7 +158,7 @@ def process_field(
# tentatives d'acceder à d'autres fichiers !
# log('field: %s' % (text))
return makeParas(text, style, suppress_empty=suppress_empty_pars)
return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars)
def get_formsemestre_bulletins_pdf(
@ -180,7 +188,7 @@ def get_formsemestre_bulletins_pdf(
)
fragments += frag
filigrannes[i] = filigranne
bookmarks[i] = suppress_accents(nt.get_sexnom(etudid))
bookmarks[i] = scu.suppress_accents(nt.get_sexnom(etudid))
i = i + 1
#
infos = {"DeptName": context.get_preference("DeptName", formsemestre_id)}
@ -189,7 +197,7 @@ def get_formsemestre_bulletins_pdf(
else:
server_name = ""
try:
PDFLOCK.acquire()
sco_pdf.PDFLOCK.acquire()
pdfdoc = pdfassemblebulletins(
formsemestre_id,
fragments,
@ -201,11 +209,11 @@ def get_formsemestre_bulletins_pdf(
context=context,
)
finally:
PDFLOCK.release()
sco_pdf.PDFLOCK.release()
#
dt = time.strftime("%Y-%m-%d")
filename = "bul-%s-%s.pdf" % (sem["titre_num"], dt)
filename = unescape_html(filename).replace(" ", "_").replace("&", "")
filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "")
# fill cache
context._getNotesCache().store_bulletins_pdf(
formsemestre_id, version, filename, pdfdoc
@ -239,7 +247,7 @@ def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
else:
server_name = ""
try:
PDFLOCK.acquire()
sco_pdf.PDFLOCK.acquire()
pdfdoc = pdfassemblebulletins(
None,
fragments,
@ -251,11 +259,11 @@ def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
context=context,
)
finally:
PDFLOCK.release()
sco_pdf.PDFLOCK.release()
#
filename = "bul-%s" % (etud["nomprenom"])
filename = (
unescape_html(filename).replace(" ", "_").replace("&", "").replace(".", "")
scu.unescape_html(filename).replace(" ", "_").replace("&", "").replace(".", "")
+ ".pdf"
)

View File

@ -53,53 +53,53 @@ Lien sur Scolarite/edit_preferences (sans formsemestre_id)
et sur page "réglages bulletin" (avec formsemestre_id)
"""
import os
# import os
def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None):
"""Change pdf signature"""
filename = _get_sig_existing_filename(
context, side, formsemestre_id=formsemestre_id
)
if side == "left":
sidetxt = "gauche"
elif side == "right":
sidetxt = "droite"
else:
raise ValueError("invalid value for 'side' parameter")
signatureloc = get_bul_sig_img()
H = [
self.sco_header(REQUEST, page_title="Changement de signature"),
"""<h2>Changement de la signature bulletin de %(sidetxt)s</h2>
"""
% (sidetxt,),
]
"<p>Photo actuelle (%(signatureloc)s): "
# def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None):
# """Change pdf signature"""
# filename = _get_sig_existing_filename(
# context, side, formsemestre_id=formsemestre_id
# )
# if side == "left":
# sidetxt = "gauche"
# elif side == "right":
# sidetxt = "droite"
# else:
# raise ValueError("invalid value for 'side' parameter")
# signatureloc = get_bul_sig_img()
# H = [
# self.sco_header(REQUEST, page_title="Changement de signature"),
# """<h2>Changement de la signature bulletin de %(sidetxt)s</h2>
# """
# % (sidetxt,),
# ]
# "<p>Photo actuelle (%(signatureloc)s): "
def get_bul_sig_img(context, side, formsemestre_id=None):
"send back signature image data"
# slow, not cached, used for unfrequent access (do not bypass python)
# def get_bul_sig_img(context, side, formsemestre_id=None):
# "send back signature image data"
# # slow, not cached, used for unfrequent access (do not bypass python)
def _sig_filename(context, side, formsemestre_id=None):
if not side in ("left", "right"):
raise ValueError("side must be left or right")
dirs = [SCODOC_LOGOS_DIR, context.DeptId()]
if formsemestre_id:
dirs.append(formsemestre_id)
dirs.append("bul_sig_{}".format(side))
return os.path.join(*dirs)
# def _sig_filename(context, side, formsemestre_id=None):
# if not side in ("left", "right"):
# raise ValueError("side must be left or right")
# dirs = [SCODOC_LOGOS_DIR, context.DeptId()]
# if formsemestre_id:
# dirs.append(formsemestre_id)
# dirs.append("bul_sig_{}".format(side))
# return os.path.join(*dirs)
def _get_sig_existing_filename(context, side, formsemestre_id=None):
"full path to signature to use, or None if no signature available"
if formsemestre_id:
filename = _sig_filename(context, side, formsemestre_id=formsemestre_id)
if os.path.exists(filename):
return filename
filename = _sig_filename(context, side)
if os.path.exists(filename):
return filename
else:
return None
# def _get_sig_existing_filename(context, side, formsemestre_id=None):
# "full path to signature to use, or None if no signature available"
# if formsemestre_id:
# filename = _sig_filename(context, side, formsemestre_id=formsemestre_id)
# if os.path.exists(filename):
# return filename
# filename = _sig_filename(context, side)
# if os.path.exists(filename):
# return filename
# else:
# return None

View File

@ -34,8 +34,12 @@ E. Viennet, juillet 2011
"""
import traceback
import sco_utils as scu
import sco_formsemestre
from sco_pdf import *
import sco_pdf
from sco_pdf import blue, cm, mm
from sco_pdf import Color, Paragraph, Spacer, Table
import sco_preferences
from notes_log import log
@ -72,7 +76,6 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
I = self.infos
context = self.context
formsemestre_id = I["formsemestre_id"]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
prefs = context.get_preferences(formsemestre_id)
P = [] # elems pour générer table avec gen_table (liste de dicts)
@ -134,7 +137,7 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
total_pt_ue_v = (
ue["ue_status"]["cur_moy_ue"] * ue["ue_status"]["coef_ue"]
)
total_pt_ue = fmt_note(total_pt_ue_v)
total_pt_ue = scu.fmt_note(total_pt_ue_v)
# log('total_pt_ue = %s' % total_pt_ue)
except:
# log("ue['ue_status']['cur_moy_ue'] = %s" % ue['ue_status']['cur_moy_ue'] )
@ -212,7 +215,6 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
ue_descr = "(en cours, non prise en compte)"
ue_type = "cur"
rowstyle = " bul_ucac_row_ue_cur"
# --- UE ordinaire
pt = list_ue(ue, ue_descr)
@ -228,8 +230,8 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
{
"code_ue": "Total",
"moyenne_ue": I["moy_gen"],
"coef": fmt_note(sum_coef_ues),
"total": fmt_note(sum_pt_sem),
"coef": scu.fmt_note(sum_coef_ues),
"total": scu.fmt_note(sum_pt_sem),
"_code_ue_colspan": 4,
"_css_row_class": "bul_ucac_row_total",
"_pdf_row_markup": ["b"],

View File

@ -37,7 +37,14 @@ Malheureusement, le code de génération JSON et XML sont séparés, ce qui est
Je propose de considérer le XMl comme "deprecated" et de ne plus le modifier, sauf nécessité.
"""
from notes_table import *
import datetime
import jaxml
import sco_utils as scu
import notesdb as ndb
from notes_log import log
import scolars
import sco_codes_parcours
import sco_formsemestre
import sco_groups
import sco_photos
@ -62,9 +69,9 @@ def make_xml_formsemestre_bulletinetud(
"bulletin au format XML"
log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid))
if REQUEST:
REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE)
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
if not doc:
doc = jaxml.XML_document(encoding=SCO_ENCODING)
doc = jaxml.XML_document(encoding=scu.SCO_ENCODING)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["bul_hide_xml"] == "0" or force_publishing:
@ -98,12 +105,12 @@ def make_xml_formsemestre_bulletinetud(
etudid=etudid,
code_nip=etudinfo["code_nip"],
code_ine=etudinfo["code_ine"],
nom=quote_xml_attr(etudinfo["nom"]),
prenom=quote_xml_attr(etudinfo["prenom"]),
sexe=quote_xml_attr(etudinfo["sexe"]),
photo_url=quote_xml_attr(sco_photos.etud_photo_url(context, etudinfo)),
email=quote_xml_attr(etudinfo["email"]),
emailperso=quote_xml_attr(etudinfo["emailperso"]),
nom=scu.quote_xml_attr(etudinfo["nom"]),
prenom=scu.quote_xml_attr(etudinfo["prenom"]),
sexe=scu.quote_xml_attr(etudinfo["sexe"]),
photo_url=scu.quote_xml_attr(sco_photos.etud_photo_url(context, etudinfo)),
email=scu.quote_xml_attr(etudinfo["email"]),
emailperso=scu.quote_xml_attr(etudinfo["emailperso"]),
)
doc._pop()
@ -128,7 +135,7 @@ def make_xml_formsemestre_bulletinetud(
ues = nt.get_ues()
modimpls = nt.get_modimpls()
nbetuds = len(nt.rangs)
mg = fmt_note(nt.get_etud_moy_gen(etudid))
mg = scu.fmt_note(nt.get_etud_moy_gen(etudid))
if (
nt.get_moduleimpls_attente()
or context.get_preference("bul_show_rangs", formsemestre_id) == 0
@ -147,9 +154,9 @@ def make_xml_formsemestre_bulletinetud(
doc._push()
doc.note(
value=mg,
min=fmt_note(nt.moy_min),
max=fmt_note(nt.moy_max),
moy=fmt_note(nt.moy_moy),
min=scu.fmt_note(nt.moy_min),
max=scu.fmt_note(nt.moy_max),
moy=scu.fmt_note(nt.moy_moy),
)
doc._pop()
doc._push()
@ -177,17 +184,21 @@ def make_xml_formsemestre_bulletinetud(
doc._push()
doc.ue(
id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
code_apogee=quote_xml_attr(ue["code_apogee"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
code_apogee=scu.quote_xml_attr(ue["code_apogee"]),
)
doc._push()
if ue["type"] != UE_SPORT:
if ue["type"] != sco_codes_parcours.UE_SPORT:
v = ue_status["cur_moy_ue"]
else:
v = nt.bonus[etudid]
doc.note(value=fmt_note(v), min=fmt_note(ue["min"]), max=fmt_note(ue["max"]))
doc.note(
value=scu.fmt_note(v),
min=scu.fmt_note(ue["min"]),
max=scu.fmt_note(ue["max"]),
)
doc._pop()
try:
ects_txt = str(int(ue["ects"]))
@ -205,7 +216,9 @@ def make_xml_formsemestre_bulletinetud(
# Liste les modules de l'UE
ue_modimpls = [mod for mod in modimpls if mod["module"]["ue_id"] == ue["ue_id"]]
for modimpl in ue_modimpls:
mod_moy = fmt_note(nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid))
mod_moy = scu.fmt_note(
nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid)
)
if mod_moy == "NI": # ne mentionne pas les modules ou n'est pas inscrit
continue
mod = modimpl["module"]
@ -219,18 +232,18 @@ def make_xml_formsemestre_bulletinetud(
code=mod["code"],
coefficient=mod["coefficient"],
numero=mod["numero"],
titre=quote_xml_attr(mod["titre"]),
abbrev=quote_xml_attr(mod["abbrev"]),
code_apogee=quote_xml_attr(mod["code_apogee"])
titre=scu.quote_xml_attr(mod["titre"]),
abbrev=scu.quote_xml_attr(mod["abbrev"]),
code_apogee=scu.quote_xml_attr(mod["code_apogee"])
# ects=ects ects des modules maintenant inutilisés
)
doc._push()
modstat = nt.get_mod_stats(modimpl["moduleimpl_id"])
doc.note(
value=mod_moy,
min=fmt_note(modstat["min"]),
max=fmt_note(modstat["max"]),
moy=fmt_note(modstat["moy"]),
min=scu.fmt_note(modstat["min"]),
max=scu.fmt_note(modstat["max"]),
moy=scu.fmt_note(modstat["moy"]),
)
doc._pop()
if context.get_preference("bul_show_mod_rangs", formsemestre_id):
@ -247,14 +260,16 @@ def make_xml_formsemestre_bulletinetud(
if int(e["visibulletin"]) == 1 or version == "long":
doc._push()
doc.evaluation(
jour=DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=TimetoISO8601(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=TimetoISO8601(e["heure_fin"], null_is_empty=True),
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
evaluation_type=e["evaluation_type"],
description=quote_xml_attr(e["description"]),
description=scu.quote_xml_attr(e["description"]),
note_max_origin=e[
"note_max"
], # notes envoyées sur 20, ceci juste pour garder trace
@ -262,7 +277,7 @@ def make_xml_formsemestre_bulletinetud(
val = e["notes"].get(etudid, {"value": "NP"})[
"value"
] # NA si etud demissionnaire
val = fmt_note(val, note_max=e["note_max"])
val = scu.fmt_note(val, note_max=e["note_max"])
doc.note(value=val)
doc._pop()
# Evaluations incomplètes ou futures:
@ -276,15 +291,15 @@ def make_xml_formsemestre_bulletinetud(
if e["evaluation_id"] not in complete_eval_ids:
doc._push()
doc.evaluation(
jour=DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=TimetoISO8601(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=TimetoISO8601(
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
description=quote_xml_attr(e["description"]),
description=scu.quote_xml_attr(e["description"]),
incomplete="1",
note_max_origin=e[
"note_max"
@ -302,27 +317,25 @@ def make_xml_formsemestre_bulletinetud(
doc._push()
doc.ue_capitalisee(
id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
)
doc._push()
doc.note(value=fmt_note(ue_status["moy"]))
doc.note(value=scu.fmt_note(ue_status["moy"]))
doc._pop()
doc._push()
doc.ects(value=ects_txt)
doc._pop()
doc._push()
doc.coefficient_ue(value=fmt_note(ue_status["coef_ue"]))
doc.coefficient_ue(value=scu.fmt_note(ue_status["coef_ue"]))
doc._pop()
doc._push()
doc.date_capitalisation(value=DateDMYtoISO(ue_status["event_date"]))
doc.date_capitalisation(value=ndb.DateDMYtoISO(ue_status["event_date"]))
doc._pop()
doc._pop()
# --- Absences
if context.get_preference("bul_show_abs", formsemestre_id):
debut_sem = DateDMYtoISO(sem["date_debut"])
fin_sem = DateDMYtoISO(sem["date_fin"])
AbsEtudSem = sco_abs.getAbsSemEtud(context, sem, etudid)
nbabs = AbsEtudSem.CountAbs()
nbabsjust = AbsEtudSem.CountAbsJust()
@ -341,7 +354,7 @@ def make_xml_formsemestre_bulletinetud(
format="xml",
show_uevalid=context.get_preference("bul_show_uevalid", formsemestre_id),
)
doc.situation(quote_xml_attr(infos["situation"]))
doc.situation(scu.quote_xml_attr(infos["situation"]))
if dpv:
decision = dpv["decisions"][0]
etat = decision["etat"]
@ -375,9 +388,9 @@ def make_xml_formsemestre_bulletinetud(
doc._push()
doc.decision_ue(
ue_id=ue["ue_id"],
numero=quote_xml_attr(ue["numero"]),
acronyme=quote_xml_attr(ue["acronyme"]),
titre=quote_xml_attr(ue["titre"]),
numero=scu.quote_xml_attr(ue["numero"]),
acronyme=scu.quote_xml_attr(ue["acronyme"]),
titre=scu.quote_xml_attr(ue["titre"]),
code=decision["decisions_ue"][ue_id]["code"],
)
doc._pop()
@ -396,5 +409,7 @@ def make_xml_formsemestre_bulletinetud(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
)
for app in apprecs:
doc.appreciation(quote_xml_attr(app["comment"]), date=DateDMYtoISO(app["date"]))
doc.appreciation(
scu.quote_xml_attr(app["comment"]), date=ndb.DateDMYtoISO(app["date"])
)
return doc