formsemestre_enseignants_list: ré-écriture, fix #756

This commit is contained in:
Emmanuel Viennet 2023-12-15 03:37:55 +01:00
parent 515cbaf406
commit 88124fa388
6 changed files with 58 additions and 56 deletions

View File

@ -234,6 +234,14 @@ class User(UserMixin, db.Model, ScoDocModel):
return None
return db.session.get(User, user_id)
def sort_key(self) -> tuple:
"sort key"
return (
(self.nom or "").upper(),
(self.prenom or "").upper(),
(self.user_name or "").upper(),
)
def to_dict(self, include_email=True):
"""l'utilisateur comme un dict, avec des champs supplémentaires"""
data = {

View File

@ -208,5 +208,3 @@ def cas_users_import_config():
title=_("Importation configuration CAS utilisateurs"),
form=form,
)
return

View File

@ -22,6 +22,7 @@ class Module(db.Model):
abbrev = db.Column(db.Text()) # nom court
# certains départements ont des codes infiniment longs: donc Text !
code = db.Column(db.Text(), nullable=False)
"code module, chaine non nullable"
heures_cours = db.Column(db.Float)
heures_td = db.Column(db.Float)
heures_tp = db.Column(db.Float)

View File

@ -268,7 +268,7 @@ def get_user_list(
q = q.filter_by(active=True)
if having_role:
q = q.join(UserRole).filter_by(role_id=having_role.id)
return q.order_by(User.nom, User.user_name).all()
return q.order_by(User.nom, User.prenom, User.user_name).all()
@cache.memoize(timeout=50) # seconds

View File

@ -30,7 +30,6 @@ Module notes: issu de ScoDoc7 / ZNotes.py
Emmanuel Viennet, 2021
"""
from operator import itemgetter
import time
@ -59,6 +58,7 @@ from app.comp import jury, res_sem
from app.comp.res_compat import NotesTableCompat
from app.models import (
ApcNiveau,
Assiduite,
BulAppreciations,
DispenseUE,
Evaluation,
@ -1266,66 +1266,60 @@ def formsemestre_enseignants_list(formsemestre_id, fmt="html"):
"""Liste les enseignants intervenants dans le semestre (resp. modules et chargés de TD)
et indique les absences saisies par chacun.
"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
# resp. de modules:
mods = sco_moduleimpl.moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
sem_ens = {}
for mod in mods:
if not mod["responsable_id"] in sem_ens:
sem_ens[mod["responsable_id"]] = {"mods": [mod]}
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
# resp. de modules et charges de TD
sem_ens: dict[
int, list[ModuleImpl]
] = {} # uid : { "mods" : liste des modimpls, ... }
modimpls = formsemestre.modimpls_sorted
for modimpl in modimpls:
if not modimpl.responsable_id in sem_ens:
sem_ens[modimpl.responsable_id] = {"mods": [modimpl]}
else:
sem_ens[mod["responsable_id"]]["mods"].append(mod)
# charges de TD:
for mod in mods:
for ensd in mod["ens"]:
if not ensd["ens_id"] in sem_ens:
sem_ens[ensd["ens_id"]] = {"mods": [mod]}
sem_ens[modimpl.responsable_id]["mods"].append(modimpl)
for enseignant in modimpl.enseignants:
if not enseignant.id in sem_ens:
sem_ens[enseignant.id] = {"mods": [modimpl]}
else:
sem_ens[ensd["ens_id"]]["mods"].append(mod)
sem_ens[enseignant.id]["mods"].append(modimpl)
# compte les absences ajoutées par chacun dans tout le semestre
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
for ens in sem_ens:
u = User.query.filter_by(id=ens).first()
if not u:
continue
cursor.execute(
"""SELECT * FROM scolog L, notes_formsemestre_inscription I
WHERE method = 'AddAbsence'
and authenticated_user = %(authenticated_user)s
and L.etudid = I.etudid
and I.formsemestre_id = %(formsemestre_id)s
and date > %(date_debut)s
and date < %(date_fin)s
""",
{
"authenticated_user": u.user_name,
"formsemestre_id": formsemestre_id,
"date_debut": ndb.DateDMYtoISO(sem["date_debut"]),
"date_fin": ndb.DateDMYtoISO(sem["date_fin"]),
},
for uid, info in sem_ens.items():
# Note : avant 9.6, on utilisait Scolog pour compter les opérations AddAbsence
# ici on compte directement les assiduités
info["nbabsadded"] = (
Assiduite.query.filter_by(user_id=uid, etat=scu.EtatAssiduite.ABSENT)
.filter(
Assiduite.date_debut >= formsemestre.date_debut,
Assiduite.date_debut <= formsemestre.date_fin,
)
.join(Identite)
.join(FormSemestreInscription)
.filter_by(formsemestre_id=formsemestre.id)
.count()
)
events = cursor.dictfetchall()
sem_ens[ens]["nbabsadded"] = len(events)
# description textuelle des modules
for ens in sem_ens:
sem_ens[ens]["descr_mods"] = ", ".join(
[x["module"]["code"] or "?" for x in sem_ens[ens]["mods"]]
for uid, info in sem_ens.items():
info["descr_mods"] = ", ".join(
[modimpl.module.code for modimpl in sem_ens[uid]["mods"]]
)
# ajoute infos sur enseignant:
for ens in sem_ens:
sem_ens[ens].update(sco_users.user_info(ens))
if sem_ens[ens]["email"]:
sem_ens[ens]["_email_target"] = "mailto:%s" % sem_ens[ens]["email"]
for uid, info in sem_ens.items():
user: User = db.session.get(User, uid)
if user:
if user.email:
info["email"] = user.email
info["_email_target"] = f"mailto:{user.email}"
info["nom_fmt"] = user.get_nom_fmt()
info["prenom_fmt"] = user.get_prenom_fmt()
info["sort_key"] = user.sort_key()
sem_ens_list = list(sem_ens.values())
sem_ens_list.sort(key=itemgetter("nomprenom"))
sem_ens_list.sort(key=itemgetter("sort_key"))
# --- Generate page with table
title = "Enseignants de " + sem["titremois"]
title = f"Enseignants de {formsemestre.titre_mois()}"
T = GenTable(
columns_ids=["nom_fmt", "prenom_fmt", "descr_mods", "nbabsadded", "email"],
titles={
@ -1338,12 +1332,13 @@ def formsemestre_enseignants_list(formsemestre_id, fmt="html"):
rows=sem_ens_list,
html_sortable=True,
html_class="table_leftalign",
filename=scu.make_filename("Enseignants-" + sem["titreannee"]),
filename=scu.make_filename(f"Enseignants-{formsemestre.titre_annee()}"),
html_title=html_sco_header.html_sem_header(
"Enseignants du semestre", with_page_header=False
),
base_url="%s?formsemestre_id=%s" % (request.base_url, formsemestre_id),
caption="Tous les enseignants (responsables ou associés aux modules de ce semestre) apparaissent. Le nombre de saisies d'absences est le nombre d'opérations d'ajout effectuées sur ce semestre, sans tenir compte des annulations ou double saisies.",
base_url=f"{request.base_url}?formsemestre_id={formsemestre_id}",
caption="""Tous les enseignants (responsables ou associés aux modules de
ce semestre) apparaissent. Le nombre de saisies d'absences est indicatif.""",
preferences=sco_preferences.SemPreferences(formsemestre_id),
)
return T.make_page(page_title=title, title=title, fmt=fmt)

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "9.6.70"
SCOVERSION = "9.6.71"
SCONAME = "ScoDoc"