UE capitalisées sur bulletins BUT PDF + code cleaning
This commit is contained in:
parent
e482e6bd3d
commit
8d453eb42b
@ -286,7 +286,7 @@ def bulletin(
|
|||||||
if pdf:
|
if pdf:
|
||||||
pdf_response, _ = do_formsemestre_bulletinetud(
|
pdf_response, _ = do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
etud.id,
|
etud,
|
||||||
version=version,
|
version=version,
|
||||||
format="pdf",
|
format="pdf",
|
||||||
with_img_signatures_pdf=with_img_signatures_pdf,
|
with_img_signatures_pdf=with_img_signatures_pdf,
|
||||||
|
@ -187,6 +187,8 @@ class BulletinBUT:
|
|||||||
)
|
)
|
||||||
if ue_capitalisee.formsemestre_id
|
if ue_capitalisee.formsemestre_id
|
||||||
else None,
|
else None,
|
||||||
|
"ressources": {}, # sans détail en BUT
|
||||||
|
"saes": {},
|
||||||
}
|
}
|
||||||
if self.prefs["bul_show_ects"]:
|
if self.prefs["bul_show_ects"]:
|
||||||
d[ue.acronyme]["ECTS"] = {
|
d[ue.acronyme]["ECTS"] = {
|
||||||
@ -473,6 +475,7 @@ class BulletinBUT:
|
|||||||
|
|
||||||
def bulletin_etud_complet(self, etud: Identite, version="long") -> dict:
|
def bulletin_etud_complet(self, etud: Identite, version="long") -> dict:
|
||||||
"""Bulletin dict complet avec toutes les infos pour les bulletins BUT pdf
|
"""Bulletin dict complet avec toutes les infos pour les bulletins BUT pdf
|
||||||
|
(pas utilisé pour json/html)
|
||||||
Résultat compatible avec celui de sco_bulletins.formsemestre_bulletinetud_dict
|
Résultat compatible avec celui de sco_bulletins.formsemestre_bulletinetud_dict
|
||||||
"""
|
"""
|
||||||
d = self.bulletin_etud(
|
d = self.bulletin_etud(
|
||||||
|
@ -5,6 +5,20 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""Génération bulletin BUT au format PDF standard
|
"""Génération bulletin BUT au format PDF standard
|
||||||
|
|
||||||
|
La génération du bulletin PDF suit le chemin suivant:
|
||||||
|
|
||||||
|
- vue formsemestre_bulletinetud -> sco_bulletins.formsemestre_bulletinetud
|
||||||
|
|
||||||
|
bul_dict = bulletin_but.BulletinBUT(formsemestre).bulletin_etud_complet(etud)
|
||||||
|
|
||||||
|
- sco_bulletins_generator.make_formsemestre_bulletinetud(infos)
|
||||||
|
- instance de BulletinGeneratorStandardBUT(infos)
|
||||||
|
- BulletinGeneratorStandardBUT.generate(format="pdf")
|
||||||
|
sco_bulletins_generator.BulletinGenerator.generate()
|
||||||
|
.generate_pdf()
|
||||||
|
.bul_table() (ci-dessous)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from reportlab.lib.colors import blue
|
from reportlab.lib.colors import blue
|
||||||
from reportlab.lib.units import cm, mm
|
from reportlab.lib.units import cm, mm
|
||||||
@ -65,7 +79,9 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
|
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
def but_table_synthese_ues(self, title_bg=(182, 235, 255)):
|
def but_table_synthese_ues(
|
||||||
|
self, title_bg=(182, 235, 255), title_ue_cap_bg=(150, 207, 147)
|
||||||
|
):
|
||||||
"""La table de synthèse; pour chaque UE, liste des ressources et SAÉs avec leurs notes
|
"""La table de synthèse; pour chaque UE, liste des ressources et SAÉs avec leurs notes
|
||||||
et leurs coefs.
|
et leurs coefs.
|
||||||
Renvoie: colkeys, P, pdf_style, colWidths
|
Renvoie: colkeys, P, pdf_style, colWidths
|
||||||
@ -74,6 +90,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
- pdf_style : commandes table Platypus
|
- pdf_style : commandes table Platypus
|
||||||
- largeurs de colonnes pour PDF
|
- largeurs de colonnes pour PDF
|
||||||
"""
|
"""
|
||||||
|
# nb: self.infos a ici été donné par BulletinBUT.bulletin_etud_complet()
|
||||||
col_widths = {
|
col_widths = {
|
||||||
"titre": None,
|
"titre": None,
|
||||||
"min": 1.5 * cm,
|
"min": 1.5 * cm,
|
||||||
@ -95,6 +112,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
col_keys += ["coef", "moyenne"]
|
col_keys += ["coef", "moyenne"]
|
||||||
# Couleur fond:
|
# Couleur fond:
|
||||||
title_bg = tuple(x / 255.0 for x in title_bg)
|
title_bg = tuple(x / 255.0 for x in title_bg)
|
||||||
|
title_ue_cap_bg = tuple(x / 255.0 for x in title_ue_cap_bg)
|
||||||
# elems pour générer table avec gen_table (liste de dicts)
|
# elems pour générer table avec gen_table (liste de dicts)
|
||||||
rows = [
|
rows = [
|
||||||
# Ligne de titres
|
# Ligne de titres
|
||||||
@ -141,9 +159,13 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
blue,
|
blue,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
ues_capitalisees = self.infos.get("ues_capitalisees", {})
|
||||||
for ue_acronym, ue in self.infos["ues"].items():
|
for ue_acronym, ue in self.infos["ues"].items():
|
||||||
self.ue_rows(rows, ue_acronym, ue, title_bg)
|
self._ue_rows(rows, ue_acronym, ue, title_bg)
|
||||||
|
if ue_acronym in ues_capitalisees:
|
||||||
|
self._ue_rows(
|
||||||
|
rows, ue_acronym, ues_capitalisees[ue_acronym], title_ue_cap_bg
|
||||||
|
)
|
||||||
|
|
||||||
# Global pdf style commands:
|
# Global pdf style commands:
|
||||||
pdf_style = [
|
pdf_style = [
|
||||||
@ -152,20 +174,18 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
]
|
]
|
||||||
return col_keys, rows, pdf_style, col_widths
|
return col_keys, rows, pdf_style, col_widths
|
||||||
|
|
||||||
def ue_rows(self, rows: list, ue_acronym: str, ue: dict, title_bg: tuple):
|
def _ue_rows(self, rows: list, ue_acronym: str, ue: dict, title_bg: tuple):
|
||||||
"Décrit une UE dans la table synthèse: titre, sous-titre et liste modules"
|
"Décrit une UE dans la table synthèse: titre, sous-titre et liste modules"
|
||||||
if (ue["type"] == UE_SPORT) and len(ue.get("modules", [])) == 0:
|
if (ue["type"] == UE_SPORT) and len(ue.get("modules", [])) == 0:
|
||||||
# ne mentionne l'UE que s'il y a des modules
|
# ne mentionne l'UE que s'il y a des modules
|
||||||
return
|
return
|
||||||
# 1er ligne titre UE
|
# 1er ligne titre UE
|
||||||
moy_ue = ue.get("moyenne")
|
moy_ue = ue.get("moyenne", "-")
|
||||||
|
if isinstance(moy_ue, dict):
|
||||||
|
moy_ue = moy_ue.get("value", "-") if moy_ue is not None else "-"
|
||||||
t = {
|
t = {
|
||||||
"titre": f"{ue_acronym} - {ue['titre']}",
|
"titre": f"{ue_acronym} - {ue['titre']}",
|
||||||
"moyenne": Paragraph(
|
"moyenne": Paragraph(f"""<para align=right><b>{moy_ue}</b></para>"""),
|
||||||
f"""<para align=right><b>{moy_ue.get("value", "-")
|
|
||||||
if moy_ue is not None else "-"
|
|
||||||
}</b></para>"""
|
|
||||||
),
|
|
||||||
"_css_row_class": "note_bold",
|
"_css_row_class": "note_bold",
|
||||||
"_pdf_row_markup": ["b"],
|
"_pdf_row_markup": ["b"],
|
||||||
"_pdf_style": [
|
"_pdf_style": [
|
||||||
@ -196,25 +216,40 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
# case Bonus/Malus/Rang "bmr"
|
# case Bonus/Malus/Rang "bmr"
|
||||||
fields_bmr = []
|
fields_bmr = []
|
||||||
try:
|
try:
|
||||||
value = float(ue["bonus"])
|
value = float(ue.get("bonus", 0.0))
|
||||||
if value != 0:
|
if value != 0:
|
||||||
fields_bmr.append(f"Bonus: {ue['bonus']}")
|
fields_bmr.append(f"Bonus: {ue['bonus']}")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
value = float(ue["malus"])
|
value = float(ue.get("malus", 0.0))
|
||||||
if value != 0:
|
if value != 0:
|
||||||
fields_bmr.append(f"Malus: {ue['malus']}")
|
fields_bmr.append(f"Malus: {ue['malus']}")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if self.preferences["bul_show_ue_rangs"]:
|
|
||||||
fields_bmr.append(
|
moy_ue = ue.get("moyenne", "-")
|
||||||
f"Rang: {ue['moyenne']['rang']} / {ue['moyenne']['total']}"
|
if isinstance(moy_ue, dict): # UE non capitalisées
|
||||||
|
if self.preferences["bul_show_ue_rangs"]:
|
||||||
|
fields_bmr.append(
|
||||||
|
f"Rang: {ue['moyenne']['rang']} / {ue['moyenne']['total']}"
|
||||||
|
)
|
||||||
|
ue_min, ue_max, ue_moy = (
|
||||||
|
ue["moyenne"]["min"],
|
||||||
|
ue["moyenne"]["max"],
|
||||||
|
ue["moyenne"]["moy"],
|
||||||
)
|
)
|
||||||
|
else: # UE capitalisée
|
||||||
|
ue_min, ue_max, ue_moy = "", "", moy_ue
|
||||||
|
date_capitalisation = ue.get("date_capitalisation")
|
||||||
|
if date_capitalisation:
|
||||||
|
fields_bmr.append(
|
||||||
|
f"""Capitalisée le {date_capitalisation.strftime("%d/%m/%Y")}"""
|
||||||
|
)
|
||||||
t = {
|
t = {
|
||||||
"titre": " - ".join(fields_bmr),
|
"titre": " - ".join(fields_bmr),
|
||||||
"coef": ects_txt,
|
"coef": ects_txt,
|
||||||
"_coef_pdf": Paragraph(f"""<para align=left>{ects_txt}</para>"""),
|
"_coef_pdf": Paragraph(f"""<para align=right>{ects_txt}</para>"""),
|
||||||
"_coef_colspan": 2,
|
"_coef_colspan": 2,
|
||||||
"_pdf_style": [
|
"_pdf_style": [
|
||||||
("BACKGROUND", (0, 0), (-1, 0), title_bg),
|
("BACKGROUND", (0, 0), (-1, 0), title_bg),
|
||||||
@ -222,9 +257,9 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
# ligne au dessus du bonus/malus, gris clair
|
# ligne au dessus du bonus/malus, gris clair
|
||||||
("LINEABOVE", (0, 0), (-1, 0), self.PDF_LINEWIDTH, (0.7, 0.7, 0.7)),
|
("LINEABOVE", (0, 0), (-1, 0), self.PDF_LINEWIDTH, (0.7, 0.7, 0.7)),
|
||||||
],
|
],
|
||||||
"min": ue["moyenne"]["min"],
|
"min": ue_min,
|
||||||
"max": ue["moyenne"]["max"],
|
"max": ue_max,
|
||||||
"moy": ue["moyenne"]["moy"],
|
"moy": ue_moy,
|
||||||
}
|
}
|
||||||
rows.append(t)
|
rows.append(t)
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
)
|
)
|
||||||
# matrice de NaN: inscrits par défaut à AUCUNE UE:
|
# matrice de NaN: inscrits par défaut à AUCUNE UE:
|
||||||
ues_inscr_parcours_df = pd.DataFrame(
|
ues_inscr_parcours_df = pd.DataFrame(
|
||||||
np.nan, index=etuds_parcour_id.keys(), columns=ue_ids, dtype=float # XXX
|
np.nan, index=etuds_parcour_id.keys(), columns=ue_ids, dtype=float
|
||||||
)
|
)
|
||||||
# Construit pour chaque parcours du référentiel l'ensemble de ses UE
|
# Construit pour chaque parcours du référentiel l'ensemble de ses UE
|
||||||
# (considère aussi le cas des semestres sans parcours: None)
|
# (considère aussi le cas des semestres sans parcours: None)
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
from flask import abort, has_request_context, url_for
|
from flask import abort, has_request_context, url_for
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
@ -155,9 +157,19 @@ class Identite(db.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_first_email(self, field="email") -> str:
|
def get_first_email(self, field="email") -> str:
|
||||||
"Le mail associé à la première adrese de l'étudiant, ou None"
|
"Le mail associé à la première adresse de l'étudiant, ou None"
|
||||||
return getattr(self.adresses[0], field) if self.adresses.count() > 0 else None
|
return getattr(self.adresses[0], field) if self.adresses.count() > 0 else None
|
||||||
|
|
||||||
|
def get_formsemestres(self) -> list:
|
||||||
|
"""Liste des formsemestres dans lesquels l'étudiant est (a été) inscrit,
|
||||||
|
triée par date_debut
|
||||||
|
"""
|
||||||
|
return sorted(
|
||||||
|
[ins.formsemestre for ins in self.formsemestre_inscriptions],
|
||||||
|
key=attrgetter("date_debut"),
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
|
||||||
def to_dict_short(self) -> dict:
|
def to_dict_short(self) -> dict:
|
||||||
"""Les champs essentiels"""
|
"""Les champs essentiels"""
|
||||||
return {
|
return {
|
||||||
|
@ -82,11 +82,11 @@ def get_formsemestre_bulletin_etud_json(
|
|||||||
) -> str:
|
) -> str:
|
||||||
"""Le JSON du bulletin d'un étudiant, quel que soit le type de formation."""
|
"""Le JSON du bulletin d'un étudiant, quel que soit le type de formation."""
|
||||||
if formsemestre.formation.is_apc():
|
if formsemestre.formation.is_apc():
|
||||||
bul = bulletin_but.BulletinBUT(formsemestre)
|
bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
|
||||||
if not etud.id in bul.res.identdict:
|
if not etud.id in bulletins_sem.res.identdict:
|
||||||
return json_error(404, "get_formsemestre_bulletin_etud_json: invalid etud")
|
return json_error(404, "get_formsemestre_bulletin_etud_json: invalid etud")
|
||||||
return jsonify(
|
return jsonify(
|
||||||
bul.bulletin_etud(
|
bulletins_sem.bulletin_etud(
|
||||||
etud,
|
etud,
|
||||||
formsemestre,
|
formsemestre,
|
||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
@ -746,7 +746,10 @@ def etud_descr_situation_semestre(
|
|||||||
infos["refcomp_specialite_long"] = ""
|
infos["refcomp_specialite_long"] = ""
|
||||||
if formsemestre.formation.is_apc():
|
if formsemestre.formation.is_apc():
|
||||||
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
|
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
|
||||||
parcour: ApcParcours = ApcParcours.query.get(res.etuds_parcour_id[etudid])
|
parcour_id = res.etuds_parcour_id[etudid]
|
||||||
|
parcour: ApcParcours = (
|
||||||
|
ApcParcours.query.get(parcour_id) if parcour_id is not None else None
|
||||||
|
)
|
||||||
if parcour:
|
if parcour:
|
||||||
infos["parcours_titre"] = parcour.libelle or ""
|
infos["parcours_titre"] = parcour.libelle or ""
|
||||||
infos["parcours_code"] = parcour.code or ""
|
infos["parcours_code"] = parcour.code or ""
|
||||||
@ -930,13 +933,14 @@ def formsemestre_bulletinetud(
|
|||||||
|
|
||||||
bulletin = do_formsemestre_bulletinetud(
|
bulletin = do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
etud.id,
|
etud,
|
||||||
format=format,
|
format=format,
|
||||||
version=version,
|
version=version,
|
||||||
xml_with_decisions=xml_with_decisions,
|
xml_with_decisions=xml_with_decisions,
|
||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
prefer_mail_perso=prefer_mail_perso,
|
prefer_mail_perso=prefer_mail_perso,
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
if format not in {"html", "pdfmail"}:
|
if format not in {"html", "pdfmail"}:
|
||||||
filename = scu.bul_filename(formsemestre, etud, format)
|
filename = scu.bul_filename(formsemestre, etud, format)
|
||||||
mime, suffix = scu.get_mime_suffix(format)
|
mime, suffix = scu.get_mime_suffix(format)
|
||||||
@ -973,7 +977,7 @@ def can_send_bulletin_by_mail(formsemestre_id):
|
|||||||
|
|
||||||
def do_formsemestre_bulletinetud(
|
def do_formsemestre_bulletinetud(
|
||||||
formsemestre: FormSemestre,
|
formsemestre: FormSemestre,
|
||||||
etudid: int,
|
etud: Identite,
|
||||||
version="long", # short, long, selectedevals
|
version="long", # short, long, selectedevals
|
||||||
format=None,
|
format=None,
|
||||||
xml_with_decisions: bool = False,
|
xml_with_decisions: bool = False,
|
||||||
@ -1001,7 +1005,7 @@ def do_formsemestre_bulletinetud(
|
|||||||
if format == "xml":
|
if format == "xml":
|
||||||
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
etudid,
|
etud.id,
|
||||||
xml_with_decisions=xml_with_decisions,
|
xml_with_decisions=xml_with_decisions,
|
||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
version=version,
|
version=version,
|
||||||
@ -1012,7 +1016,7 @@ def do_formsemestre_bulletinetud(
|
|||||||
elif format == "json": # utilisé pour classic et "oldjson"
|
elif format == "json": # utilisé pour classic et "oldjson"
|
||||||
bul = sco_bulletins_json.make_json_formsemestre_bulletinetud(
|
bul = sco_bulletins_json.make_json_formsemestre_bulletinetud(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
etudid,
|
etud.id,
|
||||||
xml_with_decisions=xml_with_decisions,
|
xml_with_decisions=xml_with_decisions,
|
||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
version=version,
|
version=version,
|
||||||
@ -1022,22 +1026,20 @@ def do_formsemestre_bulletinetud(
|
|||||||
version = version[:-4] # enlève le "_mat"
|
version = version[:-4] # enlève le "_mat"
|
||||||
|
|
||||||
if formsemestre.formation.is_apc():
|
if formsemestre.formation.is_apc():
|
||||||
etudiant = Identite.query.get(etudid)
|
bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
|
||||||
r = bulletin_but.BulletinBUT(formsemestre)
|
bul_dict = bulletins_sem.bulletin_etud_complet(etud, version=version)
|
||||||
infos = r.bulletin_etud_complet(etudiant, version=version)
|
|
||||||
else:
|
else:
|
||||||
infos = formsemestre_bulletinetud_dict(formsemestre.id, etudid)
|
bul_dict = formsemestre_bulletinetud_dict(formsemestre.id, etud.id)
|
||||||
etud = infos["etud"]
|
|
||||||
|
|
||||||
if format == "html":
|
if format == "html":
|
||||||
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
||||||
infos, version=version, format="html"
|
bul_dict, version=version, format="html"
|
||||||
)
|
)
|
||||||
return htm, infos["filigranne"]
|
return htm, bul_dict["filigranne"]
|
||||||
|
|
||||||
elif format == "pdf" or format == "pdfpart":
|
elif format == "pdf" or format == "pdfpart":
|
||||||
bul, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
bul, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
||||||
infos,
|
bul_dict,
|
||||||
version=version,
|
version=version,
|
||||||
format="pdf",
|
format="pdf",
|
||||||
stand_alone=(format != "pdfpart"),
|
stand_alone=(format != "pdfpart"),
|
||||||
@ -1046,10 +1048,10 @@ def do_formsemestre_bulletinetud(
|
|||||||
if format == "pdf":
|
if format == "pdf":
|
||||||
return (
|
return (
|
||||||
scu.sendPDFFile(bul, filename),
|
scu.sendPDFFile(bul, filename),
|
||||||
infos["filigranne"],
|
bul_dict["filigranne"],
|
||||||
) # unused ret. value
|
) # unused ret. value
|
||||||
else:
|
else:
|
||||||
return bul, infos["filigranne"]
|
return bul, bul_dict["filigranne"]
|
||||||
|
|
||||||
elif format == "pdfmail":
|
elif format == "pdfmail":
|
||||||
# format pdfmail: envoie le pdf par mail a l'etud, et affiche le html
|
# format pdfmail: envoie le pdf par mail a l'etud, et affiche le html
|
||||||
@ -1058,24 +1060,28 @@ def do_formsemestre_bulletinetud(
|
|||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
|
|
||||||
pdfdata, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
pdfdata, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
||||||
infos, version=version, format="pdf"
|
bul_dict, version=version, format="pdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
if prefer_mail_perso:
|
if prefer_mail_perso:
|
||||||
recipient_addr = etud.get("emailperso", "") or etud.get("email", "")
|
recipient_addr = (
|
||||||
|
etud.get_first_email("emailperso") or etud.get_first_email()
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
recipient_addr = etud.get("email", "") or etud.get("emailperso", "")
|
recipient_addr = etud.get_first_email() or etud.get_first_email(
|
||||||
|
"emailperso"
|
||||||
|
)
|
||||||
|
|
||||||
if not recipient_addr:
|
if not recipient_addr:
|
||||||
flash(f"{etud['nomprenom']} n'a pas d'adresse e-mail !")
|
flash(f"{etud.nomprenom} n'a pas d'adresse e-mail !")
|
||||||
return False, infos["filigranne"]
|
return False, bul_dict["filigranne"]
|
||||||
else:
|
else:
|
||||||
mail_bulletin(formsemestre.id, infos, pdfdata, filename, recipient_addr)
|
mail_bulletin(formsemestre.id, bul_dict, pdfdata, filename, recipient_addr)
|
||||||
flash(f"mail envoyé à {recipient_addr}")
|
flash(f"mail envoyé à {recipient_addr}")
|
||||||
|
|
||||||
return True, infos["filigranne"]
|
return True, bul_dict["filigranne"]
|
||||||
|
|
||||||
raise ValueError("do_formsemestre_bulletinetud: invalid format (%s)" % format)
|
raise ValueError(f"do_formsemestre_bulletinetud: invalid format ({format})")
|
||||||
|
|
||||||
|
|
||||||
def mail_bulletin(formsemestre_id, infos, pdfdata, filename, recipient_addr):
|
def mail_bulletin(formsemestre_id, infos, pdfdata, filename, recipient_addr):
|
||||||
|
@ -83,7 +83,7 @@ class BulletinGenerator:
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
infos,
|
bul_dict,
|
||||||
authuser=None,
|
authuser=None,
|
||||||
version="long",
|
version="long",
|
||||||
filigranne=None,
|
filigranne=None,
|
||||||
@ -92,16 +92,18 @@ class BulletinGenerator:
|
|||||||
):
|
):
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
if not version in scu.BULLETINS_VERSIONS:
|
if version not in scu.BULLETINS_VERSIONS:
|
||||||
raise ValueError("invalid version code !")
|
raise ValueError("invalid version code !")
|
||||||
self.infos = infos
|
self.bul_dict = bul_dict
|
||||||
self.authuser = authuser # nécessaire pour version HTML qui contient liens dépendant de l'utilisateur
|
self.infos = bul_dict # legacy code compat
|
||||||
|
# authuser nécessaire pour version HTML qui contient liens dépendants de l'utilisateur
|
||||||
|
self.authuser = authuser
|
||||||
self.version = version
|
self.version = version
|
||||||
self.filigranne = filigranne
|
self.filigranne = filigranne
|
||||||
self.server_name = server_name
|
self.server_name = server_name
|
||||||
self.with_img_signatures_pdf = with_img_signatures_pdf
|
self.with_img_signatures_pdf = with_img_signatures_pdf
|
||||||
# Store preferences for convenience:
|
# Store preferences for convenience:
|
||||||
formsemestre_id = self.infos["formsemestre_id"]
|
formsemestre_id = self.bul_dict["formsemestre_id"]
|
||||||
self.preferences = sco_preferences.SemPreferences(formsemestre_id)
|
self.preferences = sco_preferences.SemPreferences(formsemestre_id)
|
||||||
self.diagnostic = None # error message if any problem
|
self.diagnostic = None # error message if any problem
|
||||||
# Common PDF styles:
|
# Common PDF styles:
|
||||||
@ -127,13 +129,13 @@ class BulletinGenerator:
|
|||||||
|
|
||||||
def get_filename(self):
|
def get_filename(self):
|
||||||
"""Build a filename to be proposed to the web client"""
|
"""Build a filename to be proposed to the web client"""
|
||||||
sem = sco_formsemestre.get_formsemestre(self.infos["formsemestre_id"])
|
sem = sco_formsemestre.get_formsemestre(self.bul_dict["formsemestre_id"])
|
||||||
return scu.bul_filename_old(sem, self.infos["etud"], "pdf")
|
return scu.bul_filename_old(sem, self.bul_dict["etud"], "pdf")
|
||||||
|
|
||||||
def generate(self, format="", stand_alone=True):
|
def generate(self, format="", stand_alone=True):
|
||||||
"""Return bulletin in specified format"""
|
"""Return bulletin in specified format"""
|
||||||
if not format in self.supported_formats:
|
if not format in self.supported_formats:
|
||||||
raise ValueError("unsupported bulletin format (%s)" % format)
|
raise ValueError(f"unsupported bulletin format ({format})")
|
||||||
try:
|
try:
|
||||||
PDFLOCK.acquire() # this lock is necessary since reportlab is not re-entrant
|
PDFLOCK.acquire() # this lock is necessary since reportlab is not re-entrant
|
||||||
if format == "html":
|
if format == "html":
|
||||||
@ -141,7 +143,7 @@ class BulletinGenerator:
|
|||||||
elif format == "pdf":
|
elif format == "pdf":
|
||||||
return self.generate_pdf(stand_alone=stand_alone)
|
return self.generate_pdf(stand_alone=stand_alone)
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid bulletin format (%s)" % format)
|
raise ValueError(f"invalid bulletin format ({format})")
|
||||||
finally:
|
finally:
|
||||||
PDFLOCK.release()
|
PDFLOCK.release()
|
||||||
|
|
||||||
@ -163,11 +165,12 @@ class BulletinGenerator:
|
|||||||
"""
|
"""
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
formsemestre_id = self.infos["formsemestre_id"]
|
formsemestre_id = self.bul_dict["formsemestre_id"]
|
||||||
|
nomprenom = self.bul_dict["etud"]["nomprenom"]
|
||||||
marque_debut_bulletin = sco_pdf.DebutBulletin(
|
marque_debut_bulletin = sco_pdf.DebutBulletin(
|
||||||
self.infos["etud"]["nomprenom"],
|
nomprenom,
|
||||||
filigranne=self.infos["filigranne"],
|
filigranne=self.bul_dict["filigranne"],
|
||||||
footer_content=f"""ScoDoc - Bulletin de {self.infos["etud"]["nomprenom"]} - {time.strftime("%d/%m/%Y %H:%M")}""",
|
footer_content=f"""ScoDoc - Bulletin de {nomprenom} - {time.strftime("%d/%m/%Y %H:%M")}""",
|
||||||
)
|
)
|
||||||
story = []
|
story = []
|
||||||
# partie haute du bulletin
|
# partie haute du bulletin
|
||||||
@ -208,8 +211,7 @@ class BulletinGenerator:
|
|||||||
document,
|
document,
|
||||||
author="%s %s (E. Viennet) [%s]"
|
author="%s %s (E. Viennet) [%s]"
|
||||||
% (sco_version.SCONAME, sco_version.SCOVERSION, self.description),
|
% (sco_version.SCONAME, sco_version.SCOVERSION, self.description),
|
||||||
title="Bulletin %s de %s"
|
title=f"""Bulletin {sem["titremois"]} de {nomprenom}""",
|
||||||
% (sem["titremois"], self.infos["etud"]["nomprenom"]),
|
|
||||||
subject="Bulletin de note",
|
subject="Bulletin de note",
|
||||||
margins=self.margins,
|
margins=self.margins,
|
||||||
server_name=self.server_name,
|
server_name=self.server_name,
|
||||||
@ -247,7 +249,7 @@ class BulletinGenerator:
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
def make_formsemestre_bulletinetud(
|
def make_formsemestre_bulletinetud(
|
||||||
infos,
|
bul_dict,
|
||||||
version=None, # short, long, selectedevals
|
version=None, # short, long, selectedevals
|
||||||
format="pdf", # html, pdf
|
format="pdf", # html, pdf
|
||||||
stand_alone=True,
|
stand_alone=True,
|
||||||
@ -262,10 +264,10 @@ def make_formsemestre_bulletinetud(
|
|||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
version = version or "long"
|
version = version or "long"
|
||||||
if not version in scu.BULLETINS_VERSIONS:
|
if version not in scu.BULLETINS_VERSIONS:
|
||||||
raise ValueError("invalid version code !")
|
raise ValueError("invalid version code !")
|
||||||
|
|
||||||
formsemestre_id = infos["formsemestre_id"]
|
formsemestre_id = bul_dict["formsemestre_id"]
|
||||||
bul_class_name = sco_preferences.get_preference("bul_class_name", formsemestre_id)
|
bul_class_name = sco_preferences.get_preference("bul_class_name", formsemestre_id)
|
||||||
|
|
||||||
gen_class = None
|
gen_class = None
|
||||||
@ -274,7 +276,7 @@ def make_formsemestre_bulletinetud(
|
|||||||
# si pas trouvé (modifs locales bizarres ,), ré-essaye avec la valeur par défaut
|
# si pas trouvé (modifs locales bizarres ,), ré-essaye avec la valeur par défaut
|
||||||
bulletin_default_class_name(),
|
bulletin_default_class_name(),
|
||||||
):
|
):
|
||||||
if infos.get("type") == "BUT" and format.startswith("pdf"):
|
if bul_dict.get("type") == "BUT" and format.startswith("pdf"):
|
||||||
gen_class = bulletin_get_class(bul_class_name + "BUT")
|
gen_class = bulletin_get_class(bul_class_name + "BUT")
|
||||||
if gen_class is None:
|
if gen_class is None:
|
||||||
gen_class = bulletin_get_class(bul_class_name)
|
gen_class = bulletin_get_class(bul_class_name)
|
||||||
@ -285,10 +287,10 @@ def make_formsemestre_bulletinetud(
|
|||||||
try:
|
try:
|
||||||
PDFLOCK.acquire()
|
PDFLOCK.acquire()
|
||||||
bul_generator = gen_class(
|
bul_generator = gen_class(
|
||||||
infos,
|
bul_dict,
|
||||||
authuser=current_user,
|
authuser=current_user,
|
||||||
version=version,
|
version=version,
|
||||||
filigranne=infos["filigranne"],
|
filigranne=bul_dict["filigranne"],
|
||||||
server_name=request.url_root,
|
server_name=request.url_root,
|
||||||
with_img_signatures_pdf=with_img_signatures_pdf,
|
with_img_signatures_pdf=with_img_signatures_pdf,
|
||||||
)
|
)
|
||||||
@ -301,24 +303,22 @@ def make_formsemestre_bulletinetud(
|
|||||||
bul_class_name = bulletin_default_class_name()
|
bul_class_name = bulletin_default_class_name()
|
||||||
gen_class = bulletin_get_class(bul_class_name)
|
gen_class = bulletin_get_class(bul_class_name)
|
||||||
bul_generator = gen_class(
|
bul_generator = gen_class(
|
||||||
infos,
|
bul_dict,
|
||||||
authuser=current_user,
|
authuser=current_user,
|
||||||
version=version,
|
version=version,
|
||||||
filigranne=infos["filigranne"],
|
filigranne=bul_dict["filigranne"],
|
||||||
server_name=request.url_root,
|
server_name=request.url_root,
|
||||||
with_img_signatures_pdf=with_img_signatures_pdf,
|
with_img_signatures_pdf=with_img_signatures_pdf,
|
||||||
)
|
)
|
||||||
|
|
||||||
data = bul_generator.generate(format=format, stand_alone=stand_alone)
|
data = bul_generator.generate(format=format, stand_alone=stand_alone)
|
||||||
finally:
|
finally:
|
||||||
PDFLOCK.release()
|
PDFLOCK.release()
|
||||||
|
|
||||||
if bul_generator.diagnostic:
|
if bul_generator.diagnostic:
|
||||||
log("bul_error: %s" % bul_generator.diagnostic)
|
log(f"bul_error: {bul_generator.diagnostic}")
|
||||||
raise NoteProcessError(bul_generator.diagnostic)
|
raise NoteProcessError(bul_generator.diagnostic)
|
||||||
|
|
||||||
filename = bul_generator.get_filename()
|
filename = bul_generator.get_filename()
|
||||||
|
|
||||||
return data, filename
|
return data, filename
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ Pour définir un nouveau type de bulletin:
|
|||||||
(s'inspirer de sco_bulletins_pdf_default);
|
(s'inspirer de sco_bulletins_pdf_default);
|
||||||
- en fin du fichier sco_bulletins_pdf.py, ajouter la ligne
|
- en fin du fichier sco_bulletins_pdf.py, ajouter la ligne
|
||||||
import sco_bulletins_pdf_xxxx
|
import sco_bulletins_pdf_xxxx
|
||||||
- votre type sera alors (après redémarrage de ScoDoc) proposé dans le formulaire de paramètrage ScoDoc.
|
- votre type sera alors (après redémarrage de ScoDoc) proposé dans le formulaire de paramètrage.
|
||||||
|
|
||||||
Chaque semestre peut si nécessaire utiliser un type de bulletin différent.
|
Chaque semestre peut si nécessaire utiliser un type de bulletin différent.
|
||||||
|
|
||||||
@ -60,13 +60,12 @@ import traceback
|
|||||||
from flask import g, request
|
from flask import g, request
|
||||||
|
|
||||||
from app import log, ScoValueError
|
from app import log, ScoValueError
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre, Identite
|
||||||
|
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc import sco_pdf
|
from app.scodoc import sco_pdf
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_etud
|
|
||||||
from app.scodoc.sco_logos import find_logo
|
from app.scodoc.sco_logos import find_logo
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
@ -97,8 +96,8 @@ def assemble_bulletins_pdf(
|
|||||||
document.addPageTemplates(
|
document.addPageTemplates(
|
||||||
sco_pdf.ScoDocPageTemplate(
|
sco_pdf.ScoDocPageTemplate(
|
||||||
document,
|
document,
|
||||||
author="%s %s (E. Viennet)" % (sco_version.SCONAME, sco_version.SCOVERSION),
|
author=f"{sco_version.SCONAME} {sco_version.SCOVERSION} (E. Viennet)",
|
||||||
title="Bulletin %s" % bul_title,
|
title=f"Bulletin {bul_title}",
|
||||||
subject="Bulletin de note",
|
subject="Bulletin de note",
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
margins=margins,
|
margins=margins,
|
||||||
@ -125,11 +124,13 @@ def replacement_function(match):
|
|||||||
|
|
||||||
|
|
||||||
class WrapDict(object):
|
class WrapDict(object):
|
||||||
"""Wrap a dict so that getitem returns '' when values are None"""
|
"""Wrap a dict so that getitem returns '' when values are None
|
||||||
|
and non existent keys returns an error message as value.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, adict, NoneValue=""):
|
def __init__(self, adict, none_value=""):
|
||||||
self.dict = adict
|
self.dict = adict
|
||||||
self.NoneValue = NoneValue
|
self.none_value = none_value
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
try:
|
try:
|
||||||
@ -137,12 +138,11 @@ class WrapDict(object):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return f"XXX {key} invalide XXX"
|
return f"XXX {key} invalide XXX"
|
||||||
if value is None:
|
if value is None:
|
||||||
return self.NoneValue
|
return self.none_value
|
||||||
else:
|
return value
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"):
|
def process_field(field, cdict, style, suppress_empty_pars=False, fmt="pdf"):
|
||||||
"""Process a field given in preferences, returns
|
"""Process a field given in preferences, returns
|
||||||
- if format = 'pdf': a list of Platypus objects
|
- if format = 'pdf': a list of Platypus objects
|
||||||
- if format = 'html' : a string
|
- if format = 'html' : a string
|
||||||
@ -183,7 +183,7 @@ def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"):
|
|||||||
)
|
)
|
||||||
# remove unhandled or dangerous tags:
|
# remove unhandled or dangerous tags:
|
||||||
text = re.sub(r"<\s*img", "", text)
|
text = re.sub(r"<\s*img", "", text)
|
||||||
if format == "html":
|
if fmt == "html":
|
||||||
# convert <para>
|
# convert <para>
|
||||||
text = re.sub(r"<\s*para(\s*)(.*?)>", r"<p>", text)
|
text = re.sub(r"<\s*para(\s*)(.*?)>", r"<p>", text)
|
||||||
return text
|
return text
|
||||||
@ -219,7 +219,7 @@ def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"):
|
|||||||
for etud in formsemestre.get_inscrits(include_demdef=True, order=True):
|
for etud in formsemestre.get_inscrits(include_demdef=True, order=True):
|
||||||
frag, _ = sco_bulletins.do_formsemestre_bulletinetud(
|
frag, _ = sco_bulletins.do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
etud.id,
|
etud,
|
||||||
format="pdfpart",
|
format="pdfpart",
|
||||||
version=version,
|
version=version,
|
||||||
)
|
)
|
||||||
@ -256,22 +256,21 @@ def get_etud_bulletins_pdf(etudid, version="selectedevals"):
|
|||||||
"Bulletins pdf de tous les semestres de l'étudiant, et filename"
|
"Bulletins pdf de tous les semestres de l'étudiant, et filename"
|
||||||
from app.scodoc import sco_bulletins
|
from app.scodoc import sco_bulletins
|
||||||
|
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
fragments = []
|
fragments = []
|
||||||
bookmarks = {}
|
bookmarks = {}
|
||||||
filigrannes = {}
|
filigrannes = {}
|
||||||
i = 1
|
i = 1
|
||||||
for sem in etud["sems"]:
|
for formsemestre in etud.get_formsemestres():
|
||||||
formsemestre = FormSemestre.query.get(sem["formsemestre_id"])
|
|
||||||
frag, filigranne = sco_bulletins.do_formsemestre_bulletinetud(
|
frag, filigranne = sco_bulletins.do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
etudid,
|
etud,
|
||||||
format="pdfpart",
|
format="pdfpart",
|
||||||
version=version,
|
version=version,
|
||||||
)
|
)
|
||||||
fragments += frag
|
fragments += frag
|
||||||
filigrannes[i] = filigranne
|
filigrannes[i] = filigranne
|
||||||
bookmarks[i] = sem["session_id"] # eg RT-DUT-FI-S1-2015
|
bookmarks[i] = formsemestre.session_id() # eg RT-DUT-FI-S1-2015
|
||||||
i = i + 1
|
i = i + 1
|
||||||
infos = {"DeptName": sco_preferences.get_preference("DeptName")}
|
infos = {"DeptName": sco_preferences.get_preference("DeptName")}
|
||||||
if request:
|
if request:
|
||||||
@ -283,7 +282,7 @@ def get_etud_bulletins_pdf(etudid, version="selectedevals"):
|
|||||||
pdfdoc = assemble_bulletins_pdf(
|
pdfdoc = assemble_bulletins_pdf(
|
||||||
None,
|
None,
|
||||||
fragments,
|
fragments,
|
||||||
etud["nomprenom"],
|
etud.nomprenom,
|
||||||
infos,
|
infos,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
filigranne=filigrannes,
|
filigranne=filigrannes,
|
||||||
@ -292,7 +291,7 @@ def get_etud_bulletins_pdf(etudid, version="selectedevals"):
|
|||||||
finally:
|
finally:
|
||||||
sco_pdf.PDFLOCK.release()
|
sco_pdf.PDFLOCK.release()
|
||||||
#
|
#
|
||||||
filename = "bul-%s" % (etud["nomprenom"])
|
filename = f"bul-{etud.nomprenom}"
|
||||||
filename = (
|
filename = (
|
||||||
scu.unescape_html(filename).replace(" ", "_").replace("&", "").replace(".", "")
|
scu.unescape_html(filename).replace(" ", "_").replace("&", "").replace(".", "")
|
||||||
+ ".pdf"
|
+ ".pdf"
|
||||||
|
@ -186,13 +186,13 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
self.preferences["bul_pdf_caption"],
|
self.preferences["bul_pdf_caption"],
|
||||||
self.infos,
|
self.infos,
|
||||||
self.FieldStyle,
|
self.FieldStyle,
|
||||||
format="pdf",
|
fmt="pdf",
|
||||||
)
|
)
|
||||||
field = sco_bulletins_pdf.process_field(
|
field = sco_bulletins_pdf.process_field(
|
||||||
self.preferences["bul_pdf_caption"],
|
self.preferences["bul_pdf_caption"],
|
||||||
self.infos,
|
self.infos,
|
||||||
self.FieldStyle,
|
self.FieldStyle,
|
||||||
format="html",
|
fmt="html",
|
||||||
)
|
)
|
||||||
H.append('<div class="bul_decision">' + field + "</div>")
|
H.append('<div class="bul_decision">' + field + "</div>")
|
||||||
|
|
||||||
|
@ -939,7 +939,7 @@ def fill_etuds_info(etuds: list[dict], add_admission=True):
|
|||||||
def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
||||||
"""Dict avec les informations sur les semestres passés et courant.
|
"""Dict avec les informations sur les semestres passés et courant.
|
||||||
{
|
{
|
||||||
"sems" : ,
|
"sems" : , # trie les semestres par date de debut, le plus recent d'abord
|
||||||
"ins" : ,
|
"ins" : ,
|
||||||
"cursem" : ,
|
"cursem" : ,
|
||||||
"inscription" : ,
|
"inscription" : ,
|
||||||
|
@ -397,8 +397,8 @@ def gen_formsemestre_recapcomplet_json(
|
|||||||
etudid = t[-1]
|
etudid = t[-1]
|
||||||
if is_apc:
|
if is_apc:
|
||||||
etud = Identite.query.get(etudid)
|
etud = Identite.query.get(etudid)
|
||||||
r = bulletin_but.BulletinBUT(formsemestre)
|
bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
|
||||||
bul = r.bulletin_etud(etud, formsemestre)
|
bul = bulletins_sem.bulletin_etud(etud, formsemestre)
|
||||||
else:
|
else:
|
||||||
bul = sco_bulletins_json.formsemestre_bulletinetud_published_dict(
|
bul = sco_bulletins_json.formsemestre_bulletinetud_published_dict(
|
||||||
formsemestre_id,
|
formsemestre_id,
|
||||||
|
@ -335,7 +335,8 @@ def formsemestre_bulletinetud(
|
|||||||
|
|
||||||
if format == "oldjson":
|
if format == "oldjson":
|
||||||
format = "json"
|
format = "json"
|
||||||
r = sco_bulletins.formsemestre_bulletinetud(
|
|
||||||
|
response = sco_bulletins.formsemestre_bulletinetud(
|
||||||
etud,
|
etud,
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
format=format,
|
format=format,
|
||||||
@ -344,7 +345,8 @@ def formsemestre_bulletinetud(
|
|||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
prefer_mail_perso=prefer_mail_perso,
|
prefer_mail_perso=prefer_mail_perso,
|
||||||
)
|
)
|
||||||
if format == "pdfmail":
|
|
||||||
|
if format == "pdfmail": # ne renvoie rien dans ce cas (mails envoyés)
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
"notes.formsemestre_bulletinetud",
|
"notes.formsemestre_bulletinetud",
|
||||||
@ -353,7 +355,7 @@ def formsemestre_bulletinetud(
|
|||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return r
|
return response
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
@ -2074,7 +2076,7 @@ def formsemestre_bulletins_mailetuds(
|
|||||||
for inscription in inscriptions:
|
for inscription in inscriptions:
|
||||||
sent, _ = sco_bulletins.do_formsemestre_bulletinetud(
|
sent, _ = sco_bulletins.do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
inscription.etudid,
|
inscription.etud,
|
||||||
version=version,
|
version=version,
|
||||||
prefer_mail_perso=prefer_mail_perso,
|
prefer_mail_perso=prefer_mail_perso,
|
||||||
format="pdfmail",
|
format="pdfmail",
|
||||||
|
Loading…
Reference in New Issue
Block a user