forked from ScoDoc/ScoDoc
bulletins XML sans jaxml
This commit is contained in:
parent
0afab38f6e
commit
cdc1969520
@ -895,8 +895,7 @@ def do_formsemestre_bulletinetud(
|
||||
et filigranne est un message à placer en "filigranne" (eg "Provisoire").
|
||||
"""
|
||||
if format == "xml":
|
||||
bul = repr(
|
||||
sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
||||
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
||||
context,
|
||||
formsemestre_id,
|
||||
etudid,
|
||||
@ -905,7 +904,7 @@ def do_formsemestre_bulletinetud(
|
||||
force_publishing=force_publishing,
|
||||
version=version,
|
||||
)
|
||||
)
|
||||
|
||||
return bul, ""
|
||||
|
||||
elif format == "json":
|
||||
|
@ -29,16 +29,20 @@
|
||||
|
||||
|
||||
Note: la structure de ce XML est issue de (mauvais) choix historiques
|
||||
et ne peut pas être modifiée car d'autres logiciels l'utilisent (portail publication bulletins etudiants).
|
||||
et ne peut pas être modifiée car d'autres logiciels l'utilisent (portail publication
|
||||
bulletins etudiants).
|
||||
|
||||
Je recommande d'utiliser la version JSON.
|
||||
Malheureusement, le code de génération JSON et XML sont séparés, ce qui est absurde et complique la maintenance (si on ajoute des informations aux bulletins).
|
||||
Malheureusement, le code de génération JSON et XML sont séparés, ce qui est absurde et
|
||||
complique la maintenance (si on ajoute des informations aux bulletins).
|
||||
|
||||
Je propose de considérer le XMl comme "deprecated" et de ne plus le modifier, sauf nécessité.
|
||||
"""
|
||||
|
||||
# revu en juillet 21 pour utiliser ElementTree au lieu de jaxml
|
||||
|
||||
import datetime
|
||||
import jaxml
|
||||
from xml.etree import ElementTree
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -53,6 +57,7 @@ from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_photos
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_xml
|
||||
|
||||
# -------- Bulletin en XML
|
||||
# (fonction séparée: n'utilise pas formsemestre_bulletinetud_dict()
|
||||
@ -75,14 +80,12 @@ def make_xml_formsemestre_bulletinetud(
|
||||
log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid))
|
||||
if REQUEST:
|
||||
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
||||
if not doc:
|
||||
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:
|
||||
published = 1
|
||||
published = "1"
|
||||
else:
|
||||
published = 0
|
||||
published = "0"
|
||||
if xml_nodate:
|
||||
docdate = ""
|
||||
else:
|
||||
@ -95,18 +98,22 @@ def make_xml_formsemestre_bulletinetud(
|
||||
"publie": published,
|
||||
}
|
||||
if sem["etapes"]:
|
||||
el["etape_apo"] = sem["etapes"][0] or ""
|
||||
el["etape_apo"] = str(sem["etapes"][0]) or ""
|
||||
n = 2
|
||||
for et in sem["etapes"][1:]:
|
||||
el["etape_apo" + str(n)] = et or ""
|
||||
el["etape_apo" + str(n)] = str(et) or ""
|
||||
n += 1
|
||||
|
||||
doc.bulletinetud(**el)
|
||||
|
||||
x = Element("bulletinetud", **el)
|
||||
if doc:
|
||||
doc.append(x)
|
||||
else:
|
||||
doc = x
|
||||
# Infos sur l'etudiant
|
||||
etudinfo = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
|
||||
doc._push()
|
||||
doc.etudiant(
|
||||
doc.append(
|
||||
Element(
|
||||
"etudiant",
|
||||
etudid=etudid,
|
||||
code_nip=etudinfo["code_nip"],
|
||||
code_ine=etudinfo["code_ine"],
|
||||
@ -118,7 +125,7 @@ def make_xml_formsemestre_bulletinetud(
|
||||
email=scu.quote_xml_attr(etudinfo["email"]),
|
||||
emailperso=scu.quote_xml_attr(etudinfo["emailperso"]),
|
||||
)
|
||||
doc._pop()
|
||||
)
|
||||
|
||||
# Disponible pour publication ?
|
||||
if not published:
|
||||
@ -158,68 +165,61 @@ def make_xml_formsemestre_bulletinetud(
|
||||
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
|
||||
)
|
||||
|
||||
doc._push()
|
||||
doc.note(
|
||||
doc.append(
|
||||
Element(
|
||||
"note",
|
||||
value=mg,
|
||||
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()
|
||||
doc.rang(value=rang, ninscrits=nbetuds)
|
||||
doc._pop()
|
||||
)
|
||||
doc.append(Element("rang", value=str(rang), ninscrits=str(nbetuds)))
|
||||
|
||||
if rang_gr:
|
||||
for partition in partitions:
|
||||
doc._push()
|
||||
doc.rang_group(
|
||||
doc.append(
|
||||
Element(
|
||||
"rang_group",
|
||||
group_type=partition["partition_name"],
|
||||
group_name=gr_name[partition["partition_id"]],
|
||||
value=rang_gr[partition["partition_id"]],
|
||||
ninscrits=ninscrits_gr[partition["partition_id"]],
|
||||
value=str(rang_gr[partition["partition_id"]]),
|
||||
ninscrits=str(ninscrits_gr[partition["partition_id"]]),
|
||||
)
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.note_max(value=20) # notes toujours sur 20
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.bonus_sport_culture(value=nt.bonus[etudid])
|
||||
doc._pop()
|
||||
)
|
||||
doc.append(Element("note_max", value="20")) # notes toujours sur 20
|
||||
doc.append(Element("bonus_sport_culture", value=str(nt.bonus[etudid])))
|
||||
# Liste les UE / modules /evals
|
||||
for ue in ues:
|
||||
ue_status = nt.get_etud_ue_status(etudid, ue["ue_id"])
|
||||
doc._push()
|
||||
doc.ue(
|
||||
x_ue = Element(
|
||||
"ue",
|
||||
id=ue["ue_id"],
|
||||
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()
|
||||
doc.append(x_ue)
|
||||
if ue["type"] != sco_codes_parcours.UE_SPORT:
|
||||
v = ue_status["cur_moy_ue"]
|
||||
else:
|
||||
v = nt.bonus[etudid]
|
||||
doc.note(
|
||||
x_ue.append(
|
||||
Element(
|
||||
"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"]))
|
||||
except:
|
||||
except (ValueError, TypeError):
|
||||
ects_txt = ""
|
||||
doc._push()
|
||||
doc.ects(value=ects_txt)
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.rang(value=str(nt.ue_rangs[ue["ue_id"]][0][etudid]))
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.effectif(value=str(nt.ue_rangs[ue["ue_id"]][1]))
|
||||
doc._pop()
|
||||
x_ue.append(Element("ects", value=ects_txt))
|
||||
x_ue.append(Element("rang", value=str(nt.ue_rangs[ue["ue_id"]][0][etudid])))
|
||||
x_ue.append(Element("effectif", value=str(nt.ue_rangs[ue["ue_id"]][1])))
|
||||
# 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:
|
||||
@ -229,46 +229,53 @@ def make_xml_formsemestre_bulletinetud(
|
||||
if mod_moy == "NI": # ne mentionne pas les modules ou n'est pas inscrit
|
||||
continue
|
||||
mod = modimpl["module"]
|
||||
doc._push()
|
||||
# if mod['ects'] is None:
|
||||
# ects = ''
|
||||
# else:
|
||||
# ects = str(mod['ects'])
|
||||
doc.module(
|
||||
x_mod = Element(
|
||||
"module",
|
||||
id=modimpl["moduleimpl_id"],
|
||||
code=mod["code"],
|
||||
coefficient=mod["coefficient"],
|
||||
numero=mod["numero"],
|
||||
coefficient=str(mod["coefficient"]),
|
||||
numero=str(mod["numero"]),
|
||||
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()
|
||||
x_ue.append(x_mod)
|
||||
modstat = nt.get_mod_stats(modimpl["moduleimpl_id"])
|
||||
doc.note(
|
||||
x_mod.append(
|
||||
Element(
|
||||
"note",
|
||||
value=mod_moy,
|
||||
min=scu.fmt_note(modstat["min"]),
|
||||
max=scu.fmt_note(modstat["max"]),
|
||||
moy=scu.fmt_note(modstat["moy"]),
|
||||
)
|
||||
doc._pop()
|
||||
)
|
||||
if sco_preferences.get_preference(
|
||||
context, "bul_show_mod_rangs", formsemestre_id
|
||||
):
|
||||
doc._push()
|
||||
doc.rang(value=nt.mod_rangs[modimpl["moduleimpl_id"]][0][etudid])
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.effectif(value=nt.mod_rangs[modimpl["moduleimpl_id"]][1])
|
||||
doc._pop()
|
||||
x_mod.append(
|
||||
Element(
|
||||
"rang",
|
||||
value=str(nt.mod_rangs[modimpl["moduleimpl_id"]][0][etudid]),
|
||||
)
|
||||
)
|
||||
x_mod.append(
|
||||
Element(
|
||||
"effectif", value=str(nt.mod_rangs[modimpl["moduleimpl_id"]][1])
|
||||
)
|
||||
)
|
||||
# --- notes de chaque eval:
|
||||
evals = nt.get_evals_in_mod(modimpl["moduleimpl_id"])
|
||||
if version != "short":
|
||||
for e in evals:
|
||||
if int(e["visibulletin"]) == 1 or version == "long":
|
||||
doc._push()
|
||||
doc.evaluation(
|
||||
x_eval = Element(
|
||||
"evaluation",
|
||||
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
|
||||
heure_debut=ndb.TimetoISO8601(
|
||||
e["heure_debut"], null_is_empty=True
|
||||
@ -276,19 +283,18 @@ def make_xml_formsemestre_bulletinetud(
|
||||
heure_fin=ndb.TimetoISO8601(
|
||||
e["heure_fin"], null_is_empty=True
|
||||
),
|
||||
coefficient=e["coefficient"],
|
||||
evaluation_type=e["evaluation_type"],
|
||||
coefficient=str(e["coefficient"]),
|
||||
evaluation_type=str(e["evaluation_type"]),
|
||||
description=scu.quote_xml_attr(e["description"]),
|
||||
note_max_origin=e[
|
||||
"note_max"
|
||||
], # notes envoyées sur 20, ceci juste pour garder trace
|
||||
# notes envoyées sur 20, ceci juste pour garder trace:
|
||||
note_max_origin=str(e["note_max"]),
|
||||
)
|
||||
x_mod.append(x_eval)
|
||||
val = e["notes"].get(etudid, {"value": "NP"})[
|
||||
"value"
|
||||
] # NA si etud demissionnaire
|
||||
val = scu.fmt_note(val, note_max=e["note_max"])
|
||||
doc.note(value=val)
|
||||
doc._pop()
|
||||
x_eval.append(Element("note", value=val))
|
||||
# Evaluations incomplètes ou futures:
|
||||
complete_eval_ids = set([e["evaluation_id"] for e in evals])
|
||||
if sco_preferences.get_preference(
|
||||
@ -300,8 +306,8 @@ def make_xml_formsemestre_bulletinetud(
|
||||
all_evals.reverse() # plus ancienne d'abord
|
||||
for e in all_evals:
|
||||
if e["evaluation_id"] not in complete_eval_ids:
|
||||
doc._push()
|
||||
doc.evaluation(
|
||||
x_eval = Element(
|
||||
"evaluation",
|
||||
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
|
||||
heure_debut=ndb.TimetoISO8601(
|
||||
e["heure_debut"], null_is_empty=True
|
||||
@ -309,50 +315,45 @@ def make_xml_formsemestre_bulletinetud(
|
||||
heure_fin=ndb.TimetoISO8601(
|
||||
e["heure_fin"], null_is_empty=True
|
||||
),
|
||||
coefficient=e["coefficient"],
|
||||
coefficient=str(e["coefficient"]),
|
||||
description=scu.quote_xml_attr(e["description"]),
|
||||
incomplete="1",
|
||||
note_max_origin=e[
|
||||
"note_max"
|
||||
], # notes envoyées sur 20, ceci juste pour garder trace
|
||||
# notes envoyées sur 20, ceci juste pour garder trace:
|
||||
note_max_origin=e["note_max"],
|
||||
)
|
||||
doc._pop()
|
||||
doc._pop()
|
||||
doc._pop()
|
||||
x_mod.append(x_eval)
|
||||
# UE capitalisee (listee seulement si meilleure que l'UE courante)
|
||||
if ue_status["is_capitalized"]:
|
||||
try:
|
||||
ects_txt = str(int(ue_status["ue"].get("ects", "")))
|
||||
except:
|
||||
except (ValueError, TypeError):
|
||||
ects_txt = ""
|
||||
doc._push()
|
||||
doc.ue_capitalisee(
|
||||
x_ue = Element(
|
||||
"ue_capitalisee",
|
||||
id=ue["ue_id"],
|
||||
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=scu.fmt_note(ue_status["moy"]))
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.ects(value=ects_txt)
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.coefficient_ue(value=scu.fmt_note(ue_status["coef_ue"]))
|
||||
doc._pop()
|
||||
doc._push()
|
||||
doc.date_capitalisation(value=ndb.DateDMYtoISO(ue_status["event_date"]))
|
||||
doc._pop()
|
||||
doc._pop()
|
||||
doc.append(x_ue)
|
||||
x_ue.append(Element("note", value=scu.fmt_note(ue_status["moy"])))
|
||||
x_ue.append(Element("ects", value=ects_txt))
|
||||
x_ue.append(
|
||||
Element("coefficient_ue", value=scu.fmt_note(ue_status["coef_ue"]))
|
||||
)
|
||||
x_ue.append(
|
||||
Element(
|
||||
"date_capitalisation",
|
||||
value=ndb.DateDMYtoISO(ue_status["event_date"]),
|
||||
)
|
||||
)
|
||||
|
||||
# --- Absences
|
||||
if sco_preferences.get_preference(context, "bul_show_abs", formsemestre_id):
|
||||
AbsEtudSem = sco_abs.getAbsSemEtud(context, sem, etudid)
|
||||
nbabs = AbsEtudSem.CountAbs()
|
||||
nbabsjust = AbsEtudSem.CountAbsJust()
|
||||
doc._push()
|
||||
doc.absences(nbabs=nbabs, nbabsjust=nbabsjust)
|
||||
doc._pop()
|
||||
abs_sem_etud = sco_abs.getAbsSemEtud(context, sem, etudid)
|
||||
nbabs = abs_sem_etud.CountAbs()
|
||||
nbabsjust = abs_sem_etud.CountAbsJust()
|
||||
doc.append(Element("absences", nbabs=nbabs, nbabsjust=nbabsjust))
|
||||
# --- Decision Jury
|
||||
if (
|
||||
sco_preferences.get_preference(context, "bul_show_decision", formsemestre_id)
|
||||
@ -367,7 +368,9 @@ def make_xml_formsemestre_bulletinetud(
|
||||
context, "bul_show_uevalid", formsemestre_id
|
||||
),
|
||||
)
|
||||
doc.situation(scu.quote_xml_attr(infos["situation"]))
|
||||
x_situation = Element("situation")
|
||||
x_situation.text = scu.quote_xml_attr(infos["situation"])
|
||||
doc.append(x_situation)
|
||||
if dpv:
|
||||
decision = dpv["decisions"][0]
|
||||
etat = decision["etat"]
|
||||
@ -375,54 +378,58 @@ def make_xml_formsemestre_bulletinetud(
|
||||
code = decision["decision_sem"]["code"]
|
||||
else:
|
||||
code = ""
|
||||
doc._push()
|
||||
|
||||
if (
|
||||
decision["decision_sem"]
|
||||
and "compense_formsemestre_id" in decision["decision_sem"]
|
||||
):
|
||||
doc.decision(
|
||||
doc.append(
|
||||
Element(
|
||||
"decision",
|
||||
code=code,
|
||||
etat=etat,
|
||||
etat=str(etat),
|
||||
compense_formsemestre_id=decision["decision_sem"][
|
||||
"compense_formsemestre_id"
|
||||
],
|
||||
)
|
||||
)
|
||||
else:
|
||||
doc.decision(code=code, etat=etat)
|
||||
|
||||
doc._pop()
|
||||
doc.append(Element("decision", code=code, etat=str(etat)))
|
||||
|
||||
if decision[
|
||||
"decisions_ue"
|
||||
]: # and sco_preferences.get_preference(context, 'bul_show_uevalid', formsemestre_id): always publish (car utile pour export Apogee)
|
||||
for ue_id in decision["decisions_ue"].keys():
|
||||
ue = sco_edit_ue.do_ue_list(context, {"ue_id": ue_id})[0]
|
||||
doc._push()
|
||||
doc.decision_ue(
|
||||
doc.append(
|
||||
Element(
|
||||
"decision_ue",
|
||||
ue_id=ue["ue_id"],
|
||||
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()
|
||||
)
|
||||
|
||||
for aut in decision["autorisations"]:
|
||||
doc._push()
|
||||
doc.autorisation_inscription(semestre_id=aut["semestre_id"])
|
||||
doc._pop()
|
||||
doc.append(
|
||||
Element(
|
||||
"autorisation_inscription", semestre_id=str(aut["semestre_id"])
|
||||
)
|
||||
)
|
||||
else:
|
||||
doc._push()
|
||||
doc.decision(code="", etat="DEM")
|
||||
doc._pop()
|
||||
doc.append(Element("decision", code="", etat="DEM"))
|
||||
# --- Appreciations
|
||||
cnx = ndb.GetDBConnexion()
|
||||
apprecs = sco_etud.appreciations_list(
|
||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
||||
)
|
||||
for app in apprecs:
|
||||
doc.appreciation(
|
||||
scu.quote_xml_attr(app["comment"]), date=ndb.DateDMYtoISO(app["date"])
|
||||
doc.append(
|
||||
Element(
|
||||
"appreciation",
|
||||
scu.quote_xml_attr(app["comment"]),
|
||||
date=ndb.DateDMYtoISO(app["date"]),
|
||||
)
|
||||
return doc
|
||||
)
|
||||
return sco_xml.XML_HEADER + ElementTree.tostring(doc)
|
||||
|
Loading…
Reference in New Issue
Block a user