forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -234,6 +234,14 @@ class User(UserMixin, db.Model, ScoDocModel):
|
|||||||
return None
|
return None
|
||||||
return db.session.get(User, user_id)
|
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):
|
def to_dict(self, include_email=True):
|
||||||
"""l'utilisateur comme un dict, avec des champs supplémentaires"""
|
"""l'utilisateur comme un dict, avec des champs supplémentaires"""
|
||||||
data = {
|
data = {
|
||||||
|
@ -208,5 +208,3 @@ def cas_users_import_config():
|
|||||||
title=_("Importation configuration CAS utilisateurs"),
|
title=_("Importation configuration CAS utilisateurs"),
|
||||||
form=form,
|
form=form,
|
||||||
)
|
)
|
||||||
|
|
||||||
return
|
|
||||||
|
@ -22,6 +22,7 @@ class Module(db.Model):
|
|||||||
abbrev = db.Column(db.Text()) # nom court
|
abbrev = db.Column(db.Text()) # nom court
|
||||||
# certains départements ont des codes infiniment longs: donc Text !
|
# certains départements ont des codes infiniment longs: donc Text !
|
||||||
code = db.Column(db.Text(), nullable=False)
|
code = db.Column(db.Text(), nullable=False)
|
||||||
|
"code module, chaine non nullable"
|
||||||
heures_cours = db.Column(db.Float)
|
heures_cours = db.Column(db.Float)
|
||||||
heures_td = db.Column(db.Float)
|
heures_td = db.Column(db.Float)
|
||||||
heures_tp = db.Column(db.Float)
|
heures_tp = db.Column(db.Float)
|
||||||
|
@ -268,7 +268,7 @@ def get_user_list(
|
|||||||
q = q.filter_by(active=True)
|
q = q.filter_by(active=True)
|
||||||
if having_role:
|
if having_role:
|
||||||
q = q.join(UserRole).filter_by(role_id=having_role.id)
|
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
|
@cache.memoize(timeout=50) # seconds
|
||||||
|
@ -30,7 +30,6 @@ Module notes: issu de ScoDoc7 / ZNotes.py
|
|||||||
|
|
||||||
Emmanuel Viennet, 2021
|
Emmanuel Viennet, 2021
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@ -59,6 +58,7 @@ 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 (
|
||||||
ApcNiveau,
|
ApcNiveau,
|
||||||
|
Assiduite,
|
||||||
BulAppreciations,
|
BulAppreciations,
|
||||||
DispenseUE,
|
DispenseUE,
|
||||||
Evaluation,
|
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)
|
"""Liste les enseignants intervenants dans le semestre (resp. modules et chargés de TD)
|
||||||
et indique les absences saisies par chacun.
|
et indique les absences saisies par chacun.
|
||||||
"""
|
"""
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
# resp. de modules:
|
# resp. de modules et charges de TD
|
||||||
mods = sco_moduleimpl.moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
|
sem_ens: dict[
|
||||||
sem_ens = {}
|
int, list[ModuleImpl]
|
||||||
for mod in mods:
|
] = {} # uid : { "mods" : liste des modimpls, ... }
|
||||||
if not mod["responsable_id"] in sem_ens:
|
modimpls = formsemestre.modimpls_sorted
|
||||||
sem_ens[mod["responsable_id"]] = {"mods": [mod]}
|
for modimpl in modimpls:
|
||||||
|
if not modimpl.responsable_id in sem_ens:
|
||||||
|
sem_ens[modimpl.responsable_id] = {"mods": [modimpl]}
|
||||||
else:
|
else:
|
||||||
sem_ens[mod["responsable_id"]]["mods"].append(mod)
|
sem_ens[modimpl.responsable_id]["mods"].append(modimpl)
|
||||||
# charges de TD:
|
|
||||||
for mod in mods:
|
for enseignant in modimpl.enseignants:
|
||||||
for ensd in mod["ens"]:
|
if not enseignant.id in sem_ens:
|
||||||
if not ensd["ens_id"] in sem_ens:
|
sem_ens[enseignant.id] = {"mods": [modimpl]}
|
||||||
sem_ens[ensd["ens_id"]] = {"mods": [mod]}
|
|
||||||
else:
|
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
|
# compte les absences ajoutées par chacun dans tout le semestre
|
||||||
cnx = ndb.GetDBConnexion()
|
for uid, info in sem_ens.items():
|
||||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
# Note : avant 9.6, on utilisait Scolog pour compter les opérations AddAbsence
|
||||||
for ens in sem_ens:
|
# ici on compte directement les assiduités
|
||||||
u = User.query.filter_by(id=ens).first()
|
info["nbabsadded"] = (
|
||||||
if not u:
|
Assiduite.query.filter_by(user_id=uid, etat=scu.EtatAssiduite.ABSENT)
|
||||||
continue
|
.filter(
|
||||||
cursor.execute(
|
Assiduite.date_debut >= formsemestre.date_debut,
|
||||||
"""SELECT * FROM scolog L, notes_formsemestre_inscription I
|
Assiduite.date_debut <= formsemestre.date_fin,
|
||||||
WHERE method = 'AddAbsence'
|
)
|
||||||
and authenticated_user = %(authenticated_user)s
|
.join(Identite)
|
||||||
and L.etudid = I.etudid
|
.join(FormSemestreInscription)
|
||||||
and I.formsemestre_id = %(formsemestre_id)s
|
.filter_by(formsemestre_id=formsemestre.id)
|
||||||
and date > %(date_debut)s
|
.count()
|
||||||
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"]),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
events = cursor.dictfetchall()
|
|
||||||
sem_ens[ens]["nbabsadded"] = len(events)
|
|
||||||
|
|
||||||
# description textuelle des modules
|
# description textuelle des modules
|
||||||
for ens in sem_ens:
|
for uid, info in sem_ens.items():
|
||||||
sem_ens[ens]["descr_mods"] = ", ".join(
|
info["descr_mods"] = ", ".join(
|
||||||
[x["module"]["code"] or "?" for x in sem_ens[ens]["mods"]]
|
[modimpl.module.code for modimpl in sem_ens[uid]["mods"]]
|
||||||
)
|
)
|
||||||
|
|
||||||
# ajoute infos sur enseignant:
|
# ajoute infos sur enseignant:
|
||||||
for ens in sem_ens:
|
for uid, info in sem_ens.items():
|
||||||
sem_ens[ens].update(sco_users.user_info(ens))
|
user: User = db.session.get(User, uid)
|
||||||
if sem_ens[ens]["email"]:
|
if user:
|
||||||
sem_ens[ens]["_email_target"] = "mailto:%s" % sem_ens[ens]["email"]
|
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 = list(sem_ens.values())
|
||||||
sem_ens_list.sort(key=itemgetter("nomprenom"))
|
sem_ens_list.sort(key=itemgetter("sort_key"))
|
||||||
|
|
||||||
# --- Generate page with table
|
# --- Generate page with table
|
||||||
title = "Enseignants de " + sem["titremois"]
|
title = f"Enseignants de {formsemestre.titre_mois()}"
|
||||||
T = GenTable(
|
T = GenTable(
|
||||||
columns_ids=["nom_fmt", "prenom_fmt", "descr_mods", "nbabsadded", "email"],
|
columns_ids=["nom_fmt", "prenom_fmt", "descr_mods", "nbabsadded", "email"],
|
||||||
titles={
|
titles={
|
||||||
@ -1338,12 +1332,13 @@ def formsemestre_enseignants_list(formsemestre_id, fmt="html"):
|
|||||||
rows=sem_ens_list,
|
rows=sem_ens_list,
|
||||||
html_sortable=True,
|
html_sortable=True,
|
||||||
html_class="table_leftalign",
|
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(
|
html_title=html_sco_header.html_sem_header(
|
||||||
"Enseignants du semestre", with_page_header=False
|
"Enseignants du semestre", with_page_header=False
|
||||||
),
|
),
|
||||||
base_url="%s?formsemestre_id=%s" % (request.base_url, formsemestre_id),
|
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 le nombre d'opérations d'ajout effectuées sur ce semestre, sans tenir compte des annulations ou double saisies.",
|
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),
|
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
||||||
)
|
)
|
||||||
return T.make_page(page_title=title, title=title, fmt=fmt)
|
return T.make_page(page_title=title, title=title, fmt=fmt)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.6.70"
|
SCOVERSION = "9.6.71"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user