# -*- 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 = [ """' % 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 = [ #
', '
    ', htmlutils.make_menu("Semestre", menuSemestre, base_url=base_url), htmlutils.make_menu("Inscriptions", menuInscriptions, base_url=base_url), htmlutils.make_menu("Groupes", menuGroupes, base_url=base_url), htmlutils.make_menu("Notes", menuNotes, base_url=base_url), htmlutils.make_menu("Jury", menuJury, base_url=base_url), htmlutils.make_menu("Statistiques", menuStats, base_url=base_url), formsemestre_custommenu_html(context, formsemestre_id, base_url=base_url), "
", #'
' ] 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 = """
Erreur dans des formules utilisateurs:") 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 ), """") evals = sco_evaluations.do_evaluation_etat_in_sem(context, formsemestre_id) H.append( '") if evals["attente"]: H.append( """""" ) H.append("
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("
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("
Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur indicative.
") 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"]), '
', formsemestre_status_head( context, formsemestre_id=formsemestre_id, page_title="Tableau de bord" ), """

Tableau de bord: cliquez sur un module pour saisir des notes

""", ] nt = context._getNotesCache().get_NotesTable(context, formsemestre_id) if nt.expr_diagnostics: H.append(html_expr_diagnostic(context, nt.expr_diagnostics)) H.append( """

""" ) mails_enseignants = set( [ context.Users.user_info(ens_id, REQUEST)["email"] for ens_id in sem["responsables"] ] ) # adr. mail des enseignants for M in Mlist: Mod = M["module"] ModDescr = ( "Module " + M["module"]["titre"] + ", coef. " + str(M["module"]["coefficient"]) ) ModEns = context.Users.user_info(M["responsable_id"])["nomcomplet"] if M["ens"]: ModEns += " (resp.), " + ", ".join( [context.Users.user_info(e["ens_id"])["nomcomplet"] for e in M["ens"]] ) ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list( context, moduleimpl_id=M["moduleimpl_id"] ) mails_enseignants.add( context.Users.user_info(M["responsable_id"], REQUEST)["email"] ) mails_enseignants |= set( [context.Users.user_info(m["ens_id"], REQUEST)["email"] for m in M["ens"]] ) ue = M["ue"] if prev_ue_id != ue["ue_id"]: prev_ue_id = ue["ue_id"] acronyme = ue["acronyme"] titre = ue["titre"] if context.get_preference("use_ue_coefs", formsemestre_id): titre += " (coef. %s)" % (ue["coefficient"] or 0.0) H.append( """") if M["ue"]["type"] != sco_codes_parcours.UE_STANDARD: fontorange = " fontorange" # style css additionnel else: fontorange = "" etat = sco_evaluations.do_evaluation_etat_in_mod( context, nt, M["moduleimpl_id"] ) if ( etat["nb_evals_completes"] > 0 and etat["nb_evals_en_cours"] == 0 and etat["nb_evals_vides"] == 0 ): H.append('' % fontorange) else: H.append('' % fontorange) H.append( '' % (M["moduleimpl_id"], ModDescr, Mod["code"]) ) H.append( '' % (M["moduleimpl_id"], ModDescr, Mod["abbrev"] or Mod["titre"]) ) H.append('' % len(ModInscrits)) H.append( '' % ( M["moduleimpl_id"], ModEns, context.Users.user_info(M["responsable_id"])["prenomnom"], ) ) if Mod["module_type"] == scu.MODULE_STANDARD: H.append('") H.append("
Code Module Inscrits Responsable Evaluations
%s %s """ % (acronyme, titre) ) expr = sco_compute_moy.get_ue_expression( formsemestre_id, ue["ue_id"], cnx, html_quote=True ) if can_edit: H.append( ' ' % (formsemestre_id, ue["ue_id"]) ) H.append( scu.icontag( "formula", title="Mode calcul moyenne d'UE", style="vertical-align:middle", ) ) if can_edit: H.append("") if expr: H.append( """ %s""" % expr ) H.append("
%s%s%s%s') nb_evals = ( etat["nb_evals_completes"] + etat["nb_evals_en_cours"] + etat["nb_evals_vides"] ) if nb_evals != 0: H.append( '%s prévues, %s ok' % (M["moduleimpl_id"], nb_evals, etat["nb_evals_completes"]) ) if etat["nb_evals_en_cours"] > 0: H.append( ', %s en cours' % (M["moduleimpl_id"], etat["nb_evals_en_cours"]) ) if etat["attente"]: H.append( ' [en attente]' % M["moduleimpl_id"] ) elif Mod["module_type"] == scu.MODULE_MALUS: nb_malus_notes = sum( [ e["etat"]["nb_notes"] for e in nt.get_mod_evaluation_etat_list(M["moduleimpl_id"]) ] ) H.append( """ malus (%d notes) """ % (M["moduleimpl_id"], nb_malus_notes) ) else: raise ValueError("Invalid module_type") # a bug H.append("

") if context.get_preference("use_ue_coefs", formsemestre_id): H.append( """

utilise les coefficients d'UE pour calculer la moyenne générale.

""" ) # --- LISTE DES ETUDIANTS H += ['
', context.make_listes_sem(sem, REQUEST), "
"] # --- Lien mail enseignants: adrlist = list(mails_enseignants - set([""])) if adrlist: H.append( '

Courrier aux %d enseignants du semestre

' % (",".join(adrlist), len(adrlist)) ) return "".join(H) + context.sco_footer(REQUEST)