This commit is contained in:
Emmanuel Viennet 2023-09-10 19:37:01 +02:00
commit 0a1fb71801
4 changed files with 107 additions and 5 deletions

View File

@ -1097,10 +1097,12 @@ def mail_bulletin(formsemestre_id, infos, pdfdata, filename, recipient_addr):
hea = "" hea = ""
if sco_preferences.get_preference("bul_mail_list_abs"): if sco_preferences.get_preference("bul_mail_list_abs"):
hea += "\n\n" + "(LISTE D'ABSENCES NON DISPONIBLE)" # XXX TODO-ASSIDUITE from app.views.assiduites import generate_bul_list
# sco_abs_views.ListeAbsEtud(
# etud["etudid"], with_evals=False, format="text" etud_identite: Identite = Identite.get_etud(etud["etudid"])
# ) form_semestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id)
hea += "\n\n"
hea += generate_bul_list(etud_identite, form_semestre)
subject = f"""Relevé de notes de {etud["nomprenom"]}""" subject = f"""Relevé de notes de {etud["nomprenom"]}"""
recipients = [recipient_addr] recipients = [recipient_addr]

View File

@ -1750,6 +1750,17 @@ class BasePreferences:
"category": "bul_mail", "category": "bul_mail",
}, },
), ),
(
"bul_mail_list_abs_nb",
{
"initvalue": 10,
"title": "Nombre maximum de dates par catégorie",
"explanation": "dans la liste des absences dans le mail envoyant le bulletin de notes (catégories : abs,abs_just, retard,justificatifs)",
"type": "int",
"size": 3,
"category": "bul_mail",
},
),
( (
"bul_mail_contact_addr", "bul_mail_contact_addr",
{ {

View File

@ -0,0 +1,16 @@
<=== Assiduité ===>
--- Absences non justifiées {{stats.absent[metric] - stats.absent.justifie[metric]}} ({{metrique}}) ---
{% for assi in abs_nj %}- Absence non just. {{assi.date}}
{% endfor %}
--- Absences justifiées {{stats.absent.justifie[metric]}} ({{metrique}}) ---
{% for assi in abs_j %}- Absence just. {{assi.date}}
{% endfor %}
--- Retard {{stats.retard[metric]}} ({{metrique}}) ---
{% for assi in retards %}- Retard {{assi.date}}
{% endfor %}
--- Justificatif ---
{% for justi in justifs %}- Justificatif {{justi.date}} {{justi.raison}} : {{justi.etat}}
{% endfor %}

View File

@ -16,6 +16,7 @@ from app.models import (
Identite, Identite,
ScoDocSiteConfig, ScoDocSiteConfig,
Assiduite, Assiduite,
Justificatif,
Departement, Departement,
FormSemestreInscription, FormSemestreInscription,
Evaluation, Evaluation,
@ -1082,7 +1083,7 @@ def signal_evaluation_abs(etudid: int = None, evaluation_id: int = None):
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
duplication="oui", duplication="oui",
) )
raise ScoValueError(msg, dest) raise ScoValueError(msg, dest) from see
db.session.add(assiduite_unique) db.session.add(assiduite_unique)
db.session.commit() db.session.commit()
@ -1098,9 +1099,81 @@ def signal_evaluation_abs(etudid: int = None, evaluation_id: int = None):
) )
def generate_bul_list(etud: Identite, semestre: FormSemestre) -> str:
"""Génère la liste des assiduités d'un étudiant pour le bulletin mail"""
metrique: str = scu.translate_assiduites_metric(
sco_preferences.get_preference("assi_metrique", formsemestre_id=semestre.id),
)
max_nb: int = int(
sco_preferences.get_preference(
"bul_mail_list_abs_nb", formsemestre_id=semestre.id
)
)
assiduites = scass.filter_by_formsemestre(
etud.assiduites, Assiduite, semestre
).order_by(Assiduite.entry_date.desc())
justificatifs = scass.filter_by_formsemestre(
etud.justificatifs, Justificatif, semestre
).order_by(Justificatif.entry_date.desc())
stats: dict = scass.get_assiduites_stats(
assiduites, metric=metrique, filtered={"split": True}
)
abs_j: list[str] = [
{"date": _get_date_str(assi.date_debut, assi.date_fin)}
for assi in assiduites
if assi.etat == scu.EtatAssiduite.ABSENT and assi.est_just is True
]
abs_nj: list[str] = [
{"date": _get_date_str(assi.date_debut, assi.date_fin)}
for assi in assiduites
if assi.etat == scu.EtatAssiduite.ABSENT and assi.est_just is False
]
retards: list[str] = [
{"date": _get_date_str(assi.date_debut, assi.date_fin)}
for assi in assiduites
if assi.etat == scu.EtatAssiduite.RETARD
]
justifs: list[dict[str, str]] = [
{
"date": _get_date_str(justi.date_debut, justi.date_fin),
"raison": "" if justi.raison is None else justi.raison,
"etat": {
scu.EtatJustificatif.VALIDE: "justificatif valide",
scu.EtatJustificatif.NON_VALIDE: "justificatif invalide",
scu.EtatJustificatif.ATTENTE: "justificatif en attente de validation",
scu.EtatJustificatif.MODIFIE: "justificatif ayant été modifié",
}.get(justi.etat),
}
for justi in justificatifs
]
return render_template(
"assiduites/widgets/liste_assiduites_mail.j2",
abs_j=abs_j[:max_nb],
abs_nj=abs_nj[:max_nb],
retards=retards[:max_nb],
justifs=justifs[:max_nb],
stats=stats,
metrique=scu.translate_assiduites_metric(metrique, short=True, inverse=False),
metric=metrique,
)
# --- Fonctions internes --- # --- Fonctions internes ---
def _get_date_str(deb: datetime.datetime, fin: datetime.datetime) -> str:
if deb.date() == fin.date():
temps = deb.strftime("%d/%m/%Y %H:%M").split(" ") + [fin.strftime("%H:%M")]
return f"le {temps[0]} de {temps[1]} à {temps[2]}"
return f'du {deb.strftime("%d/%m/%Y %H:%M")} au {fin.strftime("%d/%m/%Y %H:%M")}'
def _get_days_between_dates(deb: str, fin: str): def _get_days_between_dates(deb: str, fin: str):
if deb is None or fin is None: if deb is None or fin is None:
return "null" return "null"