forked from ScoDoc/DocScoDoc
WIP suite de la migration
This commit is contained in:
parent
8f91d5292c
commit
6a4d6e5109
@ -1,838 +0,0 @@
|
|||||||
# -*- 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
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
"""Site ScoDoc pour plusieurs departements:
|
|
||||||
gestion de l'installation et des creation de départements.
|
|
||||||
|
|
||||||
Chaque departement est géré par un ZScolar sous ZScoDoc.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
import string
|
|
||||||
import glob
|
|
||||||
import re
|
|
||||||
import inspect
|
|
||||||
import urllib
|
|
||||||
import urllib2
|
|
||||||
import cgi
|
|
||||||
import xml
|
|
||||||
|
|
||||||
from cStringIO import StringIO
|
|
||||||
from zipfile import ZipFile
|
|
||||||
import os.path
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
from email.MIMEMultipart import ( # pylint: disable=no-name-in-module,import-error
|
|
||||||
MIMEMultipart,
|
|
||||||
)
|
|
||||||
from email.MIMEText import MIMEText # pylint: disable=no-name-in-module,import-error
|
|
||||||
from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-error
|
|
||||||
from email.Header import Header # pylint: disable=no-name-in-module,import-error
|
|
||||||
from email import Encoders # pylint: disable=no-name-in-module,import-error
|
|
||||||
|
|
||||||
from app.scodoc.sco_zope import (
|
|
||||||
ObjectManager,
|
|
||||||
PropertyManager,
|
|
||||||
RoleManager,
|
|
||||||
Item,
|
|
||||||
Persistent,
|
|
||||||
Implicit,
|
|
||||||
ClassSecurityInfo,
|
|
||||||
DTMLFile,
|
|
||||||
Globals,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import Products.ZPsycopgDA.DA as ZopeDA
|
|
||||||
except:
|
|
||||||
import ZPsycopgDA.DA as ZopeDA # interp.py
|
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
|
||||||
from app.scodoc import VERSION
|
|
||||||
import mails
|
|
||||||
from app.scodoc.notes_log import log
|
|
||||||
from app.scodoc import sco_find_etud
|
|
||||||
from app.scodoc import sco_users
|
|
||||||
from app.scodoc.sco_permissions import (
|
|
||||||
ScoView,
|
|
||||||
ScoEnsView,
|
|
||||||
ScoImplement,
|
|
||||||
ScoChangeFormation,
|
|
||||||
ScoObservateur,
|
|
||||||
ScoEtudInscrit,
|
|
||||||
ScoEtudChangeGroups,
|
|
||||||
ScoEtudChangeAdr,
|
|
||||||
ScoEtudSupprAnnotations,
|
|
||||||
ScoEditAllEvals,
|
|
||||||
ScoEditAllNotes,
|
|
||||||
ScoEditFormationTags,
|
|
||||||
ScoEditApo,
|
|
||||||
ScoSuperAdmin,
|
|
||||||
)
|
|
||||||
from app.scodoc.sco_exceptions import (
|
|
||||||
ScoValueError,
|
|
||||||
ScoLockedFormError,
|
|
||||||
ScoGenError,
|
|
||||||
AccessDenied,
|
|
||||||
)
|
|
||||||
from app.scodoc import html_sco_header
|
|
||||||
|
|
||||||
|
|
||||||
class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit):
|
|
||||||
|
|
||||||
"ZScoDoc object"
|
|
||||||
|
|
||||||
meta_type = "ZScoDoc"
|
|
||||||
security = ClassSecurityInfo()
|
|
||||||
file_path = Globals.package_home(globals())
|
|
||||||
|
|
||||||
# This is the list of the methods associated to 'tabs' in the ZMI
|
|
||||||
# Be aware that The first in the list is the one shown by default, so if
|
|
||||||
# the 'View' tab is the first, you will never see your tabs by cliquing
|
|
||||||
# on the object.
|
|
||||||
manage_options = (
|
|
||||||
({"label": "Contents", "action": "manage_main"},)
|
|
||||||
+ PropertyManager.manage_options # add the 'Properties' tab
|
|
||||||
+ ({"label": "View", "action": "index_html"},)
|
|
||||||
+ Item.manage_options # add the 'Undo' & 'Owner' tab
|
|
||||||
+ RoleManager.manage_options # add the 'Security' tab
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, id, title):
|
|
||||||
"Initialise a new instance of ZScoDoc"
|
|
||||||
self.id = id
|
|
||||||
self.title = title
|
|
||||||
self.manage_addProperty("admin_password_initialized", "0", "string")
|
|
||||||
|
|
||||||
security.declareProtected(ScoView, "ScoDocURL")
|
|
||||||
|
|
||||||
def ScoDocURL(self):
|
|
||||||
"base URL for this instance (top level for ScoDoc site)"
|
|
||||||
return self.absolute_url()
|
|
||||||
|
|
||||||
def _check_admin_perm(self, REQUEST):
|
|
||||||
"""Check if user has permission to add/delete departements"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
if authuser.has_role("manager") or authuser.has_permission(
|
|
||||||
Permission.ScoSuperAdmin, self
|
|
||||||
):
|
|
||||||
return ""
|
|
||||||
else:
|
|
||||||
return """<h2>Vous n'avez pas le droit d'accéder à cette page</h2>"""
|
|
||||||
|
|
||||||
def _check_users_folder(self, REQUEST=None):
|
|
||||||
"""Vérifie UserFolder et le crée s'il le faut"""
|
|
||||||
try:
|
|
||||||
_ = self.UsersDB
|
|
||||||
return "<!-- uf ok -->"
|
|
||||||
except:
|
|
||||||
e = self._check_admin_perm(REQUEST)
|
|
||||||
if not e: # admin permissions:
|
|
||||||
self.create_users_cnx(REQUEST)
|
|
||||||
self.create_users_folder(REQUEST)
|
|
||||||
return '<div class="head_message">Création du connecteur utilisateurs réussie</div>'
|
|
||||||
else:
|
|
||||||
return """<div class="head_message">Installation non terminée: connectez vous avec les droits d'administrateur</div>"""
|
|
||||||
|
|
||||||
security.declareProtected("View", "create_users_folder")
|
|
||||||
|
|
||||||
def create_users_folder(self, REQUEST=None):
|
|
||||||
"""Create Zope user folder"""
|
|
||||||
e = self._check_admin_perm(REQUEST)
|
|
||||||
if e:
|
|
||||||
return e
|
|
||||||
|
|
||||||
if REQUEST is None:
|
|
||||||
REQUEST = {}
|
|
||||||
|
|
||||||
REQUEST.form["pgauth_connection"] = "UsersDB"
|
|
||||||
REQUEST.form["pgauth_table"] = "sco_users"
|
|
||||||
REQUEST.form["pgauth_usernameColumn"] = "user_name"
|
|
||||||
REQUEST.form["pgauth_passwordColumn"] = "passwd"
|
|
||||||
REQUEST.form["pgauth_rolesColumn"] = "roles"
|
|
||||||
|
|
||||||
add_method = self.manage_addProduct["OFSP"].manage_addexUserFolder
|
|
||||||
log("create_users_folder: in %s" % self.id)
|
|
||||||
return add_method(
|
|
||||||
authId="pgAuthSource",
|
|
||||||
propId="nullPropSource",
|
|
||||||
memberId="nullMemberSource",
|
|
||||||
groupId="nullGroupSource",
|
|
||||||
cryptoId="MD51",
|
|
||||||
# doAuth='1', doProp='1', doMember='1', doGroup='1', allDone='1',
|
|
||||||
cookie_mode=2,
|
|
||||||
session_length=500,
|
|
||||||
not_session_length=0,
|
|
||||||
REQUEST=REQUEST,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _fix_users_folder(self):
|
|
||||||
"""removes docLogin and docLogout dtml methods from exUserFolder, so that we use ours.
|
|
||||||
(called each time be index_html, to fix old ScoDoc installations.)
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.acl_users.manage_delObjects(ids=["docLogin", "docLogout"])
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
# add missing getAuthFailedMessage (bug in exUserFolder ?)
|
|
||||||
try:
|
|
||||||
_ = self.getAuthFailedMessage
|
|
||||||
except:
|
|
||||||
log("adding getAuthFailedMessage to Zope install")
|
|
||||||
parent = self.aq_parent
|
|
||||||
from OFS.DTMLMethod import addDTMLMethod # pylint: disable=import-error
|
|
||||||
|
|
||||||
addDTMLMethod(parent, "getAuthFailedMessage", file="Identification")
|
|
||||||
|
|
||||||
security.declareProtected("View", "create_users_cnx")
|
|
||||||
|
|
||||||
def create_users_cnx(self, REQUEST=None):
|
|
||||||
"""Create Zope connector to UsersDB
|
|
||||||
|
|
||||||
Note: la connexion est fixée (SCOUSERS) (base crée par l'installeur) !
|
|
||||||
Les utilisateurs avancés pourront la changer ensuite.
|
|
||||||
"""
|
|
||||||
# ce connecteur zope - db est encore pour l'instant utilisé par exUserFolder.pgAuthSource
|
|
||||||
# (en lecture seule en principe)
|
|
||||||
oid = "UsersDB"
|
|
||||||
log("create_users_cnx: in %s" % self.id)
|
|
||||||
da = ZopeDA.Connection(
|
|
||||||
oid,
|
|
||||||
"Cnx bd utilisateurs",
|
|
||||||
scu.SCO_DEFAULT_SQL_USERS_CNX,
|
|
||||||
False,
|
|
||||||
check=1,
|
|
||||||
tilevel=2,
|
|
||||||
encoding="LATIN1",
|
|
||||||
)
|
|
||||||
self._setObject(oid, da)
|
|
||||||
|
|
||||||
security.declareProtected("View", "change_admin_user")
|
|
||||||
|
|
||||||
def change_admin_user(self, password, REQUEST=None):
|
|
||||||
"""Change password of admin user"""
|
|
||||||
# note: controle sur le role et non pas sur une permission
|
|
||||||
# (non definies au top level)
|
|
||||||
if not REQUEST.AUTHENTICATED_USER.has_role("Manager"):
|
|
||||||
log("user %s is not Manager" % REQUEST.AUTHENTICATED_USER)
|
|
||||||
log("roles=%s" % REQUEST.AUTHENTICATED_USER.getRolesInContext(self))
|
|
||||||
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
|
|
||||||
log("trying to change admin password")
|
|
||||||
# 1-- check strong password
|
|
||||||
if not sco_users.is_valid_password(password):
|
|
||||||
log("refusing weak password")
|
|
||||||
return REQUEST.RESPONSE.redirect(
|
|
||||||
"change_admin_user_form?message=Mot%20de%20passe%20trop%20simple,%20recommencez"
|
|
||||||
)
|
|
||||||
# 2-- change password for admin user
|
|
||||||
username = "admin"
|
|
||||||
acl_users = self.aq_parent.acl_users
|
|
||||||
user = acl_users.getUser(username)
|
|
||||||
r = acl_users._changeUser(
|
|
||||||
username, password, password, user.roles, user.domains
|
|
||||||
)
|
|
||||||
if not r:
|
|
||||||
# OK, set property to indicate we changed the password
|
|
||||||
log("admin password changed successfully")
|
|
||||||
self.manage_changeProperties(admin_password_initialized="1")
|
|
||||||
return r or REQUEST.RESPONSE.redirect("index_html")
|
|
||||||
|
|
||||||
security.declareProtected("View", "change_admin_user_form")
|
|
||||||
|
|
||||||
def change_admin_user_form(self, message="", REQUEST=None):
|
|
||||||
"""Form allowing to change the ScoDoc admin password"""
|
|
||||||
# note: controle sur le role et non pas sur une permission
|
|
||||||
# (non definies au top level)
|
|
||||||
if not REQUEST.AUTHENTICATED_USER.has_role("Manager"):
|
|
||||||
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
|
|
||||||
H = [
|
|
||||||
html_sco_header.scodoc_top_html_header(
|
|
||||||
self, REQUEST, page_title="ScoDoc: changement mot de passe"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
if message:
|
|
||||||
H.append('<div id="message">%s</div>' % message)
|
|
||||||
H.append(
|
|
||||||
"""<h2>Changement du mot de passe administrateur (utilisateur admin)</h2>
|
|
||||||
<p>
|
|
||||||
<form action="change_admin_user" method="post"><table>
|
|
||||||
<tr><td>Nouveau mot de passe:</td><td><input type="password" size="14" name="password"/></td></tr>
|
|
||||||
<tr><td>Confirmation: </td><td><input type="password" size="14" name="password2" /></td></tr>
|
|
||||||
</table>
|
|
||||||
<input type="submit" value="Changer">
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
H.append("""</body></html>""")
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
security.declareProtected("View", "list_depts")
|
|
||||||
|
|
||||||
def list_depts(self, viewable=True, format=None, REQUEST=None):
|
|
||||||
"""List departments
|
|
||||||
If viewable, list only depts viewable the current user.
|
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
viewable = int(viewable)
|
|
||||||
return scu.sendResult(
|
|
||||||
REQUEST,
|
|
||||||
[
|
|
||||||
d.id
|
|
||||||
for d in self._list_depts()
|
|
||||||
if (not viewable)
|
|
||||||
or authuser.has_permission(Permission.ScoView, d.Scolarite)
|
|
||||||
],
|
|
||||||
name="depts",
|
|
||||||
format=format,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _list_depts(self, REQUEST=None): # not published
|
|
||||||
# List departments folders
|
|
||||||
# (returns a list of Zope folders containing a ZScolar instance)
|
|
||||||
folders = self.objectValues("Folder")
|
|
||||||
# select folders with Scolarite object:
|
|
||||||
r = []
|
|
||||||
for folder in folders:
|
|
||||||
try:
|
|
||||||
_ = folder.Scolarite
|
|
||||||
r.append(folder)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return r
|
|
||||||
|
|
||||||
security.declareProtected("View", "create_dept")
|
|
||||||
|
|
||||||
def create_dept(self, REQUEST=None, DeptId="", pass2=False):
|
|
||||||
"""Creation (ajout) d'un site departement
|
|
||||||
(instance ZScolar + dossier la contenant)
|
|
||||||
"""
|
|
||||||
e = self._check_admin_perm(REQUEST)
|
|
||||||
if e:
|
|
||||||
return e
|
|
||||||
|
|
||||||
if not DeptId:
|
|
||||||
raise ValueError("nom de departement invalide")
|
|
||||||
if not pass2:
|
|
||||||
# 1- Creation de repertoire Dept
|
|
||||||
log("creating Zope folder " + DeptId)
|
|
||||||
add_method = self.manage_addProduct["OFSP"].manage_addFolder
|
|
||||||
add_method(DeptId, title="Site dept. " + DeptId)
|
|
||||||
|
|
||||||
DeptFolder = self[DeptId]
|
|
||||||
|
|
||||||
if not pass2:
|
|
||||||
# 2- Creation du repertoire Fotos
|
|
||||||
log("creating Zope folder %s/Fotos" % DeptId)
|
|
||||||
add_method = DeptFolder.manage_addProduct["OFSP"].manage_addFolder
|
|
||||||
add_method("Fotos", title="Photos identites " + DeptId)
|
|
||||||
|
|
||||||
# 3- Creation instance ScoDoc
|
|
||||||
log("creating Zope ZScolar instance")
|
|
||||||
add_method = DeptFolder.manage_addProduct["ScoDoc"].manage_addZScolarForm
|
|
||||||
return add_method(DeptId, REQUEST=REQUEST)
|
|
||||||
|
|
||||||
security.declareProtected("View", "delete_dept")
|
|
||||||
|
|
||||||
def delete_dept(self, REQUEST=None, DeptId="", force=False):
|
|
||||||
"""Supprime un departement (de Zope seulement, ne touche pas la BD)"""
|
|
||||||
e = self._check_admin_perm(REQUEST)
|
|
||||||
if e:
|
|
||||||
return e
|
|
||||||
|
|
||||||
if not force and DeptId not in [x.id for x in self._list_depts()]:
|
|
||||||
raise ValueError("nom de departement invalide")
|
|
||||||
|
|
||||||
self.manage_delObjects(ids=[DeptId])
|
|
||||||
|
|
||||||
return (
|
|
||||||
"<p>Département "
|
|
||||||
+ DeptId
|
|
||||||
+ """ supprimé du serveur web (la base de données n'est pas affectée)!</p><p><a href="/ScoDoc">Continuer</a></p>"""
|
|
||||||
)
|
|
||||||
|
|
||||||
security.declareProtected("View", "index_html")
|
|
||||||
|
|
||||||
def index_html(self, REQUEST=None, message=None):
|
|
||||||
"""Top level page for ScoDoc"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
deptList = self._list_depts()
|
|
||||||
self._fix_users_folder() # fix our exUserFolder
|
|
||||||
isAdmin = not self._check_admin_perm(REQUEST)
|
|
||||||
try:
|
|
||||||
admin_password_initialized = self.admin_password_initialized
|
|
||||||
except:
|
|
||||||
admin_password_initialized = "0"
|
|
||||||
if isAdmin and admin_password_initialized != "1":
|
|
||||||
return REQUEST.RESPONSE.redirect(
|
|
||||||
"ScoDoc/change_admin_user_form?message=Le%20mot%20de%20passe%20administrateur%20doit%20etre%20change%20!"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Si l'URL indique que l'on est dans un folder, affiche page login du departement
|
|
||||||
try:
|
|
||||||
deptfoldername = REQUEST.URL0.split("ScoDoc")[1].split("/")[1]
|
|
||||||
if deptfoldername in [x.id for x in self._list_depts()]:
|
|
||||||
return self.index_dept(deptfoldername=deptfoldername, REQUEST=REQUEST)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
H = [
|
|
||||||
html_sco_header.scodoc_top_html_header(
|
|
||||||
self, REQUEST, page_title="ScoDoc: bienvenue"
|
|
||||||
),
|
|
||||||
self._check_users_folder(REQUEST=REQUEST), # ensure setup is done
|
|
||||||
]
|
|
||||||
if message:
|
|
||||||
H.append('<div id="message">%s</div>' % message)
|
|
||||||
|
|
||||||
if isAdmin and not message:
|
|
||||||
H.append('<div id="message">Attention: connecté comme administrateur</div>')
|
|
||||||
|
|
||||||
H.append(
|
|
||||||
"""
|
|
||||||
<div class="maindiv">
|
|
||||||
<h2>ScoDoc: gestion scolarité</h2>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
if authuser.has_role("Authenticated"):
|
|
||||||
H.append(
|
|
||||||
"""<p>Bonjour <font color="red"><b>%s</b></font>.</p>""" % str(authuser)
|
|
||||||
)
|
|
||||||
H.append(
|
|
||||||
"""<p>N'oubliez pas de vous <a href="acl_users/logout">déconnecter</a> après usage.</p>"""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
H.append(
|
|
||||||
"""<p>Ce site est <font color="red"><b>réservé au personnel autorisé</b></font></p>"""
|
|
||||||
)
|
|
||||||
H.append(self.authentication_form(destination="."))
|
|
||||||
|
|
||||||
if not deptList:
|
|
||||||
H.append("<em>aucun département existant !</em>")
|
|
||||||
# si pas de dept et pas admin, propose lien pour loger admin
|
|
||||||
if not isAdmin:
|
|
||||||
H.append(
|
|
||||||
"""<p><a href="/force_admin_authentication">Identifiez vous comme administrateur</a> (au début: nom 'admin', mot de passe 'scodoc')</p>"""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
H.append('<ul class="main">')
|
|
||||||
if isAdmin:
|
|
||||||
dest_folder = "/Scolarite"
|
|
||||||
else:
|
|
||||||
dest_folder = ""
|
|
||||||
for deptFolder in self._list_depts():
|
|
||||||
if authuser.has_permission(Permission.ScoView, deptFolder.Scolarite):
|
|
||||||
link_cls = "link_accessible"
|
|
||||||
else:
|
|
||||||
link_cls = "link_unauthorized"
|
|
||||||
# Essai de recuperer le nom du departement dans ses preferences
|
|
||||||
try:
|
|
||||||
DeptName = (
|
|
||||||
deptFolder.Scolarite.get_preference("DeptName") or deptFolder.id
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
DeptName = deptFolder.id
|
|
||||||
H.append(
|
|
||||||
'<li><a class="stdlink %s" href="%s%s">Département %s</a>'
|
|
||||||
% (link_cls, deptFolder.absolute_url(), dest_folder, DeptName)
|
|
||||||
)
|
|
||||||
# check if roles are initialized in this depts, and do it if necessary
|
|
||||||
if deptFolder.Scolarite.roles_initialized == "0":
|
|
||||||
if isAdmin:
|
|
||||||
deptFolder.Scolarite._setup_initial_roles_and_permissions()
|
|
||||||
else:
|
|
||||||
H.append(" (non initialisé, connectez vous comme admin)")
|
|
||||||
H.append("</li>")
|
|
||||||
H.append("</ul>")
|
|
||||||
# Recherche etudiant
|
|
||||||
H.append(sco_find_etud.form_search_etud_in_accessible_depts(self, REQUEST))
|
|
||||||
|
|
||||||
if isAdmin:
|
|
||||||
H.append('<p><a href="scodoc_admin">Administration de ScoDoc</a></p>')
|
|
||||||
else:
|
|
||||||
H.append(
|
|
||||||
'<p><a href="%s/force_admin_authentication">Se connecter comme administrateur</a></p>'
|
|
||||||
% REQUEST.BASE0
|
|
||||||
)
|
|
||||||
|
|
||||||
# Lien expérimental temporaire:
|
|
||||||
H.append(
|
|
||||||
'<p><a href="/ScoDoc/static/mobile">Version mobile (expérimentale, à vos risques et périls)</a></p>'
|
|
||||||
)
|
|
||||||
|
|
||||||
H.append(
|
|
||||||
"""
|
|
||||||
<div id="scodoc_attribution">
|
|
||||||
<p><a href="%s">ScoDoc</a> est un logiciel libre de suivi de la scolarité des étudiants conçu par
|
|
||||||
E. Viennet (Université Paris 13).</p>
|
|
||||||
</div>
|
|
||||||
</div>"""
|
|
||||||
% (scu.SCO_WEBSITE,)
|
|
||||||
)
|
|
||||||
|
|
||||||
H.append("""</body></html>""")
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
def authentication_form(self, destination=""):
|
|
||||||
"""html snippet for authentication"""
|
|
||||||
return (
|
|
||||||
"""<!-- authentication_form -->
|
|
||||||
<form action="doLogin" method="post">
|
|
||||||
<input type="hidden" name="destination" value="%s"/>
|
|
||||||
<p>
|
|
||||||
<table border="0" cellpadding="3">
|
|
||||||
<tr>
|
|
||||||
<td><b>Nom:</b></td>
|
|
||||||
<td><input id="name" type="text" name="__ac_name" size="20"/></td>
|
|
||||||
</tr><tr>
|
|
||||||
<td><b>Mot de passe:</b></td>
|
|
||||||
<td><input id="password" type="password" name="__ac_password" size="20"/></td>
|
|
||||||
<td><input id="submit" name="submit" type="submit" value="OK"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</p>
|
|
||||||
</form>"""
|
|
||||||
% destination
|
|
||||||
)
|
|
||||||
|
|
||||||
security.declareProtected("View", "index_dept")
|
|
||||||
|
|
||||||
def index_dept(self, deptfoldername="", REQUEST=None):
|
|
||||||
"""Page d'accueil departement"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
try:
|
|
||||||
dept = getattr(self, deptfoldername)
|
|
||||||
if authuser.has_permission(Permission.ScoView, dept):
|
|
||||||
return REQUEST.RESPONSE.redirect("ScoDoc/%s/Scolarite" % deptfoldername)
|
|
||||||
except:
|
|
||||||
log(
|
|
||||||
"*** problem in index_dept (%s) user=%s"
|
|
||||||
% (deptfoldername, str(authuser))
|
|
||||||
)
|
|
||||||
|
|
||||||
H = [
|
|
||||||
html_sco_header.standard_html_header(),
|
|
||||||
"""<div style="margin: 1em;">
|
|
||||||
<h2>Scolarité du département %s</h2>"""
|
|
||||||
% deptfoldername,
|
|
||||||
"""<p>Ce site est
|
|
||||||
<font color="#FF0000"><b>réservé au personnel du département</b></font>.
|
|
||||||
</p>""",
|
|
||||||
self.authentication_form(destination="Scolarite"),
|
|
||||||
"""
|
|
||||||
<p>Pour quitter, <a href="acl_users/logout">logout</a></p>
|
|
||||||
<p><a href="%s">Retour à l'accueil</a></p>
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
% self.ScoDocURL(),
|
|
||||||
html_sco_header.standard_html_footer(),
|
|
||||||
]
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
security.declareProtected("View", "doLogin")
|
|
||||||
|
|
||||||
def doLogin(self, REQUEST=None, destination=None):
|
|
||||||
"redirect to destination after login"
|
|
||||||
if destination:
|
|
||||||
return REQUEST.RESPONSE.redirect(destination)
|
|
||||||
|
|
||||||
security.declareProtected("View", "docLogin")
|
|
||||||
docLogin = DTMLFile("dtml/docLogin", globals())
|
|
||||||
security.declareProtected("View", "docLogout")
|
|
||||||
docLogout = DTMLFile("dtml/docLogout", globals())
|
|
||||||
|
|
||||||
security.declareProtected("View", "query_string_to_form_inputs")
|
|
||||||
|
|
||||||
def query_string_to_form_inputs(self, query_string=""):
|
|
||||||
"""Return html snippet representing the query string as POST form hidden inputs.
|
|
||||||
This is useful in conjonction with exUserfolder to correctly redirect the response
|
|
||||||
after authentication.
|
|
||||||
"""
|
|
||||||
H = []
|
|
||||||
for a in query_string.split("&"):
|
|
||||||
if a:
|
|
||||||
nv = a.split("=")
|
|
||||||
if len(nv) == 2:
|
|
||||||
name, value = nv
|
|
||||||
H.append(
|
|
||||||
'<input type="hidden" name="'
|
|
||||||
+ name
|
|
||||||
+ '" value="'
|
|
||||||
+ value
|
|
||||||
+ '"/>'
|
|
||||||
)
|
|
||||||
|
|
||||||
return "<!-- query string -->\n" + "\n".join(H)
|
|
||||||
|
|
||||||
security.declareProtected("View", "standard_error_message")
|
|
||||||
|
|
||||||
def standard_error_message(
|
|
||||||
self,
|
|
||||||
error_value=None,
|
|
||||||
error_message=None, # unused ?
|
|
||||||
error_type=None,
|
|
||||||
error_traceback=None,
|
|
||||||
error_tb=None,
|
|
||||||
**kv
|
|
||||||
):
|
|
||||||
"Recuperation des exceptions Zope"
|
|
||||||
# neat (or should I say dirty ?) hack to get REQUEST
|
|
||||||
# in fact, our caller (probably SimpleItem.py) has the REQUEST variable
|
|
||||||
# that we'd like to use for our logs, but does not pass it as an argument.
|
|
||||||
try:
|
|
||||||
frame = inspect.currentframe()
|
|
||||||
REQUEST = frame.f_back.f_locals["REQUEST"]
|
|
||||||
except:
|
|
||||||
REQUEST = {}
|
|
||||||
|
|
||||||
# Authentication uses exceptions, pass them up
|
|
||||||
HTTP_X_FORWARDED_FOR = REQUEST.get("HTTP_X_FORWARDED_FOR", "")
|
|
||||||
if error_type == "LoginRequired":
|
|
||||||
log("LoginRequired from %s" % HTTP_X_FORWARDED_FOR)
|
|
||||||
self.login_page = error_value
|
|
||||||
return error_value
|
|
||||||
elif error_type == "Unauthorized":
|
|
||||||
log("Unauthorized from %s" % HTTP_X_FORWARDED_FOR)
|
|
||||||
return self.acl_users.docLogin(self, REQUEST=REQUEST)
|
|
||||||
|
|
||||||
log("exception caught: %s" % error_type)
|
|
||||||
log(traceback.format_exc())
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"error_type": error_type,
|
|
||||||
"error_value": error_value,
|
|
||||||
"error_tb": error_tb,
|
|
||||||
"sco_exc_mail": scu.SCO_EXC_MAIL,
|
|
||||||
"sco_dev_mail": scu.SCO_DEV_MAIL,
|
|
||||||
}
|
|
||||||
|
|
||||||
if error_type == "ScoGenError":
|
|
||||||
return "<p>" + str(error_value) + "</p>"
|
|
||||||
elif error_type in ("ScoValueError", "FormatError"):
|
|
||||||
# Not a bug, presents a gentle message to the user:
|
|
||||||
H = [
|
|
||||||
html_sco_header.standard_html_header(),
|
|
||||||
"""<h2>Erreur !</h2><p>%s</p>""" % error_value,
|
|
||||||
]
|
|
||||||
if error_value.dest_url:
|
|
||||||
H.append('<p><a href="%s">Continuer</a></p>' % error_value.dest_url)
|
|
||||||
H.append(html_sco_header.standard_html_footer())
|
|
||||||
return "\n".join(H)
|
|
||||||
else: # Other exceptions, try carefully to build an error page...
|
|
||||||
# log('exc A')
|
|
||||||
H = []
|
|
||||||
try:
|
|
||||||
H.append(html_sco_header.standard_html_header())
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
H.append(
|
|
||||||
"""<table border="0" width="100%%"><tr valign="top">
|
|
||||||
<td width="10%%" align="center"></td>
|
|
||||||
<td width="90%%"><h2>Erreur !</h2>
|
|
||||||
<p>Une erreur est survenue</p>
|
|
||||||
<p>
|
|
||||||
<strong>Error Type: %(error_type)s</strong><br>
|
|
||||||
<strong>Error Value: %(error_value)s</strong><br>
|
|
||||||
</p>
|
|
||||||
<hr noshade>
|
|
||||||
<p>L'URL est peut-etre incorrecte ?</p>
|
|
||||||
|
|
||||||
<p>Si l'erreur persiste, contactez Emmanuel Viennet:
|
|
||||||
<a href="mailto:%(sco_dev_mail)s">%(sco_dev_mail)s</a>
|
|
||||||
en copiant ce message d'erreur et le contenu du cadre bleu ci-dessous si possible.
|
|
||||||
</p>
|
|
||||||
</td></tr>
|
|
||||||
</table> """
|
|
||||||
% params
|
|
||||||
)
|
|
||||||
# display error traceback (? may open a security risk via xss attack ?)
|
|
||||||
params["txt_html"] = self._report_request(REQUEST, fmt="html")
|
|
||||||
H.append(
|
|
||||||
"""<h4 class="scodoc">Zope Traceback (à envoyer par mail à <a href="mailto:%(sco_dev_mail)s">%(sco_dev_mail)s</a>)</h4><div style="background-color: rgb(153,153,204); border: 1px;">
|
|
||||||
%(error_tb)s
|
|
||||||
<p><b>Informations:</b><br/>
|
|
||||||
%(txt_html)s
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>Merci de votre patience !</p>
|
|
||||||
"""
|
|
||||||
% params
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
H.append(html_sco_header.standard_html_footer())
|
|
||||||
except:
|
|
||||||
log("no footer found for error page")
|
|
||||||
pass
|
|
||||||
|
|
||||||
# --- Mail:
|
|
||||||
params["error_traceback_txt"] = scu.scodoc_html2txt(error_tb)
|
|
||||||
txt = (
|
|
||||||
"""
|
|
||||||
ErrorType: %(error_type)s
|
|
||||||
|
|
||||||
%(error_traceback_txt)s
|
|
||||||
"""
|
|
||||||
% params
|
|
||||||
)
|
|
||||||
|
|
||||||
mails.send_debug_alert(context, txt, REQUEST=REQUEST)
|
|
||||||
# ---
|
|
||||||
log("done processing exception")
|
|
||||||
# log( '\n page=\n' + '\n'.join(H) )
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
security.declareProtected("View", "scodoc_admin")
|
|
||||||
|
|
||||||
def scodoc_admin(self, REQUEST=None):
|
|
||||||
"""Page Operations d'administration"""
|
|
||||||
e = self._check_admin_perm(REQUEST)
|
|
||||||
if e:
|
|
||||||
return e
|
|
||||||
|
|
||||||
H = [
|
|
||||||
html_sco_header.scodoc_top_html_header(
|
|
||||||
self, REQUEST, page_title="ScoDoc: bienvenue"
|
|
||||||
),
|
|
||||||
"""
|
|
||||||
<h3>Administration ScoDoc</h3>
|
|
||||||
|
|
||||||
<p><a href="change_admin_user_form">changer le mot de passe super-administrateur</a></p>
|
|
||||||
<p><a href="%s">retour à la page d'accueil</a></p>
|
|
||||||
|
|
||||||
<h4 class="scodoc">Création d'un département</h4>
|
|
||||||
<p class="help_important">Le département doit avoir été créé au préalable sur le serveur en utilisant le script
|
|
||||||
<tt>create_dept.sh</tt> (à lancer comme <tt>root</tt> dans le répertoire <tt>config</tt> de ScoDoc).
|
|
||||||
</p>"""
|
|
||||||
% self.absolute_url(),
|
|
||||||
]
|
|
||||||
|
|
||||||
deptList = [x.id for x in self._list_depts()] # definis dans Zope
|
|
||||||
deptIds = set(self._list_depts_ids()) # definis sur le filesystem
|
|
||||||
existingDepts = set(deptList)
|
|
||||||
addableDepts = deptIds - existingDepts
|
|
||||||
|
|
||||||
if not addableDepts:
|
|
||||||
# aucun departement defini: aide utilisateur
|
|
||||||
H.append("<p>Aucun département à ajouter !</p>")
|
|
||||||
else:
|
|
||||||
H.append("""<form action="create_dept"><select name="DeptId"/>""")
|
|
||||||
for deptId in addableDepts:
|
|
||||||
H.append("""<option value="%s">%s</option>""" % (deptId, deptId))
|
|
||||||
H.append(
|
|
||||||
"""</select>
|
|
||||||
<input type="submit" value="Créer département">
|
|
||||||
</form>"""
|
|
||||||
)
|
|
||||||
|
|
||||||
if deptList:
|
|
||||||
H.append(
|
|
||||||
"""
|
|
||||||
<h4 class="scodoc">Suppression d'un département</h4>
|
|
||||||
<p>Ceci permet de supprimer le site web associé à un département, mais n'affecte pas la base de données
|
|
||||||
(le site peut donc être recréé sans perte de données).
|
|
||||||
</p>
|
|
||||||
<form action="delete_dept">
|
|
||||||
<select name="DeptId">
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
for deptFolder in self._list_depts():
|
|
||||||
H.append(
|
|
||||||
'<option value="%s">%s</option>' % (deptFolder.id, deptFolder.id)
|
|
||||||
)
|
|
||||||
H.append(
|
|
||||||
"""</select>
|
|
||||||
<input type="submit" value="Supprimer département">
|
|
||||||
|
|
||||||
</form>"""
|
|
||||||
)
|
|
||||||
|
|
||||||
H.append("""</body></html>""")
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
def _list_depts_ids(self):
|
|
||||||
"""Liste de id de departements definis par create_dept.sh
|
|
||||||
(fichiers depts/*.cfg)
|
|
||||||
"""
|
|
||||||
filenames = glob.glob(scu.SCODOC_VAR_DIR + "/config/depts/*.cfg")
|
|
||||||
ids = [os.path.split(os.path.splitext(f)[0])[1] for f in filenames]
|
|
||||||
return ids
|
|
||||||
|
|
||||||
security.declareProtected("View", "http_expiration_date")
|
|
||||||
|
|
||||||
def http_expiration_date(self):
|
|
||||||
"http expiration date for cachable elements (css, ...)"
|
|
||||||
d = datetime.timedelta(minutes=10)
|
|
||||||
return (datetime.datetime.utcnow() + d).strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
|
|
||||||
security.declareProtected("View", "get_etud_dept")
|
|
||||||
|
|
||||||
def get_etud_dept(self, REQUEST=None):
|
|
||||||
"""Returns the dept id (eg "GEII") of an etud (identified by etudid, INE or NIP in REQUEST).
|
|
||||||
Warning: This function is inefficient and its result should be cached.
|
|
||||||
"""
|
|
||||||
depts = self._list_depts()
|
|
||||||
depts_etud = [] # liste des depts où l'etud est defini
|
|
||||||
for dept in depts:
|
|
||||||
etuds = dept.Scolarite.getEtudInfo(REQUEST=REQUEST)
|
|
||||||
if etuds:
|
|
||||||
depts_etud.append((dept, etuds))
|
|
||||||
if not depts_etud:
|
|
||||||
return "" # not found
|
|
||||||
elif len(depts_etud) == 1:
|
|
||||||
return depts_etud[0][0].id
|
|
||||||
# inscriptions dans plusieurs departements: cherche la plus recente
|
|
||||||
last_dept = None
|
|
||||||
last_date = None
|
|
||||||
for (dept, etuds) in depts_etud:
|
|
||||||
sco_etud.fill_etuds_info(self, etuds)
|
|
||||||
etud = etuds[0]
|
|
||||||
if etud["sems"]:
|
|
||||||
if (not last_date) or (etud["sems"][0]["date_fin_iso"] > last_date):
|
|
||||||
last_date = etud["sems"][0]["date_fin_iso"]
|
|
||||||
last_dept = dept
|
|
||||||
if not last_dept:
|
|
||||||
# est present dans plusieurs semestres mais inscrit dans aucun
|
|
||||||
return depts_etud[0][0]
|
|
||||||
return last_dept.id
|
|
||||||
|
|
||||||
security.declareProtected("View", "table_etud_in_accessible_depts")
|
|
||||||
table_etud_in_accessible_depts = sco_find_etud.table_etud_in_accessible_depts
|
|
||||||
|
|
||||||
security.declareProtected("View", "search_inscr_etud_by_nip")
|
|
||||||
search_inscr_etud_by_nip = sco_find_etud.search_inscr_etud_by_nip
|
|
||||||
|
|
||||||
|
|
||||||
def manage_addZScoDoc(self, id="ScoDoc", title="Site ScoDoc", REQUEST=None):
|
|
||||||
"Add a ZScoDoc instance to a folder."
|
|
||||||
log("============== creating a new ScoDoc instance =============")
|
|
||||||
zscodoc = ZScoDoc(
|
|
||||||
id, title
|
|
||||||
) # ne cree (presque rien), tout se passe lors du 1er accès
|
|
||||||
self._setObject(id, zscodoc)
|
|
||||||
if REQUEST is not None:
|
|
||||||
REQUEST.RESPONSE.redirect("/ScoDoc/manage_workspace")
|
|
||||||
return id
|
|
@ -27,7 +27,7 @@ for sem in sems:
|
|||||||
print sem['formsemestre_id'], sem['titre_num']
|
print sem['formsemestre_id'], sem['titre_num']
|
||||||
|
|
||||||
# Recupere la table de notes:
|
# Recupere la table de notes:
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id)
|
nt = sco_core.get_notes_cache(context).get_NotesTable(context.Notes, formsemestre_id)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -54,9 +54,10 @@ from reportlab.lib import styles
|
|||||||
from reportlab.lib.units import inch, cm, mm
|
from reportlab.lib.units import inch, cm, mm
|
||||||
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
|
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
from app.scodoc import html_sco_header
|
||||||
import app.scodoc.sco_excel
|
from app.scodoc import sco_utils as scu
|
||||||
import app.scodoc.sco_pdf
|
from app.scodoc import sco_excel
|
||||||
|
from app.scodoc import sco_pdf
|
||||||
from app.scodoc.sco_pdf import SU
|
from app.scodoc.sco_pdf import SU
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ def retreive_dept():
|
|||||||
# Alarms by email:
|
# Alarms by email:
|
||||||
def sendAlarm(context, subj, txt):
|
def sendAlarm(context, subj, txt):
|
||||||
import sco_utils
|
import sco_utils
|
||||||
import mails
|
import sco_emails
|
||||||
import sco_preferences
|
import sco_preferences
|
||||||
|
|
||||||
msg = MIMEMultipart()
|
msg = MIMEMultipart()
|
||||||
@ -111,7 +111,7 @@ def sendAlarm(context, subj, txt):
|
|||||||
msg.epilogue = ""
|
msg.epilogue = ""
|
||||||
txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING)
|
txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING)
|
||||||
msg.attach(txt)
|
msg.attach(txt)
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
|
|
||||||
|
|
||||||
# Debug: log call stack
|
# Debug: log call stack
|
||||||
|
@ -57,7 +57,8 @@ import pprint
|
|||||||
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant
|
from app.scodoc import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant
|
||||||
|
from app.scodoc import sco_core
|
||||||
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import pe_tagtable
|
from app.scodoc import pe_tagtable
|
||||||
from app.scodoc import pe_tools
|
from app.scodoc import pe_tools
|
||||||
from app.scodoc import pe_semestretag
|
from app.scodoc import pe_semestretag
|
||||||
@ -331,7 +332,7 @@ class JuryPE:
|
|||||||
nt = self.get_cache_notes_d_un_semestre(
|
nt = self.get_cache_notes_d_un_semestre(
|
||||||
self.context, sem["formsemestre_id"]
|
self.context, sem["formsemestre_id"]
|
||||||
)
|
)
|
||||||
# context.Notes._getNotesCache().get_NotesTable(context.Notes, sem['formsemestre_id'])
|
# sco_core.get_notes_cache(context).get_NotesTable(context.Notes, sem['formsemestre_id'])
|
||||||
etudiantsDuSemestre = (
|
etudiantsDuSemestre = (
|
||||||
nt.get_etudids()
|
nt.get_etudids()
|
||||||
) # nt.identdict.keys() # identification des etudiants du semestre
|
) # nt.identdict.keys() # identification des etudiants du semestre
|
||||||
@ -1139,7 +1140,7 @@ class JuryPE:
|
|||||||
self, context, formsemestre_id
|
self, context, formsemestre_id
|
||||||
): # inutile en realité !
|
): # inutile en realité !
|
||||||
"""Charge la table des notes d'un formsemestre"""
|
"""Charge la table des notes d'un formsemestre"""
|
||||||
return context.Notes._getNotesCache().get_NotesTable(
|
return sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ Created on Fri Sep 9 09:15:05 2016
|
|||||||
|
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_tag_module
|
from app.scodoc import sco_tag_module
|
||||||
from app.scodoc import pe_tagtable
|
from app.scodoc import pe_tagtable
|
||||||
|
|
||||||
@ -269,8 +270,8 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
# => le formsemestre_id du semestre dont vient la capitalisation
|
# => le formsemestre_id du semestre dont vient la capitalisation
|
||||||
fid_prec = fids_prec[0]
|
fid_prec = fids_prec[0]
|
||||||
# Lecture des notes de ce semestre
|
# Lecture des notes de ce semestre
|
||||||
nt_prec = self.context.Notes._getNotesCache().get_NotesTable(
|
nt_prec = sco_core.get_notes_cache(self.context).get_NotesTable(
|
||||||
self.context.Notes, fid_prec
|
self.context, fid_prec
|
||||||
) # le tableau de note du semestre considéré
|
) # le tableau de note du semestre considéré
|
||||||
|
|
||||||
# Y-a-t-il un module équivalent c'est à dire correspondant au même code (le module_id n'étant pas significatif en cas de changement de PPN)
|
# Y-a-t-il un module équivalent c'est à dire correspondant au même code (le module_id n'étant pas significatif en cas de changement de PPN)
|
||||||
|
@ -41,9 +41,10 @@ from app.scodoc import notesdb as ndb
|
|||||||
from app.scodoc.scolog import logdb
|
from app.scodoc.scolog import logdb
|
||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
|
from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
|
||||||
from app.scodoc import sco_abs_notification
|
from app.scodoc import sco_abs_notification
|
||||||
|
from app.scodoc import sco_core
|
||||||
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_etud
|
|
||||||
|
|
||||||
# --- Misc tools.... ------------------
|
# --- Misc tools.... ------------------
|
||||||
|
|
||||||
@ -968,7 +969,7 @@ class CAbsSemEtud:
|
|||||||
self.etudid = etudid
|
self.etudid = etudid
|
||||||
self._loaded = False
|
self._loaded = False
|
||||||
formsemestre_id = sem["formsemestre_id"]
|
formsemestre_id = sem["formsemestre_id"]
|
||||||
context.Notes._getNotesCache().add_listener(
|
sco_core.get_notes_cache(context).add_listener(
|
||||||
self.invalidate, formsemestre_id, (etudid, formsemestre_id)
|
self.invalidate, formsemestre_id, (etudid, formsemestre_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -992,11 +993,11 @@ class CAbsSemEtud:
|
|||||||
debut_sem = ndb.DateDMYtoISO(self.sem["date_debut"])
|
debut_sem = ndb.DateDMYtoISO(self.sem["date_debut"])
|
||||||
fin_sem = ndb.DateDMYtoISO(self.sem["date_fin"])
|
fin_sem = ndb.DateDMYtoISO(self.sem["date_fin"])
|
||||||
|
|
||||||
self._CountAbs = self.sco_abs.CountAbs(
|
self._CountAbs = CountAbs(
|
||||||
context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||||
)
|
)
|
||||||
self._CountAbsJust = self.sco_abs.CountAbsJust(
|
self._CountAbsJust = CountAbsJust(
|
||||||
context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||||
)
|
)
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ from email.mime.multipart import MIMEMultipart
|
|||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
|
|
||||||
from app.scodoc import mails
|
from app.scodoc import sco_emails
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
@ -119,7 +119,7 @@ def abs_notify_send(
|
|||||||
for email in destinations:
|
for email in destinations:
|
||||||
del msg["To"]
|
del msg["To"]
|
||||||
msg["To"] = email
|
msg["To"] = email
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
ndb.SimpleQuery(
|
ndb.SimpleQuery(
|
||||||
context,
|
context,
|
||||||
"""insert into absences_notifications (etudid, email, nbabs, nbabsjust, formsemestre_id) values (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)""",
|
"""insert into absences_notifications (etudid, email, nbabs, nbabsjust, formsemestre_id) values (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)""",
|
||||||
|
@ -39,6 +39,7 @@ from app.scodoc.scolog import logdb
|
|||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_abs
|
from app.scodoc import sco_abs
|
||||||
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_find_etud
|
from app.scodoc import sco_find_etud
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
@ -124,7 +125,7 @@ def doSignaleAbsence(
|
|||||||
if moduleimpl_id and moduleimpl_id != "NULL":
|
if moduleimpl_id and moduleimpl_id != "NULL":
|
||||||
mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||||
formsemestre_id = mod["formsemestre_id"]
|
formsemestre_id = mod["formsemestre_id"]
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
)
|
)
|
||||||
ues = nt.get_ues(etudid=etudid)
|
ues = nt.get_ues(etudid=etudid)
|
||||||
@ -185,7 +186,7 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
|
|||||||
require_module = sco_preferences.get_preference(
|
require_module = sco_preferences.get_preference(
|
||||||
context, "abs_require_module", formsemestre_id
|
context, "abs_require_module", formsemestre_id
|
||||||
)
|
)
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
)
|
)
|
||||||
ues = nt.get_ues(etudid=etudid)
|
ues = nt.get_ues(etudid=etudid)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc import ImportScolars
|
from app.scodoc import sco_import_etuds
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_trombino
|
from app.scodoc import sco_trombino
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
@ -227,8 +227,8 @@ def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename):
|
|||||||
# --- Upload d'un ensemble de fichiers (pour un groupe d'étudiants)
|
# --- Upload d'un ensemble de fichiers (pour un groupe d'étudiants)
|
||||||
def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
|
def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
|
||||||
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)"""
|
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)"""
|
||||||
fmt = ImportScolars.sco_import_format()
|
fmt = sco_import_etuds.sco_import_format()
|
||||||
data = ImportScolars.sco_import_generate_excel_sample(
|
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||||
fmt,
|
fmt,
|
||||||
context=context,
|
context=context,
|
||||||
group_ids=[group_id],
|
group_ids=[group_id],
|
||||||
|
@ -41,13 +41,14 @@ from email.header import Header
|
|||||||
|
|
||||||
from reportlab.lib.colors import Color
|
from reportlab.lib.colors import Color
|
||||||
|
|
||||||
from app.scodoc import mails
|
from app.scodoc import sco_emails
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_exceptions import AccessDenied
|
from app.scodoc.sco_exceptions import AccessDenied
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import sco_abs
|
||||||
from app.scodoc import sco_abs_views
|
from app.scodoc import sco_abs_views
|
||||||
from app.scodoc import sco_bulletins_generator
|
from app.scodoc import sco_bulletins_generator
|
||||||
from app.scodoc import sco_bulletins_json
|
from app.scodoc import sco_bulletins_json
|
||||||
@ -1048,7 +1049,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
|
|||||||
email.encoders.encode_base64(att)
|
email.encoders.encode_base64(att)
|
||||||
msg.attach(att)
|
msg.attach(att)
|
||||||
log("mail bulletin a %s" % msg["To"])
|
log("mail bulletin a %s" % msg["To"])
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
|
|
||||||
|
|
||||||
def _formsemestre_bulletinetud_header_html(
|
def _formsemestre_bulletinetud_header_html(
|
||||||
|
@ -47,6 +47,7 @@ from app.scodoc import sco_abs
|
|||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
from app.scodoc import sco_formulas
|
from app.scodoc import sco_formulas
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
@ -211,8 +212,8 @@ def do_moduleimpl_moyennes(context, nt, mod):
|
|||||||
inssem_set = set(
|
inssem_set = set(
|
||||||
[
|
[
|
||||||
x["etudid"]
|
x["etudid"]
|
||||||
for x in context.do_formsemestre_inscription_listinscrits(
|
for x in sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||||
mod["formsemestre_id"]
|
context, mod["formsemestre_id"]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -254,7 +254,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
|
|||||||
)
|
)
|
||||||
#
|
#
|
||||||
if create:
|
if create:
|
||||||
formation_id = context.do_formation_create(tf[2], REQUEST)
|
formation_id = do_formation_create(context, tf[2], REQUEST)
|
||||||
else:
|
else:
|
||||||
do_formation_edit(context, tf[2])
|
do_formation_edit(context, tf[2])
|
||||||
return REQUEST.RESPONSE.redirect("ue_list?formation_id=%s" % formation_id)
|
return REQUEST.RESPONSE.redirect("ue_list?formation_id=%s" % formation_id)
|
||||||
|
@ -41,6 +41,7 @@ from email import Encoders # pylint: disable=no-name-in-module,import-error
|
|||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
|
from app.scodoc import VERSION
|
||||||
|
|
||||||
|
|
||||||
def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8
|
def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8
|
@ -389,7 +389,7 @@ apo_csv_store(context, csv_data, annee_scolaire, sem_id)
|
|||||||
|
|
||||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(context, [sco_groups.get_default_group(context, formsemestre_id)], formsemestre_id=formsemestre_id, REQUEST=REQUEST)
|
groups_infos = sco_groups_view.DisplayedGroupsInfos(context, [sco_groups.get_default_group(context, formsemestre_id)], formsemestre_id=formsemestre_id, REQUEST=REQUEST)
|
||||||
|
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id)
|
nt = sco_core.get_notes_cache(context).get_NotesTable(context.Notes, formsemestre_id)
|
||||||
|
|
||||||
#
|
#
|
||||||
s = SemSet(context, 'NSS29902')
|
s = SemSet(context, 'NSS29902')
|
||||||
|
@ -37,7 +37,7 @@ from email.mime.text import MIMEText
|
|||||||
from email.header import Header
|
from email.header import Header
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
|
|
||||||
from app.scodoc import mails
|
from app.scodoc import sco_emails
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.sco_utils import SCO_ENCODING
|
from app.scodoc.sco_utils import SCO_ENCODING
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
@ -46,7 +46,6 @@ from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
|
|||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
from app.scodoc import safehtml
|
from app.scodoc import safehtml
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.scolog import logdb
|
from app.scodoc.scolog import logdb
|
||||||
|
|
||||||
@ -450,7 +449,7 @@ def notify_etud_change(context, email_addr, etud, before, after, subject):
|
|||||||
msg["To"] = email_addr
|
msg["To"] = email_addr
|
||||||
mime_txt = MIMEText(txt, "plain", SCO_ENCODING)
|
mime_txt = MIMEText(txt, "plain", SCO_ENCODING)
|
||||||
msg.attach(mime_txt)
|
msg.attach(mime_txt)
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@ -901,6 +900,7 @@ def fill_etuds_info(etuds):
|
|||||||
Pour chaque etudiant, ajoute ou formatte les champs
|
Pour chaque etudiant, ajoute ou formatte les champs
|
||||||
-> informations pour fiche etudiant ou listes diverses
|
-> informations pour fiche etudiant ou listes diverses
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_inscriptions
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
|
|
||||||
context = None # XXX en attendant la suppression du context ScoDoc7
|
context = None # XXX en attendant la suppression du context ScoDoc7
|
||||||
@ -1004,6 +1004,8 @@ def fill_etuds_info(etuds):
|
|||||||
|
|
||||||
def descr_situation_etud(context, etudid, ne=""):
|
def descr_situation_etud(context, etudid, ne=""):
|
||||||
"""chaine decrivant la situation actuelle de l'etudiant"""
|
"""chaine decrivant la situation actuelle de l'etudiant"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
|
@ -45,6 +45,7 @@ from app.scodoc import sco_core
|
|||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_news
|
from app.scodoc import sco_news
|
||||||
@ -180,6 +181,146 @@ def do_evaluation_list_in_formsemestre(context, formsemestre_id):
|
|||||||
return evals
|
return evals
|
||||||
|
|
||||||
|
|
||||||
|
def _check_evaluation_args(context, args):
|
||||||
|
"Check coefficient, dates and duration, raises exception if invalid"
|
||||||
|
moduleimpl_id = args["moduleimpl_id"]
|
||||||
|
# check bareme
|
||||||
|
note_max = args.get("note_max", None)
|
||||||
|
if note_max is None:
|
||||||
|
raise ScoValueError("missing note_max")
|
||||||
|
try:
|
||||||
|
note_max = float(note_max)
|
||||||
|
except ValueError:
|
||||||
|
raise ScoValueError("Invalid note_max value")
|
||||||
|
if note_max < 0:
|
||||||
|
raise ScoValueError("Invalid note_max value (must be positive or null)")
|
||||||
|
# check coefficient
|
||||||
|
coef = args.get("coefficient", None)
|
||||||
|
if coef is None:
|
||||||
|
raise ScoValueError("missing coefficient")
|
||||||
|
try:
|
||||||
|
coef = float(coef)
|
||||||
|
except ValueError:
|
||||||
|
raise ScoValueError("Invalid coefficient value")
|
||||||
|
if coef < 0:
|
||||||
|
raise ScoValueError("Invalid coefficient value (must be positive or null)")
|
||||||
|
# check date
|
||||||
|
jour = args.get("jour", None)
|
||||||
|
args["jour"] = jour
|
||||||
|
if jour:
|
||||||
|
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||||
|
d, m, y = [int(x) for x in sem["date_debut"].split("/")]
|
||||||
|
date_debut = datetime.date(y, m, d)
|
||||||
|
d, m, y = [int(x) for x in sem["date_fin"].split("/")]
|
||||||
|
date_fin = datetime.date(y, m, d)
|
||||||
|
# passe par ndb.DateDMYtoISO pour avoir date pivot
|
||||||
|
y, m, d = [int(x) for x in ndb.DateDMYtoISO(jour).split("-")]
|
||||||
|
jour = datetime.date(y, m, d)
|
||||||
|
if (jour > date_fin) or (jour < date_debut):
|
||||||
|
raise ScoValueError(
|
||||||
|
"La date de l'évaluation (%s/%s/%s) n'est pas dans le semestre !"
|
||||||
|
% (d, m, y)
|
||||||
|
)
|
||||||
|
heure_debut = args.get("heure_debut", None)
|
||||||
|
args["heure_debut"] = heure_debut
|
||||||
|
heure_fin = args.get("heure_fin", None)
|
||||||
|
args["heure_fin"] = heure_fin
|
||||||
|
if jour and ((not heure_debut) or (not heure_fin)):
|
||||||
|
raise ScoValueError("Les heures doivent être précisées")
|
||||||
|
d = ndb.TimeDuration(heure_debut, heure_fin)
|
||||||
|
if d and ((d < 0) or (d > 60 * 12)):
|
||||||
|
raise ScoValueError("Heures de l'évaluation incohérentes !")
|
||||||
|
|
||||||
|
|
||||||
|
def do_evaluation_create(
|
||||||
|
context,
|
||||||
|
moduleimpl_id=None,
|
||||||
|
jour=None,
|
||||||
|
heure_debut=None,
|
||||||
|
heure_fin=None,
|
||||||
|
description=None,
|
||||||
|
note_max=None,
|
||||||
|
coefficient=None,
|
||||||
|
visibulletin=None,
|
||||||
|
publish_incomplete=None,
|
||||||
|
evaluation_type=None,
|
||||||
|
numero=None,
|
||||||
|
REQUEST=None,
|
||||||
|
):
|
||||||
|
"""Create an evaluation"""
|
||||||
|
if not sco_permissions_check.can_edit_evaluation(
|
||||||
|
context, REQUEST, moduleimpl_id=moduleimpl_id
|
||||||
|
):
|
||||||
|
raise AccessDenied(
|
||||||
|
"Modification évaluation impossible pour %s"
|
||||||
|
% scu.get_current_user_name(REQUEST)
|
||||||
|
)
|
||||||
|
args = locals()
|
||||||
|
log("do_evaluation_create: args=" + str(args))
|
||||||
|
_check_evaluation_args(context, args)
|
||||||
|
# Check numeros
|
||||||
|
module_evaluation_renumber(
|
||||||
|
context, moduleimpl_id, REQUEST=REQUEST, only_if_unumbered=True
|
||||||
|
)
|
||||||
|
if not "numero" in args or args["numero"] is None:
|
||||||
|
n = None
|
||||||
|
# determine le numero avec la date
|
||||||
|
# Liste des eval existantes triees par date, la plus ancienne en tete
|
||||||
|
ModEvals = do_evaluation_list(
|
||||||
|
context,
|
||||||
|
args={"moduleimpl_id": moduleimpl_id},
|
||||||
|
sortkey="jour asc, heure_debut asc",
|
||||||
|
)
|
||||||
|
if args["jour"]:
|
||||||
|
next_eval = None
|
||||||
|
t = (
|
||||||
|
ndb.DateDMYtoISO(args["jour"]),
|
||||||
|
ndb.TimetoISO8601(args["heure_debut"]),
|
||||||
|
)
|
||||||
|
for e in ModEvals:
|
||||||
|
if (
|
||||||
|
ndb.DateDMYtoISO(e["jour"]),
|
||||||
|
ndb.TimetoISO8601(e["heure_debut"]),
|
||||||
|
) > t:
|
||||||
|
next_eval = e
|
||||||
|
break
|
||||||
|
if next_eval:
|
||||||
|
n = module_evaluation_insert_before(
|
||||||
|
context, ModEvals, next_eval, REQUEST
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
n = None # a placer en fin
|
||||||
|
if n is None: # pas de date ou en fin:
|
||||||
|
if ModEvals:
|
||||||
|
log(pprint.pformat(ModEvals[-1]))
|
||||||
|
n = ModEvals[-1]["numero"] + 1
|
||||||
|
else:
|
||||||
|
n = 0 # the only one
|
||||||
|
# log("creating with numero n=%d" % n)
|
||||||
|
args["numero"] = n
|
||||||
|
|
||||||
|
#
|
||||||
|
cnx = ndb.GetDBConnexion()
|
||||||
|
r = _evaluationEditor.create(cnx, args)
|
||||||
|
|
||||||
|
# news
|
||||||
|
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||||
|
mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
|
||||||
|
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
||||||
|
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
||||||
|
sco_news.add(
|
||||||
|
context,
|
||||||
|
REQUEST,
|
||||||
|
typ=sco_news.NEWS_NOTE,
|
||||||
|
object=moduleimpl_id,
|
||||||
|
text='Création d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
||||||
|
url=mod["url"],
|
||||||
|
)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
def do_evaluation_edit(context, REQUEST, args):
|
def do_evaluation_edit(context, REQUEST, args):
|
||||||
"edit an evaluation"
|
"edit an evaluation"
|
||||||
evaluation_id = args["evaluation_id"]
|
evaluation_id = args["evaluation_id"]
|
||||||
@ -187,9 +328,16 @@ def do_evaluation_edit(context, REQUEST, args):
|
|||||||
if not the_evals:
|
if not the_evals:
|
||||||
raise ValueError("evaluation inexistante !")
|
raise ValueError("evaluation inexistante !")
|
||||||
moduleimpl_id = the_evals[0]["moduleimpl_id"]
|
moduleimpl_id = the_evals[0]["moduleimpl_id"]
|
||||||
|
if not sco_permissions_check.can_edit_evaluation(
|
||||||
|
context, REQUEST, moduleimpl_id=moduleimpl_id
|
||||||
|
):
|
||||||
|
raise AccessDenied(
|
||||||
|
"Modification évaluation impossible pour %s"
|
||||||
|
% scu.get_current_user_name(REQUEST)
|
||||||
|
)
|
||||||
args["moduleimpl_id"] = moduleimpl_id
|
args["moduleimpl_id"] = moduleimpl_id
|
||||||
context._check_evaluation_args(args)
|
_check_evaluation_args(context, args)
|
||||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
context._evaluationEditor.edit(cnx, args)
|
context._evaluationEditor.edit(cnx, args)
|
||||||
# inval cache pour ce semestre
|
# inval cache pour ce semestre
|
||||||
@ -204,7 +352,14 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
|
|||||||
the_evals = do_evaluation_list(context, {"evaluation_id": evaluation_id})
|
the_evals = do_evaluation_list(context, {"evaluation_id": evaluation_id})
|
||||||
if not the_evals:
|
if not the_evals:
|
||||||
raise ValueError("evaluation inexistante !")
|
raise ValueError("evaluation inexistante !")
|
||||||
|
moduleimpl_id = the_evals[0]["moduleimpl_id"]
|
||||||
|
if not sco_permissions_check.can_edit_evaluation(
|
||||||
|
context, REQUEST, moduleimpl_id=moduleimpl_id
|
||||||
|
):
|
||||||
|
raise AccessDenied(
|
||||||
|
"Modification évaluation impossible pour %s"
|
||||||
|
% scu.get_current_user_name(REQUEST)
|
||||||
|
)
|
||||||
NotesDB = do_evaluation_get_all_notes(context, evaluation_id) # { etudid : value }
|
NotesDB = do_evaluation_get_all_notes(context, evaluation_id) # { etudid : value }
|
||||||
notes = [x["value"] for x in NotesDB.values()]
|
notes = [x["value"] for x in NotesDB.values()]
|
||||||
if notes:
|
if notes:
|
||||||
@ -212,8 +367,6 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
|
|||||||
"Impossible de supprimer cette évaluation: il reste des notes"
|
"Impossible de supprimer cette évaluation: il reste des notes"
|
||||||
)
|
)
|
||||||
|
|
||||||
moduleimpl_id = the_evals[0]["moduleimpl_id"]
|
|
||||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
|
|
||||||
context._evaluationEditor.delete(cnx, evaluation_id)
|
context._evaluationEditor.delete(cnx, evaluation_id)
|
||||||
@ -295,7 +448,9 @@ def do_evaluation_etat(
|
|||||||
# Il faut considerer les inscriptions au semestre
|
# Il faut considerer les inscriptions au semestre
|
||||||
# (pour avoir l'etat et le groupe) et aussi les inscriptions
|
# (pour avoir l'etat et le groupe) et aussi les inscriptions
|
||||||
# au module (pour gerer les modules optionnels correctement)
|
# au module (pour gerer les modules optionnels correctement)
|
||||||
insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
|
insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||||
|
context, formsemestre_id
|
||||||
|
)
|
||||||
insmod = sco_moduleimpl.do_moduleimpl_inscription_list(
|
insmod = sco_moduleimpl.do_moduleimpl_inscription_list(
|
||||||
context, moduleimpl_id=E["moduleimpl_id"]
|
context, moduleimpl_id=E["moduleimpl_id"]
|
||||||
)
|
)
|
||||||
@ -676,7 +831,7 @@ def evaluation_date_first_completion(context, evaluation_id):
|
|||||||
# E = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
# E = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
||||||
# M = sco_moduleimpl.do_moduleimpl_list(context,moduleimpl_id=E["moduleimpl_id"])[0]
|
# M = sco_moduleimpl.do_moduleimpl_list(context,moduleimpl_id=E["moduleimpl_id"])[0]
|
||||||
# formsemestre_id = M["formsemestre_id"]
|
# formsemestre_id = M["formsemestre_id"]
|
||||||
# insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
|
# insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(context, formsemestre_id)
|
||||||
# insmod = sco_moduleimpl.do_moduleimpl_inscription_list(context,moduleimpl_id=E["moduleimpl_id"])
|
# insmod = sco_moduleimpl.do_moduleimpl_inscription_list(context,moduleimpl_id=E["moduleimpl_id"])
|
||||||
# insmodset = set([x["etudid"] for x in insmod])
|
# insmodset = set([x["etudid"] for x in insmod])
|
||||||
# retire de insem ceux qui ne sont pas inscrits au module
|
# retire de insem ceux qui ne sont pas inscrits au module
|
||||||
@ -814,9 +969,14 @@ def module_evaluation_move(context, evaluation_id, after=0, REQUEST=None, redire
|
|||||||
"""
|
"""
|
||||||
e = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
e = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
||||||
redirect = int(redirect)
|
redirect = int(redirect)
|
||||||
|
# access: can change eval ?
|
||||||
# access: can change eval ? (raises exception)
|
if not sco_permissions_check.can_edit_evaluation(
|
||||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=e["moduleimpl_id"])
|
context, REQUEST, moduleimpl_id=e["moduleimpl_id"]
|
||||||
|
):
|
||||||
|
raise AccessDenied(
|
||||||
|
"Modification évaluation impossible pour %s"
|
||||||
|
% scu.get_current_user_name(REQUEST)
|
||||||
|
)
|
||||||
|
|
||||||
module_evaluation_renumber(
|
module_evaluation_renumber(
|
||||||
context, e["moduleimpl_id"], REQUEST=REQUEST, only_if_unumbered=True
|
context, e["moduleimpl_id"], REQUEST=REQUEST, only_if_unumbered=True
|
||||||
@ -977,13 +1137,14 @@ def evaluation_create_form(
|
|||||||
formsemestre_id = M["formsemestre_id"]
|
formsemestre_id = M["formsemestre_id"]
|
||||||
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
||||||
if not readonly:
|
if not readonly:
|
||||||
try:
|
if not sco_permissions_check.can_edit_evaluation(
|
||||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
context, REQUEST, moduleimpl_id=moduleimpl_id
|
||||||
except AccessDenied as e:
|
):
|
||||||
return (
|
return (
|
||||||
html_sco_header.sco_header(context, REQUEST)
|
html_sco_header.sco_header(context, REQUEST)
|
||||||
+ "<h2>Opération non autorisée</h2><p>"
|
+ "<h2>Opération non autorisée</h2><p>"
|
||||||
+ str(e)
|
+ "Modification évaluation impossible pour %s"
|
||||||
|
% scu.get_current_user_name(REQUEST)
|
||||||
+ "</p>"
|
+ "</p>"
|
||||||
+ '<p><a href="%s">Revenir</a></p>' % (str(REQUEST.HTTP_REFERER),)
|
+ '<p><a href="%s">Revenir</a></p>' % (str(REQUEST.HTTP_REFERER),)
|
||||||
+ html_sco_header.sco_footer(context, REQUEST)
|
+ html_sco_header.sco_footer(context, REQUEST)
|
||||||
@ -1227,7 +1388,7 @@ def evaluation_create_form(
|
|||||||
tf[2]["visibulletin"] = 0
|
tf[2]["visibulletin"] = 0
|
||||||
if not edit:
|
if not edit:
|
||||||
# creation d'une evaluation
|
# creation d'une evaluation
|
||||||
evaluation_id = context.do_evaluation_create(REQUEST=REQUEST, **tf[2])
|
evaluation_id = do_evaluation_create(context, REQUEST=REQUEST, **tf[2])
|
||||||
return REQUEST.RESPONSE.redirect(dest_url)
|
return REQUEST.RESPONSE.redirect(dest_url)
|
||||||
else:
|
else:
|
||||||
do_evaluation_edit(context, REQUEST, tf[2])
|
do_evaluation_edit(context, REQUEST, tf[2])
|
||||||
|
@ -38,6 +38,7 @@ from app.scodoc import notesdb
|
|||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc.scolog import logdb
|
from app.scodoc.scolog import logdb
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
|
|
||||||
# colors, voir exemple format.py
|
# colors, voir exemple format.py
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"""Recherche d'étudiants
|
"""Recherche d'étudiants
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from scodoc_manager import sco_mgr
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
@ -266,12 +267,6 @@ def form_search_etud_in_accessible_depts(context, REQUEST):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def can_view_dept(context, REQUEST):
|
|
||||||
"""True if auth user can access (View) this context"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
return authuser.has_permission(Permission.ScoView)
|
|
||||||
|
|
||||||
|
|
||||||
def search_etud_in_accessible_depts(context, expnom=None, code_nip=None, REQUEST=None):
|
def search_etud_in_accessible_depts(context, expnom=None, code_nip=None, REQUEST=None):
|
||||||
"""
|
"""
|
||||||
context est le ZScoDoc
|
context est le ZScoDoc
|
||||||
@ -279,10 +274,10 @@ def search_etud_in_accessible_depts(context, expnom=None, code_nip=None, REQUEST
|
|||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
accessible_depts = []
|
accessible_depts = []
|
||||||
deptList = context._list_depts() # definis dans Zope
|
dept_list = sco_mgr.get_dept_ids()
|
||||||
for dept in deptList:
|
for dept in dept_list:
|
||||||
# log('%s searching %s' % (str(REQUEST.AUTHENTICATED_USER),dept))
|
# log('%s searching %s' % (str(REQUEST.AUTHENTICATED_USER),dept))
|
||||||
if can_view_dept(dept, REQUEST):
|
if REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoView, dept=dept):
|
||||||
if expnom or code_nip:
|
if expnom or code_nip:
|
||||||
accessible_depts.append(dept.Scolarite.DeptId())
|
accessible_depts.append(dept.Scolarite.DeptId())
|
||||||
etuds = search_etuds_infos(
|
etuds = search_etuds_infos(
|
||||||
|
@ -35,16 +35,17 @@ import app.scodoc.sco_utils as scu
|
|||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_tag_module
|
|
||||||
from app.scodoc import sco_preferences
|
|
||||||
from app.scodoc.gen_tables import GenTable
|
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
|
||||||
from app.scodoc.sco_permissions import Permission
|
|
||||||
from app.scodoc import VERSION
|
|
||||||
from app.scodoc import sco_edit_matiere
|
from app.scodoc import sco_edit_matiere
|
||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
from app.scodoc import sco_news
|
||||||
|
from app.scodoc import sco_preferences
|
||||||
|
from app.scodoc import sco_tag_module
|
||||||
|
from app.scodoc import VERSION
|
||||||
|
from app.scodoc.gen_tables import GenTable
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
_formationEditor = ndb.EditableTable(
|
_formationEditor = ndb.EditableTable(
|
||||||
"notes_formations",
|
"notes_formations",
|
||||||
@ -164,6 +165,8 @@ def formation_import_xml(
|
|||||||
"""Create a formation from XML representation
|
"""Create a formation from XML representation
|
||||||
(format dumped by formation_export( format='xml' ))
|
(format dumped by formation_export( format='xml' ))
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_edit_formation
|
||||||
|
|
||||||
log("formation_import_xml: doc=%s" % doc)
|
log("formation_import_xml: doc=%s" % doc)
|
||||||
try:
|
try:
|
||||||
dom = xml.dom.minidom.parseString(doc)
|
dom = xml.dom.minidom.parseString(doc)
|
||||||
@ -199,7 +202,7 @@ def formation_import_xml(
|
|||||||
# create formation
|
# create formation
|
||||||
# F_unquoted = F.copy()
|
# F_unquoted = F.copy()
|
||||||
# unescape_html_dict(F_unquoted)
|
# unescape_html_dict(F_unquoted)
|
||||||
formation_id = context.do_formation_create(F, REQUEST)
|
formation_id = sco_edit_formation.do_formation_create(context, F, REQUEST)
|
||||||
log("formation %s created" % formation_id)
|
log("formation %s created" % formation_id)
|
||||||
ues_old2new = {} # xml ue_id : new ue_id
|
ues_old2new = {} # xml ue_id : new ue_id
|
||||||
modules_old2new = {} # xml module_id : new module_id
|
modules_old2new = {} # xml module_id : new module_id
|
||||||
@ -362,3 +365,24 @@ def formation_list_table(context, formation_id=None, args={}, REQUEST=None):
|
|||||||
context,
|
context,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def formation_create_new_version(context, formation_id, redirect=True, REQUEST=None):
|
||||||
|
"duplicate formation, with new version number"
|
||||||
|
xml = formation_export(context, formation_id, export_ids=True, format="xml")
|
||||||
|
new_id, modules_old2new, ues_old2new = formation_import_xml(context, REQUEST, xml)
|
||||||
|
# news
|
||||||
|
F = formation_list(context, args={"formation_id": new_id})[0]
|
||||||
|
sco_news.add(
|
||||||
|
context,
|
||||||
|
REQUEST,
|
||||||
|
typ=sco_news.NEWS_FORM,
|
||||||
|
object=new_id,
|
||||||
|
text="Nouvelle version de la formation %(acronyme)s" % F,
|
||||||
|
)
|
||||||
|
if redirect:
|
||||||
|
return REQUEST.RESPONSE.redirect(
|
||||||
|
"ue_list?formation_id=" + new_id + "&msg=Nouvelle version !"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return new_id, modules_old2new, ues_old2new
|
@ -29,16 +29,16 @@
|
|||||||
"""
|
"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
from scodoc_manager import sco_mgr
|
||||||
import app.scodoc.notesdb as ndb
|
|
||||||
from app.scodoc.notes_log import log
|
|
||||||
from app.scodoc.gen_tables import GenTable
|
|
||||||
|
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
|
|
||||||
from app.scodoc import sco_core
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
from app.scodoc.gen_tables import GenTable
|
||||||
|
from app.scodoc.notes_log import log
|
||||||
|
from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
import app.scodoc.notesdb as ndb
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
_formsemestreEditor = ndb.EditableTable(
|
_formsemestreEditor = ndb.EditableTable(
|
||||||
"notes_formsemestre",
|
"notes_formsemestre",
|
||||||
@ -219,6 +219,41 @@ def etapes_apo_str(etapes):
|
|||||||
return ", ".join([str(x) for x in etapes])
|
return ", ".join([str(x) for x in etapes])
|
||||||
|
|
||||||
|
|
||||||
|
def do_formsemestre_create(context, args, REQUEST, silent=False):
|
||||||
|
"create a formsemestre"
|
||||||
|
cnx = ndb.GetDBConnexion()
|
||||||
|
formsemestre_id = _formsemestreEditor.create(cnx, args)
|
||||||
|
if args["etapes"]:
|
||||||
|
args["formsemestre_id"] = formsemestre_id
|
||||||
|
write_formsemestre_etapes(context, args)
|
||||||
|
if args["responsables"]:
|
||||||
|
args["formsemestre_id"] = formsemestre_id
|
||||||
|
write_formsemestre_responsables(context, args)
|
||||||
|
|
||||||
|
# create default partition
|
||||||
|
partition_id = sco_groups.partition_create(
|
||||||
|
context, formsemestre_id, default=True, redirect=0, REQUEST=REQUEST
|
||||||
|
)
|
||||||
|
_group_id = sco_groups.createGroup(
|
||||||
|
context, partition_id, default=True, REQUEST=REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
|
# news
|
||||||
|
if not args.has_key("titre"):
|
||||||
|
args["titre"] = "sans titre"
|
||||||
|
args["formsemestre_id"] = formsemestre_id
|
||||||
|
args["url"] = "Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s" % args
|
||||||
|
if not silent:
|
||||||
|
sco_news.add(
|
||||||
|
context,
|
||||||
|
REQUEST,
|
||||||
|
typ=sco_news.NEWS_SEM,
|
||||||
|
text='Création du semestre <a href="%(url)s">%(titre)s</a>' % args,
|
||||||
|
url=args["url"],
|
||||||
|
)
|
||||||
|
return formsemestre_id
|
||||||
|
|
||||||
|
|
||||||
def do_formsemestre_edit(context, sem, cnx=None, **kw):
|
def do_formsemestre_edit(context, sem, cnx=None, **kw):
|
||||||
"""Apply modifications to formsemestre.
|
"""Apply modifications to formsemestre.
|
||||||
Update etapes and resps. Invalidate cache."""
|
Update etapes and resps. Invalidate cache."""
|
||||||
@ -500,7 +535,7 @@ def sem_est_courant(context, sem):
|
|||||||
|
|
||||||
def scodoc_get_all_unlocked_sems(context):
|
def scodoc_get_all_unlocked_sems(context):
|
||||||
"""Liste de tous les semestres non verrouillés de tous les départements"""
|
"""Liste de tous les semestres non verrouillés de tous les départements"""
|
||||||
depts = context._list_depts()
|
depts = sco_mgr.get_dept_ids()
|
||||||
semdepts = []
|
semdepts = []
|
||||||
for dept in depts:
|
for dept in depts:
|
||||||
semdepts += [
|
semdepts += [
|
||||||
|
@ -715,7 +715,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
|
|||||||
)
|
)
|
||||||
if not edit:
|
if not edit:
|
||||||
# creation du semestre
|
# creation du semestre
|
||||||
formsemestre_id = context.do_formsemestre_create(tf[2], REQUEST)
|
formsemestre_id = sco_formsemestre.do_formsemestre_create(
|
||||||
|
context, tf[2], REQUEST
|
||||||
|
)
|
||||||
# creation des modules
|
# creation des modules
|
||||||
for module_id in tf[2]["tf-checked"]:
|
for module_id in tf[2]["tf-checked"]:
|
||||||
modargs = {
|
modargs = {
|
||||||
@ -1014,7 +1016,7 @@ def do_formsemestre_clone(
|
|||||||
args["date_debut"] = date_debut
|
args["date_debut"] = date_debut
|
||||||
args["date_fin"] = date_fin
|
args["date_fin"] = date_fin
|
||||||
args["etat"] = 1 # non verrouillé
|
args["etat"] = 1 # non verrouillé
|
||||||
formsemestre_id = context.do_formsemestre_create(args, REQUEST)
|
formsemestre_id = sco_formsemestre.do_formsemestre_create(context, args, REQUEST)
|
||||||
log("created formsemestre %s" % formsemestre_id)
|
log("created formsemestre %s" % formsemestre_id)
|
||||||
# 2- create moduleimpls
|
# 2- create moduleimpls
|
||||||
mods_orig = sco_moduleimpl.do_moduleimpl_list(
|
mods_orig = sco_moduleimpl.do_moduleimpl_list(
|
||||||
@ -1041,7 +1043,7 @@ def do_formsemestre_clone(
|
|||||||
args = e.copy()
|
args = e.copy()
|
||||||
del args["jour"] # erase date
|
del args["jour"] # erase date
|
||||||
args["moduleimpl_id"] = mid
|
args["moduleimpl_id"] = mid
|
||||||
_ = context.do_evaluation_create(REQUEST=REQUEST, **args)
|
_ = sco_evaluations.do_evaluation_create(context, REQUEST=REQUEST, **args)
|
||||||
|
|
||||||
# 3- copy uecoefs
|
# 3- copy uecoefs
|
||||||
objs = sco_formsemestre.formsemestre_uecoef_list(
|
objs = sco_formsemestre.formsemestre_uecoef_list(
|
||||||
@ -1196,14 +1198,18 @@ def do_formsemestres_associate_new_version(context, formsemestre_ids, REQUEST=No
|
|||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# New formation:
|
# New formation:
|
||||||
formation_id, modules_old2new, ues_old2new = context.formation_create_new_version(
|
(
|
||||||
formation_id, redirect=False, REQUEST=REQUEST
|
formation_id,
|
||||||
|
modules_old2new,
|
||||||
|
ues_old2new,
|
||||||
|
) = sco_formations.formation_create_new_version(
|
||||||
|
context, formation_id, redirect=False, REQUEST=REQUEST
|
||||||
)
|
)
|
||||||
|
|
||||||
for formsemestre_id in formsemestre_ids:
|
for formsemestre_id in formsemestre_ids:
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
sem["formation_id"] = formation_id
|
sem["formation_id"] = formation_id
|
||||||
context.do_formsemestre_edit(sem, cnx=cnx, html_quote=False)
|
sco_formsemestre.do_formsemestre_edit(context, sem, cnx=cnx, html_quote=False)
|
||||||
_reassociate_moduleimpls(
|
_reassociate_moduleimpls(
|
||||||
context, cnx, formsemestre_id, ues_old2new, modules_old2new
|
context, cnx, formsemestre_id, ues_old2new, modules_old2new
|
||||||
)
|
)
|
||||||
@ -1339,7 +1345,7 @@ def do_formsemestre_delete(context, formsemestre_id, REQUEST):
|
|||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
|
|
||||||
# --- Destruction des modules de ce semestre
|
# --- Destruction des modules de ce semestre
|
||||||
mods = context.do_moduleimpl_list(formsemestre_id=formsemestre_id)
|
mods = sco_moduleimpl.do_moduleimpl_list(formsemestre_id=formsemestre_id)
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
# evaluations
|
# evaluations
|
||||||
evals = sco_evaluations.do_evaluation_list(
|
evals = sco_evaluations.do_evaluation_list(
|
||||||
@ -1474,7 +1480,7 @@ def formsemestre_change_lock(
|
|||||||
if etat not in (0, 1):
|
if etat not in (0, 1):
|
||||||
raise ScoValueError("formsemestre_lock: invalid value for etat (%s)" % etat)
|
raise ScoValueError("formsemestre_lock: invalid value for etat (%s)" % etat)
|
||||||
args = {"formsemestre_id": formsemestre_id, "etat": etat}
|
args = {"formsemestre_id": formsemestre_id, "etat": etat}
|
||||||
context.do_formsemestre_edit(args)
|
sco_formsemestre.do_formsemestre_edit(context, args)
|
||||||
if REQUEST:
|
if REQUEST:
|
||||||
return REQUEST.RESPONSE.redirect(
|
return REQUEST.RESPONSE.redirect(
|
||||||
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
||||||
@ -1517,7 +1523,7 @@ def formsemestre_change_publication_bul(
|
|||||||
"formsemestre_change_publication_bul: invalid value for etat (%s)" % etat
|
"formsemestre_change_publication_bul: invalid value for etat (%s)" % etat
|
||||||
)
|
)
|
||||||
args = {"formsemestre_id": formsemestre_id, "bul_hide_xml": etat}
|
args = {"formsemestre_id": formsemestre_id, "bul_hide_xml": etat}
|
||||||
context.do_formsemestre_edit(args)
|
sco_formsemestre.do_formsemestre_edit(context, args)
|
||||||
if REQUEST:
|
if REQUEST:
|
||||||
return REQUEST.RESPONSE.redirect(
|
return REQUEST.RESPONSE.redirect(
|
||||||
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
||||||
|
@ -63,7 +63,9 @@ def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
|
|||||||
sem_params["modalite"] = "EXT"
|
sem_params["modalite"] = "EXT"
|
||||||
sem_params["etapes"] = None
|
sem_params["etapes"] = None
|
||||||
sem_params["responsables"] = [str(REQUEST.AUTHENTICATED_USER)]
|
sem_params["responsables"] = [str(REQUEST.AUTHENTICATED_USER)]
|
||||||
formsemestre_id = context.do_formsemestre_create(sem_params, REQUEST, silent=True)
|
formsemestre_id = sco_formsemestre.do_formsemestre_create(
|
||||||
|
context, sem_params, REQUEST, silent=True
|
||||||
|
)
|
||||||
# nota: le semestre est créé vide: pas de modules
|
# nota: le semestre est créé vide: pas de modules
|
||||||
|
|
||||||
# Inscription au semestre
|
# Inscription au semestre
|
||||||
|
@ -43,7 +43,6 @@ from app.scodoc import sco_moduleimpl
|
|||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_core
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_formsemestre_edit
|
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
|
|
||||||
@ -62,6 +61,19 @@ def do_formsemestre_inscription_list(context, *args, **kw):
|
|||||||
return _formsemestre_inscriptionEditor.list(cnx, *args, **kw)
|
return _formsemestre_inscriptionEditor.list(cnx, *args, **kw)
|
||||||
|
|
||||||
|
|
||||||
|
def do_formsemestre_inscription_listinscrits(context, formsemestre_id):
|
||||||
|
"""Liste les inscrits (état I) à ce semestre et cache le résultat"""
|
||||||
|
cache = sco_core.get_formsemestre_inscription_cache(context)
|
||||||
|
r = cache.get(formsemestre_id)
|
||||||
|
if r is None:
|
||||||
|
# retreive list
|
||||||
|
r = do_formsemestre_inscription_list(
|
||||||
|
context, args={"formsemestre_id": formsemestre_id, "etat": "I"}
|
||||||
|
)
|
||||||
|
cache.set(formsemestre_id, r)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
|
def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
|
||||||
"create a formsemestre_inscription (and sco event)"
|
"create a formsemestre_inscription (and sco event)"
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
@ -126,6 +138,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
|
|||||||
"""Désinscription d'un étudiant.
|
"""Désinscription d'un étudiant.
|
||||||
Si semestre extérieur et dernier inscrit, suppression de ce semestre.
|
Si semestre extérieur et dernier inscrit, suppression de ce semestre.
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre_edit
|
||||||
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
# -- check lock
|
# -- check lock
|
||||||
if sem["etat"] != "1":
|
if sem["etat"] != "1":
|
||||||
|
@ -346,7 +346,9 @@ def formsemestre_status_menubar(context, sem, REQUEST):
|
|||||||
"title": "Créer/modifier les partitions...",
|
"title": "Créer/modifier les partitions...",
|
||||||
"endpoint": "scolar.editPartitionForm",
|
"endpoint": "scolar.editPartitionForm",
|
||||||
"args": {"formsemestre_id": formsemestre_id},
|
"args": {"formsemestre_id": formsemestre_id},
|
||||||
"enabled": sco_groups.can_change_groups(context, REQUEST, formsemestre_id),
|
"enabled": sco_groups.sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
# 1 item / partition:
|
# 1 item / partition:
|
||||||
@ -355,7 +357,10 @@ def formsemestre_status_menubar(context, sem, REQUEST):
|
|||||||
)
|
)
|
||||||
submenu = []
|
submenu = []
|
||||||
enabled = (
|
enabled = (
|
||||||
sco_groups.can_change_groups(context, REQUEST, formsemestre_id) and partitions
|
sco_groups.sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
)
|
||||||
|
and partitions
|
||||||
)
|
)
|
||||||
for partition in partitions:
|
for partition in partitions:
|
||||||
submenu.append(
|
submenu.append(
|
||||||
@ -873,13 +878,17 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
|
|||||||
H.append("</table>")
|
H.append("</table>")
|
||||||
else:
|
else:
|
||||||
H.append('<p class="help indent">Aucun groupe dans cette partition')
|
H.append('<p class="help indent">Aucun groupe dans cette partition')
|
||||||
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
|
if sco_groups.sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
):
|
||||||
H.append(
|
H.append(
|
||||||
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
|
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
|
||||||
% partition["partition_id"]
|
% partition["partition_id"]
|
||||||
)
|
)
|
||||||
H.append("</p>")
|
H.append("</p>")
|
||||||
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
|
if sco_groups.sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
):
|
||||||
H.append(
|
H.append(
|
||||||
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
|
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
|
||||||
% formsemestre_id
|
% formsemestre_id
|
||||||
|
@ -51,26 +51,12 @@ from app.scodoc import html_sco_header
|
|||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc import sco_core
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_permissions_check
|
||||||
from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError
|
from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
|
||||||
|
|
||||||
def can_change_groups(context, REQUEST, formsemestre_id):
|
|
||||||
"Vrai si l'utilisateur peut changer les groupes dans ce semestre"
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
|
||||||
if sem["etat"] != "1":
|
|
||||||
return False # semestre verrouillé
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
if authuser.has_permission(Permission.ScoEtudChangeGroups):
|
|
||||||
return True # admin, chef dept
|
|
||||||
uid = str(authuser)
|
|
||||||
if uid in sem["responsables"]:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def checkGroupName(
|
def checkGroupName(
|
||||||
groupName,
|
groupName,
|
||||||
): # XXX unused: now allow any string as a group or partition name
|
): # XXX unused: now allow any string as a group or partition name
|
||||||
@ -275,6 +261,8 @@ def get_group_members(context, group_id, etat=None):
|
|||||||
|
|
||||||
def get_group_infos(context, group_id, etat=None): # was _getlisteetud
|
def get_group_infos(context, group_id, etat=None): # was _getlisteetud
|
||||||
"""legacy code: used by group_list and trombino"""
|
"""legacy code: used by group_list and trombino"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
group = get_group(context, group_id)
|
group = get_group(context, group_id)
|
||||||
sem = sco_formsemestre.get_formsemestre(context, group["formsemestre_id"])
|
sem = sco_formsemestre.get_formsemestre(context, group["formsemestre_id"])
|
||||||
@ -446,12 +434,14 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
|
|||||||
<etud etuid="" sexe="" nom="" prenom="" origin=""/>
|
<etud etuid="" sexe="" nom="" prenom="" origin=""/>
|
||||||
</groupe>
|
</groupe>
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
groups = get_partition_groups(context, partition)
|
groups = get_partition_groups(context, partition)
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
) # > inscrdict
|
) # > inscrdict
|
||||||
etuds_set = set(nt.inscrdict)
|
etuds_set = set(nt.inscrdict)
|
||||||
@ -621,9 +611,11 @@ def setGroups(
|
|||||||
groupsToCreate: lignes "group_name;etudid;...\n"
|
groupsToCreate: lignes "group_name;etudid;...\n"
|
||||||
groupsToDelete: group_id;group_id;...
|
groupsToDelete: group_id;group_id;...
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
log("***setGroups: partition_id=%s" % partition_id)
|
log("***setGroups: partition_id=%s" % partition_id)
|
||||||
log("groupsLists=%s" % groupsLists)
|
log("groupsLists=%s" % groupsLists)
|
||||||
@ -710,7 +702,9 @@ def createGroup(context, partition_id, group_name="", default=False, REQUEST=Non
|
|||||||
"""
|
"""
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if REQUEST and not can_change_groups(context, REQUEST, formsemestre_id):
|
if REQUEST and not sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
#
|
#
|
||||||
if group_name:
|
if group_name:
|
||||||
@ -747,7 +741,9 @@ def suppressGroup(context, group_id, partition_id=None, REQUEST=None):
|
|||||||
else:
|
else:
|
||||||
partition_id = group["partition_id"]
|
partition_id = group["partition_id"]
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
if not can_change_groups(context, REQUEST, partition["formsemestre_id"]):
|
if not sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, partition["formsemestre_id"]
|
||||||
|
):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
log(
|
log(
|
||||||
"suppressGroup: group_id=%s group_name=%s partition_name=%s"
|
"suppressGroup: group_id=%s group_name=%s partition_name=%s"
|
||||||
@ -766,7 +762,9 @@ def partition_create(
|
|||||||
redirect=1,
|
redirect=1,
|
||||||
):
|
):
|
||||||
"""Create a new partition"""
|
"""Create a new partition"""
|
||||||
if REQUEST and not can_change_groups(context, REQUEST, formsemestre_id):
|
if REQUEST and not sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
if partition_name:
|
if partition_name:
|
||||||
partition_name = partition_name.strip()
|
partition_name = partition_name.strip()
|
||||||
@ -810,7 +808,7 @@ def getArrowIconsTags(context, REQUEST):
|
|||||||
def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
|
def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
|
||||||
"""Form to create/suppress partitions"""
|
"""Form to create/suppress partitions"""
|
||||||
# ad-hoc form
|
# ad-hoc form
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
partitions = get_partitions_list(context, formsemestre_id)
|
partitions = get_partitions_list(context, formsemestre_id)
|
||||||
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
|
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
|
||||||
@ -940,7 +938,7 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
|
|||||||
|
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
|
|
||||||
log("partition_set_attr(%s, %s, %s)" % (partition_id, attr, value))
|
log("partition_set_attr(%s, %s, %s)" % (partition_id, attr, value))
|
||||||
@ -963,7 +961,7 @@ def partition_delete(
|
|||||||
default partition cannot be suppressed (unless force)"""
|
default partition cannot be suppressed (unless force)"""
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
|
|
||||||
if not partition["partition_name"] and not force:
|
if not partition["partition_name"] and not force:
|
||||||
@ -1007,7 +1005,7 @@ def partition_move(context, partition_id, after=0, REQUEST=None, redirect=1):
|
|||||||
"""Move before/after previous one (decrement/increment numero)"""
|
"""Move before/after previous one (decrement/increment numero)"""
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
#
|
#
|
||||||
redirect = int(redirect)
|
redirect = int(redirect)
|
||||||
@ -1042,7 +1040,7 @@ def partition_rename(context, partition_id, REQUEST=None):
|
|||||||
"""Form to rename a partition"""
|
"""Form to rename a partition"""
|
||||||
partition = get_partition(context, partition_id)
|
partition = get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
H = ["<h2>Renommer une partition</h2>"]
|
H = ["<h2>Renommer une partition</h2>"]
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
@ -1103,7 +1101,7 @@ def partition_set_name(context, partition_id, partition_name, REQUEST=None, redi
|
|||||||
"Partition %s déjà existante dans ce semestre !" % partition_name
|
"Partition %s déjà existante dans ce semestre !" % partition_name
|
||||||
)
|
)
|
||||||
|
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
redirect = int(redirect)
|
redirect = int(redirect)
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
@ -1128,7 +1126,7 @@ def group_set_name(context, group_id, group_name, REQUEST=None, redirect=1):
|
|||||||
if group["group_name"] is None:
|
if group["group_name"] is None:
|
||||||
raise ValueError("can't set a name to default group")
|
raise ValueError("can't set a name to default group")
|
||||||
formsemestre_id = group["formsemestre_id"]
|
formsemestre_id = group["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
redirect = int(redirect)
|
redirect = int(redirect)
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
@ -1145,7 +1143,7 @@ def group_rename(context, group_id, REQUEST=None):
|
|||||||
"""Form to rename a group"""
|
"""Form to rename a group"""
|
||||||
group = get_group(context, group_id)
|
group = get_group(context, group_id)
|
||||||
formsemestre_id = group["formsemestre_id"]
|
formsemestre_id = group["formsemestre_id"]
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]]
|
H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]]
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
@ -1193,7 +1191,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
|
|||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
# renvoie sur page édition groupes
|
# renvoie sur page édition groupes
|
||||||
dest_url = "affectGroups?partition_id=%s" % partition_id
|
dest_url = "affectGroups?partition_id=%s" % partition_id
|
||||||
if not can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_permissions_check.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
|
|
||||||
@ -1261,7 +1259,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
|
|||||||
createGroup(context, partition_id, group_name, REQUEST=REQUEST)
|
createGroup(context, partition_id, group_name, REQUEST=REQUEST)
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
) # > identdict
|
) # > identdict
|
||||||
identdict = nt.identdict
|
identdict = nt.identdict
|
||||||
|
@ -40,7 +40,9 @@ def affectGroups(context, partition_id, REQUEST=None):
|
|||||||
# Ported from DTML and adapted to new group management (nov 2009)
|
# Ported from DTML and adapted to new group management (nov 2009)
|
||||||
partition = sco_groups.get_partition(context, partition_id)
|
partition = sco_groups.get_partition(context, partition_id)
|
||||||
formsemestre_id = partition["formsemestre_id"]
|
formsemestre_id = partition["formsemestre_id"]
|
||||||
if not sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
|
if not sco_groups.sco_permissions_check.can_change_groups(
|
||||||
|
context, REQUEST, formsemestre_id
|
||||||
|
):
|
||||||
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
|
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
@ -53,6 +53,7 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoGenError,
|
ScoGenError,
|
||||||
)
|
)
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
@ -31,7 +31,7 @@ from email.mime.multipart import MIMEMultipart
|
|||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
|
|
||||||
from app.scodoc import mails
|
from app.scodoc import sco_emails
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoException
|
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoException
|
||||||
@ -228,4 +228,4 @@ Pour plus d'informations sur ce logiciel, voir %s
|
|||||||
msg.epilogue = ""
|
msg.epilogue = ""
|
||||||
txt = MIMEText(txt, "plain", scu.SCO_ENCODING)
|
txt = MIMEText(txt, "plain", scu.SCO_ENCODING)
|
||||||
msg.attach(txt)
|
msg.attach(txt)
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
|
@ -107,8 +107,8 @@ def list_inscrits(context, formsemestre_id, with_dems=False):
|
|||||||
{ etudid : etud }
|
{ etudid : etud }
|
||||||
"""
|
"""
|
||||||
if not with_dems:
|
if not with_dems:
|
||||||
ins = context.Notes.do_formsemestre_inscription_listinscrits(
|
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||||
formsemestre_id
|
context, formsemestre_id
|
||||||
) # optimized
|
) # optimized
|
||||||
else:
|
else:
|
||||||
args = {"formsemestre_id": formsemestre_id}
|
args = {"formsemestre_id": formsemestre_id}
|
||||||
@ -215,8 +215,8 @@ def do_inscrit(context, sem, etudids, REQUEST=None, inscrit_groupes=False):
|
|||||||
def do_desinscrit(context, sem, etudids, REQUEST):
|
def do_desinscrit(context, sem, etudids, REQUEST):
|
||||||
log("do_desinscrit: %s" % etudids)
|
log("do_desinscrit: %s" % etudids)
|
||||||
for etudid in etudids:
|
for etudid in etudids:
|
||||||
context.do_formsemestre_desinscription(
|
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
|
||||||
etudid, sem["formsemestre_id"], REQUEST=REQUEST
|
context, etudid, sem["formsemestre_id"], REQUEST=REQUEST
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,9 @@ def moduleimpl_inscriptions_edit(
|
|||||||
% (moduleimpl_id, mod["titre"], mod["code"]),
|
% (moduleimpl_id, mod["titre"], mod["code"]),
|
||||||
]
|
]
|
||||||
# Liste des inscrits à ce semestre
|
# Liste des inscrits à ce semestre
|
||||||
inscrits = context.Notes.do_formsemestre_inscription_listinscrits(formsemestre_id)
|
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||||
|
context, formsemestre_id
|
||||||
|
)
|
||||||
for ins in inscrits:
|
for ins in inscrits:
|
||||||
etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
|
etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
|
||||||
if not etuds_info:
|
if not etuds_info:
|
||||||
|
@ -40,7 +40,7 @@ import PyRSS2Gen # pylint: disable=import-error
|
|||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.notes_log import log
|
from app.scodoc.notes_log import log
|
||||||
from app.scodoc import mails
|
from app.scodoc import sco_emails
|
||||||
from app.scodoc.sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE
|
from app.scodoc.sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
@ -301,4 +301,4 @@ def _send_news_by_mail(context, n):
|
|||||||
del msg["To"]
|
del msg["To"]
|
||||||
msg["To"] = email_addr
|
msg["To"] = email_addr
|
||||||
# log('xxx mail: %s' % msg)
|
# log('xxx mail: %s' % msg)
|
||||||
mails.sendEmail(context, msg)
|
sco_emails.sendEmail(context, msg)
|
||||||
|
@ -70,18 +70,18 @@ def _menuScolarite(context, authuser, sem, etudid):
|
|||||||
|
|
||||||
if ins["etat"] != "D":
|
if ins["etat"] != "D":
|
||||||
dem_title = "Démission"
|
dem_title = "Démission"
|
||||||
dem_url = "formDem"
|
dem_url = "scolar.formDem"
|
||||||
else:
|
else:
|
||||||
dem_title = "Annuler la démission"
|
dem_title = "Annuler la démission"
|
||||||
dem_url = "doCancelDem"
|
dem_url = "scolar.doCancelDem"
|
||||||
|
|
||||||
# Note: seul un etudiant inscrit (I) peut devenir défaillant.
|
# Note: seul un etudiant inscrit (I) peut devenir défaillant.
|
||||||
if ins["etat"] != sco_codes_parcours.DEF:
|
if ins["etat"] != sco_codes_parcours.DEF:
|
||||||
def_title = "Déclarer défaillance"
|
def_title = "Déclarer défaillance"
|
||||||
def_url = "formDef"
|
def_url = "scolar.formDef"
|
||||||
elif ins["etat"] == sco_codes_parcours.DEF:
|
elif ins["etat"] == sco_codes_parcours.DEF:
|
||||||
def_title = "Annuler la défaillance"
|
def_title = "Annuler la défaillance"
|
||||||
def_url = "doCancelDef"
|
def_url = "scolar.doCancelDef"
|
||||||
def_enabled = (
|
def_enabled = (
|
||||||
(ins["etat"] != "D")
|
(ins["etat"] != "D")
|
||||||
and authuser.has_permission(Permission.ScoEtudInscrit)
|
and authuser.has_permission(Permission.ScoEtudInscrit)
|
||||||
|
@ -9,9 +9,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_exceptions
|
from app.scodoc import sco_exceptions
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_parcours_dut
|
|
||||||
|
|
||||||
|
|
||||||
def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
|
def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
|
||||||
@ -21,6 +19,9 @@ def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
|
|||||||
Si des décisions de jury ont déjà été saisies dans ce semestre,
|
Si des décisions de jury ont déjà été saisies dans ce semestre,
|
||||||
seul le directeur des études peut saisir des notes (et il ne devrait pas).
|
seul le directeur des études peut saisir des notes (et il ne devrait pas).
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
from app.scodoc import sco_parcours_dut
|
||||||
|
|
||||||
uid = str(authuser)
|
uid = str(authuser)
|
||||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||||
@ -49,6 +50,39 @@ def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def can_edit_evaluation(context, REQUEST, moduleimpl_id=None):
|
||||||
|
"""Vérifie que l'on a le droit de modifier, créer ou détruire une
|
||||||
|
évaluation dans ce module.
|
||||||
|
Sinon, lance une exception.
|
||||||
|
(nb: n'implique pas le droit de saisir ou modifier des notes)
|
||||||
|
"""
|
||||||
|
# was _evaluation_check_write_access
|
||||||
|
# AccessDenied("Modification évaluation impossible pour %s" % (uid,))
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
from app.scodoc import sco_moduleimpl
|
||||||
|
|
||||||
|
# acces pour resp. moduleimpl et resp. form semestre (dir etud)
|
||||||
|
if moduleimpl_id is None:
|
||||||
|
raise ValueError("no moduleimpl specified") # bug
|
||||||
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
uid = str(authuser)
|
||||||
|
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||||
|
|
||||||
|
if (
|
||||||
|
authuser.has_permission(Permission.ScoEditAllEvals)
|
||||||
|
or uid == M["responsable_id"]
|
||||||
|
or uid in sem["responsables"]
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
elif sem["ens_can_edit_eval"]:
|
||||||
|
for ens in M["ens"]:
|
||||||
|
if ens["ens_id"] == uid:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def can_suppress_annotation(context, annotation_id, REQUEST):
|
def can_suppress_annotation(context, annotation_id, REQUEST):
|
||||||
"""True if current user can suppress this annotation
|
"""True if current user can suppress this annotation
|
||||||
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
|
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
|
||||||
@ -60,13 +94,9 @@ def can_suppress_annotation(context, annotation_id, REQUEST):
|
|||||||
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
||||||
anno = annos[0]
|
anno = annos[0]
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
# note: les anciennes installations n'ont pas le role ScoEtudSupprAnnotations
|
|
||||||
# c'est pourquoi on teste aussi ScoEtudInscrit (normalement détenue par le chef)
|
|
||||||
return (
|
return (
|
||||||
(str(authuser) == anno["zope_authenticated_user"])
|
str(authuser) == anno["zope_authenticated_user"]
|
||||||
or authuser.has_permission(Permission.ScoEtudSupprAnnotations)
|
) or authuser.has_permission(Permission.ScoEtudAddAnnotations)
|
||||||
or authuser.has_permission(Permission.ScoEtudInscrit)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def can_edit_suivi(context, REQUEST=None):
|
def can_edit_suivi(context, REQUEST=None):
|
||||||
@ -77,6 +107,8 @@ def can_edit_suivi(context, REQUEST=None):
|
|||||||
|
|
||||||
def can_validate_sem(context, REQUEST, formsemestre_id):
|
def can_validate_sem(context, REQUEST, formsemestre_id):
|
||||||
"Vrai si utilisateur peut saisir decision de jury dans ce semestre"
|
"Vrai si utilisateur peut saisir decision de jury dans ce semestre"
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
if sem["etat"] != "1":
|
if sem["etat"] != "1":
|
||||||
return False # semestre verrouillé
|
return False # semestre verrouillé
|
||||||
@ -86,6 +118,7 @@ def can_validate_sem(context, REQUEST, formsemestre_id):
|
|||||||
|
|
||||||
def can_edit_pv(context, REQUEST, formsemestre_id):
|
def can_edit_pv(context, REQUEST, formsemestre_id):
|
||||||
"Vrai si utilisateur peut editer un PV de jury de ce semestre"
|
"Vrai si utilisateur peut editer un PV de jury de ce semestre"
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
if is_chef_or_diretud(context, REQUEST, sem):
|
if is_chef_or_diretud(context, REQUEST, sem):
|
||||||
@ -114,6 +147,8 @@ def check_access_diretud(
|
|||||||
"""Check if access granted: responsable or ScoImplement
|
"""Check if access granted: responsable or ScoImplement
|
||||||
Return True|False, HTML_error_page
|
Return True|False, HTML_error_page
|
||||||
"""
|
"""
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
header = html_sco_header.sco_header(
|
header = html_sco_header.sco_header(
|
||||||
@ -137,3 +172,19 @@ def check_access_diretud(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return True, ""
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
|
def can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
|
"Vrai si l'utilisateur peut changer les groupes dans ce semestre"
|
||||||
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
|
if sem["etat"] != "1":
|
||||||
|
return False # semestre verrouillé
|
||||||
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
if authuser.has_permission(Permission.ScoEtudChangeGroups):
|
||||||
|
return True # admin, chef dept
|
||||||
|
uid = str(authuser)
|
||||||
|
if uid in sem["responsables"]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
@ -46,6 +46,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import htmlutils
|
from app.scodoc import htmlutils
|
||||||
|
from app.scodoc import sco_abs
|
||||||
from app.scodoc import sco_core
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
|
@ -50,7 +50,7 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
from app.scodoc.sco_pdf import SU
|
from app.scodoc.sco_pdf import SU
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import htmlutils
|
from app.scodoc import htmlutils
|
||||||
from app.scodoc import ImportScolars
|
from app.scodoc import sco_import_etuds
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
@ -470,8 +470,8 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST):
|
|||||||
# --------------------- Upload des photos de tout un groupe
|
# --------------------- Upload des photos de tout un groupe
|
||||||
def photos_generate_excel_sample(context, group_ids=[], REQUEST=None):
|
def photos_generate_excel_sample(context, group_ids=[], REQUEST=None):
|
||||||
"""Feuille excel pour import fichiers photos"""
|
"""Feuille excel pour import fichiers photos"""
|
||||||
fmt = ImportScolars.sco_import_format()
|
fmt = sco_import_etuds.sco_import_format()
|
||||||
data = ImportScolars.sco_import_generate_excel_sample(
|
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||||
fmt,
|
fmt,
|
||||||
context=context,
|
context=context,
|
||||||
group_ids=group_ids,
|
group_ids=group_ids,
|
||||||
|
@ -164,7 +164,7 @@ def external_ue_inscrit_et_note(
|
|||||||
evaluation_id = ModEvals[0]["evaluation_id"]
|
evaluation_id = ModEvals[0]["evaluation_id"]
|
||||||
else:
|
else:
|
||||||
# crée une évaluation:
|
# crée une évaluation:
|
||||||
evaluation_id = context.do_evaluation_create(
|
evaluation_id = sco_evaluations.do_evaluation_create(context,
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
moduleimpl_id=moduleimpl_id,
|
moduleimpl_id=moduleimpl_id,
|
||||||
note_max=20.0,
|
note_max=20.0,
|
||||||
|
@ -385,6 +385,15 @@ def UsersURL():
|
|||||||
return "NotImplemented"
|
return "NotImplemented"
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user_name(REQUEST):
|
||||||
|
"""return a displayable string identifying the current user.
|
||||||
|
XXX For now, the login, but will be the name. #sco8
|
||||||
|
"""
|
||||||
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
uid = str(authuser)
|
||||||
|
return uid
|
||||||
|
|
||||||
|
|
||||||
# ---- Simple python utilities
|
# ---- Simple python utilities
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,8 +81,10 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
|
|||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_abs
|
from app.scodoc import sco_abs
|
||||||
from app.scodoc import sco_abs_notification, sco_abs_views
|
from app.scodoc import sco_abs_notification
|
||||||
|
from app.scodoc import sco_abs_views
|
||||||
from app.scodoc import sco_compute_moy
|
from app.scodoc import sco_compute_moy
|
||||||
|
from app.scodoc import sco_core
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
@ -248,7 +250,9 @@ def SignaleAbsenceGrHebdo(
|
|||||||
else:
|
else:
|
||||||
# Si aucun etudiant n'est inscrit au module choisi...
|
# Si aucun etudiant n'est inscrit au module choisi...
|
||||||
moduleimpl_id = None
|
moduleimpl_id = None
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id)
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
|
context.Notes, formsemestre_id
|
||||||
|
)
|
||||||
sem = sco_formsemestre.do_formsemestre_list(
|
sem = sco_formsemestre.do_formsemestre_list(
|
||||||
context, {"formsemestre_id": formsemestre_id}
|
context, {"formsemestre_id": formsemestre_id}
|
||||||
)[0]
|
)[0]
|
||||||
@ -421,7 +425,7 @@ def SignaleAbsenceGrSemestre(
|
|||||||
base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id
|
base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id
|
||||||
|
|
||||||
if etuds:
|
if etuds:
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
)
|
)
|
||||||
sem = sco_formsemestre.do_formsemestre_list(
|
sem = sco_formsemestre.do_formsemestre_list(
|
||||||
@ -638,7 +642,7 @@ def _gen_form_saisie_groupe(
|
|||||||
# UE capitalisee dans semestre courant ?
|
# UE capitalisee dans semestre courant ?
|
||||||
cap = []
|
cap = []
|
||||||
if etud["cursem"]:
|
if etud["cursem"]:
|
||||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||||
context.Notes, etud["cursem"]["formsemestre_id"]
|
context.Notes, etud["cursem"]["formsemestre_id"]
|
||||||
) # > get_ues, get_etud_ue_status
|
) # > get_ues, get_etud_ue_status
|
||||||
for ue in nt.get_ues():
|
for ue in nt.get_ues():
|
||||||
|
@ -41,7 +41,7 @@ def sco_exemple(etudid="NON"):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# En ScoDoc 7, on a souvent des vues qui en appellent d'autres
|
# En ScoDoc 7, on avait des vues qui en appellaient d'autres
|
||||||
# avec context.sco_exemple( etudid="E12" )
|
# avec context.sco_exemple( etudid="E12" )
|
||||||
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple2")
|
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple2")
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -486,33 +486,11 @@ def formation_import_xml_form(context, REQUEST):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formation_create_new_version")
|
sco_publish(
|
||||||
@permission_required(Permission.ScoChangeFormation)
|
"/formation_create_new_version",
|
||||||
@scodoc7func(context)
|
sco_formations.formation_create_new_version,
|
||||||
def formation_create_new_version(context, formation_id, redirect=True, REQUEST=None):
|
Permission.ScoChangeFormation,
|
||||||
"duplicate formation, with new version number"
|
)
|
||||||
xml = sco_formations.formation_export(
|
|
||||||
context, formation_id, export_ids=True, format="xml"
|
|
||||||
)
|
|
||||||
new_id, modules_old2new, ues_old2new = sco_formations.formation_import_xml(
|
|
||||||
context, REQUEST, xml
|
|
||||||
)
|
|
||||||
# news
|
|
||||||
F = sco_formations.formation_list(context, args={"formation_id": new_id})[0]
|
|
||||||
sco_news.add(
|
|
||||||
context,
|
|
||||||
REQUEST,
|
|
||||||
typ=sco_news.NEWS_FORM,
|
|
||||||
object=new_id,
|
|
||||||
text="Nouvelle version de la formation %(acronyme)s" % F,
|
|
||||||
)
|
|
||||||
if redirect:
|
|
||||||
return REQUEST.RESPONSE.redirect(
|
|
||||||
"ue_list?formation_id=" + new_id + "&msg=Nouvelle version !"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return new_id, modules_old2new, ues_old2new
|
|
||||||
|
|
||||||
|
|
||||||
# --- UE
|
# --- UE
|
||||||
sco_publish(
|
sco_publish(
|
||||||
@ -579,42 +557,6 @@ sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormatio
|
|||||||
|
|
||||||
|
|
||||||
# --- Semestres de formation
|
# --- Semestres de formation
|
||||||
@bp.route("/do_formsemestre_create")
|
|
||||||
@permission_required(Permission.ScoImplement)
|
|
||||||
@scodoc7func(context)
|
|
||||||
def do_formsemestre_create(context, args, REQUEST, silent=False):
|
|
||||||
"create a formsemestre"
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
formsemestre_id = sco_formsemestre._formsemestreEditor.create(cnx, args)
|
|
||||||
if args["etapes"]:
|
|
||||||
args["formsemestre_id"] = formsemestre_id
|
|
||||||
sco_formsemestre.write_formsemestre_etapes(context, args)
|
|
||||||
if args["responsables"]:
|
|
||||||
args["formsemestre_id"] = formsemestre_id
|
|
||||||
sco_formsemestre.write_formsemestre_responsables(context, args)
|
|
||||||
|
|
||||||
# create default partition
|
|
||||||
partition_id = sco_groups.partition_create(
|
|
||||||
context, formsemestre_id, default=True, redirect=0, REQUEST=REQUEST
|
|
||||||
)
|
|
||||||
_group_id = sco_groups.createGroup(
|
|
||||||
context, partition_id, default=True, REQUEST=REQUEST
|
|
||||||
)
|
|
||||||
|
|
||||||
# news
|
|
||||||
if not args.has_key("titre"):
|
|
||||||
args["titre"] = "sans titre"
|
|
||||||
args["formsemestre_id"] = formsemestre_id
|
|
||||||
args["url"] = "Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s" % args
|
|
||||||
if not silent:
|
|
||||||
sco_news.add(
|
|
||||||
context,
|
|
||||||
REQUEST,
|
|
||||||
typ=sco_news.NEWS_SEM,
|
|
||||||
text='Création du semestre <a href="%(url)s">%(titre)s</a>' % args,
|
|
||||||
url=args["url"],
|
|
||||||
)
|
|
||||||
return formsemestre_id
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre_list")
|
@bp.route("/formsemestre_list")
|
||||||
@ -1285,14 +1227,9 @@ def do_formsemestre_inscription_listinscrits(
|
|||||||
context, formsemestre_id, format=None, REQUEST=None
|
context, formsemestre_id, format=None, REQUEST=None
|
||||||
):
|
):
|
||||||
"""Liste les inscrits (état I) à ce semestre et cache le résultat"""
|
"""Liste les inscrits (état I) à ce semestre et cache le résultat"""
|
||||||
cache = sco_core.get_formsemestre_inscription_cache(context)
|
r = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||||
r = cache.get(formsemestre_id)
|
context, formsemestre_id
|
||||||
if r is None:
|
)
|
||||||
# retreive list
|
|
||||||
r = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
|
||||||
context, args={"formsemestre_id": formsemestre_id, "etat": "I"}
|
|
||||||
)
|
|
||||||
cache.set(formsemestre_id, r)
|
|
||||||
return scu.sendResult(REQUEST, r, format=format, name="inscrits")
|
return scu.sendResult(REQUEST, r, format=format, name="inscrits")
|
||||||
|
|
||||||
|
|
||||||
@ -1365,7 +1302,9 @@ def formsemestre_desinscription(
|
|||||||
parameters={"etudid": etudid, "formsemestre_id": formsemestre_id},
|
parameters={"etudid": etudid, "formsemestre_id": formsemestre_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
context.do_formsemestre_desinscription(etudid, formsemestre_id, REQUEST=REQUEST)
|
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
|
||||||
|
context, etudid, formsemestre_id, REQUEST=REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
html_sco_header.sco_header(context, REQUEST)
|
html_sco_header.sco_header(context, REQUEST)
|
||||||
@ -1458,170 +1397,6 @@ sco_publish(
|
|||||||
# --- Evaluations
|
# --- Evaluations
|
||||||
|
|
||||||
|
|
||||||
def _evaluation_check_write_access(context, REQUEST, moduleimpl_id=None):
|
|
||||||
"""Vérifie que l'on a le droit de modifier, créer ou détruire une
|
|
||||||
évaluation dans ce module.
|
|
||||||
Sinon, lance une exception.
|
|
||||||
(nb: n'implique pas le droit de saisir ou modifier des notes)
|
|
||||||
"""
|
|
||||||
# acces pour resp. moduleimpl et resp. form semestre (dir etud)
|
|
||||||
if moduleimpl_id is None:
|
|
||||||
raise ValueError("no moduleimpl specified") # bug
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
uid = str(authuser)
|
|
||||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
|
||||||
|
|
||||||
if (
|
|
||||||
(not authuser.has_permission(Permission.ScoEditAllEvals))
|
|
||||||
and uid != M["responsable_id"]
|
|
||||||
and uid not in sem["responsables"]
|
|
||||||
):
|
|
||||||
if sem["ens_can_edit_eval"]:
|
|
||||||
for ens in M["ens"]:
|
|
||||||
if ens["ens_id"] == uid:
|
|
||||||
return # ok
|
|
||||||
raise AccessDenied("Modification évaluation impossible pour %s" % (uid,))
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/do_evaluation_create")
|
|
||||||
@permission_required(Permission.ScoEnsView)
|
|
||||||
@scodoc7func(context)
|
|
||||||
def do_evaluation_create(
|
|
||||||
context,
|
|
||||||
moduleimpl_id=None,
|
|
||||||
jour=None,
|
|
||||||
heure_debut=None,
|
|
||||||
heure_fin=None,
|
|
||||||
description=None,
|
|
||||||
note_max=None,
|
|
||||||
coefficient=None,
|
|
||||||
visibulletin=None,
|
|
||||||
publish_incomplete=None,
|
|
||||||
evaluation_type=None,
|
|
||||||
numero=None,
|
|
||||||
REQUEST=None,
|
|
||||||
**kw
|
|
||||||
):
|
|
||||||
"""Create an evaluation"""
|
|
||||||
args = locals()
|
|
||||||
log("do_evaluation_create: args=" + str(args))
|
|
||||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
|
||||||
context._check_evaluation_args(args)
|
|
||||||
# Check numeros
|
|
||||||
sco_evaluations.module_evaluation_renumber(
|
|
||||||
context, moduleimpl_id, REQUEST=REQUEST, only_if_unumbered=True
|
|
||||||
)
|
|
||||||
if not "numero" in args or args["numero"] is None:
|
|
||||||
n = None
|
|
||||||
# determine le numero avec la date
|
|
||||||
# Liste des eval existantes triees par date, la plus ancienne en tete
|
|
||||||
ModEvals = sco_evaluations.do_evaluation_list(
|
|
||||||
context,
|
|
||||||
args={"moduleimpl_id": moduleimpl_id},
|
|
||||||
sortkey="jour asc, heure_debut asc",
|
|
||||||
)
|
|
||||||
if args["jour"]:
|
|
||||||
next_eval = None
|
|
||||||
t = (
|
|
||||||
ndb.DateDMYtoISO(args["jour"]),
|
|
||||||
ndb.TimetoISO8601(args["heure_debut"]),
|
|
||||||
)
|
|
||||||
for e in ModEvals:
|
|
||||||
if (
|
|
||||||
ndb.DateDMYtoISO(e["jour"]),
|
|
||||||
ndb.TimetoISO8601(e["heure_debut"]),
|
|
||||||
) > t:
|
|
||||||
next_eval = e
|
|
||||||
break
|
|
||||||
if next_eval:
|
|
||||||
n = sco_evaluations.module_evaluation_insert_before(
|
|
||||||
context, ModEvals, next_eval, REQUEST
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
n = None # a placer en fin
|
|
||||||
if n is None: # pas de date ou en fin:
|
|
||||||
if ModEvals:
|
|
||||||
log(pprint.pformat(ModEvals[-1]))
|
|
||||||
n = ModEvals[-1]["numero"] + 1
|
|
||||||
else:
|
|
||||||
n = 0 # the only one
|
|
||||||
# log("creating with numero n=%d" % n)
|
|
||||||
args["numero"] = n
|
|
||||||
|
|
||||||
#
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
r = sco_evaluations._evaluationEditor.create(cnx, args)
|
|
||||||
|
|
||||||
# news
|
|
||||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
|
||||||
mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
|
|
||||||
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
|
||||||
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
|
||||||
sco_news.add(
|
|
||||||
context,
|
|
||||||
REQUEST,
|
|
||||||
typ=sco_news.NEWS_NOTE,
|
|
||||||
object=moduleimpl_id,
|
|
||||||
text='Création d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
|
||||||
url=mod["url"],
|
|
||||||
)
|
|
||||||
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def _check_evaluation_args(context, args):
|
|
||||||
"Check coefficient, dates and duration, raises exception if invalid"
|
|
||||||
moduleimpl_id = args["moduleimpl_id"]
|
|
||||||
# check bareme
|
|
||||||
note_max = args.get("note_max", None)
|
|
||||||
if note_max is None:
|
|
||||||
raise ScoValueError("missing note_max")
|
|
||||||
try:
|
|
||||||
note_max = float(note_max)
|
|
||||||
except ValueError:
|
|
||||||
raise ScoValueError("Invalid note_max value")
|
|
||||||
if note_max < 0:
|
|
||||||
raise ScoValueError("Invalid note_max value (must be positive or null)")
|
|
||||||
# check coefficient
|
|
||||||
coef = args.get("coefficient", None)
|
|
||||||
if coef is None:
|
|
||||||
raise ScoValueError("missing coefficient")
|
|
||||||
try:
|
|
||||||
coef = float(coef)
|
|
||||||
except ValueError:
|
|
||||||
raise ScoValueError("Invalid coefficient value")
|
|
||||||
if coef < 0:
|
|
||||||
raise ScoValueError("Invalid coefficient value (must be positive or null)")
|
|
||||||
# check date
|
|
||||||
jour = args.get("jour", None)
|
|
||||||
args["jour"] = jour
|
|
||||||
if jour:
|
|
||||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
|
||||||
d, m, y = [int(x) for x in sem["date_debut"].split("/")]
|
|
||||||
date_debut = datetime.date(y, m, d)
|
|
||||||
d, m, y = [int(x) for x in sem["date_fin"].split("/")]
|
|
||||||
date_fin = datetime.date(y, m, d)
|
|
||||||
# passe par ndb.DateDMYtoISO pour avoir date pivot
|
|
||||||
y, m, d = [int(x) for x in ndb.DateDMYtoISO(jour).split("-")]
|
|
||||||
jour = datetime.date(y, m, d)
|
|
||||||
if (jour > date_fin) or (jour < date_debut):
|
|
||||||
raise ScoValueError(
|
|
||||||
"La date de l'évaluation (%s/%s/%s) n'est pas dans le semestre !"
|
|
||||||
% (d, m, y)
|
|
||||||
)
|
|
||||||
heure_debut = args.get("heure_debut", None)
|
|
||||||
args["heure_debut"] = heure_debut
|
|
||||||
heure_fin = args.get("heure_fin", None)
|
|
||||||
args["heure_fin"] = heure_fin
|
|
||||||
if jour and ((not heure_debut) or (not heure_fin)):
|
|
||||||
raise ScoValueError("Les heures doivent être précisées")
|
|
||||||
d = ndb.TimeDuration(heure_debut, heure_fin)
|
|
||||||
if d and ((d < 0) or (d > 60 * 12)):
|
|
||||||
raise ScoValueError("Heures de l'évaluation incohérentes !")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/evaluation_delete")
|
@bp.route("/evaluation_delete")
|
||||||
@permission_required(Permission.ScoEnsView)
|
@permission_required(Permission.ScoEnsView)
|
||||||
@scodoc7func(context)
|
@scodoc7func(context)
|
||||||
|
@ -85,7 +85,7 @@ from app.scodoc.gen_tables import GenTable
|
|||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import html_sidebar
|
from app.scodoc import html_sidebar
|
||||||
from app.scodoc import imageresize
|
from app.scodoc import imageresize
|
||||||
from app.scodoc import ImportScolars
|
from app.scodoc import sco_import_etuds
|
||||||
from app.scodoc import sco_abs
|
from app.scodoc import sco_abs
|
||||||
from app.scodoc import sco_archives_etud
|
from app.scodoc import sco_archives_etud
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
@ -1736,7 +1736,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
|
|||||||
<table>
|
<table>
|
||||||
<tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>"""
|
<tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>"""
|
||||||
]
|
]
|
||||||
for t in ImportScolars.sco_import_format(
|
for t in sco_import_etuds.sco_import_format(
|
||||||
with_codesemestre=(formsemestre_id == None)
|
with_codesemestre=(formsemestre_id == None)
|
||||||
):
|
):
|
||||||
if int(t[3]):
|
if int(t[3]):
|
||||||
@ -1752,7 +1752,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
|
|||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return REQUEST.RESPONSE.redirect(dest_url)
|
return REQUEST.RESPONSE.redirect(dest_url)
|
||||||
else:
|
else:
|
||||||
return ImportScolars.students_import_excel(
|
return sco_import_etuds.students_import_excel(
|
||||||
context,
|
context,
|
||||||
tf[2]["csvfile"],
|
tf[2]["csvfile"],
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
@ -1771,8 +1771,8 @@ def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
|
|||||||
with_codesemestre = int(with_codesemestre)
|
with_codesemestre = int(with_codesemestre)
|
||||||
else:
|
else:
|
||||||
with_codesemestre = 0
|
with_codesemestre = 0
|
||||||
format = ImportScolars.sco_import_format()
|
format = sco_import_etuds.sco_import_format()
|
||||||
data = ImportScolars.sco_import_generate_excel_sample(
|
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||||
format, with_codesemestre, exclude_cols=["photo_filename"], REQUEST=REQUEST
|
format, with_codesemestre, exclude_cols=["photo_filename"], REQUEST=REQUEST
|
||||||
)
|
)
|
||||||
return sco_excel.sendExcelFile(REQUEST, data, "ImportEtudiants.xls")
|
return sco_excel.sendExcelFile(REQUEST, data, "ImportEtudiants.xls")
|
||||||
@ -1787,8 +1787,8 @@ def import_generate_admission_sample(context, REQUEST, formsemestre_id):
|
|||||||
group = sco_groups.get_group(
|
group = sco_groups.get_group(
|
||||||
context, sco_groups.get_default_group(context, formsemestre_id)
|
context, sco_groups.get_default_group(context, formsemestre_id)
|
||||||
)
|
)
|
||||||
fmt = ImportScolars.sco_import_format()
|
fmt = sco_import_etuds.sco_import_format()
|
||||||
data = ImportScolars.sco_import_generate_excel_sample(
|
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||||
fmt,
|
fmt,
|
||||||
only_tables=["identite", "admissions", "adresse"],
|
only_tables=["identite", "admissions", "adresse"],
|
||||||
exclude_cols=["nationalite", "foto", "photo_filename"],
|
exclude_cols=["nationalite", "foto", "photo_filename"],
|
||||||
@ -1889,7 +1889,7 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
|||||||
Seule la première feuille du classeur sera utilisée.
|
Seule la première feuille du classeur sera utilisée.
|
||||||
<div id="adm_table_description_format">
|
<div id="adm_table_description_format">
|
||||||
"""
|
"""
|
||||||
+ ImportScolars.adm_table_description_format(context).html()
|
+ sco_import_etuds.adm_table_description_format(context).html()
|
||||||
+ """</div>"""
|
+ """</div>"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1913,7 +1913,7 @@ def _students_import_admission(
|
|||||||
context, csvfile, type_admission="", REQUEST=None, formsemestre_id=None
|
context, csvfile, type_admission="", REQUEST=None, formsemestre_id=None
|
||||||
):
|
):
|
||||||
"import donnees admission from Excel file (v2016)"
|
"import donnees admission from Excel file (v2016)"
|
||||||
diag = ImportScolars.scolars_import_admission(
|
diag = sco_import_etuds.scolars_import_admission(
|
||||||
csvfile,
|
csvfile,
|
||||||
context.Notes,
|
context.Notes,
|
||||||
REQUEST,
|
REQUEST,
|
||||||
|
10
refactor.py
Normal file → Executable file
10
refactor.py
Normal file → Executable file
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
- remplace context.xxx par module.xxx
|
- remplace context.xxx par module.xxx
|
||||||
|
|
||||||
./refactor.py refactor method module app/scodoc/*.py
|
./refactor.py refactor module.method app/scodoc/*.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -34,14 +34,6 @@ import tempfile
|
|||||||
import shutil
|
import shutil
|
||||||
import click
|
import click
|
||||||
|
|
||||||
# import flask
|
|
||||||
|
|
||||||
# import app
|
|
||||||
# from app import create_app, cli, db
|
|
||||||
# from app.auth.models import User, Role, UserRole
|
|
||||||
|
|
||||||
# from app.views import notes
|
|
||||||
|
|
||||||
TYPES_TO_SCAN = {
|
TYPES_TO_SCAN = {
|
||||||
types.FunctionType,
|
types.FunctionType,
|
||||||
# types.ClassType,
|
# types.ClassType,
|
||||||
|
Loading…
Reference in New Issue
Block a user