ScoDoc/app/scodoc/sco_moduleimpl.py

242 lines
7.9 KiB
Python

# -*- 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 import db
from app.models import Formation
from app.scodoc 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_create(args):
"create a moduleimpl"
# TODO remplacer par une methode de ModuleImpl qui appelle super().create_from_dict() puis invalide le formsemestre
cnx = ndb.GetDBConnexion()
r = _moduleimplEditor.create(cnx, args)
sco_cache.invalidate_formsemestre(
formsemestre_id=args["formsemestre_id"]
) # > creation moduleimpl
return r
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 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(
cnx,
method="moduleimpl_inscription",
etudid=args["etudid"],
msg=f"inscription module {args['moduleimpl_id']}",
commit=False,
)
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