# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2024 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 (legacy: use models.moduleimpls instead) """ import psycopg2 from app.models import Scolog from app.scodoc import sco_cache import app.scodoc.notesdb as ndb from app.scodoc.sco_exceptions import ScoValueError # --- 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 = ndb.EditableTable( "notes_moduleimpl", "moduleimpl_id", ( "moduleimpl_id", "module_id", "formsemestre_id", "responsable_id", "computation_expr", ), ) def do_moduleimpl_delete(oid, formsemestre_id=None): "delete moduleimpl (desinscrit tous les etudiants)" cnx = ndb.GetDBConnexion() # --- desinscription des etudiants cursor = cnx.cursor(cursor_factory=ndb.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) sco_cache.invalidate_formsemestre( formsemestre_id=formsemestre_id ) # > moduleimpl_delete def moduleimpl_list( moduleimpl_id=None, formsemestre_id=None, module_id=None ) -> list[dict]: "list moduleimpls" args = locals() cnx = ndb.GetDBConnexion() modimpls = _moduleimplEditor.list(cnx, args) return modimpls def do_moduleimpl_edit(args, formsemestre_id=None, cnx=None): "edit a moduleimpl" if not cnx: cnx = ndb.GetDBConnexion() _moduleimplEditor.edit(cnx, args) sco_cache.invalidate_formsemestre( formsemestre_id=formsemestre_id ) # > modif moduleimpl def moduleimpls_in_external_ue(ue_id): """List of modimpls in this ue""" cursor = ndb.SimpleQuery( """SELECT DISTINCT mi.* FROM notes_ue u, notes_moduleimpl mi, notes_modules m WHERE u.is_external is true AND mi.module_id = m.id AND m.ue_id = %(ue_id)s """, {"ue_id": ue_id}, ) return cursor.dictfetchall() def do_moduleimpl_inscription_list(moduleimpl_id=None, etudid=None): "list moduleimpl_inscriptions" args = locals() cnx = ndb.GetDBConnexion() return _moduleimpl_inscriptionEditor.list(cnx, args) def moduleimpl_listeetuds(moduleimpl_id): # XXX OBSOLETE "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.id and M.id = %(moduleimpl_id)s """ cnx = ndb.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor.execute(req, {"moduleimpl_id": moduleimpl_id}) res = cursor.fetchall() return [x[0] for x in res] def do_moduleimpl_inscrit_tout_semestre(moduleimpl_id, formsemestre_id): "inscrit tous les etudiants inscrit au semestre a ce module" # UNUSED cnx = ndb.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ndb.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 = ndb.EditableTable( "notes_moduleimpl_inscription", "moduleimpl_inscription_id", ("moduleimpl_inscription_id", "etudid", "moduleimpl_id"), ) def do_moduleimpl_inscription_create(args, formsemestre_id=None, cnx=None): "create a moduleimpl_inscription" cnx = cnx or ndb.GetDBConnexion() try: r = _moduleimpl_inscriptionEditor.create(cnx, args) except psycopg2.errors.UniqueViolation as exc: raise ScoValueError( "Inscription impossible car déjà existante: vérifiez la situation" ) from exc sco_cache.invalidate_formsemestre( formsemestre_id=formsemestre_id ) # > moduleimpl_inscription Scolog.logdb( method="moduleimpl_inscription", etudid=args["etudid"], msg=f"inscription module {args['moduleimpl_id']}", commit=True, ) return r def do_moduleimpl_inscription_delete(oid, formsemestre_id=None): "delete moduleimpl_inscription" cnx = ndb.GetDBConnexion() _moduleimpl_inscriptionEditor.delete(cnx, oid) sco_cache.invalidate_formsemestre( formsemestre_id=formsemestre_id ) # > moduleimpl_inscription def do_moduleimpl_inscrit_etuds(moduleimpl_id, formsemestre_id, etudids, reset=False): """Inscrit les etudiants (liste d'etudids) a ce module. Si reset, desinscrit tous les autres. """ from app.scodoc import sco_formsemestre_inscriptions # Verifie qu'ils sont tous bien inscrits au semestre for etudid in etudids: insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( args={"formsemestre_id": formsemestre_id, "etudid": etudid} ) if not insem: raise ScoValueError(f"{etudid} n'est pas inscrit au semestre !") cnx = ndb.GetDBConnexion() # Desinscriptions if reset: cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor.execute( "delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s", {"moduleimpl_id": moduleimpl_id}, ) # Inscriptions au module: inmod_set = { x["etudid"] for x in do_moduleimpl_inscription_list(moduleimpl_id=moduleimpl_id) } for etudid in etudids: # déja inscrit ? if not etudid in inmod_set: do_moduleimpl_inscription_create( {"moduleimpl_id": moduleimpl_id, "etudid": etudid}, formsemestre_id=formsemestre_id, cnx=cnx, ) cnx.commit() sco_cache.invalidate_formsemestre( formsemestre_id=formsemestre_id ) # > moduleimpl_inscrit_etuds