forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -531,10 +531,6 @@ class BulletinBUT:
|
|||||||
] = f"{d['semestre']['rang']['value']} / {d['semestre']['rang']['total']}"
|
] = f"{d['semestre']['rang']['value']} / {d['semestre']['rang']['total']}"
|
||||||
d["rang_txt"] = "Rang " + d["rang_nt"]
|
d["rang_txt"] = "Rang " + d["rang_nt"]
|
||||||
|
|
||||||
# --- Appréciations
|
|
||||||
d.update(
|
|
||||||
sco_bulletins.get_appreciations_list(self.res.formsemestre.id, etud.id)
|
|
||||||
)
|
|
||||||
d.update(sco_bulletins.make_context_dict(self.res.formsemestre, d["etud"]))
|
d.update(sco_bulletins.make_context_dict(self.res.formsemestre, d["etud"]))
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
@ -12,8 +12,8 @@ La génération du bulletin PDF suit le chemin suivant:
|
|||||||
|
|
||||||
bul_dict = bulletin_but.BulletinBUT(formsemestre).bulletin_etud_complet(etud)
|
bul_dict = bulletin_but.BulletinBUT(formsemestre).bulletin_etud_complet(etud)
|
||||||
|
|
||||||
- sco_bulletins_generator.make_formsemestre_bulletinetud(infos)
|
- sco_bulletins_generator.make_formsemestre_bulletin_etud()
|
||||||
- instance de BulletinGeneratorStandardBUT(infos)
|
- instance de BulletinGeneratorStandardBUT
|
||||||
- BulletinGeneratorStandardBUT.generate(format="pdf")
|
- BulletinGeneratorStandardBUT.generate(format="pdf")
|
||||||
sco_bulletins_generator.BulletinGenerator.generate()
|
sco_bulletins_generator.BulletinGenerator.generate()
|
||||||
.generate_pdf()
|
.generate_pdf()
|
||||||
@ -42,7 +42,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
multi_pages = True # plusieurs pages par bulletins
|
multi_pages = True # plusieurs pages par bulletins
|
||||||
small_fontsize = "8"
|
small_fontsize = "8"
|
||||||
|
|
||||||
def bul_table(self, format="html"):
|
def bul_table(self, fmt="html"):
|
||||||
"""Génère la table centrale du bulletin de notes
|
"""Génère la table centrale du bulletin de notes
|
||||||
Renvoie:
|
Renvoie:
|
||||||
- en HTML: une chaine
|
- en HTML: une chaine
|
||||||
@ -71,7 +71,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
|||||||
html_class_ignore_default=True,
|
html_class_ignore_default=True,
|
||||||
html_with_td_classes=True,
|
html_with_td_classes=True,
|
||||||
)
|
)
|
||||||
table_objects = table.gen(format=format)
|
table_objects = table.gen(format=fmt)
|
||||||
objects += table_objects
|
objects += table_objects
|
||||||
# objects += [KeepInFrame(0, 0, table_objects, mode="shrink")]
|
# objects += [KeepInFrame(0, 0, table_objects, mode="shrink")]
|
||||||
if i != 2:
|
if i != 2:
|
||||||
|
@ -40,7 +40,7 @@ from xml.etree.ElementTree import Element
|
|||||||
|
|
||||||
from app import log
|
from app import log
|
||||||
from app.but import bulletin_but
|
from app.but import bulletin_but
|
||||||
from app.models import FormSemestre, Identite
|
from app.models import BulAppreciations, FormSemestre, Identite
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
@ -315,16 +315,13 @@ def bulletin_but_xml_compat(
|
|||||||
else:
|
else:
|
||||||
doc.append(Element("decision", code="", etat="DEM"))
|
doc.append(Element("decision", code="", etat="DEM"))
|
||||||
# --- Appreciations
|
# --- Appreciations
|
||||||
cnx = ndb.GetDBConnexion()
|
appreciations = BulAppreciations.get_appreciations_list(formsemestre.id, etudid)
|
||||||
apprecs = sco_etud.appreciations_list(
|
for appreciation in appreciations:
|
||||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
|
||||||
)
|
|
||||||
for appr in apprecs:
|
|
||||||
x_appr = Element(
|
x_appr = Element(
|
||||||
"appreciation",
|
"appreciation",
|
||||||
date=ndb.DateDMYtoISO(appr["date"]),
|
date=appreciation.date.isoformat() if appreciation.date else "",
|
||||||
)
|
)
|
||||||
x_appr.text = quote_xml_attr(appr["comment"])
|
x_appr.text = quote_xml_attr(appreciation.comment_safe())
|
||||||
doc.append(x_appr)
|
doc.append(x_appr)
|
||||||
|
|
||||||
if is_appending:
|
if is_appending:
|
||||||
|
@ -296,26 +296,27 @@ class Identite(db.Model):
|
|||||||
from app.scodoc import sco_photos
|
from app.scodoc import sco_photos
|
||||||
|
|
||||||
d = {
|
d = {
|
||||||
|
"boursier": self.boursier or "",
|
||||||
|
"civilite_etat_civil": self.civilite_etat_civil,
|
||||||
"civilite": self.civilite,
|
"civilite": self.civilite,
|
||||||
"code_ine": self.code_ine or "",
|
"code_ine": self.code_ine or "",
|
||||||
"code_nip": self.code_nip or "",
|
"code_nip": self.code_nip or "",
|
||||||
"date_naissance": self.date_naissance.strftime("%d/%m/%Y")
|
"date_naissance": self.date_naissance.strftime("%d/%m/%Y")
|
||||||
if self.date_naissance
|
if self.date_naissance
|
||||||
else "",
|
else "",
|
||||||
"dept_id": self.dept_id,
|
|
||||||
"dept_acronym": self.departement.acronym,
|
"dept_acronym": self.departement.acronym,
|
||||||
|
"dept_id": self.dept_id,
|
||||||
|
"dept_naissance": self.dept_naissance or "",
|
||||||
"email": self.get_first_email() or "",
|
"email": self.get_first_email() or "",
|
||||||
"emailperso": self.get_first_email("emailperso"),
|
"emailperso": self.get_first_email("emailperso"),
|
||||||
|
"etat_civil": self.etat_civil,
|
||||||
"etudid": self.id,
|
"etudid": self.id,
|
||||||
"nom": self.nom_disp(),
|
|
||||||
"prenom": self.prenom or "",
|
|
||||||
"nomprenom": self.nomprenom or "",
|
|
||||||
"lieu_naissance": self.lieu_naissance or "",
|
"lieu_naissance": self.lieu_naissance or "",
|
||||||
"dept_naissance": self.dept_naissance or "",
|
|
||||||
"nationalite": self.nationalite or "",
|
"nationalite": self.nationalite or "",
|
||||||
"boursier": self.boursier or "",
|
"nom": self.nom_disp(),
|
||||||
"civilite_etat_civil": self.civilite_etat_civil,
|
"nomprenom": self.nomprenom or "",
|
||||||
"prenom_etat_civil": self.prenom_etat_civil,
|
"prenom_etat_civil": self.prenom_etat_civil,
|
||||||
|
"prenom": self.prenom or "",
|
||||||
}
|
}
|
||||||
if include_urls and has_request_context():
|
if include_urls and has_request_context():
|
||||||
# test request context so we can use this func in tests under the flask shell
|
# test request context so we can use this func in tests under the flask shell
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from app import db
|
from app import db
|
||||||
|
from app.scodoc import safehtml
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -26,6 +27,31 @@ class BulAppreciations(db.Model):
|
|||||||
author = db.Column(db.Text) # le pseudo (user_name), sans contrainte
|
author = db.Column(db.Text) # le pseudo (user_name), sans contrainte
|
||||||
comment = db.Column(db.Text) # texte libre
|
comment = db.Column(db.Text) # texte libre
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_appreciations_list(
|
||||||
|
cls, formsemestre_id: int, etudid: int
|
||||||
|
) -> list["BulAppreciations"]:
|
||||||
|
"Liste des appréciations pour cet étudiant dans ce semestre"
|
||||||
|
return (
|
||||||
|
BulAppreciations.query.filter_by(
|
||||||
|
etudid=etudid, formsemestre_id=formsemestre_id
|
||||||
|
)
|
||||||
|
.order_by(BulAppreciations.date)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def summarize(cls, appreciations: list["BulAppreciations"]) -> list[str]:
|
||||||
|
"Liste de chaines résumant une liste d'appréciations, pour bulletins"
|
||||||
|
return [
|
||||||
|
f"{x.date.strftime('%d/%m/%Y') if x.date else ''}: {x.comment or ''}"
|
||||||
|
for x in appreciations
|
||||||
|
]
|
||||||
|
|
||||||
|
def comment_safe(self) -> str:
|
||||||
|
"Le comment, safe pour inclusion dans HTML (None devient '')"
|
||||||
|
return safehtml.html_to_safe_html(self.comment or "")
|
||||||
|
|
||||||
|
|
||||||
class NotesNotes(db.Model):
|
class NotesNotes(db.Model):
|
||||||
"""Une note"""
|
"""Une note"""
|
||||||
|
@ -224,9 +224,6 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
|
|||||||
elif I["etud_etat"] == codes_cursus.DEF:
|
elif I["etud_etat"] == codes_cursus.DEF:
|
||||||
I["demission"] = "(Défaillant)"
|
I["demission"] = "(Défaillant)"
|
||||||
|
|
||||||
# --- Appreciations
|
|
||||||
I.update(get_appreciations_list(formsemestre_id, etudid))
|
|
||||||
|
|
||||||
# --- Notes
|
# --- Notes
|
||||||
ues = nt.get_ues_stat_dict()
|
ues = nt.get_ues_stat_dict()
|
||||||
modimpls = nt.get_modimpls_dict()
|
modimpls = nt.get_modimpls_dict()
|
||||||
@ -417,21 +414,6 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
|
|||||||
return C
|
return C
|
||||||
|
|
||||||
|
|
||||||
def get_appreciations_list(formsemestre_id: int, etudid: int) -> dict:
|
|
||||||
"""Appréciations pour cet étudiant dans ce semestre"""
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
apprecs = sco_etud.appreciations_list(
|
|
||||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
|
||||||
)
|
|
||||||
d = {
|
|
||||||
"appreciations_list": apprecs,
|
|
||||||
"appreciations_txt": [x["date"] + ": " + x["comment"] for x in apprecs],
|
|
||||||
}
|
|
||||||
# deprecated / keep it for backward compat in templates:
|
|
||||||
d["appreciations"] = d["appreciations_txt"]
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
def _get_etud_etat_html(etat: str) -> str:
|
def _get_etud_etat_html(etat: str) -> str:
|
||||||
"""chaine html représentant l'état (backward compat sco7)"""
|
"""chaine html représentant l'état (backward compat sco7)"""
|
||||||
if etat == scu.INSCRIT:
|
if etat == scu.INSCRIT:
|
||||||
@ -1035,16 +1017,18 @@ def do_formsemestre_bulletinetud(
|
|||||||
bul_dict = formsemestre_bulletinetud_dict(formsemestre.id, etud.id)
|
bul_dict = formsemestre_bulletinetud_dict(formsemestre.id, etud.id)
|
||||||
|
|
||||||
if format == "html":
|
if format == "html":
|
||||||
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
|
htm, _ = sco_bulletins_generator.make_formsemestre_bulletin_etud(
|
||||||
bul_dict, version=version, format="html"
|
bul_dict, etud=etud, formsemestre=formsemestre, version=version, fmt="html"
|
||||||
)
|
)
|
||||||
return htm, bul_dict["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_bulletin_etud(
|
||||||
bul_dict,
|
bul_dict,
|
||||||
|
etud=etud,
|
||||||
|
formsemestre=formsemestre,
|
||||||
version=version,
|
version=version,
|
||||||
format="pdf",
|
fmt="pdf",
|
||||||
stand_alone=(format != "pdfpart"),
|
stand_alone=(format != "pdfpart"),
|
||||||
with_img_signatures_pdf=with_img_signatures_pdf,
|
with_img_signatures_pdf=with_img_signatures_pdf,
|
||||||
)
|
)
|
||||||
@ -1062,8 +1046,8 @@ def do_formsemestre_bulletinetud(
|
|||||||
if not can_send_bulletin_by_mail(formsemestre.id):
|
if not can_send_bulletin_by_mail(formsemestre.id):
|
||||||
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_bulletin_etud(
|
||||||
bul_dict, version=version, format="pdf"
|
bul_dict, etud=etud, formsemestre=formsemestre, version=version, fmt="pdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
if prefer_mail_perso:
|
if prefer_mail_perso:
|
||||||
|
@ -47,14 +47,14 @@ class BulletinGeneratorExample(sco_bulletins_standard.BulletinGeneratorStandard)
|
|||||||
# En général, on veut définir un format de table spécial, sans changer le reste (titre, pied de page).
|
# En général, on veut définir un format de table spécial, sans changer le reste (titre, pied de page).
|
||||||
# Si on veut changer le reste, surcharger les méthodes:
|
# Si on veut changer le reste, surcharger les méthodes:
|
||||||
# .bul_title_pdf(self) : partie haute du bulletin
|
# .bul_title_pdf(self) : partie haute du bulletin
|
||||||
# .bul_part_below(self, format='') : infos sous la table
|
# .bul_part_below(self, fmt='') : infos sous la table
|
||||||
# .bul_signatures_pdf(self) : signatures
|
# .bul_signatures_pdf(self) : signatures
|
||||||
|
|
||||||
def bul_table(self, format=""):
|
def bul_table(self, fmt=""):
|
||||||
"""Défini la partie centrale de notre bulletin PDF.
|
"""Défini la partie centrale de notre bulletin PDF.
|
||||||
Doit renvoyer une liste d'objets PLATYPUS
|
Doit renvoyer une liste d'objets PLATYPUS
|
||||||
"""
|
"""
|
||||||
assert format == "pdf" # garde fou
|
assert fmt == "pdf" # garde fou
|
||||||
return [
|
return [
|
||||||
Paragraph(
|
Paragraph(
|
||||||
sco_pdf.SU(
|
sco_pdf.SU(
|
||||||
|
@ -31,8 +31,8 @@ class BulletinGenerator:
|
|||||||
description
|
description
|
||||||
supported_formats = [ 'pdf', 'html' ]
|
supported_formats = [ 'pdf', 'html' ]
|
||||||
.bul_title_pdf()
|
.bul_title_pdf()
|
||||||
.bul_table(format)
|
.bul_table(fmt)
|
||||||
.bul_part_below(format)
|
.bul_part_below(fmt)
|
||||||
.bul_signatures_pdf()
|
.bul_signatures_pdf()
|
||||||
|
|
||||||
.__init__ et .generate(format) methodes appelees par le client (sco_bulletin)
|
.__init__ et .generate(format) methodes appelees par le client (sco_bulletin)
|
||||||
@ -62,6 +62,7 @@ from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from app.models import FormSemestre, Identite
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc.sco_exceptions import NoteProcessError
|
from app.scodoc.sco_exceptions import NoteProcessError
|
||||||
from app import log
|
from app import log
|
||||||
@ -85,9 +86,11 @@ class BulletinGenerator:
|
|||||||
self,
|
self,
|
||||||
bul_dict,
|
bul_dict,
|
||||||
authuser=None,
|
authuser=None,
|
||||||
version="long",
|
etud: Identite = None,
|
||||||
filigranne=None,
|
filigranne=None,
|
||||||
|
formsemestre: FormSemestre = None,
|
||||||
server_name=None,
|
server_name=None,
|
||||||
|
version="long",
|
||||||
with_img_signatures_pdf: bool = True,
|
with_img_signatures_pdf: bool = True,
|
||||||
):
|
):
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
@ -98,9 +101,11 @@ class BulletinGenerator:
|
|||||||
self.infos = bul_dict # legacy code compat
|
self.infos = bul_dict # legacy code compat
|
||||||
# authuser nécessaire pour version HTML qui contient liens dépendants de l'utilisateur
|
# authuser nécessaire pour version HTML qui contient liens dépendants de l'utilisateur
|
||||||
self.authuser = authuser
|
self.authuser = authuser
|
||||||
self.version = version
|
self.etud: Identite = etud
|
||||||
self.filigranne = filigranne
|
self.filigranne = filigranne
|
||||||
|
self.formsemestre: FormSemestre = formsemestre
|
||||||
self.server_name = server_name
|
self.server_name = server_name
|
||||||
|
self.version = version
|
||||||
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.bul_dict["formsemestre_id"]
|
formsemestre_id = self.bul_dict["formsemestre_id"]
|
||||||
@ -151,9 +156,9 @@ class BulletinGenerator:
|
|||||||
"""Return bulletin as an HTML string"""
|
"""Return bulletin as an HTML string"""
|
||||||
H = ['<div class="notes_bulletin">']
|
H = ['<div class="notes_bulletin">']
|
||||||
# table des notes:
|
# table des notes:
|
||||||
H.append(self.bul_table(format="html")) # pylint: disable=no-member
|
H.append(self.bul_table(fmt="html")) # pylint: disable=no-member
|
||||||
# infos sous la table:
|
# infos sous la table:
|
||||||
H.append(self.bul_part_below(format="html")) # pylint: disable=no-member
|
H.append(self.bul_part_below(fmt="html")) # pylint: disable=no-member
|
||||||
H.append("</div>")
|
H.append("</div>")
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ class BulletinGenerator:
|
|||||||
nomprenom = self.bul_dict["etud"]["nomprenom"]
|
nomprenom = self.bul_dict["etud"]["nomprenom"]
|
||||||
etat_civil = self.bul_dict["etud"]["etat_civil"]
|
etat_civil = self.bul_dict["etud"]["etat_civil"]
|
||||||
marque_debut_bulletin = sco_pdf.DebutBulletin(
|
marque_debut_bulletin = sco_pdf.DebutBulletin(
|
||||||
self.bul_dict["etat_civil"],
|
etat_civil,
|
||||||
filigranne=self.bul_dict["filigranne"],
|
filigranne=self.bul_dict["filigranne"],
|
||||||
footer_content=f"""ScoDoc - Bulletin de {nomprenom} - {time.strftime("%d/%m/%Y %H:%M")}""",
|
footer_content=f"""ScoDoc - Bulletin de {nomprenom} - {time.strftime("%d/%m/%Y %H:%M")}""",
|
||||||
)
|
)
|
||||||
@ -179,9 +184,9 @@ class BulletinGenerator:
|
|||||||
index_obj_debut = len(story)
|
index_obj_debut = len(story)
|
||||||
|
|
||||||
# table des notes
|
# table des notes
|
||||||
story += self.bul_table(format="pdf") # pylint: disable=no-member
|
story += self.bul_table(fmt="pdf") # pylint: disable=no-member
|
||||||
# infos sous la table
|
# infos sous la table
|
||||||
story += self.bul_part_below(format="pdf") # pylint: disable=no-member
|
story += self.bul_part_below(fmt="pdf") # pylint: disable=no-member
|
||||||
# signatures
|
# signatures
|
||||||
story += self.bul_signatures_pdf() # pylint: disable=no-member
|
story += self.bul_signatures_pdf() # pylint: disable=no-member
|
||||||
if self.scale_table_in_page:
|
if self.scale_table_in_page:
|
||||||
@ -249,10 +254,12 @@ class BulletinGenerator:
|
|||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
def make_formsemestre_bulletinetud(
|
def make_formsemestre_bulletin_etud(
|
||||||
bul_dict,
|
bul_dict,
|
||||||
|
etud: Identite = None,
|
||||||
|
formsemestre: FormSemestre = None,
|
||||||
version=None, # short, long, selectedevals
|
version=None, # short, long, selectedevals
|
||||||
format="pdf", # html, pdf
|
fmt="pdf", # html, pdf
|
||||||
stand_alone=True,
|
stand_alone=True,
|
||||||
with_img_signatures_pdf: bool = True,
|
with_img_signatures_pdf: bool = True,
|
||||||
):
|
):
|
||||||
@ -277,7 +284,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 bul_dict.get("type") == "BUT" and format.startswith("pdf"):
|
if bul_dict.get("type") == "BUT" and fmt.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)
|
||||||
@ -290,28 +297,32 @@ def make_formsemestre_bulletinetud(
|
|||||||
bul_generator = gen_class(
|
bul_generator = gen_class(
|
||||||
bul_dict,
|
bul_dict,
|
||||||
authuser=current_user,
|
authuser=current_user,
|
||||||
version=version,
|
etud=etud,
|
||||||
filigranne=bul_dict["filigranne"],
|
filigranne=bul_dict["filigranne"],
|
||||||
|
formsemestre=formsemestre,
|
||||||
server_name=request.url_root,
|
server_name=request.url_root,
|
||||||
|
version=version,
|
||||||
with_img_signatures_pdf=with_img_signatures_pdf,
|
with_img_signatures_pdf=with_img_signatures_pdf,
|
||||||
)
|
)
|
||||||
if format not in bul_generator.supported_formats:
|
if fmt not in bul_generator.supported_formats:
|
||||||
# use standard generator
|
# use standard generator
|
||||||
log(
|
log(
|
||||||
"Bulletin format %s not supported by %s, using %s"
|
"Bulletin format %s not supported by %s, using %s"
|
||||||
% (format, bul_class_name, bulletin_default_class_name())
|
% (fmt, bul_class_name, bulletin_default_class_name())
|
||||||
)
|
)
|
||||||
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(
|
||||||
bul_dict,
|
bul_dict,
|
||||||
authuser=current_user,
|
authuser=current_user,
|
||||||
version=version,
|
etud=etud,
|
||||||
filigranne=bul_dict["filigranne"],
|
filigranne=bul_dict["filigranne"],
|
||||||
|
formsemestre=formsemestre,
|
||||||
server_name=request.url_root,
|
server_name=request.url_root,
|
||||||
|
version=version,
|
||||||
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=fmt, stand_alone=stand_alone)
|
||||||
finally:
|
finally:
|
||||||
PDFLOCK.release()
|
PDFLOCK.release()
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ from app import db, ScoDocJSONEncoder
|
|||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import but_validations
|
from app.models import but_validations
|
||||||
from app.models import Evaluation, Matiere, UniteEns
|
from app.models import BulAppreciations, Evaluation, Matiere, UniteEns
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
|
|
||||||
@ -303,18 +303,14 @@ def formsemestre_bulletinetud_published_dict(
|
|||||||
d.update(dict_decision_jury(etud, formsemestre, with_decisions=xml_with_decisions))
|
d.update(dict_decision_jury(etud, formsemestre, with_decisions=xml_with_decisions))
|
||||||
|
|
||||||
# --- Appréciations
|
# --- Appréciations
|
||||||
cnx = ndb.GetDBConnexion()
|
appreciations = BulAppreciations.get_appreciations_list(formsemestre.id, etudid)
|
||||||
apprecs = sco_etud.appreciations_list(
|
d["appreciation"] = [
|
||||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
{
|
||||||
)
|
"comment": quote_xml_attr(appreciation["comment"]),
|
||||||
d["appreciation"] = []
|
"date": appreciation.date.isoformat() if appreciation.date else "",
|
||||||
for app in apprecs:
|
}
|
||||||
d["appreciation"].append(
|
for appreciation in appreciations
|
||||||
dict(
|
]
|
||||||
comment=quote_xml_attr(app["comment"]),
|
|
||||||
date=ndb.DateDMYtoISO(app["date"]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
return d
|
return d
|
||||||
|
@ -34,10 +34,14 @@
|
|||||||
CE FORMAT N'EVOLUERA PLUS ET EST CONSIDERE COMME OBSOLETE.
|
CE FORMAT N'EVOLUERA PLUS ET EST CONSIDERE COMME OBSOLETE.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from flask import g, url_for
|
||||||
|
|
||||||
from reportlab.lib.colors import Color, blue
|
from reportlab.lib.colors import Color, blue
|
||||||
from reportlab.lib.units import cm, mm
|
from reportlab.lib.units import cm, mm
|
||||||
from reportlab.platypus import Paragraph, Spacer, Table
|
from reportlab.platypus import Paragraph, Spacer, Table
|
||||||
|
|
||||||
|
from app.models import BulAppreciations
|
||||||
from app.scodoc import sco_bulletins_generator
|
from app.scodoc import sco_bulletins_generator
|
||||||
from app.scodoc import sco_bulletins_pdf
|
from app.scodoc import sco_bulletins_pdf
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
@ -65,14 +69,14 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
) # impose un espace vertical entre le titre et la table qui suit
|
) # impose un espace vertical entre le titre et la table qui suit
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
def bul_table(self, format="html"):
|
def bul_table(self, fmt="html"):
|
||||||
"""Table bulletin"""
|
"""Table bulletin"""
|
||||||
if format == "pdf":
|
if fmt == "pdf":
|
||||||
return self.bul_table_pdf()
|
return self.bul_table_pdf()
|
||||||
elif format == "html":
|
elif fmt == "html":
|
||||||
return self.bul_table_html()
|
return self.bul_table_html()
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid bulletin format (%s)" % format)
|
raise ValueError(f"invalid bulletin format ({fmt})")
|
||||||
|
|
||||||
def bul_table_pdf(self):
|
def bul_table_pdf(self):
|
||||||
"""Génère la table centrale du bulletin de notes
|
"""Génère la table centrale du bulletin de notes
|
||||||
@ -239,16 +243,16 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
# ---------------
|
# ---------------
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
def bul_part_below(self, format="html"):
|
def bul_part_below(self, fmt="html"):
|
||||||
"""Génère les informations placées sous la table de notes
|
"""Génère les informations placées sous la table de notes
|
||||||
(absences, appréciations, décisions de jury...)
|
(absences, appréciations, décisions de jury...)
|
||||||
"""
|
"""
|
||||||
if format == "pdf":
|
if fmt == "pdf":
|
||||||
return self.bul_part_below_pdf()
|
return self.bul_part_below_pdf()
|
||||||
elif format == "html":
|
elif fmt == "html":
|
||||||
return self.bul_part_below_html()
|
return self.bul_part_below_html()
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid bulletin format (%s)" % format)
|
raise ValueError("invalid bulletin format (%s)" % fmt)
|
||||||
|
|
||||||
def bul_part_below_pdf(self):
|
def bul_part_below_pdf(self):
|
||||||
"""
|
"""
|
||||||
@ -277,11 +281,17 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# ----- APPRECIATIONS
|
# ----- APPRECIATIONS
|
||||||
if self.infos.get("appreciations_list", False):
|
appreciations = BulAppreciations.get_appreciations_list(
|
||||||
|
self.formsemestre.id, self.etud.id
|
||||||
|
)
|
||||||
|
if appreciations:
|
||||||
objects.append(Spacer(1, 3 * mm))
|
objects.append(Spacer(1, 3 * mm))
|
||||||
objects.append(
|
objects.append(
|
||||||
Paragraph(
|
Paragraph(
|
||||||
SU("Appréciation : " + "\n".join(self.infos["appreciations_txt"])),
|
SU(
|
||||||
|
"Appréciation : "
|
||||||
|
+ "\n".join(BulAppreciations.summarize(appreciations))
|
||||||
|
),
|
||||||
self.CellStyle,
|
self.CellStyle,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -325,24 +335,40 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
authuser.has_permission(Permission.ScoEtudInscrit)
|
authuser.has_permission(Permission.ScoEtudInscrit)
|
||||||
)
|
)
|
||||||
H.append('<div class="bull_appreciations">')
|
H.append('<div class="bull_appreciations">')
|
||||||
if I["appreciations_list"]:
|
appreciations = BulAppreciations.get_appreciations_list(
|
||||||
H.append("<p><b>Appréciations</b></p>")
|
self.formsemestre.id, self.etud.id
|
||||||
for app in I["appreciations_list"]:
|
|
||||||
if can_edit_app:
|
|
||||||
mlink = (
|
|
||||||
'<a class="stdlink" href="appreciation_add_form?id=%s">modifier</a> <a class="stdlink" href="appreciation_add_form?id=%s&suppress=1">supprimer</a>'
|
|
||||||
% (app["id"], app["id"])
|
|
||||||
)
|
)
|
||||||
|
if appreciations:
|
||||||
|
H.append("<p><b>Appréciations</b></p>")
|
||||||
|
for appreciation in appreciations:
|
||||||
|
if can_edit_app:
|
||||||
|
mlink = f"""<a class="stdlink" href="{
|
||||||
|
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dpt, appreciation_id=appreciation.id)
|
||||||
|
}">modifier</a>
|
||||||
|
<a class="stdlink" href="{
|
||||||
|
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dpt, appreciation_id=appreciation.id, suppress=1)
|
||||||
|
}">supprimer</a>"""
|
||||||
else:
|
else:
|
||||||
mlink = ""
|
mlink = ""
|
||||||
H.append(
|
H.append(
|
||||||
'<p><span class="bull_appreciations_date">%s</span>%s<span class="bull_appreciations_link">%s</span></p>'
|
f"""<p>
|
||||||
% (app["date"], app["comment"], mlink)
|
<span class="bull_appreciations_date">{
|
||||||
|
appreciation.date.strftime("%d/%m/%y") if appreciation.date else ""
|
||||||
|
}</span>
|
||||||
|
{appreciation.comment_safe()}
|
||||||
|
<span class="bull_appreciations_link">{mlink}</span>
|
||||||
|
</p>"""
|
||||||
)
|
)
|
||||||
if can_edit_app:
|
if can_edit_app:
|
||||||
H.append(
|
H.append(
|
||||||
'<p><a class="stdlink" href="appreciation_add_form?etudid=%(etudid)s&formsemestre_id=%(formsemestre_id)s">Ajouter une appréciation</a></p>'
|
f"""<p>
|
||||||
% self.infos
|
<a class="stdlink" href="{
|
||||||
|
url_for('notes.appreciation_add_form',
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
etudid=self.etud.id,
|
||||||
|
formsemestre_id=self.formsemestre.id)
|
||||||
|
}">Ajouter une appréciation</a>
|
||||||
|
</p>"""
|
||||||
)
|
)
|
||||||
H.append("</div>")
|
H.append("</div>")
|
||||||
# ---------------
|
# ---------------
|
||||||
|
@ -51,6 +51,7 @@ from reportlab.lib.colors import Color, blue
|
|||||||
from reportlab.lib.units import cm, mm
|
from reportlab.lib.units import cm, mm
|
||||||
from reportlab.platypus import KeepTogether, Paragraph, Spacer, Table
|
from reportlab.platypus import KeepTogether, Paragraph, Spacer, Table
|
||||||
|
|
||||||
|
from app.models import BulAppreciations
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
gen_tables,
|
gen_tables,
|
||||||
@ -92,7 +93,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
) # impose un espace vertical entre le titre et la table qui suit
|
) # impose un espace vertical entre le titre et la table qui suit
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
def bul_table(self, format="html"):
|
def bul_table(self, fmt="html"):
|
||||||
"""Génère la table centrale du bulletin de notes
|
"""Génère la table centrale du bulletin de notes
|
||||||
Renvoie:
|
Renvoie:
|
||||||
- en HTML: une chaine
|
- en HTML: une chaine
|
||||||
@ -112,9 +113,9 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
html_with_td_classes=True,
|
html_with_td_classes=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return T.gen(format=format)
|
return T.gen(format=fmt)
|
||||||
|
|
||||||
def bul_part_below(self, format="html"):
|
def bul_part_below(self, fmt="html"):
|
||||||
"""Génère les informations placées sous la table de notes
|
"""Génère les informations placées sous la table de notes
|
||||||
(absences, appréciations, décisions de jury...)
|
(absences, appréciations, décisions de jury...)
|
||||||
Renvoie:
|
Renvoie:
|
||||||
@ -156,45 +157,53 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
# ---- APPRECIATIONS
|
# ---- APPRECIATIONS
|
||||||
# le dir. des etud peut ajouter des appreciations,
|
# le dir. des etud peut ajouter des appreciations,
|
||||||
# mais aussi le chef (perm. ScoEtudInscrit)
|
# mais aussi le chef (perm. ScoEtudInscrit)
|
||||||
can_edit_app = (self.authuser.id in self.infos["responsables"]) or (
|
can_edit_app = (self.formsemestre.est_responsable(self.authuser)) or (
|
||||||
self.authuser.has_permission(Permission.ScoEtudInscrit)
|
self.authuser.has_permission(Permission.ScoEtudInscrit)
|
||||||
)
|
)
|
||||||
H.append('<div class="bull_appreciations">')
|
H.append('<div class="bull_appreciations">')
|
||||||
for app in self.infos["appreciations_list"]:
|
appreciations = BulAppreciations.get_appreciations_list(
|
||||||
|
self.formsemestre.id, self.etud.id
|
||||||
|
)
|
||||||
|
for appreciation in appreciations:
|
||||||
if can_edit_app:
|
if can_edit_app:
|
||||||
mlink = f"""<a class="stdlink" href="{
|
mlink = f"""<a class="stdlink" href="{
|
||||||
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept, id=app['id'])
|
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept, appreciation_id=appreciation.id)
|
||||||
}">modifier</a>
|
}">modifier</a>
|
||||||
<a class="stdlink" href="{
|
<a class="stdlink" href="{
|
||||||
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept, id=app['id'], suppress=1)
|
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept, appreciation_id=appreciation.id, suppress=1)
|
||||||
}">supprimer</a>"""
|
}">supprimer</a>"""
|
||||||
else:
|
else:
|
||||||
mlink = ""
|
mlink = ""
|
||||||
H.append(
|
H.append(
|
||||||
f"""<p><span class="bull_appreciations_date">{app["date"]}</span>{
|
f"""<p>
|
||||||
app["comment"]}<span class="bull_appreciations_link">{mlink}</span>
|
<span class="bull_appreciations_date">{
|
||||||
</p>"""
|
appreciation.date.strftime("%d/%m/%Y")
|
||||||
|
if appreciation.date else ""}</span>
|
||||||
|
{appreciation.comment_safe()}
|
||||||
|
<span class="bull_appreciations_link">{mlink}</span>
|
||||||
|
</p>
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
if can_edit_app:
|
if can_edit_app:
|
||||||
H.append(
|
H.append(
|
||||||
f"""<p><a class="stdlink" href="{
|
f"""<p><a class="stdlink" href="{
|
||||||
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept,
|
url_for('notes.appreciation_add_form', scodoc_dept=g.scodoc_dept,
|
||||||
etudid=self.infos['etudid'],
|
etudid=self.etud.etudid,
|
||||||
formsemestre_id=self.infos['formsemestre_id']
|
formsemestre_id=self.formsemestre.id
|
||||||
)
|
)
|
||||||
}">Ajouter une appréciation</a></p>"""
|
}">Ajouter une appréciation</a></p>"""
|
||||||
% self.infos
|
% self.infos
|
||||||
)
|
)
|
||||||
H.append("</div>")
|
H.append("</div>")
|
||||||
# Appréciations sur PDF:
|
# Appréciations sur PDF:
|
||||||
if self.infos.get("appreciations_list", False):
|
if appreciations:
|
||||||
story.append(Spacer(1, 3 * mm))
|
story.append(Spacer(1, 3 * mm))
|
||||||
try:
|
try:
|
||||||
story.append(
|
story.append(
|
||||||
Paragraph(
|
Paragraph(
|
||||||
SU(
|
SU(
|
||||||
"Appréciation : "
|
"Appréciation : "
|
||||||
+ "\n".join(self.infos["appreciations_txt"])
|
+ "\n".join(BulAppreciations.summarize(appreciations))
|
||||||
),
|
),
|
||||||
self.CellStyle,
|
self.CellStyle,
|
||||||
)
|
)
|
||||||
@ -221,14 +230,14 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
|||||||
H.append('<div class="bul_decision">' + field + "</div>")
|
H.append('<div class="bul_decision">' + field + "</div>")
|
||||||
|
|
||||||
# -----
|
# -----
|
||||||
if format == "pdf":
|
if fmt == "pdf":
|
||||||
if self.scale_table_in_page:
|
if self.scale_table_in_page:
|
||||||
# le scaling (pour tenir sur une page) semble incompatible avec
|
# le scaling (pour tenir sur une page) semble incompatible avec
|
||||||
# le KeepTogether()
|
# le KeepTogether()
|
||||||
return story
|
return story
|
||||||
else:
|
else:
|
||||||
return [KeepTogether(story)]
|
return [KeepTogether(story)]
|
||||||
elif format == "html":
|
elif fmt == "html":
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
def bul_signatures_pdf(self):
|
def bul_signatures_pdf(self):
|
||||||
|
@ -50,8 +50,7 @@ import app.scodoc.sco_utils as scu
|
|||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app import log
|
from app import log
|
||||||
from app.but.bulletin_but_xml_compat import bulletin_but_xml_compat
|
from app.but.bulletin_but_xml_compat import bulletin_but_xml_compat
|
||||||
from app.models.evaluations import Evaluation
|
from app.models import BulAppreciations, Evaluation, FormSemestre
|
||||||
from app.models.formsemestre import FormSemestre
|
|
||||||
from app.scodoc import sco_assiduites
|
from app.scodoc import sco_assiduites
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
@ -415,16 +414,13 @@ def make_xml_formsemestre_bulletinetud(
|
|||||||
else:
|
else:
|
||||||
doc.append(Element("decision", code="", etat="DEM"))
|
doc.append(Element("decision", code="", etat="DEM"))
|
||||||
# --- Appreciations
|
# --- Appreciations
|
||||||
cnx = ndb.GetDBConnexion()
|
appreciations = BulAppreciations.get_appreciations_list(formsemestre.id, etudid)
|
||||||
apprecs = sco_etud.appreciations_list(
|
for appreciation in appreciations:
|
||||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
|
||||||
)
|
|
||||||
for appr in apprecs:
|
|
||||||
x_appr = Element(
|
x_appr = Element(
|
||||||
"appreciation",
|
"appreciation",
|
||||||
date=ndb.DateDMYtoISO(appr["date"]),
|
date=appreciation.date.isoformat() if appreciation.date else "",
|
||||||
)
|
)
|
||||||
x_appr.text = quote_xml_attr(appr["comment"])
|
x_appr.text = quote_xml_attr(appreciation.comment_safe())
|
||||||
doc.append(x_appr)
|
doc.append(x_appr)
|
||||||
|
|
||||||
if is_appending:
|
if is_appending:
|
||||||
|
@ -741,31 +741,6 @@ def add_annotations_to_etud_list(etuds):
|
|||||||
etud["annotations_str"] = ", ".join(l)
|
etud["annotations_str"] = ", ".join(l)
|
||||||
|
|
||||||
|
|
||||||
# -------- APPRECIATIONS (sur bulletins) -------------------
|
|
||||||
# Les appreciations sont dans la table postgres notes_appreciations
|
|
||||||
_appreciationsEditor = ndb.EditableTable(
|
|
||||||
"notes_appreciations",
|
|
||||||
"id",
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
"date",
|
|
||||||
"etudid",
|
|
||||||
"formsemestre_id",
|
|
||||||
"author",
|
|
||||||
"comment",
|
|
||||||
"author",
|
|
||||||
),
|
|
||||||
sortkey="date desc",
|
|
||||||
convert_null_outputs_to_empty=True,
|
|
||||||
output_formators={"comment": safehtml.html_to_safe_html, "date": ndb.DateISOtoDMY},
|
|
||||||
)
|
|
||||||
|
|
||||||
appreciations_create = _appreciationsEditor.create
|
|
||||||
appreciations_delete = _appreciationsEditor.delete
|
|
||||||
appreciations_list = _appreciationsEditor.list
|
|
||||||
appreciations_edit = _appreciationsEditor.edit
|
|
||||||
|
|
||||||
|
|
||||||
# -------- Noms des Lycées à partir du code
|
# -------- Noms des Lycées à partir du code
|
||||||
def read_etablissements():
|
def read_etablissements():
|
||||||
filename = os.path.join(scu.SCO_TOOLS_DIR, scu.CONFIG.ETABL_FILENAME)
|
filename = os.path.join(scu.SCO_TOOLS_DIR, scu.CONFIG.ETABL_FILENAME)
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
app.comment}}<span
|
app.comment}}<span
|
||||||
class="bull_appreciations_link">{% if can_edit_appreciations %}<a
|
class="bull_appreciations_link">{% if can_edit_appreciations %}<a
|
||||||
class="stdlink" href="{{url_for('notes.appreciation_add_form',
|
class="stdlink" href="{{url_for('notes.appreciation_add_form',
|
||||||
scodoc_dept=g.scodoc_dept, id=app.id)}}">modifier</a>
|
scodoc_dept=g.scodoc_dept, appreciation_id=app.id)}}">modifier</a>
|
||||||
<a class="stdlink" href="{{url_for('notes.appreciation_add_form',
|
<a class="stdlink" href="{{url_for('notes.appreciation_add_form',
|
||||||
scodoc_dept=g.scodoc_dept, id=app.id, suppress=1)}}">supprimer</a>{% endif %}
|
scodoc_dept=g.scodoc_dept, appreciation_id=app.id, suppress=1)}}">supprimer</a>{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -58,6 +58,7 @@ from app.but.forms import jury_but_forms
|
|||||||
from app.comp import jury, res_sem
|
from app.comp import jury, res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import (
|
from app.models import (
|
||||||
|
BulAppreciations,
|
||||||
Evaluation,
|
Evaluation,
|
||||||
Formation,
|
Formation,
|
||||||
ScolarAutorisationInscription,
|
ScolarAutorisationInscription,
|
||||||
@ -316,14 +317,14 @@ def formsemestre_bulletinetud(
|
|||||||
if formsemestre.formation.is_apc() and format == "html":
|
if formsemestre.formation.is_apc() and format == "html":
|
||||||
return render_template(
|
return render_template(
|
||||||
"but/bulletin.j2",
|
"but/bulletin.j2",
|
||||||
appreciations=models.BulAppreciations.query.filter_by(
|
appreciations=BulAppreciations.get_appreciations_list(
|
||||||
etudid=etudid, formsemestre_id=formsemestre.id
|
formsemestre.id, etud.id
|
||||||
).order_by(models.BulAppreciations.date),
|
),
|
||||||
bul_url=url_for(
|
bul_url=url_for(
|
||||||
"notes.formsemestre_bulletinetud",
|
"notes.formsemestre_bulletinetud",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
etudid=etudid,
|
etudid=etud.id,
|
||||||
format="json",
|
format="json",
|
||||||
force_publishing=1, # pour ScoDoc lui même
|
force_publishing=1, # pour ScoDoc lui même
|
||||||
version=version,
|
version=version,
|
||||||
@ -2039,64 +2040,72 @@ sco_publish(
|
|||||||
def appreciation_add_form(
|
def appreciation_add_form(
|
||||||
etudid=None,
|
etudid=None,
|
||||||
formsemestre_id=None,
|
formsemestre_id=None,
|
||||||
id=None, # si id, edit
|
appreciation_id=None, # si id, edit
|
||||||
suppress=False, # si true, supress id
|
suppress=False, # si true, supress id
|
||||||
):
|
):
|
||||||
"form ajout ou edition d'une appreciation"
|
"form ajout ou edition d'une appreciation"
|
||||||
cnx = ndb.GetDBConnexion()
|
if appreciation_id: # edit mode
|
||||||
if id: # edit mode
|
appreciation = db.session.get(BulAppreciations, appreciation_id)
|
||||||
apps = sco_etud.appreciations_list(cnx, args={"id": id})
|
if appreciation is None:
|
||||||
if not apps:
|
|
||||||
raise ScoValueError("id d'appreciation invalide !")
|
raise ScoValueError("id d'appreciation invalide !")
|
||||||
app = apps[0]
|
formsemestre_id = appreciation.formsemestre_id
|
||||||
formsemestre_id = app["formsemestre_id"]
|
etudid = appreciation.etudid
|
||||||
etudid = app["etudid"]
|
etud: Identite = Identite.query.filter_by(
|
||||||
|
id=etudid, dept_id=g.scodoc_dept_id
|
||||||
|
).first_or_404()
|
||||||
vals = scu.get_request_args()
|
vals = scu.get_request_args()
|
||||||
if "edit" in vals:
|
if "edit" in vals:
|
||||||
edit = int(vals["edit"])
|
edit = int(vals["edit"])
|
||||||
elif id:
|
elif appreciation_id:
|
||||||
edit = 1
|
edit = 1
|
||||||
else:
|
else:
|
||||||
edit = 0
|
edit = 0
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
# check custom access permission
|
# check custom access permission
|
||||||
can_edit_app = (current_user.id in sem["responsables"]) or (
|
can_edit_app = formsemestre.est_responsable(current_user) or (
|
||||||
current_user.has_permission(Permission.ScoEtudInscrit)
|
current_user.has_permission(Permission.ScoEtudInscrit)
|
||||||
)
|
)
|
||||||
if not can_edit_app:
|
if not can_edit_app:
|
||||||
raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation")
|
raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation")
|
||||||
#
|
#
|
||||||
bull_url = "formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" % (
|
bul_url = url_for(
|
||||||
formsemestre_id,
|
"notes.formsemestre_bulletinetud",
|
||||||
etudid,
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
etudid=etudid,
|
||||||
)
|
)
|
||||||
|
|
||||||
if suppress:
|
if suppress:
|
||||||
sco_etud.appreciations_delete(cnx, id)
|
db.session.delete(appreciation)
|
||||||
logdb(cnx, method="appreciation_suppress", etudid=etudid, msg="")
|
Scolog.logdb(
|
||||||
return flask.redirect(bull_url)
|
method="appreciation_suppress",
|
||||||
|
etudid=etudid,
|
||||||
|
)
|
||||||
|
db.session.commit()
|
||||||
|
flash("appréciation supprimée")
|
||||||
|
return flask.redirect(bul_url)
|
||||||
#
|
#
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
if appreciation_id:
|
||||||
if id:
|
action = "Édition"
|
||||||
a = "Edition"
|
|
||||||
else:
|
else:
|
||||||
a = "Ajout"
|
action = "Ajout"
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header()
|
html_sco_header.sco_header(),
|
||||||
+ "<h2>%s d'une appréciation sur %s</h2>" % (a, etud["nomprenom"])
|
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
||||||
]
|
]
|
||||||
F = html_sco_header.sco_footer()
|
F = html_sco_header.sco_footer()
|
||||||
descr = [
|
descr = [
|
||||||
("edit", {"input_type": "hidden", "default": edit}),
|
("edit", {"input_type": "hidden", "default": edit}),
|
||||||
("etudid", {"input_type": "hidden"}),
|
("etudid", {"input_type": "hidden"}),
|
||||||
("formsemestre_id", {"input_type": "hidden"}),
|
("formsemestre_id", {"input_type": "hidden"}),
|
||||||
("id", {"input_type": "hidden"}),
|
("appreciation_id", {"input_type": "hidden"}),
|
||||||
("comment", {"title": "", "input_type": "textarea", "rows": 4, "cols": 60}),
|
("comment", {"title": "", "input_type": "textarea", "rows": 4, "cols": 60}),
|
||||||
]
|
]
|
||||||
if id:
|
if appreciation_id:
|
||||||
initvalues = {
|
initvalues = {
|
||||||
"etudid": etudid,
|
"etudid": etudid,
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
"comment": app["comment"],
|
"comment": appreciation.comment,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
initvalues = {}
|
initvalues = {}
|
||||||
@ -2111,31 +2120,33 @@ def appreciation_add_form(
|
|||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + "\n" + tf[1] + F
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(bull_url)
|
return flask.redirect(bul_url)
|
||||||
else:
|
else:
|
||||||
args = {
|
|
||||||
"etudid": etudid,
|
|
||||||
"formsemestre_id": formsemestre_id,
|
|
||||||
"author": current_user.user_name,
|
|
||||||
"comment": tf[2]["comment"],
|
|
||||||
}
|
|
||||||
if edit:
|
if edit:
|
||||||
args["id"] = id
|
appreciation.author = (current_user.user_name,)
|
||||||
sco_etud.appreciations_edit(cnx, args)
|
appreciation.comment = tf[2]["comment"].strip()
|
||||||
|
flash("appréciation modifiée")
|
||||||
else: # nouvelle
|
else: # nouvelle
|
||||||
sco_etud.appreciations_create(cnx, args)
|
appreciation = BulAppreciations(
|
||||||
|
etudid=etudid,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
author=current_user.user_name,
|
||||||
|
comment=tf[2]["comment"].strip(),
|
||||||
|
)
|
||||||
|
flash("appréciation ajoutée")
|
||||||
|
db.session.add(appreciation)
|
||||||
# log
|
# log
|
||||||
logdb(
|
Scolog.logdb(
|
||||||
cnx,
|
|
||||||
method="appreciation_add",
|
method="appreciation_add",
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
msg=tf[2]["comment"],
|
msg=appreciation.comment_safe(),
|
||||||
)
|
)
|
||||||
|
db.session.commit()
|
||||||
# ennuyeux mais necessaire (pour le PDF seulement)
|
# ennuyeux mais necessaire (pour le PDF seulement)
|
||||||
sco_cache.invalidate_formsemestre(
|
sco_cache.invalidate_formsemestre(
|
||||||
pdfonly=True, formsemestre_id=formsemestre_id
|
pdfonly=True, formsemestre_id=formsemestre_id
|
||||||
) # > appreciation_add
|
) # > appreciation_add
|
||||||
return flask.redirect(bull_url)
|
return flask.redirect(bul_url)
|
||||||
|
|
||||||
|
|
||||||
# --- FORMULAIRE POUR VALIDATION DES UE ET SEMESTRES
|
# --- FORMULAIRE POUR VALIDATION DES UE ET SEMESTRES
|
||||||
|
Loading…
Reference in New Issue
Block a user