# -*- 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 # ############################################################################## """Fonctions sur les moduleimpl """ # codes anciens déplacés de ZEntreprise import datetime import sco_utils as scu from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO from sco_permissions import ScoImplement from sco_exceptions import ScoValueError, AccessDenied from notes_log import log import scolog import sco_formsemestre # --- Gestion des "Implémentations de Modules" # Un "moduleimpl" correspond a la mise en oeuvre d'un module # dans une formation spécifique, à une date spécifique. _moduleimplEditor = EditableTable( "notes_moduleimpl", "moduleimpl_id", ( "moduleimpl_id", "module_id", "formsemestre_id", "responsable_id", "computation_expr", ), ) _modules_enseignantsEditor = EditableTable( "notes_modules_enseignants", "modules_enseignants_id", ("modules_enseignants_id", "moduleimpl_id", "ens_id"), ) def do_moduleimpl_create(context, args): "create a moduleimpl" cnx = context.GetDBConnexion() r = _moduleimplEditor.create(cnx, args) context._inval_cache( formsemestre_id=args["formsemestre_id"] ) # > creation moduleimpl return r def do_moduleimpl_delete(context, oid, formsemestre_id=None): "delete moduleimpl (desinscrit tous les etudiants)" cnx = context.GetDBConnexion() # --- desinscription des etudiants cursor = cnx.cursor(cursor_factory=ScoDocCursor) req = ( "DELETE FROM notes_moduleimpl_inscription WHERE moduleimpl_id=%(moduleimpl_id)s" ) cursor.execute(req, {"moduleimpl_id": oid}) # --- suppression des enseignants cursor.execute( "DELETE FROM notes_modules_enseignants WHERE moduleimpl_id=%(moduleimpl_id)s", {"moduleimpl_id": oid}, ) # --- suppression des references dans les absences cursor.execute( "UPDATE absences SET moduleimpl_id=NULL WHERE moduleimpl_id=%(moduleimpl_id)s", {"moduleimpl_id": oid}, ) # --- destruction du moduleimpl _moduleimplEditor.delete(cnx, oid) context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_delete def do_moduleimpl_list( context, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None ): "list moduleimpls" args = locals() cnx = context.GetDBConnexion() modimpls = _moduleimplEditor.list(cnx, args) # *args, **kw) # Ajoute la liste des enseignants for mo in modimpls: mo["ens"] = do_ens_list(context, args={"moduleimpl_id": mo["moduleimpl_id"]}) return scu.return_text_if_published(modimpls, REQUEST) def do_moduleimpl_edit(context, args, formsemestre_id=None, cnx=None): "edit a moduleimpl" if not cnx: cnx = context.GetDBConnexion() _moduleimplEditor.edit(cnx, args) context._inval_cache(formsemestre_id=formsemestre_id) # > modif moduleimpl def do_moduleimpl_withmodule_list( context, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None ): """Liste les moduleimpls et ajoute dans chacun le module correspondant Tri la liste par semestre/UE/numero_matiere/numero_module. Attention: Cette fonction fait partie de l'API ScoDoc 7 et est publiée. """ args = locals() del args["context"] del args["REQUEST"] modimpls = do_moduleimpl_list(context, **args) for mo in modimpls: mo["module"] = context.do_module_list(args={"module_id": mo["module_id"]})[0] mo["ue"] = context.do_ue_list(args={"ue_id": mo["module"]["ue_id"]})[0] mo["matiere"] = context.do_matiere_list( args={"matiere_id": mo["module"]["matiere_id"]} )[0] # tri par semestre/UE/numero_matiere/numero_module extr = lambda x: ( x["ue"]["numero"], x["ue"]["ue_id"], x["matiere"]["numero"], x["matiere"]["matiere_id"], x["module"]["numero"], x["module"]["code"], ) modimpls.sort(lambda x, y: cmp(extr(x), extr(y))) return scu.return_text_if_published(modimpls, REQUEST) def do_moduleimpl_inscription_list( context, moduleimpl_id=None, etudid=None, REQUEST=None ): "list moduleimpl_inscriptions" args = locals() cnx = context.GetDBConnexion() return scu.return_text_if_published( _moduleimpl_inscriptionEditor.list(cnx, args), REQUEST ) def do_moduleimpl_listeetuds(context, moduleimpl_id): "retourne liste des etudids inscrits a ce module" req = "select distinct Im.etudid from notes_moduleimpl_inscription Im, notes_formsemestre_inscription Isem, notes_moduleimpl M where Isem.etudid=Im.etudid and Im.moduleimpl_id=M.moduleimpl_id and M.moduleimpl_id = %(moduleimpl_id)s" cnx = context.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor.execute(req, {"moduleimpl_id": moduleimpl_id}) res = cursor.fetchall() return [x[0] for x in res] def do_moduleimpl_inscrit_tout_semestre(context, moduleimpl_id, formsemestre_id): "inscrit tous les etudiants inscrit au semestre a ce module" # UNUSED cnx = context.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ScoDocCursor) req = """INSERT INTO notes_moduleimpl_inscription (moduleimpl_id, etudid) SELECT %(moduleimpl_id)s, I.etudid FROM notes_formsemestre_inscription I WHERE I.formsemestre_id=%(formsemestre_id)s""" args = {"moduleimpl_id": moduleimpl_id, "formsemestre_id": formsemestre_id} cursor.execute(req, args) # --- Inscriptions aux modules _moduleimpl_inscriptionEditor = EditableTable( "notes_moduleimpl_inscription", "moduleimpl_inscription_id", ("moduleimpl_inscription_id", "etudid", "moduleimpl_id"), ) def do_moduleimpl_inscription_create(context, args, REQUEST=None, formsemestre_id=None): "create a moduleimpl_inscription" cnx = context.GetDBConnexion() log("do_moduleimpl_inscription_create: " + str(args)) r = _moduleimpl_inscriptionEditor.create(cnx, args) context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription if REQUEST: scolog.logdb( REQUEST, cnx, method="moduleimpl_inscription", etudid=args["etudid"], msg="inscription module %s" % args["moduleimpl_id"], commit=False, ) return r def do_moduleimpl_inscription_delete(context, oid, formsemestre_id=None): "delete moduleimpl_inscription" cnx = context.GetDBConnexion() _moduleimpl_inscriptionEditor.delete(cnx, oid) context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription def do_moduleimpl_inscrit_etuds( context, moduleimpl_id, formsemestre_id, etudids, reset=False, REQUEST=None ): """Inscrit les etudiants (liste d'etudids) a ce module. Si reset, desinscrit tous les autres. """ # Verifie qu'ils sont tous bien inscrits au semestre for etudid in etudids: insem = context.do_formsemestre_inscription_list( args={"formsemestre_id": formsemestre_id, "etudid": etudid} ) if not insem: raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) # Desinscriptions if reset: cnx = context.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor.execute( "delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s", {"moduleimpl_id": moduleimpl_id}, ) # Inscriptions au module: inmod_set = set( [ # hum ? x["etudid"] for x in do_moduleimpl_inscription_list( context, moduleimpl_id=moduleimpl_id ) ] ) for etudid in etudids: # deja inscrit ? if not etudid in inmod_set: do_moduleimpl_inscription_create( context, {"moduleimpl_id": moduleimpl_id, "etudid": etudid}, REQUEST=REQUEST, formsemestre_id=formsemestre_id, ) context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscrit_etuds def do_ens_list(context, *args, **kw): "liste les enseignants d'un moduleimpl (pas le responsable)" cnx = context.GetDBConnexion() ens = _modules_enseignantsEditor.list(cnx, *args, **kw) return ens def do_ens_edit(context, *args, **kw): "edit ens" cnx = context.GetDBConnexion() _modules_enseignantsEditor.edit(cnx, *args, **kw) def do_ens_create(context, args): "create ens" cnx = context.GetDBConnexion() r = _modules_enseignantsEditor.create(cnx, args) return r def do_ens_delete(context, oid): "delete ens" cnx = context.GetDBConnexion() r = _modules_enseignantsEditor.delete(cnx, oid) return r def can_change_module_resp(context, REQUEST, moduleimpl_id): """Check if current user can modify module resp. (raise exception if not). = Admin, et dir des etud. (si option l'y autorise) """ M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0] # -- check lock sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) if sem["etat"] != "1": raise ScoValueError("Modification impossible: semestre verrouille") # -- check access authuser = REQUEST.AUTHENTICATED_USER uid = str(authuser) # admin ou resp. semestre avec flag resp_can_change_resp if not authuser.has_permission(ScoImplement, context) and ( (uid not in sem["responsables"]) or (not sem["resp_can_change_ens"]) ): raise AccessDenied("Modification impossible pour %s" % uid) return M, sem def can_change_ens(context, REQUEST, moduleimpl_id, raise_exc=True): "check if current user can modify ens list (raise exception if not)" M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0] # -- check lock sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) if sem["etat"] != "1": if raise_exc: raise ScoValueError("Modification impossible: semestre verrouille") else: return False # -- check access authuser = REQUEST.AUTHENTICATED_USER uid = str(authuser) # admin, resp. module ou resp. semestre if ( uid != M["responsable_id"] and not authuser.has_permission(ScoImplement, context) and (uid not in sem["responsables"]) ): if raise_exc: raise AccessDenied("Modification impossible pour %s" % uid) else: return False return M, sem