# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Tableau de bord semestre
"""
# Rewritten from ancient DTML code
from notes_log import log
import sco_utils as scu
from sco_permissions import (
ScoImplement,
ScoChangeFormation,
ScoEtudInscrit,
ScoView,
ScoEtudChangeAdr,
)
from sco_exceptions import ScoValueError
import VERSION
import htmlutils
from sco_formsemestre_custommenu import formsemestre_custommenu_html
from gen_tables import GenTable
import sco_archives
import sco_groups
import sco_evaluations
import sco_formsemestre
import sco_formsemestre_edit
import sco_moduleimpl
import sco_compute_moy
import sco_codes_parcours
import sco_bulletins
# H = [ """
# """ % (cssclass, title)
# ]
# for item in items:
# if item.get('enabled', True):
# if base_url:
# item['urlq'] = urllib.quote(item['url'])
# else:
# item['urlq'] = item['url']
# H.append('- %(title)s
' % item)
# else:
# H.append('' % item)
# H.append('
%s>' % elem)
# return ''.join(H)
def defMenuStats(context, formsemestre_id):
"Définition du menu 'Statistiques' "
return [
{
"title": "Statistiques...",
"url": "formsemestre_report_counts?formsemestre_id=" + formsemestre_id,
},
{
"title": "Suivi de cohortes",
"url": "formsemestre_suivi_cohorte?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
{
"title": "Graphe des parcours",
"url": "formsemestre_graph_parcours?formsemestre_id=" + formsemestre_id,
"enabled": scu.WITH_PYDOT,
},
{
"title": "Codes des parcours",
"url": "formsemestre_suivi_parcours?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
{
"title": "Lycées d'origine",
"url": "formsemestre_etuds_lycees?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
{
"title": 'Table "poursuite"',
"url": "formsemestre_poursuite_report?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
{
"title": "Documents Avis Poursuite Etudes",
"url": "pe_view_sem_recap?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
{"title": 'Table "débouchés"', "url": "report_debouche_date", "enabled": True},
{
"title": "Estimation du coût de la formation",
"url": "formsemestre_estim_cost?formsemestre_id=" + formsemestre_id,
"enabled": True,
},
# { 'title' : 'experimental sub',
# 'submenu' : [
# { 'title' : 'sous 1',
# 'url' : '#' },
# { 'title' : 'sous 2',
# 'url' : '#' },
# { 'title' : 'sous 3',
# 'url' : '#' },
# ]
# },
]
def formsemestre_status_menubar(context, sem, REQUEST):
"""HTML to render menubar"""
authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser)
formsemestre_id = sem["formsemestre_id"]
if int(sem["etat"]):
change_lock_msg = "Verrouiller"
else:
change_lock_msg = "Déverrouiller"
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
menuSemestre = [
{
"title": "Tableau de bord",
"url": "formsemestre_status?formsemestre_id=%(formsemestre_id)s" % sem,
"enabled": True,
"helpmsg": "Tableau de bord du semestre",
},
{
"title": "Voir la formation %(acronyme)s (v%(version)s)" % F,
"url": "ue_list?formation_id=%(formation_id)s" % sem,
"enabled": True,
"helpmsg": "Tableau de bord du semestre",
},
{
"title": "Modifier le semestre",
"url": "formsemestre_editwithmodules?formation_id=%(formation_id)s&formsemestre_id=%(formsemestre_id)s"
% sem,
"enabled": (
authuser.has_permission(ScoImplement, context)
or (
str(REQUEST.AUTHENTICATED_USER) in sem["responsables"]
and sem["resp_can_edit"]
)
)
and (sem["etat"] == "1"),
"helpmsg": "Modifie le contenu du semestre (modules)",
},
{
"title": "Préférences du semestre",
"url": "formsemestre_edit_preferences?formsemestre_id=%(formsemestre_id)s"
% sem,
"enabled": (
authuser.has_permission(ScoImplement, context)
or (
str(REQUEST.AUTHENTICATED_USER) in sem["responsables"]
and sem["resp_can_edit"]
)
)
and (sem["etat"] == "1"),
"helpmsg": "Préférences du semestre",
},
{
"title": "Réglages bulletins",
"url": "formsemestre_edit_options?formsemestre_id=" + formsemestre_id,
"enabled": (uid in sem["responsables"])
or authuser.has_permission(ScoImplement, context),
"helpmsg": "Change les options",
},
{
"title": change_lock_msg,
"url": "formsemestre_change_lock?formsemestre_id=" + formsemestre_id,
"enabled": (uid in sem["responsables"])
or authuser.has_permission(ScoImplement, context),
"helpmsg": "",
},
{
"title": "Description du semestre",
"url": "formsemestre_description?formsemestre_id=" + formsemestre_id,
"enabled": True,
"helpmsg": "",
},
{
"title": "Vérifier absences aux évaluations",
"url": "formsemestre_check_absences_html?formsemestre_id="
+ formsemestre_id,
"enabled": True,
"helpmsg": "",
},
{
"title": "Lister tous les enseignants",
"url": "formsemestre_enseignants_list?formsemestre_id=" + formsemestre_id,
"enabled": True,
"helpmsg": "",
},
{
"title": "Cloner ce semestre",
"url": "formsemestre_clone?formsemestre_id=" + formsemestre_id,
"enabled": authuser.has_permission(ScoImplement, context),
"helpmsg": "",
},
{
"title": "Associer à une nouvelle version du programme",
"url": "formsemestre_associate_new_version?formsemestre_id="
+ formsemestre_id,
"enabled": authuser.has_permission(ScoChangeFormation, context)
and (sem["etat"] == "1"),
"helpmsg": "",
},
{
"title": "Supprimer ce semestre",
"url": "formsemestre_delete?formsemestre_id=" + formsemestre_id,
"enabled": authuser.has_permission(ScoImplement, context),
"helpmsg": "",
},
]
# debug :
if uid == "root" or uid[:7] == "viennet":
menuSemestre.append(
{
"title": "Check integrity",
"url": "check_sem_integrity?formsemestre_id=" + formsemestre_id,
"enabled": True,
}
)
menuInscriptions = [
{
"title": "Voir les inscriptions aux modules",
"url": "moduleimpl_inscriptions_stats?formsemestre_id=" + formsemestre_id,
}
]
menuInscriptions += [
{
"title": "Passage des étudiants depuis d'autres semestres",
"url": "formsemestre_inscr_passage?formsemestre_id=" + formsemestre_id,
"enabled": authuser.has_permission(ScoEtudInscrit, context)
and (sem["etat"] == "1"),
},
{
"title": "Synchroniser avec étape Apogée",
"url": "formsemestre_synchro_etuds?formsemestre_id=" + formsemestre_id,
"enabled": authuser.has_permission(ScoView, context)
and context.get_preference("portal_url")
and (sem["etat"] == "1"),
},
{
"title": "Inscrire un étudiant",
"url": "formsemestre_inscription_with_modules_etud?formsemestre_id="
+ formsemestre_id,
"enabled": authuser.has_permission(ScoEtudInscrit, context)
and (sem["etat"] == "1"),
},
{
"title": "Importer des étudiants dans ce semestre (table Excel)",
"url": "form_students_import_excel?formsemestre_id=" + formsemestre_id,
"enabled": authuser.has_permission(ScoEtudInscrit, context)
and (sem["etat"] == "1"),
},
{
"title": "Import/export des données admission",
"url": "form_students_import_infos_admissions?formsemestre_id="
+ formsemestre_id,
"enabled": authuser.has_permission(ScoView, context),
},
{
"title": "Resynchroniser données identité",
"url": "formsemestre_import_etud_admission?formsemestre_id="
+ formsemestre_id,
"enabled": authuser.has_permission(ScoEtudChangeAdr, context)
and context.get_preference("portal_url"),
},
{
"title": "Exporter table des étudiants",
"url": "groups_view?format=allxls&group_ids="
+ sco_groups.get_default_group(
context, formsemestre_id, fix_if_missing=True, REQUEST=REQUEST
),
},
{
"title": "Vérifier inscriptions multiples",
"url": "formsemestre_inscrits_ailleurs?formsemestre_id=" + formsemestre_id,
},
]
menuGroupes = [
{
"title": "Listes, photos, feuilles...",
"url": "groups_view?formsemestre_id=" + formsemestre_id,
"enabled": True,
"helpmsg": "Accès aux listes des groupes d'étudiants",
},
# On laisse l'accès à l'ancienne page, le temps de tester
{
"title": "Listes (ancienne page)",
"url": "formsemestre_lists?formsemestre_id=" + formsemestre_id,
"enabled": True,
"helpmsg": "Accès aux listes des groupes d'étudiants",
},
{
"title": "Créer/modifier les partitions...",
"url": "editPartitionForm?formsemestre_id=" + formsemestre_id,
"enabled": sco_groups.can_change_groups(context, REQUEST, formsemestre_id),
},
]
# 1 item / partition:
partitions = sco_groups.get_partitions_list(
context, formsemestre_id, with_default=False
)
submenu = []
enabled = (
sco_groups.can_change_groups(context, REQUEST, formsemestre_id) and partitions
)
for partition in partitions:
submenu.append(
{
"title": "%s" % partition["partition_name"],
"url": "affectGroups?partition_id=%s" % partition["partition_id"],
"enabled": enabled,
}
)
menuGroupes.append(
{"title": "Modifier les groupes", "submenu": submenu, "enabled": enabled}
)
menuNotes = [
{
"title": "Tableau des moyennes (et liens bulletins)",
"url": "formsemestre_recapcomplet?formsemestre_id=" + formsemestre_id,
},
{
"title": "Saisie des notes",
"url": "formsemestre_status?formsemestre_id=%(formsemestre_id)s" % sem,
"enabled": True,
"helpmsg": "Tableau de bord du semestre",
},
{
"title": "Classeur PDF des bulletins",
"url": "formsemestre_bulletins_pdf_choice?formsemestre_id="
+ formsemestre_id,
"helpmsg": "PDF regroupant tous les bulletins",
},
{
"title": "Envoyer à chaque étudiant son bulletin par e-mail",
"url": "formsemestre_bulletins_mailetuds_choice?formsemestre_id="
+ formsemestre_id,
"enabled": sco_bulletins.can_send_bulletin_by_mail(
context, formsemestre_id, REQUEST
),
},
{
"title": "Calendrier des évaluations",
"url": "formsemestre_evaluations_cal?formsemestre_id=" + formsemestre_id,
},
{
"title": "Lister toutes les saisies de notes",
"url": "formsemestre_list_saisies_notes?formsemestre_id=" + formsemestre_id,
},
]
menuJury = [
{
"title": "Voir les décisions du jury",
"url": "formsemestre_pvjury?formsemestre_id=" + formsemestre_id,
},
{
"title": "Générer feuille préparation Jury",
"url": "feuille_preparation_jury?formsemestre_id=" + formsemestre_id,
},
{
"title": "Saisie des décisions du jury",
"url": "formsemestre_recapcomplet?modejury=1&hidemodules=1&hidebac=1&pref_override=0&formsemestre_id="
+ formsemestre_id,
"enabled": context._can_validate_sem(REQUEST, formsemestre_id),
},
{
"title": "Editer les PV et archiver les résultats",
"url": "formsemestre_archive?formsemestre_id=" + formsemestre_id,
"enabled": context._can_edit_pv(REQUEST, formsemestre_id),
},
{
"title": "Documents archivés",
"url": "formsemestre_list_archives?formsemestre_id=" + formsemestre_id,
"enabled": sco_archives.PVArchive.list_obj_archives(
context, formsemestre_id
),
},
]
menuStats = defMenuStats(context, formsemestre_id)
base_url = context.absolute_url() + "/" # context must be Notes
H = [
# '
]
return "\n".join(H)
def retreive_formsemestre_from_request(context, REQUEST):
"""Cherche si on a de quoi déduire le semestre affiché à partir des
arguments de la requête:
formsemestre_id ou moduleimpl ou evaluation ou group_id ou partition_id
"""
# Search formsemestre
group_ids = REQUEST.form.get("group_ids", [])
if REQUEST.form.has_key("formsemestre_id"):
formsemestre_id = REQUEST.form["formsemestre_id"]
elif REQUEST.form.has_key("moduleimpl_id"):
modimpl = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=REQUEST.form["moduleimpl_id"]
)
if not modimpl:
return None # suppressed ?
modimpl = modimpl[0]
formsemestre_id = modimpl["formsemestre_id"]
elif REQUEST.form.has_key("evaluation_id"):
E = context.do_evaluation_list({"evaluation_id": REQUEST.form["evaluation_id"]})
if not E:
return None # evaluation suppressed ?
E = E[0]
modimpl = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
formsemestre_id = modimpl["formsemestre_id"]
elif REQUEST.form.has_key("group_id"):
group = sco_groups.get_group(context, REQUEST.form["group_id"])
formsemestre_id = group["formsemestre_id"]
elif group_ids:
if group_ids:
if type(group_ids) == str:
group_id = group_ids
else:
# prend le semestre du 1er groupe de la liste:
group_id = group_ids[0]
group = sco_groups.get_group(context, group_id)
formsemestre_id = group["formsemestre_id"]
elif REQUEST.form.has_key("partition_id"):
partition = sco_groups.get_partition(context, REQUEST.form["partition_id"])
formsemestre_id = partition["formsemestre_id"]
else:
return None # no current formsemestre
return formsemestre_id
# Element HTML decrivant un semestre (barre de menu et infos)
def formsemestre_page_title(context, REQUEST):
"""Element HTML decrivant un semestre (barre de menu et infos)
Cherche dans REQUEST si un semestre est défini (formsemestre_id ou moduleimpl ou evaluation ou group)
"""
try:
context = context.Notes
except:
pass
formsemestre_id = retreive_formsemestre_from_request(context, REQUEST)
#
if not formsemestre_id:
return ""
try:
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id).copy()
except:
log("can't find formsemestre_id %s" % formsemestre_id)
return ""
fill_formsemestre(context, sem, REQUEST=REQUEST)
H = [
"""""",
"""
"""
% sem,
formsemestre_status_menubar(context, sem, REQUEST),
"""
""",
]
return "\n".join(H)
def fill_formsemestre(context, sem, REQUEST=None):
"""Add some useful fields to help display formsemestres"""
notes_url = context.NotesURL()
sem["notes_url"] = notes_url
formsemestre_id = sem["formsemestre_id"]
if sem["etat"] != "1":
sem[
"locklink"
] = """%s""" % (
notes_url,
sem["formsemestre_id"],
scu.icontag("lock_img", border="0", title="Semestre verrouillé"),
)
else:
sem["locklink"] = ""
if context.get_preference("bul_display_publication", formsemestre_id):
if sem["bul_hide_xml"] != "0":
eyeicon = scu.icontag("hide_img", border="0", title="Bulletins NON publiés")
else:
eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés")
sem["eyelink"] = (
"""%s"""
% (notes_url, sem["formsemestre_id"], eyeicon)
)
else:
sem["eyelink"] = ""
F = context.Notes.formation_list(args={"formation_id": sem["formation_id"]})[0]
sem["formation"] = F
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
if sem["semestre_id"] != -1:
sem["num_sem"] = ", %s %s" % (parcours.SESSION_NAME, sem["semestre_id"])
else:
sem["num_sem"] = "" # formation sans semestres
if sem["modalite"]:
sem["modalitestr"] = " en %s" % sem["modalite"]
else:
sem["modalitestr"] = ""
sem["etape_apo_str"] = "Code étape Apogée: " + (
sco_formsemestre.formsemestre_etape_apo_str(sem) or "Pas de code étape"
)
inscrits = context.Notes.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id}
)
sem["nbinscrits"] = len(inscrits)
uresps = [
context.Users.user_info(responsable_id)
for responsable_id in sem["responsables"]
]
sem["resp"] = ", ".join([u["prenomnom"] for u in uresps])
sem["nomcomplet"] = ", ".join([u["nomcomplet"] for u in uresps])
# Description du semestre sous forme de table exportable
def formsemestre_description_table(
context, formsemestre_id, REQUEST=None, with_evals=False
):
"""Description du semestre sous forme de table exportable
Liste des modules et de leurs coefficients
"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
nt = context._getNotesCache().get_NotesTable(
context, formsemestre_id
) # > liste evaluations
use_ue_coefs = context.get_preference("use_ue_coefs", formsemestre_id)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
R = []
sum_coef = 0
sum_ects = 0
last_ue_id = None
for M in Mlist:
# Ligne UE avec ECTS:
ue = M["ue"]
if ue["ue_id"] != last_ue_id:
last_ue_id = ue["ue_id"]
if ue["ects"] is None:
ects_str = "-"
else:
sum_ects += ue["ects"]
ects_str = ue["ects"]
ue_info = {
"UE": ue["acronyme"],
"ects": ects_str,
"Module": ue["titre"],
"_css_row_class": "table_row_ue",
}
if use_ue_coefs:
ue_info["Coef."] = ue["coefficient"]
ue_info["Coef._class"] = "ue_coef"
R.append(ue_info)
ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_id"]
)
enseignants = ", ".join(
[
context.Users.user_info(m["ens_id"], REQUEST)["nomprenom"]
for m in M["ens"]
]
)
l = {
"UE": M["ue"]["acronyme"],
"Code": M["module"]["code"],
"Module": M["module"]["abbrev"] or M["module"]["titre"],
"_Module_class": "scotext",
"Inscrits": len(ModInscrits),
"Responsable": context.Users.user_info(M["responsable_id"])["nomprenom"],
"_Responsable_class": "scotext",
"Enseignants": enseignants,
"_Enseignants_class": "scotext",
"Coef.": M["module"]["coefficient"],
# 'ECTS' : M['module']['ects'],
# Lien sur titre -> module
"_Module_target": "moduleimpl_status?moduleimpl_id=" + M["moduleimpl_id"],
"_Code_target": "moduleimpl_status?moduleimpl_id=" + M["moduleimpl_id"],
}
R.append(l)
if M["module"]["coefficient"]:
sum_coef += M["module"]["coefficient"]
if with_evals:
# Ajoute lignes pour evaluations
evals = nt.get_mod_evaluation_etat_list(M["moduleimpl_id"])
evals.reverse() # ordre chronologique
# Ajoute etat:
for e in evals:
# Cosmetic: conversions pour affichage
if e["etat"]["evalcomplete"]:
e["evalcomplete_str"] = "Oui"
e["_evalcomplete_str_td_attrs"] = 'style="color: green;"'
else:
e["evalcomplete_str"] = "Non"
e["_evalcomplete_str_td_attrs"] = 'style="color: red;"'
if int(e["publish_incomplete"]):
e["publish_incomplete_str"] = "Oui"
e["_publish_incomplete_str_td_attrs"] = 'style="color: green;"'
else:
e["publish_incomplete_str"] = "Non"
e["_publish_incomplete_str_td_attrs"] = 'style="color: red;"'
R += evals
sums = {"_css_row_class": "moyenne sortbottom", "ects": sum_ects, "Coef.": sum_coef}
R.append(sums)
columns_ids = ["UE", "Code", "Module", "Coef."]
if context.get_preference("bul_show_ects", formsemestre_id):
columns_ids += ["ects"]
columns_ids += ["Inscrits", "Responsable", "Enseignants"]
if with_evals:
columns_ids += [
"jour",
"description",
"coefficient",
"evalcomplete_str",
"publish_incomplete_str",
]
titles = {title: title for title in columns_ids}
titles["ects"] = "ECTS"
titles["jour"] = "Evaluation"
titles["description"] = ""
titles["coefficient"] = "Coef. éval."
titles["evalcomplete_str"] = "Complète"
titles["publish_incomplete_str"] = "Toujours Utilisée"
title = "%s %s" % (scu.strcapitalize(parcours.SESSION_NAME), sem["titremois"])
return GenTable(
columns_ids=columns_ids,
rows=R,
titles=titles,
origin="Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr() + "",
caption=title,
html_caption=title,
html_class="table_leftalign formsemestre_description",
base_url="%s?formsemestre_id=%s&with_evals=%s"
% (REQUEST.URL0, formsemestre_id, with_evals),
page_title=title,
html_title=context.html_sem_header(
REQUEST, "Description du semestre", sem, with_page_header=False
),
pdf_title=title,
preferences=context.get_preferences(formsemestre_id),
)
def formsemestre_description(
context, formsemestre_id, format="html", with_evals=False, REQUEST=None
):
"""Description du semestre sous forme de table exportable
Liste des modules et de leurs coefficients
"""
with_evals = int(with_evals)
tab = formsemestre_description_table(
context, formsemestre_id, REQUEST, with_evals=with_evals
)
tab.html_before_table = """"
return tab.make_page(context, format=format, REQUEST=REQUEST)
def formsemestre_lists(context, formsemestre_id, REQUEST=None):
"""Listes des étudiants
XXX (ancienne page, remplacée par groups_view, va être supprimée)
"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [
context.html_sem_header(REQUEST, "", sem),
_make_listes_sem(context, sem, REQUEST),
context.sco_footer(REQUEST),
]
return "\n".join(H)
# genere liste html pour accès aux groupes de ce semestre
# XXX #sco8 vérifier si c'est encore utilisé !
def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
context = context
authuser = REQUEST.AUTHENTICATED_USER
r = context.ScoURL() # root url
# construit l'URL "destination"
# (a laquelle on revient apres saisie absences)
query_args = cgi.parse_qs(REQUEST.QUERY_STRING)
if "head_message" in query_args:
del query_args["head_message"]
destination = "%s?%s" % (REQUEST.URL, urllib.urlencode(query_args, True))
destination = destination.replace(
"%", "%%"
) # car ici utilisee dans un format string !
#
H = []
# pas de menu absences si pas autorise:
if with_absences and not authuser.has_permission(ScoAbsChange, context):
with_absences = False
#
H.append(
'Listes de %(titre)s (%(mois_debut)s - %(mois_fin)s)
'
% sem
)
formsemestre_id = sem["formsemestre_id"]
# calcule dates 1er jour semaine pour absences
try:
if with_absences:
first_monday = sco_abs.ddmmyyyy(sem["date_debut"]).prev_monday()
FA = [] # formulaire avec menu saisi absences
FA.append(
'
| ")
FormAbs = "\n".join(FA)
else:
FormAbs = ""
except ScoInvalidDateError: # dates incorrectes dans semestres ?
FormAbs = ""
#
H.append('')
# Genere liste pour chaque partition (categorie de groupes)
for partition in sco_groups.get_partitions_list(context, sem["formsemestre_id"]):
if not partition["partition_name"]:
H.append("
Tous les étudiants
" % partition)
else:
H.append("
Groupes de %(partition_name)s
" % partition)
groups = sco_groups.get_partition_groups(context, partition)
if groups:
H.append("
")
for group in groups:
n_members = len(
sco_groups.get_group_members(context, group["group_id"])
)
group["url"] = r
if group["group_name"]:
group["label"] = "groupe %(group_name)s" % group
else:
group["label"] = "liste"
H.append('')
H.append(
"""
%(label)s
|
(format tableur)
Photos
| """
% group
)
H.append("(%d étudiants) | " % n_members)
if with_absences:
H.append(FormAbs % group)
H.append("
")
H.append("
")
else:
H.append('
Aucun groupe dans cette partition')
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
H.append(
' (créer)'
% partition["partition_id"]
)
H.append("
")
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
H.append(
'
'
% formsemestre_id
)
H.append("
")
return "\n".join(H)
def html_expr_diagnostic(context, diagnostics):
"""Affiche messages d'erreur des formules utilisateurs"""
H = []
H.append('Erreur dans des formules utilisateurs:
')
last_id, last_msg = None, None
for diag in diagnostics:
if "moduleimpl_id" in diag:
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=diag["moduleimpl_id"]
)[0]
H.append(
'- module %s: %s
'
% (
diag["moduleimpl_id"],
mod["module"]["abbrev"] or mod["module"]["code"] or "?",
diag["msg"],
)
)
else:
if diag["ue_id"] != last_id or diag["msg"] != last_msg:
ue = context.do_ue_list({"ue_id": diag["ue_id"]})[0]
H.append(
'- UE "%s": %s
'
% (ue["acronyme"] or ue["titre"] or "?", diag["msg"])
)
last_id, last_msg = diag["ue_id"], diag["msg"]
H.append("
")
return "".join(H)
def formsemestre_status_head(
context, formsemestre_id=None, REQUEST=None, page_title=None
):
"""En-tête HTML des pages "semestre" """
semlist = sco_formsemestre.do_formsemestre_list(
context, args={"formsemestre_id": formsemestre_id}
)
if not semlist:
raise ScoValueError("Session inexistante (elle a peut être été supprimée ?)")
sem = semlist[0]
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
page_title = page_title or "Modules de "
H = [
context.html_sem_header(
REQUEST, page_title, sem, with_page_header=False, with_h2=False
),
"""
Formation: |
%(titre)s"""
% F,
]
if sem["semestre_id"] >= 0:
H.append(", %s %s" % (parcours.SESSION_NAME, sem["semestre_id"]))
if sem["modalite"]:
H.append(" en %(modalite)s" % sem)
if sem["etapes"]:
H.append(
" (étape %s)"
% (sem["etapes_apo_str"] or "-")
)
H.append(" |
")
evals = sco_evaluations.do_evaluation_etat_in_sem(context, formsemestre_id)
H.append(
'Evaluations: | %(nb_evals_completes)s ok, %(nb_evals_en_cours)s en cours, %(nb_evals_vides)s vides'
% evals
)
if evals["last_modif"]:
H.append(
" (dernière note saisie le %s)"
% evals["last_modif"].strftime("%d/%m/%Y à %Hh%M")
)
H.append(" |
")
if evals["attente"]:
H.append(
""" |
Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur indicative.
|
"""
)
H.append("
")
if sem["bul_hide_xml"] != "0":
H.append(
'Bulletins non publiés sur le portail
'
)
if sem["semestre_id"] >= 0 and not sco_formsemestre.sem_une_annee(context, sem):
H.append(
'Attention: ce semestre couvre plusieurs années scolaires !
'
)
# elif context.get_preference('bul_display_publication', formsemestre_id):
# H.append('Bulletins publiés sur le portail
')
return "".join(H)
def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
"""Tableau de bord semestre HTML"""
# porté du DTML
cnx = context.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
# inscrits = context.do_formsemestre_inscription_list(
# args={"formsemestre_id": formsemestre_id}
# )
prev_ue_id = None
can_edit = sco_formsemestre_edit.can_edit_sem(
context, REQUEST, formsemestre_id, sem=sem
)
H = [
context.sco_header(REQUEST, page_title="Semestre %s" % sem["titreannee"]),
'