# -*- 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 import notesdb as ndb 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...", "endpoint": "notes.formsemestre_report_counts", "args": {"formsemestre_id": formsemestre_id}, }, { "title": "Suivi de cohortes", "endpoint": "notes.formsemestre_suivi_cohorte", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, { "title": "Graphe des parcours", "endpoint": "notes.formsemestre_graph_parcours", "args": {"formsemestre_id": formsemestre_id}, "enabled": scu.WITH_PYDOT, }, { "title": "Codes des parcours", "endpoint": "notes.formsemestre_suivi_parcours", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, { "title": "Lycées d'origine", "endpoint": "notes.formsemestre_etuds_lycees", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, { "title": 'Table "poursuite"', "endpoint": "notes.formsemestre_poursuite_report", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, { "title": "Documents Avis Poursuite Etudes", "endpoint": "notes.pe_view_sem_recap", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, { "title": 'Table "débouchés"', "endpoint": "notes.report_debouche_date", "enabled": True, }, { "title": "Estimation du coût de la formation", "endpoint": "notes.formsemestre_estim_cost?formsemestre_id", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, }, ] 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 = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] menuSemestre = [ { "title": "Tableau de bord", "endpoint": "notes.formsemestre_status", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "Tableau de bord du semestre", }, { "title": "Voir la formation %(acronyme)s (v%(version)s)" % F, "endpoint": "notes.ue_list", "args": {"formation_id": sem["formation_id"]}, "enabled": True, "helpmsg": "Tableau de bord du semestre", }, { "title": "Modifier le semestre", "endpoint": "notes.formsemestre_editwithmodules?formation_id=%(formation_id)s&formsemestre_id=%(formsemestre_id)s" % sem, "args": {"formsemestre_id": formsemestre_id}, "enabled": ( authuser.has_permission(Permission.ScoImplement) 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", "endpoint": "notes.formsemestre_edit_preferences", "args": {"formsemestre_id": formsemestre_id}, "enabled": ( authuser.has_permission(Permission.ScoImplement) 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", "endpoint": "notes.formsemestre_edit_options", "args": {"formsemestre_id": formsemestre_id}, "enabled": (uid in sem["responsables"]) or authuser.has_permission(Permission.ScoImplement), "helpmsg": "Change les options", }, { "title": change_lock_msg, "endpoint": "notes.formsemestre_change_lock", "args": {"formsemestre_id": formsemestre_id}, "enabled": (uid in sem["responsables"]) or authuser.has_permission(Permission.ScoImplement), "helpmsg": "", }, { "title": "Description du semestre", "endpoint": "notes.formsemestre_description", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "", }, { "title": "Vérifier absences aux évaluations", "endpoint": "notes.formsemestre_check_absences_html", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "", }, { "title": "Lister tous les enseignants", "endpoint": "notes.formsemestre_enseignants_list", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "", }, { "title": "Cloner ce semestre", "endpoint": "notes.formsemestre_clone", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoImplement), "helpmsg": "", }, { "title": "Associer à une nouvelle version du programme", "endpoint": "notes.formsemestre_associate_new_version", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoChangeFormation) and (sem["etat"] == "1"), "helpmsg": "", }, { "title": "Supprimer ce semestre", "endpoint": "notes.formsemestre_delete", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoImplement), "helpmsg": "", }, ] # debug : if app.config["ENV"] == "development": menuSemestre.append( { "title": "Check integrity", "endpoint": "notes.check_sem_integrity", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, } ) menuInscriptions = [ { "title": "Voir les inscriptions aux modules", "endpoint": "notes.moduleimpl_inscriptions_stats", "args": {"formsemestre_id": formsemestre_id}, } ] menuInscriptions += [ { "title": "Passage des étudiants depuis d'autres semestres", "endpoint": "notes.formsemestre_inscr_passage", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoEtudInscrit) and (sem["etat"] == "1"), }, { "title": "Synchroniser avec étape Apogée", "endpoint": "notes.formsemestre_synchro_etuds", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoView) and sco_preferences.get_preference(context, "portal_url") and (sem["etat"] == "1"), }, { "title": "Inscrire un étudiant", "endpoint": "notes.formsemestre_inscription_with_modules_etud", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoEtudInscrit) and (sem["etat"] == "1"), }, { "title": "Importer des étudiants dans ce semestre (table Excel)", "endpoint": "notes.form_students_import_excel", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoEtudInscrit) and (sem["etat"] == "1"), }, { "title": "Import/export des données admission", "endpoint": "notes.form_students_import_infos_admissions", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoView), }, { "title": "Resynchroniser données identité", "endpoint": "notes.formsemestre_import_etud_admission", "args": {"formsemestre_id": formsemestre_id}, "enabled": authuser.has_permission(Permission.ScoEtudChangeAdr) and sco_preferences.get_preference(context, "portal_url"), }, { "title": "Exporter table des étudiants", "endpoint": "notes.groups_view", "args": { "format": allxls, "group_ids": sco_groups.get_default_group( context, formsemestre_id, fix_if_missing=True, REQUEST=REQUEST ), }, }, { "title": "Vérifier inscriptions multiples", "endpoint": "notes.formsemestre_inscrits_ailleurs", "args": {"formsemestre_id": formsemestre_id}, }, ] menuGroupes = [ { "title": "Listes, photos, feuilles...", "endpoint": "notes.groups_view", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "Accès aux listes des groupes d'étudiants", }, { "title": "Créer/modifier les partitions...", "endpoint": "notes.editPartitionForm", "args": {"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"], "endpoint": "notes.affectGroups", "args": {"partition_id": partition["partition_id"]}, "enabled": enabled, } ) menuGroupes.append( {"title": "Modifier les groupes", "submenu": submenu, "enabled": enabled} ) menuNotes = [ { "title": "Tableau des moyennes (et liens bulletins)", "endpoint": "notes.formsemestre_recapcomplet", "args": {"formsemestre_id": formsemestre_id}, }, { "title": "Saisie des notes", "endpoint": "notes.formsemestre_status", "args": {"formsemestre_id": formsemestre_id}, "enabled": True, "helpmsg": "Tableau de bord du semestre", }, { "title": "Classeur PDF des bulletins", "endpoint": "notes.formsemestre_bulletins_pdf_choice", "args": {"formsemestre_id": formsemestre_id}, "helpmsg": "PDF regroupant tous les bulletins", }, { "title": "Envoyer à chaque étudiant son bulletin par e-mail", "endpoint": "notes.formsemestre_bulletins_mailetuds_choice", "args": {"formsemestre_id": formsemestre_id}, "enabled": sco_bulletins.can_send_bulletin_by_mail( context, formsemestre_id, REQUEST ), }, { "title": "Calendrier des évaluations", "endpoint": "notes.formsemestre_evaluations_cal", "args": {"formsemestre_id": formsemestre_id}, }, { "title": "Lister toutes les saisies de notes", "endpoint": "notes.formsemestre_list_saisies_notes", "args": {"formsemestre_id": formsemestre_id}, }, ] menuJury = [ { "title": "Voir les décisions du jury", "endpoint": "notes.formsemestre_pvjury", "args": {"formsemestre_id": formsemestre_id}, }, { "title": "Générer feuille préparation Jury", "endpoint": "notes.feuille_preparation_jury", "args": {"formsemestre_id": formsemestre_id}, }, { "title": "Saisie des décisions du jury", "endpoint": "notes.formsemestre_recapcomplet", "args": { "formsemestre_id": formsemestre_id, "modejury": 1, "hidemodules": 1, "hidebac": 1, "pref_override": 0, }, "enabled": sco_permissions.can_validate_sem( context, REQUEST, formsemestre_id ), }, { "title": "Editer les PV et archiver les résultats", "endpoint": "notes.formsemestre_archive", "args": {"formsemestre_id": formsemestre_id}, "enabled": sco_permissions.can_edit_pv(context, REQUEST, formsemestre_id), }, { "title": "Documents archivés", "endpoint": "notes.formsemestre_list_archives", "args": {"formsemestre_id": formsemestre_id}, "enabled": sco_archives.PVArchive.list_obj_archives( context, formsemestre_id ), }, ] menuStats = defMenuStats(context, formsemestre_id) H = [ #
', '
    ', htmlutils.make_menu("Semestre", menuSemestre), htmlutils.make_menu("Inscriptions", menuInscriptions), htmlutils.make_menu("Groupes", menuGroupes), htmlutils.make_menu("Notes", menuNotes), htmlutils.make_menu("Jury", menuJury), htmlutils.make_menu("Statistiques", menuStats), formsemestre_custommenu_html(context, formsemestre_id), "
", #'
' ] 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 = scu.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 sco_preferences.get_preference( context, "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 = sco_formations.formation_list(context, 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 = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, 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 = sco_core.get_notes_cache(context).get_NotesTable( context, formsemestre_id ) # > liste evaluations use_ue_coefs = sco_preferences.get_preference( context, "use_ue_coefs", formsemestre_id ) F = sco_formations.formation_list(context, 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 sco_preferences.get_preference(context, "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=html_sco_header.html_sem_header( context, REQUEST, "Description du semestre", sem, with_page_header=False ), pdf_title=title, preferences=sco_preferences.SemPreferences(context, 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 = """
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( '' ) FA.append( '' % sem ) FA.append('') FA.append( '' % destination ) FA.append('') FA.append('") FA.append( 'état' % sem ) 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( """""" % group ) H.append("" % 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( '

Ajouter une partition

' % 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:
") 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 = sco_formations.formation_list(context, 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 = [ html_sco_header.html_sem_header( context, 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 sco_preferences.get_preference(context, '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 = ndb.GetDBConnexion() sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list( context, formsemestre_id=formsemestre_id ) # inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, # args={"formsemestre_id": formsemestre_id} # ) prev_ue_id = None can_edit = sco_formsemestre_edit.can_edit_sem( context, REQUEST, formsemestre_id, sem=sem ) H = [ html_sco_header.sco_header( context, 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 = sco_core.get_notes_cache( context, ).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 sco_preferences.get_preference(context, "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 sco_preferences.get_preference(context, "use_ue_coefs", formsemestre_id): H.append( """

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

""" ) # --- LISTE DES ETUDIANTS H += [ '
', _make_listes_sem(context, 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) + html_sco_header.sco_footer(context, REQUEST)