Envoi bulletin, génération classeur: choix groupe étudiants

This commit is contained in:
Emmanuel Viennet 2024-02-22 16:43:00 +01:00
parent f1ce70e6de
commit 13e7bd4512
3 changed files with 149 additions and 96 deletions

View File

@ -62,10 +62,13 @@ from flask import g, request
from app import log, ScoValueError
from app.comp.res_but import ResultatsSemestreBUT
from app.models import FormSemestre, Identite
from app.scodoc import sco_cache
from app.scodoc import codes_cursus
from app.scodoc import sco_pdf
from app.scodoc import sco_preferences
from app.scodoc import (
codes_cursus,
sco_cache,
sco_groups_view,
sco_pdf,
sco_preferences,
)
from app.scodoc.sco_logos import find_logo
import app.scodoc.sco_utils as scu
@ -211,7 +214,11 @@ def process_field(
)
def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"):
def get_formsemestre_bulletins_pdf(
formsemestre_id,
version="selectedevals",
groups_infos=None, # si indiqué, ne prend que ces groupes
):
"Document pdf avec tous les bulletins du semestre, et filename"
from app.but import bulletin_but_court
from app.scodoc import sco_bulletins
@ -226,13 +233,20 @@ def get_formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"):
raise ScoValueError(
"get_formsemestre_bulletins_pdf: version de bulletin demandée invalide !"
)
cached = sco_cache.SemBulletinsPDFCache.get(str(formsemestre_id) + "_" + version)
etuds = formsemestre.get_inscrits(include_demdef=True, order=True)
if groups_infos is not None:
etudids = {m["etudid"] for m in groups_infos.members}
etuds = [etud for etud in etuds if etud.id in etudids]
cache_key = (
str(formsemestre_id) + "_" + version + "_" + groups_infos.get_groups_key()
)
cached = sco_cache.SemBulletinsPDFCache.get(cache_key)
if cached:
return cached[1], cached[0]
fragments = []
# Make each bulletin
for etud in formsemestre.get_inscrits(include_demdef=True, order=True):
for etud in etuds:
if version == "butcourt":
frag = bulletin_but_court.bulletin_but_court_pdf_frag(etud, formsemestre)
else:

View File

@ -331,6 +331,7 @@ class DisplayedGroupsInfos:
empty_list_select_all=True,
moduleimpl_id=None, # used to find formsemestre when unspecified
):
group_ids = [] if group_ids is None else group_ids
if isinstance(group_ids, int):
if group_ids:
group_ids = [group_ids] # cas ou un seul parametre, pas de liste
@ -466,6 +467,10 @@ class DisplayedGroupsInfos:
else None
)
def get_groups_key(self) -> str:
"clé identifiant les groupes sélectionnés, utile pour cache"
return "-".join(str(x) for x in sorted(self.group_ids))
# Ancien ZScolar.group_list renommé ici en group_table
def groups_table(

View File

@ -90,7 +90,6 @@ from app.decorators import (
# ---------------
from app.pe import pe_view # ne pas enlever, ajoute des vues
from app.scodoc import sco_bulletins_json, sco_utils as scu
from app.scodoc import notesdb as ndb
from app import log, send_scodoc_alarm
from app.scodoc.sco_exceptions import (
@ -98,59 +97,62 @@ from app.scodoc.sco_exceptions import (
ScoValueError,
ScoInvalidIdType,
)
from app.scodoc import html_sco_header
from app.scodoc import sco_apogee_compare
from app.scodoc import sco_archives_formsemestre
from app.scodoc import sco_assiduites
from app.scodoc import sco_bulletins
from app.scodoc import sco_bulletins_pdf
from app.scodoc import sco_cache
from app.scodoc import sco_cost_formation
from app.scodoc import sco_debouche
from app.scodoc import sco_edit_apc
from app.scodoc import sco_edit_formation
from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue
from app.scodoc import sco_etape_apogee_view
from app.scodoc import sco_etud
from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_check_abs
from app.scodoc import sco_evaluation_db
from app.scodoc import sco_evaluation_edit
from app.scodoc import sco_evaluation_recap
from app.scodoc import sco_export_results
from app.scodoc import sco_formations
from app.scodoc import sco_formation_recap
from app.scodoc import sco_formation_versions
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_custommenu
from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_formsemestre_exterieurs
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_inscr_passage
from app.scodoc import sco_liste_notes
from app.scodoc import sco_lycee
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_moduleimpl_inscriptions
from app.scodoc import sco_moduleimpl_status
from app.scodoc import sco_placement
from app.scodoc import sco_poursuite_dut
from app.scodoc import sco_preferences
from app.scodoc import sco_prepajury
from app.scodoc import sco_pv_forms
from app.scodoc import sco_recapcomplet
from app.scodoc import sco_report
from app.scodoc import sco_report_but
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_semset
from app.scodoc import sco_synchro_etuds
from app.scodoc import sco_tag_module
from app.scodoc import sco_ue_external
from app.scodoc import sco_undo_notes
from app.scodoc import sco_users
from app.scodoc import (
html_sco_header,
sco_apogee_compare,
sco_archives_formsemestre,
sco_assiduites,
sco_bulletins,
sco_bulletins_pdf,
sco_cache,
sco_cost_formation,
sco_debouche,
sco_edit_apc,
sco_edit_formation,
sco_edit_matiere,
sco_edit_module,
sco_edit_ue,
sco_etape_apogee_view,
sco_etud,
sco_evaluations,
sco_evaluation_check_abs,
sco_evaluation_db,
sco_evaluation_edit,
sco_evaluation_recap,
sco_export_results,
sco_formations,
sco_formation_recap,
sco_formation_versions,
sco_formsemestre,
sco_formsemestre_custommenu,
sco_formsemestre_edit,
sco_formsemestre_exterieurs,
sco_formsemestre_inscriptions,
sco_formsemestre_status,
sco_formsemestre_validation,
sco_groups_view,
sco_inscr_passage,
sco_liste_notes,
sco_lycee,
sco_moduleimpl,
sco_moduleimpl_inscriptions,
sco_moduleimpl_status,
sco_placement,
sco_poursuite_dut,
sco_preferences,
sco_prepajury,
sco_pv_forms,
sco_recapcomplet,
sco_report,
sco_report_but,
sco_saisie_notes,
sco_semset,
sco_synchro_etuds,
sco_tag_module,
sco_ue_external,
sco_undo_notes,
sco_users,
)
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_pv_dict import descr_autorisations
from app.scodoc.sco_permissions import Permission
@ -1844,10 +1846,20 @@ sco_publish(
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
def formsemestre_bulletins_pdf(formsemestre_id, version="selectedevals"):
def formsemestre_bulletins_pdf(
formsemestre_id,
group_ids: list[int] = None, # si indiqué, ne prend que ces groupes
version="selectedevals",
):
"Publie les bulletins dans un classeur PDF"
# Informations sur les groupes à utiliser:
groups_infos = sco_groups_view.DisplayedGroupsInfos(
group_ids,
formsemestre_id=formsemestre_id,
select_all_when_unspecified=True,
)
pdfdoc, filename = sco_bulletins_pdf.get_formsemestre_bulletins_pdf(
formsemestre_id, version=version
formsemestre_id, groups_infos=groups_infos, version=version
)
return scu.sendPDFFile(pdfdoc, filename)
@ -1864,18 +1876,29 @@ _EXPL_BULL = """Versions des bulletins:
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
def formsemestre_bulletins_pdf_choice(formsemestre_id, version=None):
def formsemestre_bulletins_pdf_choice(
formsemestre_id,
version=None,
group_ids: list[int] = None, # si indiqué, ne prend que ces groupes
):
"""Choix version puis envoi classeur bulletins pdf"""
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
# Informations sur les groupes à utiliser:
groups_infos = sco_groups_view.DisplayedGroupsInfos(
group_ids,
formsemestre_id=formsemestre_id,
select_all_when_unspecified=True,
)
if version:
pdfdoc, filename = sco_bulletins_pdf.get_formsemestre_bulletins_pdf(
formsemestre_id, version=version
formsemestre_id, groups_infos=groups_infos, version=version
)
return scu.sendPDFFile(pdfdoc, filename)
return _formsemestre_bulletins_choice(
formsemestre,
title="Choisir la version des bulletins à générer",
explanation=_EXPL_BULL,
groups_infos=groups_infos,
title="Choisir la version des bulletins à générer",
)
@ -1900,8 +1923,15 @@ def formsemestre_bulletins_mailetuds_choice(
version=None,
dialog_confirmed=False,
prefer_mail_perso=0,
group_ids: list[int] = None, # si indiqué, ne prend que ces groupes
):
"""Choix version puis envoi classeur bulletins pdf"""
# Informations sur les groupes à utiliser:
groups_infos = sco_groups_view.DisplayedGroupsInfos(
group_ids,
formsemestre_id=formsemestre_id,
select_all_when_unspecified=True,
)
if version:
return flask.redirect(
url_for(
@ -1909,8 +1939,9 @@ def formsemestre_bulletins_mailetuds_choice(
scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id,
version=version,
dialog_confirmed=dialog_confirmed,
dialog_confirmed=int(dialog_confirmed),
prefer_mail_perso=prefer_mail_perso,
group_ids=groups_infos.group_ids,
)
)
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
@ -1934,45 +1965,41 @@ def formsemestre_bulletins_mailetuds_choice(
</p><p>"""
+ expl_bull,
choose_mail=True,
groups_infos=groups_infos,
)
# not published
def _formsemestre_bulletins_choice(
formsemestre: FormSemestre, title="", explanation="", choose_mail=False
formsemestre: FormSemestre,
title="",
explanation="",
choose_mail=False,
groups_infos=None,
):
"""Choix d'une version de bulletin"""
versions = (
"""Choix d'une version de bulletin
(pour envois mail ou génération classeur pdf)
"""
versions_bulletins = (
scu.BULLETINS_VERSIONS_BUT
if formsemestre.formation.is_apc()
else scu.BULLETINS_VERSIONS
)
H = [
html_sco_header.html_sem_header(title),
f"""
<form name="f" method="GET" action="{request.base_url}">
<input type="hidden" name="formsemestre_id" value="{formsemestre.id}"></input>
""",
]
H.append("""<select name="version" class="noprint">""")
for version, description in versions.items():
H.append(f"""<option value="{version}">{description}</option>""")
H.append("""</select>&nbsp;&nbsp;<input type="submit" value="Générer"/>""")
if choose_mail:
H.append(
"""<div>
<input type="checkbox" name="prefer_mail_perso" value="1"
/>Utiliser si possible les adresses personnelles
</div>"""
return render_template(
"formsemestre/bulletins_choice.j2",
explanation=explanation,
choose_mail=choose_mail,
formsemestre=formsemestre,
menu_groups_choice=sco_groups_view.menu_groups_choice(groups_infos),
sco=ScoData(formsemestre=formsemestre),
sco_groups_view=sco_groups_view,
title=title,
versions_bulletins=versions_bulletins,
)
H.append(f"""<p class="help">{explanation}</p>""")
return "\n".join(H) + html_sco_header.sco_footer()
@bp.route("/formsemestre_bulletins_mailetuds")
@bp.route("/formsemestre_bulletins_mailetuds", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
@ -1981,16 +2008,23 @@ def formsemestre_bulletins_mailetuds(
version="long",
dialog_confirmed=False,
prefer_mail_perso=0,
group_ids: list[int] = None, # si indiqué, ne prend que ces groupes
):
"""Envoie à chaque etudiant son bulletin
(inscrit non démissionnaire ni défaillant et ayant un mail renseigné dans ScoDoc)
"""
groups_infos = sco_groups_view.DisplayedGroupsInfos(
group_ids,
formsemestre_id=formsemestre_id,
select_all_when_unspecified=True,
)
etudids = {m["etudid"] for m in groups_infos.members}
prefer_mail_perso = int(prefer_mail_perso)
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
inscriptions = [
inscription
for inscription in formsemestre.inscriptions
if inscription.etat == scu.INSCRIT
if inscription.etat == scu.INSCRIT and inscription.etudid in etudids
]
#
if not sco_bulletins.can_send_bulletin_by_mail(formsemestre_id):
@ -1998,7 +2032,7 @@ def formsemestre_bulletins_mailetuds(
# Confirmation dialog
if not dialog_confirmed:
return scu.confirm_dialog(
f"<h2>Envoyer les {len(inscriptions)} bulletins par e-mail aux étudiants inscrits ?",
f"<h2>Envoyer les {len(inscriptions)} bulletins par e-mail aux étudiants inscrits sélectionnés ?",
dest_url="",
cancel_url=url_for(
"notes.formsemestre_status",