Compare commits
3 Commits
8f91d5292c
...
ede5aa680d
Author | SHA1 | Date | |
---|---|---|---|
ede5aa680d | |||
597b83e6a4 | |||
6a4d6e5109 |
@ -133,7 +133,7 @@ class User(UserMixin, db.Model):
|
||||
|
||||
Args:
|
||||
perm: integer, one of the value defined in Permission class.
|
||||
context:
|
||||
dept: dept id (eg 'RT')
|
||||
"""
|
||||
if dept is False:
|
||||
dept = g.scodoc_dept
|
||||
|
@ -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
|
@ -19,7 +19,7 @@ authuser = app.acl_users.getUserById('admin')
|
||||
authuser = authuser.__of__(app.acl_users)
|
||||
|
||||
Exemple:
|
||||
sems = context.Notes.formsemestre_list()
|
||||
sems = sco_formsemestre.do_formsemestre_list.formsemestre_list(context)
|
||||
formsemestre_id = sems[0]['formsemestre_id']
|
||||
|
||||
# Affiche tous les semestres:
|
||||
@ -27,7 +27,7 @@ for sem in sems:
|
||||
print sem['formsemestre_id'], sem['titre_num']
|
||||
|
||||
# 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, formsemestre_id)
|
||||
|
||||
|
||||
"""
|
||||
|
@ -54,9 +54,10 @@ from reportlab.lib import styles
|
||||
from reportlab.lib.units import inch, cm, mm
|
||||
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.sco_excel
|
||||
import app.scodoc.sco_pdf
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc import sco_excel
|
||||
from app.scodoc import sco_pdf
|
||||
from app.scodoc.sco_pdf import SU
|
||||
from app.scodoc.notes_log import log
|
||||
|
||||
|
@ -100,7 +100,7 @@ def retreive_dept():
|
||||
# Alarms by email:
|
||||
def sendAlarm(context, subj, txt):
|
||||
import sco_utils
|
||||
import mails
|
||||
import sco_emails
|
||||
import sco_preferences
|
||||
|
||||
msg = MIMEMultipart()
|
||||
@ -111,7 +111,7 @@ def sendAlarm(context, subj, txt):
|
||||
msg.epilogue = ""
|
||||
txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING)
|
||||
msg.attach(txt)
|
||||
mails.sendEmail(context, msg)
|
||||
sco_emails.sendEmail(context, msg)
|
||||
|
||||
|
||||
# Debug: log call stack
|
||||
|
@ -1205,7 +1205,7 @@ class NotesTable:
|
||||
and moy_ue_cap >= self.parcours.NOTES_BARRE_VALID_UE
|
||||
):
|
||||
if not cnx:
|
||||
cnx = self.context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
sco_parcours_dut.do_formsemestre_validate_ue(
|
||||
cnx,
|
||||
nt_cap,
|
||||
|
@ -57,7 +57,9 @@ import pprint
|
||||
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
||||
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_core
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import pe_tagtable
|
||||
from app.scodoc import pe_tools
|
||||
from app.scodoc import pe_semestretag
|
||||
@ -331,7 +333,7 @@ class JuryPE:
|
||||
nt = self.get_cache_notes_d_un_semestre(
|
||||
self.context, sem["formsemestre_id"]
|
||||
)
|
||||
# context.Notes._getNotesCache().get_NotesTable(context.Notes, sem['formsemestre_id'])
|
||||
# sco_core.get_notes_cache(context).get_NotesTable(context, sem['formsemestre_id'])
|
||||
etudiantsDuSemestre = (
|
||||
nt.get_etudids()
|
||||
) # nt.identdict.keys() # identification des etudiants du semestre
|
||||
@ -466,7 +468,7 @@ class JuryPE:
|
||||
|
||||
reponse = False
|
||||
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
|
||||
(_, parcours) = sco_report.get_codeparcoursetud(self.context.Notes, etud)
|
||||
(_, parcours) = sco_report.get_codeparcoursetud(self.context, etud)
|
||||
if (
|
||||
len(set(sco_codes_parcours.CODES_SEM_REO.keys()) & set(parcours.values()))
|
||||
> 0
|
||||
@ -498,7 +500,7 @@ class JuryPE:
|
||||
lastdate = max(sesdates) # date de fin de l'inscription la plus récente
|
||||
|
||||
# if PETable.AFFICHAGE_DEBUG_PE == True : pe_tools.pe_print(" derniere inscription = ", lastDateSem)
|
||||
semestresDeScoDoc = self.context.Notes.formsemestre_list()
|
||||
semestresDeScoDoc = sco_formsemestre.formsemestre_list(self.context)
|
||||
semestresSuperieurs = [
|
||||
sem for sem in semestresDeScoDoc if sem["semestre_id"] > sonDernierSidValide
|
||||
] # Semestre de rang plus élevé que son dernier sem valide
|
||||
@ -530,7 +532,7 @@ class JuryPE:
|
||||
|
||||
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
|
||||
(code, parcours) = sco_report.get_codeparcoursetud(
|
||||
self.context.Notes, etud
|
||||
self.context, etud
|
||||
) # description = '1234:A', parcours = {1:ADM, 2:NAR, ...}
|
||||
sonDernierSemestreValide = max(
|
||||
[
|
||||
@ -1139,8 +1141,8 @@ class JuryPE:
|
||||
self, context, formsemestre_id
|
||||
): # inutile en realité !
|
||||
"""Charge la table des notes d'un formsemestre"""
|
||||
return context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
return sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, formsemestre_id
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
@ -1245,8 +1247,8 @@ def get_cosemestres_diplomants(context, semBase, avec_meme_formation=False):
|
||||
> dont la formation est la même (optionnel)
|
||||
> ne prenant en compte que les etudiants sans redoublement
|
||||
"""
|
||||
tousLesSems = (
|
||||
context.Notes.formsemestre_list()
|
||||
tousLesSems = sco_formsemestre.formsemestre_list(
|
||||
context
|
||||
) # tous les semestres memorises dans scodoc
|
||||
diplome = get_annee_diplome_semestre(semBase)
|
||||
|
||||
|
@ -38,6 +38,7 @@ Created on Fri Sep 9 09:15:05 2016
|
||||
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_tag_module
|
||||
from app.scodoc import pe_tagtable
|
||||
|
||||
@ -269,8 +270,8 @@ class SemestreTag(pe_tagtable.TableTag):
|
||||
# => le formsemestre_id du semestre dont vient la capitalisation
|
||||
fid_prec = fids_prec[0]
|
||||
# Lecture des notes de ce semestre
|
||||
nt_prec = self.context.Notes._getNotesCache().get_NotesTable(
|
||||
self.context.Notes, fid_prec
|
||||
nt_prec = sco_core.get_notes_cache(self.context).get_NotesTable(
|
||||
self.context, fid_prec
|
||||
) # 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)
|
||||
|
@ -41,9 +41,10 @@ from app.scodoc import notesdb as ndb
|
||||
from app.scodoc.scolog import logdb
|
||||
from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
|
||||
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_preferences
|
||||
from app.scodoc import sco_etud
|
||||
|
||||
# --- Misc tools.... ------------------
|
||||
|
||||
@ -436,7 +437,7 @@ def GetAbsDescription(context, a, cursor=None):
|
||||
if a["moduleimpl_id"] and a["moduleimpl_id"] != "NULL":
|
||||
# Trouver le nom du module
|
||||
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
|
||||
context.Notes, moduleimpl_id=a["moduleimpl_id"]
|
||||
context, moduleimpl_id=a["moduleimpl_id"]
|
||||
)
|
||||
if Mlist:
|
||||
M = Mlist[0]
|
||||
@ -968,7 +969,7 @@ class CAbsSemEtud:
|
||||
self.etudid = etudid
|
||||
self._loaded = False
|
||||
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)
|
||||
)
|
||||
|
||||
@ -992,11 +993,11 @@ class CAbsSemEtud:
|
||||
debut_sem = ndb.DateDMYtoISO(self.sem["date_debut"])
|
||||
fin_sem = ndb.DateDMYtoISO(self.sem["date_fin"])
|
||||
|
||||
self._CountAbs = self.sco_abs.CountAbs(
|
||||
context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||
self._CountAbs = CountAbs(
|
||||
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||
)
|
||||
self._CountAbsJust = self.sco_abs.CountAbsJust(
|
||||
context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||
self._CountAbsJust = CountAbsJust(
|
||||
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
|
||||
)
|
||||
self._loaded = True
|
||||
|
||||
@ -1054,8 +1055,8 @@ def invalidateAbsEtudDate(context, etudid, date):
|
||||
True # efface toujours le PDF car il affiche en général les absences
|
||||
)
|
||||
|
||||
context.Notes._inval_cache(
|
||||
pdfonly=pdfonly, formsemestre_id=sem["formsemestre_id"]
|
||||
sco_core.inval_cache(
|
||||
context, pdfonly=pdfonly, formsemestre_id=sem["formsemestre_id"]
|
||||
)
|
||||
|
||||
# Inval cache compteurs absences:
|
||||
|
@ -37,7 +37,7 @@ from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
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.sco_utils as scu
|
||||
from app.scodoc.notes_log import log
|
||||
@ -62,7 +62,7 @@ def abs_notify(context, etudid, date):
|
||||
debut_sem = ndb.DateDMYtoISO(sem["date_debut"])
|
||||
fin_sem = ndb.DateDMYtoISO(sem["date_fin"])
|
||||
nbabs = sco_abs.CountAbs(context, etudid, debut=debut_sem, fin=fin_sem)
|
||||
nbabsjust = context.CountAbsJust(etudid, debut=debut_sem, fin=fin_sem)
|
||||
nbabsjust = sco_abs.CountAbsJust(context, etudid, debut=debut_sem, fin=fin_sem)
|
||||
|
||||
do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust)
|
||||
|
||||
@ -119,7 +119,7 @@ def abs_notify_send(
|
||||
for email in destinations:
|
||||
del msg["To"]
|
||||
msg["To"] = email
|
||||
mails.sendEmail(context, msg)
|
||||
sco_emails.sendEmail(context, msg)
|
||||
ndb.SimpleQuery(
|
||||
context,
|
||||
"""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 import html_sco_header
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_find_etud
|
||||
from app.scodoc import sco_formsemestre
|
||||
@ -124,9 +125,7 @@ def doSignaleAbsence(
|
||||
if moduleimpl_id and moduleimpl_id != "NULL":
|
||||
mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||
formsemestre_id = mod["formsemestre_id"]
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id)
|
||||
ues = nt.get_ues(etudid=etudid)
|
||||
for ue in ues:
|
||||
modimpls = nt.get_modimpls(ue_id=ue["ue_id"])
|
||||
@ -185,9 +184,7 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
|
||||
require_module = sco_preferences.get_preference(
|
||||
context, "abs_require_module", formsemestre_id
|
||||
)
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id)
|
||||
ues = nt.get_ues(etudid=etudid)
|
||||
if require_module:
|
||||
menu_module = """
|
||||
@ -740,7 +737,7 @@ def CalAbs(context, REQUEST=None): # etud implied
|
||||
datedebut = str(anneescolaire) + "-08-31"
|
||||
datefin = str(anneescolaire + 1) + "-07-31"
|
||||
nbabs = sco_abs.CountAbs(context, etudid=etudid, debut=datedebut, fin=datefin)
|
||||
nbabsjust = context.CountAbsJust(etudid=etudid, debut=datedebut, fin=datefin)
|
||||
nbabsjust = sco_abs.CountAbsJust(context, etudid=etudid, debut=datedebut, fin=datefin)
|
||||
events = []
|
||||
for a in sco_abs.ListeAbsJust(context, etudid=etudid, datedebut=datedebut):
|
||||
events.append(
|
||||
@ -967,7 +964,7 @@ def _TablesAbsEtud(
|
||||
ex = []
|
||||
for ev in a["evals"]:
|
||||
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
|
||||
context.Notes, moduleimpl_id=ev["moduleimpl_id"]
|
||||
context, moduleimpl_id=ev["moduleimpl_id"]
|
||||
)[0]
|
||||
if format == "html":
|
||||
ex.append(
|
||||
@ -984,7 +981,7 @@ def _TablesAbsEtud(
|
||||
ex = []
|
||||
for ev in a.get("absent", []):
|
||||
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
|
||||
context.Notes, moduleimpl_id=ev["moduleimpl_id"]
|
||||
context, moduleimpl_id=ev["moduleimpl_id"]
|
||||
)[0]
|
||||
if format == "html":
|
||||
ex.append(
|
||||
|
@ -31,7 +31,7 @@
|
||||
"""
|
||||
|
||||
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_trombino
|
||||
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)
|
||||
def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
|
||||
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)"""
|
||||
fmt = ImportScolars.sco_import_format()
|
||||
data = ImportScolars.sco_import_generate_excel_sample(
|
||||
fmt = sco_import_etuds.sco_import_format()
|
||||
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||
fmt,
|
||||
context=context,
|
||||
group_ids=[group_id],
|
||||
|
@ -41,13 +41,14 @@ from email.header import Header
|
||||
|
||||
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.notesdb as ndb
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_exceptions import AccessDenied
|
||||
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_bulletins_generator
|
||||
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)
|
||||
msg.attach(att)
|
||||
log("mail bulletin a %s" % msg["To"])
|
||||
mails.sendEmail(context, msg)
|
||||
sco_emails.sendEmail(context, msg)
|
||||
|
||||
|
||||
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_evaluations
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
from app.scodoc import sco_formulas
|
||||
from app.scodoc import sco_moduleimpl
|
||||
from app.scodoc import sco_etud
|
||||
@ -211,8 +212,8 @@ def do_moduleimpl_moyennes(context, nt, mod):
|
||||
inssem_set = set(
|
||||
[
|
||||
x["etudid"]
|
||||
for x in context.do_formsemestre_inscription_listinscrits(
|
||||
mod["formsemestre_id"]
|
||||
for x in sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||
context, mod["formsemestre_id"]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
@ -254,7 +254,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
|
||||
)
|
||||
#
|
||||
if create:
|
||||
formation_id = context.do_formation_create(tf[2], REQUEST)
|
||||
formation_id = do_formation_create(context, tf[2], REQUEST)
|
||||
else:
|
||||
do_formation_edit(context, tf[2])
|
||||
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
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc import VERSION
|
||||
|
||||
|
||||
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)
|
||||
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id)
|
||||
|
||||
#
|
||||
s = SemSet(context, 'NSS29902')
|
||||
|
@ -37,7 +37,7 @@ from email.mime.text import MIMEText
|
||||
from email.header import Header
|
||||
from email.mime.base import MIMEBase
|
||||
|
||||
from app.scodoc import mails
|
||||
from app.scodoc import sco_emails
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.sco_utils import SCO_ENCODING
|
||||
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.TrivialFormulator import TrivialFormulator
|
||||
from app.scodoc import safehtml
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_preferences
|
||||
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
|
||||
mime_txt = MIMEText(txt, "plain", SCO_ENCODING)
|
||||
msg.attach(mime_txt)
|
||||
mails.sendEmail(context, msg)
|
||||
sco_emails.sendEmail(context, msg)
|
||||
return txt
|
||||
|
||||
|
||||
@ -901,6 +900,7 @@ def fill_etuds_info(etuds):
|
||||
Pour chaque etudiant, ajoute ou formatte les champs
|
||||
-> informations pour fiche etudiant ou listes diverses
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
|
||||
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=""):
|
||||
"""chaine decrivant la situation actuelle de l'etudiant"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
cnx = ndb.GetDBConnexion()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
cursor.execute(
|
||||
|
@ -27,10 +27,11 @@
|
||||
|
||||
"""Evaluations
|
||||
"""
|
||||
import datetime
|
||||
import operator
|
||||
import pprint
|
||||
import time
|
||||
import urllib
|
||||
import operator
|
||||
import datetime
|
||||
|
||||
from app.scodoc.notes_log import log, logCallStack
|
||||
import app.scodoc.sco_utils as scu
|
||||
@ -45,6 +46,7 @@ from app.scodoc import sco_core
|
||||
from app.scodoc import sco_edit_module
|
||||
from app.scodoc import sco_edit_ue
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_moduleimpl
|
||||
from app.scodoc import sco_news
|
||||
@ -180,6 +182,146 @@ def do_evaluation_list_in_formsemestre(context, formsemestre_id):
|
||||
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):
|
||||
"edit an evaluation"
|
||||
evaluation_id = args["evaluation_id"]
|
||||
@ -187,11 +329,18 @@ def do_evaluation_edit(context, REQUEST, args):
|
||||
if not the_evals:
|
||||
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)
|
||||
)
|
||||
args["moduleimpl_id"] = moduleimpl_id
|
||||
context._check_evaluation_args(args)
|
||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
||||
_check_evaluation_args(context, args)
|
||||
|
||||
cnx = ndb.GetDBConnexion()
|
||||
context._evaluationEditor.edit(cnx, args)
|
||||
_evaluationEditor.edit(cnx, args)
|
||||
# inval cache pour ce semestre
|
||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||
sco_core.inval_cache(
|
||||
@ -204,7 +353,14 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
|
||||
the_evals = do_evaluation_list(context, {"evaluation_id": evaluation_id})
|
||||
if not the_evals:
|
||||
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 }
|
||||
notes = [x["value"] for x in NotesDB.values()]
|
||||
if notes:
|
||||
@ -212,11 +368,9 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
|
||||
"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()
|
||||
|
||||
context._evaluationEditor.delete(cnx, evaluation_id)
|
||||
_evaluationEditor.delete(cnx, evaluation_id)
|
||||
# inval cache pour ce semestre
|
||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||
sco_core.inval_cache(context, formsemestre_id=M["formsemestre_id"]) # > eval delete
|
||||
@ -295,7 +449,9 @@ def do_evaluation_etat(
|
||||
# Il faut considerer les inscriptions au semestre
|
||||
# (pour avoir l'etat et le groupe) et aussi les inscriptions
|
||||
# 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(
|
||||
context, moduleimpl_id=E["moduleimpl_id"]
|
||||
)
|
||||
@ -676,7 +832,7 @@ def evaluation_date_first_completion(context, evaluation_id):
|
||||
# E = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
||||
# M = sco_moduleimpl.do_moduleimpl_list(context,moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
# 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"])
|
||||
# insmodset = set([x["etudid"] for x in insmod])
|
||||
# retire de insem ceux qui ne sont pas inscrits au module
|
||||
@ -814,9 +970,14 @@ def module_evaluation_move(context, evaluation_id, after=0, REQUEST=None, redire
|
||||
"""
|
||||
e = do_evaluation_list(context, args={"evaluation_id": evaluation_id})[0]
|
||||
redirect = int(redirect)
|
||||
|
||||
# access: can change eval ? (raises exception)
|
||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=e["moduleimpl_id"])
|
||||
# access: can change eval ?
|
||||
if not sco_permissions_check.can_edit_evaluation(
|
||||
context, REQUEST, moduleimpl_id=e["moduleimpl_id"]
|
||||
):
|
||||
raise AccessDenied(
|
||||
"Modification évaluation impossible pour %s"
|
||||
% scu.get_current_user_name(REQUEST)
|
||||
)
|
||||
|
||||
module_evaluation_renumber(
|
||||
context, e["moduleimpl_id"], REQUEST=REQUEST, only_if_unumbered=True
|
||||
@ -977,13 +1138,14 @@ def evaluation_create_form(
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
||||
if not readonly:
|
||||
try:
|
||||
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
||||
except AccessDenied as e:
|
||||
if not sco_permissions_check.can_edit_evaluation(
|
||||
context, REQUEST, moduleimpl_id=moduleimpl_id
|
||||
):
|
||||
return (
|
||||
html_sco_header.sco_header(context, REQUEST)
|
||||
+ "<h2>Opération non autorisée</h2><p>"
|
||||
+ str(e)
|
||||
+ "Modification évaluation impossible pour %s"
|
||||
% scu.get_current_user_name(REQUEST)
|
||||
+ "</p>"
|
||||
+ '<p><a href="%s">Revenir</a></p>' % (str(REQUEST.HTTP_REFERER),)
|
||||
+ html_sco_header.sco_footer(context, REQUEST)
|
||||
@ -1227,7 +1389,7 @@ def evaluation_create_form(
|
||||
tf[2]["visibulletin"] = 0
|
||||
if not edit:
|
||||
# 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)
|
||||
else:
|
||||
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.scolog import logdb
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc import sco_preferences
|
||||
|
||||
|
||||
# colors, voir exemple format.py
|
||||
|
@ -28,6 +28,7 @@
|
||||
"""Recherche d'étudiants
|
||||
"""
|
||||
|
||||
from scodoc_manager import sco_mgr
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
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):
|
||||
"""
|
||||
context est le ZScoDoc
|
||||
@ -279,10 +274,10 @@ def search_etud_in_accessible_depts(context, expnom=None, code_nip=None, REQUEST
|
||||
"""
|
||||
result = []
|
||||
accessible_depts = []
|
||||
deptList = context._list_depts() # definis dans Zope
|
||||
for dept in deptList:
|
||||
depts = sco_mgr.get_dept_ids()
|
||||
for dept in depts:
|
||||
# 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:
|
||||
accessible_depts.append(dept.Scolarite.DeptId())
|
||||
etuds = search_etuds_infos(
|
||||
|
@ -35,16 +35,17 @@ import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc.notes_log import log
|
||||
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_module
|
||||
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(
|
||||
"notes_formations",
|
||||
@ -164,6 +165,8 @@ def formation_import_xml(
|
||||
"""Create a formation from XML representation
|
||||
(format dumped by formation_export( format='xml' ))
|
||||
"""
|
||||
from app.scodoc import sco_edit_formation
|
||||
|
||||
log("formation_import_xml: doc=%s" % doc)
|
||||
try:
|
||||
dom = xml.dom.minidom.parseString(doc)
|
||||
@ -199,7 +202,7 @@ def formation_import_xml(
|
||||
# create formation
|
||||
# F_unquoted = F.copy()
|
||||
# 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)
|
||||
ues_old2new = {} # xml ue_id : new ue_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,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
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 app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
|
||||
from scodoc_manager import sco_mgr
|
||||
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_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
|
||||
import app.scodoc.notesdb as ndb
|
||||
import app.scodoc.sco_utils as scu
|
||||
|
||||
_formsemestreEditor = ndb.EditableTable(
|
||||
"notes_formsemestre",
|
||||
@ -219,6 +219,44 @@ def etapes_apo_str(etapes):
|
||||
return ", ".join([str(x) for x in etapes])
|
||||
|
||||
|
||||
def do_formsemestre_create(context, args, REQUEST, silent=False):
|
||||
"create a formsemestre"
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_news
|
||||
|
||||
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):
|
||||
"""Apply modifications to formsemestre.
|
||||
Update etapes and resps. Invalidate cache."""
|
||||
@ -322,7 +360,7 @@ def _write_formsemestre_aux(context, sem, fieldname, valuename):
|
||||
# uniquify
|
||||
values = set([str(x) for x in sem[fieldname]])
|
||||
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
tablename = "notes_formsemestre_" + fieldname
|
||||
try:
|
||||
@ -500,7 +538,7 @@ def sem_est_courant(context, sem):
|
||||
|
||||
def scodoc_get_all_unlocked_sems(context):
|
||||
"""Liste de tous les semestres non verrouillés de tous les départements"""
|
||||
depts = context._list_depts()
|
||||
depts = sco_mgr.get_dept_ids()
|
||||
semdepts = []
|
||||
for dept in depts:
|
||||
semdepts += [
|
||||
|
@ -715,7 +715,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
|
||||
)
|
||||
if not edit:
|
||||
# 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
|
||||
for module_id in tf[2]["tf-checked"]:
|
||||
modargs = {
|
||||
@ -1014,7 +1016,7 @@ def do_formsemestre_clone(
|
||||
args["date_debut"] = date_debut
|
||||
args["date_fin"] = date_fin
|
||||
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)
|
||||
# 2- create moduleimpls
|
||||
mods_orig = sco_moduleimpl.do_moduleimpl_list(
|
||||
@ -1041,7 +1043,9 @@ def do_formsemestre_clone(
|
||||
args = e.copy()
|
||||
del args["jour"] # erase date
|
||||
args["moduleimpl_id"] = mid
|
||||
_ = context.do_evaluation_create(REQUEST=REQUEST, **args)
|
||||
_ = sco_evaluations.do_evaluation_create(
|
||||
context, REQUEST=REQUEST, **args
|
||||
)
|
||||
|
||||
# 3- copy uecoefs
|
||||
objs = sco_formsemestre.formsemestre_uecoef_list(
|
||||
@ -1196,14 +1200,18 @@ def do_formsemestres_associate_new_version(context, formsemestre_ids, REQUEST=No
|
||||
|
||||
cnx = ndb.GetDBConnexion()
|
||||
# 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:
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_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(
|
||||
context, cnx, formsemestre_id, ues_old2new, modules_old2new
|
||||
)
|
||||
@ -1339,7 +1347,7 @@ def do_formsemestre_delete(context, formsemestre_id, REQUEST):
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
|
||||
# --- Destruction des modules de ce semestre
|
||||
mods = context.do_moduleimpl_list(formsemestre_id=formsemestre_id)
|
||||
mods = sco_moduleimpl.do_moduleimpl_list(context, formsemestre_id=formsemestre_id)
|
||||
for mod in mods:
|
||||
# evaluations
|
||||
evals = sco_evaluations.do_evaluation_list(
|
||||
@ -1474,7 +1482,7 @@ def formsemestre_change_lock(
|
||||
if etat not in (0, 1):
|
||||
raise ScoValueError("formsemestre_lock: invalid value for etat (%s)" % etat)
|
||||
args = {"formsemestre_id": formsemestre_id, "etat": etat}
|
||||
context.do_formsemestre_edit(args)
|
||||
sco_formsemestre.do_formsemestre_edit(context, args)
|
||||
if REQUEST:
|
||||
return REQUEST.RESPONSE.redirect(
|
||||
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
||||
@ -1517,7 +1525,7 @@ def formsemestre_change_publication_bul(
|
||||
"formsemestre_change_publication_bul: invalid value for etat (%s)" % etat
|
||||
)
|
||||
args = {"formsemestre_id": formsemestre_id, "bul_hide_xml": etat}
|
||||
context.do_formsemestre_edit(args)
|
||||
sco_formsemestre.do_formsemestre_edit(context, args)
|
||||
if REQUEST:
|
||||
return REQUEST.RESPONSE.redirect(
|
||||
"formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
||||
@ -1529,7 +1537,6 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
|
||||
"""Changement manuel des coefficients des UE capitalisées."""
|
||||
from app.scodoc import notes_table
|
||||
|
||||
context = context.Notes # si appele d'en haut, eg par exception ScoValueError
|
||||
ok, err = sco_permissions_check.check_access_diretud(
|
||||
context, formsemestre_id, REQUEST
|
||||
)
|
||||
|
@ -63,7 +63,9 @@ def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
|
||||
sem_params["modalite"] = "EXT"
|
||||
sem_params["etapes"] = None
|
||||
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
|
||||
|
||||
# Inscription au semestre
|
||||
|
@ -43,7 +43,6 @@ from app.scodoc import sco_moduleimpl
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_formsemestre_edit
|
||||
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)
|
||||
|
||||
|
||||
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):
|
||||
"create a formsemestre_inscription (and sco event)"
|
||||
cnx = ndb.GetDBConnexion()
|
||||
@ -126,6 +138,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
|
||||
"""Désinscription d'un étudiant.
|
||||
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)
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
@ -332,7 +346,7 @@ def formsemestre_inscription_with_modules(
|
||||
]
|
||||
F = html_sco_header.sco_footer(context, REQUEST)
|
||||
# Check 1: déjà inscrit ici ?
|
||||
ins = context.Notes.do_formsemestre_inscription_list({"etudid": etudid})
|
||||
ins = do_formsemestre_inscription_list(context, {"etudid": etudid})
|
||||
already = False
|
||||
for i in ins:
|
||||
if i["formsemestre_id"] == formsemestre_id:
|
||||
|
@ -346,7 +346,9 @@ def formsemestre_status_menubar(context, sem, REQUEST):
|
||||
"title": "Créer/modifier les partitions...",
|
||||
"endpoint": "scolar.editPartitionForm",
|
||||
"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:
|
||||
@ -355,7 +357,10 @@ def formsemestre_status_menubar(context, sem, REQUEST):
|
||||
)
|
||||
submenu = []
|
||||
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:
|
||||
submenu.append(
|
||||
@ -522,10 +527,6 @@ def formsemestre_page_title(context, REQUEST):
|
||||
"""Element HTML decrivant un semestre (barre de menu et infos)
|
||||
Cherche dans REQUEST si un semestre est défini (formsemestre_id ou moduleimpl ou evaluation ou group)
|
||||
"""
|
||||
try:
|
||||
context = context.Notes
|
||||
except:
|
||||
pass
|
||||
formsemestre_id = retreive_formsemestre_from_request(context, REQUEST)
|
||||
#
|
||||
if not formsemestre_id:
|
||||
@ -873,13 +874,17 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
|
||||
H.append("</table>")
|
||||
else:
|
||||
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(
|
||||
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
|
||||
% partition["partition_id"]
|
||||
)
|
||||
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(
|
||||
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
|
||||
% formsemestre_id
|
||||
|
@ -968,7 +968,7 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
|
||||
) # > get_etudids, get_etud_decision_sem, get_ues, get_etud_decision_ues, get_etud_ue_status
|
||||
etudids = nt.get_etudids()
|
||||
modifs = [] # liste d'étudiants modifiés
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
for etudid in etudids:
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
|
||||
@ -1046,7 +1046,7 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
|
||||
def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
|
||||
"""Suppression des decisions de jury pour un etudiant."""
|
||||
log("formsemestre_validation_suppress_etud( %s, %s)" % (formsemestre_id, etudid))
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
args = {"formsemestre_id": formsemestre_id, "etudid": etudid}
|
||||
try:
|
||||
@ -1228,7 +1228,7 @@ def do_formsemestre_validate_previous_ue(
|
||||
cette UE (utile seulement pour les semestres extérieurs).
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > get_etud_ue_status
|
||||
|
@ -51,26 +51,12 @@ from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_core
|
||||
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_permissions import Permission
|
||||
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(
|
||||
groupName,
|
||||
): # 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
|
||||
"""legacy code: used by group_list and trombino"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
cnx = ndb.GetDBConnexion()
|
||||
group = get_group(context, group_id)
|
||||
sem = sco_formsemestre.get_formsemestre(context, group["formsemestre_id"])
|
||||
@ -446,13 +434,15 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
|
||||
<etud etuid="" sexe="" nom="" prenom="" origin=""/>
|
||||
</groupe>
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
t0 = time.time()
|
||||
partition = get_partition(context, partition_id)
|
||||
formsemestre_id = partition["formsemestre_id"]
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
groups = get_partition_groups(context, partition)
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > inscrdict
|
||||
etuds_set = set(nt.inscrdict)
|
||||
# XML response:
|
||||
@ -605,7 +595,9 @@ def change_etud_group_in_partition(
|
||||
)
|
||||
cnx.commit()
|
||||
# 4- invalidate cache
|
||||
context.Notes._inval_cache(formsemestre_id=formsemestre_id) # > change etud group
|
||||
sco_core.inval_cache(
|
||||
context, formsemestre_id=formsemestre_id
|
||||
) # > change etud group
|
||||
|
||||
|
||||
def setGroups(
|
||||
@ -621,9 +613,11 @@ def setGroups(
|
||||
groupsToCreate: lignes "group_name;etudid;...\n"
|
||||
groupsToDelete: group_id;group_id;...
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
partition = get_partition(context, partition_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 !")
|
||||
log("***setGroups: partition_id=%s" % partition_id)
|
||||
log("groupsLists=%s" % groupsLists)
|
||||
@ -710,7 +704,9 @@ def createGroup(context, partition_id, group_name="", default=False, REQUEST=Non
|
||||
"""
|
||||
partition = get_partition(context, partition_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 !")
|
||||
#
|
||||
if group_name:
|
||||
@ -747,7 +743,9 @@ def suppressGroup(context, group_id, partition_id=None, REQUEST=None):
|
||||
else:
|
||||
partition_id = group["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 !")
|
||||
log(
|
||||
"suppressGroup: group_id=%s group_name=%s partition_name=%s"
|
||||
@ -766,7 +764,9 @@ def partition_create(
|
||||
redirect=1,
|
||||
):
|
||||
"""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 !")
|
||||
if partition_name:
|
||||
partition_name = partition_name.strip()
|
||||
@ -810,7 +810,7 @@ def getArrowIconsTags(context, REQUEST):
|
||||
def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
|
||||
"""Form to create/suppress partitions"""
|
||||
# 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 !")
|
||||
partitions = get_partitions_list(context, formsemestre_id)
|
||||
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
|
||||
@ -940,7 +940,7 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
|
||||
|
||||
partition = get_partition(context, partition_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 !")
|
||||
|
||||
log("partition_set_attr(%s, %s, %s)" % (partition_id, attr, value))
|
||||
@ -950,8 +950,8 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
|
||||
partition[attr] = value
|
||||
partitionEditor.edit(cnx, partition)
|
||||
# invalid bulletin cache
|
||||
context.Notes._inval_cache(
|
||||
pdfonly=True, formsemestre_id=partition["formsemestre_id"]
|
||||
sco_core.inval_cache(
|
||||
context, pdfonly=True, formsemestre_id=partition["formsemestre_id"]
|
||||
)
|
||||
return "enregistré"
|
||||
|
||||
@ -963,7 +963,7 @@ def partition_delete(
|
||||
default partition cannot be suppressed (unless force)"""
|
||||
partition = get_partition(context, partition_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 !")
|
||||
|
||||
if not partition["partition_name"] and not force:
|
||||
@ -1007,7 +1007,7 @@ def partition_move(context, partition_id, after=0, REQUEST=None, redirect=1):
|
||||
"""Move before/after previous one (decrement/increment numero)"""
|
||||
partition = get_partition(context, partition_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 !")
|
||||
#
|
||||
redirect = int(redirect)
|
||||
@ -1042,7 +1042,7 @@ def partition_rename(context, partition_id, REQUEST=None):
|
||||
"""Form to rename a partition"""
|
||||
partition = get_partition(context, partition_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 !")
|
||||
H = ["<h2>Renommer une partition</h2>"]
|
||||
tf = TrivialFormulator(
|
||||
@ -1103,7 +1103,7 @@ def partition_set_name(context, partition_id, partition_name, REQUEST=None, redi
|
||||
"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 !")
|
||||
redirect = int(redirect)
|
||||
cnx = ndb.GetDBConnexion()
|
||||
@ -1128,7 +1128,7 @@ def group_set_name(context, group_id, group_name, REQUEST=None, redirect=1):
|
||||
if group["group_name"] is None:
|
||||
raise ValueError("can't set a name to default group")
|
||||
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 !")
|
||||
redirect = int(redirect)
|
||||
cnx = ndb.GetDBConnexion()
|
||||
@ -1145,7 +1145,7 @@ def group_rename(context, group_id, REQUEST=None):
|
||||
"""Form to rename a group"""
|
||||
group = get_group(context, group_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 !")
|
||||
H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]]
|
||||
tf = TrivialFormulator(
|
||||
@ -1189,11 +1189,13 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
|
||||
"""Reparti les etudiants dans des groupes dans une partition, en respectant le niveau
|
||||
et la mixité.
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
partition = get_partition(context, partition_id)
|
||||
formsemestre_id = partition["formsemestre_id"]
|
||||
# renvoie sur page édition groupes
|
||||
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 !")
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
|
||||
@ -1261,8 +1263,8 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
|
||||
createGroup(context, partition_id, group_name, REQUEST=REQUEST)
|
||||
)
|
||||
#
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > identdict
|
||||
identdict = nt.identdict
|
||||
# build: { civilite : liste etudids trie par niveau croissant }
|
||||
@ -1270,7 +1272,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
|
||||
listes = {}
|
||||
for civilite in civilites:
|
||||
listes[civilite] = [
|
||||
(get_prev_moy(context.Notes, x["etudid"], formsemestre_id), x["etudid"])
|
||||
(get_prev_moy(context, x["etudid"], formsemestre_id), x["etudid"])
|
||||
for x in identdict.values()
|
||||
if x["civilite"] == civilite
|
||||
]
|
||||
@ -1474,6 +1476,8 @@ def form_group_choice(
|
||||
"""Partie de formulaire pour le choix d'un ou plusieurs groupes.
|
||||
Variable : group_ids
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if display_sem_title:
|
||||
sem_title = "%s: " % sem["titremois"]
|
||||
|
@ -40,7 +40,9 @@ def affectGroups(context, partition_id, REQUEST=None):
|
||||
# Ported from DTML and adapted to new group management (nov 2009)
|
||||
partition = sco_groups.get_partition(context, partition_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")
|
||||
|
||||
H = [
|
||||
|
@ -791,10 +791,10 @@ def groups_table(
|
||||
sco_etud.etud_add_lycee_infos(etud)
|
||||
# et ajoute le parcours
|
||||
Se = sco_parcours_dut.SituationEtudParcours(
|
||||
context.Notes, etud, groups_infos.formsemestre_id
|
||||
context, etud, groups_infos.formsemestre_id
|
||||
)
|
||||
m["parcours"] = Se.get_parcours_descr()
|
||||
m["codeparcours"], _ = sco_report.get_codeparcoursetud(context.Notes, etud)
|
||||
m["codeparcours"], _ = sco_report.get_codeparcoursetud(context, etud)
|
||||
|
||||
def dicttakestr(d, keys):
|
||||
r = []
|
||||
|
@ -53,6 +53,7 @@ from app.scodoc.sco_exceptions import (
|
||||
ScoGenError,
|
||||
)
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_groups
|
||||
@ -231,7 +232,7 @@ def students_import_excel(
|
||||
"import students from Excel file"
|
||||
diag = scolars_import_excel_file(
|
||||
csvfile,
|
||||
context.Notes,
|
||||
context,
|
||||
REQUEST,
|
||||
formsemestre_id=formsemestre_id,
|
||||
check_homonyms=check_homonyms,
|
||||
@ -268,7 +269,7 @@ def scolars_import_excel_file(
|
||||
et les inscrit dans le semestre indiqué (et à TOUS ses modules)
|
||||
"""
|
||||
log("scolars_import_excel_file: formsemestre_id=%s" % formsemestre_id)
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
annee_courante = time.localtime()[0]
|
||||
always_require_ine = sco_preferences.get_preference(context, "always_require_ine")
|
||||
@ -489,11 +490,40 @@ def scolars_import_excel_file(
|
||||
cnx.commit()
|
||||
|
||||
# Invalide les caches des semestres dans lesquels on a inscrit des etudiants:
|
||||
context.Notes._inval_cache(formsemestre_id_list=formsemestre_to_invalidate)
|
||||
sco_core.inval_cache(context, formsemestre_id_list=formsemestre_to_invalidate)
|
||||
|
||||
return diag
|
||||
|
||||
|
||||
def students_import_admission(
|
||||
context, csvfile, type_admission="", REQUEST=None, formsemestre_id=None
|
||||
):
|
||||
"import donnees admission from Excel file (v2016)"
|
||||
diag = scolars_import_admission(
|
||||
csvfile,
|
||||
context,
|
||||
REQUEST,
|
||||
formsemestre_id=formsemestre_id,
|
||||
type_admission=type_admission,
|
||||
)
|
||||
if REQUEST:
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
context, REQUEST, page_title="Import données admissions"
|
||||
)
|
||||
]
|
||||
H.append("<p>Import terminé !</p>")
|
||||
H.append(
|
||||
'<p><a class="stdlink" href="%s">Continuer</a></p>'
|
||||
% "formsemestre_status?formsemestre_id=%s"
|
||||
% formsemestre_id
|
||||
)
|
||||
if diag:
|
||||
H.append("<p>Diagnostic: <ul><li>%s</li></ul></p>" % "</li><li>".join(diag))
|
||||
|
||||
return "\n".join(H) + html_sco_header.sco_footer(REQUEST)
|
||||
|
||||
|
||||
def _import_one_student(
|
||||
context,
|
||||
cnx,
|
@ -31,7 +31,7 @@ from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.header import Header
|
||||
|
||||
from app.scodoc import mails
|
||||
from app.scodoc import sco_emails
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoException
|
||||
@ -228,4 +228,4 @@ Pour plus d'informations sur ce logiciel, voir %s
|
||||
msg.epilogue = ""
|
||||
txt = MIMEText(txt, "plain", scu.SCO_ENCODING)
|
||||
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 }
|
||||
"""
|
||||
if not with_dems:
|
||||
ins = context.Notes.do_formsemestre_inscription_listinscrits(
|
||||
formsemestre_id
|
||||
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||
context, formsemestre_id
|
||||
) # optimized
|
||||
else:
|
||||
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):
|
||||
log("do_desinscrit: %s" % etudids)
|
||||
for etudid in etudids:
|
||||
context.do_formsemestre_desinscription(
|
||||
etudid, sem["formsemestre_id"], REQUEST=REQUEST
|
||||
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
|
||||
context, etudid, sem["formsemestre_id"], REQUEST=REQUEST
|
||||
)
|
||||
|
||||
|
||||
|
@ -91,7 +91,9 @@ def moduleimpl_inscriptions_edit(
|
||||
% (moduleimpl_id, mod["titre"], mod["code"]),
|
||||
]
|
||||
# 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:
|
||||
etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
|
||||
if not etuds_info:
|
||||
|
@ -40,7 +40,7 @@ import PyRSS2Gen # pylint: disable=import-error
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
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 import sco_formsemestre
|
||||
from app.scodoc import sco_moduleimpl
|
||||
@ -301,4 +301,4 @@ def _send_news_by_mail(context, n):
|
||||
del msg["To"]
|
||||
msg["To"] = email_addr
|
||||
# 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":
|
||||
dem_title = "Démission"
|
||||
dem_url = "formDem"
|
||||
dem_url = "scolar.formDem"
|
||||
else:
|
||||
dem_title = "Annuler la démission"
|
||||
dem_url = "doCancelDem"
|
||||
dem_url = "scolar.doCancelDem"
|
||||
|
||||
# Note: seul un etudiant inscrit (I) peut devenir défaillant.
|
||||
if ins["etat"] != sco_codes_parcours.DEF:
|
||||
def_title = "Déclarer défaillance"
|
||||
def_url = "formDef"
|
||||
def_url = "scolar.formDef"
|
||||
elif ins["etat"] == sco_codes_parcours.DEF:
|
||||
def_title = "Annuler la défaillance"
|
||||
def_url = "doCancelDef"
|
||||
def_url = "scolar.doCancelDef"
|
||||
def_enabled = (
|
||||
(ins["etat"] != "D")
|
||||
and authuser.has_permission(Permission.ScoEtudInscrit)
|
||||
@ -211,7 +211,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
|
||||
for sem in info["sems"]:
|
||||
if sem["ins"]["etat"] != "I":
|
||||
descr, _ = etud_descr_situation_semestre(
|
||||
context.Notes,
|
||||
context,
|
||||
etudid,
|
||||
sem["formsemestre_id"],
|
||||
info["ne"],
|
||||
@ -239,10 +239,10 @@ def ficheEtud(context, etudid=None, REQUEST=None):
|
||||
|
||||
if info["sems"]:
|
||||
Se = sco_parcours_dut.SituationEtudParcours(
|
||||
context.Notes, etud, info["last_formsemestre_id"]
|
||||
context, etud, info["last_formsemestre_id"]
|
||||
)
|
||||
info["liste_inscriptions"] = formsemestre_recap_parcours_table(
|
||||
context.Notes,
|
||||
context,
|
||||
Se,
|
||||
etudid,
|
||||
with_links=False,
|
||||
@ -535,7 +535,7 @@ def etud_info_html(context, etudid, with_photo="1", REQUEST=None, debug=False):
|
||||
Used for popups information windows.
|
||||
"""
|
||||
try:
|
||||
context = context.Notes
|
||||
context = context
|
||||
except:
|
||||
pass
|
||||
# log('etud_info_html: %s' % REQUEST.QUERY_STRING)
|
||||
@ -551,7 +551,7 @@ def etud_info_html(context, etudid, with_photo="1", REQUEST=None, debug=False):
|
||||
)
|
||||
# experimental: may be too slow to be here
|
||||
etud["codeparcours"], etud["decisions_jury"] = sco_report.get_codeparcoursetud(
|
||||
context.Notes, etud, prefix="S", separator=", "
|
||||
context, etud, prefix="S", separator=", "
|
||||
)
|
||||
|
||||
bac = sco_bac.Baccalaureat(etud["bac"], etud["specialite"])
|
||||
|
@ -543,7 +543,7 @@ class SituationEtudParcoursGeneric:
|
||||
"""Enregistre la decision (instance de DecisionSem)
|
||||
Enregistre codes semestre et UE, et autorisations inscription.
|
||||
"""
|
||||
cnx = self.context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
# -- check
|
||||
if decision.code_etat in self.parcours.UNUSED_CODES:
|
||||
raise ScoValueError("code decision invalide dans ce parcours")
|
||||
@ -909,7 +909,7 @@ def formsemestre_validate_ues(
|
||||
Les UE des semestres NON ASSIDUS ne sont jamais validées (code AJ).
|
||||
"""
|
||||
valid_semestre = CODES_SEM_VALIDES.get(code_etat_sem, False)
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > get_ues, get_etud_ue_status
|
||||
|
@ -9,9 +9,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_exceptions
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_moduleimpl
|
||||
from app.scodoc import sco_parcours_dut
|
||||
|
||||
|
||||
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,
|
||||
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)
|
||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
"""True if current user can suppress this annotation
|
||||
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 !")
|
||||
anno = annos[0]
|
||||
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 (
|
||||
(str(authuser) == anno["zope_authenticated_user"])
|
||||
or authuser.has_permission(Permission.ScoEtudSupprAnnotations)
|
||||
or authuser.has_permission(Permission.ScoEtudInscrit)
|
||||
)
|
||||
str(authuser) == anno["zope_authenticated_user"]
|
||||
) or authuser.has_permission(Permission.ScoEtudAddAnnotations)
|
||||
|
||||
|
||||
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):
|
||||
"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)
|
||||
if sem["etat"] != "1":
|
||||
return False # semestre verrouillé
|
||||
@ -86,6 +118,7 @@ def can_validate_sem(context, REQUEST, formsemestre_id):
|
||||
|
||||
def can_edit_pv(context, REQUEST, formsemestre_id):
|
||||
"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)
|
||||
if is_chef_or_diretud(context, REQUEST, sem):
|
||||
@ -114,6 +147,8 @@ def check_access_diretud(
|
||||
"""Check if access granted: responsable or ScoImplement
|
||||
Return True|False, HTML_error_page
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
header = html_sco_header.sco_header(
|
||||
@ -137,3 +172,19 @@ def check_access_diretud(
|
||||
)
|
||||
else:
|
||||
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
|
||||
|
@ -112,11 +112,12 @@ get_base_preferences(context, formsemestre_id)
|
||||
"""
|
||||
from flask import g
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.sco_exceptions import ScoValueError, ScoException
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
import app.scodoc.notesdb as ndb
|
||||
import app.scodoc.sco_utils as scu
|
||||
|
||||
_SCO_BASE_PREFERENCES = {} # { URL: BasePreferences instance }
|
||||
|
||||
@ -1919,7 +1920,7 @@ class BasePreferences(object):
|
||||
|
||||
# les preferences peuvent affecter les PDF cachés et les notes calculées:
|
||||
if modif:
|
||||
self.context.Notes._inval_cache(pdfonly=False) # > modif preferences
|
||||
sco_core.inval_cache(self.context, pdfonly=False) # > modif preferences
|
||||
finally:
|
||||
scu.GSL.release()
|
||||
|
||||
@ -1947,7 +1948,7 @@ class BasePreferences(object):
|
||||
if pdb:
|
||||
log("deleting pref sem=%s %s" % (formsemestre_id, name))
|
||||
self._editor.delete(cnx, pdb[0]["pref_id"])
|
||||
self.context.Notes._inval_cache(pdfonly=False) # > modif preferences
|
||||
sco_core.inval_cache(self.context, pdfonly=False) # > modif preferences
|
||||
finally:
|
||||
scu.GSL.release()
|
||||
|
||||
@ -2091,7 +2092,9 @@ class SemPreferences(object):
|
||||
) # a bug !
|
||||
sem = sco_formsemestre.get_formsemestre(self.context, self.formsemestre_id)
|
||||
H = [
|
||||
self.context.Notes.html_sem_header(REQUEST, "Préférences du semestre", sem),
|
||||
html_sco_header.html_sem_header(
|
||||
self.context, REQUEST, "Préférences du semestre", sem
|
||||
),
|
||||
"""
|
||||
<p class="help">Les paramètres définis ici ne s'appliqueront qu'à ce semestre.</p>
|
||||
<p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p>
|
||||
|
@ -46,6 +46,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import htmlutils
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_edit_module
|
||||
from app.scodoc import sco_evaluations
|
||||
@ -471,7 +472,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
|
||||
# Recherche notes existantes
|
||||
NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
|
||||
# Met a jour la base
|
||||
cnx = context.GetDBConnexion(autocommit=False)
|
||||
cnx = ndb.GetDBConnexion(autocommit=False)
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
nb_changed = 0
|
||||
nb_suppress = 0
|
||||
|
@ -50,7 +50,7 @@ from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_pdf import SU
|
||||
from app.scodoc import html_sco_header
|
||||
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_formsemestre
|
||||
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
|
||||
def photos_generate_excel_sample(context, group_ids=[], REQUEST=None):
|
||||
"""Feuille excel pour import fichiers photos"""
|
||||
fmt = ImportScolars.sco_import_format()
|
||||
data = ImportScolars.sco_import_generate_excel_sample(
|
||||
fmt = sco_import_etuds.sco_import_format()
|
||||
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||
fmt,
|
||||
context=context,
|
||||
group_ids=group_ids,
|
||||
|
@ -164,7 +164,7 @@ def external_ue_inscrit_et_note(
|
||||
evaluation_id = ModEvals[0]["evaluation_id"]
|
||||
else:
|
||||
# crée une évaluation:
|
||||
evaluation_id = context.do_evaluation_create(
|
||||
evaluation_id = sco_evaluations.do_evaluation_create(context,
|
||||
REQUEST=REQUEST,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
note_max=20.0,
|
||||
|
@ -385,6 +385,15 @@ def UsersURL():
|
||||
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
|
||||
|
||||
|
||||
|
@ -10,4 +10,4 @@ essais_bp = Blueprint("essais", __name__)
|
||||
|
||||
from app.views import notes, scolar, absences, essais
|
||||
|
||||
scolar.context.Notes = notes.context
|
||||
scolar.context.Notes = notes.context # XXX transitoire #sco8
|
||||
|
@ -81,8 +81,10 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc import html_sco_header
|
||||
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_core
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_excel
|
||||
from app.scodoc import sco_formsemestre
|
||||
@ -238,7 +240,7 @@ def SignaleAbsenceGrHebdo(
|
||||
[
|
||||
x["etudid"]
|
||||
for x in sco_moduleimpl.do_moduleimpl_inscription_list(
|
||||
context.Notes, moduleimpl_id=moduleimpl_id
|
||||
context, moduleimpl_id=moduleimpl_id
|
||||
)
|
||||
]
|
||||
)
|
||||
@ -248,7 +250,7 @@ def SignaleAbsenceGrHebdo(
|
||||
else:
|
||||
# Si aucun etudiant n'est inscrit au module choisi...
|
||||
moduleimpl_id = None
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id)
|
||||
sem = sco_formsemestre.do_formsemestre_list(
|
||||
context, {"formsemestre_id": formsemestre_id}
|
||||
)[0]
|
||||
@ -402,7 +404,7 @@ def SignaleAbsenceGrSemestre(
|
||||
[
|
||||
x["etudid"]
|
||||
for x in sco_moduleimpl.do_moduleimpl_inscription_list(
|
||||
context.Notes, moduleimpl_id=moduleimpl_id
|
||||
context, moduleimpl_id=moduleimpl_id
|
||||
)
|
||||
]
|
||||
)
|
||||
@ -421,9 +423,7 @@ def SignaleAbsenceGrSemestre(
|
||||
base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id
|
||||
|
||||
if etuds:
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, formsemestre_id
|
||||
)
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id)
|
||||
sem = sco_formsemestre.do_formsemestre_list(
|
||||
context, {"formsemestre_id": formsemestre_id}
|
||||
)[0]
|
||||
@ -638,8 +638,8 @@ def _gen_form_saisie_groupe(
|
||||
# UE capitalisee dans semestre courant ?
|
||||
cap = []
|
||||
if etud["cursem"]:
|
||||
nt = context.Notes._getNotesCache().get_NotesTable(
|
||||
context.Notes, etud["cursem"]["formsemestre_id"]
|
||||
nt = sco_core.get_notes_cache(context).get_NotesTable(
|
||||
context, etud["cursem"]["formsemestre_id"]
|
||||
) # > get_ues, get_etud_ue_status
|
||||
for ue in nt.get_ues():
|
||||
status = nt.get_etud_ue_status(etudid, ue["ue_id"])
|
||||
@ -765,8 +765,8 @@ def EtatAbsencesGr(
|
||||
nbabs = sco_abs.CountAbs(
|
||||
context, etudid=etud["etudid"], debut=datedebut, fin=datefin
|
||||
)
|
||||
nbabsjust = context.CountAbsJust(
|
||||
etudid=etud["etudid"], debut=datedebut, fin=datefin
|
||||
nbabsjust = sco_abs.CountAbsJust(
|
||||
context, etudid=etud["etudid"], debut=datedebut, fin=datefin
|
||||
)
|
||||
nbjustifs_noabs = len(
|
||||
sco_abs.ListeJustifs(
|
||||
@ -846,8 +846,8 @@ def EtatAbsencesGr(
|
||||
init_qtip=True,
|
||||
javascripts=["js/etud_info.js"],
|
||||
),
|
||||
html_title=context.Notes.html_sem_header(
|
||||
REQUEST, "%s" % title, sem, with_page_header=False
|
||||
html_title=html_sco_header.html_sem_header(
|
||||
context, REQUEST, "%s" % title, sem, with_page_header=False
|
||||
)
|
||||
+ "<p>Période du %s au %s (nombre de <b>demi-journées</b>)<br/>" % (debut, fin),
|
||||
base_url="%s&formsemestre_id=%s&debut=%s&fin=%s"
|
||||
@ -918,11 +918,11 @@ def EtatAbsencesDate(
|
||||
)
|
||||
if (nbabsam != 0) or (nbabspm != 0):
|
||||
nbetud += 1
|
||||
nbabsjustam = context.CountAbsJust(
|
||||
etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1
|
||||
nbabsjustam = sco_abs.CountAbsJust(
|
||||
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1
|
||||
)
|
||||
nbabsjustpm = context.CountAbsJust(
|
||||
etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0
|
||||
nbabsjustpm = sco_abs.CountAbsJust(
|
||||
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0
|
||||
)
|
||||
H.append(
|
||||
"""<tr bgcolor="#FFFFFF"><td>
|
||||
@ -1210,7 +1210,8 @@ def deleteBilletAbsence(context, billet_id, REQUEST=None, dialog_confirmed=False
|
||||
)
|
||||
if not dialog_confirmed:
|
||||
tab = _tableBillets(context, billets)
|
||||
return context.confirmDialog(
|
||||
return scu.confirm_dialog(
|
||||
context,
|
||||
"""<h2>Supprimer ce billet ?</h2>""" + tab.html(),
|
||||
dest_url="",
|
||||
REQUEST=REQUEST,
|
||||
|
@ -73,7 +73,7 @@ def sidebar(context, REQUEST):
|
||||
"barre gauche (overide std sco sidebar)"
|
||||
# rewritten from legacy DTML code
|
||||
# XXX rare cas restant d'utilisation de l'acquisition Zope2: à revoir
|
||||
params = {"ScoURL": context.ScoURL()}
|
||||
params = {"ScoURL": scu.ScoURL()}
|
||||
H = [
|
||||
"""<div id="sidebar-container">
|
||||
<div class="sidebar">""",
|
||||
@ -285,7 +285,7 @@ def entreprise_contact_list(context, entreprise_id=None, format="html", REQUEST=
|
||||
c["etud"] = context.getEtudInfo(etudid=c["etudid"], filled=1)[0]
|
||||
c["etudnom"] = c["etud"]["nomprenom"]
|
||||
c["_etudnom_target"] = "%s/ficheEtud?etudid=%s" % (
|
||||
context.ScoURL(),
|
||||
scu.ScoURL(),
|
||||
c["etudid"],
|
||||
)
|
||||
else:
|
||||
@ -1012,7 +1012,7 @@ def entreprise_delete(context, entreprise_id, REQUEST=None):
|
||||
for c in Cts:
|
||||
H.append("""<li>%(date)s %(description)s</li>""" % c)
|
||||
H.append("""</ul>""")
|
||||
tf = context.TrivialFormulator(
|
||||
tf = TrivialFormulator(
|
||||
REQUEST.URL0,
|
||||
REQUEST.form,
|
||||
(("entreprise_id", {"input_type": "hidden"}),),
|
||||
@ -1290,7 +1290,7 @@ def entreprise_edit(context, entreprise_id, REQUEST=None, start=1):
|
||||
etud = etud[0]
|
||||
H.append(
|
||||
"""<a href="%s/ficheEtud?etudid=%s">%s</a>"""
|
||||
% (context.ScoURL(), c["etudid"], etud["nomprenom"])
|
||||
% (scu.ScoURL(), c["etudid"], etud["nomprenom"])
|
||||
)
|
||||
if c["description"]:
|
||||
H.append("(%s)" % c["description"])
|
||||
|
@ -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" )
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple2")
|
||||
@login_required
|
||||
|
@ -486,33 +486,11 @@ def formation_import_xml_form(context, REQUEST):
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/formation_create_new_version")
|
||||
@permission_required(Permission.ScoChangeFormation)
|
||||
@scodoc7func(context)
|
||||
def formation_create_new_version(context, formation_id, redirect=True, REQUEST=None):
|
||||
"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
|
||||
|
||||
sco_publish(
|
||||
"/formation_create_new_version",
|
||||
sco_formations.formation_create_new_version,
|
||||
Permission.ScoChangeFormation,
|
||||
)
|
||||
|
||||
# --- UE
|
||||
sco_publish(
|
||||
@ -579,42 +557,6 @@ sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormatio
|
||||
|
||||
|
||||
# --- 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")
|
||||
@ -905,7 +847,7 @@ def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
|
||||
)
|
||||
|
||||
|
||||
_expr_help = """<p class="help">Expérimental: formule de calcul de la moyenne %(target)s</p>
|
||||
_EXPR_HELP = """<p class="help">Expérimental: formule de calcul de la moyenne %(target)s</p>
|
||||
<p class="help">Attention: l'utilisation de formules ralenti considérablement
|
||||
les traitements. A utiliser uniquement dans els cas ne pouvant pas être traités autrement.</p>
|
||||
<p class="help">Dans la formule, les variables suivantes sont définies:</p>
|
||||
@ -943,7 +885,7 @@ def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
|
||||
% (moduleimpl_id, M["module"]["titre"]),
|
||||
sem,
|
||||
),
|
||||
context._expr_help
|
||||
_EXPR_HELP
|
||||
% {
|
||||
"target": "du module",
|
||||
"objs": "évaluations",
|
||||
@ -1099,7 +1041,7 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
|
||||
% (ue["acronyme"], ue["titre"]),
|
||||
sem,
|
||||
),
|
||||
context._expr_help % {"target": "de l'UE", "objs": "modules", "ordre": ""},
|
||||
_EXPR_HELP % {"target": "de l'UE", "objs": "modules", "ordre": ""},
|
||||
]
|
||||
el = sco_compute_moy.formsemestre_ue_computation_expr_list(
|
||||
cnx, {"formsemestre_id": formsemestre_id, "ue_id": ue_id}
|
||||
@ -1285,14 +1227,9 @@ def do_formsemestre_inscription_listinscrits(
|
||||
context, formsemestre_id, format=None, REQUEST=None
|
||||
):
|
||||
"""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 = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
||||
context, args={"formsemestre_id": formsemestre_id, "etat": "I"}
|
||||
)
|
||||
cache.set(formsemestre_id, r)
|
||||
r = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
|
||||
context, formsemestre_id
|
||||
)
|
||||
return scu.sendResult(REQUEST, r, format=format, name="inscrits")
|
||||
|
||||
|
||||
@ -1365,7 +1302,9 @@ def formsemestre_desinscription(
|
||||
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 (
|
||||
html_sco_header.sco_header(context, REQUEST)
|
||||
@ -1458,170 +1397,6 @@ sco_publish(
|
||||
# --- 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")
|
||||
@permission_required(Permission.ScoEnsView)
|
||||
@scodoc7func(context)
|
||||
@ -1861,6 +1636,7 @@ def formsemestre_bulletins_mailetuds_choice(
|
||||
):
|
||||
"""Choix version puis envois classeur bulletins pdf"""
|
||||
if version:
|
||||
# XXX devrait plutôt utiliser un redirect #sco8
|
||||
return context.formsemestre_bulletins_mailetuds(
|
||||
formsemestre_id,
|
||||
REQUEST,
|
||||
@ -2676,10 +2452,10 @@ def check_integrity_all(context, REQUEST=None):
|
||||
for F in sco_formations.formation_list(
|
||||
context,
|
||||
):
|
||||
context.check_form_integrity(F["formation_id"], REQUEST=REQUEST)
|
||||
check_form_integrity(context, F["formation_id"], REQUEST=REQUEST)
|
||||
# semestres
|
||||
for sem in sco_formsemestre.do_formsemestre_list(context):
|
||||
context.check_formsemestre_integrity(sem["formsemestre_id"], REQUEST=REQUEST)
|
||||
check_formsemestre_integrity(context, sem["formsemestre_id"], REQUEST=REQUEST)
|
||||
return (
|
||||
html_sco_header.sco_header(context, REQUEST=REQUEST)
|
||||
+ "<p>empty page: see logs and mails</p>"
|
||||
|
@ -85,10 +85,11 @@ from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import html_sidebar
|
||||
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_archives_etud
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_core
|
||||
from app.scodoc import sco_debouche
|
||||
from app.scodoc import sco_dept
|
||||
from app.scodoc import sco_dump_db
|
||||
@ -197,7 +198,7 @@ def edit_preferences(context, REQUEST):
|
||||
def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
|
||||
"""Edit preferences for a semestre"""
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
sem = sco_formsemestre.get_formsemestre(context.Notes, formsemestre_id)
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
ok = (
|
||||
authuser.has_permission(Permission.ScoImplement)
|
||||
or ((str(authuser) in sem["responsables"]) and sem["resp_can_edit"])
|
||||
@ -756,7 +757,8 @@ def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False
|
||||
@scodoc7func(context)
|
||||
def formDem(context, etudid, formsemestre_id, REQUEST):
|
||||
"Formulaire Démission Etudiant"
|
||||
return context._formDem_of_Def(
|
||||
return _formDem_of_Def(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
REQUEST=REQUEST,
|
||||
@ -770,7 +772,8 @@ def formDem(context, etudid, formsemestre_id, REQUEST):
|
||||
@scodoc7func(context)
|
||||
def formDef(context, etudid, formsemestre_id, REQUEST):
|
||||
"Formulaire Défaillance Etudiant"
|
||||
return context._formDem_of_Def(
|
||||
return _formDem_of_Def(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
REQUEST=REQUEST,
|
||||
@ -832,7 +835,8 @@ def _formDem_of_Def(
|
||||
@scodoc7func(context)
|
||||
def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
|
||||
"Déclare la démission d'un etudiant dans le semestre"
|
||||
return context._doDem_or_Def_Etudiant(
|
||||
return _do_dem_or_def_etud(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
event_date=event_date,
|
||||
@ -848,7 +852,8 @@ def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=Non
|
||||
@scodoc7func(context)
|
||||
def doDefEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
|
||||
"Déclare la défaillance d'un etudiant dans le semestre"
|
||||
return context._doDem_or_Def_Etudiant(
|
||||
return _do_dem_or_def_etud(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
event_date=event_date,
|
||||
@ -859,7 +864,7 @@ def doDefEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=Non
|
||||
)
|
||||
|
||||
|
||||
def _doDem_or_Def_Etudiant(
|
||||
def _do_dem_or_def_etud(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
@ -908,7 +913,8 @@ def doCancelDem(
|
||||
context, etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
|
||||
):
|
||||
"Annule une démission"
|
||||
return context._doCancelDem_or_Def(
|
||||
return _do_cancel_dem_or_def(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
dialog_confirmed=dialog_confirmed,
|
||||
@ -929,7 +935,8 @@ def doCancelDef(
|
||||
context, etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
|
||||
):
|
||||
"Annule la défaillance de l'étudiant"
|
||||
return context._doCancelDem_or_Def(
|
||||
return _do_cancel_dem_or_def(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
dialog_confirmed=dialog_confirmed,
|
||||
@ -943,7 +950,7 @@ def doCancelDef(
|
||||
)
|
||||
|
||||
|
||||
def _doCancelDem_or_Def(
|
||||
def _do_cancel_dem_or_def(
|
||||
context,
|
||||
etudid,
|
||||
formsemestre_id,
|
||||
@ -1009,7 +1016,7 @@ def _doCancelDem_or_Def(
|
||||
@scodoc7func(context)
|
||||
def etudident_create_form(context, REQUEST=None):
|
||||
"formulaire creation individuelle etudiant"
|
||||
return context._etudident_create_or_edit_form(REQUEST, edit=False)
|
||||
return _etudident_create_or_edit_form(context, REQUEST, edit=False)
|
||||
|
||||
|
||||
@bp.route("/etudident_edit_form")
|
||||
@ -1017,7 +1024,7 @@ def etudident_create_form(context, REQUEST=None):
|
||||
@scodoc7func(context)
|
||||
def etudident_edit_form(context, REQUEST=None):
|
||||
"formulaire edition individuelle etudiant"
|
||||
return context._etudident_create_or_edit_form(REQUEST, edit=True)
|
||||
return _etudident_create_or_edit_form(context, REQUEST, edit=True)
|
||||
|
||||
|
||||
def _etudident_create_or_edit_form(context, REQUEST, edit):
|
||||
@ -1411,8 +1418,8 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
|
||||
# Inval semesters with this student:
|
||||
to_inval = [s["formsemestre_id"] for s in etud["sems"]]
|
||||
if to_inval:
|
||||
context.Notes._inval_cache(
|
||||
formsemestre_id_list=to_inval
|
||||
sco_core.inval_cache(
|
||||
context, formsemestre_id_list=to_inval
|
||||
) # > etudident_create_or_edit
|
||||
#
|
||||
return REQUEST.RESPONSE.redirect("ficheEtud?etudid=" + etudid)
|
||||
@ -1476,7 +1483,7 @@ def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
|
||||
# Inval semestres où il était inscrit:
|
||||
to_inval = [s["formsemestre_id"] for s in etud["sems"]]
|
||||
if to_inval:
|
||||
context.Notes._inval_cache(formsemestre_id_list=to_inval) # >
|
||||
sco_core.inval_cache(context, formsemestre_id_list=to_inval) # >
|
||||
return REQUEST.RESPONSE.redirect(
|
||||
scu.ScoURL() + r"?head_message=Etudiant%20supprimé"
|
||||
)
|
||||
@ -1499,8 +1506,11 @@ def check_group_apogee(
|
||||
|
||||
cnx = ndb.GetDBConnexion()
|
||||
H = [
|
||||
context.Notes.html_sem_header(
|
||||
REQUEST, "Etudiants du %s" % (group["group_name"] or "semestre"), sem
|
||||
html_sco_header.html_sem_header(
|
||||
context,
|
||||
REQUEST,
|
||||
"Etudiants du %s" % (group["group_name"] or "semestre"),
|
||||
sem,
|
||||
),
|
||||
'<table class="sortable" id="listegroupe">',
|
||||
"<tr><th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th><th>NIP (ScoDoc)</th><th>Apogée</th></tr>",
|
||||
@ -1628,7 +1638,7 @@ def check_group_apogee(
|
||||
def form_students_import_excel(context, REQUEST, formsemestre_id=None):
|
||||
"formulaire import xls"
|
||||
if formsemestre_id:
|
||||
sem = sco_formsemestre.get_formsemestre(context.Notes, formsemestre_id)
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
dest_url = (
|
||||
scu.ScoURL() + "/formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
||||
)
|
||||
@ -1736,7 +1746,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
|
||||
<table>
|
||||
<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)
|
||||
):
|
||||
if int(t[3]):
|
||||
@ -1752,7 +1762,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
|
||||
elif tf[0] == -1:
|
||||
return REQUEST.RESPONSE.redirect(dest_url)
|
||||
else:
|
||||
return ImportScolars.students_import_excel(
|
||||
return sco_import_etuds.students_import_excel(
|
||||
context,
|
||||
tf[2]["csvfile"],
|
||||
REQUEST=REQUEST,
|
||||
@ -1771,8 +1781,8 @@ def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
|
||||
with_codesemestre = int(with_codesemestre)
|
||||
else:
|
||||
with_codesemestre = 0
|
||||
format = ImportScolars.sco_import_format()
|
||||
data = ImportScolars.sco_import_generate_excel_sample(
|
||||
format = sco_import_etuds.sco_import_format()
|
||||
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||
format, with_codesemestre, exclude_cols=["photo_filename"], REQUEST=REQUEST
|
||||
)
|
||||
return sco_excel.sendExcelFile(REQUEST, data, "ImportEtudiants.xls")
|
||||
@ -1787,13 +1797,13 @@ def import_generate_admission_sample(context, REQUEST, formsemestre_id):
|
||||
group = sco_groups.get_group(
|
||||
context, sco_groups.get_default_group(context, formsemestre_id)
|
||||
)
|
||||
fmt = ImportScolars.sco_import_format()
|
||||
data = ImportScolars.sco_import_generate_excel_sample(
|
||||
fmt = sco_import_etuds.sco_import_format()
|
||||
data = sco_import_etuds.sco_import_generate_excel_sample(
|
||||
fmt,
|
||||
only_tables=["identite", "admissions", "adresse"],
|
||||
exclude_cols=["nationalite", "foto", "photo_filename"],
|
||||
group_ids=[group["group_id"]],
|
||||
context=context.Notes,
|
||||
context=context,
|
||||
REQUEST=REQUEST,
|
||||
)
|
||||
return sco_excel.sendExcelFile(REQUEST, data, "AdmissionEtudiants.xls")
|
||||
@ -1889,7 +1899,7 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
||||
Seule la première feuille du classeur sera utilisée.
|
||||
<div id="adm_table_description_format">
|
||||
"""
|
||||
+ ImportScolars.adm_table_description_format(context).html()
|
||||
+ sco_import_etuds.adm_table_description_format(context).html()
|
||||
+ """</div>"""
|
||||
)
|
||||
|
||||
@ -1900,7 +1910,8 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
||||
scu.ScoURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id
|
||||
)
|
||||
else:
|
||||
return context._students_import_admission(
|
||||
return sco_import_etuds.students_import_admission(
|
||||
context,
|
||||
tf[2]["csvfile"],
|
||||
type_admission=tf[2]["type_admission"],
|
||||
REQUEST=REQUEST,
|
||||
@ -1908,36 +1919,6 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
||||
)
|
||||
|
||||
|
||||
# unpublished
|
||||
def _students_import_admission(
|
||||
context, csvfile, type_admission="", REQUEST=None, formsemestre_id=None
|
||||
):
|
||||
"import donnees admission from Excel file (v2016)"
|
||||
diag = ImportScolars.scolars_import_admission(
|
||||
csvfile,
|
||||
context.Notes,
|
||||
REQUEST,
|
||||
formsemestre_id=formsemestre_id,
|
||||
type_admission=type_admission,
|
||||
)
|
||||
if REQUEST:
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
context, REQUEST, page_title="Import données admissions"
|
||||
)
|
||||
]
|
||||
H.append("<p>Import terminé !</p>")
|
||||
H.append(
|
||||
'<p><a class="stdlink" href="%s">Continuer</a></p>'
|
||||
% "formsemestre_status?formsemestre_id=%s"
|
||||
% formsemestre_id
|
||||
)
|
||||
if diag:
|
||||
H.append("<p>Diagnostic: <ul><li>%s</li></ul></p>" % "</li><li>".join(diag))
|
||||
|
||||
return "\n".join(H) + html_sco_header.sco_footer(REQUEST)
|
||||
|
||||
|
||||
@bp.route("/formsemestre_import_etud_admission")
|
||||
@permission_required(Permission.ScoEtudChangeAdr)
|
||||
@scodoc7func(context)
|
||||
@ -1950,10 +1931,10 @@ def formsemestre_import_etud_admission(
|
||||
unknowns,
|
||||
changed_mails,
|
||||
) = sco_synchro_etuds.formsemestre_import_etud_admission(
|
||||
context.Notes, formsemestre_id, import_identite=True, import_email=import_email
|
||||
context, formsemestre_id, import_identite=True, import_email=import_email
|
||||
)
|
||||
H = [
|
||||
context.Notes.html_sem_header(REQUEST, "Reimport données admission"),
|
||||
html_sco_header.html_sem_header(context, REQUEST, "Reimport données admission"),
|
||||
"<h3>Opération effectuée</h3>",
|
||||
]
|
||||
if no_nip:
|
||||
|
10
refactor.py
Normal file → Executable file
10
refactor.py
Normal file → Executable file
@ -9,7 +9,7 @@
|
||||
|
||||
- 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 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.FunctionType,
|
||||
# types.ClassType,
|
||||
|
Loading…
Reference in New Issue
Block a user