# -*- 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 # ############################################################################## """Opérations d'inscriptions aux semestres et modules """ import sco_utils as scu from notes_log import log from sco_exceptions import ScoValueError from sco_permissions import ScoEtudInscrit from sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME import notesdb as ndb from notesdb import ScoDocCursor, DateISOtoDMY, DateDMYtoISO from TrivialFormulator import TrivialFormulator, TF # from notes_table import * import sco_find_etud import sco_formsemestre import sco_moduleimpl import sco_groups # --- Gestion des inscriptions aux semestres _formsemestre_inscriptionEditor = ndb.EditableTable( "notes_formsemestre_inscription", "formsemestre_inscription_id", ("formsemestre_inscription_id", "etudid", "formsemestre_id", "etat", "etape"), sortkey="formsemestre_id", ) def do_formsemestre_inscription_list(context, *args, **kw): "list formsemestre_inscriptions" cnx = ndb.GetDBConnexion() return _formsemestre_inscriptionEditor.list(cnx, *args, **kw) def do_formsemestre_inscription_create(context, args, REQUEST, method=None): "create a formsemestre_inscription (and sco event)" cnx = ndb.GetDBConnexion() log("do_formsemestre_inscription_create: args=%s" % str(args)) sems = sco_formsemestre.do_formsemestre_list( context, {"formsemestre_id": args["formsemestre_id"]} ) if len(sems) != 1: raise ScoValueError("code de semestre invalide: %s" % args["formsemestre_id"]) sem = sems[0] # check lock if sem["etat"] != "1": raise ScoValueError("inscription: semestre verrouille") # r = _formsemestre_inscriptionEditor.create(cnx, args) # Evenement scolars.scolar_events_create( cnx, args={ "etudid": args["etudid"], "event_date": time.strftime("%d/%m/%Y"), "formsemestre_id": args["formsemestre_id"], "event_type": "INSCRIPTION", }, ) # Log etudiant logdb( REQUEST, cnx, method=method, etudid=args["etudid"], msg="inscription en semestre %s" % args["formsemestre_id"], commit=False, ) # sco_core.inval_cache( context, formsemestre_id=args["formsemestre_id"] ) # > inscription au semestre return r def do_formsemestre_inscription_delete(context, oid, formsemestre_id=None): "delete formsemestre_inscription" cnx = ndb.GetDBConnexion() _formsemestre_inscriptionEditor.delete(cnx, oid) sco_core.inval_cache( context, formsemestre_id=formsemestre_id ) # > desinscription du semestre def do_formsemestre_inscription_edit(context, args=None, formsemestre_id=None): "edit a formsemestre_inscription" cnx = ndb.GetDBConnexion() _formsemestre_inscriptionEditor.edit(cnx, args) sco_core.inval_cache( context, formsemestre_id=formsemestre_id ) # > modif inscription semestre (demission ?) def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=None): """Désinscription d'un étudiant. Si semestre extérieur et dernier inscrit, suppression de ce semestre. """ sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) # -- check lock if sem["etat"] != "1": raise ScoValueError("desinscription impossible: semestre verrouille") # -- Si decisions de jury, desinscription interdite nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) if nt.etud_has_decision(etudid): raise ScoValueError( "desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)" ) insem = do_formsemestre_inscription_list(context, args={"formsemestre_id": formsemestre_id, "etudid": etudid} ) if not insem: raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) insem = insem[0] # -- desinscription de tous les modules cnx = ndb.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor.execute( "select moduleimpl_inscription_id from notes_moduleimpl_inscription Im, notes_moduleimpl M where Im.etudid=%(etudid)s and Im.moduleimpl_id = M.moduleimpl_id and M.formsemestre_id = %(formsemestre_id)s", {"etudid": etudid, "formsemestre_id": formsemestre_id}, ) res = cursor.fetchall() moduleimpl_inscription_ids = [x[0] for x in res] for moduleimpl_inscription_id in moduleimpl_inscription_ids: sco_moduleimpl.do_moduleimpl_inscription_delete( context, moduleimpl_inscription_id, formsemestre_id=formsemestre_id ) # -- desincription du semestre do_formsemestre_inscription_delete( context, insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id ) # --- Semestre extérieur if sem["modalite"] == "EXT": inscrits = do_formsemestre_inscription_list(context, args={"formsemestre_id": formsemestre_id} ) nbinscrits = len(inscrits) if nbinscrits == 0: log( "do_formsemestre_desinscription: suppression du semestre extérieur %s" % formsemestre_id ) sco_formsemestre_edit.do_formsemestre_delete( context, formsemestre_id, REQUEST=REQUEST ) if REQUEST: logdb( REQUEST, cnx, method="formsemestre_desinscription", etudid=etudid, msg="desinscription semestre %s" % formsemestre_id, commit=False, ) def do_formsemestre_inscription_with_modules( context, formsemestre_id, etudid, group_ids=[], etat="I", etape=None, REQUEST=None, method="inscription_with_modules", ): """Inscrit cet etudiant à ce semestre et TOUS ses modules STANDARDS (donc sauf le sport) """ # inscription au semestre args = {"formsemestre_id": formsemestre_id, "etudid": etudid} if etat is not None: args["etat"] = etat do_formsemestre_inscription_create(context, args, REQUEST, method=method) log( "do_formsemestre_inscription_with_modules: etudid=%s formsemestre_id=%s" % (etudid, formsemestre_id) ) # inscriptions aux groupes # 1- inscrit au groupe 'tous' group_id = sco_groups.get_default_group(context, formsemestre_id) sco_groups.set_group(context, etudid, group_id) gdone = {group_id: 1} # empeche doublons # 2- inscrit aux groupes for group_id in group_ids: if group_id and not group_id in gdone: sco_groups.set_group(context, etudid, group_id) gdone[group_id] = 1 # inscription a tous les modules de ce semestre modimpls = sco_moduleimpl.do_moduleimpl_withmodule_list( context, formsemestre_id=formsemestre_id ) for mod in modimpls: if mod["ue"]["type"] != UE_SPORT: sco_moduleimpl.do_moduleimpl_inscription_create( context, {"moduleimpl_id": mod["moduleimpl_id"], "etudid": etudid}, REQUEST=REQUEST, formsemestre_id=formsemestre_id, ) def formsemestre_inscription_with_modules_etud( context, formsemestre_id, etudid=None, group_ids=None, REQUEST=None ): """Form. inscription d'un étudiant au semestre. Si etudid n'est pas specifié, form. choix etudiant. """ if not etudid: return sco_find_etud.form_search_etud( context, title="Choix de l'étudiant à inscrire dans ce semestre", add_headers=True, dest_url="formsemestre_inscription_with_modules_etud", parameters={"formsemestre_id": formsemestre_id}, REQUEST=REQUEST, ) return formsemestre_inscription_with_modules( context, etudid, formsemestre_id, REQUEST=REQUEST, group_ids=group_ids ) def formsemestre_inscription_with_modules_form( context, etudid, REQUEST, only_ext=False ): """Formulaire inscription de l'etud dans l'un des semestres existants. Si only_ext, ne montre que les semestre extérieurs. """ etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] H = [ html_sco_header.sco_header(context, REQUEST), "
L'étudiant sera inscrit à tous les modules du semestre choisi (sauf Sport & Culture).
aucune session de formation !
") H.append( '%s est déjà inscrit dans le semestre %s
' % (etud["nomprenom"], sem["titremois"]) ) H.append( """""" % (etudid, etud["nomprenom"], formsemestre_id, sem["titremois"]) ) return "\n".join(H) + F # Check 2: déjà inscrit dans un semestre recouvrant les même dates ? # Informe et propose dé-inscriptions others = est_inscrit_ailleurs(context, etudid, formsemestre_id) if others and not multiple_ok: l = [] for s in others: l.append( '%(titremois)s' % s ) H.append( 'Attention: %s est déjà inscrit sur la même période dans: %s.
' % (etud["nomprenom"], ", ".join(l)) ) H.append("Continuer quand même l'inscription
""" % (etudid, formsemestre_id, sco_groups.make_query_groups(group_ids)) ) return "\n".join(H) + F # if group_ids is not None: # OK, inscription do_formsemestre_inscription_with_modules( context, formsemestre_id, etudid, group_ids=group_ids, etat="I", REQUEST=REQUEST, method="formsemestre_inscription_with_modules", ) return REQUEST.RESPONSE.redirect(scu.ScoURL() + "/ficheEtud?etudid=" + etudid) else: # formulaire choix groupe H.append( """ """ ) return "\n".join(H) + F def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=None): """Dialogue pour (dés)inscription à des modules optionnels.""" sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) if sem["etat"] != "1": raise ScoValueError("Modification impossible: semestre verrouille") etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] nt = sco_core.get_notes_cache(context).get_NotesTable( context, formsemestre_id ) # > get_etud_ue_status F = html_sco_header.sco_footer(context, REQUEST) H = [ html_sco_header.sco_header(context, REQUEST) + "Voici la liste des modules du semestre choisi.
Les modules cochés sont ceux dans lesquels l'étudiant est inscrit. Vous pouvez l'inscrire ou le désincrire d'un ou plusieurs modules.
Attention: cette méthode ne devrait être utilisée que pour les modules optionnels (ou les activités culturelles et sportives) et pour désinscrire les étudiants dispensés (UE validées).
""" ) return "\n".join(H) + "\n" + tf[1] + F elif tf[0] == -1: return REQUEST.RESPONSE.redirect( "%s/ficheEtud?etudid=%s" % (scu.ScoURL(), etudid) ) else: # Inscriptions aux modules choisis # il faut desinscrire des modules qui ne figurent pas # et inscrire aux autres, sauf si deja inscrit a_desinscrire = {}.fromkeys([x["moduleimpl_id"] for x in mods]) insdict = {} for ins in inscr: insdict[ins["moduleimpl_id"]] = ins for ue in ues: ue_id = ue["ue_id"] for moduleimpl_id in tf[2]["moduleimpls_%s" % ue_id]: if a_desinscrire.has_key(moduleimpl_id): del a_desinscrire[moduleimpl_id] # supprime ceux auxquel pas inscrit for moduleimpl_id in a_desinscrire.keys(): if not insdict.has_key(moduleimpl_id): del a_desinscrire[moduleimpl_id] a_inscrire = set() for ue in ues: ue_id = ue["ue_id"] a_inscrire.update(tf[2]["moduleimpls_%s" % ue_id]) # supprime ceux auquel deja inscrit: for ins in inscr: if ins["moduleimpl_id"] in a_inscrire: a_inscrire.remove(ins["moduleimpl_id"]) # dict des modules: modsdict = {} for mod in mods: modsdict[mod["moduleimpl_id"]] = mod # if (not a_inscrire) and (not a_desinscrire): H.append( """%s va être désinscrit%s des modules:
%s va être inscrit%s aux modules:
Total: %d étudiants concernés.
" % len(etudlist)) H.append( """Ces étudiants sont inscrits dans le semestre sélectionné et aussi dans d'autres semestres qui se déroulent en même temps !
Sauf exception, cette situation est anormale:
Aucun étudiant en inscription multiple (c'est normal) !
""") return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)