refactoring: élimination de 'context' (très frais, tests en cours).

This commit is contained in:
Emmanuel Viennet 2021-08-21 00:24:51 +02:00
parent 2d7b2547b8
commit 14991a2119
111 changed files with 1384 additions and 2151 deletions

View File

@ -258,7 +258,7 @@ class User(UserMixin, db.Model):
if self.nom:
n = sco_etud.format_nom(self.nom)
else:
n = scu.strupper(self.user_name)
n = self.user_name.upper()
return "%s %s (%s)" % (
n,
sco_etud.format_prenom(self.prenom),

View File

@ -145,122 +145,95 @@ def admin_required(f):
return permission_required(Permission.ScoSuperAdmin)(f)
def scodoc7func(context):
def scodoc7func(func):
"""Décorateur pour intégrer les fonctions Zope 2 de ScoDoc 7.
Ajoute l'argument REQUEST s'il est dans la signature de la fonction.
Les paramètres de la query string deviennent des (keywords) paramètres de la fonction.
"""
def s7_decorator(func):
@wraps(func)
def scodoc7func_decorator(*args, **kwargs):
"""Decorator allowing legacy Zope published methods to be called via Flask
routes without modification.
@wraps(func)
def scodoc7func_decorator(*args, **kwargs):
"""Decorator allowing legacy Zope published methods to be called via Flask
routes without modification.
There are two cases: the function can be called
1. via a Flask route ("top level call")
2. or be called directly from Python.
There are two cases: the function can be called
1. via a Flask route ("top level call")
2. or be called directly from Python.
If called via a route, this decorator setups a REQUEST object (emulating Zope2 REQUEST)
"""
# Détermine si on est appelé via une route ("toplevel")
# ou par un appel de fonction python normal.
top_level = not hasattr(g, "zrequest")
if not top_level:
# ne "redécore" pas
return func(*args, **kwargs)
# --- Emulate Zope's REQUEST
REQUEST = ZRequest()
g.zrequest = REQUEST
req_args = REQUEST.form # args from query string (get) or form (post)
# --- Add positional arguments
pos_arg_values = []
argspec = inspect.getfullargspec(func)
# current_app.logger.info("argspec=%s" % str(argspec))
nb_default_args = len(argspec.defaults) if argspec.defaults else 0
if nb_default_args:
arg_names = argspec.args[:-nb_default_args]
If called via a route, this decorator setups a REQUEST object (emulating Zope2 REQUEST)
"""
# Détermine si on est appelé via une route ("toplevel")
# ou par un appel de fonction python normal.
top_level = not hasattr(g, "zrequest")
if not top_level:
# ne "redécore" pas
return func(*args, **kwargs)
# --- Emulate Zope's REQUEST
REQUEST = ZRequest()
g.zrequest = REQUEST
req_args = REQUEST.form # args from query string (get) or form (post)
# --- Add positional arguments
pos_arg_values = []
argspec = inspect.getfullargspec(func)
# current_app.logger.info("argspec=%s" % str(argspec))
nb_default_args = len(argspec.defaults) if argspec.defaults else 0
if nb_default_args:
arg_names = argspec.args[:-nb_default_args]
else:
arg_names = argspec.args
for arg_name in arg_names:
if arg_name == "REQUEST": # special case
pos_arg_values.append(REQUEST)
else:
arg_names = argspec.args
for arg_name in arg_names:
v = req_args[arg_name]
# try to convert all arguments to INTEGERS
# necessary for db ids and boolean values
try:
v = int(v)
except ValueError:
pass
pos_arg_values.append(v)
# current_app.logger.info("pos_arg_values=%s" % pos_arg_values)
# current_app.logger.info("req_args=%s" % req_args)
# Add keyword arguments
if nb_default_args:
for arg_name in argspec.args[-nb_default_args:]:
if arg_name == "REQUEST": # special case
pos_arg_values.append(REQUEST)
elif arg_name == "context":
pos_arg_values.append(context)
else:
kwargs[arg_name] = REQUEST
elif arg_name in req_args:
# set argument kw optionnel
v = req_args[arg_name]
# try to convert all arguments to INTEGERS
# necessary for db ids and boolean values
try:
v = int(v)
except ValueError:
except (ValueError, TypeError):
pass
pos_arg_values.append(v)
# current_app.logger.info("pos_arg_values=%s" % pos_arg_values)
# current_app.logger.info("req_args=%s" % req_args)
# Add keyword arguments
if nb_default_args:
for arg_name in argspec.args[-nb_default_args:]:
if arg_name == "REQUEST": # special case
kwargs[arg_name] = REQUEST
elif arg_name in req_args:
# set argument kw optionnel
v = req_args[arg_name]
# try to convert all arguments to INTEGERS
# necessary for db ids and boolean values
try:
v = int(v)
except (ValueError, TypeError):
pass
kwargs[arg_name] = v
# current_app.logger.info(
# "scodoc7func_decorator: top_level=%s, pos_arg_values=%s, kwargs=%s"
# % (top_level, pos_arg_values, kwargs)
# )
value = func(*pos_arg_values, **kwargs)
kwargs[arg_name] = v
# current_app.logger.info(
# "scodoc7func_decorator: top_level=%s, pos_arg_values=%s, kwargs=%s"
# % (top_level, pos_arg_values, kwargs)
# )
value = func(*pos_arg_values, **kwargs)
if not top_level:
return value
else:
if isinstance(value, werkzeug.wrappers.response.Response):
return value # redirected
# Build response, adding collected http headers:
headers = []
kw = {"response": value, "status": 200}
if g.zrequest:
headers = g.zrequest.RESPONSE.headers
if not headers:
# no customized header, speedup:
return value
if "content-type" in headers:
kw["mimetype"] = headers["content-type"]
r = flask.Response(**kw)
for h in headers:
r.headers[h] = headers[h]
return r
if not top_level:
return value
else:
if isinstance(value, werkzeug.wrappers.response.Response):
return value # redirected
# Build response, adding collected http headers:
headers = []
kw = {"response": value, "status": 200}
if g.zrequest:
headers = g.zrequest.RESPONSE.headers
if not headers:
# no customized header, speedup:
return value
if "content-type" in headers:
kw["mimetype"] = headers["content-type"]
r = flask.Response(**kw)
for h in headers:
r.headers[h] = headers[h]
return r
return scodoc7func_decorator
return s7_decorator
# Le "context" de ScoDoc7
class ScoDoc7Context(object):
"""Context object for legacy Zope methods.
Mainly used to call published methods, as context.function(...)
"""
def __init__(self, name=""):
self.name = name
# logging.getLogger(__name__).info("created %s" % self)
def populate(self, globals_dict):
# logging.getLogger(__name__).info("populating context %s" % self)
for k in globals_dict:
if (not k.startswith("_")) and (
isinstance(globals_dict[k], types.FunctionType)
):
setattr(self, k, globals_dict[k].__get__(self))
def __repr__(self):
return "ScoDoc7Context('%s')" % self.name
return scodoc7func_decorator

View File

@ -1,142 +0,0 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Configuration pour debugguer en mode console
Lancer ScoDoc ainsi: (comme root)
/opt/scodoc/bin/zopectl debug
Puis
from debug import *
context = go(app)
# ou
context = go_dept(app, 'CJ')
authuser = app.acl_users.getUserById('admin')
# ou app.ScoDoc.acl_users.getUserById('toto') pour un utilisateur scodoc
authuser = authuser.__of__(app.acl_users)
Exemple:
sems = sco_formsemestre.do_formsemestre_list.formsemestre_list(context)
formsemestre_id = sems[0]['formsemestre_id']
# Affiche tous les semestres:
for sem in sems:
print sem['formsemestre_id'], sem['titre_num']
# Recupere la table de notes:
nt = sco_cache.NotesTableCache.get( formsemestre_id)
"""
from __future__ import print_function
import pdb # pylint: disable=unused-import
import pprint
import app.scodoc.notesdb as ndb # pylint: disable=unused-import
from app.scodoc.notesdb import * # pylint: disable=wildcard-import,unused-wildcard-import
from app.scodoc.notes_log import log
import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import * # pylint: disable=wildcard-import, unused-wildcard-import
from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sco_header
from app.scodoc import sco_archives
from app.scodoc import sco_bulletins
from app.scodoc import sco_bulletins_xml
from app.scodoc import sco_cache
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_compute_moy
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_excel
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_news
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_permissions
from app.scodoc import sco_preferences
from app.scodoc import sco_tag_module
from app.scodoc import sco_etud
# Prend le premier departement comme context
def go(app, n=0, verbose=True):
context = app.ScoDoc.objectValues("Folder")[n].Scolarite
if verbose:
print("context in dept ", scu.get_dept_id())
return context
def go_dept(app, dept, verbose=True):
objs = app.ScoDoc.objectValues("Folder")
for o in objs:
try:
context = o.Scolarite
except AttributeError:
# ignore other folders, like old "icons"
continue
if scu.get_dept_id() == dept:
if verbose:
print("context in dept ", scu.get_dept_id())
return context
raise ValueError("dep %s not found" % dept)
class FakeUser(object):
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def has_permission(self, op, dept=None):
return True
def has_role(self, role):
return True
class DummyResponse(object):
"""Emulation vide de Reponse http Zope"""
def __init__(self):
self.header = {}
self.redirected = ""
def setHeader(self, name, value):
self.header[name] = value
def redirect(self, url):
self.redirected = url
class DummyRequest(object):
"""Emulation vide de Request Zope"""
def __init__(self):
self.RESPONSE = DummyResponse()
self.AUTHENTICATED_USER = FakeUser("admin")
self.form = {}
self.URL = "http://scodoc/"
self.URL0 = self.URL
self.BASE0 = "localhost"
self.REMOTE_ADDR = "127.0.0.1"
self.HTTP_REFERER = ""
self.REQUEST_METHOD = "get"
self.QUERY_STRING = ""
REQUEST = DummyRequest()
# handful shorcut
pp = pprint.pprint

View File

@ -157,8 +157,6 @@ def sco_header(
"Main HTML page header for ScoDoc"
from app.scodoc.sco_formsemestre_status import formsemestre_page_title
context = None # XXX TODO à enlever #context
# Get head message from http request:
if not head_message:
if request.method == "POST":
@ -308,7 +306,7 @@ def sco_header(
H.append("""<div class="gtrcontent" id="gtrcontent">""")
#
# Barre menu semestre:
H.append(formsemestre_page_title(context))
H.append(formsemestre_page_title())
# Avertissement si mot de passe à changer
if user_check:

View File

@ -64,7 +64,7 @@ log = _logguer()
# Alarms by email:
def sendAlarm(context, subj, txt):
def sendAlarm(subj, txt):
from . import sco_utils
from . import sco_emails
from . import sco_preferences
@ -77,7 +77,7 @@ def sendAlarm(context, subj, txt):
msg.epilogue = ""
txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING)
msg.attach(txt)
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)
# Debug: log call stack

View File

@ -102,7 +102,7 @@ def comp_ranks(T):
return rangs
def get_sem_ues_modimpls(context, formsemestre_id, modimpls=None):
def get_sem_ues_modimpls(formsemestre_id, modimpls=None):
"""Get liste des UE du semestre (à partir des moduleimpls)
(utilisé quand on ne peut pas construire nt et faire nt.get_ues())
"""
@ -122,7 +122,7 @@ def get_sem_ues_modimpls(context, formsemestre_id, modimpls=None):
return ues, modimpls
def comp_etud_sum_coef_modules_ue(context, formsemestre_id, etudid, ue_id):
def comp_etud_sum_coef_modules_ue(formsemestre_id, etudid, ue_id):
"""Somme des coefficients des modules de l'UE dans lesquels cet étudiant est inscrit
ou None s'il n'y a aucun module.
@ -171,13 +171,10 @@ class NotesTable(object):
"""
def __init__(
self, context, formsemestre_id
): # context is not used in ScoDoc8 ! XXX
def __init__(self, formsemestre_id):
log("NotesTable( formsemestre_id=%s )" % formsemestre_id)
if not formsemestre_id:
raise ValueError("invalid formsemestre_id (%s)" % formsemestre_id)
self.context = context
self.formsemestre_id = formsemestre_id
cnx = ndb.GetDBConnexion()
self.sem = sco_formsemestre.get_formsemestre(formsemestre_id)
@ -218,7 +215,7 @@ class NotesTable(object):
valid_evals,
mods_att,
self.expr_diagnostics,
) = sco_compute_moy.do_formsemestre_moyennes(context, self, formsemestre_id)
) = sco_compute_moy.do_formsemestre_moyennes(self, formsemestre_id)
self._mods_att = mods_att # liste des modules avec des notes en attente
self._matmoys = {} # moyennes par matieres
self._valid_evals = {} # { evaluation_id : eval }
@ -372,16 +369,14 @@ class NotesTable(object):
def get_sexnom(self, etudid):
"M. DUPONT"
etud = self.identdict[etudid]
return (
etud["civilite_str"] + " " + scu.strupper(etud["nom_usuel"] or etud["nom"])
)
return etud["civilite_str"] + " " + (etud["nom_usuel"] or etud["nom"]).upper()
def get_nom_short(self, etudid):
"formatte nom d'un etud (pour table recap)"
etud = self.identdict[etudid]
# Attention aux caracteres multibytes pour decouper les 2 premiers:
return (
scu.strupper(etud["nom_usuel"] or etud["nom"])
(etud["nom_usuel"] or etud["nom"]).upper()
+ " "
+ etud["prenom"].capitalize()[:2]
+ "."
@ -681,7 +676,6 @@ class NotesTable(object):
formula = sco_compute_moy.get_ue_expression(self.formsemestre_id, ue_id, cnx)
if formula:
moy = sco_compute_moy.compute_user_formula(
self.context,
self.sem,
etudid,
moy,
@ -980,7 +974,7 @@ class NotesTable(object):
# { groupe : { etudid : rang } }
if not group_id in self.group_etuds:
# lazy fill: list of etud in group_id
etuds = sco_groups.get_group_members(self.context, group_id)
etuds = sco_groups.get_group_members(group_id)
self.group_etuds[group_id] = set([x["etudid"] for x in etuds])
# 1- build T restricted to group
Tr = []
@ -1056,7 +1050,7 @@ class NotesTable(object):
"Warning: %s capitalized an UE %s which is not part of current sem %s"
% (etudid, ue_id, self.formsemestre_id)
)
ue = sco_edit_ue.do_ue_list(self.context, args={"ue_id": ue_id})[0]
ue = sco_edit_ue.do_ue_list(args={"ue_id": ue_id})[0]
self.uedict[ue_id] = ue # record this UE
if ue_id not in self._uecoef:
cl = formsemestre_uecoef_list(
@ -1146,9 +1140,7 @@ class NotesTable(object):
self.ue_capitalisees = scu.DictDefault(defaultvalue=[])
cnx = None
for etudid in self.get_etudids():
capital = formsemestre_get_etud_capitalisation(
self.context, self.sem, etudid
)
capital = formsemestre_get_etud_capitalisation(self.sem, etudid)
for ue_cap in capital:
# Si la moyenne d'UE n'avait pas été stockée (anciennes versions de ScoDoc)
# il faut la calculer ici et l'enregistrer
@ -1194,7 +1186,7 @@ class NotesTable(object):
cnx.commit()
# log('comp_ue_capitalisees=\n%s' % pprint.pformat(self.ue_capitalisees) )
# def comp_etud_sum_coef_modules_ue(self, etudid, ue_id):
# def comp_etud_sum_coef_modules_ue( etudid, ue_id):
# """Somme des coefficients des modules de l'UE dans lesquels cet étudiant est inscrit
# ou None s'il n'y a aucun module
# """
@ -1235,7 +1227,7 @@ class NotesTable(object):
if ue_cap["formsemestre_id"]:
# Somme des coefs dans l'UE du semestre d'origine (nouveau: 23/01/2016)
coef = comp_etud_sum_coef_modules_ue(
self.context, ue_cap["formsemestre_id"], etudid, ue_cap["ue_id"]
ue_cap["formsemestre_id"], etudid, ue_cap["ue_id"]
)
if coef != None:
return coef
@ -1243,9 +1235,7 @@ class NotesTable(object):
# Capitalisation UE externe: quel coef appliquer ?
# Si l'étudiant est inscrit dans le semestre courant,
# somme des coefs des modules de l'UE auxquels il est inscrit
c = comp_etud_sum_coef_modules_ue(
self.context, self.formsemestre_id, etudid, ue["ue_id"]
)
c = comp_etud_sum_coef_modules_ue(self.formsemestre_id, etudid, ue["ue_id"])
if c is not None: # inscrit à au moins un module de cette UE
return c
# arfff: aucun moyen de déterminer le coefficient de façon sûre

View File

@ -66,9 +66,7 @@ def get_code_latex_from_modele(fichier):
# ----------------------------------------------------------------------------------------
def get_code_latex_from_scodoc_preference(
context, formsemestre_id, champ="pe_avis_latex_tmpl"
):
def get_code_latex_from_scodoc_preference(formsemestre_id, champ="pe_avis_latex_tmpl"):
"""
Extrait le template (ou le tag d'annotation au regard du champ fourni) des préférences LaTeX
et s'assure qu'il est renvoyé au format unicode
@ -221,7 +219,7 @@ def get_code_latex_avis_etudiant(
# ----------------------------------------------------------------------------------------
def get_annotation_PE(context, etudid, tag_annotation_pe):
def get_annotation_PE(etudid, tag_annotation_pe):
"""Renvoie l'annotation PE dans la liste de ces annotations ;
Cette annotation est reconnue par la présence d'un tag **PE**
(cf. .get_preferences -> pe_tag_annotation_avis_latex).
@ -387,7 +385,7 @@ def get_bilanParTag(donnees_etudiant, groupe="groupe"):
# ----------------------------------------------------------------------------------------
def get_avis_poursuite_par_etudiant(
context, jury, etudid, template_latex, tag_annotation_pe, footer_latex, prefs
jury, etudid, template_latex, tag_annotation_pe, footer_latex, prefs
):
"""Renvoie un nom de fichier et le contenu de l'avis latex d'un étudiant dont l'etudid est fourni.
result: [ chaine unicode, chaine unicode ]
@ -417,9 +415,7 @@ def get_avis_poursuite_par_etudiant(
)
# les annnotations
annotationPE = get_annotation_PE(
context, etudid, tag_annotation_pe=tag_annotation_pe
)
annotationPE = get_annotation_PE(etudid, tag_annotation_pe=tag_annotation_pe)
if pe_tools.PE_DEBUG:
pe_tools.pe_print(annotationPE, type(annotationPE))
@ -456,7 +452,7 @@ def get_templates_from_distrib(template="avis"):
# ----------------------------------------------------------------------------------------
def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe):
def table_syntheseAnnotationPE(syntheseJury, tag_annotation_pe):
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant"""
sT = SeqGenTable() # le fichier excel à générer
@ -514,9 +510,7 @@ def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe):
n += 1
# L'annotation PE
annotationPE = get_annotation_PE(
context, etudid, tag_annotation_pe=tag_annotation_pe
)
annotationPE = get_annotation_PE(etudid, tag_annotation_pe=tag_annotation_pe)
row["Annotation PE"] = annotationPE if annotationPE else ""
rows.append(row)

View File

@ -61,7 +61,7 @@ from app.scodoc import pe_semestretag
from app.scodoc import pe_settag
# ----------------------------------------------------------------------------------------
def comp_nom_semestre_dans_parcours(context, sem):
def comp_nom_semestre_dans_parcours(sem):
"""Le nom a afficher pour titrer un semestre
par exemple: "semestre 2 FI 2015"
"""
@ -83,15 +83,12 @@ class JuryPE(object):
base sur NotesTable
Attributs : - diplome : l'annee d'obtention du diplome DUT et du jury de PE (generalement fevrier XXXX)
- context : le contexte Zope
- juryEtudDict : dictionnaire récapitulant les étudiants participant au jury PE (données administratives +
celles des semestres valides à prendre en compte permettant le calcul des moyennes ...
{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}
Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue
et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif
Note (EV:): les attributs sont des chaines encodées (utf8), comme dans ScoDoc (pas des unicodes)
"""
# Variables de classe décrivant les aggrégats, leur ordre d'apparition temporelle et
@ -148,19 +145,17 @@ class JuryPE(object):
}
# ------------------------------------------------------------------------------------------------------------------
def __init__(self, context, semBase):
def __init__(self, semBase):
"""
Création d'une table PE sur la base d'un semestre selectionné. De ce semestre est déduit :
1. l'année d'obtention du DUT,
2. tous les étudiants susceptibles à ce stade (au regard de leur parcours) d'être diplomés.
Args:
context:
semBase: le dictionnaire sem donnant la base du jury
meme_programme: si True, impose un même programme pour tous les étudiants participant au jury,
si False, permet des programmes differents
"""
self.context = context
self.semTagDict = (
{}
) # Les semestres taggués à la base des calculs de moyenne par tag
@ -275,7 +270,7 @@ class JuryPE(object):
"""
# Les cosemestres donnant lieu à meme année de diplome
coSems = get_cosemestres_diplomants(
self.context, semBase, avec_meme_formation=avec_meme_formation
semBase, avec_meme_formation=avec_meme_formation
) # calcul des coSemestres
if pe_tools.PE_DEBUG:
pe_tools.pe_print(
@ -323,9 +318,7 @@ class JuryPE(object):
for sem in semsListe: # pour chacun des semestres de la liste
# nt = self.get_notes_d_un_semestre( sem['formsemestre_id'] )
nt = self.get_cache_notes_d_un_semestre(
self.context, sem["formsemestre_id"]
)
nt = self.get_cache_notes_d_un_semestre(sem["formsemestre_id"])
# sco_cache.NotesTableCache.get( sem['formsemestre_id'])
etudiantsDuSemestre = (
nt.get_etudids()
@ -377,7 +370,7 @@ class JuryPE(object):
if etudid not in self.PARCOURSINFO_DICT:
etud = self.get_cache_etudInfo_d_un_etudiant(
self.context, etudid
etudid
) # On charge les données de l'étudiant
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
pe_tools.pe_print(etud["nom"] + " " + etud["prenom"], end="")
@ -460,8 +453,8 @@ class JuryPE(object):
from app.scodoc import sco_report
reponse = False
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
(_, parcours) = sco_report.get_codeparcoursetud(self.context, etud)
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
(_, parcours) = sco_report.get_codeparcoursetud(etud)
if (
len(set(sco_codes_parcours.CODES_SEM_REO.keys()) & set(parcours.values()))
> 0
@ -493,7 +486,7 @@ class JuryPE(object):
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 = sco_formsemestre.do_formsemestre_list(self.context)
semestresDeScoDoc = sco_formsemestre.do_formsemestre_list()
semestresSuperieurs = [
sem for sem in semestresDeScoDoc if sem["semestre_id"] > sonDernierSidValide
] # Semestre de rang plus élevé que son dernier sem valide
@ -523,9 +516,9 @@ class JuryPE(object):
"""
from app.scodoc import sco_report
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
(code, parcours) = sco_report.get_codeparcoursetud(
self.context, etud
etud
) # description = '1234:A', parcours = {1:ADM, 2:NAR, ...}
sonDernierSemestreValide = max(
[
@ -554,9 +547,7 @@ class JuryPE(object):
for (i, sem) in enumerate(
sesSi
): # Parcours des éventuels semestres précédents
nt = self.get_cache_notes_d_un_semestre(
self.context, sem["formsemestre_id"]
)
nt = self.get_cache_notes_d_un_semestre(sem["formsemestre_id"])
dec = nt.get_etud_decision_sem(
etudid
) # quelle est la décision du jury ?
@ -597,11 +588,11 @@ class JuryPE(object):
"""
# Semestre taggué avec classement dans le groupe
if fid not in self.semTagDict:
nt = self.get_cache_notes_d_un_semestre(self.context, fid)
nt = self.get_cache_notes_d_un_semestre(fid)
# Création du semestres
self.semTagDict[fid] = pe_semestretag.SemestreTag(
self.context, nt, nt.sem
nt, nt.sem
) # Création du pesemestre associé
self.semTagDict[fid].comp_data_semtag()
lesEtudids = self.semTagDict[fid].get_etudids()
@ -612,7 +603,7 @@ class JuryPE(object):
etudid not in self.PARCOURSINFO_DICT
): # Si l'étudiant n'a pas été pris en compte dans le jury car déjà diplômé ou redoublant
lesEtudidsManquants.append(etudid)
# self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
# self.get_cache_etudInfo_d_un_etudiant(etudid)
self.add_etudiants(
etudid
) # Ajoute les élements de parcours de l'étudiant
@ -879,7 +870,7 @@ class JuryPE(object):
infos = []
for sem in sems:
nomsem = comp_nom_semestre_dans_parcours(self.context, sem)
nomsem = comp_nom_semestre_dans_parcours(sem)
infos.append(
{
"nom_semestre_dans_parcours": nomsem,
@ -1117,7 +1108,7 @@ class JuryPE(object):
# **************************************************************************************************************** #
# ------------------------------------------------------------------------------------------------------------------
def get_cache_etudInfo_d_un_etudiant(self, context, etudid):
def get_cache_etudInfo_d_un_etudiant(self, etudid):
"""Renvoie les informations sur le parcours d'un étudiant soit en les relisant depuis
ETUDINFO_DICT si mémorisée soit en les chargeant et en les mémorisant
"""
@ -1130,9 +1121,7 @@ class JuryPE(object):
# ------------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------------
def get_cache_notes_d_un_semestre(
self, context, formsemestre_id
): # inutile en realité !
def get_cache_notes_d_un_semestre(self, formsemestre_id): # inutile en realité !
"""Charge la table des notes d'un formsemestre"""
return sco_cache.NotesTableCache.get(formsemestre_id)
@ -1145,7 +1134,7 @@ class JuryPE(object):
en fonction de ses infos d'etud (cf. sco_etud.get_etud_info( etudid=etudid, filled=True)[0]),
les semestres étant triés par ordre décroissant.
Si semestre_id == None renvoie tous les semestres"""
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
if semestre_id == None:
sesSems = [sem for sem in etud["sems"] if 1 <= sem["semestre_id"] <= 4]
else:
@ -1230,7 +1219,7 @@ def get_annee_diplome_semestre(sem):
# ----------------------------------------------------------------------------------
def get_cosemestres_diplomants(context, semBase, avec_meme_formation=False):
def get_cosemestres_diplomants(semBase, avec_meme_formation=False):
"""Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
renvoie la liste de tous ses co-semestres (lui-meme inclus)
Par co-semestre, s'entend les semestres :

View File

@ -73,9 +73,7 @@ class SemestreTag(pe_tagtable.TableTag):
# -----------------------------------------------------------------------------
# Fonctions d'initialisation
# -----------------------------------------------------------------------------
def __init__(
self, context, notetable, sem
): # Initialisation sur la base d'une notetable
def __init__(self, notetable, sem): # Initialisation sur la base d'une notetable
"""Instantiation d'un objet SemestreTag à partir d'un tableau de note
et des informations sur le semestre pour le dater
"""
@ -95,7 +93,6 @@ class SemestreTag(pe_tagtable.TableTag):
)
# Les attributs spécifiques
self.context = context
self.nt = notetable
# Les attributs hérités : la liste des étudiants
@ -293,7 +290,7 @@ class SemestreTag(pe_tagtable.TableTag):
coeff / self.somme_coeffs if self.somme_coeffs != 0 else 0
) # le coeff normalisé
else:
semtag_prec = SemestreTag(self.context, nt_prec, nt_prec.sem)
semtag_prec = SemestreTag(nt_prec, nt_prec.sem)
(note, coeff_norm) = semtag_prec.get_noteEtCoeff_modimpl(
modprec_id, etudid, profondeur=profondeur - 1
) # lecture de la note via le semtag associé au modimpl capitalisé

View File

@ -171,7 +171,7 @@ def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
zipfile.writestr(rooted_path_in_zip, data)
def add_pe_stuff_to_zip(context, zipfile, ziproot):
def add_pe_stuff_to_zip(zipfile, ziproot):
"""Add auxiliary files to (already opened) zip
Put all local files found under config/doc_poursuites_etudes/local
and config/doc_poursuites_etudes/distrib

View File

@ -46,7 +46,7 @@ from app.scodoc import pe_jurype
from app.scodoc import pe_avislatex
def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None):
def _pe_view_sem_recap_form(formsemestre_id, REQUEST=None):
H = [
html_sco_header.sco_header(page_title="Avis de poursuite d'études"),
"""<h2 class="formsemestre">Génération des avis de poursuites d'études</h2>
@ -75,7 +75,6 @@ def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None):
def pe_view_sem_recap(
context,
formsemestre_id,
avis_tmpl_file=None,
footer_tmpl_file=None,
@ -88,12 +87,12 @@ def pe_view_sem_recap(
et debugger uniquement la partie avis latex
"""
if REQUEST and REQUEST.REQUEST_METHOD == "GET":
return _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=REQUEST)
return _pe_view_sem_recap_form(formsemestre_id, REQUEST=REQUEST)
prefs = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id)
semBase = sco_formsemestre.get_formsemestre(formsemestre_id)
jury = pe_jurype.JuryPE(context, semBase)
jury = pe_jurype.JuryPE(semBase)
# Ajout avis LaTeX au même zip:
etudids = list(jury.syntheseJury.keys())
@ -108,7 +107,7 @@ def pe_view_sem_recap(
else:
# template indiqué dans préférences ScoDoc ?
template_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
context, formsemestre_id, champ="pe_avis_latex_tmpl"
formsemestre_id, champ="pe_avis_latex_tmpl"
)
template_latex = template_latex.strip()
@ -124,7 +123,7 @@ def pe_view_sem_recap(
footer_latex = footer_latex
else:
footer_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
context, formsemestre_id, champ="pe_avis_latex_footer"
formsemestre_id, champ="pe_avis_latex_footer"
)
footer_latex = footer_latex.strip()
if not footer_latex:
@ -134,13 +133,11 @@ def pe_view_sem_recap(
) # fallback: footer vides
tag_annotation_pe = pe_avislatex.get_code_latex_from_scodoc_preference(
context, formsemestre_id, champ="pe_tag_annotation_avis_latex"
formsemestre_id, champ="pe_tag_annotation_avis_latex"
)
# Ajout des annotations PE dans un fichier excel
sT = pe_avislatex.table_syntheseAnnotationPE(
context, jury.syntheseJury, tag_annotation_pe
)
sT = pe_avislatex.table_syntheseAnnotationPE(jury.syntheseJury, tag_annotation_pe)
if sT:
jury.add_file_to_zip(
jury.NOM_EXPORT_ZIP + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel()
@ -149,7 +146,6 @@ def pe_view_sem_recap(
latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex
for etudid in etudids:
[nom_fichier, contenu_latex] = pe_avislatex.get_avis_poursuite_par_etudiant(
context,
jury,
etudid,
template_latex,
@ -171,7 +167,7 @@ def pe_view_sem_recap(
jury.add_file_to_zip("avis/avis_poursuite.tex", doc_latex.encode(PE_LATEX_ENCODING))
# Ajoute image, LaTeX class file(s) and modeles
pe_tools.add_pe_stuff_to_zip(context, jury.zipfile, jury.NOM_EXPORT_ZIP)
pe_tools.add_pe_stuff_to_zip(jury.zipfile, jury.NOM_EXPORT_ZIP)
data = jury.get_zipped_data()
size = len(data)

View File

@ -63,7 +63,7 @@ def _toboolean(x):
return bool(x)
def is_work_saturday(context):
def is_work_saturday():
"Vrai si le samedi est travaillé"
return int(sco_preferences.get_preference("work_saturday"))
@ -216,7 +216,7 @@ class ddmmyyyy(object):
# d = ddmmyyyy( '21/12/99' )
def DateRangeISO(context, date_beg, date_end, workable=1):
def DateRangeISO(date_beg, date_end, workable=1):
"""returns list of dates in [date_beg,date_end]
workable = 1 => keeps only workable days"""
if not date_beg:
@ -224,7 +224,7 @@ def DateRangeISO(context, date_beg, date_end, workable=1):
if not date_end:
date_end = date_beg
r = []
work_saturday = is_work_saturday(context)
work_saturday = is_work_saturday()
cur = ddmmyyyy(date_beg, work_saturday=work_saturday)
end = ddmmyyyy(date_end, work_saturday=work_saturday)
while cur <= end:
@ -235,24 +235,23 @@ def DateRangeISO(context, date_beg, date_end, workable=1):
return [x.ISO() for x in r]
def day_names(context):
def day_names():
"""Returns week day names.
If work_saturday property is set, include saturday
"""
if is_work_saturday(context):
if is_work_saturday():
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
else:
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]
def next_iso_day(context, date):
def next_iso_day(date):
"return date after date"
d = ddmmyyyy(date, fmt="iso", work_saturday=is_work_saturday(context))
d = ddmmyyyy(date, fmt="iso", work_saturday=is_work_saturday())
return d.next_day().ISO()
def YearTable(
context,
year,
events=[],
firstmonth=9,
@ -283,7 +282,7 @@ def YearTable(
events,
halfday,
dayattributes,
is_work_saturday(context),
is_work_saturday(),
pad_width=pad_width,
)
)
@ -624,7 +623,6 @@ AND B.ETUDID = %(etudid)s
def add_absence(
context,
etudid,
jour,
matin,
@ -653,10 +651,10 @@ def add_absence(
)
cnx.commit()
invalidate_abs_etud_date(etudid, jour)
sco_abs_notification.abs_notify(context, etudid, jour)
sco_abs_notification.abs_notify(etudid, jour)
def add_justif(context, etudid, jour, matin, REQUEST, description=None):
def add_justif(etudid, jour, matin, REQUEST, description=None):
"Ajoute un justificatif dans la base"
# unpublished
if _isFarFutur(jour):
@ -678,7 +676,7 @@ def add_justif(context, etudid, jour, matin, REQUEST, description=None):
invalidate_abs_etud_date(etudid, jour)
def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None):
def _add_abslist(abslist, REQUEST, moduleimpl_id=None):
for a in abslist:
etudid, jour, ampm = a.split(":")
if ampm == "am":
@ -689,10 +687,10 @@ def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None):
raise ValueError("invalid ampm !")
# ajoute abs si pas deja absent
if count_abs(etudid, jour, jour, matin, moduleimpl_id) == 0:
add_absence(context, etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
add_absence(etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
def annule_absence(context, etudid, jour, matin, moduleimpl_id=None):
def annule_absence(etudid, jour, matin, moduleimpl_id=None):
"""Annule une absence dans la base. N'efface pas l'éventuel justificatif.
Args:
etudid:
@ -721,7 +719,7 @@ def annule_absence(context, etudid, jour, matin, moduleimpl_id=None):
invalidate_abs_etud_date(etudid, jour)
def annule_justif(context, etudid, jour, matin, REQUEST=None):
def annule_justif(etudid, jour, matin, REQUEST=None):
"Annule un justificatif"
# unpublished
matin = _toboolean(matin)
@ -1087,7 +1085,7 @@ def invalidate_abs_etud_date(etudid, date): # was invalidateAbsEtudDate
for sem in sems:
# Inval cache bulletin et/ou note_table
if sco_compute_moy.formsemestre_expressions_use_abscounts(
None, sem["formsemestre_id"]
sem["formsemestre_id"]
):
# certaines formules utilisent les absences
pdfonly = False

View File

@ -50,7 +50,7 @@ from app.scodoc import sco_preferences
from app.scodoc import sco_users
def abs_notify(context, etudid, date):
def abs_notify(etudid, date):
"""Check if notifications are requested and send them
Considère le nombre d'absence dans le semestre courant
(s'il n'y a pas de semestre courant, ne fait rien,
@ -58,15 +58,15 @@ def abs_notify(context, etudid, date):
"""
from app.scodoc import sco_abs
sem = retreive_current_formsemestre(context, etudid, date)
sem = retreive_current_formsemestre(etudid, date)
if not sem:
return # non inscrit a la date, pas de notification
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust)
do_abs_notify(sem, etudid, date, nbabs, nbabsjust)
def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
def do_abs_notify(sem, etudid, date, nbabs, nbabsjust):
"""Given new counts of absences, check if notifications are requested and send them."""
# prefs fallback to global pref if sem is None:
if sem:
@ -76,9 +76,9 @@ def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
prefs = sco_preferences.SemPreferences(formsemestre_id=sem["formsemestre_id"])
destinations = abs_notify_get_destinations(
context, sem, prefs, etudid, date, nbabs, nbabsjust
sem, prefs, etudid, date, nbabs, nbabsjust
)
msg = abs_notification_message(context, sem, prefs, etudid, nbabs, nbabsjust)
msg = abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust)
if not msg:
return # abort
@ -86,9 +86,7 @@ def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
abs_notify_max_freq = sco_preferences.get_preference("abs_notify_max_freq")
destinations_filtered = []
for email_addr in destinations:
nbdays_since_last_notif = user_nbdays_since_last_notif(
context, email_addr, etudid
)
nbdays_since_last_notif = user_nbdays_since_last_notif(email_addr, etudid)
if (nbdays_since_last_notif is None) or (
nbdays_since_last_notif >= abs_notify_max_freq
):
@ -96,7 +94,6 @@ def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
if destinations_filtered:
abs_notify_send(
context,
destinations_filtered,
etudid,
msg,
@ -106,9 +103,7 @@ def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
)
def abs_notify_send(
context, destinations, etudid, msg, nbabs, nbabsjust, formsemestre_id
):
def abs_notify_send(destinations, etudid, msg, nbabs, nbabsjust, formsemestre_id):
"""Actually send the notification by email, and register it in database"""
cnx = ndb.GetDBConnexion()
log("abs_notify: sending notification to %s" % destinations)
@ -116,7 +111,7 @@ def abs_notify_send(
for email in destinations:
del msg["To"]
msg["To"] = email
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)
ndb.SimpleQuery(
"""insert into absences_notifications
(etudid, email, nbabs, nbabsjust, formsemestre_id)
@ -134,15 +129,13 @@ def abs_notify_send(
)
def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsjust):
def abs_notify_get_destinations(sem, prefs, etudid, date, nbabs, nbabsjust):
"""Returns set of destination emails to be notified"""
formsemestre_id = sem["formsemestre_id"]
destinations = [] # list of email address to notify
if abs_notify_is_above_threshold(
context, etudid, nbabs, nbabsjust, formsemestre_id
):
if abs_notify_is_above_threshold(etudid, nbabs, nbabsjust, formsemestre_id):
if sem and prefs["abs_notify_respsem"]:
# notifie chaque responsable du semestre
for responsable_id in sem["responsables"]:
@ -162,7 +155,7 @@ def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsj
# à cette date
# nb: on pourrait prevoir d'utiliser un autre format de message pour ce cas
if sem and prefs["abs_notify_respeval"]:
mods = mod_with_evals_at_date(context, date, etudid)
mods = mod_with_evals_at_date(date, etudid)
for mod in mods:
u = sco_users.user_info(mod["responsable_id"])
if u["email"]:
@ -174,7 +167,7 @@ def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsj
return destinations
def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestre_id):
def abs_notify_is_above_threshold(etudid, nbabs, nbabsjust, formsemestre_id):
"""True si il faut notifier les absences (indépendemment du destinataire)
nbabs: nombre d'absence (de tous types, unité de compte = demi-journée)
@ -189,7 +182,7 @@ def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestr
abs_notify_abs_increment = sco_preferences.get_preference(
"abs_notify_abs_increment", formsemestre_id
)
nbabs_last_notified = etud_nbabs_last_notified(context, etudid, formsemestre_id)
nbabs_last_notified = etud_nbabs_last_notified(etudid, formsemestre_id)
if nbabs_last_notified == 0:
if nbabs > abs_notify_abs_threshold:
@ -202,7 +195,7 @@ def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestr
return False
def etud_nbabs_last_notified(context, etudid, formsemestre_id=None):
def etud_nbabs_last_notified(etudid, formsemestre_id=None):
"""nbabs lors de la dernière notification envoyée pour cet étudiant dans ce semestre
ou sans semestre (ce dernier cas est nécessaire pour la transition au nouveau code)"""
cnx = ndb.GetDBConnexion()
@ -218,7 +211,7 @@ def etud_nbabs_last_notified(context, etudid, formsemestre_id=None):
return 0
def user_nbdays_since_last_notif(context, email_addr, etudid):
def user_nbdays_since_last_notif(email_addr, etudid):
"""nb days since last notification to this email, or None if no previous notification"""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -234,7 +227,7 @@ def user_nbdays_since_last_notif(context, email_addr, etudid):
return None
def abs_notification_message(context, sem, prefs, etudid, nbabs, nbabsjust):
def abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust):
"""Mime notification message based on template.
returns None if sending should be canceled (emplty template).
"""
@ -243,7 +236,7 @@ def abs_notification_message(context, sem, prefs, etudid, nbabs, nbabsjust):
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
# Variables accessibles dans les balises du template: %(nom_variable)s :
values = sco_bulletins.make_context_dict(context, sem, etud)
values = sco_bulletins.make_context_dict(sem, etud)
values["nbabs"] = nbabs
values["nbabsjust"] = nbabsjust
@ -270,7 +263,7 @@ def abs_notification_message(context, sem, prefs, etudid, nbabs, nbabsjust):
return msg
def retreive_current_formsemestre(context, etudid, cur_date):
def retreive_current_formsemestre(etudid, cur_date):
"""Get formsemestre dans lequel etudid est (ou était) inscrit a la date indiquée
date est une chaine au format ISO (yyyy-mm-dd)
"""
@ -288,7 +281,7 @@ def retreive_current_formsemestre(context, etudid, cur_date):
return sem
def mod_with_evals_at_date(context, date_abs, etudid):
def mod_with_evals_at_date(date_abs, etudid):
"""Liste des moduleimpls avec des evaluations à la date indiquée"""
req = """SELECT m.id AS moduleimpl_id, m.*
FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i

View File

@ -51,7 +51,6 @@ from app.scodoc.sco_exceptions import ScoValueError
def doSignaleAbsence(
context,
datedebut,
datefin,
moduleimpl_id=None,
@ -77,13 +76,12 @@ def doSignaleAbsence(
if not moduleimpl_id:
moduleimpl_id = None
description_abs = description
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
dates = sco_abs.DateRangeISO(datedebut, datefin)
nbadded = 0
demijournee = int(demijournee)
for jour in dates:
if demijournee == 2:
sco_abs.add_absence(
context,
etudid,
jour,
False,
@ -93,7 +91,6 @@ def doSignaleAbsence(
moduleimpl_id,
)
sco_abs.add_absence(
context,
etudid,
jour,
True,
@ -105,7 +102,6 @@ def doSignaleAbsence(
nbadded += 2
else:
sco_abs.add_absence(
context,
etudid,
jour,
demijournee,
@ -155,12 +151,12 @@ def doSignaleAbsence(
<hr>"""
% etud
)
H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(sco_find_etud.form_search_etud(REQUEST))
H.append(html_sco_header.sco_footer())
return "\n".join(H)
def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
def SignaleAbsenceEtud(REQUEST=None): # etudid implied
"""Formulaire individuel simple de signalement d'une absence"""
# brute-force portage from very old dtml code ...
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
@ -230,7 +226,6 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
"""<a href="%s">"""
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]),
sco_photos.etud_photo_html(
context,
etudid=etudid,
title="fiche de " + etud["nomprenom"],
REQUEST=REQUEST,
@ -281,7 +276,6 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doJustifAbsence(
context,
datedebut,
datefin,
demijournee,
@ -302,13 +296,12 @@ def doJustifAbsence(
etud = sco_etud.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
description_abs = description
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
dates = sco_abs.DateRangeISO(datedebut, datefin)
nbadded = 0
demijournee = int(demijournee)
for jour in dates:
if demijournee == 2:
sco_abs.add_justif(
context,
etudid=etudid,
jour=jour,
matin=False,
@ -316,7 +309,6 @@ def doJustifAbsence(
description=description_abs,
)
sco_abs.add_justif(
context,
etudid=etudid,
jour=jour,
matin=True,
@ -326,7 +318,6 @@ def doJustifAbsence(
nbadded += 2
else:
sco_abs.add_justif(
context,
etudid=etudid,
jour=jour,
matin=demijournee,
@ -361,12 +352,12 @@ def doJustifAbsence(
<hr>"""
% etud
)
H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(sco_find_etud.form_search_etud(REQUEST))
H.append(html_sco_header.sco_footer())
return "\n".join(H)
def JustifAbsenceEtud(context, REQUEST=None): # etudid implied
def JustifAbsenceEtud(REQUEST=None): # etudid implied
"""Formulaire individuel simple de justification d'une absence"""
# brute-force portage from very old dtml code ...
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
@ -383,7 +374,6 @@ def JustifAbsenceEtud(context, REQUEST=None): # etudid implied
"""<a href="%s">"""
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context,
etudid=etudid,
title="fiche de " + etud["nomprenom"],
REQUEST=REQUEST,
@ -423,22 +413,22 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doAnnuleAbsence(
context, datedebut, datefin, demijournee, etudid=False, REQUEST=None
datedebut, datefin, demijournee, etudid=False, REQUEST=None
): # etudid implied
"""Annulation des absences pour une demi journée"""
etud = sco_etud.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
dates = sco_abs.DateRangeISO(datedebut, datefin)
nbadded = 0
demijournee = int(demijournee)
for jour in dates:
if demijournee == 2:
sco_abs.annule_absence(context, etudid, jour, False)
sco_abs.annule_absence(context, etudid, jour, True)
sco_abs.annule_absence(etudid, jour, False)
sco_abs.annule_absence(etudid, jour, True)
nbadded += 2
else:
sco_abs.annule_absence(context, etudid, jour, demijournee)
sco_abs.annule_absence(etudid, jour, demijournee)
nbadded += 1
#
H = [
@ -467,12 +457,12 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
<hr>"""
% etud
)
H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(sco_find_etud.form_search_etud(REQUEST))
H.append(html_sco_header.sco_footer())
return "\n".join(H)
def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
def AnnuleAbsenceEtud(REQUEST=None): # etudid implied
"""Formulaire individuel simple d'annulation d'une absence"""
# brute-force portage from very old dtml code ...
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
@ -490,7 +480,6 @@ def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
"""<a href="%s">"""
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context,
etudid=etudid,
title="fiche de " + etud["nomprenom"],
REQUEST=REQUEST,
@ -559,23 +548,21 @@ def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
return "\n".join(H)
def doAnnuleJustif(
context, datedebut0, datefin0, demijournee, REQUEST=None
): # etudid implied
def doAnnuleJustif(datedebut0, datefin0, demijournee, REQUEST=None): # etudid implied
"""Annulation d'une justification"""
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
dates = sco_abs.DateRangeISO(context, datedebut0, datefin0)
dates = sco_abs.DateRangeISO(datedebut0, datefin0)
nbadded = 0
demijournee = int(demijournee)
for jour in dates:
# Attention: supprime matin et après-midi
if demijournee == 2:
sco_abs.annule_justif(context, etudid, jour, False, REQUEST=REQUEST)
sco_abs.annule_justif(context, etudid, jour, True, REQUEST=REQUEST)
sco_abs.annule_justif(etudid, jour, False, REQUEST=REQUEST)
sco_abs.annule_justif(etudid, jour, True, REQUEST=REQUEST)
nbadded += 2
else:
sco_abs.annule_justif(context, etudid, jour, demijournee, REQUEST=REQUEST)
sco_abs.annule_justif(etudid, jour, demijournee, REQUEST=REQUEST)
nbadded += 1
#
H = [
@ -604,12 +591,12 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
<hr>"""
% etud
)
H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(sco_find_etud.form_search_etud(REQUEST))
H.append(html_sco_header.sco_footer())
return "\n".join(H)
def AnnuleAbsencesDatesNoJust(context, etudid, dates, moduleimpl_id=None):
def AnnuleAbsencesDatesNoJust(etudid, dates, moduleimpl_id=None):
"""Supprime les absences non justifiées aux dates indiquées
Ne supprime pas les justificatifs éventuels.
Args:
@ -634,7 +621,7 @@ def AnnuleAbsencesDatesNoJust(context, etudid, dates, moduleimpl_id=None):
matin = 0
else:
raise ValueError("invalid ampm !")
sco_abs.annule_absence(context, etudid, jour, matin, moduleimpl_id)
sco_abs.annule_absence(etudid, jour, matin, moduleimpl_id)
return
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -668,14 +655,14 @@ def AnnuleAbsencesDatesNoJust(context, etudid, dates, moduleimpl_id=None):
cnx.commit()
def EtatAbsences(context, REQUEST=None):
def EtatAbsences():
"""Etat des absences: choix du groupe"""
# crude portage from 1999 DTML
H = [
html_sco_header.sco_header(page_title="Etat des absences"),
"""<h2>Etat des absences pour un groupe</h2>
<form action="EtatAbsencesGr" method="GET">""",
formChoixSemestreGroupe(context),
formChoixSemestreGroupe(),
"""<input type="submit" name="" value=" OK " width=100>
<table><tr><td>Date de début (j/m/a) : </td><td>
@ -694,7 +681,7 @@ def EtatAbsences(context, REQUEST=None):
return "\n".join(H)
def formChoixSemestreGroupe(context, all=False):
def formChoixSemestreGroupe(all=False):
"""partie de formulaire pour le choix d'un semestre et d'un groupe.
Si all, donne tous les semestres (même ceux verrouillés).
"""
@ -722,7 +709,7 @@ def formChoixSemestreGroupe(context, all=False):
return "\n".join(H)
def CalAbs(context, etudid, sco_year=None):
def CalAbs(etudid, sco_year=None):
"""Calendrier des absences d'un etudiant"""
# crude portage from 1999 DTML
REQUEST = None # XXX
@ -749,7 +736,7 @@ def CalAbs(context, etudid, sco_year=None):
events.append(
(str(a["jour"]), "X", "#8EA2C6", "", a["matin"], a["description"])
)
CalHTML = sco_abs.YearTable(context, anneescolaire, events=events, halfday=1)
CalHTML = sco_abs.YearTable(anneescolaire, events=events, halfday=1)
#
H = [
@ -773,7 +760,6 @@ def CalAbs(context, etudid, sco_year=None):
% (
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context,
etudid=etudid,
title="fiche de " + etud["nomprenom"],
REQUEST=REQUEST,
@ -796,7 +782,6 @@ def CalAbs(context, etudid, sco_year=None):
def ListeAbsEtud(
context,
etudid,
with_evals=True,
format="html",
@ -822,7 +807,7 @@ def ListeAbsEtud(
# Liste des absences et titres colonnes tables:
titles, columns_ids, absnonjust, absjust = _TablesAbsEtud(
context, etudid, datedebut, with_evals=with_evals, format=format
etudid, datedebut, with_evals=with_evals, format=format
)
if REQUEST:
base_url_nj = "%s?etudid=%s&absjust_only=0" % (REQUEST.URL0, etudid)
@ -908,7 +893,6 @@ def ListeAbsEtud(
def _TablesAbsEtud(
context,
etudid,
datedebut,
with_evals=True,

View File

@ -61,7 +61,7 @@ _help_txt = """
"""
def apo_compare_csv_form(context, REQUEST=None):
def apo_compare_csv_form():
"""Form: submit 2 CSV files to compare them."""
H = [
html_sco_header.sco_header(page_title="Comparaison de fichiers Apogée"),
@ -88,7 +88,7 @@ def apo_compare_csv_form(context, REQUEST=None):
return "\n".join(H)
def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None):
def apo_compare_csv(A_file, B_file, autodetect=True):
"""Page comparing 2 Apogee CSV files"""
A = _load_apo_data(A_file, autodetect=autodetect)
B = _load_apo_data(B_file, autodetect=autodetect)
@ -98,7 +98,7 @@ def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None):
"<h2>Comparaison de fichiers Apogée</h2>",
_help_txt,
'<div class="apo_compare_csv">',
_apo_compare_csv(context, A, B, REQUEST=None),
_apo_compare_csv(A, B),
"</div>",
"""<p><a href="apo_compare_csv_form" class="stdlink">Autre comparaison</a></p>""",
html_sco_header.sco_footer(),
@ -119,7 +119,7 @@ def _load_apo_data(csvfile, autodetect=True):
return apo_data
def _apo_compare_csv(context, A, B, REQUEST=None):
def _apo_compare_csv(A, B):
"""Generate html report comparing A and B, two instances of ApoData
representing Apogee CSV maquettes.
"""
@ -230,7 +230,7 @@ def _apo_compare_csv(context, A, B, REQUEST=None):
<p>
"""
)
T = apo_table_compare_etud_results(context, A, B, REQUEST=REQUEST)
T = apo_table_compare_etud_results(A, B)
if T.get_nb_rows() > 0:
L.append(T.html())
else:
@ -245,7 +245,7 @@ def _apo_compare_csv(context, A, B, REQUEST=None):
return "\n".join(L)
def apo_table_compare_etud_results(context, A, B, REQUEST=None):
def apo_table_compare_etud_results(A, B):
""""""
D = compare_etuds_res(A, B)
T = GenTable(

View File

@ -296,7 +296,7 @@ class ApoEtud(dict):
def __repr__(self):
return "ApoEtud( nom='%s', nip='%s' )" % (self["nom"], self["nip"])
def lookup_scodoc(self, context, etape_formsemestre_ids):
def lookup_scodoc(self, etape_formsemestre_ids):
"""Cherche l'étudiant ScoDoc associé à cet étudiant Apogée.
S'il n'est pas trouvé (état "orphelin", dans Apo mais pas chez nous),
met .etud à None.
@ -323,13 +323,13 @@ class ApoEtud(dict):
else:
self.etat = ETUD_OK
def associate_sco(self, context, apo_data):
def associate_sco(self, apo_data):
"""Recherche les valeurs des éléments Apogée pour cet étudiant
Set .new_cols
"""
self.col_elts = {} # {'V1RT': {'R': 'ADM', 'J': '', 'B': 20, 'N': '12.14'}}
if self.etat is None:
self.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
self.lookup_scodoc(apo_data.etape_formsemestre_ids)
if self.etat != ETUD_OK:
self.new_cols = (
self.cols
@ -342,11 +342,9 @@ class ApoEtud(dict):
code, None
) # {'R': ADM, 'J': '', 'B': 20, 'N': '12.14'}
if el is None: # pas déjà trouvé
cur_sem, autre_sem = self.etud_semestres_de_etape(context, apo_data)
cur_sem, autre_sem = self.etud_semestres_de_etape(apo_data)
for sem in apo_data.sems_etape:
el = self.search_elt_in_sem(
context, code, sem, cur_sem, autre_sem
)
el = self.search_elt_in_sem(code, sem, cur_sem, autre_sem)
if el != None:
sco_elts[code] = el
break
@ -376,7 +374,7 @@ class ApoEtud(dict):
# codes = set([apo_data.cols[col_id].code for col_id in apo_data.col_ids])
# return codes - set(sco_elts)
def search_elt_in_sem(self, context, code, sem, cur_sem, autre_sem):
def search_elt_in_sem(self, code, sem, cur_sem, autre_sem):
"""
VET code jury etape
ELP élément pédagogique: UE, module
@ -425,14 +423,14 @@ class ApoEtud(dict):
export_res_etape = Se.all_other_validated()
if export_res_etape:
return self.comp_elt_annuel(context, etudid, cur_sem, autre_sem)
return self.comp_elt_annuel(etudid, cur_sem, autre_sem)
else:
return VOID_APO_RES
# Element semestre:
if code in sem["elt_sem_apo"].split(","):
if self.export_res_sem:
return self.comp_elt_semestre(context, nt, decision, etudid)
return self.comp_elt_semestre(nt, decision, etudid)
else:
return VOID_APO_RES
@ -471,7 +469,7 @@ class ApoEtud(dict):
#
return None # element Apogee non trouvé dans ce semestre
def comp_elt_semestre(self, context, nt, decision, etudid):
def comp_elt_semestre(self, nt, decision, etudid):
"""Calcul résultat apo semestre"""
# resultat du semestre
decision_apo = code_scodoc_to_apo(decision["code"])
@ -486,7 +484,7 @@ class ApoEtud(dict):
note_str = _apo_fmt_note(note)
return dict(N=note_str, B=20, J="", R=decision_apo, M="")
def comp_elt_annuel(self, context, etudid, cur_sem, autre_sem):
def comp_elt_annuel(self, etudid, cur_sem, autre_sem):
"""Calcul resultat annuel (VET) à partir du semestre courant
et de l'autre (le suivant ou le précédent complétant l'année scolaire)
"""
@ -517,7 +515,7 @@ class ApoEtud(dict):
if not autre_sem:
# formations monosemestre, ou code VET semestriel,
# ou jury intermediaire et etudiant non redoublant...
return self.comp_elt_semestre(context, cur_nt, cur_decision, etudid)
return self.comp_elt_semestre(cur_nt, cur_decision, etudid)
decision_apo = code_scodoc_to_apo(cur_decision["code"])
@ -554,7 +552,7 @@ class ApoEtud(dict):
return dict(N=note_str, B=20, J="", R=decision_apo_annuelle, M="")
def etud_semestres_de_etape(self, context, apo_data):
def etud_semestres_de_etape(self, apo_data):
"""
Lorsqu'on a une formation semestrialisée mais avec un code étape annuel,
il faut considérer les deux semestres ((S1,S2) ou (S3,S4)) pour calculer
@ -712,10 +710,9 @@ class ApoData(object):
def set_periode(self, periode): # currently unused
self.periode = periode
def setup(self, context):
def setup(self):
"""Recherche semestres ScoDoc concernés"""
self.context = context
self.sems_etape = comp_apo_sems(context, self.etape_apogee, self.annee_scolaire)
self.sems_etape = comp_apo_sems(self.etape_apogee, self.annee_scolaire)
self.etape_formsemestre_ids = {s["formsemestre_id"] for s in self.sems_etape}
if self.periode != None:
self.sems_periode = [
@ -1114,7 +1111,7 @@ def _apo_skip_section(f):
# -------------------------------------
def comp_apo_sems(context, etape_apogee, annee_scolaire):
def comp_apo_sems(etape_apogee, annee_scolaire):
"""
:param etape_apogee: etape (string or ApoEtapeVDI)
:param annee_scolaire: annee (int)
@ -1125,7 +1122,7 @@ def comp_apo_sems(context, etape_apogee, annee_scolaire):
)
def nar_etuds_table(context, apo_data, NAR_Etuds):
def nar_etuds_table(apo_data, NAR_Etuds):
"""Liste les NAR -> excel table"""
code_etape = apo_data.etape_apogee
today = datetime.datetime.today().strftime("%d/%m/%y")
@ -1183,7 +1180,6 @@ def nar_etuds_table(context, apo_data, NAR_Etuds):
def export_csv_to_apogee(
context,
apo_csv_data,
periode=None,
dest_zip=None,
@ -1211,11 +1207,11 @@ def export_csv_to_apogee(
export_res_sdj=export_res_sdj,
export_res_rat=export_res_rat,
)
apo_data.setup(context) # -> .sems_etape
apo_data.setup() # -> .sems_etape
for e in apo_data.etuds:
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
e.associate_sco(context, apo_data)
e.lookup_scodoc(apo_data.etape_formsemestre_ids)
e.associate_sco(apo_data)
# Ré-écrit le fichier Apogée
f = io.StringIO()
@ -1225,7 +1221,7 @@ def export_csv_to_apogee(
# Table des NAR:
NAR_Etuds = [e for e in apo_data.etuds if e.is_NAR]
if NAR_Etuds:
nar_xls = nar_etuds_table(context, apo_data, NAR_Etuds)
nar_xls = nar_etuds_table(apo_data, NAR_Etuds)
else:
nar_xls = None

View File

@ -109,7 +109,7 @@ class BaseArchiver(object):
scu.GSL.release()
return obj_dir
def list_oids(self, context):
def list_oids(self):
"""
:return: list of archive oids
"""
@ -228,7 +228,7 @@ class BaseArchiver(object):
# XXX très incomplet: devrait inférer et assigner un type MIME
archive_id = self.get_id_from_name(oid, archive_name)
data = self.get(archive_id, filename)
ext = os.path.splitext(scu.strlower(filename))[1]
ext = os.path.splitext(filename.lower())[1]
if ext == ".html" or ext == ".htm":
return data
elif ext == ".xml":
@ -262,7 +262,6 @@ PVArchive = SemsArchiver()
def do_formsemestre_archive(
context,
REQUEST,
formsemestre_id,
group_ids=[], # si indiqué, ne prend que ces groupes
@ -297,14 +296,12 @@ def do_formsemestre_archive(
etudids = [m["etudid"] for m in groups_infos.members]
# Tableau recap notes en XLS (pour tous les etudiants, n'utilise pas les groupes)
data, _, _ = make_formsemestre_recapcomplet(
context, REQUEST, formsemestre_id, format="xls"
)
data, _, _ = make_formsemestre_recapcomplet(formsemestre_id, format="xls")
if data:
PVArchive.store(archive_id, "Tableau_moyennes" + scu.XLSX_SUFFIX, data)
# Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes)
data, _, _ = make_formsemestre_recapcomplet(
context, REQUEST, formsemestre_id, format="html", disable_etudlink=True
formsemestre_id, format="html", disable_etudlink=True
)
if data:
data = "\n".join(
@ -324,25 +321,24 @@ def do_formsemestre_archive(
# Bulletins en XML (pour tous les etudiants, n'utilise pas les groupes)
data, _, _ = make_formsemestre_recapcomplet(
context, REQUEST, formsemestre_id, format="xml", xml_with_decisions=True
formsemestre_id, format="xml", xml_with_decisions=True
)
if data:
PVArchive.store(archive_id, "Bulletins.xml", data)
# Decisions de jury, en XLS
data = sco_pvjury.formsemestre_pvjury(
context, formsemestre_id, format="xls", REQUEST=REQUEST, publish=False
formsemestre_id, format="xls", REQUEST=REQUEST, publish=False
)
if data:
PVArchive.store(archive_id, "Decisions_Jury" + scu.XLSX_SUFFIX, data)
# Classeur bulletins (PDF)
data, _ = sco_bulletins_pdf.get_formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version=bulVersion
formsemestre_id, REQUEST, version=bulVersion
)
if data:
PVArchive.store(archive_id, "Bulletins.pdf", data)
# Lettres individuelles (PDF):
data = sco_pvpdf.pdf_lettres_individuelles(
context,
formsemestre_id,
etudids=etudids,
date_jury=date_jury,
@ -352,13 +348,9 @@ def do_formsemestre_archive(
if data:
PVArchive.store(archive_id, "CourriersDecisions%s.pdf" % groups_filename, data)
# PV de jury (PDF):
dpv = sco_pvjury.dict_pvjury(
context, formsemestre_id, etudids=etudids, with_prev=True
)
dpv = sco_pvjury.dict_pvjury(formsemestre_id, etudids=etudids, with_prev=True)
data = sco_pvpdf.pvjury_pdf(
context,
dpv,
REQUEST,
date_commission=date_commission,
date_jury=date_jury,
numeroArrete=numeroArrete,
@ -372,7 +364,7 @@ def do_formsemestre_archive(
PVArchive.store(archive_id, "PV_Jury%s.pdf" % groups_filename, data)
def formsemestre_archive(context, REQUEST, formsemestre_id, group_ids=[]):
def formsemestre_archive(REQUEST, formsemestre_id, group_ids=[]):
"""Make and store new archive for this formsemestre.
(all students or only selected groups)
"""
@ -474,7 +466,6 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement.
else:
tf[2]["anonymous"] = False
do_formsemestre_archive(
context,
REQUEST,
formsemestre_id,
group_ids=group_ids,

View File

@ -232,12 +232,11 @@ def etud_get_archived_file(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):
def etudarchive_generate_excel_sample(group_id=None, REQUEST=None):
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)"""
fmt = sco_import_etuds.sco_import_format()
data = sco_import_etuds.sco_import_generate_excel_sample(
fmt,
context=context,
group_ids=[group_id],
only_tables=["identite"],
exclude_cols=[
@ -248,14 +247,13 @@ def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
"photo_filename",
],
extra_cols=["fichier_a_charger"],
REQUEST=REQUEST,
)
return sco_excel.send_excel_file(
REQUEST, data, "ImportFichiersEtudiants" + scu.XLSX_SUFFIX
)
def etudarchive_import_files_form(context, group_id, REQUEST=None):
def etudarchive_import_files_form(group_id, REQUEST=None):
"""Formulaire pour importation fichiers d'un groupe"""
H = [
html_sco_header.sco_header(
@ -316,25 +314,21 @@ def etudarchive_import_files_form(context, group_id, REQUEST=None):
)
else:
return etudarchive_import_files(
context,
group_id=tf[2]["group_id"],
xlsfile=tf[2]["xlsfile"],
zipfile=tf[2]["zipfile"],
REQUEST=REQUEST,
description=tf[2]["description"],
)
def etudarchive_import_files(
context, group_id=None, xlsfile=None, zipfile=None, REQUEST=None, description=""
):
def callback(context, etud, data, filename, REQUEST):
def etudarchive_import_files(group_id=None, xlsfile=None, zipfile=None, description=""):
def callback(etud, data, filename):
_store_etud_file_to_new_archive(etud["etudid"], data, filename, description)
filename_title = "fichier_a_charger"
page_title = "Téléchargement de fichiers associés aux étudiants"
# Utilise la fontion au depart developpee pour les photos
r = sco_trombino.zip_excel_import_files(
context, xlsfile, zipfile, REQUEST, callback, filename_title, page_title
xlsfile, zipfile, callback, filename_title, page_title
)
return r + html_sco_header.sco_footer()

View File

@ -80,7 +80,7 @@ from app.scodoc import sco_bulletins_legacy
from app.scodoc import sco_bulletins_ucac # format expérimental UCAC Cameroun
def make_context_dict(context, sem, etud):
def make_context_dict(sem, etud):
"""Construit dictionnaire avec valeurs pour substitution des textes
(preferences bul_pdf_*)
"""
@ -122,7 +122,7 @@ def make_context_dict(context, sem, etud):
def formsemestre_bulletinetud_dict(
context, formsemestre_id, etudid, version="long", REQUEST=None
formsemestre_id, etudid, version="long", REQUEST=None
):
"""Collecte informations pour bulletin de notes
Retourne un dictionnaire (avec valeur par défaut chaine vide).
@ -179,7 +179,6 @@ def formsemestre_bulletinetud_dict(
# --- Decision Jury
infos, dpv = etud_descr_situation_semestre(
context,
etudid,
formsemestre_id,
format="html",
@ -257,7 +256,7 @@ def formsemestre_bulletinetud_dict(
rang = ""
rang_gr, ninscrits_gr, gr_name = get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
)
if nt.get_moduleimpls_attente():
@ -322,7 +321,7 @@ def formsemestre_bulletinetud_dict(
else:
u["ects"] = "-"
modules, ue_attente = _ue_mod_bulletin(
context, etudid, formsemestre_id, ue["ue_id"], modimpls, nt, version
etudid, formsemestre_id, ue["ue_id"], modimpls, nt, version
)
#
u["modules"] = modules # detail des modules de l'UE (dans le semestre courant)
@ -353,7 +352,6 @@ def formsemestre_bulletinetud_dict(
) # > toutes notes
u["modules_capitalized"], _ = _ue_mod_bulletin(
context,
etudid,
formsemestre_id,
ue_status["capitalized_ue_id"],
@ -387,7 +385,7 @@ def formsemestre_bulletinetud_dict(
I["matieres_modules"].update(_sort_mod_by_matiere(modules, nt, etudid))
#
C = make_context_dict(context, I["sem"], I["etud"])
C = make_context_dict(I["sem"], I["etud"])
C.update(I)
#
# log( 'C = \n%s\n' % pprint.pformat(C) ) # tres pratique pour voir toutes les infos dispo
@ -409,7 +407,7 @@ def _sort_mod_by_matiere(modlist, nt, etudid):
return matmod
def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, version):
def _ue_mod_bulletin(etudid, formsemestre_id, ue_id, modimpls, nt, version):
"""Infos sur les modules (et évaluations) dans une UE
(ajoute les informations aux modimpls)
Result: liste de modules de l'UE avec les infos dans chacun (seulement ceux où l'étudiant est inscrit).
@ -600,7 +598,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
def get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
):
"""Ramene rang et nb inscrits dans chaque partition"""
rang_gr, ninscrits_gr, gr_name = {}, {}, {}
@ -624,7 +622,6 @@ def get_etud_rangs_groups(
def etud_descr_situation_semestre(
context,
etudid,
formsemestre_id,
ne="",
@ -722,7 +719,7 @@ def etud_descr_situation_semestre(
infos["descr_decision_jury"] = "Défaillant%s" % ne
infos["situation"] += " " + infos["descr_defaillance"]
dpv = sco_pvjury.dict_pvjury(context, formsemestre_id, etudids=[etudid])
dpv = sco_pvjury.dict_pvjury(formsemestre_id, etudids=[etudid])
if not show_decisions:
return infos, dpv
@ -764,7 +761,6 @@ def etud_descr_situation_semestre(
# ------ Page bulletin
def formsemestre_bulletinetud(
context,
etudid=None,
formsemestre_id=None,
format="html",
@ -782,7 +778,6 @@ def formsemestre_bulletinetud(
return scu.log_unknown_etud(REQUEST, format=format)
bulletin = do_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
format=format,
@ -798,7 +793,7 @@ def formsemestre_bulletinetud(
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
H = [
_formsemestre_bulletinetud_header_html(
context, etud, etudid, sem, formsemestre_id, format, version, REQUEST
etud, etudid, sem, formsemestre_id, format, version, REQUEST
),
bulletin,
]
@ -852,7 +847,6 @@ def can_send_bulletin_by_mail(formsemestre_id):
def do_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
version="long", # short, long, selectedevals
@ -870,7 +864,6 @@ def do_formsemestre_bulletinetud(
"""
if format == "xml":
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
REQUEST=REQUEST,
@ -883,7 +876,6 @@ def do_formsemestre_bulletinetud(
elif format == "json":
bul = sco_bulletins_json.make_json_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
REQUEST=REQUEST,
@ -893,20 +885,17 @@ def do_formsemestre_bulletinetud(
)
return bul, ""
I = formsemestre_bulletinetud_dict(
context, formsemestre_id, etudid, REQUEST=REQUEST
)
I = formsemestre_bulletinetud_dict(formsemestre_id, etudid, REQUEST=REQUEST)
etud = I["etud"]
if format == "html":
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
context, I, version=version, format="html", REQUEST=REQUEST
I, version=version, format="html", REQUEST=REQUEST
)
return htm, I["filigranne"]
elif format == "pdf" or format == "pdfpart":
bul, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
context,
I,
version=version,
format="pdf",
@ -931,11 +920,11 @@ def do_formsemestre_bulletinetud(
htm = "" # speed up if html version not needed
else:
htm, _ = sco_bulletins_generator.make_formsemestre_bulletinetud(
context, I, version=version, format="html", REQUEST=REQUEST
I, version=version, format="html", REQUEST=REQUEST
)
pdfdata, filename = sco_bulletins_generator.make_formsemestre_bulletinetud(
context, I, version=version, format="pdf", REQUEST=REQUEST
I, version=version, format="pdf", REQUEST=REQUEST
)
if prefer_mail_perso:
@ -953,7 +942,7 @@ def do_formsemestre_bulletinetud(
) + htm
return h, I["filigranne"]
#
mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr)
mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr)
emaillink = '<a class="stdlink" href="mailto:%s">%s</a>' % (
recipient_addr,
recipient_addr,
@ -968,7 +957,7 @@ def do_formsemestre_bulletinetud(
raise ValueError("do_formsemestre_bulletinetud: invalid format (%s)" % format)
def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr):
def mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr):
"""Send bulletin by email to etud
If bul_mail_list_abs pref is true, put list of absences in mail body (text).
"""
@ -991,7 +980,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
if sco_preferences.get_preference("bul_mail_list_abs"):
hea += "\n\n" + sco_abs_views.ListeAbsEtud(
context, etud["etudid"], with_evals=False, format="text"
etud["etudid"], with_evals=False, format="text"
)
msg = MIMEMultipart()
@ -1015,11 +1004,10 @@ 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"])
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)
def _formsemestre_bulletinetud_header_html(
context,
etud,
etudid,
sem,
@ -1095,7 +1083,7 @@ def _formsemestre_bulletinetud_header_html(
{
"title": 'Version papier (pdf, format "%s")'
% sco_bulletins_generator.bulletin_get_class_name_displayed(
context, formsemestre_id
formsemestre_id
),
"endpoint": endpoint,
"args": {
@ -1220,7 +1208,7 @@ def _formsemestre_bulletinetud_header_html(
% (
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context, etud, title="fiche de " + etud["nom"], REQUEST=REQUEST
etud, title="fiche de " + etud["nom"], REQUEST=REQUEST
),
)
)

View File

@ -85,7 +85,7 @@ def bulletin_get_class(class_name):
return BULLETIN_CLASSES[class_name]
def bulletin_get_class_name_displayed(context, formsemestre_id):
def bulletin_get_class_name_displayed(formsemestre_id):
"""Le nom du générateur utilisé, en clair"""
from app.scodoc import sco_preferences
@ -106,7 +106,6 @@ class BulletinGenerator(object):
def __init__(
self,
context,
infos,
authuser=None,
version="long",
@ -117,7 +116,6 @@ class BulletinGenerator(object):
if not version in scu.BULLETINS_VERSIONS:
raise ValueError("invalid version code !")
self.context = context
self.infos = infos
self.authuser = authuser # nécessaire pour version HTML qui contient liens dépendant de l'utilisateur
self.version = version
@ -259,7 +257,6 @@ class BulletinGenerator(object):
# ---------------------------------------------------------------------------
def make_formsemestre_bulletinetud(
context,
infos,
version="long", # short, long, selectedevals
format="pdf", # html, pdf
@ -289,7 +286,6 @@ def make_formsemestre_bulletinetud(
try:
PDFLOCK.acquire()
bul_generator = gen_class(
context,
infos,
authuser=REQUEST.AUTHENTICATED_USER,
version=version,
@ -305,7 +301,6 @@ def make_formsemestre_bulletinetud(
bul_class_name = bulletin_default_class_name()
gen_class = bulletin_get_class(bul_class_name)
bul_generator = gen_class(
context,
infos,
authuser=REQUEST.AUTHENTICATED_USER,
version=version,

View File

@ -47,7 +47,6 @@ from app.scodoc import sco_etud
def make_json_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
REQUEST=None,
@ -58,7 +57,6 @@ def make_json_formsemestre_bulletinetud(
"""Renvoie bulletin en chaine JSON"""
d = formsemestre_bulletinetud_published_dict(
context,
formsemestre_id,
etudid,
force_publishing=force_publishing,
@ -77,7 +75,6 @@ def make_json_formsemestre_bulletinetud(
# pour simplifier le code, mais attention a la maintenance !)
#
def formsemestre_bulletinetud_published_dict(
context,
formsemestre_id,
etudid,
force_publishing=False,
@ -129,9 +126,7 @@ def formsemestre_bulletinetud_published_dict(
nom=scu.quote_xml_attr(etudinfo["nom"]),
prenom=scu.quote_xml_attr(etudinfo["prenom"]),
civilite=scu.quote_xml_attr(etudinfo["civilite_str"]),
photo_url=scu.quote_xml_attr(
sco_photos.etud_photo_url(context, etudinfo, fast=True)
),
photo_url=scu.quote_xml_attr(sco_photos.etud_photo_url(etudinfo, fast=True)),
email=scu.quote_xml_attr(etudinfo["email"]),
emailperso=scu.quote_xml_attr(etudinfo["emailperso"]),
)
@ -164,7 +159,7 @@ def formsemestre_bulletinetud_published_dict(
else:
rang = str(nt.get_etud_rang(etudid))
rang_gr, ninscrits_gr, gr_name = sco_bulletins.get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
)
d["note"] = dict(
@ -341,7 +336,6 @@ def formsemestre_bulletinetud_published_dict(
or xml_with_decisions
):
infos, dpv = sco_bulletins.etud_descr_situation_semestre(
context,
etudid,
formsemestre_id,
format="xml",

View File

@ -56,7 +56,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
Renvoie une liste d'objets platypus
"""
objects = sco_bulletins_pdf.process_field(
self.context, self.preferences["bul_pdf_title"], self.infos, self.FieldStyle
self.preferences["bul_pdf_title"], self.infos, self.FieldStyle
)
objects.append(
Spacer(1, 5 * mm)
@ -77,7 +77,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
Renvoie une liste d'objets PLATYPUS (eg instance de Table).
"""
P, pdfTableStyle, colWidths = _bulletin_pdf_table_legacy(
self.context, self.infos, version=self.version
self.infos, version=self.version
)
return [self.buildTableObject(P, pdfTableStyle, colWidths)]
@ -85,7 +85,6 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
"""Génère la table centrale du bulletin de notes: chaine HTML"""
I = self.infos
formsemestre_id = self.infos["formsemestre_id"]
context = self.context
bul_show_abs_modules = sco_preferences.get_preference(
"bul_show_abs_modules", formsemestre_id
@ -285,7 +284,6 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
# ----- DECISION JURY
if self.preferences["bul_show_decision"]:
objects += sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_caption"],
self.infos,
self.FieldStyle,
@ -354,7 +352,6 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
L = [
[
sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_sig_left"],
self.infos,
self.FieldStyle,
@ -366,7 +363,6 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
if show_right:
L[0].append(
sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_sig_right"],
self.infos,
self.FieldStyle,
@ -435,7 +431,7 @@ class BulTableStyle(object):
self.pdfTableStyle.append(("LINEABOVE", (0, i), (-1, i), 1, self.MODSEPCOLOR))
def _bulletin_pdf_table_legacy(context, I, version="long"):
def _bulletin_pdf_table_legacy(I, version="long"):
"""Génère la table centrale du bulletin de notes
Renvoie un triplet:
- table (liste de listes de chaines de caracteres)

View File

@ -76,7 +76,6 @@ def pdfassemblebulletins(
pagesbookmarks,
filigranne=None,
server_name="",
context=None,
):
"generate PDF document from a list of PLATYPUS objects"
if not objects:
@ -109,9 +108,7 @@ def pdfassemblebulletins(
return data
def process_field(
context, field, cdict, style, suppress_empty_pars=False, format="pdf"
):
def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"):
"""Process a field given in preferences, returns
- if format = 'pdf': a list of Platypus objects
- if format = 'html' : a string
@ -165,9 +162,7 @@ def process_field(
return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars)
def get_formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version="selectedevals"
):
def get_formsemestre_bulletins_pdf(formsemestre_id, REQUEST, version="selectedevals"):
"document pdf et filename"
from app.scodoc import sco_bulletins
@ -183,7 +178,6 @@ def get_formsemestre_bulletins_pdf(
i = 1
for etudid in nt.get_etudids():
frag, filigranne = sco_bulletins.do_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
format="pdfpart",
@ -210,7 +204,6 @@ def get_formsemestre_bulletins_pdf(
bookmarks,
filigranne=filigrannes,
server_name=server_name,
context=context,
)
finally:
sco_pdf.PDFLOCK.release()
@ -225,7 +218,7 @@ def get_formsemestre_bulletins_pdf(
return pdfdoc, filename
def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
def get_etud_bulletins_pdf(etudid, REQUEST, version="selectedevals"):
"Bulletins pdf de tous les semestres de l'étudiant, et filename"
from app.scodoc import sco_bulletins
@ -236,7 +229,6 @@ def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
i = 1
for sem in etud["sems"]:
frag, filigranne = sco_bulletins.do_formsemestre_bulletinetud(
context,
sem["formsemestre_id"],
etudid,
format="pdfpart",
@ -262,7 +254,6 @@ def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
bookmarks,
filigranne=filigrannes,
server_name=server_name,
context=context,
)
finally:
sco_pdf.PDFLOCK.release()

View File

@ -56,10 +56,10 @@ et sur page "réglages bulletin" (avec formsemestre_id)
# import os
# def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None):
# def form_change_bul_sig(side, formsemestre_id=None, REQUEST=None):
# """Change pdf signature"""
# filename = _get_sig_existing_filename(
# context, side, formsemestre_id=formsemestre_id
# side, formsemestre_id=formsemestre_id
# )
# if side == "left":
# sidetxt = "gauche"
@ -77,12 +77,12 @@ et sur page "réglages bulletin" (avec formsemestre_id)
# "<p>Photo actuelle (%(signatureloc)s): "
# def get_bul_sig_img(context, side, formsemestre_id=None):
# def get_bul_sig_img(side, formsemestre_id=None):
# "send back signature image data"
# # slow, not cached, used for unfrequent access (do not bypass python)
# def _sig_filename(context, side, formsemestre_id=None):
# def _sig_filename(side, formsemestre_id=None):
# if not side in ("left", "right"):
# raise ValueError("side must be left or right")
# dirs = [SCODOC_LOGOS_DIR, scu.get_dept_id()]
@ -92,13 +92,13 @@ et sur page "réglages bulletin" (avec formsemestre_id)
# return os.path.join(*dirs)
# def _get_sig_existing_filename(context, side, formsemestre_id=None):
# def _get_sig_existing_filename(side, formsemestre_id=None):
# "full path to signature to use, or None if no signature available"
# if formsemestre_id:
# filename = _sig_filename(context, side, formsemestre_id=formsemestre_id)
# filename = _sig_filename(side, formsemestre_id=formsemestre_id)
# if os.path.exists(filename):
# return filename
# filename = _sig_filename(context, side)
# filename = _sig_filename(side)
# if os.path.exists(filename):
# return filename
# else:

View File

@ -76,7 +76,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
Renvoie une liste d'objets platypus
"""
objects = sco_bulletins_pdf.process_field(
self.context, self.preferences["bul_pdf_title"], self.infos, self.FieldStyle
self.preferences["bul_pdf_title"], self.infos, self.FieldStyle
)
objects.append(
Spacer(1, 5 * mm)
@ -179,14 +179,12 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
# ----- DECISION JURY
if self.preferences["bul_show_decision"]:
Op += sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_caption"],
self.infos,
self.FieldStyle,
format="pdf",
)
field = sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_caption"],
self.infos,
self.FieldStyle,
@ -211,7 +209,6 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
L = [
[
sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_sig_left"],
self.infos,
self.FieldStyle,
@ -223,7 +220,6 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
if show_right:
L[0].append(
sco_bulletins_pdf.process_field(
self.context,
self.preferences["bul_pdf_sig_right"],
self.infos,
self.FieldStyle,
@ -275,7 +271,6 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
- largeurs de colonnes pour PDF
"""
I = self.infos
context = self.context
P = [] # elems pour générer table avec gen_table (liste de dicts)
formsemestre_id = I["formsemestre_id"]
prefs = sco_preferences.SemPreferences(formsemestre_id)

View File

@ -70,7 +70,6 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
- largeurs de colonnes pour PDF
"""
I = self.infos
context = self.context
formsemestre_id = I["formsemestre_id"]
prefs = sco_preferences.SemPreferences(formsemestre_id)
@ -304,5 +303,5 @@ class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):
sco_bulletins_generator.register_bulletin_class(BulletinGeneratorUCAC)
def bulletin_table_ucac(context, I, version=None):
def bulletin_table_ucac(I, version=None):
""""""

View File

@ -64,7 +64,6 @@ from app.scodoc import sco_xml
# pour simplifier le code, mais attention a la maintenance !)
#
def make_xml_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
doc=None, # XML document
@ -123,7 +122,7 @@ def make_xml_formsemestre_bulletinetud(
prenom=scu.quote_xml_attr(etudinfo["prenom"]),
civilite=scu.quote_xml_attr(etudinfo["civilite_str"]),
sexe=scu.quote_xml_attr(etudinfo["civilite_str"]), # compat
photo_url=scu.quote_xml_attr(sco_photos.etud_photo_url(context, etudinfo)),
photo_url=scu.quote_xml_attr(sco_photos.etud_photo_url(etudinfo)),
email=scu.quote_xml_attr(etudinfo["email"]),
emailperso=scu.quote_xml_attr(etudinfo["emailperso"]),
)
@ -157,7 +156,7 @@ def make_xml_formsemestre_bulletinetud(
else:
rang = str(nt.get_etud_rang(etudid))
rang_gr, ninscrits_gr, gr_name = sco_bulletins.get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
)
doc.append(
@ -351,7 +350,6 @@ def make_xml_formsemestre_bulletinetud(
or xml_with_decisions
):
infos, dpv = sco_bulletins.etud_descr_situation_semestre(
context,
etudid,
formsemestre_id,
format="xml",

View File

@ -37,7 +37,7 @@
# sco_cache.NotesTableCache.get( formsemestre_id)
# => sco_cache.NotesTableCache.get(formsemestre_id)
#
# sco_core.inval_cache(context, formsemestre_id=None, pdfonly=False, formsemestre_id_list=None)
# sco_core.inval_cache(formsemestre_id=None, pdfonly=False, formsemestre_id_list=None)
# => deprecated, NotesTableCache.invalidate_formsemestre(formsemestre_id=None, pdfonly=False)
#
#
@ -231,8 +231,7 @@ class NotesTableCache(ScoDocCache):
from app.scodoc import notes_table
t0 = time.time()
context = None # XXX TO REMOVE #context
nt = notes_table.NotesTable(context, formsemestre_id)
nt = notes_table.NotesTable(formsemestre_id)
dt = time.time() - t0
log("caching formsemestre_id=%s (%gs)" % (formsemestre_id, dt))
_ = cls.set(formsemestre_id, nt)
@ -240,7 +239,7 @@ class NotesTableCache(ScoDocCache):
return nt
def invalidate_formsemestre( # was inval_cache( context, formsemestre_id=None, pdfonly=False)
def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=False)
formsemestre_id=None, pdfonly=False
):
"""expire cache pour un semestre (ou tous si formsemestre_id non spécifié).

View File

@ -52,7 +52,7 @@ from app.scodoc import sco_moduleimpl
from app.scodoc import sco_etud
def moduleimpl_has_expression(context, mod):
def moduleimpl_has_expression(mod):
"True if we should use a user-defined expression"
expr = mod["computation_expr"]
if not expr:
@ -63,7 +63,7 @@ def moduleimpl_has_expression(context, mod):
return True
def formsemestre_expressions_use_abscounts(context, formsemestre_id):
def formsemestre_expressions_use_abscounts(formsemestre_id):
"""True si les notes de ce semestre dépendent des compteurs d'absences.
Cela n'est normalement pas le cas, sauf si des formules utilisateur utilisent ces compteurs.
"""
@ -80,7 +80,7 @@ def formsemestre_expressions_use_abscounts(context, formsemestre_id):
return True
# 2- moyennes de modules
for mod in sco_moduleimpl.do_moduleimpl_list(formsemestre_id=formsemestre_id):
if moduleimpl_has_expression(context, mod) and ab in mod["computation_expr"]:
if moduleimpl_has_expression(mod) and ab in mod["computation_expr"]:
return True
return False
@ -120,7 +120,6 @@ def get_ue_expression(formsemestre_id, ue_id, cnx, html_quote=False):
def compute_user_formula(
context,
sem,
etudid,
moy,
@ -184,7 +183,7 @@ def compute_user_formula(
return user_moy
def do_moduleimpl_moyennes(context, nt, mod):
def do_moduleimpl_moyennes(nt, mod):
"""Retourne dict { etudid : note_moyenne } pour tous les etuds inscrits
au moduleimpl mod, la liste des evaluations "valides" (toutes notes entrées
ou en attente), et att (vrai s'il y a des notes en attente dans ce module).
@ -219,7 +218,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
key=lambda x: (x["numero"], x["jour"], x["heure_debut"])
) # la plus ancienne en tête
user_expr = moduleimpl_has_expression(context, mod)
user_expr = moduleimpl_has_expression(mod)
attente = False
# recupere les notes de toutes les evaluations
eval_rattr = None
@ -330,7 +329,6 @@ def do_moduleimpl_moyennes(context, nt, mod):
coefs_mask.append(0)
if nb_notes > 0 or formula_use_abs:
user_moy = compute_user_formula(
context,
sem,
etudid,
R[etudid],
@ -367,7 +365,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
return R, valid_evals, attente, diag_info
def do_formsemestre_moyennes(context, nt, formsemestre_id):
def do_formsemestre_moyennes(nt, formsemestre_id):
"""retourne dict { moduleimpl_id : { etudid, note_moyenne_dans_ce_module } },
la liste des moduleimpls, la liste des evaluations valides,
liste des moduleimpls avec notes en attente.
@ -392,7 +390,7 @@ def do_formsemestre_moyennes(context, nt, formsemestre_id):
moduleimpl_id = modimpl["moduleimpl_id"]
assert moduleimpl_id not in D
D[moduleimpl_id], valid_evals_mod, attente, expr_diag = do_moduleimpl_moyennes(
context, nt, modimpl
nt, modimpl
)
valid_evals_per_mod[moduleimpl_id] = valid_evals_mod
valid_evals += valid_evals_mod

View File

@ -40,7 +40,6 @@ from app.scodoc import sco_preferences
def formsemestre_table_estim_cost(
context,
formsemestre_id,
n_group_td=1,
n_group_tp=1,
@ -149,7 +148,6 @@ def formsemestre_table_estim_cost(
def formsemestre_estim_cost(
context,
formsemestre_id,
n_group_td=1,
n_group_tp=1,
@ -166,7 +164,6 @@ def formsemestre_estim_cost(
coef_cours = float(coef_cours)
tab = formsemestre_table_estim_cost(
context,
formsemestre_id,
n_group_td=n_group_td,
n_group_tp=n_group_tp,

View File

@ -47,17 +47,17 @@ from app.scodoc import sco_tag_module
from app.scodoc import sco_etud
def report_debouche_date(context, start_year=None, format="html", REQUEST=None):
def report_debouche_date(start_year=None, format="html", REQUEST=None):
"""Rapport (table) pour les débouchés des étudiants sortis à partir de l'année indiquée."""
if not start_year:
return report_debouche_ask_date(context, REQUEST=REQUEST)
return report_debouche_ask_date(REQUEST=REQUEST)
if format == "xls":
keep_numeric = True # pas de conversion des notes en strings
else:
keep_numeric = False
etudids = get_etudids_with_debouche(context, start_year)
tab = table_debouche_etudids(context, etudids, keep_numeric=keep_numeric)
etudids = get_etudids_with_debouche(start_year)
tab = table_debouche_etudids(etudids, keep_numeric=keep_numeric)
tab.filename = scu.make_filename("debouche_scodoc_%s" % start_year)
tab.origin = "Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr() + ""
@ -73,7 +73,7 @@ def report_debouche_date(context, start_year=None, format="html", REQUEST=None):
)
def get_etudids_with_debouche(context, start_year):
def get_etudids_with_debouche(start_year):
"""Liste des etudids de tous les semestres terminant
à partir du 1er janvier de start_year
et ayant un 'debouche' renseigné.
@ -102,7 +102,7 @@ def get_etudids_with_debouche(context, start_year):
return [x["etudid"] for x in r]
def table_debouche_etudids(context, etudids, keep_numeric=True):
def table_debouche_etudids(etudids, keep_numeric=True):
"""Rapport pour ces etudiants"""
L = []
for etudid in etudids:
@ -139,7 +139,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True):
}
# recherche des débouchés
debouche = itemsuivi_list_etud(context, etudid) # liste de plusieurs items
debouche = itemsuivi_list_etud(etudid) # liste de plusieurs items
if debouche:
row["debouche"] = "<br>".join(
[
@ -192,7 +192,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True):
return tab
def report_debouche_ask_date(context, REQUEST=None):
def report_debouche_ask_date(REQUEST=None):
"""Formulaire demande date départ"""
return (
html_sco_header.sco_header()
@ -247,7 +247,7 @@ def itemsuivi_get(cnx, itemsuivi_id, ignore_errors=False):
return None
def itemsuivi_suppress(context, itemsuivi_id, REQUEST=None):
def itemsuivi_suppress(itemsuivi_id, REQUEST=None):
"""Suppression d'un item"""
if not sco_permissions_check.can_edit_suivi():
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
@ -259,9 +259,7 @@ def itemsuivi_suppress(context, itemsuivi_id, REQUEST=None):
log("suppressed itemsuivi %s" % (itemsuivi_id,))
def itemsuivi_create(
context, etudid, item_date=None, situation="", REQUEST=None, format=None
):
def itemsuivi_create(etudid, item_date=None, situation="", REQUEST=None, format=None):
"""Creation d'un item"""
if not sco_permissions_check.can_edit_suivi():
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
@ -277,7 +275,7 @@ def itemsuivi_create(
return item
def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None):
def itemsuivi_set_date(itemsuivi_id, item_date, REQUEST=None):
"""set item date
item_date is a string dd/mm/yyyy
"""
@ -290,7 +288,7 @@ def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None):
_itemsuivi_edit(cnx, item)
def itemsuivi_set_situation(context, object, value, REQUEST=None):
def itemsuivi_set_situation(object, value, REQUEST=None):
"""set situation"""
if not sco_permissions_check.can_edit_suivi():
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
@ -304,18 +302,18 @@ def itemsuivi_set_situation(context, object, value, REQUEST=None):
return situation or scu.IT_SITUATION_MISSING_STR
def itemsuivi_list_etud(context, etudid, format=None, REQUEST=None):
def itemsuivi_list_etud(etudid, format=None, REQUEST=None):
"""Liste des items pour cet étudiant, avec tags"""
cnx = ndb.GetDBConnexion()
items = _itemsuivi_list(cnx, {"etudid": etudid})
for it in items:
it["tags"] = ", ".join(itemsuivi_tag_list(context, it["itemsuivi_id"]))
it["tags"] = ", ".join(itemsuivi_tag_list(it["itemsuivi_id"]))
if format == "json":
return scu.sendJSON(REQUEST, items)
return items
def itemsuivi_tag_list(context, itemsuivi_id):
def itemsuivi_tag_list(itemsuivi_id):
"""les noms de tags associés à cet item"""
r = ndb.SimpleDictFetch(
"""SELECT t.title
@ -328,7 +326,7 @@ def itemsuivi_tag_list(context, itemsuivi_id):
return [x["title"] for x in r]
def itemsuivi_tag_search(context, term, REQUEST=None):
def itemsuivi_tag_search(term, REQUEST=None):
"""List all used tag names (for auto-completion)"""
# restrict charset to avoid injections
if not scu.ALPHANUM_EXP.match(term):
@ -343,7 +341,7 @@ def itemsuivi_tag_search(context, term, REQUEST=None):
return scu.sendJSON(REQUEST, data)
def itemsuivi_tag_set(context, itemsuivi_id="", taglist=[], REQUEST=None):
def itemsuivi_tag_set(itemsuivi_id="", taglist=[], REQUEST=None):
"""taglist may either be:
a string with tag names separated by commas ("un;deux")
or a list of strings (["un", "deux"])
@ -361,14 +359,14 @@ def itemsuivi_tag_set(context, itemsuivi_id="", taglist=[], REQUEST=None):
_ = itemsuivi_get(cnx, itemsuivi_id)
newtags = set(taglist)
oldtags = set(itemsuivi_tag_list(context, itemsuivi_id))
oldtags = set(itemsuivi_tag_list(itemsuivi_id))
to_del = oldtags - newtags
to_add = newtags - oldtags
# should be atomic, but it's not.
for tagname in to_add:
t = ItemSuiviTag(context, tagname, object_id=itemsuivi_id)
t = ItemSuiviTag(tagname, object_id=itemsuivi_id)
for tagname in to_del:
t = ItemSuiviTag(context, tagname)
t = ItemSuiviTag(tagname)
t.remove_tag_from_object(itemsuivi_id)
return "", http.HTTPStatus.NO_CONTENT

View File

@ -45,16 +45,16 @@ from app.scodoc import sco_up_to_date
from app.scodoc import sco_users
def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
def index_html(REQUEST=None, showcodes=0, showsemtable=0):
"Page accueil département (liste des semestres)"
showsemtable = int(showsemtable)
H = []
# News:
H.append(sco_news.scolar_news_summary_html(context))
H.append(sco_news.scolar_news_summary_html())
# Avertissement de mise à jour:
H.append(sco_up_to_date.html_up_to_date_box(context))
H.append(sco_up_to_date.html_up_to_date_box())
# Liste de toutes les sessions:
sems = sco_formsemestre.do_formsemestre_list()
@ -105,7 +105,7 @@ def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
# Liste des formsemestres "courants"
if cursems:
H.append('<h2 class="listesems">Sessions en cours</h2>')
H.append(_sem_table(context, cursems))
H.append(_sem_table(cursems))
else:
# aucun semestre courant: affiche aide
H.append(
@ -125,7 +125,7 @@ def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
"""
% sco_preferences.get_preference("DeptName")
)
H.append(_sem_table_gt(context, sems).html())
H.append(_sem_table_gt(sems).html())
H.append("</table>")
if not showsemtable:
H.append(
@ -178,7 +178,7 @@ Chercher étape courante: <input name="etape_apo" type="text" size="8" spellchec
return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
def _sem_table(context, sems):
def _sem_table(sems):
"""Affiche liste des semestres, utilisée pour semestres en cours"""
tmpl = """<tr class="%(trclass)s">%(tmpcode)s
<td class="semicon">%(lockimg)s <a href="%(notes_url)s/formsemestre_status?formsemestre_id=%(formsemestre_id)s#groupes">%(groupicon)s</a></td>
@ -190,7 +190,7 @@ def _sem_table(context, sems):
"""
# Liste des semestres, groupés par modalités
sems_by_mod, modalites = sco_modalites.group_sems_by_modalite(context, sems)
sems_by_mod, modalites = sco_modalites.group_sems_by_modalite(sems)
H = ['<table class="listesems">']
for modalite in modalites:
@ -211,9 +211,9 @@ def _sem_table(context, sems):
return "\n".join(H)
def _sem_table_gt(context, sems, showcodes=False):
def _sem_table_gt(sems, showcodes=False):
"""Nouvelle version de la table des semestres"""
_style_sems(context, sems)
_style_sems(sems)
columns_ids = (
"lockimg",
"semestre_id_n",
@ -249,7 +249,7 @@ def _sem_table_gt(context, sems, showcodes=False):
return tab
def _style_sems(context, sems):
def _style_sems(sems):
"""ajoute quelques attributs de présentation pour la table"""
for sem in sems:
sem["notes_url"] = scu.NotesURL()

View File

@ -64,7 +64,7 @@ from app.scodoc.sco_exceptions import ScoValueError
SCO_DUMP_LOCK = "/tmp/scodump.lock"
def sco_dump_and_send_db(context, REQUEST=None):
def sco_dump_and_send_db(REQUEST=None):
"""Dump base de données et l'envoie anonymisée pour debug"""
H = [html_sco_header.sco_header(page_title="Assistance technique")]
# get currect (dept) DB name:
@ -93,7 +93,7 @@ def sco_dump_and_send_db(context, REQUEST=None):
_anonymize_db(ano_db_name)
# Send
r = _send_db(context, REQUEST, ano_db_name)
r = _send_db(REQUEST, ano_db_name)
if (
r.status_code
== requests.codes.INSUFFICIENT_STORAGE # pylint: disable=no-member
@ -164,14 +164,14 @@ def _anonymize_db(ano_db_name):
)
def _get_scodoc_serial(context):
def _get_scodoc_serial():
try:
return int(open(os.path.join(scu.SCODOC_VERSION_DIR, "scodoc.sn")).read())
except:
return 0
def _send_db(context, REQUEST, ano_db_name):
def _send_db(REQUEST, ano_db_name):
"""Dump this (anonymized) database and send it to tech support"""
log("dumping anonymized database {}".format(ano_db_name))
try:
@ -189,7 +189,7 @@ def _send_db(context, REQUEST, ano_db_name):
files=files,
data={
"dept_name": sco_preferences.get_preference("DeptName"),
"serial": _get_scodoc_serial(context),
"serial": _get_scodoc_serial(),
"sco_user": str(REQUEST.AUTHENTICATED_USER),
"sent_by": sco_users.user_info(str(REQUEST.AUTHENTICATED_USER))[
"nomcomplet"

View File

@ -207,7 +207,7 @@ def module_create(matiere_id=None, REQUEST=None):
{
"input_type": "menu",
"type": "int",
"title": scu.strcapitalize(parcours.SESSION_NAME),
"title": parcours.SESSION_NAME.capitalize(),
"explanation": "%s de début du module dans la formation standard"
% parcours.SESSION_NAME,
"labels": [str(x) for x in semestres_indices],

View File

@ -305,7 +305,7 @@ def ue_edit(ue_id=None, create=False, formation_id=None, REQUEST=None):
{
"input_type": "menu",
"type": "int",
"title": scu.strcapitalize(parcours.SESSION_NAME),
"title": parcours.SESSION_NAME.capitalize(),
"explanation": "%s de début du module dans la formation"
% parcours.SESSION_NAME,
"labels": [str(x) for x in semestres_indices],

View File

@ -47,7 +47,7 @@ from app.scodoc import sco_groups_view
from app.scodoc import sco_preferences
def formsemestre_get_ics_url(context, sem):
def formsemestre_get_ics_url(sem):
"""
edt_sem_ics_url est un template
utilisé avec .format(sem=sem)
@ -72,10 +72,10 @@ def formsemestre_get_ics_url(context, sem):
return ics_url
def formsemestre_load_ics(context, sem):
def formsemestre_load_ics(sem):
"""Load ics data, from our cache or, when necessary, from external provider"""
# TODO: cacher le résultat
ics_url = formsemestre_get_ics_url(context, sem)
ics_url = formsemestre_get_ics_url(sem)
if not ics_url:
ics_data = ""
else:
@ -90,13 +90,13 @@ def formsemestre_load_ics(context, sem):
return cal
# def formsemestre_edt_groups_used(context, sem):
# def formsemestre_edt_groups_used(sem):
# """L'ensemble des groupes EDT utilisés dans l'emploi du temps publié"""
# cal = formsemestre_load_ics(context, sem)
# cal = formsemestre_load_ics(sem)
# return {e["X-GROUP-ID"].decode("utf8") for e in events}
def get_edt_transcodage_groups(context, formsemestre_id):
def get_edt_transcodage_groups(formsemestre_id):
"""-> { nom_groupe_edt : nom_groupe_scodoc }"""
# TODO: valider ces données au moment où on enregistre les préférences
edt2sco = {}
@ -123,7 +123,7 @@ def get_edt_transcodage_groups(context, formsemestre_id):
return edt2sco, sco2edt, msg
def group_edt_json(context, group_id, start="", end="", REQUEST=None):
def group_edt_json(group_id, start="", end="", REQUEST=None): # actuellement inutilisé
"""EDT complet du semestre, au format JSON
TODO: indiquer un groupe
TODO: utiliser start et end (2 dates au format ISO YYYY-MM-DD)
@ -131,14 +131,12 @@ def group_edt_json(context, group_id, start="", end="", REQUEST=None):
"""
group = sco_groups.get_group(group_id)
sem = sco_formsemestre.get_formsemestre(group["formsemestre_id"])
edt2sco, sco2edt, msg = get_edt_transcodage_groups(
context, group["formsemestre_id"]
)
edt2sco, sco2edt, msg = get_edt_transcodage_groups(group["formsemestre_id"])
edt_group_name = sco2edt.get(group["group_name"], group["group_name"])
log("group scodoc=%s : edt=%s" % (group["group_name"], edt_group_name))
cal = formsemestre_load_ics(context, sem)
cal = formsemestre_load_ics(sem)
events = [e for e in cal.walk() if e.name == "VEVENT"]
J = []
for e in events:
@ -161,7 +159,9 @@ for e in events:
"""
def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=None):
def experimental_calendar(
group_id=None, formsemestre_id=None, REQUEST=None
): # inutilisé
"""experimental page"""
return "\n".join(
[
@ -191,7 +191,7 @@ def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=
"""<form id="group_selector" method="get">
<span style="font-weight: bold; font-size:120%">Emplois du temps du groupe</span>""",
sco_groups_view.menu_group_choice(
context, group_id=group_id, formsemestre_id=formsemestre_id
group_id=group_id, formsemestre_id=formsemestre_id
),
"""</form><div id="loading">loading...</div>
<div id="calendar"></div>

View File

@ -48,11 +48,11 @@ from app.scodoc.notes_log import log
from app.scodoc import VERSION
def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8
def sendEmail(msg): # TODO A REECRIRE ScoDoc8
"""Send an email to the address using the mailhost, if there is one."""
raise NotImplementedError()
try:
mail_host = context.MailHost
mail_host = xxx.MailHost
except:
log("warning: sendEmail: no MailHost found !")
return
@ -66,7 +66,7 @@ def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8
pass
def sendEmailFromException(context, msg):
def sendEmailFromException(msg):
# Send email by hand, as it seems to be not possible to use Zope Mail Host
# from an exception handler (see https://bugs.launchpad.net/zope2/+bug/246748)
log("sendEmailFromException")
@ -80,13 +80,13 @@ def sendEmailFromException(context, msg):
log("an exception occurred sending mail")
def send_debug_alert(context, txt, REQUEST=None):
def send_debug_alert(txt, REQUEST=None):
"""Send an alert email (bug report) to ScoDoc developpers"""
if not scu.SCO_EXC_MAIL:
log("send_debug_alert: email disabled")
return
if REQUEST:
txt = _report_request(context, REQUEST) + txt
txt = _report_request(REQUEST) + txt
URL = REQUEST.URL
else:
URL = "send_debug_alert"
@ -98,11 +98,11 @@ def send_debug_alert(context, txt, REQUEST=None):
msg["From"] = "scodoc-alert"
msg.epilogue = ""
msg.attach(MIMEText(txt, "plain", scu.SCO_ENCODING))
sendEmailFromException(context, msg)
sendEmailFromException(msg)
log("Sent mail alert:\n" + txt)
def _report_request(context, REQUEST, fmt="txt"):
def _report_request(REQUEST, fmt="txt"):
"""string describing current request for bug reports"""
QUERY_STRING = REQUEST.QUERY_STRING
if QUERY_STRING:

View File

@ -67,7 +67,6 @@ class EntreprisesEditor(EditableTable):
test="=",
sortkey=None,
sort_on_contact=False,
context=None,
limit="",
offset="",
):
@ -85,7 +84,6 @@ class EntreprisesEditor(EditableTable):
if sort_on_contact:
for r in R:
c = do_entreprise_contact_list(
context,
args={"entreprise_id": r["entreprise_id"]},
disable_formatting=True,
)
@ -199,95 +197,94 @@ _entreprise_contactEditor = EditableTable(
)
def do_entreprise_create(context, args):
def do_entreprise_create(args):
"entreprise_create"
cnx = ndb.GetDBConnexion()
r = _entreprisesEditor.create(cnx, args)
return r
def do_entreprise_delete(context, oid):
def do_entreprise_delete(oid):
"entreprise_delete"
cnx = ndb.GetDBConnexion()
_entreprisesEditor.delete(cnx, oid)
def do_entreprise_list(context, **kw):
def do_entreprise_list(**kw):
"entreprise_list"
cnx = ndb.GetDBConnexion()
kw["context"] = context
return _entreprisesEditor.list(cnx, **kw)
def do_entreprise_list_by_etud(context, **kw):
def do_entreprise_list_by_etud(**kw):
"entreprise_list_by_etud"
cnx = ndb.GetDBConnexion()
return _entreprisesEditor.list_by_etud(cnx, **kw)
def do_entreprise_edit(context, *args, **kw):
def do_entreprise_edit(*args, **kw):
"entreprise_edit"
cnx = ndb.GetDBConnexion()
_entreprisesEditor.edit(cnx, *args, **kw)
def do_entreprise_correspondant_create(context, args):
def do_entreprise_correspondant_create(args):
"entreprise_correspondant_create"
cnx = ndb.GetDBConnexion()
r = _entreprise_correspEditor.create(cnx, args)
return r
def do_entreprise_correspondant_delete(context, oid):
def do_entreprise_correspondant_delete(oid):
"entreprise_correspondant_delete"
cnx = ndb.GetDBConnexion()
_entreprise_correspEditor.delete(cnx, oid)
def do_entreprise_correspondant_list(context, **kw):
def do_entreprise_correspondant_list(**kw):
"entreprise_correspondant_list"
cnx = ndb.GetDBConnexion()
return _entreprise_correspEditor.list(cnx, **kw)
def do_entreprise_correspondant_edit(context, *args, **kw):
def do_entreprise_correspondant_edit(*args, **kw):
"entreprise_correspondant_edit"
cnx = ndb.GetDBConnexion()
_entreprise_correspEditor.edit(cnx, *args, **kw)
def do_entreprise_correspondant_listnames(context, args={}):
def do_entreprise_correspondant_listnames(args={}):
"-> liste des noms des correspondants (pour affichage menu)"
C = do_entreprise_correspondant_list(context, args=args)
C = do_entreprise_correspondant_list(args=args)
return [(x["prenom"] + " " + x["nom"], str(x["entreprise_corresp_id"])) for x in C]
def do_entreprise_contact_delete(context, oid):
def do_entreprise_contact_delete(oid):
"entreprise_contact_delete"
cnx = ndb.GetDBConnexion()
_entreprise_contactEditor.delete(cnx, oid)
def do_entreprise_contact_list(context, **kw):
def do_entreprise_contact_list(**kw):
"entreprise_contact_list"
cnx = ndb.GetDBConnexion()
return _entreprise_contactEditor.list(cnx, **kw)
def do_entreprise_contact_edit(context, *args, **kw):
def do_entreprise_contact_edit(*args, **kw):
"entreprise_contact_edit"
cnx = ndb.GetDBConnexion()
_entreprise_contactEditor.edit(cnx, *args, **kw)
def do_entreprise_contact_create(context, args):
def do_entreprise_contact_create(args):
"entreprise_contact_create"
cnx = ndb.GetDBConnexion()
r = _entreprise_contactEditor.create(cnx, args)
return r
def do_entreprise_check_etudiant(context, etudiant):
def do_entreprise_check_etudiant(etudiant):
"""Si etudiant est vide, ou un ETUDID valide, ou un nom unique,
retourne (1, ETUDID).
Sinon, retourne (0, 'message explicatif')
@ -315,8 +312,7 @@ def do_entreprise_check_etudiant(context, etudiant):
e = ['<ul class="entreprise_etud_list">']
for x in r:
e.append(
"<li>%s %s (code %s)</li>"
% (scu.strupper(x[1]), x[2] or "", x[0].strip())
"<li>%s %s (code %s)</li>" % ((x[1]).upper(), x[2] or "", x[0].strip())
)
e.append("</ul>")
return (

View File

@ -43,19 +43,19 @@
apo_csv_get()
API:
apo_csv_store(context, csv, annee_scolaire, sem_id)
apo_csv_store( annee_scolaire, sem_id)
store maq file (archive)
apo_csv_get(context, etape_apo, annee_scolaire, sem_id, vdi_apo=None)
apo_csv_get(etape_apo, annee_scolaire, sem_id, vdi_apo=None)
get maq data (read stored file and returns string)
if vdi_apo, get maq for this etape/vdi, else returns the first matching etape.
apo_csv_delete(context, etape_apo, annee_scolaire, sem_id)
apo_csv_delete(etape_apo, annee_scolaire, sem_id)
apo_csv_list_stored_etapes(context, annee_scolaire=None, sem_id=None, etapes=None)
apo_csv_list_stored_etapes(annee_scolaire=None, sem_id=None, etapes=None)
returns: liste des codes etapes et version vdi stockés (pour l'annee_scolaire et le sem_id indiqués)
apo_csv_semset_check(context, semset)
apo_csv_semset_check(semset)
check students in stored maqs vs students in sem
Cas à détecter:
- etudiants ScoDoc sans code NIP
@ -70,7 +70,7 @@
dups_apo : liste de { 'NIP', 'nom', 'prenom', 'etapes_apo' }
etapes_missing_csv : liste des étapes du semestre sans maquette CSV
apo_csv_check_etape(context, semset, set_nips, etape_apo)
apo_csv_check_etape(semset, set_nips, etape_apo)
check une etape
"""
@ -91,7 +91,7 @@ class ApoCSVArchiver(sco_archives.BaseArchiver):
ApoCSVArchive = ApoCSVArchiver()
# def get_sem_apo_archive(context, formsemestre_id):
# def get_sem_apo_archive(formsemestre_id):
# """Get, or create if necessary, the archive for apo CSV files"""
# archive_id
@ -99,7 +99,7 @@ ApoCSVArchive = ApoCSVArchiver()
# return archive_id
def apo_csv_store(context, csv_data, annee_scolaire, sem_id):
def apo_csv_store(csv_data, annee_scolaire, sem_id):
"""
csv_data: maquette content, as a string, encoding given by APO_INPUT_ENCODING (latin-1, not utf8)
annee_scolaire: int (2016)
@ -120,9 +120,7 @@ def apo_csv_store(context, csv_data, annee_scolaire, sem_id):
filename = str(apo_data.etape) + ".csv" # will concatenate VDI to etape
if str(apo_data.etape) in apo_csv_list_stored_etapes(
context, annee_scolaire, sem_id=sem_id
):
if str(apo_data.etape) in apo_csv_list_stored_etapes(annee_scolaire, sem_id=sem_id):
raise ScoValueError(
"Etape %s déjà stockée pour cette année scolaire !" % apo_data.etape
)
@ -135,14 +133,12 @@ def apo_csv_store(context, csv_data, annee_scolaire, sem_id):
return apo_data.etape
def apo_csv_list_stored_archives(
context, annee_scolaire=None, sem_id=None, etapes=None
):
def apo_csv_list_stored_archives(annee_scolaire=None, sem_id=None, etapes=None):
"""
:return: list of informations about stored CSV
[ { } ]
"""
oids = ApoCSVArchive.list_oids(context) # [ '2016-1', ... ]
oids = ApoCSVArchive.list_oids() # [ '2016-1', ... ]
# filter
if annee_scolaire:
e = re.compile(str(annee_scolaire) + "-.+")
@ -177,25 +173,25 @@ def apo_csv_list_stored_archives(
return infos
def apo_csv_list_stored_etapes(context, annee_scolaire, sem_id=None, etapes=None):
def apo_csv_list_stored_etapes(annee_scolaire, sem_id=None, etapes=None):
"""
:return: list of stored etapes [ ApoEtapeVDI, ... ]
"""
infos = apo_csv_list_stored_archives(
context, annee_scolaire=annee_scolaire, sem_id=sem_id, etapes=etapes
annee_scolaire=annee_scolaire, sem_id=sem_id, etapes=etapes
)
return [info["etape_apo"] for info in infos]
def apo_csv_delete(context, archive_id):
def apo_csv_delete(archive_id):
"""Delete archived CSV"""
ApoCSVArchive.delete_archive(archive_id)
def apo_csv_get_archive(context, etape_apo, annee_scolaire="", sem_id=""):
def apo_csv_get_archive(etape_apo, annee_scolaire="", sem_id=""):
"""Get archive"""
stored_archives = apo_csv_list_stored_archives(
context, annee_scolaire=annee_scolaire, sem_id=sem_id
annee_scolaire=annee_scolaire, sem_id=sem_id
)
for info in stored_archives:
if info["etape_apo"] == etape_apo:
@ -203,11 +199,11 @@ def apo_csv_get_archive(context, etape_apo, annee_scolaire="", sem_id=""):
return None
def apo_csv_get(context, etape_apo="", annee_scolaire="", sem_id=""):
def apo_csv_get(etape_apo="", annee_scolaire="", sem_id=""):
"""Get CSV data for given etape_apo
:return: CSV, as a data string
"""
info = apo_csv_get_archive(context, etape_apo, annee_scolaire, sem_id)
info = apo_csv_get_archive(etape_apo, annee_scolaire, sem_id)
if not info:
raise ScoValueError(
"Etape %s non enregistree (%s, %s)" % (etape_apo, annee_scolaire, sem_id)
@ -220,7 +216,7 @@ def apo_csv_get(context, etape_apo="", annee_scolaire="", sem_id=""):
# ------------------------------------------------------------------------
def apo_get_sem_etapes(context, sem):
def apo_get_sem_etapes(sem):
"""Etapes de ce semestre: pour l'instant, celles déclarées
Dans une future version, on pourrait aussi utiliser les étapes
d'inscription des étudiants, recupérées via le portail,
@ -231,12 +227,10 @@ def apo_get_sem_etapes(context, sem):
return sem["etapes"]
def apo_csv_check_etape(context, semset, set_nips, etape_apo):
def apo_csv_check_etape(semset, set_nips, etape_apo):
"""Check etape vs set of sems"""
# Etudiants dans la maquette CSV:
csv_data = apo_csv_get(
context, etape_apo, semset["annee_scolaire"], semset["sem_id"]
)
csv_data = apo_csv_get(etape_apo, semset["annee_scolaire"], semset["sem_id"])
apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"])
apo_nips = {e["nip"] for e in apo_data.etuds}
#
@ -245,14 +239,14 @@ def apo_csv_check_etape(context, semset, set_nips, etape_apo):
nips_no_sco = apo_nips - set_nips # dans Apogée mais pas dans ScoDoc
# Elements Apogee vs ScoDoc
apo_data.setup(context)
apo_data.setup()
maq_elems, sem_elems = apo_data.list_elements()
return nips_ok, apo_nips, nips_no_apo, nips_no_sco, maq_elems, sem_elems
def apo_csv_semset_check(
context, semset, allow_missing_apo=False, allow_missing_csv=False
semset, allow_missing_apo=False, allow_missing_csv=False
): # was apo_csv_check
"""
check students in stored maqs vs students in semset
@ -266,7 +260,7 @@ def apo_csv_semset_check(
"""
# Etapes du semestre sans maquette CSV:
etapes_apo = apo_csv_list_stored_etapes(
context, semset["annee_scolaire"], semset["sem_id"], etapes=semset.list_etapes()
semset["annee_scolaire"], semset["sem_id"], etapes=semset.list_etapes()
)
etapes_missing_csv = []
for e in semset.list_etapes():
@ -292,7 +286,7 @@ def apo_csv_semset_check(
et_nips_no_sco,
et_maq_elems,
et_sem_elems,
) = apo_csv_check_etape(context, semset, set_nips, etape_apo)
) = apo_csv_check_etape(semset, set_nips, etape_apo)
nips_ok |= et_nips_ok
nips_no_apo -= et_apo_nips
nips_no_sco |= et_nips_no_sco
@ -330,19 +324,15 @@ def apo_csv_semset_check(
)
def apo_csv_retreive_etuds_by_nip(context, semset, nips):
def apo_csv_retreive_etuds_by_nip(semset, nips):
"""
Search info about listed nips in stored CSV
:return: list [ { 'etape_apo', 'nip', 'nom', 'prenom' } ]
"""
apo_etuds_by_nips = {}
etapes_apo = apo_csv_list_stored_etapes(
context, semset["annee_scolaire"], semset["sem_id"]
)
etapes_apo = apo_csv_list_stored_etapes(semset["annee_scolaire"], semset["sem_id"])
for etape_apo in etapes_apo:
csv_data = apo_csv_get(
context, etape_apo, semset["annee_scolaire"], semset["sem_id"]
)
csv_data = apo_csv_get(etape_apo, semset["annee_scolaire"], semset["sem_id"])
apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"])
etape_apo = apo_data.etape_apogee
for e in apo_data.etuds:
@ -367,7 +357,7 @@ from app.scodoc.sco_etape_apogee import *
from app.scodoc.sco_apogee_csv import *
from app.scodoc.sco_semset import *
context = go_dept(app, 'RT').Notes
app.set_sco_dept('RT')
csv_data = open('/opt/misc/VDTRT_V1RT.TXT').read()
annee_scolaire=2015
sem_id=1
@ -375,15 +365,15 @@ sem_id=1
apo_data = sco_apogee_csv.ApoData(csv_data, periode=sem_id)
print apo_data.etape_apogee
apo_data.setup(context)
apo_data.setup()
e = apo_data.etuds[0]
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
e.associate_sco(context, apo_data)
e.lookup_scodoc( apo_data.etape_formsemestre_ids)
e.associate_sco( apo_data)
print apo_csv_list_stored_archives(context)
print apo_csv_list_stored_archives()
apo_csv_store(context, csv_data, annee_scolaire, sem_id)
apo_csv_store(csv_data, annee_scolaire, sem_id)
@ -392,24 +382,24 @@ groups_infos = sco_groups_view.DisplayedGroupsInfos( [sco_groups.get_default_gro
nt = sco_cache.NotesTableCache.get( formsemestre_id)
#
s = SemSet(context, 'NSS29902')
s = SemSet('NSS29902')
apo_data = sco_apogee_csv.ApoData(open('/opt/scodoc/var/scodoc/archives/apo_csv/RT/2015-2/2016-07-10-11-26-15/V1RT.csv').read(), periode=1)
# cas Tiziri K. (inscrite en S1, démission en fin de S1, pas inscrite en S2)
# => pas de décision, ce qui est voulu (?)
#
apo_data.setup(context)
apo_data.setup()
e = [ e for e in apo_data.etuds if e['nom'] == 'XYZ' ][0]
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
e.associate_sco(context, apo_data)
e.lookup_scodoc( apo_data.etape_formsemestre_ids)
e.associate_sco(apo_data)
self=e
col_id='apoL_c0129'
# --
from app.scodoc import sco_portal_apogee
context = go_dept(app, 'GEA').Notes
_ = go_dept(app, 'GEA').Notes
#csv_data = sco_portal_apogee.get_maquette_apogee(etape='V1GE', annee_scolaire=2015)
csv_data = open('/tmp/V1GE.txt').read()
apo_data = sco_apogee_csv.ApoData(csv_data, periode=1)
@ -426,7 +416,7 @@ from app.scodoc.sco_etape_apogee import *
from app.scodoc.sco_apogee_csv import *
from app.scodoc.sco_semset import *
context = go_dept(app, 'RT').Notes
_ = go_dept(app, 'RT').Notes
csv_data = open('/opt/misc/V2RT.csv').read()
annee_scolaire=2015
sem_id=1
@ -434,10 +424,10 @@ sem_id=1
apo_data = sco_apogee_csv.ApoData(csv_data, periode=1)
print apo_data.etape_apogee
apo_data.setup(context)
apo_data.setup()
for e in apo_data.etuds:
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
e.associate_sco(context, apo_data)
e.lookup_scodoc( apo_data.etape_formsemestre_ids)
e.associate_sco(apo_data)
# ------
# test export jury intermediaire
@ -449,7 +439,7 @@ from app.scodoc.sco_etape_apogee import *
from app.scodoc.sco_apogee_csv import *
from app.scodoc.sco_semset import *
context = go_dept(app, 'CJ').Notes
_ = go_dept(app, 'CJ').Notes
csv_data = open('/opt/scodoc/var/scodoc/archives/apo_csv/CJ/2016-1/2017-03-06-21-46-32/V1CJ.csv').read()
annee_scolaire=2016
sem_id=1
@ -457,10 +447,10 @@ sem_id=1
apo_data = sco_apogee_csv.ApoData(csv_data, periode=1)
print apo_data.etape_apogee
apo_data.setup(context)
apo_data.setup()
e = [ e for e in apo_data.etuds if e['nom'] == 'XYZ' ][0] #
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
e.associate_sco(context, apo_data)
e.lookup_scodoc( apo_data.etape_formsemestre_ids)
e.associate_sco(apo_data)
self=e

View File

@ -54,7 +54,6 @@ from app.scodoc.sco_exceptions import ScoValueError
def apo_semset_maq_status(
context,
semset_id="",
allow_missing_apo=False,
allow_missing_decisions=False,
@ -69,7 +68,7 @@ def apo_semset_maq_status(
"""Page statut / tableau de bord"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
semset.fill_formsemestres()
# autorise export meme si etudiants Apo manquants:
allow_missing_apo = int(allow_missing_apo)
@ -85,7 +84,7 @@ def apo_semset_maq_status(
prefs = sco_preferences.SemPreferences()
tab_archives = table_apo_csv_list(context, semset, REQUEST=REQUEST)
tab_archives = table_apo_csv_list(semset, REQUEST=REQUEST)
(
ok_for_export,
@ -98,7 +97,7 @@ def apo_semset_maq_status(
maq_elems,
sem_elems,
) = sco_etape_apogee.apo_csv_semset_check(
context, semset, allow_missing_apo, allow_missing_csv
semset, allow_missing_apo, allow_missing_csv
)
if not allow_missing_decisions:
@ -432,20 +431,18 @@ def apo_semset_maq_status(
return "\n".join(H)
def table_apo_csv_list(context, semset, REQUEST=None):
def table_apo_csv_list(semset, REQUEST=None):
"""Table des archives (triée par date d'archivage)"""
annee_scolaire = semset["annee_scolaire"]
sem_id = semset["sem_id"]
T = sco_etape_apogee.apo_csv_list_stored_archives(
context, annee_scolaire, sem_id, etapes=semset.list_etapes()
annee_scolaire, sem_id, etapes=semset.list_etapes()
)
for t in T:
# Ajoute qq infos pour affichage:
csv_data = sco_etape_apogee.apo_csv_get(
context, t["etape_apo"], annee_scolaire, sem_id
)
csv_data = sco_etape_apogee.apo_csv_get(t["etape_apo"], annee_scolaire, sem_id)
apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"])
t["filename"] = apo_data.titles["apoC_Fichier_Exp"]
t["nb_etuds"] = len(apo_data.etuds)
@ -488,17 +485,17 @@ def table_apo_csv_list(context, semset, REQUEST=None):
return tab
def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST=None):
def view_apo_etuds(semset_id, title="", nips=[], format="html", REQUEST=None):
"""Table des étudiants Apogée par nips"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
# annee_scolaire = semset["annee_scolaire"]
# sem_id = semset["sem_id"]
if nips and type(nips) != type([]):
nips = [nips]
etuds = sco_etape_apogee.apo_csv_retreive_etuds_by_nip(context, semset, nips)
etuds = sco_etape_apogee.apo_csv_retreive_etuds_by_nip(semset, nips)
# Ils sont parfois dans ScoDoc même si pas dans le semestre: essaie de les retrouver
for etud in etuds.values():
etud_sco = sco_etud.get_etud_info(code_nip=etud["nip"], filled=True)
@ -514,7 +511,6 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST
)
return _view_etuds_page(
context,
semset_id,
title=title,
etuds=list(etuds.values()),
@ -525,7 +521,7 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST
def view_scodoc_etuds(
context, semset_id, title="", etudids=None, nips=None, format="html", REQUEST=None
semset_id, title="", etudids=None, nips=None, format="html", REQUEST=None
):
"""Table des étudiants ScoDoc par nips ou etudids"""
if etudids is not None:
@ -549,7 +545,6 @@ def view_scodoc_etuds(
e["_prenom_td_attrs"] = 'id="pre-%s" class="etudinfo"' % (e["etudid"],)
return _view_etuds_page(
context,
semset_id,
title=title,
etuds=etuds,
@ -560,7 +555,7 @@ def view_scodoc_etuds(
def _view_etuds_page(
context, semset_id, title="", etuds=[], keys=(), format="html", REQUEST=None
semset_id, title="", etuds=[], keys=(), format="html", REQUEST=None
):
# Tri les étudiants par nom:
if etuds:
@ -605,7 +600,7 @@ def _view_etuds_page(
def view_apo_csv_store(
context, semset_id="", csvfile=None, data="", autodetect=False, REQUEST=None
semset_id="", csvfile=None, data="", autodetect=False, REQUEST=None
):
"""Store CSV data
Le semset identifie l'annee scolaire et le semestre
@ -613,7 +608,7 @@ def view_apo_csv_store(
"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
if csvfile:
data = csvfile.read()
@ -636,18 +631,16 @@ def view_apo_csv_store(
"Le code étape de ce fichier ne correspond pas à ceux de cet ensemble"
)
sco_etape_apogee.apo_csv_store(
context, data, semset["annee_scolaire"], semset["sem_id"]
)
sco_etape_apogee.apo_csv_store(data, semset["annee_scolaire"], semset["sem_id"])
return flask.redirect("apo_semset_maq_status?semset_id=" + semset_id)
def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST=None):
def view_apo_csv_download_and_store(etape_apo="", semset_id="", REQUEST=None):
"""Download maquette and store it"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
data = sco_portal_apogee.get_maquette_apogee(
etape=etape_apo, annee_scolaire=semset["annee_scolaire"]
@ -655,18 +648,16 @@ def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST
# here, data is utf8
# but we store and generate latin1 files, to ease further import in Apogée
data = data.decode(APO_PORTAL_ENCODING).encode(APO_INPUT_ENCODING) # XXX #py3
return view_apo_csv_store(
context, semset_id, data=data, autodetect=False, REQUEST=REQUEST
)
return view_apo_csv_store(semset_id, data=data, autodetect=False, REQUEST=REQUEST)
def view_apo_csv_delete(
context, etape_apo="", semset_id="", dialog_confirmed=False, REQUEST=None
etape_apo="", semset_id="", dialog_confirmed=False, REQUEST=None
):
"""Delete CSV file"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
dest_url = "apo_semset_maq_status?semset_id=" + semset_id
if not dialog_confirmed:
return scu.confirm_dialog(
@ -679,22 +670,22 @@ def view_apo_csv_delete(
)
info = sco_etape_apogee.apo_csv_get_archive(
context, etape_apo, semset["annee_scolaire"], semset["sem_id"]
etape_apo, semset["annee_scolaire"], semset["sem_id"]
)
sco_etape_apogee.apo_csv_delete(context, info["archive_id"])
sco_etape_apogee.apo_csv_delete(info["archive_id"])
return flask.redirect(dest_url + "&head_message=Archive%20supprimée")
def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=None):
def view_apo_csv(etape_apo="", semset_id="", format="html", REQUEST=None):
"""Visualise une maquette stockée
Si format="raw", renvoie le fichier maquette tel quel
"""
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
annee_scolaire = semset["annee_scolaire"]
sem_id = semset["sem_id"]
csv_data = sco_etape_apogee.apo_csv_get(context, etape_apo, annee_scolaire, sem_id)
csv_data = sco_etape_apogee.apo_csv_get(etape_apo, annee_scolaire, sem_id)
if format == "raw":
return scu.sendCSVFile(REQUEST, csv_data, etape_apo + ".txt")
apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"])
@ -709,7 +700,7 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
apo_dups,
maq_elems,
sem_elems,
) = sco_etape_apogee.apo_csv_semset_check(context, semset)
) = sco_etape_apogee.apo_csv_semset_check(semset)
H = [
html_sco_header.sco_header(
@ -788,7 +779,6 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
# called from Web
def apo_csv_export_results(
context,
semset_id,
block_export_res_etape=False,
block_export_res_sem=False,
@ -815,7 +805,7 @@ def apo_csv_export_results(
if not semset_id:
raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(context, semset_id=semset_id)
semset = sco_semset.SemSet(semset_id=semset_id)
annee_scolaire = semset["annee_scolaire"]
periode = semset["sem_id"]
@ -823,14 +813,11 @@ def apo_csv_export_results(
dest_zip = ZipFile(data, "w")
etapes_apo = sco_etape_apogee.apo_csv_list_stored_etapes(
context, annee_scolaire, periode, etapes=semset.list_etapes()
annee_scolaire, periode, etapes=semset.list_etapes()
)
for etape_apo in etapes_apo:
apo_csv = sco_etape_apogee.apo_csv_get(
context, etape_apo, annee_scolaire, periode
)
apo_csv = sco_etape_apogee.apo_csv_get(etape_apo, annee_scolaire, periode)
sco_apogee_csv.export_csv_to_apogee(
context,
apo_csv,
periode=periode,
export_res_etape=export_res_etape,

View File

@ -237,8 +237,7 @@ class EtapeBilan(object):
Structure de donnée représentation l'état global de la comparaison ScoDoc/Apogée
"""
def __init__(self, context):
self.context = context
def __init__(self):
self.semestres = (
{}
) # Dictionnaire des formsemestres du semset (formsemestre_id -> semestre)
@ -405,7 +404,7 @@ class EtapeBilan(object):
for key_etape in self.etapes:
anneeapogee, etapestr = key_to_values(key_etape)
self.etu_etapes[key_etape] = set()
for etud in get_inscrits_etape(self.context, etapestr, anneeapogee):
for etud in get_inscrits_etape(etapestr, anneeapogee):
key_etu = self.register_etud_apogee(etud, key_etape)
self.etu_etapes[key_etape].add(key_etu)

View File

@ -116,9 +116,7 @@ def format_etud_ident(etud):
def force_uppercase(s):
if s:
s = scu.strupper(s)
return s
return s.upper() if s else s
def format_nomprenom(etud, reverse=False):
@ -151,7 +149,7 @@ def format_nom(s, uppercase=True):
if not s:
return ""
if uppercase:
return scu.strupper(s)
return s.upper()
else:
return format_prenom(s)
@ -161,7 +159,7 @@ def input_civilite(s):
'M', 'F', or 'X' (and nothing else).
Raises valueError if conversion fails.
"""
s = scu.strupper(s).strip()
s = s.upper().strip()
if s in ("M", "M.", "MR", "H"):
return "M"
elif s in ("F", "MLLE", "MLLE.", "MELLE", "MME"):
@ -187,7 +185,7 @@ def format_civilite(civilite):
def format_lycee(nomlycee):
nomlycee = nomlycee.strip()
s = scu.strlower(nomlycee)
s = nomlycee.lower()
if s[:5] == "lycee" or s[:5] == "lycée":
return nomlycee[5:]
else:
@ -217,7 +215,7 @@ def format_telephone(n):
def format_pays(s):
"laisse le pays seulement si != FRANCE"
if scu.strupper(s) != "FRANCE":
if s.upper() != "FRANCE":
return s
else:
return ""
@ -321,7 +319,9 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
return True, len(res)
def _check_duplicate_code(cnx, args, code_name, context, edit=True, REQUEST=None):
def _check_duplicate_code(
cnx, args, code_name, disable_notify=False, edit=True, REQUEST=None
):
etudid = args.get("etudid", None)
if args.get(code_name, None):
etuds = identite_list(cnx, {code_name: str(args[code_name])})
@ -355,7 +355,7 @@ def _check_duplicate_code(cnx, args, code_name, context, edit=True, REQUEST=None
OK = "Annuler"
dest_url = ""
parameters = {}
if context:
if not disable_notify:
err_page = scu.confirm_dialog(
message="""<h3>Code étudiant (%s) dupliqué !</h3>""" % code_name,
helpmsg="""Le %s %s est déjà utilisé: un seul étudiant peut avoir ce code. Vérifier votre valeur ou supprimer l'autre étudiant avec cette valeur.<p><ul><li>"""
@ -377,14 +377,18 @@ def _check_civilite(args):
args["civilite"] = input_civilite(civilite) # TODO: A faire valider
def identite_edit(cnx, args, context=None, REQUEST=None):
def identite_edit(cnx, args, disable_notify=False, REQUEST=None):
"""Modifie l'identite d'un étudiant.
Si context et notification et difference, envoie message notification.
Si pref notification et difference, envoie message notification, sauf si disable_notify
"""
_check_duplicate_code(cnx, args, "code_nip", context, edit=True, REQUEST=REQUEST)
_check_duplicate_code(cnx, args, "code_ine", context, edit=True, REQUEST=REQUEST)
_check_duplicate_code(
cnx, args, "code_nip", disable_notify=disable_notify, edit=True, REQUEST=REQUEST
)
_check_duplicate_code(
cnx, args, "code_ine", disable_notify=disable_notify, edit=True, REQUEST=REQUEST
)
notify_to = None
if context:
if not disable_notify:
try:
notify_to = sco_preferences.get_preference("notify_etud_changes_to")
except:
@ -401,7 +405,6 @@ def identite_edit(cnx, args, context=None, REQUEST=None):
etud = get_etud_info(etudid=args["etudid"], filled=True)[0]
after = identite_list(cnx, {"etudid": args["etudid"]})[0]
notify_etud_change(
context,
notify_to,
etud,
before,
@ -410,10 +413,10 @@ def identite_edit(cnx, args, context=None, REQUEST=None):
)
def identite_create(cnx, args, context=None, REQUEST=None):
def identite_create(cnx, args, REQUEST=None):
"check unique etudid, then create"
_check_duplicate_code(cnx, args, "code_nip", context, edit=False, REQUEST=REQUEST)
_check_duplicate_code(cnx, args, "code_ine", context, edit=False, REQUEST=REQUEST)
_check_duplicate_code(cnx, args, "code_nip", edit=False, REQUEST=REQUEST)
_check_duplicate_code(cnx, args, "code_ine", edit=False, REQUEST=REQUEST)
_check_civilite(args)
if "etudid" in args:
@ -426,7 +429,7 @@ def identite_create(cnx, args, context=None, REQUEST=None):
return _identiteEditor.create(cnx, args)
def notify_etud_change(context, email_addr, etud, before, after, subject):
def notify_etud_change(email_addr, etud, before, after, subject):
"""Send email notifying changes to etud
before and after are two dicts, with values before and after the change.
"""
@ -458,7 +461,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)
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)
return txt
@ -493,12 +496,12 @@ adresse_delete = _adresseEditor.delete
adresse_list = _adresseEditor.list
def adresse_edit(cnx, args, context=None):
def adresse_edit(cnx, args, disable_notify=False):
"""Modifie l'adresse d'un étudiant.
Si context et notification et difference, envoie message notification.
Si pref notification et difference, envoie message notification, sauf si disable_notify
"""
notify_to = None
if context:
if not disable_notify:
try:
notify_to = sco_preferences.get_preference("notify_etud_changes_to")
except:
@ -514,7 +517,6 @@ def adresse_edit(cnx, args, context=None):
etud = get_etud_info(etudid=args["etudid"], filled=True)[0]
after = adresse_list(cnx, {"etudid": args["etudid"]})[0]
notify_etud_change(
context,
notify_to,
etud,
before,
@ -584,8 +586,8 @@ admission_edit = _admissionEditor.edit
# Edition simultanee de identite et admission
class EtudIdentEditor(object):
def create(self, cnx, args, context=None, REQUEST=None):
etudid = identite_create(cnx, args, context, REQUEST)
def create(self, cnx, args, REQUEST=None):
etudid = identite_create(cnx, args, REQUEST)
args["etudid"] = etudid
admission_create(cnx, args)
return etudid
@ -616,8 +618,8 @@ class EtudIdentEditor(object):
res.sort(key=itemgetter("nom", "prenom"))
return res
def edit(self, cnx, args, context=None, REQUEST=None):
identite_edit(cnx, args, context, REQUEST)
def edit(self, cnx, args, disable_notify=False, REQUEST=None):
identite_edit(cnx, args, disable_notify=disable_notify, REQUEST=REQUEST)
if "adm_id" in args: # safety net
admission_edit(cnx, args)
@ -668,7 +670,7 @@ def get_etud_info(etudid=False, code_nip=False, filled=False, REQUEST=None):
return etud
def create_etud(context, cnx, args={}, REQUEST=None):
def create_etud(cnx, args={}, REQUEST=None):
"""Creation d'un étudiant. génère aussi évenement et "news".
Args:
@ -680,7 +682,7 @@ def create_etud(context, cnx, args={}, REQUEST=None):
from app.scodoc import sco_news
# creation d'un etudiant
etudid = etudident_create(cnx, args, context=context, REQUEST=REQUEST)
etudid = etudident_create(cnx, args, REQUEST=REQUEST)
# crée une adresse vide (chaque etudiant doit etre dans la table "adresse" !)
_ = adresse_create(
cnx,
@ -773,7 +775,7 @@ etud_annotations_list = _etud_annotationsEditor.list
etud_annotations_edit = _etud_annotationsEditor.edit
def add_annotations_to_etud_list(context, etuds):
def add_annotations_to_etud_list(etuds):
"""Add key 'annotations' describing annotations of etuds
(used to list all annotations of a group)
"""
@ -877,16 +879,16 @@ o = open('etablissements2.csv', 'w')
o.write( f.readline() )
for l in f:
fs = l.split(';')
nom = ' '.join( [ strcapitalize(x) for x in fs[1].split() ] )
adr = ' '.join( [ strcapitalize(x) for x in fs[2].split() ] )
ville=' '.join( [ strcapitalize(x) for x in fs[4].split() ] )
nom = ' '.join( [ x.capitalize() for x in fs[1].split() ] )
adr = ' '.join( [ x.capitalize() for x in fs[2].split() ] )
ville=' '.join( [ x.capitalize() for x in fs[4].split() ] )
o.write( '%s;%s;%s;%s;%s\n' % (fs[0], nom, adr, fs[3], ville))
o.close()
"""
def list_scolog(context, etudid):
def list_scolog(etudid):
"liste des operations effectuees sur cet etudiant"
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -905,7 +907,6 @@ def fill_etuds_info(etuds):
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
context = None # XXX en attendant la suppression du context ScoDoc7
cnx = ndb.GetDBConnexion()
# open('/tmp/t','w').write( str(etuds) )
for etud in etuds:
@ -932,7 +933,7 @@ def fill_etuds_info(etuds):
cursem = None # semestre "courant" ou il est inscrit
for i in ins:
sem = sco_formsemestre.get_formsemestre(i["formsemestre_id"])
if sco_formsemestre.sem_est_courant(context, sem):
if sco_formsemestre.sem_est_courant(sem):
cursem = sem
curi = i
sem["ins"] = i
@ -947,7 +948,7 @@ def fill_etuds_info(etuds):
etud["inscriptionstr"] = "Inscrit en " + cursem["titremois"]
etud["inscription_formsemestre_id"] = cursem["formsemestre_id"]
etud["etatincursem"] = curi["etat"]
etud["situation"] = descr_situation_etud(context, etudid, etud["ne"])
etud["situation"] = descr_situation_etud(etudid, etud["ne"])
# XXX est-ce utile ? sco_groups.etud_add_group_infos( etud, cursem)
else:
if etud["sems"]:
@ -1003,7 +1004,7 @@ def fill_etuds_info(etuds):
etud["telephonemobilestr"] = ""
def descr_situation_etud(context, etudid, ne=""):
def descr_situation_etud(etudid, ne=""):
"""chaine decrivant la situation actuelle de l'etudiant"""
from app.scodoc import sco_formsemestre

View File

@ -178,7 +178,6 @@ def do_evaluation_list(args, sortkey=None):
def do_evaluation_list_in_formsemestre(formsemestre_id):
"list evaluations in this formsemestre"
context = None # #context
mods = sco_moduleimpl.do_moduleimpl_list(formsemestre_id=formsemestre_id)
evals = []
for mod in mods:
@ -188,7 +187,6 @@ def do_evaluation_list_in_formsemestre(formsemestre_id):
def _check_evaluation_args(args):
"Check coefficient, dates and duration, raises exception if invalid"
context = None # #context
moduleimpl_id = args["moduleimpl_id"]
# check bareme
note_max = args.get("note_max", None)
@ -255,7 +253,6 @@ def do_evaluation_create(
**kw, # ceci pour absorber les arguments excedentaires de tf #sco8
):
"""Create an evaluation"""
context = None # #context
if not sco_permissions_check.can_edit_evaluation(moduleimpl_id=moduleimpl_id):
raise AccessDenied(
"Modification évaluation impossible pour %s" % current_user.get_nomplogin()
@ -320,7 +317,6 @@ def do_evaluation_create(
def do_evaluation_edit(args):
"edit an evaluation"
context = None # #context
evaluation_id = args["evaluation_id"]
the_evals = do_evaluation_list({"evaluation_id": evaluation_id})
if not the_evals:
@ -342,7 +338,6 @@ def do_evaluation_edit(args):
def do_evaluation_delete(evaluation_id):
"delete evaluation"
context = None # #context
the_evals = do_evaluation_list({"evaluation_id": evaluation_id})
if not the_evals:
raise ValueError("evaluation inexistante !")
@ -390,7 +385,6 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
à ce module ont des notes)
evalattente est vrai s'il ne manque que des notes en attente
"""
context = None # #context
nb_inscrits = len(
sco_groups.do_evaluation_listeetuds_groups(evaluation_id, getallstudents=True)
)
@ -720,7 +714,6 @@ def do_evaluation_etat_in_mod(nt, moduleimpl_id):
def formsemestre_evaluations_cal(formsemestre_id, REQUEST=None):
"""Page avec calendrier de toutes les evaluations de ce semestre"""
context = None # #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
nt = sco_cache.NotesTableCache.get(formsemestre_id) # > liste evaluations
@ -781,7 +774,7 @@ def formsemestre_evaluations_cal(formsemestre_id, REQUEST=None):
e[2] = color_futur
CalHTML = sco_abs.YearTable(
context, year, events=list(events.values()), halfday=False, pad_width=None
year, events=list(events.values()), halfday=False, pad_width=None
)
H = [
@ -858,7 +851,6 @@ def formsemestre_evaluations_delai_correction(
N'indique pas les évaluations de ratrapage ni celles des modules de bonus/malus.
"""
context = None # #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
nt = sco_cache.NotesTableCache.get(formsemestre_id) # > liste evaluations
@ -1040,7 +1032,6 @@ def evaluation_describe(evaluation_id="", edit_in_place=True, REQUEST=None):
"""HTML description of evaluation, for page headers
edit_in_place: allow in-place editing when permitted (not implemented)
"""
context = None # #context
from app.scodoc import sco_saisie_notes
E = do_evaluation_list({"evaluation_id": evaluation_id})[0]
@ -1122,7 +1113,6 @@ def evaluation_create_form(
page_title="Evaluation",
):
"formulaire creation/edition des evaluations (pas des notes)"
context = None # #context
if evaluation_id != None:
the_eval = do_evaluation_list({"evaluation_id": evaluation_id})[0]
moduleimpl_id = the_eval["moduleimpl_id"]

View File

@ -733,11 +733,7 @@ def excel_feuille_listeappel(
for t in lines:
n += 1
nomprenom = (
t["civilite_str"]
+ " "
+ t["nom"]
+ " "
+ scu.strcapitalize(scu.strlower(t["prenom"]))
t["civilite_str"] + " " + t["nom"] + " " + t["prenom"].lower().capitalize()
)
style_nom = style2t3
if with_paiement:

View File

@ -45,18 +45,18 @@ from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
def _build_results_table(context, start_date=None, end_date=None, types_parcours=[]):
def _build_results_table(start_date=None, end_date=None, types_parcours=[]):
"""Construit une table avec les résultats de jury de TOUS les étudiants
de TOUS les semestres ScoDoc de ce département entre les dates indiquées
(c'est à dire commençant APRES ou à start_date et terminant avant ou à end_date)
Les dates sont des chaines iso.
"""
formsemestre_ids = get_set_formsemestre_id_dates(context, start_date, end_date)
formsemestre_ids = get_set_formsemestre_id_dates(start_date, end_date)
# Décisions de jury de tous les semestres:
dpv_by_sem = {}
for formsemestre_id in formsemestre_ids:
dpv_by_sem[formsemestre_id] = sco_pvjury.dict_pvjury(
context, formsemestre_id, with_parcours_decisions=True
formsemestre_id, with_parcours_decisions=True
)
semlist = [dpv["formsemestre"] for dpv in dpv_by_sem.values() if dpv]
@ -92,7 +92,7 @@ def _build_results_table(context, start_date=None, end_date=None, types_parcours
# sanity check
assert etudid in etuds_infos
# Construit la table (semblable à pvjury_table)
rows, titles, columns_ids = _build_results_list(context, dpv_by_sem, etuds_infos)
rows, titles, columns_ids = _build_results_list(dpv_by_sem, etuds_infos)
tab = GenTable(
rows=rows,
titles=titles,
@ -107,7 +107,7 @@ def _build_results_table(context, start_date=None, end_date=None, types_parcours
return tab, semlist
def _build_results_list(context, dpv_by_sem, etuds_infos):
def _build_results_list(dpv_by_sem, etuds_infos):
"""Construit la table (semblable à pvjury_table)
Returns:
rows, titles, columns_ids
@ -202,7 +202,7 @@ def _build_results_list(context, dpv_by_sem, etuds_infos):
return rows, titles, columns_ids
def get_set_formsemestre_id_dates(context, start_date, end_date):
def get_set_formsemestre_id_dates(start_date, end_date):
"""Ensemble des formsemestre_id entre ces dates"""
s = ndb.SimpleDictFetch(
"""SELECT id
@ -215,7 +215,7 @@ def get_set_formsemestre_id_dates(context, start_date, end_date):
def scodoc_table_results(
context, start_date="", end_date="", types_parcours=[], format="html", REQUEST=None
start_date="", end_date="", types_parcours=[], format="html", REQUEST=None
):
"""Page affichant la table des résultats
Les dates sont en dd/mm/yyyy (datepicker javascript)
@ -235,7 +235,7 @@ def scodoc_table_results(
if start_date and end_date:
tab, semlist = _build_results_table(
context, start_date_iso, end_date_iso, types_parcours
start_date_iso, end_date_iso, types_parcours
)
tab.base_url = "%s?start_date=%s&end_date=%s&types_parcours=%s" % (
REQUEST.URL0,
@ -335,17 +335,17 @@ _DATE_FORM = """
# /opt/scodoc/bin/zopectl debug
from debug import *
from app.scodoc.sco_export_results import *
context = go_dept(app, 'RT').Notes
_ = go_dept(app, 'RT').Notes
etudid = 'EID27764'
etud = sco_etud.get_etud_info( etudid=etudid, filled=True)[0]
start_date='2015-08-15'
end_date='2017-08-31'
formsemestre_ids = get_set_formsemestre_id_dates(context, start_date, end_date)
formsemestre_ids = get_set_formsemestre_id_dates( start_date, end_date)
dpv_by_sem = {}
for formsemestre_id in formsemestre_ids:
dpv_by_sem[formsemestre_id] = sco_pvjury.dict_pvjury(context, formsemestre_id, with_parcours_decisions=True)
dpv_by_sem[formsemestre_id] = sco_pvjury.dict_pvjury( formsemestre_id, with_parcours_decisions=True)
semlist = [ dpv['formsemestre'] for dpv in dpv_by_sem.values() ]

View File

@ -44,7 +44,6 @@ from app.scodoc import sco_preferences
def form_search_etud(
context,
REQUEST=None,
dest_url=None,
parameters=None,
@ -96,7 +95,7 @@ def form_search_etud(
return "\n".join(H)
def search_etud_in_dept(context, expnom="", REQUEST=None):
def search_etud_in_dept(expnom="", REQUEST=None):
"""Page recherche d'un etudiant.
Affiche la fiche de l'étudiant, ou, si la recherche donne plusieurs résultats,
@ -139,7 +138,6 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
"""<h2>%d résultats pour "%s": choisissez un étudiant:</h2>"""
% (len(etuds), expnom),
form_search_etud(
context,
dest_url=url_for(
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept
), # sans l'etudid, post du form
@ -175,7 +173,6 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
if len(etuds) > 20: # si la page est grande
H.append(
form_search_etud(
context,
dest_url=url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept),
REQUEST=REQUEST,
title="Autre recherche",
@ -197,7 +194,7 @@ def search_etuds_infos(expnom=None, code_nip=None):
may_be_nip = scu.is_valid_code_nip(expnom)
cnx = ndb.GetDBConnexion()
if expnom and not may_be_nip:
expnom = scu.strupper(expnom) # les noms dans la BD sont en uppercase
expnom = expnom.upper() # les noms dans la BD sont en uppercase
etuds = sco_etud.etudident_list(cnx, args={"nom": expnom}, test="~")
else:
code_nip = code_nip or expnom
@ -209,13 +206,13 @@ def search_etuds_infos(expnom=None, code_nip=None):
return etuds
def search_etud_by_name(context, term, REQUEST=None):
def search_etud_by_name(term, REQUEST=None):
"""Recherche noms étudiants par début du nom, pour autocomplete
Accepte aussi un début de code NIP (au moins 6 caractères)
Renvoie une liste de nom en JSON
"""
may_be_nip = scu.is_valid_code_nip(term)
# term = scu.strupper(term) # conserve les accents
# term = term.upper() # conserve les accents
term = term.upper()
if (
not scu.ALPHANUM_EXP.match(term) # n'autorise pas les caractères spéciaux
@ -335,7 +332,7 @@ def table_etud_in_accessible_depts(expnom=None):
)
def search_inscr_etud_by_nip(context, code_nip, REQUEST=None, format="json"):
def search_inscr_etud_by_nip(code_nip, REQUEST=None, format="json"):
"""Recherche multi-departement d'un étudiant par son code NIP
Seuls les départements accessibles par l'utilisateur sont cherchés.

View File

@ -218,7 +218,6 @@ def etapes_apo_str(etapes):
def do_formsemestre_create(args, silent=False):
"create a formsemestre"
context = None # XXX #context
from app.scodoc import sco_groups
from app.scodoc import sco_news
@ -440,7 +439,7 @@ def sem_in_annee_scolaire(sem, year=False):
)
def sem_une_annee(context, sem):
def sem_une_annee(sem):
"""Test si sem est entièrement sur la même année scolaire.
(ce n'est pas obligatoire mais si ce n'est pas le cas les exports Apogée ne vont pas fonctionner)
pivot au 1er août.
@ -460,7 +459,7 @@ def sem_une_annee(context, sem):
return debut == fin
def sem_est_courant(context, sem):
def sem_est_courant(sem):
"""Vrai si la date actuelle (now) est dans le semestre (les dates de début et fin sont incluses)"""
now = time.strftime("%Y-%m-%d")
debut = ndb.DateDMYtoISO(sem["date_debut"])

View File

@ -51,22 +51,22 @@ notes_formsemestre_custommenu_list = _custommenuEditor.list
notes_formsemestre_custommenu_edit = _custommenuEditor.edit
def formsemestre_custommenu_get(context, formsemestre_id):
def formsemestre_custommenu_get(formsemestre_id):
"returns dict [ { 'title' : xxx, 'url' : xxx } ]"
cnx = ndb.GetDBConnexion()
vals = notes_formsemestre_custommenu_list(cnx, {"formsemestre_id": formsemestre_id})
return vals
def formsemestre_custommenu_html(context, formsemestre_id):
def formsemestre_custommenu_html(formsemestre_id):
"HTML code for custom menu"
menu = []
# Calendrier électronique ?
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
ics_url = sco_edt_cal.formsemestre_get_ics_url(context, sem)
ics_url = sco_edt_cal.formsemestre_get_ics_url(sem)
if ics_url:
menu.append({"title": "Emploi du temps (ics)", "url": ics_url})
menu += formsemestre_custommenu_get(context, formsemestre_id)
menu += formsemestre_custommenu_get(formsemestre_id)
menu.append(
{
"title": "Modifier ce menu...",
@ -77,7 +77,7 @@ def formsemestre_custommenu_html(context, formsemestre_id):
return htmlutils.make_menu("Liens", menu)
def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None):
def formsemestre_custommenu_edit(formsemestre_id, REQUEST=None):
"""Dialog to edit the custom menu"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
dest_url = (
@ -100,7 +100,7 @@ def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None):
},
),
]
menu = formsemestre_custommenu_get(context, formsemestre_id)
menu = formsemestre_custommenu_get(formsemestre_id)
menu.append({"custommenu_id": "new", "url": "", "title": ""})
initvalues = {}
for item in menu:

View File

@ -66,7 +66,7 @@ def _default_sem_title(F):
return F["titre"]
def formsemestre_createwithmodules(context, REQUEST=None):
def formsemestre_createwithmodules(REQUEST=None):
"""Page création d'un semestre"""
H = [
html_sco_header.sco_header(
@ -77,7 +77,7 @@ def formsemestre_createwithmodules(context, REQUEST=None):
),
"""<h2>Mise en place d'un semestre de formation</h2>""",
]
r = do_formsemestre_createwithmodules(context, REQUEST=REQUEST)
r = do_formsemestre_createwithmodules(REQUEST=REQUEST)
if isinstance(r, six.string_types):
H.append(r)
else:
@ -85,7 +85,7 @@ def formsemestre_createwithmodules(context, REQUEST=None):
return "\n".join(H) + html_sco_header.sco_footer()
def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
def formsemestre_editwithmodules(REQUEST, formsemestre_id):
"""Page modification semestre"""
# portage from dtml
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
@ -105,7 +105,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
% scu.icontag("lock_img", border="0", title="Semestre verrouillé")
)
else:
r = do_formsemestre_createwithmodules(context, REQUEST=REQUEST, edit=1)
r = do_formsemestre_createwithmodules(REQUEST=REQUEST, edit=1)
if isinstance(r, six.string_types):
H.append(r)
else:
@ -130,7 +130,7 @@ def can_edit_sem(REQUEST, formsemestre_id="", sem=None):
return sem
def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
def do_formsemestre_createwithmodules(REQUEST=None, edit=False):
"Form choix modules / responsables et creation formsemestre"
# Fonction accessible à tous, controle acces à la main:
if edit:
@ -231,7 +231,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
semestre_ids = list(semestre_ids.keys())
semestre_ids.sort()
modalites = sco_modalites.do_modalite_list(context)
modalites = sco_modalites.do_modalite_list()
modalites_abbrv = [m["modalite"] for m in modalites]
modalites_titles = [m["titre"] for m in modalites]
#
@ -863,7 +863,7 @@ def formsemestre_delete_moduleimpls(formsemestre_id, module_ids_to_del):
return ok, msg
def formsemestre_clone(context, formsemestre_id, REQUEST=None):
def formsemestre_clone(formsemestre_id, REQUEST=None):
"""
Formulaire clonage d'un semestre
"""
@ -1107,7 +1107,6 @@ def do_formsemestre_clone(
def formsemestre_associate_new_version(
context,
formsemestre_id,
other_formsemestre_ids=[],
REQUEST=None,
@ -1158,7 +1157,7 @@ def formsemestre_associate_new_version(
)
else:
do_formsemestres_associate_new_version(
context, [formsemestre_id] + other_formsemestre_ids, REQUEST=REQUEST
[formsemestre_id] + other_formsemestre_ids, REQUEST=REQUEST
)
return flask.redirect(
"formsemestre_status?formsemestre_id=%s&head_message=Formation%%20dupliquée"
@ -1166,7 +1165,7 @@ def formsemestre_associate_new_version(
)
def do_formsemestres_associate_new_version(context, formsemestre_ids, REQUEST=None):
def do_formsemestres_associate_new_version(formsemestre_ids, REQUEST=None):
"""Cree une nouvelle version de la formation du semestre, et y rattache les semestres.
Tous les moduleimpl sont -associés à la nouvelle formation, ainsi que les decisions de jury
si elles existent (codes d'UE validées).
@ -1197,16 +1196,12 @@ def do_formsemestres_associate_new_version(context, formsemestre_ids, REQUEST=No
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
sem["formation_id"] = formation_id
sco_formsemestre.do_formsemestre_edit(sem, cnx=cnx, html_quote=False)
_reassociate_moduleimpls(
context, cnx, formsemestre_id, ues_old2new, modules_old2new
)
_reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new)
cnx.commit()
def _reassociate_moduleimpls(
context, cnx, formsemestre_id, ues_old2new, modules_old2new
):
def _reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new):
"""Associe les moduleimpls d'un semestre existant à un autre programme
et met à jour les décisions de jury (validations d'UE).
"""
@ -1231,7 +1226,7 @@ def _reassociate_moduleimpls(
sco_parcours_dut.scolar_formsemestre_validation_edit(cnx, e)
def formsemestre_delete(context, formsemestre_id, REQUEST=None):
def formsemestre_delete(formsemestre_id, REQUEST=None):
"""Delete a formsemestre (affiche avertissements)"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
@ -1270,7 +1265,7 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None):
cancelbutton="Annuler",
)
if tf[0] == 0:
if formsemestre_has_decisions_or_compensations(context, formsemestre_id):
if formsemestre_has_decisions_or_compensations(formsemestre_id):
H.append(
"""<p><b>Ce semestre ne peut pas être supprimé ! (il y a des décisions de jury ou des compensations par d'autres semestres)</b></p>"""
)
@ -1289,9 +1284,7 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None):
)
def formsemestre_delete2(
context, formsemestre_id, dialog_confirmed=False, REQUEST=None
):
def formsemestre_delete2(formsemestre_id, dialog_confirmed=False):
"""Delete a formsemestre (confirmation)"""
# Confirmation dialog
if not dialog_confirmed:
@ -1302,11 +1295,11 @@ def formsemestre_delete2(
parameters={"formsemestre_id": formsemestre_id},
)
# Bon, s'il le faut...
do_formsemestre_delete(context, formsemestre_id)
do_formsemestre_delete(formsemestre_id)
return flask.redirect(scu.ScoURL() + "?head_message=Semestre%20supprimé")
def formsemestre_has_decisions_or_compensations(context, formsemestre_id):
def formsemestre_has_decisions_or_compensations(formsemestre_id):
"""True if decision de jury dans ce semestre
ou bien compensation de ce semestre par d'autre ssemestres.
"""
@ -1320,7 +1313,7 @@ def formsemestre_has_decisions_or_compensations(context, formsemestre_id):
return r
def do_formsemestre_delete(context, formsemestre_id):
def do_formsemestre_delete(formsemestre_id):
"""delete formsemestre, and all its moduleimpls.
No checks, no warnings: erase all !
"""
@ -1424,7 +1417,7 @@ def do_formsemestre_delete(context, formsemestre_id):
# ---------------------------------------------------------------------------------------
def formsemestre_edit_options(context, formsemestre_id, target_url=None, REQUEST=None):
def formsemestre_edit_options(formsemestre_id, target_url=None, REQUEST=None):
"""dialog to change formsemestre options
(accessible par ScoImplement ou dir. etudes)
"""
@ -1437,9 +1430,7 @@ def formsemestre_edit_options(context, formsemestre_id, target_url=None, REQUEST
)
def formsemestre_change_lock(
context, formsemestre_id, REQUEST=None, dialog_confirmed=False
):
def formsemestre_change_lock(formsemestre_id, REQUEST=None, dialog_confirmed=False):
"""Change etat (verrouille si ouvert, déverrouille si fermé)
nota: etat (1 ouvert, 0 fermé)
"""
@ -1476,7 +1467,7 @@ def formsemestre_change_lock(
def formsemestre_change_publication_bul(
context, formsemestre_id, REQUEST=None, dialog_confirmed=False
formsemestre_id, REQUEST=None, dialog_confirmed=False
):
"""Change etat publication bulletins sur portail"""
ok, err = sco_permissions_check.check_access_diretud(formsemestre_id)
@ -1511,7 +1502,7 @@ def formsemestre_change_publication_bul(
return None
def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=None):
def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None, REQUEST=None):
"""Changement manuel des coefficients des UE capitalisées."""
from app.scodoc import notes_table
@ -1549,7 +1540,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
help,
]
#
ues, modimpls = notes_table.get_sem_ues_modimpls(context, formsemestre_id)
ues, modimpls = notes_table.get_sem_ues_modimpls(formsemestre_id)
for ue in ues:
ue["sum_coefs"] = sum(
[

View File

@ -51,7 +51,7 @@ from app.scodoc import sco_parcours_dut
from app.scodoc import sco_etud
def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
def formsemestre_ext_create(etudid, sem_params, REQUEST=None):
"""Crée un formsemestre exterieur et y inscrit l'étudiant.
sem_params: dict nécessaire à la création du formsemestre
"""
@ -71,7 +71,6 @@ def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
# Inscription au semestre
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
context,
formsemestre_id,
etudid,
REQUEST=REQUEST,
@ -80,7 +79,7 @@ def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
return formsemestre_id
def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None):
def formsemestre_ext_create_form(etudid, formsemestre_id, REQUEST=None):
"""Formulaire creation/inscription à un semestre extérieur"""
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
H = [
@ -204,15 +203,13 @@ def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None)
)
else:
tf[2]["formation_id"] = orig_sem["formation_id"]
formsemestre_ext_create(context, etudid, tf[2], REQUEST=REQUEST)
formsemestre_ext_create(etudid, tf[2], REQUEST=REQUEST)
return flask.redirect(
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
)
def formsemestre_ext_edit_ue_validations(
context, formsemestre_id, etudid, REQUEST=None
):
def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid, REQUEST=None):
"""Edition des validations d'UE et de semestre (jury)
pour un semestre extérieur.
On peut saisir pour chaque UE du programme de formation
@ -223,8 +220,8 @@ def formsemestre_ext_edit_ue_validations(
"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
ue_list = _list_ue_with_coef_and_validations(context, sem, etudid)
descr = _ue_form_description(context, ue_list, REQUEST.form)
ue_list = _list_ue_with_coef_and_validations(sem, etudid)
descr = _ue_form_description(ue_list, REQUEST.form)
if REQUEST and REQUEST.method == "GET":
initvalues = {
"note_" + str(ue["ue_id"]): ue["validation"].get("moy_ue", "")
@ -244,19 +241,19 @@ def formsemestre_ext_edit_ue_validations(
if tf[0] == -1:
return "<h4>annulation</h4>"
else:
H = _make_page(context, etud, sem, tf, REQUEST=REQUEST)
H = _make_page(etud, sem, tf, REQUEST=REQUEST)
if tf[0] == 0: # premier affichage
return "\n".join(H)
else: # soumission
# simule erreur
ok, message = _check_values(context, ue_list, tf[2])
ok, message = _check_values(ue_list, tf[2])
if not ok:
H = _make_page(context, etud, sem, tf, message=message, REQUEST=REQUEST)
H = _make_page(etud, sem, tf, message=message, REQUEST=REQUEST)
return "\n".join(H)
else:
# Submit
_record_ue_validations_and_coefs(
context, formsemestre_id, etudid, ue_list, tf[2], REQUEST=REQUEST
formsemestre_id, etudid, ue_list, tf[2], REQUEST=REQUEST
)
return flask.redirect(
"formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s"
@ -264,7 +261,7 @@ def formsemestre_ext_edit_ue_validations(
)
def _make_page(context, etud, sem, tf, message="", REQUEST=None):
def _make_page(etud, sem, tf, message="", REQUEST=None):
nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
moy_gen = nt.get_etud_moy_gen(etud["etudid"])
H = [
@ -305,7 +302,7 @@ _UE_VALID_CODES = {
}
def _ue_form_description(context, ue_list, values):
def _ue_form_description(ue_list, values):
"""Description du formulaire de saisie des UE / validations
Pour chaque UE, on peut saisir: son code jury, sa note, son coefficient.
"""
@ -377,7 +374,7 @@ def _ue_form_description(context, ue_list, values):
return descr
def _check_values(context, ue_list, values):
def _check_values(ue_list, values):
"""Check that form values are ok
for each UE:
code != None => note and coef
@ -434,7 +431,7 @@ def _convert_field_to_float(val):
return val
def _list_ue_with_coef_and_validations(context, sem, etudid):
def _list_ue_with_coef_and_validations(sem, etudid):
"""Liste des UE de la même formation que sem,
avec leurs coefs d'UE capitalisée (si déjà saisi)
et leur validation pour cet étudiant.
@ -468,7 +465,7 @@ def _list_ue_with_coef_and_validations(context, sem, etudid):
def _record_ue_validations_and_coefs(
context, formsemestre_id, etudid, ue_list, values, REQUEST=None
formsemestre_id, etudid, ue_list, values, REQUEST=None
):
for ue in ue_list:
code = values.get("valid_" + str(ue["ue_id"]), False)
@ -487,7 +484,6 @@ def _record_ue_validations_and_coefs(
)
assert code == None or (note) # si code validant, il faut une note
sco_formsemestre_validation.do_formsemestre_validate_previous_ue(
context,
formsemestre_id,
etudid,
ue["ue_id"],

View File

@ -76,7 +76,7 @@ def do_formsemestre_inscription_listinscrits(formsemestre_id):
return r
def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
def do_formsemestre_inscription_create(args, method=None):
"create a formsemestre_inscription (and sco event)"
cnx = ndb.GetDBConnexion()
log("do_formsemestre_inscription_create: args=%s" % str(args))
@ -116,7 +116,7 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
return r
def do_formsemestre_inscription_delete(context, oid, formsemestre_id=None):
def do_formsemestre_inscription_delete(oid, formsemestre_id=None):
"delete formsemestre_inscription"
cnx = ndb.GetDBConnexion()
_formsemestre_inscriptionEditor.delete(cnx, oid)
@ -126,7 +126,7 @@ def do_formsemestre_inscription_delete(context, oid, formsemestre_id=None):
) # > desinscription du semestre
def do_formsemestre_inscription_edit(context, args=None, formsemestre_id=None):
def do_formsemestre_inscription_edit(args=None, formsemestre_id=None):
"edit a formsemestre_inscription"
cnx = ndb.GetDBConnexion()
_formsemestre_inscriptionEditor.edit(cnx, args)
@ -135,7 +135,7 @@ def do_formsemestre_inscription_edit(context, args=None, formsemestre_id=None):
) # > modif inscription semestre (demission ?)
def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=None):
def do_formsemestre_desinscription(etudid, formsemestre_id, REQUEST=None):
"""Désinscription d'un étudiant.
Si semestre extérieur et dernier inscrit, suppression de ce semestre.
"""
@ -174,7 +174,7 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
)
# -- desincription du semestre
do_formsemestre_inscription_delete(
context, insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id
insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id
)
# --- Semestre extérieur
if sem["modalite"] == "EXT":
@ -187,7 +187,7 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
"do_formsemestre_desinscription: suppression du semestre extérieur %s"
% formsemestre_id
)
sco_formsemestre_edit.do_formsemestre_delete(context, formsemestre_id)
sco_formsemestre_edit.do_formsemestre_delete(formsemestre_id)
if REQUEST:
logdb(
@ -200,7 +200,6 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
def do_formsemestre_inscription_with_modules(
context,
formsemestre_id,
etudid,
group_ids=[],
@ -216,7 +215,7 @@ def do_formsemestre_inscription_with_modules(
args = {"formsemestre_id": formsemestre_id, "etudid": etudid}
if etat is not None:
args["etat"] = etat
do_formsemestre_inscription_create(context, args, REQUEST, method=method)
do_formsemestre_inscription_create(args, method=method)
log(
"do_formsemestre_inscription_with_modules: etudid=%s formsemestre_id=%s"
% (etudid, formsemestre_id)
@ -247,14 +246,13 @@ def do_formsemestre_inscription_with_modules(
def formsemestre_inscription_with_modules_etud(
context, formsemestre_id, etudid=None, group_ids=None, REQUEST=None
formsemestre_id, etudid=None, group_ids=None, REQUEST=None
):
"""Form. inscription d'un étudiant au semestre.
Si etudid n'est pas specifié, form. choix etudiant.
"""
if not etudid:
return sco_find_etud.form_search_etud(
context,
title="Choix de l'étudiant à inscrire dans ce semestre",
add_headers=True,
dest_url="formsemestre_inscription_with_modules_etud",
@ -263,13 +261,11 @@ def formsemestre_inscription_with_modules_etud(
)
return formsemestre_inscription_with_modules(
context, etudid, formsemestre_id, REQUEST=REQUEST, group_ids=group_ids
etudid, formsemestre_id, REQUEST=REQUEST, group_ids=group_ids
)
def formsemestre_inscription_with_modules_form(
context, etudid, REQUEST, only_ext=False
):
def formsemestre_inscription_with_modules_form(etudid, only_ext=False):
"""Formulaire inscription de l'etud dans l'un des semestres existants.
Si only_ext, ne montre que les semestre extérieurs.
"""
@ -320,7 +316,7 @@ def formsemestre_inscription_with_modules_form(
def formsemestre_inscription_with_modules(
context, etudid, formsemestre_id, group_ids=None, multiple_ok=False, REQUEST=None
etudid, formsemestre_id, group_ids=None, multiple_ok=False, REQUEST=None
):
"""
Inscription de l'etud dans ce semestre.
@ -372,7 +368,7 @@ def formsemestre_inscription_with_modules(
return "\n".join(H) + F
# Check 2: déjà inscrit dans un semestre recouvrant les même dates ?
# Informe et propose dé-inscriptions
others = est_inscrit_ailleurs(context, etudid, formsemestre_id)
others = est_inscrit_ailleurs(etudid, formsemestre_id)
if others and not multiple_ok:
l = []
for s in others:
@ -401,7 +397,6 @@ def formsemestre_inscription_with_modules(
if group_ids is not None:
# OK, inscription
do_formsemestre_inscription_with_modules(
context,
formsemestre_id,
etudid,
group_ids=group_ids,
@ -435,7 +430,7 @@ def formsemestre_inscription_with_modules(
return "\n".join(H) + F
def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=None):
def formsemestre_inscription_option(etudid, formsemestre_id, REQUEST=None):
"""Dialogue pour (dés)inscription à des modules optionnels."""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
if not sem["etat"]:
@ -660,7 +655,7 @@ function chkbx_select(field_id, state) {
def do_moduleimpl_incription_options(
context, etudid, modulesimpls_ainscrire, modulesimpls_adesinscrire, REQUEST=None
etudid, modulesimpls_ainscrire, modulesimpls_adesinscrire, REQUEST=None
):
"""
Effectue l'inscription et la description aux modules optionnels
@ -722,7 +717,7 @@ def do_moduleimpl_incription_options(
return "\n".join(H)
def est_inscrit_ailleurs(context, etudid, formsemestre_id):
def est_inscrit_ailleurs(etudid, formsemestre_id):
"""Vrai si l'étudiant est inscrit dans un semestre en même
temps que celui indiqué (par formsemestre_id).
Retourne la liste des semestres concernés (ou liste vide).
@ -741,7 +736,7 @@ def est_inscrit_ailleurs(context, etudid, formsemestre_id):
return r
def list_inscrits_ailleurs(context, formsemestre_id):
def list_inscrits_ailleurs(formsemestre_id):
"""Liste des etudiants inscrits ailleurs en même temps que formsemestre_id.
Pour chacun, donne la liste des semestres.
{ etudid : [ liste de sems ] }
@ -750,11 +745,11 @@ def list_inscrits_ailleurs(context, formsemestre_id):
etudids = nt.get_etudids()
d = {}
for etudid in etudids:
d[etudid] = est_inscrit_ailleurs(context, etudid, formsemestre_id)
d[etudid] = est_inscrit_ailleurs(etudid, formsemestre_id)
return d
def formsemestre_inscrits_ailleurs(context, formsemestre_id, REQUEST=None):
def formsemestre_inscrits_ailleurs(formsemestre_id, REQUEST=None):
"""Page listant les étudiants inscrits dans un autre semestre
dont les dates recouvrent le semestre indiqué.
"""
@ -766,7 +761,7 @@ def formsemestre_inscrits_ailleurs(context, formsemestre_id, REQUEST=None):
sem,
)
]
insd = list_inscrits_ailleurs(context, formsemestre_id)
insd = list_inscrits_ailleurs(formsemestre_id)
# liste ordonnée par nom
etudlist = [
sco_etud.get_etud_info(etudid=etudid, filled=1)[0]

View File

@ -63,7 +63,7 @@ from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_formsemestre_custommenu import formsemestre_custommenu_html
def defMenuStats(context, formsemestre_id):
def _build_menu_stats(formsemestre_id):
"Définition du menu 'Statistiques' "
return [
{
@ -121,7 +121,7 @@ def defMenuStats(context, formsemestre_id):
]
def formsemestre_status_menubar(context, sem):
def formsemestre_status_menubar(sem):
"""HTML to render menubar"""
uid = current_user.user_name
formsemestre_id = sem["formsemestre_id"]
@ -426,7 +426,7 @@ def formsemestre_status_menubar(context, sem):
},
]
menuStats = defMenuStats(context, formsemestre_id)
menuStats = _build_menu_stats(formsemestre_id)
H = [
# <table><tr><td>',
'<ul id="sco_menu">',
@ -436,7 +436,7 @@ def formsemestre_status_menubar(context, sem):
htmlutils.make_menu("Notes", menuNotes),
htmlutils.make_menu("Jury", menuJury),
htmlutils.make_menu("Statistiques", menuStats),
formsemestre_custommenu_html(context, formsemestre_id),
formsemestre_custommenu_html(formsemestre_id),
"</ul>",
#'</td></tr></table>'
]
@ -448,7 +448,6 @@ def retreive_formsemestre_from_request():
arguments de la requête:
formsemestre_id ou moduleimpl ou evaluation ou group_id ou partition_id
"""
context = None # XXX #context
if request.method == "GET":
args = request.args
elif request.method == "POST":
@ -494,7 +493,7 @@ def retreive_formsemestre_from_request():
# Element HTML decrivant un semestre (barre de menu et infos)
def formsemestre_page_title(context):
def formsemestre_page_title():
"""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)
"""
@ -515,7 +514,7 @@ def formsemestre_page_title(context):
"""<div class="infos">
<span class="semtitle"><a class="stdlink" title="%(session_id)s" href="%(notes_url)s/formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titre)s</a><a title="%(etape_apo_str)s">%(num_sem)s</a>%(modalitestr)s</span><span class="dates"><a title="du %(date_debut)s au %(date_fin)s ">%(mois_debut)s - %(mois_fin)s</a></span><span class="resp"><a title="%(nomcomplet)s">%(resp)s</a></span><span class="nbinscrits"><a class="discretelink" href="%(notes_url)s/formsemestre_lists?formsemestre_id=%(formsemestre_id)s">%(nbinscrits)d inscrits</a></span><span class="lock">%(locklink)s</span><span class="eye">%(eyelink)s</span></div>"""
% sem,
formsemestre_status_menubar(context, sem),
formsemestre_status_menubar(sem),
"""</div>""",
]
return "\n".join(H)
@ -523,7 +522,6 @@ def formsemestre_page_title(context):
def fill_formsemestre(sem):
"""Add some useful fields to help display formsemestres"""
context = None # XXX #context
notes_url = scu.NotesURL()
sem["notes_url"] = notes_url
formsemestre_id = sem["formsemestre_id"]
@ -576,9 +574,7 @@ def fill_formsemestre(sem):
# Description du semestre sous forme de table exportable
def formsemestre_description_table(
context, formsemestre_id, REQUEST=None, with_evals=False
):
def formsemestre_description_table(formsemestre_id, REQUEST=None, with_evals=False):
"""Description du semestre sous forme de table exportable
Liste des modules et de leurs coefficients
"""
@ -695,7 +691,7 @@ def formsemestre_description_table(
titles["coefficient"] = "Coef. éval."
titles["evalcomplete_str"] = "Complète"
titles["publish_incomplete_str"] = "Toujours Utilisée"
title = "%s %s" % (scu.strcapitalize(parcours.SESSION_NAME), sem["titremois"])
title = "%s %s" % (parcours.SESSION_NAME.capitalize(), sem["titremois"])
return GenTable(
columns_ids=columns_ids,
@ -717,14 +713,14 @@ def formsemestre_description_table(
def formsemestre_description(
context, formsemestre_id, format="html", with_evals=False, REQUEST=None
formsemestre_id, format="html", with_evals=False, REQUEST=None
):
"""Description du semestre sous forme de table exportable
Liste des modules et de leurs coefficients
"""
with_evals = int(with_evals)
tab = formsemestre_description_table(
context, formsemestre_id, REQUEST, with_evals=with_evals
formsemestre_id, REQUEST, with_evals=with_evals
)
tab.html_before_table = """<form name="f" method="get" action="%s">
<input type="hidden" name="formsemestre_id" value="%s"></input>
@ -740,8 +736,7 @@ def formsemestre_description(
# genere liste html pour accès aux groupes de ce semestre
def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
context = context
def _make_listes_sem(sem, REQUEST=None, with_absences=True):
# construit l'URL "destination"
# (a laquelle on revient apres saisie absences)
destination = url_for(
@ -778,7 +773,7 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
<select name="datedebut" class="noprint">
"""
date = first_monday
for jour in sco_abs.day_names(context):
for jour in sco_abs.day_names():
form_abs_tmpl += '<option value="%s">%s</option>' % (date, jour)
date = date.next_day()
form_abs_tmpl += """
@ -875,7 +870,7 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
return "\n".join(H)
def html_expr_diagnostic(context, diagnostics):
def html_expr_diagnostic(diagnostics):
"""Affiche messages d'erreur des formules utilisateurs"""
H = []
H.append('<div class="ue_warning">Erreur dans des formules utilisateurs:<ul>')
@ -906,9 +901,7 @@ def html_expr_diagnostic(context, diagnostics):
return "".join(H)
def formsemestre_status_head(
context, formsemestre_id=None, REQUEST=None, page_title=None
):
def formsemestre_status_head(formsemestre_id=None, REQUEST=None, page_title=None):
"""En-tête HTML des pages "semestre" """
semlist = sco_formsemestre.do_formsemestre_list(
args={"formsemestre_id": formsemestre_id}
@ -963,7 +956,7 @@ Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur ind
H.append(
'<p class="fontorange"><em>Bulletins non publiés sur le portail</em></p>'
)
if sem["semestre_id"] >= 0 and not sco_formsemestre.sem_une_annee(context, sem):
if sem["semestre_id"] >= 0 and not sco_formsemestre.sem_une_annee(sem):
H.append(
'<p class="fontorange"><em>Attention: ce semestre couvre plusieurs années scolaires !</em></p>'
)
@ -973,7 +966,7 @@ Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur ind
return "".join(H)
def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
def formsemestre_status(formsemestre_id=None, REQUEST=None):
"""Tableau de bord semestre HTML"""
# porté du DTML
cnx = ndb.GetDBConnexion()
@ -992,13 +985,13 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
html_sco_header.sco_header(page_title="Semestre %s" % sem["titreannee"]),
'<div class="formsemestre_status">',
formsemestre_status_head(
context, formsemestre_id=formsemestre_id, page_title="Tableau de bord"
formsemestre_id=formsemestre_id, page_title="Tableau de bord"
),
"""<p><b style="font-size: 130%">Tableau de bord: </b><span class="help">cliquez sur un module pour saisir des notes</span></p>""",
]
nt = sco_cache.NotesTableCache.get(formsemestre_id)
if nt.expr_diagnostics:
H.append(html_expr_diagnostic(context, nt.expr_diagnostics))
H.append(html_expr_diagnostic(nt.expr_diagnostics))
H.append(
"""
<p>
@ -1161,7 +1154,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
# --- LISTE DES ETUDIANTS
H += [
'<div id="groupes">',
_make_listes_sem(context, sem, REQUEST),
_make_listes_sem(sem, REQUEST),
"</div>",
]
# --- Lien mail enseignants:

View File

@ -57,7 +57,6 @@ from app.scodoc import sco_pvjury
# ------------------------------------------------------------------------------------
def formsemestre_validation_etud_form(
context, # ZNotes instance
formsemestre_id=None, # required
etudid=None, # one of etudid or etud_index is required
etud_index=None,
@ -151,7 +150,7 @@ def formsemestre_validation_etud_form(
% (
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context, etud, title="fiche de %s" % etud["nom"], REQUEST=REQUEST
etud, title="fiche de %s" % etud["nom"], REQUEST=REQUEST
),
)
)
@ -174,7 +173,7 @@ def formsemestre_validation_etud_form(
H.append(
formsemestre_recap_parcours_table(
context, Se, etudid, with_links=(check and not readonly)
Se, etudid, with_links=(check and not readonly)
)
)
if check:
@ -235,7 +234,7 @@ def formsemestre_validation_etud_form(
H.append("<p>Décision existante du %(event_date)s: %(code)s" % decision_jury)
H.append(" (%s)" % ass)
auts = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, formsemestre_id
etudid, formsemestre_id
)
if auts:
H.append(". Autorisé%s à s'inscrire en " % etud["ne"])
@ -315,7 +314,7 @@ def formsemestre_validation_etud_form(
)
H.append("</form>")
H.append(form_decision_manuelle(context, Se, formsemestre_id, etudid))
H.append(form_decision_manuelle(Se, formsemestre_id, etudid))
H.append(
"""<div class="link_defaillance">Ou <a class="stdlink" href="formDef?etudid=%s&formsemestre_id=%s">déclarer l'étudiant comme défaillant dans ce semestre</a></div>"""
@ -332,7 +331,6 @@ def formsemestre_validation_etud_form(
def formsemestre_validation_etud(
context, # ZNotes instance
formsemestre_id=None, # required
etudid=None, # required
codechoice=None, # required
@ -361,7 +359,6 @@ def formsemestre_validation_etud(
def formsemestre_validation_etud_manu(
context, # ZNotes instance
formsemestre_id=None, # required
etudid=None, # required
code_etat="",
@ -479,7 +476,6 @@ def decisions_possible_rows(Se, assiduite, subtitle="", trclass=""):
def formsemestre_recap_parcours_table(
context,
Se,
etudid,
with_links=False,
@ -522,7 +518,7 @@ def formsemestre_recap_parcours_table(
is_cur = Se.formsemestre_id == sem["formsemestre_id"]
num_sem += 1
dpv = sco_pvjury.dict_pvjury(context, sem["formsemestre_id"], etudids=[etudid])
dpv = sco_pvjury.dict_pvjury(sem["formsemestre_id"], etudids=[etudid])
pv = dpv["decisions"][0]
decision_sem = pv["decision_sem"]
decisions_ue = pv["decisions_ue"]
@ -693,9 +689,7 @@ def formsemestre_recap_parcours_table(
return "\n".join(H)
def form_decision_manuelle(
context, Se, formsemestre_id, etudid, desturl="", sortcol=None
):
def form_decision_manuelle(Se, formsemestre_id, etudid, desturl="", sortcol=None):
"""Formulaire pour saisie décision manuelle"""
H = [
"""
@ -825,7 +819,7 @@ def form_decision_manuelle(
# -----------
def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
def formsemestre_validation_auto(formsemestre_id, REQUEST):
"Formulaire saisie automatisee des decisions d'un semestre"
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
H = [
@ -855,7 +849,7 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
return "\n".join(H)
def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
def do_formsemestre_validation_auto(formsemestre_id, REQUEST):
"Saisie automatisee des decisions d'un semestre"
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
next_semestre_id = sem["semestre_id"] + 1
@ -890,7 +884,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
ok = False
conflicts.append(etud)
autorisations = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, formsemestre_id
etudid, formsemestre_id
)
if (
len(autorisations) != 0
@ -906,7 +900,6 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
# ok, valide !
if ok:
formsemestre_validation_etud_manu(
context,
formsemestre_id,
etudid,
code_etat=ADM,
@ -947,7 +940,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
return "\n".join(H)
def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
def formsemestre_validation_suppress_etud(formsemestre_id, etudid):
"""Suppression des decisions de jury pour un etudiant."""
log("formsemestre_validation_suppress_etud( %s, %s)" % (formsemestre_id, etudid))
cnx = ndb.GetDBConnexion(autocommit=False)
@ -973,11 +966,11 @@ def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
_invalidate_etud_formation_caches(
context, etudid, sem["formation_id"]
etudid, sem["formation_id"]
) # > suppr. decision jury (peut affecter de plusieurs semestres utilisant UE capitalisée)
def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=None):
def formsemestre_validate_previous_ue(formsemestre_id, etudid, REQUEST=None):
"""Form. saisie UE validée hors ScoDoc
(pour étudiants arrivant avec un UE antérieurement validée).
"""
@ -1000,7 +993,7 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
% (
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_html(
context, etud, title="fiche de %s" % etud["nom"], REQUEST=REQUEST
etud, title="fiche de %s" % etud["nom"], REQUEST=REQUEST
),
)
),
@ -1090,7 +1083,6 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
else:
semestre_id = None
do_formsemestre_validate_previous_ue(
context,
formsemestre_id,
etudid,
tf[2]["ue_id"],
@ -1107,7 +1099,6 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
def do_formsemestre_validate_previous_ue(
context,
formsemestre_id,
etudid,
ue_id,
@ -1151,11 +1142,11 @@ def do_formsemestre_validate_previous_ue(
msg="Validation UE %s" % ue_id,
commit=False,
)
_invalidate_etud_formation_caches(context, etudid, sem["formation_id"])
_invalidate_etud_formation_caches(etudid, sem["formation_id"])
cnx.commit()
def _invalidate_etud_formation_caches(context, etudid, formation_id):
def _invalidate_etud_formation_caches(etudid, formation_id):
"Invalide tous les semestres de cette formation où l'etudiant est inscrit..."
r = ndb.SimpleDictFetch(
"""SELECT sem.id
@ -1172,7 +1163,7 @@ def _invalidate_etud_formation_caches(context, etudid, formation_id):
) # > modif decision UE (inval tous semestres avec cet etudiant, ok mais conservatif)
def get_etud_ue_cap_html(context, etudid, formsemestre_id, ue_id, REQUEST=None):
def get_etud_ue_cap_html(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Ramene bout de HTML pour pouvoir supprimer une validation de cette UE"""
valids = ndb.SimpleDictFetch(
"""SELECT SFV.*
@ -1208,7 +1199,7 @@ def get_etud_ue_cap_html(context, etudid, formsemestre_id, ue_id, REQUEST=None):
return "\n".join(H)
def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None):
def etud_ue_suppress_validation(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Suppress a validation (ue_id, etudid) and redirect to formsemestre"""
log("etud_ue_suppress_validation( %s, %s, %s)" % (etudid, formsemestre_id, ue_id))
cnx = ndb.GetDBConnexion()
@ -1219,7 +1210,7 @@ def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST
)
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
_invalidate_etud_formation_caches(context, etudid, sem["formation_id"])
_invalidate_etud_formation_caches(etudid, sem["formation_id"])
return flask.redirect(
scu.NotesURL()

View File

@ -33,7 +33,7 @@ from app.scodoc import sco_groups
from app.scodoc.sco_exceptions import AccessDenied
def affectGroups(context, partition_id, REQUEST=None):
def affectGroups(partition_id, REQUEST=None):
"""Formulaire affectation des etudiants aux groupes de la partition.
Permet aussi la creation et la suppression de groupes.
"""

View File

@ -66,7 +66,6 @@ CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS
def groups_view(
context,
group_ids=[],
format="html",
REQUEST=None,
@ -93,7 +92,6 @@ def groups_view(
# Formats spéciaux: download direct
if format != "html":
return groups_table(
context=context,
groups_infos=groups_infos,
format=format,
REQUEST=REQUEST,
@ -113,7 +111,7 @@ def groups_view(
]
# Menu choix groupe
H.append("""<div id="group-tabs">""")
H.append(form_groups_choice(context, groups_infos, submit_on_change=True))
H.append(form_groups_choice(groups_infos, submit_on_change=True))
# Note: le formulaire est soumis a chaque modif des groupes
# on pourrait faire comme pour le form de saisie des notes. Il faudrait pour cela:
# - charger tous les etudiants au debut, quels que soient les groupes selectionnés
@ -134,7 +132,6 @@ def groups_view(
<div class="tab-pane active" id="tab-listes">
""",
groups_table(
context=context,
groups_infos=groups_infos,
format=format,
REQUEST=REQUEST,
@ -146,11 +143,11 @@ def groups_view(
),
"</div>",
"""<div class="tab-pane" id="tab-photos">""",
tab_photos_html(context, groups_infos, etat=etat, REQUEST=REQUEST),
tab_photos_html(groups_infos, etat=etat, REQUEST=REQUEST),
#'<p>hello</p>',
"</div>",
'<div class="tab-pane" id="tab-abs">',
tab_absences_html(context, groups_infos, etat=etat, REQUEST=REQUEST),
tab_absences_html(groups_infos, etat=etat, REQUEST=REQUEST),
"</div>",
)
)
@ -159,9 +156,7 @@ def groups_view(
return "\n".join(H)
def form_groups_choice(
context, groups_infos, with_selectall_butt=False, submit_on_change=False
):
def form_groups_choice(groups_infos, with_selectall_butt=False, submit_on_change=False):
"""form pour selection groupes
group_ids est la liste des groupes actuellement sélectionnés
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
@ -238,7 +233,7 @@ def menu_groups_choice(groups_infos, submit_on_change=False):
return "\n".join(H)
def menu_group_choice(context, group_id=None, formsemestre_id=None):
def menu_group_choice(group_id=None, formsemestre_id=None):
"""Un bête menu pour choisir un seul groupe
group_id est le groupe actuellement sélectionné.
Si aucun groupe selectionné, utilise formsemestre_id pour lister les groupes.
@ -427,7 +422,6 @@ class DisplayedGroupsInfos(object):
# Ancien ZScolar.group_list renommé ici en group_table
def groups_table(
context=None,
REQUEST=None,
groups_infos=None, # instance of DisplayedGroupsInfos
with_codes=0,
@ -506,7 +500,7 @@ def groups_table(
sco_archives_etud.add_archives_info_to_etud_list(groups_infos.members)
columns_ids += ["etudarchive"]
if with_annotations:
sco_etud.add_annotations_to_etud_list(context, groups_infos.members)
sco_etud.add_annotations_to_etud_list(groups_infos.members)
columns_ids += ["annotations_str"]
if groups_infos.formsemestre["semestre_id"] >= 0:
@ -784,7 +778,7 @@ def groups_table(
etud, groups_infos.formsemestre_id
)
m["parcours"] = Se.get_parcours_descr()
m["codeparcours"], _ = sco_report.get_codeparcoursetud(context, etud)
m["codeparcours"], _ = sco_report.get_codeparcoursetud(etud)
def dicttakestr(d, keys):
r = []
@ -801,7 +795,7 @@ def groups_table(
raise ValueError("unsupported format")
def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
def tab_absences_html(groups_infos, etat=None, REQUEST=None):
"""contenu du tab "absences et feuilles diverses" """
authuser = REQUEST.AUTHENTICATED_USER
H = ['<div class="tab-content">']
@ -812,12 +806,10 @@ def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
"<h3>Absences</h3>",
'<ul class="ul_abs">',
"<li>",
form_choix_saisie_semaine(
context, groups_infos, REQUEST=REQUEST
), # Ajout Le Havre
form_choix_saisie_semaine(groups_infos, REQUEST=REQUEST), # Ajout Le Havre
"</li>",
"<li>",
form_choix_jour_saisie_hebdo(context, groups_infos, REQUEST=REQUEST),
form_choix_jour_saisie_hebdo(groups_infos, REQUEST=REQUEST),
"</li>",
"""<li><a class="stdlink" href="Absences/EtatAbsencesGr?%s&debut=%s&fin=%s">Etat des absences du groupe</a></li>"""
% (
@ -862,19 +854,17 @@ def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
return "".join(H)
def tab_photos_html(context, groups_infos, etat=None, REQUEST=None):
def tab_photos_html(groups_infos, etat=None, REQUEST=None):
"""contenu du tab "photos" """
from app.scodoc import sco_trombino
if not groups_infos.members:
return '<div class="tab-content"><h3>Aucun étudiant !</h3></div>'
return sco_trombino.trombino_html(context, groups_infos, REQUEST=REQUEST)
return sco_trombino.trombino_html(groups_infos, REQUEST=REQUEST)
def form_choix_jour_saisie_hebdo(
context, groups_infos, moduleimpl_id=None, REQUEST=None
):
def form_choix_jour_saisie_hebdo(groups_infos, moduleimpl_id=None, REQUEST=None):
"""Formulaire choix jour semaine pour saisie."""
authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(Permission.ScoAbsChange):
@ -901,7 +891,7 @@ def form_choix_jour_saisie_hebdo(
FA.append("""<select name="datedebut">""")
date = first_monday
i = 0
for jour in sco_abs.day_names(context):
for jour in sco_abs.day_names():
if i == today_idx:
sel = "selected"
else:
@ -916,7 +906,7 @@ def form_choix_jour_saisie_hebdo(
# Ajout Le Havre
# Formulaire saisie absences semaine
def form_choix_saisie_semaine(context, groups_infos, REQUEST=None):
def form_choix_saisie_semaine(groups_infos, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(Permission.ScoAbsChange):
return ""
@ -947,7 +937,7 @@ def form_choix_saisie_semaine(context, groups_infos, REQUEST=None):
return "\n".join(FA)
def export_groups_as_moodle_csv(context, formsemestre_id=None, REQUEST=None):
def export_groups_as_moodle_csv(formsemestre_id=None, REQUEST=None):
"""Export all students/groups, in a CSV format suitable for Moodle
Each (student,group) will be listed on a separate line
jo@univ.fr,S3-A

View File

@ -157,7 +157,6 @@ def sco_import_generate_excel_sample(
exclude_cols=[],
extra_cols=[],
group_ids=[],
context=None,
REQUEST=None,
):
"""Generates an excel document based on format fmt
@ -171,10 +170,10 @@ def sco_import_generate_excel_sample(
titles = []
titlesStyles = []
for l in fmt:
name = scu.strlower(l[0])
name = l[0].lower()
if (not with_codesemestre) and name == "codesemestre":
continue # pas de colonne codesemestre
if only_tables is not None and scu.strlower(l[2]) not in only_tables:
if only_tables is not None and l[2].lower() not in only_tables:
continue # table non demandée
if name in exclude_cols:
continue # colonne exclue
@ -188,7 +187,7 @@ def sco_import_generate_excel_sample(
titlesStyles.append(style)
titles += extra_cols
titlesStyles += [style] * len(extra_cols)
if group_ids and context:
if group_ids:
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids, REQUEST=REQUEST)
members = groups_infos.members
log(
@ -209,7 +208,7 @@ def sco_import_generate_excel_sample(
)
l.append(etud["partitionsgroupes"])
else:
key = scu.strlower(field).split()[0]
key = field.lower().split()[0]
l.append(etud.get(key, ""))
lines.append(l)
else:
@ -220,7 +219,6 @@ def sco_import_generate_excel_sample(
def students_import_excel(
context,
csvfile,
REQUEST=None,
formsemestre_id=None,
@ -230,7 +228,6 @@ def students_import_excel(
"import students from Excel file"
diag = scolars_import_excel_file(
csvfile,
context,
REQUEST,
formsemestre_id=formsemestre_id,
check_homonyms=check_homonyms,
@ -258,7 +255,6 @@ def students_import_excel(
def scolars_import_excel_file(
datafile,
context,
REQUEST,
formsemestre_id=None,
check_homonyms=True,
@ -285,7 +281,7 @@ def scolars_import_excel_file(
titles = {}
fmt = sco_import_format()
for l in fmt:
tit = scu.strlower(l[0]).split()[0] # titles in lowercase, and take 1st word
tit = l[0].lower().split()[0] # titles in lowercase, and take 1st word
if (
(not formsemestre_id) or (tit != "codesemestre")
) and tit not in exclude_cols:
@ -294,7 +290,7 @@ def scolars_import_excel_file(
# log("titles=%s" % titles)
# remove quotes, downcase and keep only 1st word
try:
fs = [scu.strlower(scu.stripquotes(s)).split()[0] for s in data[0]]
fs = [scu.stripquotes(s).lower().split()[0] for s in data[0]]
except:
raise ScoValueError("Titres de colonnes invalides (ou vides ?)")
# log("excel: fs='%s'\ndata=%s" % (str(fs), str(data)))
@ -371,7 +367,7 @@ def scolars_import_excel_file(
% (val, linenum, titleslist[i])
)
# xxx Ad-hoc checks (should be in format description)
if scu.strlower(titleslist[i]) == "sexe":
if titleslist[i].lower() == "sexe":
try:
val = sco_etud.input_civilite(val)
except:
@ -380,13 +376,13 @@ def scolars_import_excel_file(
% (val, linenum, titleslist[i])
)
# Excel date conversion:
if scu.strlower(titleslist[i]) == "date_naissance":
if titleslist[i].lower() == "date_naissance":
if val:
# if re.match(r"^[0-9]*\.?[0-9]*$", str(val)):
val = sco_excel.xldate_as_datetime(val)
# INE
if (
scu.strlower(titleslist[i]) == "code_ine"
titleslist[i].lower() == "code_ine"
and always_require_ine
and not val
):
@ -419,7 +415,6 @@ def scolars_import_excel_file(
# Insert in DB tables
formsemestre_to_invalidate.add(
_import_one_student(
context,
cnx,
REQUEST,
formsemestre_id,
@ -494,12 +489,11 @@ def scolars_import_excel_file(
def students_import_admission(
context, csvfile, type_admission="", REQUEST=None, formsemestre_id=None
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,
@ -522,7 +516,6 @@ def students_import_admission(
def _import_one_student(
context,
cnx,
REQUEST,
formsemestre_id,
@ -542,7 +535,7 @@ def _import_one_student(
)
# Identite
args = values.copy()
etudid = sco_etud.identite_create(cnx, args, context=context, REQUEST=REQUEST)
etudid = sco_etud.identite_create(cnx, args, REQUEST=REQUEST)
created_etudids.append(etudid)
# Admissions
args["etudid"] = etudid
@ -575,7 +568,6 @@ def _import_one_student(
)
do_formsemestre_inscription_with_modules(
context,
args["formsemestre_id"],
etudid,
group_ids,
@ -594,7 +586,7 @@ def _is_new_ine(cnx, code_ine):
# ------ Fonction ré-écrite en nov 2016 pour lire des fichiers sans etudid (fichiers APB)
def scolars_import_admission(
datafile, context, REQUEST, formsemestre_id=None, type_admission=None
datafile, REQUEST, formsemestre_id=None, type_admission=None
):
"""Importe données admission depuis un fichier Excel quelconque
par exemple ceux utilisés avec APB
@ -698,13 +690,13 @@ def scolars_import_admission(
# Type admission: traitement particulier
if not cur_adm["type_admission"] and not args.get("type_admission"):
args["type_admission"] = type_admission
sco_etud.etudident_edit(cnx, args)
sco_etud.etudident_edit(cnx, args, disable_notify=True)
adr = sco_etud.adresse_list(cnx, args={"etudid": etud["etudid"]})
if adr:
args["adresse_id"] = adr[0]["adresse_id"]
sco_etud.adresse_edit(
cnx, args
) # ne passe pas le contexte: pas de notification ici
cnx, args, disable_notify=True
) # pas de notification ici
else:
args["typeadresse"] = "domicile"
args["description"] = "(infos admission)"
@ -800,7 +792,7 @@ def adm_convert_real(v):
return float(v)
def adm_table_description_format(context):
def adm_table_description_format():
"""Table HTML (ou autre format) decrivant les donnees d'admissions importables"""
Fmt = sco_import_format_dict(with_codesemestre=False)
for k in Fmt:

View File

@ -76,7 +76,7 @@ def import_excel_file(datafile, REQUEST=None, context=None):
if not data: # probably a bug
raise ScoException("import_excel_file: empty file !")
# 1- --- check title line
fs = [scu.strlower(scu.stripquotes(s)) for s in data[0]]
fs = [scu.stripquotes(s).lower() for s in data[0]]
log("excel: fs='%s'\ndata=%s" % (str(fs), str(data)))
# check cols
cols = {}.fromkeys(TITLES)
@ -230,4 +230,4 @@ Pour plus d'informations sur ce logiciel, voir %s
msg.epilogue = ""
txt = MIMEText(txt, "plain", scu.SCO_ENCODING)
msg.attach(txt)
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)

View File

@ -49,17 +49,17 @@ from app.scodoc import sco_etud
from app.scodoc.sco_exceptions import ScoValueError
def list_authorized_etuds_by_sem(context, sem, delai=274):
def list_authorized_etuds_by_sem(sem, delai=274):
"""Liste des etudiants autorisés à s'inscrire dans sem.
delai = nb de jours max entre la date de l'autorisation et celle de debut du semestre cible.
"""
src_sems = list_source_sems(context, sem, delai=delai)
inscrits = list_inscrits(context, sem["formsemestre_id"])
src_sems = list_source_sems(sem, delai=delai)
inscrits = list_inscrits(sem["formsemestre_id"])
r = {}
candidats = {} # etudid : etud (tous les etudiants candidats)
nb = 0 # debug
for src in src_sems:
liste = list_etuds_from_sem(context, src, sem)
liste = list_etuds_from_sem(src, sem)
liste_filtree = []
for e in liste:
# Filtre ceux qui se sont déjà inscrit dans un semestre APRES le semestre src
@ -105,7 +105,7 @@ def list_authorized_etuds_by_sem(context, sem, delai=274):
return r, inscrits, candidats
def list_inscrits(context, formsemestre_id, with_dems=False):
def list_inscrits(formsemestre_id, with_dems=False):
"""Etudiants déjà inscrits à ce semestre
{ etudid : etud }
"""
@ -123,10 +123,10 @@ def list_inscrits(context, formsemestre_id, with_dems=False):
return inscr
def list_etuds_from_sem(context, src, dst):
def list_etuds_from_sem(src, dst):
"""Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst."""
target = dst["semestre_id"]
dpv = sco_pvjury.dict_pvjury(context, src["formsemestre_id"])
dpv = sco_pvjury.dict_pvjury(src["formsemestre_id"])
if not dpv:
return []
etuds = [
@ -137,7 +137,7 @@ def list_etuds_from_sem(context, src, dst):
return etuds
def list_inscrits_date(context, sem):
def list_inscrits_date(sem):
"""Liste les etudiants inscrits dans n'importe quel semestre
SAUF sem à la date de début de sem.
"""
@ -156,7 +156,7 @@ def list_inscrits_date(context, sem):
return [x[0] for x in cursor.fetchall()]
def do_inscrit(context, sem, etudids, REQUEST=None, inscrit_groupes=False):
def do_inscrit(sem, etudids, REQUEST=None, inscrit_groupes=False):
"""Inscrit ces etudiants dans ce semestre
(la liste doit avoir été vérifiée au préalable)
En option: inscrit aux mêmes groupes que dans le semestre origine
@ -164,7 +164,6 @@ def do_inscrit(context, sem, etudids, REQUEST=None, inscrit_groupes=False):
log("do_inscrit (inscrit_groupes=%s): %s" % (inscrit_groupes, etudids))
for etudid in etudids:
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
context,
sem["formsemestre_id"],
etudid,
etat="I",
@ -212,15 +211,15 @@ def do_inscrit(context, sem, etudids, REQUEST=None, inscrit_groupes=False):
)
def do_desinscrit(context, sem, etudids, REQUEST):
def do_desinscrit(sem, etudids, REQUEST):
log("do_desinscrit: %s" % etudids)
for etudid in etudids:
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
context, etudid, sem["formsemestre_id"], REQUEST=REQUEST
etudid, sem["formsemestre_id"], REQUEST=REQUEST
)
def list_source_sems(context, sem, delai=None):
def list_source_sems(sem, delai=None):
"""Liste des semestres sources
sem est le semestre destination
"""
@ -256,7 +255,6 @@ def list_source_sems(context, sem, delai=None):
def formsemestre_inscr_passage(
context,
formsemestre_id,
etuds=[],
inscrit_groupes=False,
@ -288,12 +286,12 @@ def formsemestre_inscr_passage(
if type(etuds) == type(""):
etuds = etuds.split(",") # vient du form de confirmation
auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(context, sem)
auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(sem)
etuds_set = set(etuds)
candidats_set = set(candidats)
inscrits_set = set(inscrits)
candidats_non_inscrits = candidats_set - inscrits_set
inscrits_ailleurs = set(list_inscrits_date(context, sem))
inscrits_ailleurs = set(list_inscrits_date(sem))
def set_to_sorted_etud_list(etudset):
etuds = [candidats[etudid] for etudid in etudset]
@ -310,7 +308,6 @@ def formsemestre_inscr_passage(
if not submitted:
H += build_page(
context,
REQUEST,
sem,
auth_etuds_by_sem,
@ -361,7 +358,6 @@ def formsemestre_inscr_passage(
else:
# Inscription des étudiants au nouveau semestre:
do_inscrit(
context,
sem,
a_inscrire,
REQUEST=REQUEST,
@ -369,7 +365,7 @@ def formsemestre_inscr_passage(
)
# Desincriptions:
do_desinscrit(context, sem, a_desinscrire, REQUEST)
do_desinscrit(sem, a_desinscrire, REQUEST)
H.append(
"""<h3>Opération effectuée</h3>
@ -398,7 +394,6 @@ def formsemestre_inscr_passage(
def build_page(
context,
REQUEST,
sem,
auth_etuds_by_sem,
@ -429,7 +424,7 @@ def build_page(
et %d candidats supplémentaires
</div>"""
% (len(inscrits), len(candidats_non_inscrits)),
etuds_select_boxes(context, auth_etuds_by_sem, inscrits_ailleurs),
etuds_select_boxes(auth_etuds_by_sem, inscrits_ailleurs),
"""<p/><input type="submit" name="submitted" value="Appliquer les modifications"/>""",
formsemestre_inscr_passage_help(sem),
"""</form>""",
@ -473,7 +468,6 @@ def formsemestre_inscr_passage_help(sem):
def etuds_select_boxes(
context,
auth_etuds_by_cat,
inscrits_ailleurs={},
sel_inscrits=True,
@ -489,7 +483,7 @@ def etuds_select_boxes(
export_cat_xls =
"""
if export_cat_xls:
return etuds_select_box_xls(context, auth_etuds_by_cat[export_cat_xls])
return etuds_select_box_xls(auth_etuds_by_cat[export_cat_xls])
H = [
"""<script type="text/javascript">
@ -615,7 +609,7 @@ def etuds_select_boxes(
return "\n".join(H)
def etuds_select_box_xls(context, src_cat):
def etuds_select_box_xls(src_cat):
"export a box to excel"
etuds = src_cat["etuds"]
columns_ids = ["etudid", "civilite_str", "nom", "prenom", "etape"]

View File

@ -55,7 +55,7 @@ from app.scodoc.gen_tables import GenTable
from app.scodoc.htmlutils import histogram_notes
def do_evaluation_listenotes(context, REQUEST):
def do_evaluation_listenotes(REQUEST):
"""
Affichage des notes d'une évaluation
@ -204,7 +204,6 @@ def do_evaluation_listenotes(context, REQUEST):
hide_groups = tf[2]["hide_groups"]
with_emails = tf[2]["with_emails"]
return _make_table_notes(
context,
REQUEST,
tf[1],
evals,
@ -218,7 +217,6 @@ def do_evaluation_listenotes(context, REQUEST):
def _make_table_notes(
context,
REQUEST,
html_form,
evals,
@ -324,11 +322,11 @@ def _make_table_notes(
"code": code,
"_code_td_attrs": 'style="padding-left: 1em; padding-right: 2em;"',
"etudid": etudid,
"nom": scu.strupper(etud["nom"]),
"nom": etud["nom"].upper(),
"_nomprenom_target": "formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s"
% (M["formsemestre_id"], etudid),
"_nomprenom_td_attrs": 'id="%s" class="etudinfo"' % (etud["etudid"]),
"prenom": scu.strcapitalize(scu.strlower(etud["prenom"])),
"prenom": etud["prenom"].lower().capitalize(),
"nomprenom": etud["nomprenom"],
"group": grc,
"email": etud["email"],
@ -367,7 +365,6 @@ def _make_table_notes(
for e in evals:
e["eval_state"] = sco_evaluations.do_evaluation_etat(e["evaluation_id"])
notes, nb_abs, nb_att = _add_eval_columns(
context,
e,
rows,
titles,
@ -388,7 +385,6 @@ def _make_table_notes(
# Si module, ajoute moyenne du module:
if len(evals) > 1:
_add_moymod_column(
context,
sem["formsemestre_id"],
e,
rows,
@ -542,7 +538,7 @@ def _make_table_notes(
def _add_eval_columns(
context, e, rows, titles, coefs, note_max, moys, K, note_sur_20, keep_numeric
e, rows, titles, coefs, note_max, moys, K, note_sur_20, keep_numeric
):
"""Add eval e"""
nb_notes = 0
@ -645,7 +641,6 @@ def _add_eval_columns(
def _add_moymod_column(
context,
formsemestre_id,
e,
rows,
@ -707,7 +702,7 @@ def _eval_demijournee(E):
return am, pm, demijournee
def evaluation_check_absences(context, evaluation_id):
def evaluation_check_absences(evaluation_id):
"""Vérifie les absences au moment de cette évaluation.
Cas incohérents que l'on peut rencontrer pour chaque étudiant:
note et absent
@ -769,7 +764,7 @@ def evaluation_check_absences(context, evaluation_id):
def evaluation_check_absences_html(
context, evaluation_id, with_header=True, show_ok=True, REQUEST=None
evaluation_id, with_header=True, show_ok=True, REQUEST=None
):
"""Affiche etat verification absences d'une evaluation"""
@ -782,7 +777,7 @@ def evaluation_check_absences_html(
ExcNonSignalee,
ExcNonJust,
AbsButExc,
) = evaluation_check_absences(context, evaluation_id)
) = evaluation_check_absences(evaluation_id)
if with_header:
H = [
@ -871,7 +866,7 @@ def evaluation_check_absences_html(
return "\n".join(H)
def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
def formsemestre_check_absences_html(formsemestre_id, REQUEST=None):
"""Affiche etat verification absences pour toutes les evaluations du semestre !"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
H = [
@ -901,7 +896,6 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
for E in evals:
H.append(
evaluation_check_absences_html(
context,
E["evaluation_id"],
with_header=False,
show_ok=False,

View File

@ -45,18 +45,17 @@ from app.scodoc.gen_tables import GenTable
def formsemestre_table_etuds_lycees(
context, formsemestre_id, group_lycees=True, only_primo=False
formsemestre_id, group_lycees=True, only_primo=False
):
"""Récupère liste d'etudiants avec etat et decision."""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
etuds = sco_report.tsp_etud_list(context, formsemestre_id, only_primo=only_primo)[0]
etuds = sco_report.tsp_etud_list(formsemestre_id, only_primo=only_primo)[0]
if only_primo:
primostr = "primo-entrants du "
else:
primostr = "du "
title = "Lycées des étudiants %ssemestre " % primostr + sem["titreannee"]
return _table_etuds_lycees(
context,
etuds,
group_lycees,
title,
@ -64,7 +63,7 @@ def formsemestre_table_etuds_lycees(
)
def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
def scodoc_table_etuds_lycees(format="html", REQUEST=None):
"""Table avec _tous_ les étudiants des semestres non verrouillés
de _tous_ les départements.
"""
@ -74,12 +73,11 @@ def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
try:
for (sem, dept) in semdepts:
app.set_sco_dept(dept.acronym)
etuds += sco_report.tsp_etud_list(context, sem["formsemestre_id"])[0]
etuds += sco_report.tsp_etud_list(sem["formsemestre_id"])[0]
finally:
app.set_sco_dept(cur_dept)
tab, etuds_by_lycee = _table_etuds_lycees(
context,
etuds,
False,
"Lycées de TOUS les étudiants",
@ -108,9 +106,7 @@ def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
return "\n".join(H)
def _table_etuds_lycees(
context, etuds, group_lycees, title, preferences, no_links=False
):
def _table_etuds_lycees(etuds, group_lycees, title, preferences, no_links=False):
etuds = [sco_etud.etud_add_lycee_infos(e) for e in etuds]
etuds_by_lycee = scu.group_by_key(etuds, "codelycee")
#
@ -179,7 +175,6 @@ def _table_etuds_lycees(
def formsemestre_etuds_lycees(
context,
formsemestre_id,
format="html",
only_primo=False,
@ -188,7 +183,7 @@ def formsemestre_etuds_lycees(
):
"""Table des lycées d'origine"""
tab, etuds_by_lycee = formsemestre_table_etuds_lycees(
context, formsemestre_id, only_primo=only_primo, group_lycees=not no_grouping
formsemestre_id, only_primo=only_primo, group_lycees=not no_grouping
)
tab.base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id)
if only_primo:

View File

@ -38,24 +38,24 @@ import app.scodoc.sco_utils as scu
from app.scodoc.notes_log import log
def list_formsemestres_modalites(context, sems):
def list_formsemestres_modalites(sems):
"""Liste ordonnée des modalités présentes dans ces formsemestres"""
modalites = {}
for sem in sems:
if sem["modalite"] not in modalites:
m = do_modalite_list(context, args={"modalite": sem["modalite"]})[0]
m = do_modalite_list(args={"modalite": sem["modalite"]})[0]
modalites[m["modalite"]] = m
modalites = list(modalites.values())
modalites.sort(key=lambda x: x["numero"])
return modalites
def group_sems_by_modalite(context, sems):
def group_sems_by_modalite(sems):
"""Given the list of fromsemestre, group them by modalite,
sorted in each one by semestre id and date
"""
sems_by_mod = scu.DictDefault(defaultvalue=[])
modalites = list_formsemestres_modalites(context, sems)
modalites = list_formsemestres_modalites(sems)
for modalite in modalites:
for sem in sems:
if sem["semestre_id"] < 0: # formations en un semestre
@ -82,29 +82,29 @@ _modaliteEditor = ndb.EditableTable(
)
def do_modalite_list(context, *args, **kw):
def do_modalite_list(*args, **kw):
"""Liste des modalites"""
cnx = ndb.GetDBConnexion()
return _modaliteEditor.list(cnx, *args, **kw)
def do_modalite_create(context, args, REQUEST=None):
def do_modalite_create(args, REQUEST=None):
"create a modalite"
cnx = ndb.GetDBConnexion()
r = _modaliteEditor.create(cnx, args)
return r
def do_modalite_delete(context, oid, REQUEST=None):
def do_modalite_delete(oid, REQUEST=None):
"delete a modalite"
cnx = ndb.GetDBConnexion()
log("do_modalite_delete: form_modalite_id=%s" % oid)
_modaliteEditor.delete(cnx, oid)
def do_modalite_edit(context, *args, **kw): # unused
def do_modalite_edit(*args, **kw): # unused
"edit a modalite"
cnx = ndb.GetDBConnexion()
# check
_ = do_modalite_list(context, {"form_modalite_id": args[0]["form_modalite_id"]})[0]
_ = do_modalite_list({"form_modalite_id": args[0]["form_modalite_id"]})[0]
_modaliteEditor.edit(cnx, *args, **kw)

View File

@ -51,7 +51,7 @@ from app.scodoc.sco_permissions import Permission
def moduleimpl_inscriptions_edit(
context, moduleimpl_id, etuds=[], submitted=False, REQUEST=None
moduleimpl_id, etuds=[], submitted=False, REQUEST=None
):
"""Formulaire inscription des etudiants a ce module
* Gestion des inscriptions
@ -146,8 +146,8 @@ def moduleimpl_inscriptions_edit(
% M
)
H.append("<table><tr>")
H.append(_make_menu(context, partitions, "Ajouter", "true"))
H.append(_make_menu(context, partitions, "Enlever", "false"))
H.append(_make_menu(partitions, "Ajouter", "true"))
H.append(_make_menu(partitions, "Enlever", "false"))
H.append("</tr></table>")
H.append(
"""
@ -207,7 +207,7 @@ def moduleimpl_inscriptions_edit(
return "\n".join(H)
def _make_menu(context, partitions, title="", check="true"):
def _make_menu(partitions, title="", check="true"):
"""Menu with list of all groups"""
items = [{"title": "Tous", "attr": "onclick=\"group_select('', -1, %s)\"" % check}]
p_idx = 0
@ -230,7 +230,7 @@ def _make_menu(context, partitions, title="", check="true"):
)
def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
def moduleimpl_inscriptions_stats(formsemestre_id, REQUEST=None):
"""Affiche quelques informations sur les inscriptions
aux modules de ce semestre.
@ -272,7 +272,6 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
options = [] # modules ou seuls quelques etudiants sont inscrits
for mod in Mlist:
tous_inscrits, nb_inscrits, descr = descr_inscrs_module(
context,
sem,
mod["moduleimpl_id"],
set_all,
@ -342,7 +341,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
H.append("</table>")
# Etudiants "dispensés" d'une UE (capitalisée)
UECaps = get_etuds_with_capitalized_ue(context, formsemestre_id)
UECaps = get_etuds_with_capitalized_ue(formsemestre_id)
if UECaps:
H.append('<h3>Etudiants avec UEs capitalisées:</h3><ul class="ue_inscr_list">')
ues = [sco_edit_ue.do_ue_list({"ue_id": ue_id})[0] for ue_id in UECaps.keys()]
@ -420,7 +419,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
def descr_inscrs_module(
context, sem, moduleimpl_id, set_all, partitions, partitions_etud_groups
sem, moduleimpl_id, set_all, partitions, partitions_etud_groups
):
"""returns tous_inscrits, nb_inscrits, descr"""
ins = sco_moduleimpl.do_moduleimpl_inscription_list(moduleimpl_id=moduleimpl_id)
@ -429,7 +428,7 @@ def descr_inscrs_module(
if len(non_inscrits) == 0:
return True, len(ins), "" # tous inscrits
if len(non_inscrits) <= 7: # seuil arbitraire
return False, len(ins), "tous sauf " + _fmt_etud_set(context, non_inscrits)
return False, len(ins), "tous sauf " + _fmt_etud_set(non_inscrits)
# Cherche les groupes:
gr = [] # [ ( partition_name , [ group_names ] ) ]
for partition in partitions:
@ -450,12 +449,12 @@ def descr_inscrs_module(
if d:
r.append(", ".join(d))
if set_m:
r.append(_fmt_etud_set(context, set_m))
r.append(_fmt_etud_set(set_m))
#
return False, len(ins), " et ".join(r)
def _fmt_etud_set(context, ins, max_list_size=7):
def _fmt_etud_set(ins, max_list_size=7):
# max_list_size est le nombre max de noms d'etudiants listés
# au delà, on indique juste le nombre, sans les noms.
if len(ins) > max_list_size:
@ -478,7 +477,7 @@ def _fmt_etud_set(context, ins, max_list_size=7):
)
def get_etuds_with_capitalized_ue(context, formsemestre_id):
def get_etuds_with_capitalized_ue(formsemestre_id):
"""For each UE, computes list of students capitalizing the UE.
returns { ue_id : [ { infos } ] }
"""
@ -497,14 +496,14 @@ def get_etuds_with_capitalized_ue(context, formsemestre_id):
"etudid": etud["etudid"],
"ue_status": status,
"is_ins": is_inscrit_ue(
context, etud["etudid"], formsemestre_id, ue["ue_id"]
etud["etudid"], formsemestre_id, ue["ue_id"]
),
}
)
return UECaps
def is_inscrit_ue(context, etudid, formsemestre_id, ue_id):
def is_inscrit_ue(etudid, formsemestre_id, ue_id):
"""Modules de cette UE dans ce semestre
auxquels l'étudiant est inscrit.
"""
@ -525,7 +524,7 @@ def is_inscrit_ue(context, etudid, formsemestre_id, ue_id):
return r
def do_etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
def do_etud_desinscrit_ue(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Desincrit l'etudiant de tous les modules de cette UE dans ce semestre."""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -558,7 +557,7 @@ def do_etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None)
) # > desinscription etudiant des modules
def do_etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
def do_etud_inscrit_ue(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Incrit l'etudiant de tous les modules de cette UE dans ce semestre."""
# Verifie qu'il est bien inscrit au semestre
insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(

View File

@ -54,7 +54,7 @@ from app.scodoc import sco_users
# ported from old DTML code in oct 2009
# menu evaluation dans moduleimpl
def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0, REQUEST=None):
"Menu avec actions sur une evaluation"
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
modimpl = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
@ -154,7 +154,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
return htmlutils.make_menu("actions", menuEval, alone=True)
def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=None):
def moduleimpl_status(moduleimpl_id=None, partition_id=None, REQUEST=None):
"""Tableau de bord module (liste des evaluations etc)"""
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = M["formsemestre_id"]
@ -241,7 +241,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
)
H.append("</td></tr>")
# Ligne: règle de calcul
has_expression = sco_compute_moy.moduleimpl_has_expression(context, M)
has_expression = sco_compute_moy.moduleimpl_has_expression(M)
if has_expression:
H.append(
'<tr><td class="fichetitre2" colspan="4">Règle de calcul: <span class="formula" title="mode de calcul de la moyenne du module">moyenne=<tt>%s</tt></span>'
@ -271,7 +271,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
# Liens saisies absences seulement si permission et date courante dans le semestre
if current_user.has_permission(
Permission.ScoAbsChange
) and sco_formsemestre.sem_est_courant(context, sem):
) and sco_formsemestre.sem_est_courant(sem):
datelundi = sco_abs.ddmmyyyy(time.strftime("%d/%m/%Y")).prev_monday()
group_id = sco_groups.get_default_group(formsemestre_id)
H.append(
@ -287,9 +287,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
H.append("</td></tr></table>")
#
if has_expression and nt.expr_diagnostics:
H.append(
sco_formsemestre_status.html_expr_diagnostic(context, nt.expr_diagnostics)
)
H.append(sco_formsemestre_status.html_expr_diagnostic(nt.expr_diagnostics))
#
if nt.sem_has_decisions():
H.append(
@ -515,7 +513,6 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
if caneditnotes:
H.append(
moduleimpl_evaluation_menu(
context,
eval["evaluation_id"],
nbnotes=etat["nb_notes"],
REQUEST=REQUEST,

View File

@ -111,7 +111,7 @@ def add(typ, object=None, text="", url=None, max_frequency=False):
return scolar_news_create(cnx, args)
def scolar_news_summary(context, n=5):
def scolar_news_summary(n=5):
"""Return last n news.
News are "compressed", ie redondant events are joined.
"""
@ -156,7 +156,7 @@ def scolar_news_summary(context, n=5):
mois = sco_etud.MONTH_NAMES_ABBREV[int(m) - 1]
n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"])
# indication semestre si ajout notes:
infos = _get_formsemestre_infos_from_news(context, n)
infos = _get_formsemestre_infos_from_news(n)
if infos:
n["text"] += (
' (<a href="Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(descr_sem)s</a>)'
@ -169,7 +169,7 @@ def scolar_news_summary(context, n=5):
return news
def _get_formsemestre_infos_from_news(context, n):
def _get_formsemestre_infos_from_news(n):
"""Informations sur le semestre concerné par la nouvelle n
{} si inexistant
"""
@ -202,9 +202,9 @@ def _get_formsemestre_infos_from_news(context, n):
return {"formsemestre_id": formsemestre_id, "sem": sem, "descr_sem": descr_sem}
def scolar_news_summary_html(context, n=5):
def scolar_news_summary_html(n=5):
"""News summary, formated in HTML"""
news = scolar_news_summary(context, n=n)
news = scolar_news_summary(n=n)
if not news:
return ""
H = ['<div class="news"><span class="newstitle">Dernières opérations']
@ -235,8 +235,7 @@ def scolar_news_summary_html(context, n=5):
def _send_news_by_mail(n):
"""Notify by email"""
context = None # #context
infos = _get_formsemestre_infos_from_news(context, n)
infos = _get_formsemestre_infos_from_news(n)
formsemestre_id = infos.get("formsemestre_id", None)
prefs = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id)
destinations = prefs["emails_notifications"] or ""
@ -283,4 +282,4 @@ def _send_news_by_mail(n):
del msg["To"]
msg["To"] = email_addr
# log('xxx mail: %s' % msg)
sco_emails.sendEmail(context, msg)
sco_emails.sendEmail(msg)

View File

@ -54,7 +54,7 @@ from app.scodoc.sco_formsemestre_validation import formsemestre_recap_parcours_t
from app.scodoc.sco_permissions import Permission
def _menuScolarite(context, authuser, sem, etudid):
def _menuScolarite(authuser, sem, etudid):
"""HTML pour menu "scolarite" pour un etudiant dans un semestre.
Le contenu du menu depend des droits de l'utilisateur et de l'état de l'étudiant.
"""
@ -142,7 +142,7 @@ def _menuScolarite(context, authuser, sem, etudid):
)
def ficheEtud(context, etudid=None, REQUEST=None):
def ficheEtud(etudid=None, REQUEST=None):
"fiche d'informations sur un etudiant"
log("XXX ficheEtud etudid=%s" % etudid)
authuser = REQUEST.AUTHENTICATED_USER
@ -168,7 +168,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
info["info_naissance"] += " à " + info["lieu_naissance"]
if info["dept_naissance"]:
info["info_naissance"] += " (%s)" % info["dept_naissance"]
info["etudfoto"] = sco_photos.etud_photo_html(context, etud, REQUEST=REQUEST)
info["etudfoto"] = sco_photos.etud_photo_html(etud, REQUEST=REQUEST)
if (
(not info["domicile"])
and (not info["codepostaldomicile"])
@ -220,7 +220,6 @@ def ficheEtud(context, etudid=None, REQUEST=None):
for sem in info["sems"]:
if sem["ins"]["etat"] != "I":
descr, _ = etud_descr_situation_semestre(
context,
etudid,
sem["formsemestre_id"],
info["ne"],
@ -238,7 +237,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
% (group["group_id"], gr_name)
)
# infos ajoutées au semestre dans le parcours (groupe, menu)
menu = _menuScolarite(context, authuser, sem, etudid)
menu = _menuScolarite(authuser, sem, etudid)
if menu:
sem_info[sem["formsemestre_id"]] = (
"<table><tr><td>" + grlink + "</td><td>" + menu + "</td></tr></table>"
@ -249,7 +248,6 @@ def ficheEtud(context, etudid=None, REQUEST=None):
if info["sems"]:
Se = sco_parcours_dut.SituationEtudParcours(etud, info["last_formsemestre_id"])
info["liste_inscriptions"] = formsemestre_recap_parcours_table(
context,
Se,
etudid,
with_links=False,
@ -408,7 +406,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
)
else:
info["groupes_row"] = ""
info["menus_etud"] = menus_etud(context, REQUEST)
info["menus_etud"] = menus_etud(REQUEST)
tmpl = """<div class="menus_etud">%(menus_etud)s</div>
<div class="ficheEtud" id="ficheEtud"><table>
<tr><td>
@ -490,7 +488,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
return header + tmpl % info + html_sco_header.sco_footer()
def menus_etud(context, REQUEST=None):
def menus_etud(REQUEST=None):
"""Menu etudiant (operations sur l'etudiant)"""
if "etudid" not in REQUEST.form:
return ""
@ -535,23 +533,19 @@ def menus_etud(context, REQUEST=None):
return htmlutils.make_menu("Etudiant", menuEtud, alone=True)
def etud_info_html(context, etudid, with_photo="1", REQUEST=None, debug=False):
def etud_info_html(etudid, with_photo="1", REQUEST=None, debug=False):
"""An HTML div with basic information and links about this etud.
Used for popups information windows.
"""
try:
context = context
except:
pass
formsemestre_id = sco_formsemestre_status.retreive_formsemestre_from_request()
with_photo = int(with_photo)
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
photo_html = sco_photos.etud_photo_html(
context, etud, title="fiche de " + etud["nom"], REQUEST=REQUEST
etud, title="fiche de " + etud["nom"], REQUEST=REQUEST
)
# experimental: may be too slow to be here
etud["codeparcours"], etud["decisions_jury"] = sco_report.get_codeparcoursetud(
context, etud, prefix="S", separator=", "
etud, prefix="S", separator=", "
)
bac = sco_bac.Baccalaureat(etud["bac"], etud["specialite"])

View File

@ -125,7 +125,6 @@ class SituationEtudParcoursGeneric(object):
"""
etud: dict filled by fill_etuds_info()
"""
self.context = None # #context
self.etud = etud
self.etudid = etud["etudid"]
self.formsemestre_id = formsemestre_id
@ -340,7 +339,7 @@ class SituationEtudParcoursGeneric(object):
nb_max_ue = nb_ue
# add formation_code to each sem:
sem["formation_code"] = sco_formations.formation_list(
self.context, args={"formation_id": sem["formation_id"]}
args={"formation_id": sem["formation_id"]}
)[0]["formation_code"]
# si sem peut servir à compenser le semestre courant, positionne
# can_compensate
@ -585,7 +584,6 @@ class SituationEtudParcoursGeneric(object):
)
# -- decisions UEs
formsemestre_validate_ues(
self.context,
self.formsemestre_id,
self.etudid,
decision.code_etat,
@ -617,7 +615,6 @@ class SituationEtudParcoursGeneric(object):
)
# modifs des codes d'UE (pourraient passer de ADM a CMP, meme sans modif des notes)
formsemestre_validate_ues(
self.context,
self.prev["formsemestre_id"],
self.etudid,
decision.new_code_prev,
@ -901,7 +898,7 @@ def formsemestre_update_validation_sem(
def formsemestre_validate_ues(
context, formsemestre_id, etudid, code_etat_sem, assiduite, REQUEST=None
formsemestre_id, etudid, code_etat_sem, assiduite, REQUEST=None
):
"""Enregistre codes UE, selon état semestre.
Les codes UE sont toujours calculés ici, et non passés en paramètres
@ -996,7 +993,7 @@ def do_formsemestre_validate_ue(
raise
def formsemestre_has_decisions(context, formsemestre_id):
def formsemestre_has_decisions(formsemestre_id):
"""True s'il y a au moins une validation (decision de jury) dans ce semestre
equivalent to notes_table.sem_has_decisions() but much faster when nt not cached
"""
@ -1035,7 +1032,7 @@ _scolar_autorisation_inscription_editor = ndb.EditableTable(
scolar_autorisation_inscription_list = _scolar_autorisation_inscription_editor.list
def formsemestre_get_autorisation_inscription(context, etudid, origin_formsemestre_id):
def formsemestre_get_autorisation_inscription(etudid, origin_formsemestre_id):
"""Liste des autorisations d'inscription pour cet étudiant
émanant du semestre indiqué.
"""
@ -1045,7 +1042,7 @@ def formsemestre_get_autorisation_inscription(context, etudid, origin_formsemest
)
def formsemestre_get_etud_capitalisation(context, sem, etudid):
def formsemestre_get_etud_capitalisation(sem, etudid):
"""Liste des UE capitalisées (ADM) correspondant au semestre sem et à l'étudiant.
Recherche dans les semestres de la même formation (code) avec le même

View File

@ -24,14 +24,13 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True):
from app.scodoc import sco_formsemestre
from app.scodoc import sco_parcours_dut
context = None # XXX #context
uid = str(authuser)
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
if not sem["etat"]:
return False # semestre verrouillé
if sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"]):
if sco_parcours_dut.formsemestre_has_decisions(sem["formsemestre_id"]):
# il y a des décisions de jury dans ce semestre !
return (
authuser.has_permission(Permission.ScoEditAllNotes)
@ -59,7 +58,6 @@ def can_edit_evaluation(moduleimpl_id=None):
Sinon, lance une exception.
(nb: n'implique pas le droit de saisir ou modifier des notes)
"""
context = None # #context
# was _evaluation_check_write_access
# AccessDenied("Modification évaluation impossible pour %s" % (uid,))
from app.scodoc import sco_formsemestre
@ -109,7 +107,6 @@ def can_validate_sem(formsemestre_id):
"Vrai si utilisateur peut saisir decision de jury dans ce semestre"
from app.scodoc import sco_formsemestre
context = None # XXX #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
if not sem["etat"]:
return False # semestre verrouillé
@ -121,7 +118,6 @@ def can_edit_pv(formsemestre_id):
"Vrai si utilisateur peut editer un PV de jury de ce semestre"
from app.scodoc import sco_formsemestre
context = None # XXX #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
if is_chef_or_diretud(sem):
return True
@ -146,8 +142,6 @@ def check_access_diretud(formsemestre_id, required_permission=Permission.ScoImpl
"""
from app.scodoc import sco_formsemestre
context = None # XXX #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
header = html_sco_header.sco_header(page_title="Accès interdit")
footer = html_sco_header.sco_footer()
@ -174,7 +168,6 @@ def can_change_groups(formsemestre_id):
"Vrai si l'utilisateur peut changer les groupes dans ce semestre"
from app.scodoc import sco_formsemestre
context = None # XXX #context
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
if not sem["etat"]:
return False # semestre verrouillé

View File

@ -78,7 +78,7 @@ MAX_FILE_SIZE = 1024 * 1024 # max allowed size for uploaded image, in bytes
H90 = ".h90" # suffix for reduced size images
def photo_portal_url(context, etud):
def photo_portal_url(etud):
"""Returns external URL to retreive photo on portal,
or None if no portal configured"""
photo_url = sco_portal_apogee.get_photo_url()
@ -88,7 +88,7 @@ def photo_portal_url(context, etud):
return None
def etud_photo_url(context, etud, size="small", fast=False, REQUEST=None):
def etud_photo_url(etud, size="small", fast=False):
"""url to the image of the student, in "small" size or "orig" size.
If ScoDoc doesn't have an image and a portal is configured, link to it.
"""
@ -101,13 +101,13 @@ def etud_photo_url(context, etud, size="small", fast=False, REQUEST=None):
path = photo_pathname(etud, size=size)
if not path:
# Portail ?
ext_url = photo_portal_url(context, etud)
ext_url = photo_portal_url(etud)
if not ext_url:
# fallback: Photo "unknown"
photo_url = scu.ScoURL() + "/" + UNKNOWN_IMAGE_URL
else:
# essaie de copier la photo du portail
new_path, _ = copy_portal_photo_to_fs(context, etud, REQUEST=REQUEST)
new_path, _ = copy_portal_photo_to_fs(etud)
if not new_path:
# copy failed, can we use external url ?
# nb: rarement utile, car le portail est rarement accessible sans authentification
@ -118,7 +118,7 @@ def etud_photo_url(context, etud, size="small", fast=False, REQUEST=None):
return photo_url
def get_photo_image(context, etudid=None, size="small", REQUEST=None):
def get_photo_image(etudid=None, size="small", REQUEST=None):
"""Returns photo image (HTTP response)
If not etudid, use "unknown" image
"""
@ -129,10 +129,10 @@ def get_photo_image(context, etudid=None, size="small", REQUEST=None):
filename = photo_pathname(etud, size=size)
if not filename:
filename = UNKNOWN_IMAGE_PATH
return _http_jpeg_file(context, filename, REQUEST=REQUEST)
return _http_jpeg_file(filename, REQUEST=REQUEST)
def _http_jpeg_file(context, filename, REQUEST=None):
def _http_jpeg_file(filename, REQUEST=None):
"""returns an image.
This function will be modified when we kill #zope
"""
@ -168,13 +168,11 @@ def _http_jpeg_file(context, filename, REQUEST=None):
return open(filename, mode="rb").read()
def etud_photo_is_local(context, etud, size="small"):
def etud_photo_is_local(etud, size="small"):
return photo_pathname(etud, size=size)
def etud_photo_html(
context, etud=None, etudid=None, title=None, size="small", REQUEST=None
):
def etud_photo_html(etud=None, etudid=None, title=None, size="small", REQUEST=None):
"""HTML img tag for the photo, either in small size (h90)
or original size (size=="orig")
"""
@ -183,11 +181,11 @@ def etud_photo_html(
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
else:
raise ValueError("etud_photo_html: either etud or etudid must be specified")
photo_url = etud_photo_url(context, etud, size=size, REQUEST=REQUEST)
photo_url = etud_photo_url(etud, size=size)
nom = etud.get("nomprenom", etud["nom_disp"])
if title is None:
title = nom
if not etud_photo_is_local(context, etud):
if not etud_photo_is_local(etud):
fallback = (
"""onerror='this.onerror = null; this.src="%s"'""" % UNKNOWN_IMAGE_URL
)
@ -206,13 +204,13 @@ def etud_photo_html(
)
def etud_photo_orig_html(context, etud=None, etudid=None, title=None, REQUEST=None):
def etud_photo_orig_html(etud=None, etudid=None, title=None, REQUEST=None):
"""HTML img tag for the photo, in full size.
Full-size images are always stored locally in the filesystem.
They are the original uploaded images, converted in jpeg.
"""
return etud_photo_html(
context, etud=etud, etudid=etudid, title=title, size="orig", REQUEST=REQUEST
etud=etud, etudid=etudid, title=title, size="orig", REQUEST=REQUEST
)
@ -235,7 +233,7 @@ def photo_pathname(etud, size="orig"):
return False
def store_photo(context, etud, data, REQUEST=None):
def store_photo(etud, data):
"""Store image for this etud.
If there is an existing photo, it is erased and replaced.
data is a bytes string with image raw data.
@ -248,7 +246,7 @@ def store_photo(context, etud, data, REQUEST=None):
filesize = len(data)
if filesize < 10 or filesize > MAX_FILE_SIZE:
return 0, "Fichier image de taille invalide ! (%d)" % filesize
filename = save_image(context, etud["etudid"], data)
filename = save_image(etud["etudid"], data)
# update database:
etud["photo_filename"] = filename
etud["foto"] = None
@ -262,7 +260,7 @@ def store_photo(context, etud, data, REQUEST=None):
return 1, "ok"
def suppress_photo(context, etud, REQUEST=None):
def suppress_photo(etud, REQUEST=None):
"""Suppress a photo"""
log("suppress_photo etudid=%s" % etud["etudid"])
rel_path = photo_pathname(etud)
@ -288,7 +286,7 @@ def suppress_photo(context, etud, REQUEST=None):
# Internal functions
def save_image(context, etudid, data):
def save_image(etudid, data):
"""data is a bytes string.
Save image in JPEG in 2 sizes (original and h90).
Returns filename (relative to PHOTO_DIR), without extension
@ -341,12 +339,12 @@ def find_new_dir():
return d + "/"
def copy_portal_photo_to_fs(context, etud, REQUEST=None):
def copy_portal_photo_to_fs(etud):
"""Copy the photo from portal (distant website) to local fs.
Returns rel. path or None if copy failed, with a diagnotic message
"""
sco_etud.format_etud_ident(etud)
url = photo_portal_url(context, etud)
url = photo_portal_url(etud)
if not url:
return None, "%(nomprenom)s: pas de code NIP" % etud
portal_timeout = sco_preferences.get_preference("portal_timeout")
@ -365,7 +363,7 @@ def copy_portal_photo_to_fs(context, etud, REQUEST=None):
return None, "%s: erreur chargement de %s" % (etud["nomprenom"], url)
data = f.read()
try:
status, diag = store_photo(context, etud, data, REQUEST=REQUEST)
status, diag = store_photo(etud, data)
except:
status = 0
diag = "Erreur chargement photo du portail"

View File

@ -32,9 +32,11 @@ Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016
"""
import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
import random
import time
import flask
from app.scodoc.sco_exceptions import ScoValueError
import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log
@ -52,7 +54,7 @@ from app.scodoc import sco_saisie_notes
from app.scodoc import sco_etud
from app.scodoc import VERSION
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_excel import *
from app.scodoc.sco_excel import * # XXX à vérifier
from app.scodoc.TrivialFormulator import TrivialFormulator
@ -232,7 +234,7 @@ def do_placement_selectetuds(REQUEST):
)
def do_placement(context, REQUEST):
def do_placement(REQUEST):
"""
Choisi le placement
"""
@ -302,20 +304,18 @@ def do_placement(context, REQUEST):
listetud = [] # liste de couples (nom,prenom)
for etudid in etudids:
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
ident = sco_etud.etudident_list(cnx, {"etudid": etudid})[
0
] # XXX utiliser ZScolar (parent)
ident = sco_etud.etudident_list(cnx, {"etudid": etudid})[0]
# infos inscription
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
)[0]
if inscr["etat"] != "D":
nom = scu.strupper(ident["nom"])
prenom = scu.strcapitalize(scu.strlower(ident["prenom"]))
nom = ident["nom"].upper()
prenom = ident["prenom"].lower().capitalize()
listetud.append((nom, prenom))
random.shuffle(listetud)
sem_preferences = sco_preferences.SemPreferences(context)
sem_preferences = sco_preferences.SemPreferences()
space = sem_preferences.get("feuille_placement_emargement")
maxlines = sem_preferences.get("feuille_placement_positions")
@ -399,7 +399,7 @@ def do_placement(context, REQUEST):
return t
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
def placement_eval_selectetuds(evaluation_id, REQUEST=None):
"""Dialogue placement etudiants: choix methode et localisation"""
evals = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})
if not evals:

View File

@ -480,7 +480,7 @@ def _normalize_apo_fields(infolist):
for infos in infolist:
if "paiementinscription" in infos:
infos["paiementinscription"] = (
scu.strlower(infos["paiementinscription"]) == "true"
infos["paiementinscription"].lower() == "true"
)
if infos["paiementinscription"]:
infos["paiementinscription_str"] = "ok"

View File

@ -45,7 +45,7 @@ from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_codes_parcours import code_semestre_validant, code_semestre_attente
def etud_get_poursuite_info(context, sem, etud):
def etud_get_poursuite_info(sem, etud):
"""{ 'nom' : ..., 'semlist' : [ { 'semestre_id': , 'moy' : ... }, {}, ...] }"""
I = {}
I.update(etud) # copie nom, prenom, civilite, ...
@ -150,7 +150,7 @@ def _flatten_info(info):
return ids
def _getEtudInfoGroupes(context, group_ids, etat=None):
def _getEtudInfoGroupes(group_ids, etat=None):
"""liste triée d'infos (dict) sur les etudiants du groupe indiqué.
Attention: lent, car plusieurs requetes SQL par etudiant !
"""
@ -164,14 +164,10 @@ def _getEtudInfoGroupes(context, group_ids, etat=None):
return etuds
def formsemestre_poursuite_report(
context, formsemestre_id, format="html", REQUEST=None
):
def formsemestre_poursuite_report(formsemestre_id, format="html", REQUEST=None):
"""Table avec informations "poursuite" """
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
etuds = _getEtudInfoGroupes(
context, [sco_groups.get_default_group(formsemestre_id)]
)
etuds = _getEtudInfoGroupes([sco_groups.get_default_group(formsemestre_id)])
infos = []
ids = []
@ -182,7 +178,7 @@ def formsemestre_poursuite_report(
etud["_nom_target"] = fiche_url
etud["_prenom_target"] = fiche_url
etud["_nom_td_attrs"] = 'id="%s" class="etudinfo"' % (etud["etudid"])
info = etud_get_poursuite_info(context, sem, etud)
info = etud_get_poursuite_info(sem, etud)
idd = _flatten_info(info)
# On recupere la totalite des UEs dans ids
for id in idd:

View File

@ -1992,7 +1992,6 @@ class BasePreferences(object):
"""HTML dialog: edit global preferences"""
from app.scodoc import html_sco_header
context = None # XXX TO REMOVE #context
H = [
html_sco_header.sco_header(page_title="Préférences"),
"<h2>Préférences globales pour %s</h2>" % scu.ScoURL(),
@ -2122,7 +2121,6 @@ class SemPreferences(object):
raise ScoValueError(
"sem_preferences.edit doit etre appele sur un semestre !"
) # a bug !
context = None # XXX TO REMOVE
sem = sco_formsemestre.get_formsemestre(self.formsemestre_id)
H = [
html_sco_header.html_sem_header(REQUEST, "Préférences du semestre", sem),
@ -2179,7 +2177,6 @@ function set_global_pref(el, pref_name) {
scu.NotesURL()
+ "/formsemestre_status?formsemestre_id=%s" % self.formsemestre_id
)
context = None # XXX TO REMOVE
if tf[0] == 0:
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
elif tf[0] == -1:

View File

@ -43,7 +43,7 @@ from app.scodoc import sco_preferences
from app.scodoc.sco_excel import ScoExcelSheet
def feuille_preparation_jury(context, formsemestre_id, REQUEST):
def feuille_preparation_jury(formsemestre_id, REQUEST):
"Feuille excel pour preparation des jurys"
nt = sco_cache.NotesTableCache.get(
formsemestre_id
@ -117,7 +117,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
code[etudid] += "+" # indique qu'il a servi a compenser
assidu[etudid] = {False: "Non", True: "Oui"}.get(decision["assidu"], "")
aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, formsemestre_id
etudid, formsemestre_id
)
autorisations[etudid] = ", ".join(["S%s" % x["semestre_id"] for x in aut_list])
# parcours:

View File

@ -76,7 +76,7 @@ from app.scodoc.sco_pdf import PDFLOCK
from app.scodoc.TrivialFormulator import TrivialFormulator
def _descr_decisions_ues(context, nt, etudid, decisions_ue, decision_sem):
def _descr_decisions_ues(nt, etudid, decisions_ue, decision_sem):
"""Liste des UE validées dans ce semestre"""
if not decisions_ue:
return []
@ -107,7 +107,7 @@ def _descr_decisions_ues(context, nt, etudid, decisions_ue, decision_sem):
return uelist
def _descr_decision_sem(context, etat, decision_sem):
def _descr_decision_sem(etat, decision_sem):
"résumé textuel de la décision de semestre"
if etat == "D":
decision = "Démission"
@ -120,7 +120,7 @@ def _descr_decision_sem(context, etat, decision_sem):
return decision
def _descr_decision_sem_abbrev(context, etat, decision_sem):
def _descr_decision_sem_abbrev(etat, decision_sem):
"résumé textuel tres court (code) de la décision de semestre"
if etat == "D":
decision = "Démission"
@ -132,7 +132,7 @@ def _descr_decision_sem_abbrev(context, etat, decision_sem):
return decision
def descr_autorisations(context, autorisations):
def descr_autorisations(autorisations):
"résumé textuel des autorisations d'inscription (-> 'S1, S3' )"
alist = []
for aut in autorisations:
@ -186,7 +186,6 @@ def _sum_ects_dicts(s, t):
def dict_pvjury(
context,
formsemestre_id,
etudids=None,
with_prev=False,
@ -264,7 +263,7 @@ def dict_pvjury(
d["mention"] = ""
# Versions "en français": (avec les UE capitalisées d'ailleurs)
dec_ue_list = _descr_decisions_ues(
context, nt, etudid, d["decisions_ue"], d["decision_sem"]
nt, etudid, d["decisions_ue"], d["decision_sem"]
)
d["decisions_ue_nb"] = len(
dec_ue_list
@ -279,14 +278,12 @@ def dict_pvjury(
_codes.add(ue["ue_code"])
d["decisions_ue_descr"] = ", ".join([ue["acronyme"] for ue in ue_uniq])
d["decision_sem_descr"] = _descr_decision_sem(
context, d["etat"], d["decision_sem"]
)
d["decision_sem_descr"] = _descr_decision_sem(d["etat"], d["decision_sem"])
d["autorisations"] = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, formsemestre_id
etudid, formsemestre_id
)
d["autorisations_descr"] = descr_autorisations(context, d["autorisations"])
d["autorisations_descr"] = descr_autorisations(d["autorisations"])
d["validation_parcours"] = Se.parcours_validated()
d["parcours"] = Se.get_parcours_descr(filter_futur=True)
@ -340,9 +337,7 @@ def dict_pvjury(
if Se.prev and Se.prev_decision:
d["prev_decision_sem"] = Se.prev_decision
d["prev_code"] = Se.prev_decision["code"]
d["prev_code_descr"] = _descr_decision_sem(
context, "I", Se.prev_decision
)
d["prev_code_descr"] = _descr_decision_sem("I", Se.prev_decision)
d["prev"] = Se.prev
has_prev = True
else:
@ -368,7 +363,6 @@ def dict_pvjury(
def pvjury_table(
context,
dpv,
only_diplome=False,
anonymous=False,
@ -445,9 +439,7 @@ def pvjury_table(
),
"_nomprenom_td_attrs": 'id="%s" class="etudinfo"' % e["identite"]["etudid"],
"parcours": e["parcours"],
"decision": _descr_decision_sem_abbrev(
context, e["etat"], e["decision_sem"]
),
"decision": _descr_decision_sem_abbrev(e["etat"], e["decision_sem"]),
"ue_cap": e["decisions_ue_descr"],
"validation_parcours_code": "ADM" if e["validation_parcours"] else "",
"devenir": e["autorisations_descr"],
@ -496,22 +488,20 @@ def pvjury_table(
l["devenir"] = "Diplôme obtenu"
if dpv["has_prev"]:
l["prev_decision"] = _descr_decision_sem_abbrev(
context, None, e["prev_decision_sem"]
None, e["prev_decision_sem"]
)
if e["validation_parcours"] or not only_diplome:
lines.append(l)
return lines, titles, columns_ids
def formsemestre_pvjury(
context, formsemestre_id, format="html", publish=True, REQUEST=None
):
def formsemestre_pvjury(formsemestre_id, format="html", publish=True, REQUEST=None):
"""Page récapitulant les décisions de jury
dpv: result of dict_pvjury
"""
footer = html_sco_header.sco_footer()
dpv = dict_pvjury(context, formsemestre_id, with_prev=True)
dpv = dict_pvjury(formsemestre_id, with_prev=True)
if not dpv:
if format == "html":
return (
@ -524,7 +514,7 @@ def formsemestre_pvjury(
sem = dpv["formsemestre"]
formsemestre_id = sem["formsemestre_id"]
rows, titles, columns_ids = pvjury_table(context, dpv)
rows, titles, columns_ids = pvjury_table(dpv)
if format != "html" and format != "pdf":
columns_ids = ["etudid", "code_nip"] + columns_ids
@ -609,9 +599,7 @@ def formsemestre_pvjury(
# ---------------------------------------------------------------------------
def formsemestre_pvjury_pdf(
context, formsemestre_id, group_ids=[], etudid=None, REQUEST=None
):
def formsemestre_pvjury_pdf(formsemestre_id, group_ids=[], etudid=None, REQUEST=None):
"""Generation PV jury en PDF: saisie des paramètres
Si etudid, PV pour un seul etudiant. Sinon, tout les inscrits au groupe indiqué.
"""
@ -688,7 +676,7 @@ def formsemestre_pvjury_pdf(
)
else:
# submit
dpv = dict_pvjury(context, formsemestre_id, etudids=etudids, with_prev=True)
dpv = dict_pvjury(formsemestre_id, etudids=etudids, with_prev=True)
if tf[2]["showTitle"]:
tf[2]["showTitle"] = True
else:
@ -700,9 +688,7 @@ def formsemestre_pvjury_pdf(
try:
PDFLOCK.acquire()
pdfdoc = sco_pvpdf.pvjury_pdf(
context,
dpv,
REQUEST,
numeroArrete=tf[2]["numeroArrete"],
VDICode=tf[2]["VDICode"],
date_commission=tf[2]["date_commission"],
@ -807,9 +793,7 @@ def descrform_pvjury(sem):
]
def formsemestre_lettres_individuelles(
context, formsemestre_id, group_ids=[], REQUEST=None
):
def formsemestre_lettres_individuelles(formsemestre_id, group_ids=[], REQUEST=None):
"Lettres avis jury en PDF"
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
if not group_ids:
@ -866,7 +850,6 @@ def formsemestre_lettres_individuelles(
try:
PDFLOCK.acquire()
pdfdoc = sco_pvpdf.pdf_lettres_individuelles(
context,
formsemestre_id,
etudids=etudids,
date_jury=tf[2]["date_jury"],

View File

@ -151,7 +151,6 @@ class CourrierIndividuelTemplate(PageTemplate):
def __init__(
self,
document,
context=None,
pagesbookmarks={},
author=None,
title=None,
@ -275,7 +274,6 @@ class PVTemplate(CourrierIndividuelTemplate):
def __init__(
self,
document,
context=None,
author=None,
title=None,
subject=None,
@ -292,7 +290,6 @@ class PVTemplate(CourrierIndividuelTemplate):
CourrierIndividuelTemplate.__init__(
self,
document,
context=context,
author=author,
title=title,
subject=subject,
@ -326,7 +323,6 @@ class PVTemplate(CourrierIndividuelTemplate):
def pdf_lettres_individuelles(
context,
formsemestre_id,
etudids=None,
date_jury="",
@ -339,9 +335,7 @@ def pdf_lettres_individuelles(
"""
from app.scodoc import sco_pvjury
dpv = sco_pvjury.dict_pvjury(
context, formsemestre_id, etudids=etudids, with_prev=True
)
dpv = sco_pvjury.dict_pvjury(formsemestre_id, etudids=etudids, with_prev=True)
if not dpv:
return ""
# Ajoute infos sur etudiants
@ -370,7 +364,7 @@ def pdf_lettres_individuelles(
params["nomEtud"] = etud["nomprenom"]
bookmarks[npages + 1] = scu.suppress_accents(etud["nomprenom"])
objects += pdf_lettre_individuelle(
dpv["formsemestre"], e, etud, params, signature, context=context
dpv["formsemestre"], e, etud, params, signature
)
objects.append(PageBreak())
npages += 1
@ -390,7 +384,6 @@ def pdf_lettres_individuelles(
document.addPageTemplates(
CourrierIndividuelTemplate(
document,
context=context,
author="%s %s (E. Viennet)" % (VERSION.SCONAME, VERSION.SCOVERSION),
title="Lettres décision %s" % sem["titreannee"],
subject="Décision jury",
@ -418,7 +411,7 @@ def _descr_jury(sem, diplome):
return t, s # titre long, titre court
def pdf_lettre_individuelle(sem, decision, etud, params, signature=None, context=None):
def pdf_lettre_individuelle(sem, decision, etud, params, signature=None):
"""
Renvoie une liste d'objets PLATYPUS pour intégration
dans un autre document.
@ -512,7 +505,6 @@ def pdf_lettre_individuelle(sem, decision, etud, params, signature=None, context
# Corps de la lettre:
objects += sco_bulletins_pdf.process_field(
context,
sco_preferences.get_preference("PV_LETTER_TEMPLATE", sem["formsemestre_id"]),
params,
style,
@ -559,9 +551,7 @@ def pdf_lettre_individuelle(sem, decision, etud, params, signature=None, context
if signature:
objects.append(
_make_signature_image(
signature, params["htab1"], formsemestre_id, context=context
)
_make_signature_image(signature, params["htab1"], formsemestre_id)
)
return objects
@ -576,7 +566,7 @@ def _simulate_br(p, para="<para>"):
return ("</para>" + para).join(l)
def _make_signature_image(signature, leftindent, formsemestre_id, context=None):
def _make_signature_image(signature, leftindent, formsemestre_id):
"cree un paragraphe avec l'image signature"
# cree une image PIL pour avoir la taille (W,H)
from PIL import Image as PILImage
@ -604,9 +594,7 @@ def _make_signature_image(signature, leftindent, formsemestre_id, context=None):
# ----------------------------------------------
def pvjury_pdf(
context,
dpv,
REQUEST,
date_commission=None,
date_jury=None,
numeroArrete=None,
@ -626,7 +614,6 @@ def pvjury_pdf(
formsemestre_id = sem["formsemestre_id"]
objects = _pvjury_pdf_type(
context,
dpv,
only_diplome=False,
date_commission=date_commission,
@ -649,7 +636,6 @@ def pvjury_pdf(
# au moins un etudiant a validé son diplome:
objects.append(PageBreak())
objects += _pvjury_pdf_type(
context,
dpv,
only_diplome=True,
date_commission=date_commission,
@ -669,7 +655,6 @@ def pvjury_pdf(
document.addPageTemplates(
PVTemplate(
document,
context=context,
author="%s %s (E. Viennet)" % (VERSION.SCONAME, VERSION.SCOVERSION),
title=SU("PV du jury de %s" % sem["titre_num"]),
subject="PV jury",
@ -683,7 +668,6 @@ def pvjury_pdf(
def _pvjury_pdf_type(
context,
dpv,
only_diplome=False,
date_commission=None,
@ -786,7 +770,6 @@ def _pvjury_pdf_type(
)
objects += [Spacer(0, 4 * mm)]
lines, titles, columns_ids = sco_pvjury.pvjury_table(
context,
dpv,
only_diplome=only_diplome,
anonymous=anonymous,

View File

@ -55,7 +55,6 @@ from app.scodoc.sco_codes_parcours import DEF, UE_SPORT
def formsemestre_recapcomplet(
context,
formsemestre_id=None,
modejury=False, # affiche lien saisie decision jury
hidemodules=False, # cache colonnes notes modules
@ -99,7 +98,7 @@ def formsemestre_recapcomplet(
javascripts=["libjs/sorttable.js", "js/etud_info.js"],
),
sco_formsemestre_status.formsemestre_status_head(
context, formsemestre_id=formsemestre_id, REQUEST=REQUEST
formsemestre_id=formsemestre_id, REQUEST=REQUEST
),
'<form name="f" method="get" action="%s">' % REQUEST.URL0,
'<input type="hidden" name="formsemestre_id" value="%s"></input>'
@ -149,7 +148,6 @@ def formsemestre_recapcomplet(
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
H.append(
do_formsemestre_recapcomplet(
context,
REQUEST,
formsemestre_id,
format=tabformat,
@ -193,7 +191,6 @@ def formsemestre_recapcomplet(
def do_formsemestre_recapcomplet(
context=None,
REQUEST=None,
formsemestre_id=None,
format="html", # html, xml, xls, xlsall, json
@ -222,7 +219,6 @@ def do_formsemestre_recapcomplet(
def make_formsemestre_recapcomplet(
context=None,
REQUEST=None,
formsemestre_id=None,
format="html", # html, xml, xls, xlsall, json
@ -243,7 +239,6 @@ def make_formsemestre_recapcomplet(
civ_nom_prenom = False # 3 colonnes différentes ou une seule avec prénom abrégé ?
if format == "xml":
return _formsemestre_recapcomplet_xml(
context,
formsemestre_id,
xml_nodate,
xml_with_decisions=xml_with_decisions,
@ -251,7 +246,6 @@ def make_formsemestre_recapcomplet(
)
elif format == "json":
return _formsemestre_recapcomplet_json(
context,
formsemestre_id,
xml_nodate=xml_nodate,
xml_with_decisions=xml_with_decisions,
@ -344,7 +338,7 @@ def make_formsemestre_recapcomplet(
modimpl["moduleimpl_id"]
)
mod_evals[modimpl["moduleimpl_id"]] = evals
h += _list_notes_evals_titles(context, code, evals)
h += _list_notes_evals_titles(code, evals)
h += admission_extra_cols
h += ["code_nip", "etudid"]
@ -383,7 +377,7 @@ def make_formsemestre_recapcomplet(
is_dem[etudid] = False
if rank_partition_id:
rang_gr, _, rank_gr_name = sco_bulletins.get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
)
if rank_gr_name[rank_partition_id]:
rank = "%s %s" % (
@ -422,7 +416,7 @@ def make_formsemestre_recapcomplet(
# Ajoute rangs dans groupes seulement si CSV ou XLS
if format[:3] == "xls" or format == "csv":
rang_gr, _, gr_name = sco_bulletins.get_etud_rangs_groups(
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
etudid, formsemestre_id, partitions, partitions_etud_groups, nt
)
for partition in partitions:
@ -452,7 +446,7 @@ def make_formsemestre_recapcomplet(
) # moyenne etud dans module
if format == "xlsall":
l += _list_notes_evals(
context, mod_evals[modimpl["moduleimpl_id"]], etudid
mod_evals[modimpl["moduleimpl_id"]], etudid
)
j += 1
if not hidebac:
@ -531,7 +525,7 @@ def make_formsemestre_recapcomplet(
if format == "xlsall":
l += _list_notes_evals_stats(
context, mod_evals[modimpl["moduleimpl_id"]], key
mod_evals[modimpl["moduleimpl_id"]], key
)
if modejury:
l.append("") # case vide sur ligne "Moyennes"
@ -789,7 +783,7 @@ def make_formsemestre_recapcomplet(
raise ValueError("unknown format %s" % format)
def _list_notes_evals(context, evals, etudid):
def _list_notes_evals(evals, etudid):
"""Liste des notes des evaluations completes de ce module
(pour table xls avec evals)
"""
@ -811,7 +805,7 @@ def _list_notes_evals(context, evals, etudid):
return L
def _list_notes_evals_titles(context, codemodule, evals):
def _list_notes_evals_titles(codemodule, evals):
"""Liste des titres des evals completes"""
L = []
eval_index = len(evals) - 1
@ -826,7 +820,7 @@ def _list_notes_evals_titles(context, codemodule, evals):
return L
def _list_notes_evals_stats(context, evals, key):
def _list_notes_evals_stats(evals, key):
"""Liste des stats (moy, ou rien!) des evals completes"""
L = []
for e in evals:
@ -850,7 +844,6 @@ def _list_notes_evals_stats(context, evals, key):
def _formsemestre_recapcomplet_xml(
context,
formsemestre_id,
xml_nodate,
xml_with_decisions=False,
@ -883,7 +876,6 @@ def _formsemestre_recapcomplet_xml(
for t in T:
etudid = t[-1]
sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
doc=doc,
@ -899,7 +891,6 @@ def _formsemestre_recapcomplet_xml(
def _formsemestre_recapcomplet_json(
context,
formsemestre_id,
xml_nodate=False,
xml_with_decisions=False,
@ -933,7 +924,6 @@ def _formsemestre_recapcomplet_json(
etudid = t[-1]
bulletins.append(
sco_bulletins_json.formsemestre_bulletinetud_published_dict(
context,
formsemestre_id,
etudid,
force_publishing=force_publishing,
@ -943,7 +933,7 @@ def _formsemestre_recapcomplet_json(
return J, "", "json"
def formsemestres_bulletins(context, annee_scolaire, REQUEST=None):
def formsemestres_bulletins(annee_scolaire, REQUEST=None):
"""Tous les bulletins des semestres publiés des semestres de l'année indiquée.
:param annee_scolaire(int): année de début de l'année scoalaire
:returns: JSON
@ -953,7 +943,7 @@ def formsemestres_bulletins(context, annee_scolaire, REQUEST=None):
log("formsemestres_bulletins(%s): %d sems" % (annee_scolaire, len(sems)))
for sem in sems:
J, _, _ = _formsemestre_recapcomplet_json(
context, sem["formsemestre_id"], force_publishing=False
sem["formsemestre_id"], force_publishing=False
)
jslist.append(J)

View File

@ -64,7 +64,7 @@ from app.scodoc.sco_pdf import SU
MAX_ETUD_IN_DESCR = 20
def formsemestre_etuds_stats(context, sem, only_primo=False):
def formsemestre_etuds_stats(sem, only_primo=False):
"""Récupère liste d'etudiants avec etat et decision."""
nt = sco_cache.NotesTableCache.get(
sem["formsemestre_id"]
@ -85,7 +85,7 @@ def formsemestre_etuds_stats(context, sem, only_primo=False):
etud["codedecision"] = "(nd)" # pas de decision jury
# Ajout devenir (autorisations inscriptions), utile pour stats passage
aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, sem["formsemestre_id"]
etudid, sem["formsemestre_id"]
)
autorisations = ["S%s" % x["semestre_id"] for x in aut_list]
autorisations.sort()
@ -99,12 +99,12 @@ def formsemestre_etuds_stats(context, sem, only_primo=False):
bs.append(etud["specialite"])
etud["bac-specialite"] = " ".join(bs)
#
if (not only_primo) or is_primo_etud(context, etud, sem):
if (not only_primo) or is_primo_etud(etud, sem):
etuds.append(etud)
return etuds
def is_primo_etud(context, etud, sem):
def is_primo_etud(etud, sem):
"""Determine si un (filled) etud a ete inscrit avant ce semestre.
Regarde la liste des semestres dans lesquels l'étudiant est inscrit
"""
@ -133,7 +133,6 @@ def _results_by_category(
category="",
result="",
category_name=None,
context=None,
formsemestre_id=None,
):
"""Construit table: categories (eg types de bacs) en ligne, décisions jury en colonnes
@ -209,7 +208,6 @@ def _results_by_category(
# pages
def formsemestre_report(
context,
formsemestre_id,
etuds,
REQUEST=None,
@ -236,7 +234,6 @@ def formsemestre_report(
category=category,
category_name=category_name,
result=result,
context=context,
formsemestre_id=formsemestre_id,
)
#
@ -254,25 +251,23 @@ def formsemestre_report(
return tab
# def formsemestre_report_bacs(context, formsemestre_id, format='html', REQUEST=None):
# def formsemestre_report_bacs(formsemestre_id, format='html', REQUEST=None):
# """
# Tableau sur résultats par type de bac
# """
# sem = sco_formsemestre.get_formsemestre( formsemestre_id)
# title = 'Statistiques bacs ' + sem['titreannee']
# etuds = formsemestre_etuds_stats(context, sem)
# tab = formsemestre_report(context, formsemestre_id, etuds, REQUEST=REQUEST,
# etuds = formsemestre_etuds_stats(sem)
# tab = formsemestre_report(formsemestre_id, etuds, REQUEST=REQUEST,
# category='bac', result='codedecision',
# category_name='Bac',
# title=title)
# return tab.make_page(
# context,
# title = """<h2>Résultats de <a href="formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titreannee)s</a></h2>""" % sem,
# format=format, page_title = title, REQUEST=REQUEST )
def formsemestre_report_counts(
context,
formsemestre_id,
format="html",
REQUEST=None,
@ -285,11 +280,10 @@ def formsemestre_report_counts(
Tableau comptage avec choix des categories
"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
category_name = scu.strcapitalize(category)
category_name = category.capitalize()
title = "Comptages " + category_name
etuds = formsemestre_etuds_stats(context, sem, only_primo=only_primo)
etuds = formsemestre_etuds_stats(sem, only_primo=only_primo)
tab = formsemestre_report(
context,
formsemestre_id,
etuds,
REQUEST=REQUEST,
@ -380,7 +374,6 @@ def formsemestre_report_counts(
# --------------------------------------------------------------------------
def table_suivi_cohorte(
context,
formsemestre_id,
percent=False,
bac="", # selection sur type de bac
@ -437,7 +430,7 @@ def table_suivi_cohorte(
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
and (not civilite or (civilite == etud["civilite"]))
and (not statut or (statut == etud["statut"]))
and (not only_primo or is_primo_etud(context, etud, sem))
and (not only_primo or is_primo_etud(etud, sem))
):
orig_set.add(etudid)
# semestres suivants:
@ -536,7 +529,7 @@ def table_suivi_cohorte(
}
]
if nb_initial <= MAX_ETUD_IN_DESCR:
etud_descr = _descr_etud_set(context, sem["members"])
etud_descr = _descr_etud_set(sem["members"])
L[0]["_%s_help" % porigin.datedebut] = etud_descr
for idx_sem in indices_sems:
if idx_sem >= 0:
@ -553,17 +546,17 @@ def table_suivi_cohorte(
if nbetuds:
d[p.datedebut] = fmtval(nbetuds)
if nbetuds <= MAX_ETUD_IN_DESCR: # si peu d'etudiants, indique la liste
etud_descr = _descr_etud_set(context, etuds_period)
etud_descr = _descr_etud_set(etuds_period)
d["_%s_help" % p.datedebut] = etud_descr
L.append(d)
# Compte nb de démissions et de ré-orientation par période
logt("D: cout dems reos")
sem["dems"], sem["reos"] = _count_dem_reo(context, formsemestre_id, sem["members"])
sem["dems"], sem["reos"] = _count_dem_reo(formsemestre_id, sem["members"])
for p in P:
p.dems = set()
p.reos = set()
for s in p.sems:
d, r = _count_dem_reo(context, s["formsemestre_id"], s["members"])
d, r = _count_dem_reo(s["formsemestre_id"], s["members"])
p.dems.update(d)
p.reos.update(r)
# Nombre total d'etudiants par periode
@ -584,12 +577,12 @@ def table_suivi_cohorte(
porigin.datedebut: fmtval(len(sem["dems"])),
}
if len(sem["dems"]) <= MAX_ETUD_IN_DESCR:
etud_descr = _descr_etud_set(context, sem["dems"])
etud_descr = _descr_etud_set(sem["dems"])
l["_%s_help" % porigin.datedebut] = etud_descr
for p in P:
l[p.datedebut] = fmtval(len(p.dems))
if len(p.dems) <= MAX_ETUD_IN_DESCR:
etud_descr = _descr_etud_set(context, p.dems)
etud_descr = _descr_etud_set(p.dems)
l["_%s_help" % p.datedebut] = etud_descr
L.append(l)
# Nombre de réorientations par période
@ -600,12 +593,12 @@ def table_suivi_cohorte(
porigin.datedebut: fmtval(len(sem["reos"])),
}
if len(sem["reos"]) < 10:
etud_descr = _descr_etud_set(context, sem["reos"])
etud_descr = _descr_etud_set(sem["reos"])
l["_%s_help" % porigin.datedebut] = etud_descr
for p in P:
l[p.datedebut] = fmtval(len(p.reos))
if len(p.reos) <= MAX_ETUD_IN_DESCR:
etud_descr = _descr_etud_set(context, p.reos)
etud_descr = _descr_etud_set(p.reos)
l["_%s_help" % p.datedebut] = etud_descr
L.append(l)
# derniere ligne: nombre et pourcentage de diplomes
@ -687,7 +680,6 @@ def table_suivi_cohorte(
def formsemestre_suivi_cohorte(
context,
formsemestre_id,
format="html",
percent=1,
@ -710,7 +702,6 @@ def formsemestre_suivi_cohorte(
civilites,
statuts,
) = table_suivi_cohorte(
context,
formsemestre_id,
percent=percent,
bac=bac,
@ -908,7 +899,7 @@ def _gen_form_selectetuds(
return "\n".join(F)
def _descr_etud_set(context, etudids):
def _descr_etud_set(etudids):
"textual html description of a set of etudids"
etuds = []
for etudid in etudids:
@ -918,7 +909,7 @@ def _descr_etud_set(context, etudids):
return ", ".join([e["nomprenom"] for e in etuds])
def _count_dem_reo(context, formsemestre_id, etudids):
def _count_dem_reo(formsemestre_id, etudids):
"count nb of demissions and reorientation in this etud set"
nt = sco_cache.NotesTableCache.get(
formsemestre_id
@ -971,7 +962,7 @@ def _codesem(sem, short=True, prefix=""):
return "%s%s%s" % (prefix, idx, d)
def get_codeparcoursetud(context, etud, prefix="", separator=""):
def get_codeparcoursetud(etud, prefix="", separator=""):
"""calcule un code de parcours pour un etudiant
exemples:
1234A pour un etudiant ayant effectué S1, S2, S3, S4 puis diplome
@ -1019,7 +1010,6 @@ def get_codeparcoursetud(context, etud, prefix="", separator=""):
def tsp_etud_list(
context,
formsemestre_id,
only_primo=False,
bac="", # selection sur type de bac
@ -1051,7 +1041,7 @@ def tsp_etud_list(
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
and (not civilite or (civilite == etud["civilite"]))
and (not statut or (statut == etud["statut"]))
and (not only_primo or is_primo_etud(context, etud, sem))
and (not only_primo or is_primo_etud(etud, sem))
):
etuds.append(etud)
@ -1065,7 +1055,7 @@ def tsp_etud_list(
return etuds, bacs, bacspecialites, annee_bacs, civilites, statuts
def tsp_grouped_list(context, codes_etuds):
def tsp_grouped_list(codes_etuds):
"""Liste pour table regroupant le nombre d'étudiants (+ bulle avec les noms) de chaque parcours"""
L = []
parcours = list(codes_etuds.keys())
@ -1074,28 +1064,22 @@ def tsp_grouped_list(context, codes_etuds):
nb = len(codes_etuds[p])
l = {"parcours": p, "nb": nb}
if nb <= MAX_ETUD_IN_DESCR:
l["_nb_help"] = _descr_etud_set(
context, [e["etudid"] for e in codes_etuds[p]]
)
l["_nb_help"] = _descr_etud_set([e["etudid"] for e in codes_etuds[p]])
L.append(l)
# tri par effectifs décroissants
L.sort(key=itemgetter("nb"))
return L
def table_suivi_parcours(
context, formsemestre_id, only_primo=False, grouped_parcours=True
):
def table_suivi_parcours(formsemestre_id, only_primo=False, grouped_parcours=True):
"""Tableau recapitulant tous les parcours"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
etuds, bacs, bacspecialites, annee_bacs, civilites, statuts = tsp_etud_list(
context, formsemestre_id, only_primo=only_primo
formsemestre_id, only_primo=only_primo
)
codes_etuds = scu.DictDefault(defaultvalue=[])
for etud in etuds:
etud["codeparcours"], etud["decisions_jury"] = get_codeparcoursetud(
context, etud
)
etud["codeparcours"], etud["decisions_jury"] = get_codeparcoursetud(etud)
codes_etuds[etud["codeparcours"]].append(etud)
fiche_url = url_for(
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
@ -1117,7 +1101,7 @@ def table_suivi_parcours(
}
if grouped_parcours:
L = tsp_grouped_list(context, codes_etuds)
L = tsp_grouped_list(codes_etuds)
columns_ids = ("parcours", "nb")
else:
# Table avec le parcours de chaque étudiant:
@ -1201,7 +1185,6 @@ def tsp_form_primo_group(REQUEST, only_primo, no_grouping, formsemestre_id, form
def formsemestre_suivi_parcours(
context,
formsemestre_id,
format="html",
only_primo=False,
@ -1210,7 +1193,6 @@ def formsemestre_suivi_parcours(
):
"""Effectifs dans les differents parcours possibles."""
tab = table_suivi_parcours(
context,
formsemestre_id,
only_primo=only_primo,
grouped_parcours=not no_grouping,
@ -1243,7 +1225,6 @@ def formsemestre_suivi_parcours(
# -------------
def graph_parcours(
context,
formsemestre_id,
format="svg",
only_primo=False,
@ -1255,7 +1236,6 @@ def graph_parcours(
):
""""""
etuds, bacs, bacspecialites, annee_bacs, civilites, statuts = tsp_etud_list(
context,
formsemestre_id,
only_primo=only_primo,
bac=bac,
@ -1415,7 +1395,7 @@ def graph_parcours(
e.set_fontsize(8.0)
# bulle avec liste etudiants
if len(edges[(src_id, dst_id)]) <= MAX_ETUD_IN_DESCR:
etud_descr = _descr_etud_set(context, edges[(src_id, dst_id)])
etud_descr = _descr_etud_set(edges[(src_id, dst_id)])
bubbles[src_id + ":" + dst_id] = etud_descr
e.set_URL("__xxxetudlist__?" + src_id + ":" + dst_id)
# Genere graphe
@ -1469,7 +1449,6 @@ def graph_parcours(
def formsemestre_graph_parcours(
context,
formsemestre_id,
format="html",
only_primo=False,
@ -1494,7 +1473,6 @@ def formsemestre_graph_parcours(
civilites,
statuts,
) = graph_parcours(
context,
formsemestre_id,
format="pdf",
only_primo=only_primo,
@ -1517,7 +1495,6 @@ def formsemestre_graph_parcours(
civilites,
statuts,
) = graph_parcours(
context,
formsemestre_id,
format="png",
only_primo=only_primo,
@ -1553,7 +1530,6 @@ def formsemestre_graph_parcours(
civilites,
statuts,
) = graph_parcours(
context,
formsemestre_id,
only_primo=only_primo,
bac=bac,

View File

@ -163,7 +163,7 @@ def _check_notes(notes, evaluation, mod):
return L, invalids, withoutnotes, absents, tosuppress
def do_evaluation_upload_xls(context, REQUEST):
def do_evaluation_upload_xls(REQUEST):
"""
Soumission d'un fichier XLS (evaluation_id, notefile)
"""
@ -244,7 +244,7 @@ def do_evaluation_upload_xls(context, REQUEST):
raise InvalidNoteValue()
else:
nb_changed, nb_suppress, existing_decisions = _notes_add(
context, authuser, evaluation_id, L, comment
authuser, evaluation_id, L, comment
)
# news
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
@ -283,7 +283,6 @@ def do_evaluation_upload_xls(context, REQUEST):
def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
"""Initialisation des notes manquantes"""
# ? evaluation_id = REQUEST.form["evaluation_id"]
context = None # XXX #context
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = sco_moduleimpl.do_moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[
0
@ -331,7 +330,7 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
)
# ok
comment = "Initialisation notes manquantes"
nb_changed, _, _ = _notes_add(context, current_user, evaluation_id, L, comment)
nb_changed, _, _ = _notes_add(current_user, evaluation_id, L, comment)
# news
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
mod = sco_edit_module.do_module_list(args={"module_id": M["module_id"]})[0]
@ -360,7 +359,6 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
"suppress all notes in this eval"
context = None # XXX #context
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
if sco_permissions_check.can_edit_notes(
@ -383,7 +381,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
if not dialog_confirmed:
nb_changed, nb_suppress, existing_decisions = _notes_add(
context, current_user, evaluation_id, notes, do_it=False
current_user, evaluation_id, notes, do_it=False
)
msg = "<p>Confirmer la suppression des %d notes ?</p>" % nb_suppress
if existing_decisions:
@ -398,7 +396,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
# modif
nb_changed, nb_suppress, existing_decisions = _notes_add(
context, current_user, evaluation_id, notes, comment="effacer tout"
current_user, evaluation_id, notes, comment="effacer tout"
)
assert nb_changed == nb_suppress
H = ["<p>%s notes supprimées</p>" % nb_suppress]
@ -426,9 +424,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
def _notes_add(
context, user, evaluation_id: int, notes: list, comment=None, do_it=True
):
def _notes_add(user, evaluation_id: int, notes: list, comment=None, do_it=True):
"""
Insert or update notes
notes is a list of tuples (etudid,value)
@ -554,7 +550,7 @@ def _notes_add(
nb_suppress += 1
if changed:
nb_changed += 1
if has_existing_decision(context, M, E, etudid):
if has_existing_decision(M, E, etudid):
existing_decisions.append(etudid)
except:
log("*** exception in _notes_add")
@ -574,7 +570,7 @@ def _notes_add(
return nb_changed, nb_suppress, existing_decisions
def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
def saisie_notes_tableur(evaluation_id, group_ids=[], REQUEST=None):
"""Saisie des notes via un fichier Excel"""
authuser = REQUEST.AUTHENTICATED_USER
authusername = str(authuser)
@ -625,7 +621,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
# Menu choix groupe:
H.append("""<div id="group-tabs"><table><tr><td>""")
H.append(sco_groups_view.form_groups_choice(context, groups_infos))
H.append(sco_groups_view.form_groups_choice(groups_infos))
H.append("</td></tr></table></div>")
H.append(
@ -677,7 +673,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
elif nf[0] == -1:
H.append("<p>Annulation</p>")
elif nf[0] == 1:
updiag = do_evaluation_upload_xls(context, REQUEST)
updiag = do_evaluation_upload_xls(REQUEST)
if updiag[0]:
H.append(updiag[1])
H.append(
@ -749,7 +745,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
return "\n".join(H)
def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
def feuille_saisie_notes(evaluation_id, group_ids=[], REQUEST=None):
"""Document Excel pour saisie notes dans l'évaluation et les groupes indiqués"""
evals = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})
if not evals:
@ -800,7 +796,7 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
# une liste de liste de chaines: lignes de la feuille de calcul
L = []
etuds = _get_sorted_etuds(context, E, etudids, formsemestre_id)
etuds = _get_sorted_etuds(E, etudids, formsemestre_id)
for e in etuds:
etudid = e["etudid"]
groups = sco_groups.get_etud_groups(etudid, sem)
@ -809,8 +805,8 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
L.append(
[
"%s" % etudid,
scu.strupper(e["nom"]),
scu.strcapitalize(scu.strlower(e["prenom"])),
e["nom"].upper(),
e["prenom"].lower().capitalize(),
e["inscr"]["etat"],
grc,
e["val"],
@ -823,7 +819,7 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
return sco_excel.send_excel_file(REQUEST, xls, filename)
def has_existing_decision(context, M, E, etudid):
def has_existing_decision(M, E, etudid):
"""Verifie s'il y a une validation pour cet etudiant dans ce semestre ou UE
Si oui, return True
"""
@ -847,7 +843,7 @@ def has_existing_decision(context, M, E, etudid):
# Nouveau formulaire saisie notes (2016)
def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
def saisie_notes(evaluation_id, group_ids=[], REQUEST=None):
"""Formulaire saisie notes d'une évaluation pour un groupe"""
authuser = REQUEST.AUTHENTICATED_USER
authusername = str(authuser)
@ -902,7 +898,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
'<div id="saisie_notes"><span class="eval_title">Saisie des notes</span>',
]
H.append("""<div id="group-tabs"><table><tr><td>""")
H.append(sco_groups_view.form_groups_choice(context, groups_infos))
H.append(sco_groups_view.form_groups_choice(groups_infos))
H.append('</td><td style="padding-left: 35px;">')
H.append(
htmlutils.make_menu(
@ -939,7 +935,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
E["moduleimpl_id"],
)
form = _form_saisie_notes(
context, E, M, groups_infos.group_ids, destination=destination, REQUEST=REQUEST
E, M, groups_infos.group_ids, destination=destination, REQUEST=REQUEST
)
if form is None:
return flask.redirect(destination)
@ -964,7 +960,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
return "\n".join(H)
def _get_sorted_etuds(context, E, etudids, formsemestre_id):
def _get_sorted_etuds(E, etudids, formsemestre_id):
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
NotesDB = sco_evaluations.do_evaluation_get_all_notes(
E["evaluation_id"]
@ -1030,7 +1026,7 @@ def _get_sorted_etuds(context, E, etudids, formsemestre_id):
return etuds
def _form_saisie_notes(context, E, M, group_ids, destination="", REQUEST=None):
def _form_saisie_notes(E, M, group_ids, destination="", REQUEST=None):
"""Formulaire HTML saisie des notes dans l'évaluation E du moduleimpl M
pour les groupes indiqués.
@ -1047,14 +1043,12 @@ def _form_saisie_notes(context, E, M, group_ids, destination="", REQUEST=None):
return '<div class="ue_warning"><span>Aucun étudiant sélectionné !</span></div>'
# Decisions de jury existantes ?
decisions_jury = {
etudid: has_existing_decision(context, M, E, etudid) for etudid in etudids
}
decisions_jury = {etudid: has_existing_decision(M, E, etudid) for etudid in etudids}
nb_decisions = sum(
decisions_jury.values()
) # Nb de decisions de jury (pour les inscrits à l'évaluation)
etuds = _get_sorted_etuds(context, E, etudids, formsemestre_id)
etuds = _get_sorted_etuds(E, etudids, formsemestre_id)
# Build form:
descr = [
@ -1122,7 +1116,7 @@ def _form_saisie_notes(context, E, M, group_ids, destination="", REQUEST=None):
if not disabled:
explanation = (
'<span id="hist_%s">' % etudid
+ get_note_history_menu(context, evaluation_id, etudid)
+ get_note_history_menu(evaluation_id, etudid)
+ "</span>"
)
else:
@ -1208,9 +1202,7 @@ def _form_saisie_notes(context, E, M, group_ids, destination="", REQUEST=None):
return None
def save_note(
context, etudid=None, evaluation_id=None, value=None, comment="", REQUEST=None
):
def save_note(etudid=None, evaluation_id=None, value=None, comment="", REQUEST=None):
"""Enregistre une note (ajax)"""
authuser = REQUEST.AUTHENTICATED_USER
log(
@ -1229,7 +1221,7 @@ def save_note(
L, _, _, _, _ = _check_notes([(etudid, value)], E, Mod)
if L:
nbchanged, _, existing_decisions = _notes_add(
context, authuser, evaluation_id, L, comment=comment, do_it=True
authuser, evaluation_id, L, comment=comment, do_it=True
)
sco_news.add(
typ=sco_news.NEWS_NOTE,
@ -1241,18 +1233,16 @@ def save_note(
result["nbchanged"] = nbchanged
result["existing_decisions"] = existing_decisions
if nbchanged > 0:
result["history_menu"] = get_note_history_menu(
context, evaluation_id, etudid
)
result["history_menu"] = get_note_history_menu(evaluation_id, etudid)
else:
result["history_menu"] = "" # no update needed
result["status"] = "ok"
return scu.sendJSON(REQUEST, result)
def get_note_history_menu(context, evaluation_id, etudid):
def get_note_history_menu(evaluation_id, etudid):
"""Menu HTML historique de la note"""
history = sco_undo_notes.get_note_history(context, evaluation_id, etudid)
history = sco_undo_notes.get_note_history(evaluation_id, etudid)
if not history:
return ""

View File

@ -35,7 +35,7 @@ class SemSet: un ensemble de semestres d'un département, à exporter ves Apog
SemSet.add(sem): ajoute un semestre à l'ensemble
sem_set_list(context)
sem_set_list()
"""
@ -72,7 +72,7 @@ semset_delete = _semset_editor.delete
class SemSet(dict):
def __init__(self, context, semset_id=None, title="", annee_scolaire="", sem_id=""):
def __init__(self, semset_id=None, title="", annee_scolaire="", sem_id=""):
"""Load and init, or, if semset_id is not specified, create"""
if not annee_scolaire and not semset_id:
# on autorise annee_scolaire null si sem_id pour pouvoir lire les anciens semsets
@ -80,7 +80,6 @@ class SemSet(dict):
raise ScoValueError("Année scolaire invalide !")
self.semset_id = semset_id
self["semset_id"] = semset_id
self.context = context
self.sems = []
self.formsemestre_ids = []
cnx = ndb.GetDBConnexion()
@ -105,7 +104,7 @@ class SemSet(dict):
log("created new semset_id=%s" % self.semset_id)
self.load_sems()
# analyse des semestres pour construire le bilan par semestre et par étape
self.bilan = EtapeBilan(context)
self.bilan = EtapeBilan()
for sem in self.sems:
self.bilan.add_sem(sem)
@ -142,7 +141,7 @@ class SemSet(dict):
def fill_formsemestres(self):
for sem in self.sems:
sco_formsemestre_status.fill_formsemestre(sem)
ets = sco_etape_apogee.apo_get_sem_etapes(self.context, sem)
ets = sco_etape_apogee.apo_get_sem_etapes(sem)
sem["etapes_apo_str"] = sco_formsemestre.etapes_apo_str(sorted(list(ets)))
def add(self, formsemestre_id):
@ -216,7 +215,7 @@ class SemSet(dict):
def list_possible_sems(self):
"""List sems that can be added to this set"""
sems = sco_formsemestre.do_formsemestre_list(self.context)
sems = sco_formsemestre.do_formsemestre_list()
# remove sems already here:
sems = [
sem for sem in sems if sem["formsemestre_id"] not in self.formsemestre_ids
@ -238,7 +237,6 @@ class SemSet(dict):
return sems
def load_etuds(self):
context = self.context
self["etuds_without_nip"] = set() # etudids
self["jury_ok"] = True
for sem in self.sems:
@ -345,33 +343,33 @@ class SemSet(dict):
return ""
def get_semsets_list(context):
def get_semsets_list():
"""Liste de tous les semsets
Trié par date_debut, le plus récent d'abord
"""
cnx = ndb.GetDBConnexion()
L = []
for s in semset_list(cnx):
L.append(SemSet(context, semset_id=s["semset_id"]))
L.append(SemSet(semset_id=s["semset_id"]))
L.sort(key=lambda s: s["date_debut"], reverse=True)
return L
def do_semset_create(context, title="", annee_scolaire=None, sem_id=None, REQUEST=None):
def do_semset_create(title="", annee_scolaire=None, sem_id=None):
"""Create new setset"""
log(
"do_semset_create(title=%s, annee_scolaire=%s, sem_id=%s)"
% (title, annee_scolaire, sem_id)
)
SemSet(context, title=title, annee_scolaire=annee_scolaire, sem_id=sem_id)
SemSet(title=title, annee_scolaire=annee_scolaire, sem_id=sem_id)
return flask.redirect("semset_page")
def do_semset_delete(context, semset_id, dialog_confirmed=False, REQUEST=None):
def do_semset_delete(semset_id, dialog_confirmed=False):
"""Delete a semset"""
if not semset_id:
raise ScoValueError("empty semset_id")
s = SemSet(context, semset_id=semset_id)
s = SemSet(semset_id=semset_id)
if not dialog_confirmed:
return scu.confirm_dialog(
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
@ -383,22 +381,22 @@ def do_semset_delete(context, semset_id, dialog_confirmed=False, REQUEST=None):
return flask.redirect("semset_page")
def edit_semset_set_title(context, id=None, value=None, REQUEST=None):
def edit_semset_set_title(id=None, value=None):
"""Change title of semset"""
title = value.strip()
if not id:
raise ScoValueError("empty semset_id")
SemSet(context, semset_id=id)
SemSet(semset_id=id)
cnx = ndb.GetDBConnexion()
semset_edit(cnx, {"semset_id": id, "title": title})
return title
def do_semset_add_sem(context, semset_id, formsemestre_id, REQUEST=None):
def do_semset_add_sem(semset_id, formsemestre_id):
"""Add a sem to a semset"""
if not semset_id:
raise ScoValueError("empty semset_id")
s = SemSet(context, semset_id=semset_id)
s = SemSet(semset_id=semset_id)
# check for valid formsemestre_id
_ = sco_formsemestre.get_formsemestre(formsemestre_id) # raise exc
@ -407,11 +405,11 @@ def do_semset_add_sem(context, semset_id, formsemestre_id, REQUEST=None):
return flask.redirect("apo_semset_maq_status?semset_id=%s" % semset_id)
def do_semset_remove_sem(context, semset_id, formsemestre_id, REQUEST=None):
def do_semset_remove_sem(semset_id, formsemestre_id):
"""Add a sem to a semset"""
if not semset_id:
raise ScoValueError("empty semset_id")
s = SemSet(context, semset_id)
s = SemSet(semset_id)
s.remove(formsemestre_id)
@ -421,11 +419,11 @@ def do_semset_remove_sem(context, semset_id, formsemestre_id, REQUEST=None):
# ----------------------------------------
def semset_page(context, format="html", REQUEST=None):
def semset_page(format="html", REQUEST=None):
"""Page avec liste semsets:
Table avec : date_debut date_fin titre liste des semestres
"""
semsets = get_semsets_list(context)
semsets = get_semsets_list()
for s in semsets:
s["suppress"] = scu.icontag(
"delete_small_img", border="0", alt="supprimer", title="Supprimer"

View File

@ -57,7 +57,6 @@ EKEY_NAME = "code NIP"
def formsemestre_synchro_etuds(
context,
formsemestre_id,
etuds=[], # liste des codes NIP des etudiants a inscrire (ou deja inscrits)
inscrits_without_key=[], # codes etudid des etudiants sans code NIP a laisser inscrits
@ -132,12 +131,11 @@ def formsemestre_synchro_etuds(
inscrits_set,
inscrits_without_key_all,
etudsapo_ident,
) = list_synch(context, sem, anneeapogee=anneeapogee)
) = list_synch(sem, anneeapogee=anneeapogee)
if export_cat_xls:
filename = export_cat_xls
xls = build_page(
context,
sem,
etuds_by_cat,
anneeapogee,
@ -150,7 +148,6 @@ def formsemestre_synchro_etuds(
H = [header]
if not submitted:
H += build_page(
context,
sem,
etuds_by_cat,
anneeapogee,
@ -167,7 +164,7 @@ def formsemestre_synchro_etuds(
inscrits_without_key
)
log("a_desinscrire_without_key=%s" % a_desinscrire_without_key)
inscrits_ailleurs = set(sco_inscr_passage.list_inscrits_date(context, sem))
inscrits_ailleurs = set(sco_inscr_passage.list_inscrits_date(sem))
a_inscrire = a_inscrire.intersection(etuds_set)
if not dialog_confirmed:
@ -236,13 +233,9 @@ def formsemestre_synchro_etuds(
etudids_a_desinscrire = [nip2etudid(x) for x in a_desinscrire]
etudids_a_desinscrire += a_desinscrire_without_key
#
do_import_etuds_from_portal(
context, sem, a_importer, etudsapo_ident, REQUEST
)
sco_inscr_passage.do_inscrit(context, sem, etudids_a_inscrire, REQUEST)
sco_inscr_passage.do_desinscrit(
context, sem, etudids_a_desinscrire, REQUEST
)
do_import_etuds_from_portal(sem, a_importer, etudsapo_ident, REQUEST)
sco_inscr_passage.do_inscrit(sem, etudids_a_inscrire, REQUEST)
sco_inscr_passage.do_desinscrit(sem, etudids_a_desinscrire, REQUEST)
H.append(
"""<h3>Opération effectuée</h3>
@ -269,7 +262,6 @@ def formsemestre_synchro_etuds(
def build_page(
context,
sem,
etuds_by_cat,
anneeapogee,
@ -279,7 +271,7 @@ def build_page(
):
if export_cat_xls:
return sco_inscr_passage.etuds_select_boxes(
context, etuds_by_cat, export_cat_xls=export_cat_xls, base_url=base_url
etuds_by_cat, export_cat_xls=export_cat_xls, base_url=base_url
)
year = time.localtime()[0]
if anneeapogee and abs(year - int(anneeapogee)) < 50:
@ -331,7 +323,6 @@ def build_page(
"""
% sem, # "
sco_inscr_passage.etuds_select_boxes(
context,
etuds_by_cat,
sel_inscrits=False,
show_empty_boxes=True,
@ -341,17 +332,15 @@ def build_page(
""
if read_only
else """<p/><input type="submit" name="submitted" value="Appliquer les modifications"/>""",
formsemestre_synchro_etuds_help(context, sem),
formsemestre_synchro_etuds_help(sem),
"""</form>""",
]
return H
def list_synch(context, sem, anneeapogee=None):
def list_synch(sem, anneeapogee=None):
""""""
inscrits = sco_inscr_passage.list_inscrits(
context, sem["formsemestre_id"], with_dems=True
)
inscrits = sco_inscr_passage.list_inscrits(sem["formsemestre_id"], with_dems=True)
# Tous les ensembles d'etudiants sont ici des ensembles de codes NIP (voir EKEY_SCO)
# (sauf inscrits_without_key)
inscrits_set = set()
@ -387,7 +376,7 @@ def list_synch(context, sem, anneeapogee=None):
# categories:
etuds_ok = etudsapo_set.intersection(inscrits_set)
etuds_aposco, a_importer, key2etudid = list_all(context, etudsapo_set)
etuds_aposco, a_importer, key2etudid = list_all(etudsapo_set)
etuds_noninscrits = etuds_aposco - inscrits_set
etuds_nonapogee = inscrits_set - etudsapo_set
# Etudiants ayant payé (avec balise <paiementinscription> true)
@ -501,7 +490,7 @@ def list_synch(context, sem, anneeapogee=None):
)
def list_all(context, etudsapo_set):
def list_all(etudsapo_set):
"""Cherche le sous-ensemble des etudiants Apogee de ce semestre
qui existent dans ScoDoc.
"""
@ -522,7 +511,7 @@ def list_all(context, etudsapo_set):
return etuds_aposco, a_importer, key2etudid
def formsemestre_synchro_etuds_help(context, sem):
def formsemestre_synchro_etuds_help(sem):
sem["default_group_id"] = sco_groups.get_default_group(sem["formsemestre_id"])
return (
"""<div class="pas_help pas_help_left"><h3><a name="help">Explications</a></h3>
@ -575,7 +564,7 @@ def get_annee_naissance(ddmmyyyyy): # stokee en dd/mm/yyyy dans le XML portail
return None
def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUEST):
def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident, REQUEST):
"""Inscrit les etudiants Apogee dans ce semestre."""
log("do_import_etuds_from_portal: a_importer=%s" % a_importer)
if not a_importer:
@ -621,14 +610,13 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
args["etudid"] = sco_etud.identite_create(cnx, args)
created_etudids.append(args["etudid"])
# Admissions
do_import_etud_admission(context, cnx, args["etudid"], etud)
do_import_etud_admission(cnx, args["etudid"], etud)
# Adresse
sco_etud.adresse_create(cnx, args)
# Inscription au semestre
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
context,
sem["formsemestre_id"],
args["etudid"],
etat="I",
@ -682,7 +670,7 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
def do_import_etud_admission(
context, cnx, etudid, etud, import_naissance=False, import_identite=False
cnx, etudid, etud, import_naissance=False, import_identite=False
):
"""Importe les donnees admission pour cet etud.
etud est un dictionnaire traduit du XML portail
@ -759,7 +747,7 @@ def get_bac(etud):
return serie_bac, spe_bac
def update_etape_formsemestre_inscription(context, ins, etud):
def update_etape_formsemestre_inscription(ins, etud):
"""Met à jour l'étape de l'inscription.
Args:
@ -768,13 +756,11 @@ def update_etape_formsemestre_inscription(context, ins, etud):
"""
if etud["etape"] != ins["etape"]:
ins["etape"] = etud["etape"]
sco_formsemestre_inscriptions.do_formsemestre_inscription_edit(
context, args=ins
)
sco_formsemestre_inscriptions.do_formsemestre_inscription_edit(args=ins)
def formsemestre_import_etud_admission(
context, formsemestre_id, import_identite=True, import_email=False
formsemestre_id, import_identite=True, import_email=False
):
"""Tente d'importer les données admission depuis le portail
pour tous les étudiants du semestre.
@ -818,9 +804,8 @@ def formsemestre_import_etud_admission(
# pas vu dans les etudiants de l'étape, tente en individuel
etud = sco_portal_apogee.get_etud_apogee(code_nip)
if etud:
update_etape_formsemestre_inscription(context, i, etud)
update_etape_formsemestre_inscription(i, etud)
do_import_etud_admission(
context,
cnx,
etudid,
etud,
@ -843,7 +828,6 @@ def formsemestre_import_etud_admission(
"email": etud["mail"],
"emailperso": apo_emailperso,
},
context=context,
)
# notifie seulement les changements d'adresse mail institutionnelle
if info["email"] != etud["mail"]:
@ -854,12 +838,11 @@ def formsemestre_import_etud_admission(
return no_nip, unknowns, changed_mails
def do_synch_inscrits_etuds(context, sem, etuds, REQUEST=None):
def do_synch_inscrits_etuds(sem, etuds, REQUEST=None): # unused ?
"""inscrits ces etudiants (déja dans ScoDoc) au semestre"""
log("do_synch_inscrits_etuds: inscription de %d etudiants" % len(etuds))
for etud in etuds:
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
context,
sem["formsemestre_id"],
etud["etudid"],
etat="I",

View File

@ -68,9 +68,8 @@ class ScoTag(object):
assoc_table = None # table (tag_id, object_id)
obj_colname = None # column name for object_id in assoc_table
def __init__(self, context, title, object_id=""):
def __init__(self, title, object_id=""):
"""Load tag, or create if does not exist"""
self.context = context
self.title = title.strip()
if not self.title:
raise ScoValueError("invalid empty tag")
@ -197,7 +196,7 @@ class ModuleTag(ScoTag):
# API
def module_tag_search(context, term, REQUEST=None):
def module_tag_search(term, REQUEST=None):
"""List all used tag names (for auto-completion)"""
# restrict charset to avoid injections
if not scu.ALPHANUM_EXP.match(term):
@ -230,7 +229,6 @@ def module_tag_set(module_id="", taglist=None):
a string with tag names separated by commas ("un;deux")
or a list of strings (["un", "deux"])
"""
context = None # #context
if not taglist:
taglist = []
elif isinstance(taglist, str):
@ -249,15 +247,15 @@ def module_tag_set(module_id="", taglist=None):
# should be atomic, but it's not.
for tagname in to_add:
t = ModuleTag(context, tagname, object_id=module_id)
t = ModuleTag(tagname, object_id=module_id)
for tagname in to_del:
t = ModuleTag(context, tagname)
t = ModuleTag(tagname)
t.remove_tag_from_object(module_id)
return "", http.HTTPStatus.NO_CONTENT
def get_etud_tagged_modules(context, etudid, tagname):
def get_etud_tagged_modules(etudid, tagname):
"""Liste d'infos sur les modules de ce semestre avec ce tag.
Cherche dans tous les semestres dans lesquel l'étudiant est ou a été inscrit.
Construit la liste des modules avec le tag donné par tagname
@ -307,13 +305,13 @@ def split_tagname_coeff(tag, separateur=":"):
"""Tests:
from debug import *
from app.scodoc.sco_tag_module import *
context = go_dept(app, 'RT').Notes
_ = go_dept(app, 'RT').Notes
t = ModuleTag(context, 'essai')
t = ModuleTag( 'essai')
t.tag_module('totoro') # error (module invalide)
t.tag_module('MOD21460')
t.delete() # detruit tag et assoc
t = ModuleTag(context, 'essai2')
t = ModuleTag( 'essai2')
t.tag_module('MOD21460')
t.tag_module('MOD21464')
t.list_modules()
@ -324,13 +322,13 @@ t.list_modules(formation_code='FCOD2')
Un essai de get_etud_tagged_modules:
from debug import *
from app.scodoc.sco_tag_module import *
context = go_dept(app, 'GEA').Notes
_ = go_dept(app, 'GEA').Notes
etudid='GEAEID80687'
etud = sco_etud.get_etud_info( etudid=etudid, filled=True)[0]
sem = etud['sems'][0]
[ tm['moy'] for tm in get_etud_tagged_modules(context, etudid, 'allo') ]
[ tm['moy'] for tm in get_etud_tagged_modules( etudid, 'allo') ]
# si besoin après modif par le Web:
# sco_cache.invalidate_formsemestre()

View File

@ -66,7 +66,6 @@ from app.scodoc import sco_etud
def trombino(
context,
REQUEST=None,
group_ids=[], # liste des groupes à afficher
formsemestre_id=None, # utilisé si pas de groupes selectionné
@ -85,27 +84,27 @@ def trombino(
#
if format != "html" and not dialog_confirmed:
ok, dialog = check_local_photos_availability(
context, groups_infos, REQUEST, format=format
groups_infos, REQUEST, format=format
)
if not ok:
return dialog
if format == "zip":
return _trombino_zip(context, groups_infos, REQUEST)
return _trombino_zip(groups_infos, REQUEST)
elif format == "pdf":
return _trombino_pdf(context, groups_infos, REQUEST)
return _trombino_pdf(groups_infos, REQUEST)
elif format == "pdflist":
return _listeappel_photos_pdf(context, groups_infos, REQUEST)
return _listeappel_photos_pdf(groups_infos, REQUEST)
else:
raise Exception("invalid format")
# return _trombino_html_header(context, REQUEST) + trombino_html(context, group, members, REQUEST=REQUEST) + html_sco_header.sco_footer( REQUEST)
# return _trombino_html_header() + trombino_html( group, members, REQUEST=REQUEST) + html_sco_header.sco_footer( REQUEST)
def _trombino_html_header(context, REQUEST):
def _trombino_html_header():
return html_sco_header.sco_header(javascripts=["js/trombino.js"])
def trombino_html(context, groups_infos, REQUEST=None):
def trombino_html(groups_infos, REQUEST=None):
"HTML snippet for trombino (with title and menu)"
menuTrombi = [
{
@ -150,8 +149,8 @@ def trombino_html(context, groups_infos, REQUEST=None):
'<span class="trombi_box"><span class="trombi-photo" id="trombi-%s">'
% t["etudid"]
)
if sco_photos.etud_photo_is_local(context, t, size="small"):
foto = sco_photos.etud_photo_html(context, t, title="", REQUEST=REQUEST)
if sco_photos.etud_photo_is_local(t, size="small"):
foto = sco_photos.etud_photo_html(t, title="", REQUEST=REQUEST)
else: # la photo n'est pas immédiatement dispo
foto = (
'<span class="unloaded_img" id="%s"><img border="0" height="90" alt="en cours" src="/ScoDoc/static/icons/loading.jpg"/></span>'
@ -184,7 +183,7 @@ def trombino_html(context, groups_infos, REQUEST=None):
return "\n".join(H)
def check_local_photos_availability(context, groups_infos, REQUEST, format=""):
def check_local_photos_availability(groups_infos, REQUEST, format=""):
"""Verifie que toutes les photos (des gropupes indiqués) sont copiées localement
dans ScoDoc (seules les photos dont nous disposons localement peuvent être exportées
en pdf ou en zip).
@ -192,10 +191,8 @@ def check_local_photos_availability(context, groups_infos, REQUEST, format=""):
"""
nb_missing = 0
for t in groups_infos.members:
_ = sco_photos.etud_photo_url(
context, t, REQUEST=REQUEST
) # -> copy distant files if needed
if not sco_photos.etud_photo_is_local(context, t):
_ = sco_photos.etud_photo_url(t) # -> copy distant files if needed
if not sco_photos.etud_photo_is_local(t):
nb_missing += 1
if nb_missing > 0:
parameters = {"group_ids": groups_infos.group_ids, "format": format}
@ -218,7 +215,7 @@ def check_local_photos_availability(context, groups_infos, REQUEST, format=""):
return True, ""
def _trombino_zip(context, groups_infos, REQUEST):
def _trombino_zip(groups_infos, REQUEST):
"Send photos as zip archive"
data = io.BytesIO()
Z = ZipFile(data, "w")
@ -248,7 +245,7 @@ def _trombino_zip(context, groups_infos, REQUEST):
# Copy photos from portal to ScoDoc
def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=False):
def trombino_copy_photos(group_ids=[], REQUEST=None, dialog_confirmed=False):
"Copy photos from portal to ScoDoc (overwriting local copy)"
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids, REQUEST=REQUEST)
back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args
@ -278,7 +275,7 @@ def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=F
msg = []
nok = 0
for etud in groups_infos.members:
path, diag = sco_photos.copy_portal_photo_to_fs(context, etud, REQUEST=REQUEST)
path, diag = sco_photos.copy_portal_photo_to_fs(etud)
msg.append(diag)
if path:
nok += 1
@ -295,7 +292,7 @@ def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=F
)
def _get_etud_platypus_image(context, t, image_width=2 * cm):
def _get_etud_platypus_image(t, image_width=2 * cm):
"""Returns aplatypus object for the photo of student t"""
try:
path = sco_photos.photo_pathname(t, size="small")
@ -319,7 +316,7 @@ def _get_etud_platypus_image(context, t, image_width=2 * cm):
raise
def _trombino_pdf(context, groups_infos, REQUEST):
def _trombino_pdf(groups_infos, REQUEST):
"Send photos as pdf page"
# Generate PDF page
filename = "trombino_%s" % groups_infos.groups_filename + ".pdf"
@ -342,7 +339,7 @@ def _trombino_pdf(context, groups_infos, REQUEST):
currow = []
log("_trombino_pdf %d elements" % len(groups_infos.members))
for t in groups_infos.members:
img = _get_etud_platypus_image(context, t, image_width=PHOTOWIDTH)
img = _get_etud_platypus_image(t, image_width=PHOTOWIDTH)
elem = Table(
[
[img],
@ -393,7 +390,7 @@ def _trombino_pdf(context, groups_infos, REQUEST):
# --------------------- Sur une idée de l'IUT d'Orléans:
def _listeappel_photos_pdf(context, groups_infos, REQUEST):
def _listeappel_photos_pdf(groups_infos, REQUEST):
"Doc pdf pour liste d'appel avec photos"
filename = "trombino_%s" % groups_infos.groups_filename + ".pdf"
sem = groups_infos.formsemestre # suppose 1 seul semestre
@ -424,7 +421,7 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST):
# for page in range(npages):
for i in range(n): # page*2*ROWS_PER_PAGE, (page+1)*2*ROWS_PER_PAGE):
t = groups_infos.members[i]
img = _get_etud_platypus_image(context, t, image_width=PHOTOWIDTH)
img = _get_etud_platypus_image(t, image_width=PHOTOWIDTH)
txt = Paragraph(
SU(sco_etud.format_nomprenom(t)),
StyleSheet["Normal"],
@ -469,12 +466,11 @@ 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):
def photos_generate_excel_sample(group_ids=[], REQUEST=None):
"""Feuille excel pour import fichiers photos"""
fmt = sco_import_etuds.sco_import_format()
data = sco_import_etuds.sco_import_generate_excel_sample(
fmt,
context=context,
group_ids=group_ids,
only_tables=["identite"],
exclude_cols=[
@ -485,12 +481,11 @@ def photos_generate_excel_sample(context, group_ids=[], REQUEST=None):
"photo_filename",
],
extra_cols=["fichier_photo"],
REQUEST=REQUEST,
)
return sco_excel.send_excel_file(REQUEST, data, "ImportPhotos" + scu.XLSX_SUFFIX)
def photos_import_files_form(context, group_ids=[], REQUEST=None):
def photos_import_files_form(group_ids=[], REQUEST=None):
"""Formulaire pour importation photos"""
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids, REQUEST=REQUEST)
back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args
@ -532,7 +527,6 @@ def photos_import_files_form(context, group_ids=[], REQUEST=None):
return flask.redirect(back_url)
else:
return photos_import_files(
context,
group_ids=tf[2]["group_ids"],
xlsfile=tf[2]["xlsfile"],
zipfile=tf[2]["zipfile"],
@ -540,29 +534,23 @@ def photos_import_files_form(context, group_ids=[], REQUEST=None):
)
def photos_import_files(
context, group_ids=[], xlsfile=None, zipfile=None, REQUEST=None
):
def photos_import_files(group_ids=[], xlsfile=None, zipfile=None, REQUEST=None):
"""Importation des photos"""
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids, REQUEST=REQUEST)
back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args
filename_title = "fichier_photo"
page_title = "Téléchargement des photos des étudiants"
def callback(context, etud, data, filename, REQUEST):
sco_photos.store_photo(context, etud, data, REQUEST)
def callback(etud, data, filename):
sco_photos.store_photo(etud, data)
zip_excel_import_files(
context, xlsfile, zipfile, REQUEST, callback, filename_title, page_title
)
zip_excel_import_files(xlsfile, zipfile, callback, filename_title, page_title)
return flask.redirect(back_url + "&head_message=photos%20 importees")
def zip_excel_import_files(
context,
xlsfile=None,
zipfile=None,
REQUEST=None,
callback=None,
filename_title="", # doit obligatoirement etre specifié
page_title="",
@ -595,7 +583,7 @@ def zip_excel_import_files(
fn = fn.replace("\\", "/") # not sure if this is necessary ?
fn = fn.strip()
if lowercase:
fn = scu.strlower(fn)
fn = fn.lower()
fn = fn.split("/")[-1] # use only last component, not directories
return fn
@ -627,11 +615,9 @@ def zip_excel_import_files(
raise ScoValueError("ID étudiant invalide: %s" % etudid)
callback(
context,
etud,
data,
normfilename(name, lowercase=False),
REQUEST=REQUEST,
)
stored.append((etud, name))
@ -649,7 +635,7 @@ def zip_excel_import_files(
unmatched_files = []
# 3- Result page
H = [
_trombino_html_header(context, REQUEST),
_trombino_html_header(),
"""<h2 class="formsemestre">%s</h2>
<h3>Opération effectuée</h3>
"""

View File

@ -54,7 +54,6 @@ N_PER_ROW = 5
def pdf_trombino_tours(
context,
group_ids=[], # liste des groupes à afficher
formsemestre_id=None, # utilisé si pas de groupes selectionné
REQUEST=None,
@ -176,9 +175,7 @@ def pdf_trombino_tours(
)
n = 1
for m in members:
img = sco_trombino._get_etud_platypus_image(
context, m, image_width=PHOTOWIDTH
)
img = sco_trombino._get_etud_platypus_image(m, image_width=PHOTOWIDTH)
etud_main_group = sco_groups.get_etud_main_group(m["etudid"], sem)
if group_id != etud_main_group["group_id"]:
text_group = " (" + etud_main_group["group_name"] + ")"
@ -282,7 +279,6 @@ def pdf_trombino_tours(
def pdf_feuille_releve_absences(
context,
group_ids=[], # liste des groupes à afficher
formsemestre_id=None, # utilisé si pas de groupes selectionné
REQUEST=None,

View File

@ -29,7 +29,7 @@
On rapatrie (saisit) les notes (et crédits ECTS).
Contexte: les étudiants d'une formation gérée par ScoDoc peuvent
Cas d'usage: les étudiants d'une formation gérée par ScoDoc peuvent
suivre un certain nombre d'UE à l'extérieur. L'établissement a reconnu
au préalable une forme d'équivalence entre ces UE et celles du
programme. Les UE effectuées à l'extérieur sont par nature variable
@ -76,7 +76,6 @@ from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
def external_ue_create(
context,
formsemestre_id,
titre="",
acronyme="",
@ -138,7 +137,7 @@ def external_ue_create(
def external_ue_inscrit_et_note(
context, moduleimpl_id, formsemestre_id, notes_etuds, REQUEST=None
moduleimpl_id, formsemestre_id, notes_etuds, REQUEST=None
):
log(
"external_ue_inscrit_et_note(moduleimpl_id=%s, notes_etuds=%s)"
@ -171,7 +170,6 @@ def external_ue_inscrit_et_note(
)
# Saisie des notes
_, _, _ = sco_saisie_notes._notes_add(
context,
REQUEST.AUTHENTICATED_USER,
evaluation_id,
list(notes_etuds.items()),
@ -179,14 +177,14 @@ def external_ue_inscrit_et_note(
)
def get_existing_external_ue(context, formation_id):
def get_existing_external_ue(formation_id):
"la liste de toutes les UE externes définies dans cette formation"
return sco_edit_ue.do_ue_list(
args={"formation_id": formation_id, "is_external": True}
)
def get_external_moduleimpl_id(context, formsemestre_id, ue_id):
def get_external_moduleimpl_id(formsemestre_id, ue_id):
"moduleimpl correspondant à l'UE externe indiquée de ce formsemestre"
r = ndb.SimpleDictFetch(
"""
@ -204,7 +202,7 @@ def get_external_moduleimpl_id(context, formsemestre_id, ue_id):
# Web function
def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
def external_ue_create_form(formsemestre_id, etudid, REQUEST=None):
"""Formulaire création UE externe + inscription étudiant et saisie note
- Demande UE: peut-être existante (liste les UE externes de cette formation),
ou sinon spécifier titre, acronyme, type, ECTS
@ -221,7 +219,7 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
formation_id = sem["formation_id"]
existing_external_ue = get_existing_external_ue(context, formation_id)
existing_external_ue = get_existing_external_ue(formation_id)
H = [
html_sco_header.html_sem_header(
@ -346,7 +344,7 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
)
if tf[2]["existing_ue"]:
ue_id = tf[2]["existing_ue"]
moduleimpl_id = get_external_moduleimpl_id(context, formsemestre_id, ue_id)
moduleimpl_id = get_external_moduleimpl_id(formsemestre_id, ue_id)
else:
acronyme = tf[2]["acronyme"].strip()
if not acronyme:
@ -358,7 +356,6 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
+ html_footer
)
moduleimpl_id = external_ue_create(
context,
formsemestre_id,
REQUEST=REQUEST,
titre=tf[2]["titre"],
@ -368,7 +365,6 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
)
external_ue_inscrit_et_note(
context,
moduleimpl_id,
formsemestre_id,
{etudid: note_value},

View File

@ -80,7 +80,7 @@ class NotesOperation(dict):
self["nb_notes"] = len(self["notes"])
self["datestr"] = self["date"].strftime("%a %d/%m/%y %Hh%M")
def undo(self, context):
def undo(self):
"undo operation"
pass
# replace notes by last found in notes_log
@ -100,7 +100,7 @@ class NotesOperation(dict):
# + invalider cache sco_cache.EvaluationCache.delete(evaluation_id)
def list_operations(context, evaluation_id):
def list_operations(evaluation_id):
"""returns list of NotesOperation for this evaluation"""
notes = list(
sco_evaluations.do_evaluation_get_all_notes(
@ -144,12 +144,12 @@ def list_operations(context, evaluation_id):
return Ops
def evaluation_list_operations(context, REQUEST, evaluation_id):
def evaluation_list_operations(evaluation_id, REQUEST=None):
"""Page listing operations on evaluation"""
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
Ops = list_operations(context, evaluation_id)
Ops = list_operations(evaluation_id)
columns_ids = ("datestr", "uid", "nb_notes", "comment")
titles = {
@ -170,9 +170,7 @@ def evaluation_list_operations(context, REQUEST, evaluation_id):
return tab.make_page(REQUEST=REQUEST)
def formsemestre_list_saisies_notes(
context, formsemestre_id, format="html", REQUEST=None
):
def formsemestre_list_saisies_notes(formsemestre_id, format="html", REQUEST=None):
"""Table listant toutes les opérations de saisies de notes, dans toutes
les évaluations du semestre.
"""
@ -225,7 +223,7 @@ def formsemestre_list_saisies_notes(
return tab.make_page(format=format, REQUEST=REQUEST)
def get_note_history(context, evaluation_id, etudid, REQUEST=None, fmt=""):
def get_note_history(evaluation_id, etudid, REQUEST=None, fmt=""):
"""Historique d'une note
= liste chronologique d'opérations, la plus récente d'abord
[ { 'value', 'date', 'comment', 'uid' } ]
@ -269,6 +267,6 @@ def get_note_history(context, evaluation_id, etudid, REQUEST=None, fmt=""):
"""
from debug import *
from app.scodoc.sco_undo_notes import *
context = go_dept(app, 'RT').Notes
get_note_history(context, 'EVAL29740', 'EID28403')
_ = go_dept(app, 'RT').Notes
get_note_history( 'EVAL29740', 'EID28403')
"""

View File

@ -66,7 +66,7 @@ _UP_TO_DATE = True # cached result (limit requests to 1 per day)
_UP_TO_DATE_MSG = ""
def is_up_to_date(context):
def is_up_to_date():
"""True if up_to_date
Returns status, message
"""
@ -128,9 +128,9 @@ def is_up_to_date(context):
# return _UP_TO_DATE, _UP_TO_DATE_MSG
def html_up_to_date_box(context):
def html_up_to_date_box():
""""""
status, msg = is_up_to_date(context)
status, msg = is_up_to_date()
if status:
return ""
return (

View File

@ -81,7 +81,7 @@ def is_valid_password(cleartxt):
# ---------------
def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="html"):
def index_html(REQUEST, all_depts=False, with_inactives=False, format="html"):
"gestion utilisateurs..."
all_depts = int(all_depts)
with_inactives = int(with_inactives)
@ -116,7 +116,6 @@ def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="
)
L = list_users(
context,
g.scodoc_dept,
all_depts=all_depts,
with_inactives=with_inactives,
@ -133,7 +132,6 @@ def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="
def list_users(
context,
dept,
all_depts=False, # tous les departements
with_inactives=False, # inclut les anciens utilisateurs (status "old")
@ -211,7 +209,7 @@ def list_users(
html_sortable=True,
base_url="%s?all=%s" % (REQUEST.URL0, all),
pdf_link=False, # table is too wide to fit in a paper page => disable pdf
preferences=sco_preferences.SemPreferences(context),
preferences=sco_preferences.SemPreferences(),
)
return tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
@ -284,7 +282,7 @@ def user_info(user_name=None, user=None):
return info
def user_info_page(context, user_name=None, REQUEST=None):
def user_info_page(user_name=None, REQUEST=None):
"""Display page of info about given user.
If user_name not specified, user current_user
"""

View File

@ -576,19 +576,6 @@ def check_scodoc7_password(scodoc7_hash, password):
# Simple string manipulations
# not necessary anymore in Python 3 ! TODO remove
def strupper(s):
return s.upper()
# return s.decode(SCO_ENCODING).upper().encode(SCO_ENCODING)
# XXX fonctions inutiles en Python3 !
def strlower(s):
return s.lower()
def strcapitalize(s):
return s.capitalize()
def abbrev_prenom(prenom):

View File

@ -34,7 +34,7 @@ Code dérivé de la partie la plus ancienne de ScoDoc, et à revoir.
L'API de plus bas niveau est en gros:
AnnuleAbsencesDatesNoJust(etudid, dates)
AnnuleAbsencesDatesNoJust( dates)
count_abs(etudid, debut, fin, matin=None, moduleimpl_id=None)
count_abs_just(etudid, debut, fin, matin=None, moduleimpl_id=None)
list_abs_just(etudid, datedebut) [pas de fin ?]
@ -65,7 +65,6 @@ from flask import current_app
from app.decorators import (
scodoc,
scodoc7func,
ScoDoc7Context,
permission_required,
admin_required,
login_required,
@ -102,23 +101,15 @@ from app.scodoc import sco_xml
CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS
context = ScoDoc7Context("absences")
def sco_publish(route, function, permission, methods=["GET"]):
"""Declare a route for a python function,
protected by permission and called following ScoDoc 7 Zope standards.
"""
return bp.route(route, methods=methods)(
scodoc(permission_required(permission)(scodoc7func(context)(function)))
scodoc(permission_required(permission)(scodoc7func(function)))
)
def _toboolean(x):
"convert a value to boolean"
return x # not necessary anymore !
# --------------------------------------------------------------------
#
# ABSENCES (/ScoDoc/<dept>/Scolarite/Absences/...)
@ -130,8 +121,8 @@ def _toboolean(x):
@bp.route("/index_html")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def index_html(context, REQUEST=None):
@scodoc7func
def index_html(REQUEST=None):
"""Gestionnaire absences, page principale"""
# crude portage from 1999 DTML
sems = sco_formsemestre.do_formsemestre_list()
@ -160,7 +151,7 @@ def index_html(context, REQUEST=None):
H.append(
"""<p>Pour signaler, annuler ou justifier une absence, choisissez d'abord l'étudiant concerné:</p>"""
)
H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(sco_find_etud.form_search_etud(REQUEST))
if authuser.has_permission(Permission.ScoAbsChange):
H.extend(
(
@ -173,9 +164,9 @@ def index_html(context, REQUEST=None):
<input name="datelundi" type="hidden" value="x"/>
"""
% REQUEST.URL0,
sco_abs_views.formChoixSemestreGroupe(context),
sco_abs_views.formChoixSemestreGroupe(),
"</p>",
cal_select_week(context),
cal_select_week(),
"""<p class="help">Sélectionner le groupe d'étudiants, puis cliquez sur une semaine pour
saisir les absences de toute cette semaine.</p>
</form>""",
@ -190,7 +181,7 @@ saisir les absences de toute cette semaine.</p>
return "\n".join(H)
def cal_select_week(context, year=None):
def cal_select_week(year=None):
"display calendar allowing week selection"
if not year:
year = scu.AnneeScolaire()
@ -199,7 +190,7 @@ def cal_select_week(context, year=None):
js = ""
else:
js = 'onmouseover="highlightweek(this);" onmouseout="deselectweeks();" onclick="wclick(this);"'
C = sco_abs.YearTable(context, int(year), dayattributes=js)
C = sco_abs.YearTable(int(year), dayattributes=js)
return C
@ -271,9 +262,8 @@ sco_publish("/CountAbsJust", sco_abs.count_abs_just, Permission.ScoView)
@bp.route("/doSignaleAbsenceGrSemestre", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoAbsChange)
@scodoc7func(context)
@scodoc7func
def doSignaleAbsenceGrSemestre(
context,
moduleimpl_id=None,
abslist=[],
dates="",
@ -298,14 +288,12 @@ def doSignaleAbsenceGrSemestre(
# 1- Efface les absences
if dates:
for etudid in etudids:
sco_abs_views.AnnuleAbsencesDatesNoJust(
context, etudid, dates, moduleimpl_id
)
sco_abs_views.AnnuleAbsencesDatesNoJust(etudid, dates, moduleimpl_id)
return "Absences effacées"
# 2- Ajoute les absences
if abslist:
sco_abs._add_abslist(context, abslist, REQUEST, moduleimpl_id)
sco_abs._add_abslist(abslist, REQUEST, moduleimpl_id)
return "Absences ajoutées"
return ""
@ -315,9 +303,9 @@ def doSignaleAbsenceGrSemestre(
@bp.route("/SignaleAbsenceGrHebdo", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoAbsChange)
@scodoc7func(context)
@scodoc7func
def SignaleAbsenceGrHebdo(
context, datelundi, group_ids=[], destination="", moduleimpl_id=None, REQUEST=None
datelundi, group_ids=[], destination="", moduleimpl_id=None, REQUEST=None
):
"Saisie hebdomadaire des absences"
if not moduleimpl_id:
@ -369,8 +357,8 @@ def SignaleAbsenceGrHebdo(
# calcule dates jours de cette semaine
# liste de dates iso "yyyy-mm-dd"
datessem = [ndb.DateDMYtoISO(datelundi)]
for _ in sco_abs.day_names(context)[1:]:
datessem.append(sco_abs.next_iso_day(context, datessem[-1]))
for _ in sco_abs.day_names()[1:]:
datessem.append(sco_abs.next_iso_day(datessem[-1]))
#
if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en"
@ -465,7 +453,7 @@ def SignaleAbsenceGrHebdo(
)
H += _gen_form_saisie_groupe(
context, etuds, datessem, destination, moduleimpl_id, require_module
etuds, datessem, destination, moduleimpl_id, require_module
)
H.append(html_sco_header.sco_footer())
@ -475,9 +463,8 @@ def SignaleAbsenceGrHebdo(
@bp.route("/SignaleAbsenceGrSemestre", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoAbsChange)
@scodoc7func(context)
@scodoc7func
def SignaleAbsenceGrSemestre(
context,
datedebut,
datefin,
destination="",
@ -531,7 +518,7 @@ def SignaleAbsenceGrSemestre(
sem = sco_formsemestre.do_formsemestre_list(
{"formsemestre_id": formsemestre_id}
)[0]
work_saturday = sco_abs.is_work_saturday(context)
work_saturday = sco_abs.is_work_saturday()
jourdebut = sco_abs.ddmmyyyy(datedebut, work_saturday=work_saturday)
jourfin = sco_abs.ddmmyyyy(datefin, work_saturday=work_saturday)
today = sco_abs.ddmmyyyy(
@ -569,7 +556,7 @@ def SignaleAbsenceGrSemestre(
url_link_semaines += "&moduleimpl_id=" + moduleimpl_id
#
dates = [x.ISO() for x in dates]
dayname = sco_abs.day_names(context)[jourdebut.weekday]
dayname = sco_abs.day_names()[jourdebut.weekday]
if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en"
@ -652,14 +639,14 @@ onchange="document.location='%(url)s&moduleimpl_id='+document.getElementById('mo
)
H += _gen_form_saisie_groupe(
context, etuds, dates, destination, moduleimpl_id, require_module
etuds, dates, destination, moduleimpl_id, require_module
)
H.append(html_sco_header.sco_footer())
return "\n".join(H)
def _gen_form_saisie_groupe(
context, etuds, dates, destination="", moduleimpl_id=None, require_module=False
etuds, dates, destination="", moduleimpl_id=None, require_module=False
):
"""Formulaire saisie absences
@ -706,7 +693,7 @@ def _gen_form_saisie_groupe(
end = dates[-1]
# Titres colonnes
noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ]
jn = sco_abs.day_names(context)
jn = sco_abs.day_names()
for d in odates:
idx_jour = d.weekday()
noms_jours.append(jn[idx_jour])
@ -847,9 +834,8 @@ def _gen_form_saisie_groupe(
@bp.route("/EtatAbsencesGr")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context) # ported from dtml
@scodoc7func # ported from dtml
def EtatAbsencesGr(
context,
group_ids=[], # list of groups to display
debut="",
fin="",
@ -984,9 +970,9 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
@bp.route("/EtatAbsencesDate")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def EtatAbsencesDate(
context, group_ids=[], date=None, REQUEST=None # list of groups to display
group_ids=[], date=None, REQUEST=None # list of groups to display
):
# ported from dtml
"""Etat des absences pour un groupe à une date donnée"""
@ -1067,9 +1053,8 @@ def EtatAbsencesDate(
@bp.route("/AddBilletAbsence")
@scodoc
@permission_required(Permission.ScoAbsAddBillet)
@scodoc7func(context)
@scodoc7func
def AddBilletAbsence(
context,
begin,
end,
description,
@ -1117,7 +1102,7 @@ def AddBilletAbsence(
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
tab = _tableBillets(context, billets, etud=etud)
tab = _tableBillets(billets, etud=etud)
log("AddBilletAbsence: new billet_id=%s (%gs)" % (billet_id, time.time() - t0))
return tab.make_page(REQUEST=REQUEST, format="xml")
else:
@ -1127,8 +1112,8 @@ def AddBilletAbsence(
@bp.route("/AddBilletAbsenceForm")
@scodoc
@permission_required(Permission.ScoAbsAddBillet)
@scodoc7func(context)
def AddBilletAbsenceForm(context, etudid, REQUEST=None):
@scodoc7func
def AddBilletAbsenceForm(etudid, REQUEST=None):
"""Formulaire ajout billet (pour tests seulement, le vrai formulaire accessible aux etudiants
étant sur le portail étudiant).
"""
@ -1163,7 +1148,6 @@ def AddBilletAbsenceForm(context, etudid, REQUEST=None):
end = e[2] + "-" + e[1] + "-" + e[0] + " 00:00:00"
log(
AddBilletAbsence(
context,
begin,
end,
tf[2]["description"],
@ -1175,7 +1159,7 @@ def AddBilletAbsenceForm(context, etudid, REQUEST=None):
return flask.redirect("listeBilletsEtud?etudid=" + str(etudid))
def _tableBillets(context, billets, etud=None, title=""):
def _tableBillets(billets, etud=None, title=""):
for b in billets:
if b["abs_begin"].hour < 12:
m = " matin"
@ -1240,8 +1224,8 @@ def _tableBillets(context, billets, etud=None, title=""):
@bp.route("/listeBilletsEtud")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def listeBilletsEtud(context, etudid=False, REQUEST=None, format="html"):
@scodoc7func
def listeBilletsEtud(etudid=False, REQUEST=None, format="html"):
"""Liste billets pour un etudiant"""
etuds = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)
if not etuds:
@ -1250,20 +1234,20 @@ def listeBilletsEtud(context, etudid=False, REQUEST=None, format="html"):
etud = etuds[0]
cnx = ndb.GetDBConnexion()
billets = sco_abs.billet_absence_list(cnx, {"etudid": etud["etudid"]})
tab = _tableBillets(context, billets, etud=etud)
tab = _tableBillets(billets, etud=etud)
return tab.make_page(REQUEST=REQUEST, format=format)
@bp.route("/XMLgetBilletsEtud")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def XMLgetBilletsEtud(context, etudid=False, REQUEST=None):
@scodoc7func
def XMLgetBilletsEtud(etudid=False, REQUEST=None):
"""Liste billets pour un etudiant"""
if not sco_preferences.get_preference("handle_billets_abs"):
return ""
t0 = time.time()
r = listeBilletsEtud(context, etudid, REQUEST=REQUEST, format="xml")
r = listeBilletsEtud(etudid, REQUEST=REQUEST, format="xml")
log("XMLgetBilletsEtud (%gs)" % (time.time() - t0))
return r
@ -1271,12 +1255,12 @@ def XMLgetBilletsEtud(context, etudid=False, REQUEST=None):
@bp.route("/listeBillets")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def listeBillets(context, REQUEST=None):
@scodoc7func
def listeBillets(REQUEST=None):
"""Page liste des billets non traités et formulaire recherche d'un billet"""
cnx = ndb.GetDBConnexion()
billets = sco_abs.billet_absence_list(cnx, {"etat": 0})
tab = _tableBillets(context, billets)
tab = _tableBillets(billets)
T = tab.html()
H = [
html_sco_header.sco_header(page_title="Billet d'absence non traités"),
@ -1300,8 +1284,8 @@ def listeBillets(context, REQUEST=None):
@bp.route("/deleteBilletAbsence")
@scodoc
@permission_required(Permission.ScoAbsChange)
@scodoc7func(context)
def deleteBilletAbsence(context, billet_id, REQUEST=None, dialog_confirmed=False):
@scodoc7func
def deleteBilletAbsence(billet_id, REQUEST=None, dialog_confirmed=False):
"""Supprime un billet."""
cnx = ndb.GetDBConnexion()
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
@ -1310,7 +1294,7 @@ def deleteBilletAbsence(context, billet_id, REQUEST=None, dialog_confirmed=False
"listeBillets?head_message=Billet%%20%s%%20inexistant !" % billet_id
)
if not dialog_confirmed:
tab = _tableBillets(context, billets)
tab = _tableBillets(billets)
return scu.confirm_dialog(
"""<h2>Supprimer ce billet ?</h2>""" + tab.html(),
dest_url="",
@ -1323,7 +1307,7 @@ def deleteBilletAbsence(context, billet_id, REQUEST=None, dialog_confirmed=False
return flask.redirect("listeBillets?head_message=Billet%20supprimé")
def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
def _ProcessBilletAbsence(billet, estjust, description, REQUEST):
"""Traite un billet: ajoute absence(s) et éventuellement justificatifs,
et change l'état du billet à 1.
NB: actuellement, les heures ne sont utilisées que pour déterminer si matin et/ou après-midi.
@ -1337,11 +1321,10 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
# 1-- ajout des absences (et justifs)
datedebut = billet["abs_begin"].strftime("%d/%m/%Y")
datefin = billet["abs_end"].strftime("%d/%m/%Y")
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
dates = sco_abs.DateRangeISO(datedebut, datefin)
# commence après-midi ?
if dates and billet["abs_begin"].hour > 11:
sco_abs.add_absence(
context,
billet["etudid"],
dates[0],
0,
@ -1354,7 +1337,6 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
# termine matin ?
if dates and billet["abs_end"].hour < 12:
sco_abs.add_absence(
context,
billet["etudid"],
dates[-1],
1,
@ -1367,7 +1349,6 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
for jour in dates:
sco_abs.add_absence(
context,
billet["etudid"],
jour,
0,
@ -1376,7 +1357,6 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
description=description,
)
sco_abs.add_absence(
context,
billet["etudid"],
jour,
1,
@ -1395,8 +1375,8 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
@bp.route("/ProcessBilletAbsenceForm")
@scodoc
@permission_required(Permission.ScoAbsChange)
@scodoc7func(context)
def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
@scodoc7func
def ProcessBilletAbsenceForm(billet_id, REQUEST=None):
"""Formulaire traitement d'un billet"""
cnx = ndb.GetDBConnexion()
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
@ -1443,7 +1423,7 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
submitlabel="Enregistrer ces absences",
)
if tf[0] == 0:
tab = _tableBillets(context, [billet], etud=etud)
tab = _tableBillets([billet], etud=etud)
H.append(tab.html())
if billet["justified"]:
H.append(
@ -1460,7 +1440,7 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
return flask.redirect(scu.ScoURL())
else:
n = _ProcessBilletAbsence(
context, billet, tf[2]["estjust"], tf[2]["description"], REQUEST
billet, tf[2]["estjust"], tf[2]["description"], REQUEST
)
if tf[2]["estjust"]:
j = "justifiées"
@ -1478,7 +1458,7 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
% (etud["nomprenom"])
)
billets = sco_abs.billet_absence_list(cnx, {"etudid": etud["etudid"]})
tab = _tableBillets(context, billets, etud=etud)
tab = _tableBillets(billets, etud=etud)
H.append(tab.html())
return "\n".join(H) + html_sco_header.sco_footer()
@ -1486,8 +1466,8 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
@bp.route("/XMLgetAbsEtud")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def XMLgetAbsEtud(context, beg_date="", end_date="", REQUEST=None):
@scodoc7func
def XMLgetAbsEtud(beg_date="", end_date="", REQUEST=None):
"""returns list of absences in date interval"""
t0 = time.time()
etud = sco_etud.get_etud_info(REQUEST=REQUEST)[0]
@ -1516,6 +1496,3 @@ def XMLgetAbsEtud(context, beg_date="", end_date="", REQUEST=None):
)
log("XMLgetAbsEtud (%gs)" % (time.time() - t0))
return sco_xml.XML_HEADER + ElementTree.tostring(doc).decode(scu.SCO_ENCODING)
context.populate(globals())

View File

@ -54,15 +54,14 @@ import calendar
# import sco_entreprises
def entreprise_header(context, REQUEST=None, page_title=""):
def entreprise_header(REQUEST=None, page_title=""):
"common header for all Entreprises pages"
return html_sco_header.sco_header( page_title=page_title
)
return html_sco_header.sco_header(page_title=page_title)
def entreprise_footer(context, REQUEST):
def entreprise_footer(REQUEST):
"common entreprise footer"
return html_sco_header.sco_footer( REQUEST)
return html_sco_header.sco_footer(REQUEST)
security.declareProtected(ScoEntrepriseView, "sidebar")
@ -73,7 +72,6 @@ def sidebar(REQUEST):
# rewritten from legacy DTML code
# XXX rare cas restant d'utilisation de l'acquisition Zope2: à revoir
params = {"ScoURL": scu.ScoURL()}
context=None # XXX #context
H = [
"""<div id="sidebar-container">
<div class="sidebar">""",
@ -82,9 +80,7 @@ def sidebar(REQUEST):
<ul class="insidebar">"""
% params,
]
if REQUEST.AUTHENTICATED_USER.has_permission(
Permission.ScoEntrepriseChange
):
if REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoEntrepriseChange):
H.append(
"""<li class="insidebar"><a href="%(ScoURL)s/Entreprises/entreprise_create" class="sidebar">Nouvelle entreprise</a> </li>"""
% params
@ -98,9 +94,7 @@ def sidebar(REQUEST):
# --- entreprise selectionnée:
if "entreprise_id" in REQUEST.form:
entreprise_id = REQUEST.form["entreprise_id"]
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})
if E:
E = E[0]
params.update(E)
@ -133,9 +127,7 @@ def sidebar(REQUEST):
#
H.append("""<br/><br/>%s""" % scu.icontag("entreprise_side_img"))
if not REQUEST.AUTHENTICATED_USER.has_permission(
Permission.ScoEntrepriseChange
):
if not REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoEntrepriseChange):
H.append("""<br/><em>(Lecture seule)</em>""")
H.append("""</div> </div> <!-- end of sidebar -->""")
return "".join(H)
@ -149,9 +141,7 @@ def sidebar(REQUEST):
security.declareProtected(ScoEntrepriseView, "index_html")
def index_html(
context, REQUEST=None, etud_nom=None, limit=50, offset="", format="html"
):
def index_html(REQUEST=None, etud_nom=None, limit=50, offset="", format="html"):
"""Accueil module entreprises"""
# Traduit du DTML - utilise table standard
if limit:
@ -161,12 +151,11 @@ def index_html(
if etud_nom:
entreprises = sco_entreprises.do_entreprise_list_by_etud(
context, args=REQUEST.form, sort_on_contact=True
args=REQUEST.form, sort_on_contact=True
)
table_navigation = ""
else:
entreprises = sco_entreprises.do_entreprise_list(
context,
args=REQUEST.form,
test="~*",
sort_on_contact=True,
@ -200,14 +189,14 @@ def index_html(
for e in entreprises:
e["_nom_target"] = "entreprise_edit?entreprise_id=%(entreprise_id)s" % e
e["correspondants"] = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_id": e["entreprise_id"]}
args={"entreprise_id": e["entreprise_id"]}
)
e["nbcorr"] = "%d corr." % len(e["correspondants"])
e["_nbcorr_target"] = (
"entreprise_correspondant_list?entreprise_id=%(entreprise_id)s" % e
)
e["contacts"] = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_id": e["entreprise_id"]}
args={"entreprise_id": e["entreprise_id"]}
)
e["nbcontact"] = "%d contacts." % len(e["contacts"])
e["_nbcontact_target"] = (
@ -236,15 +225,15 @@ def index_html(
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page( format=format, REQUEST=REQUEST)
return tab.make_page(format=format, REQUEST=REQUEST)
else:
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2>Suivi relations entreprises</h2>""",
"""<div class="entreprise_list_table">""",
tab.html(),
"""</div>""",
entreprise_footer(context, REQUEST),
entreprise_footer(REQUEST),
]
return "\n".join(H)
@ -252,15 +241,13 @@ def index_html(
security.declareProtected(ScoEntrepriseView, "entreprise_contact_list")
def entreprise_contact_list(context, entreprise_id=None, format="html", REQUEST=None):
def entreprise_contact_list(entreprise_id=None, format="html", REQUEST=None):
"""Liste des contacts de l'entreprise"""
H = [entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises")]
H = [entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises")]
if entreprise_id:
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
C = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_id": entreprise_id}
args={"entreprise_id": entreprise_id}
)
H.append(
"""<h2 class="entreprise_contact">Listes des contacts avec l'entreprise %(nom)s</h2>
@ -268,18 +255,18 @@ def entreprise_contact_list(context, entreprise_id=None, format="html", REQUEST=
% E
)
else:
C = sco_entreprises.do_entreprise_contact_list(context, args={})
C = sco_entreprises.do_entreprise_contact_list(args={})
H.append(
"""<h2 class="entreprise_contact">Listes des contacts</h2>
"""
)
for c in C:
c["_date_target"] = "%s/entreprise_contact_edit?entreprise_contact_id=%s" % (
scu.EntreprisesURL(context, ),
scu.EntreprisesURL(),
c["entreprise_contact_id"],
)
c["entreprise"] = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": c["entreprise_id"]}
args={"entreprise_id": c["entreprise_id"]}
)[0]
if c["etudid"]:
c["etud"] = context.getEtudInfo(etudid=c["etudid"], filled=1)[0]
@ -311,13 +298,11 @@ def entreprise_contact_list(context, entreprise_id=None, format="html", REQUEST=
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page( format=format, REQUEST=REQUEST)
return tab.make_page(format=format, REQUEST=REQUEST)
H.append(tab.html())
if REQUEST.AUTHENTICATED_USER.has_permission(
Permission.ScoEntrepriseChange
):
if REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoEntrepriseChange):
if entreprise_id:
H.append(
"""<p class="entreprise_create"><a class="entreprise_create" href="entreprise_contact_create?entreprise_id=%(entreprise_id)s">nouveau "contact"</a></p>
@ -325,7 +310,7 @@ def entreprise_contact_list(context, entreprise_id=None, format="html", REQUEST=
% E
)
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
@ -333,31 +318,28 @@ security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_list")
def entreprise_correspondant_list(
context,
entreprise_id=None,
format="html",
REQUEST=None,
):
"""Liste des correspondants de l'entreprise"""
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""
<h2>Listes des correspondants dans l'entreprise %(nom)s</h2>
"""
% E,
]
correspondants = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_id": entreprise_id}
args={"entreprise_id": entreprise_id}
)
for c in correspondants:
c["nomprenom"] = c["nom"].upper() + " " + c["nom"].capitalize()
c[
"_nomprenom_target"
] = "%s/entreprise_correspondant_edit?entreprise_corresp_id=%s" % (
scu.EntreprisesURL(context, ),
scu.EntreprisesURL(),
c["entreprise_corresp_id"],
)
@ -422,44 +404,42 @@ def entreprise_correspondant_list(
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page( format=format, REQUEST=REQUEST)
return tab.make_page(format=format, REQUEST=REQUEST)
H.append(tab.html())
if REQUEST.AUTHENTICATED_USER.has_permission(
Permission.ScoEntrepriseChange
):
if REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoEntrepriseChange):
H.append(
"""<p class="entreprise_create"><a class="entreprise_create" href="entreprise_correspondant_create?entreprise_id=%(entreprise_id)s">Ajouter un correspondant dans l'entreprise %(nom)s</a></p>
"""
% E
)
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseView, "entreprise_contact_edit")
def entreprise_contact_edit(context, entreprise_contact_id, REQUEST=None):
def entreprise_contact_edit(entreprise_contact_id, REQUEST=None):
"""Form edit contact"""
c = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_contact_id": entreprise_contact_id}
args={"entreprise_contact_id": entreprise_contact_id}
)[0]
link_create_corr = (
'<a href="%s/entreprise_correspondant_create?entreprise_id=%s">créer un nouveau correspondant</a>'
% (scu.EntreprisesURL(context, ), c["entreprise_id"])
% (scu.EntreprisesURL(), c["entreprise_id"])
)
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": c["entreprise_id"]}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": c["entreprise_id"]})[
0
]
correspondants = sco_entreprises.do_entreprise_correspondant_listnames(
context, args={"entreprise_id": c["entreprise_id"]}
args={"entreprise_id": c["entreprise_id"]}
) + [("inconnu", "")]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2 class="entreprise_contact">Suivi entreprises</h2>
<h3>Contact avec entreprise %(nom)s</h3>"""
% E,
@ -553,33 +533,31 @@ def entreprise_contact_edit(context, entreprise_contact_id, REQUEST=None):
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context))
else:
etudok = sco_entreprises.do_entreprise_check_etudiant(
context, tf[2]["etudiant"]
)
etudok = sco_entreprises.do_entreprise_check_etudiant(tf[2]["etudiant"])
if etudok[0] == 0:
H.append("""<p class="entreprise_warning">%s</p>""" % etudok[1])
else:
tf[2].update({"etudid": etudok[1]})
sco_entreprises.do_entreprise_contact_edit(context, tf[2])
sco_entreprises.do_entreprise_contact_edit(tf[2])
return flask.redirect(
scu.EntreprisesURL(context, )
scu.EntreprisesURL()
+ "/entreprise_contact_list?entreprise_id="
+ str(c["entreprise_id"])
)
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_edit")
def entreprise_correspondant_edit(context, entreprise_corresp_id, REQUEST=None):
def entreprise_correspondant_edit(entreprise_corresp_id, REQUEST=None):
"""Form édition d'un correspondant"""
c = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_corresp_id": entreprise_corresp_id}
args={"entreprise_corresp_id": entreprise_corresp_id}
)[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2 class="entreprise_correspondant">Édition contact entreprise</h2>""",
]
tf = TrivialFormulator(
@ -673,38 +651,36 @@ def entreprise_correspondant_edit(context, entreprise_corresp_id, REQUEST=None):
elif tf[0] == -1:
return flask.redirect(
"%s/entreprise_correspondant_list?entreprise_id=%s"
% (scu.EntreprisesURL(context, ), c["entreprise_id"])
% (scu.EntreprisesURL(), c["entreprise_id"])
)
else:
sco_entreprises.do_entreprise_correspondant_edit(context, tf[2])
sco_entreprises.do_entreprise_correspondant_edit(tf[2])
return flask.redirect(
"%s/entreprise_correspondant_list?entreprise_id=%s"
% (scu.EntreprisesURL(context, ), c["entreprise_id"])
% (scu.EntreprisesURL(), c["entreprise_id"])
)
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_contact_create")
def entreprise_contact_create(context, entreprise_id, REQUEST=None):
def entreprise_contact_create(entreprise_id, REQUEST=None):
"""Form création contact"""
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
correspondants = sco_entreprises.do_entreprise_correspondant_listnames(
context, args={"entreprise_id": entreprise_id}
args={"entreprise_id": entreprise_id}
)
if not correspondants:
correspondants = [("inconnu", "")]
curtime = time.strftime("%d/%m/%Y")
link_create_corr = (
'<a href="%s/entreprise_correspondant_create?entreprise_id=%s">créer un nouveau correspondant</a>'
% (scu.EntreprisesURL(context, ), entreprise_id)
% (scu.EntreprisesURL(), entreprise_id)
)
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2 class="entreprise_contact">Nouveau "contact" avec l'entreprise %(nom)s</h2>"""
% E,
]
@ -784,29 +760,27 @@ def entreprise_contact_create(context, entreprise_id, REQUEST=None):
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context))
else:
etudok = sco_entreprises.do_entreprise_check_etudiant(
context, tf[2]["etudiant"]
)
etudok = sco_entreprises.do_entreprise_check_etudiant(tf[2]["etudiant"])
if etudok[0] == 0:
H.append("""<p class="entreprise_warning">%s</p>""" % etudok[1])
else:
tf[2].update({"etudid": etudok[1]})
sco_entreprises.do_entreprise_contact_create(context, tf[2])
return flask.redirect(scu.EntreprisesURL(context, ))
H.append(entreprise_footer(context, REQUEST))
sco_entreprises.do_entreprise_contact_create(tf[2])
return flask.redirect(scu.EntreprisesURL())
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_contact_delete")
def entreprise_contact_delete(context, entreprise_contact_id, REQUEST=None):
def entreprise_contact_delete(entreprise_contact_id, REQUEST=None):
"""Form delete contact"""
c = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_contact_id": entreprise_contact_id}
args={"entreprise_contact_id": entreprise_contact_id}
)[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2>Suppression du contact</h2>""",
]
tf = TrivialFormulator(
@ -816,33 +790,27 @@ def entreprise_contact_delete(context, entreprise_contact_id, REQUEST=None):
initvalues=c,
submitlabel="Confirmer la suppression",
cancelbutton="Annuler",
readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
ScoEntrepriseChange
),
readonly=not REQUEST.AUTHENTICATED_USER.has_permission(ScoEntrepriseChange),
)
if tf[0] == 0:
H.append(tf[1])
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context))
else:
sco_entreprises.do_entreprise_contact_delete(
context, c["entreprise_contact_id"]
)
sco_entreprises.do_entreprise_contact_delete(c["entreprise_contact_id"])
return flask.redirect(scu.EntreprisesURL(context))
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_create")
def entreprise_correspondant_create(context, entreprise_id, REQUEST=None):
def entreprise_correspondant_create(entreprise_id, REQUEST=None):
"""Form création correspondant"""
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2 class="entreprise_contact">Nouveau correspondant l'entreprise %(nom)s</h2>"""
% E,
]
@ -934,22 +902,22 @@ def entreprise_correspondant_create(context, entreprise_id, REQUEST=None):
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context))
else:
sco_entreprises.do_entreprise_correspondant_create(context, tf[2])
sco_entreprises.do_entreprise_correspondant_create(tf[2])
return flask.redirect(scu.EntreprisesURL(context))
H.append(entreprise_footer(context, REQUEST))
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_delete")
def entreprise_correspondant_delete(context, entreprise_corresp_id, REQUEST=None):
def entreprise_correspondant_delete(entreprise_corresp_id, REQUEST=None):
"""Form delete correspondant"""
c = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_corresp_id": entreprise_corresp_id}
args={"entreprise_corresp_id": entreprise_corresp_id}
)[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2>Suppression du correspondant %(nom)s %(prenom)s</h2>""" % c,
]
tf = TrivialFormulator(
@ -966,33 +934,29 @@ def entreprise_correspondant_delete(context, entreprise_corresp_id, REQUEST=None
if tf[0] == 0:
H.append(tf[1])
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context, ))
return flask.redirect(scu.EntreprisesURL())
else:
sco_entreprises.do_entreprise_correspondant_delete(
context, c["entreprise_corresp_id"]
)
return flask.redirect(scu.EntreprisesURL(context, ))
H.append(entreprise_footer(context, REQUEST))
sco_entreprises.do_entreprise_correspondant_delete(c["entreprise_corresp_id"])
return flask.redirect(scu.EntreprisesURL())
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_delete")
def entreprise_delete(context, entreprise_id, REQUEST=None):
def entreprise_delete(entreprise_id, REQUEST=None):
"""Form delete entreprise"""
E = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
E = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
H = [
entreprise_header(context, REQUEST=REQUEST, page_title="Suivi entreprises"),
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
"""<h2>Suppression de l'entreprise %(nom)s</h2>
<p class="entreprise_warning">Attention: supression définitive de l'entreprise, de ses correspondants et contacts.
</p>"""
% E,
]
Cl = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_id": entreprise_id}
args={"entreprise_id": entreprise_id}
)
if Cl:
H.append(
@ -1003,7 +967,7 @@ def entreprise_delete(context, entreprise_id, REQUEST=None):
H.append("""</ul>""")
Cts = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_id": entreprise_id}
args={"entreprise_id": entreprise_id}
)
if Cts:
H.append(
@ -1026,11 +990,11 @@ def entreprise_delete(context, entreprise_id, REQUEST=None):
if tf[0] == 0:
H.append(tf[1])
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context, ))
return flask.redirect(scu.EntreprisesURL())
else:
sco_entreprises.do_entreprise_delete(context, E["entreprise_id"])
return flask.redirect(scu.EntreprisesURL(context, ))
H.append(entreprise_footer(context, REQUEST))
sco_entreprises.do_entreprise_delete(E["entreprise_id"])
return flask.redirect(scu.EntreprisesURL())
H.append(entreprise_footer(REQUEST))
return "\n".join(H)
@ -1038,10 +1002,10 @@ def entreprise_delete(context, entreprise_id, REQUEST=None):
security.declareProtected(ScoEntrepriseChange, "entreprise_create")
def entreprise_create(context, REQUEST=None):
def entreprise_create(REQUEST=None):
"""Form. création entreprise"""
H = [
entreprise_header(context, REQUEST, page_title="Création d'une entreprise"),
entreprise_header(REQUEST, page_title="Création d'une entreprise"),
"""<h2 class="entreprise_new">Création d'une entreprise</h2>""",
]
tf = TrivialFormulator(
@ -1121,26 +1085,24 @@ def entreprise_create(context, REQUEST=None):
),
)
if tf[0] == 0:
return "\n".join(H) + tf[1] + entreprise_footer(context, REQUEST)
return "\n".join(H) + tf[1] + entreprise_footer(REQUEST)
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context, ))
return flask.redirect(scu.EntreprisesURL())
else:
sco_entreprises.do_entreprise_create(context, tf[2])
return flask.redirect(scu.EntreprisesURL(context, ))
sco_entreprises.do_entreprise_create(tf[2])
return flask.redirect(scu.EntreprisesURL())
security.declareProtected(ScoEntrepriseView, "entreprise_edit")
def entreprise_edit(context, entreprise_id, REQUEST=None, start=1):
def entreprise_edit(entreprise_id, REQUEST=None, start=1):
"""Form. edit entreprise"""
authuser = REQUEST.AUTHENTICATED_USER
readonly = not authuser.has_permission(Permission.ScoEntrepriseChange)
F = sco_entreprises.do_entreprise_list(
context, args={"entreprise_id": entreprise_id}
)[0]
F = sco_entreprises.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
H = [
entreprise_header(context, REQUEST, page_title="Entreprise"),
entreprise_header(REQUEST, page_title="Entreprise"),
"""<h2 class="entreprise">%(nom)s</h2>""" % F,
]
tf = TrivialFormulator(
@ -1226,10 +1188,10 @@ def entreprise_edit(context, entreprise_id, REQUEST=None, start=1):
if tf[0] == 0:
H.append(tf[1])
Cl = sco_entreprises.do_entreprise_correspondant_list(
context, args={"entreprise_id": F["entreprise_id"]}
args={"entreprise_id": F["entreprise_id"]}
)
Cts = sco_entreprises.do_entreprise_contact_list(
context, args={"entreprise_id": F["entreprise_id"]}
args={"entreprise_id": F["entreprise_id"]}
)
if not readonly:
H.append(
@ -1296,9 +1258,9 @@ def entreprise_edit(context, entreprise_id, REQUEST=None, start=1):
H.append("(%s)" % c["description"])
H.append("</li>")
H.append("</ul>")
return "\n".join(H) + entreprise_footer(context, REQUEST)
return "\n".join(H) + entreprise_footer(REQUEST)
elif tf[0] == -1:
return flask.redirect(scu.EntreprisesURL(context, ) + "?start=" + start)
return flask.redirect(scu.EntreprisesURL() + "?start=" + start)
else:
sco_entreprises.do_entreprise_edit(context, tf[2])
return flask.redirect(scu.EntreprisesURL(context, ) + "?start=" + start)
sco_entreprises.do_entreprise_edit(tf[2])
return flask.redirect(scu.EntreprisesURL() + "?start=" + start)

View File

@ -49,7 +49,6 @@ from app.auth.models import User
from app.decorators import (
scodoc,
scodoc7func,
ScoDoc7Context,
permission_required,
admin_required,
login_required,
@ -136,15 +135,13 @@ from app.scodoc.sco_permissions import Permission
from app.scodoc.TrivialFormulator import TrivialFormulator
import app.scodoc.VERSION as VERSION
context = ScoDoc7Context("notes")
def sco_publish(route, function, permission, methods=["GET"]):
"""Declare a route for a python function,
protected by permission and called following ScoDoc 7 Zope standards.
"""
return bp.route(route, methods=methods)(
scodoc(permission_required(permission)(scodoc7func(context)(function)))
scodoc(permission_required(permission)(scodoc7func(function)))
)
@ -152,20 +149,17 @@ def sco_publish(route, function, permission, methods=["GET"]):
@bp.route("/essai")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def essai(context, REQUEST=None):
return essai_(context, REQUEST)
@scodoc7func
def essai(REQUEST=None):
return essai_(REQUEST)
def essai_(context, REQUEST):
return "<html><body><h2>essai !</h2><p>%s</p><p>%s</p></body></html>" % (
context,
REQUEST,
)
def essai_(REQUEST):
return "<html><body><h2>essai !</h2><p>%s</p></body></html>" % (REQUEST,)
def essai2(context):
return essai_(context, "sans request")
def essai2():
return essai_("sans request")
sco_publish("/essai2", essai2, Permission.ScoImplement)
@ -383,8 +377,8 @@ sco_publish(
@bp.route("/index_html")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def index_html(context, REQUEST=None):
@scodoc7func
def index_html(REQUEST=None):
"Page accueil formations"
editable = REQUEST.AUTHENTICATED_USER.has_permission(Permission.ScoChangeFormation)
@ -436,7 +430,7 @@ sco_publish(
@bp.route("/formation_list")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formation_list(format=None, REQUEST=None, formation_id=None, args={}):
"""List formation(s) with given id, or matching args
(when args is given, formation_id is ignored).
@ -448,10 +442,8 @@ def formation_list(format=None, REQUEST=None, formation_id=None, args={}):
@bp.route("/formation_export")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formation_export(
context, formation_id, export_ids=False, format=None, REQUEST=None
):
@scodoc7func
def formation_export(formation_id, export_ids=False, format=None, REQUEST=None):
"Export de la formation au format indiqué (xml ou json)"
return sco_formations.formation_export(
formation_id, export_ids=export_ids, format=format, REQUEST=REQUEST
@ -461,7 +453,7 @@ def formation_export(
@bp.route("/formation_import_xml")
@scodoc
@permission_required(Permission.ScoChangeFormation)
@scodoc7func(context)
@scodoc7func
def formation_import_xml(file):
"import d'une formation en XML"
log("formation_import_xml")
@ -472,8 +464,8 @@ def formation_import_xml(file):
@bp.route("/formation_import_xml_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoChangeFormation)
@scodoc7func(context)
def formation_import_xml_form(context, REQUEST):
@scodoc7func
def formation_import_xml_form(REQUEST):
"form import d'une formation en XML"
H = [
html_sco_header.sco_header(page_title="Import d'une formation"),
@ -496,7 +488,7 @@ def formation_import_xml_form(context, REQUEST):
return flask.redirect(scu.NotesURL())
else:
formation_id, _, _ = sco_formations.formation_import_xml(
context, tf[2]["xmlfile"].read()
tf[2]["xmlfile"].read()
)
return (
@ -554,8 +546,8 @@ sco_publish(
@bp.route("/formation_count_sems")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formation_count_sems(context, formation_id):
@scodoc7func
def formation_count_sems(formation_id):
"Number of formsemestre in this formation (locked or not)"
sems = sco_formsemestre.do_formsemestre_list(args={"formation_id": formation_id})
return len(sems)
@ -585,9 +577,8 @@ sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormatio
@bp.route("/formsemestre_list")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_list(
context,
format=None,
REQUEST=None,
formsemestre_id=None,
@ -612,8 +603,8 @@ def formsemestre_list(
@bp.route("/XMLgetFormsemestres")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def XMLgetFormsemestres(context, etape_apo=None, formsemestre_id=None, REQUEST=None):
@scodoc7func
def XMLgetFormsemestres(etape_apo=None, formsemestre_id=None, REQUEST=None):
"""List all formsemestres matching etape, XML format
DEPRECATED: use formsemestre_list()
"""
@ -665,12 +656,12 @@ sco_publish(
@bp.route("/formsemestre_custommenu_edit", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_custommenu_edit(context, REQUEST, formsemestre_id):
@scodoc7func
def formsemestre_custommenu_edit(REQUEST, formsemestre_id):
"Dialogue modif menu"
# accessible à tous !
return sco_formsemestre_custommenu.formsemestre_custommenu_edit(
context, formsemestre_id, REQUEST=REQUEST
formsemestre_id, REQUEST=REQUEST
)
@ -678,8 +669,8 @@ def formsemestre_custommenu_edit(context, REQUEST, formsemestre_id):
@bp.route("/edit_enseignants_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def edit_enseignants_form(context, REQUEST, moduleimpl_id):
@scodoc7func
def edit_enseignants_form(REQUEST, moduleimpl_id):
"modif liste enseignants/moduleimpl"
M, sem = sco_moduleimpl.can_change_ens(REQUEST, moduleimpl_id)
# --
@ -788,8 +779,8 @@ def edit_enseignants_form(context, REQUEST, moduleimpl_id):
@bp.route("/edit_moduleimpl_resp", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
@scodoc7func
def edit_moduleimpl_resp(REQUEST, moduleimpl_id):
"""Changement d'un enseignant responsable de module
Accessible par Admin et dir des etud si flag resp_can_change_ens
"""
@ -894,8 +885,8 @@ _EXPR_HELP = """<p class="help">Expérimental: formule de calcul de la moyenne %
@bp.route("/edit_moduleimpl_expr", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
@scodoc7func
def edit_moduleimpl_expr(REQUEST, moduleimpl_id):
"""Edition formule calcul moyenne module
Accessible par Admin, dir des etud et responsable module
"""
@ -961,8 +952,8 @@ def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
@bp.route("/view_module_abs")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
@scodoc7func
def view_module_abs(REQUEST, moduleimpl_id, format="html"):
"""Visualisation des absences a un module"""
M = sco_moduleimpl.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
@ -1039,8 +1030,8 @@ def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
@bp.route("/edit_ue_expr", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
@scodoc7func
def edit_ue_expr(REQUEST, formsemestre_id, ue_id):
"""Edition formule calcul moyenne UE"""
# Check access
sem = sco_formsemestre_edit.can_edit_sem(REQUEST, formsemestre_id)
@ -1113,8 +1104,8 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
@bp.route("/formsemestre_enseignants_list")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_enseignants_list(context, REQUEST, formsemestre_id, format="html"):
@scodoc7func
def formsemestre_enseignants_list(REQUEST, formsemestre_id, format="html"):
"""Liste les enseignants intervenants dans le semestre (resp. modules et chargés de TD)
et indique les absences saisies par chacun.
"""
@ -1204,8 +1195,8 @@ def formsemestre_enseignants_list(context, REQUEST, formsemestre_id, format="htm
@bp.route("/edit_enseignants_form_delete", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def edit_enseignants_form_delete(context, REQUEST, moduleimpl_id, ens_id: int):
@scodoc7func
def edit_enseignants_form_delete(REQUEST, moduleimpl_id, ens_id: int):
"""remove ens from this modueimpl
ens_id: user.id
@ -1253,7 +1244,7 @@ sco_publish(
@bp.route("/do_formsemestre_inscription_listinscrits")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def do_formsemestre_inscription_listinscrits(
formsemestre_id, format=None, REQUEST=None
):
@ -1267,9 +1258,9 @@ def do_formsemestre_inscription_listinscrits(
@bp.route("/formsemestre_desinscription")
@scodoc
@permission_required(Permission.ScoImplement)
@scodoc7func(context)
@scodoc7func
def formsemestre_desinscription(
context, etudid, formsemestre_id, REQUEST=None, dialog_confirmed=False
etudid, formsemestre_id, REQUEST=None, dialog_confirmed=False
):
"""desinscrit l'etudiant de ce semestre (et donc de tous les modules).
A n'utiliser qu'en cas d'erreur de saisie.
@ -1333,7 +1324,7 @@ def formsemestre_desinscription(
)
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
context, etudid, formsemestre_id, REQUEST=REQUEST
etudid, formsemestre_id, REQUEST=REQUEST
)
return (
@ -1354,11 +1345,11 @@ sco_publish(
@bp.route("/etud_desinscrit_ue")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
@scodoc7func
def etud_desinscrit_ue(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Desinscrit l'etudiant de tous les modules de cette UE dans ce semestre."""
sco_moduleimpl_inscriptions.do_etud_desinscrit_ue(
context, etudid, formsemestre_id, ue_id, REQUEST=REQUEST
etudid, formsemestre_id, ue_id, REQUEST=REQUEST
)
return flask.redirect(
scu.ScoURL()
@ -1370,11 +1361,11 @@ def etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
@bp.route("/etud_inscrit_ue")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
@scodoc7func
def etud_inscrit_ue(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Inscrit l'etudiant de tous les modules de cette UE dans ce semestre."""
sco_moduleimpl_inscriptions.do_etud_inscrit_ue(
context, etudid, formsemestre_id, ue_id, REQUEST=REQUEST
etudid, formsemestre_id, ue_id, REQUEST=REQUEST
)
return flask.redirect(
scu.ScoURL()
@ -1434,8 +1425,8 @@ sco_publish(
@bp.route("/evaluation_delete", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEnsView)
@scodoc7func(context)
def evaluation_delete(context, REQUEST, evaluation_id):
@scodoc7func
def evaluation_delete(REQUEST, evaluation_id):
"""Form delete evaluation"""
El = sco_evaluations.do_evaluation_list(args={"evaluation_id": evaluation_id})
if not El:
@ -1518,7 +1509,7 @@ sco_publish(
@bp.route("/evaluation_edit", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEnsView)
@scodoc7func(context)
@scodoc7func
def evaluation_edit(evaluation_id, REQUEST):
"form edit evaluation"
return sco_evaluations.evaluation_create_form(
@ -1529,7 +1520,7 @@ def evaluation_edit(evaluation_id, REQUEST):
@bp.route("/evaluation_create", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEnsView)
@scodoc7func(context)
@scodoc7func
def evaluation_create(moduleimpl_id, REQUEST):
"form create evaluation"
return sco_evaluations.evaluation_create_form(
@ -1540,8 +1531,8 @@ def evaluation_create(moduleimpl_id, REQUEST):
@bp.route("/evaluation_listenotes")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def evaluation_listenotes(context, REQUEST=None):
@scodoc7func
def evaluation_listenotes(REQUEST=None):
"""Affichage des notes d'une évaluation"""
if REQUEST.form.get("format", "html") == "html":
H = html_sco_header.sco_header(
@ -1552,7 +1543,7 @@ def evaluation_listenotes(context, REQUEST=None):
F = html_sco_header.sco_footer()
else:
H, F = "", ""
B = sco_liste_notes.do_evaluation_listenotes(context, REQUEST)
B = sco_liste_notes.do_evaluation_listenotes(REQUEST)
return H + B + F
@ -1622,13 +1613,11 @@ sco_publish(
@bp.route("/formsemestre_bulletins_pdf")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version="selectedevals"
):
@scodoc7func
def formsemestre_bulletins_pdf(formsemestre_id, REQUEST, version="selectedevals"):
"Publie les bulletins dans un classeur PDF"
pdfdoc, filename = sco_bulletins_pdf.get_formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version=version
formsemestre_id, REQUEST, version=version
)
return scu.sendPDFFile(REQUEST, pdfdoc, filename)
@ -1639,16 +1628,15 @@ _EXPL_BULL = """Versions des bulletins:<ul><li><bf>courte</bf>: moyennes des mod
@bp.route("/formsemestre_bulletins_pdf_choice")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_bulletins_pdf_choice(context, REQUEST, formsemestre_id, version=None):
@scodoc7func
def formsemestre_bulletins_pdf_choice(REQUEST, formsemestre_id, version=None):
"""Choix version puis envois classeur bulletins pdf"""
if version:
pdfdoc, filename = sco_bulletins_pdf.get_formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version=version
formsemestre_id, REQUEST, version=version
)
return scu.sendPDFFile(REQUEST, pdfdoc, filename)
return formsemestre_bulletins_choice(
context,
REQUEST,
formsemestre_id,
title="Choisir la version des bulletins à générer",
@ -1659,11 +1647,11 @@ def formsemestre_bulletins_pdf_choice(context, REQUEST, formsemestre_id, version
@bp.route("/etud_bulletins_pdf")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
@scodoc7func
def etud_bulletins_pdf(etudid, REQUEST, version="selectedevals"):
"Publie tous les bulletins d'un etudiants dans un classeur PDF"
pdfdoc, filename = sco_bulletins_pdf.get_etud_bulletins_pdf(
context, etudid, REQUEST, version=version
etudid, REQUEST, version=version
)
return scu.sendPDFFile(REQUEST, pdfdoc, filename)
@ -1671,28 +1659,30 @@ def etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
@bp.route("/formsemestre_bulletins_mailetuds_choice")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_bulletins_mailetuds_choice(
context,
REQUEST,
formsemestre_id,
version=None,
dialog_confirmed=False,
prefer_mail_perso=0,
):
"""Choix version puis envois classeur bulletins pdf"""
"""Choix version puis envoi classeur bulletins pdf"""
if version:
# XXX devrait plutôt utiliser un redirect #sco8
return context.formsemestre_bulletins_mailetuds(
formsemestre_id,
REQUEST,
version=version,
dialog_confirmed=dialog_confirmed,
prefer_mail_perso=prefer_mail_perso,
# XXX à tester
return flask.redirect(
url_for(
"notes.formsemestre_bulletins_mailetuds",
scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id,
version=version,
dialog_confirmed=dialog_confirmed,
prefer_mail_perso=prefer_mail_perso,
)
)
expl_bull = """Versions des bulletins:<ul><li><bf>courte</bf>: moyennes des modules</li><li><bf>intermédiaire</bf>: moyennes des modules et notes des évaluations sélectionnées</li><li><bf>complète</bf>: toutes les notes</li><ul>"""
return formsemestre_bulletins_choice(
context,
REQUEST,
formsemestre_id,
title="Choisir la version des bulletins à envoyer par mail",
@ -1704,7 +1694,7 @@ def formsemestre_bulletins_mailetuds_choice(
# not published
def formsemestre_bulletins_choice(
context, REQUEST, formsemestre_id, title="", explanation="", choose_mail=False
REQUEST, formsemestre_id, title="", explanation="", choose_mail=False
):
"""Choix d'une version de bulletin"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
@ -1738,9 +1728,8 @@ def formsemestre_bulletins_choice(
@bp.route("/formsemestre_bulletins_mailetuds")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_bulletins_mailetuds(
context,
formsemestre_id,
REQUEST,
version="long",
@ -1771,7 +1760,6 @@ def formsemestre_bulletins_mailetuds(
nb_send = 0
for etudid in etudids:
h, _ = sco_bulletins.do_formsemestre_bulletinetud(
context,
formsemestre_id,
etudid,
version=version,
@ -1802,9 +1790,8 @@ sco_publish(
@bp.route("/appreciation_add_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEnsView)
@scodoc7func(context)
@scodoc7func
def appreciation_add_form(
context,
etudid=None,
formsemestre_id=None,
id=None, # si id, edit
@ -1912,9 +1899,8 @@ def appreciation_add_form(
@bp.route("/formsemestre_validation_etud_form")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_validation_etud_form(
context,
formsemestre_id,
etudid=None,
etud_index=None,
@ -1926,7 +1912,6 @@ def formsemestre_validation_etud_form(
"Formulaire choix jury pour un étudiant"
readonly = not sco_permissions_check.can_validate_sem(formsemestre_id)
return sco_formsemestre_validation.formsemestre_validation_etud_form(
context,
formsemestre_id,
etudid=etudid,
etud_index=etud_index,
@ -1941,9 +1926,8 @@ def formsemestre_validation_etud_form(
@bp.route("/formsemestre_validation_etud")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_validation_etud(
context,
formsemestre_id,
etudid=None,
codechoice=None,
@ -1960,7 +1944,6 @@ def formsemestre_validation_etud(
)
return sco_formsemestre_validation.formsemestre_validation_etud(
context,
formsemestre_id,
etudid=etudid,
codechoice=codechoice,
@ -1973,9 +1956,8 @@ def formsemestre_validation_etud(
@bp.route("/formsemestre_validation_etud_manu")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_validation_etud_manu(
context,
formsemestre_id,
etudid=None,
code_etat="",
@ -1995,7 +1977,6 @@ def formsemestre_validation_etud_manu(
)
return sco_formsemestre_validation.formsemestre_validation_etud_manu(
context,
formsemestre_id,
etudid=etudid,
code_etat=code_etat,
@ -2011,10 +1992,8 @@ def formsemestre_validation_etud_manu(
@bp.route("/formsemestre_validate_previous_ue")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_validate_previous_ue(
context, formsemestre_id, etudid=None, REQUEST=None
):
@scodoc7func
def formsemestre_validate_previous_ue(formsemestre_id, etudid=None, REQUEST=None):
"Form. saisie UE validée hors ScoDoc"
if not sco_permissions_check.can_validate_sem(formsemestre_id):
return scu.confirm_dialog(
@ -2023,7 +2002,7 @@ def formsemestre_validate_previous_ue(
dest_url=scu.ScoURL(),
)
return sco_formsemestre_validation.formsemestre_validate_previous_ue(
context, formsemestre_id, etudid, REQUEST=REQUEST
formsemestre_id, etudid, REQUEST=REQUEST
)
@ -2038,10 +2017,8 @@ sco_publish(
@bp.route("/formsemestre_ext_edit_ue_validations", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_ext_edit_ue_validations(
context, formsemestre_id, etudid=None, REQUEST=None
):
@scodoc7func
def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid=None, REQUEST=None):
"Form. edition UE semestre extérieur"
if not sco_permissions_check.can_validate_sem(formsemestre_id):
return scu.confirm_dialog(
@ -2050,7 +2027,7 @@ def formsemestre_ext_edit_ue_validations(
dest_url=scu.ScoURL(),
)
return sco_formsemestre_exterieurs.formsemestre_ext_edit_ue_validations(
context, formsemestre_id, etudid, REQUEST=REQUEST
formsemestre_id, etudid, REQUEST=REQUEST
)
@ -2064,8 +2041,8 @@ sco_publish(
@bp.route("/etud_ue_suppress_validation")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None):
@scodoc7func
def etud_ue_suppress_validation(etudid, formsemestre_id, ue_id, REQUEST=None):
"""Suppress a validation (ue_id, etudid) and redirect to formsemestre"""
if not sco_permissions_check.can_validate_sem(formsemestre_id):
return scu.confirm_dialog(
@ -2074,15 +2051,15 @@ def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST
dest_url=scu.ScoURL(),
)
return sco_formsemestre_validation.etud_ue_suppress_validation(
context, etudid, formsemestre_id, ue_id, REQUEST=REQUEST
etudid, formsemestre_id, ue_id, REQUEST=REQUEST
)
@bp.route("/formsemestre_validation_auto")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
@scodoc7func
def formsemestre_validation_auto(formsemestre_id, REQUEST):
"Formulaire saisie automatisee des decisions d'un semestre"
if not sco_permissions_check.can_validate_sem(formsemestre_id):
return scu.confirm_dialog(
@ -2092,15 +2069,15 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
)
return sco_formsemestre_validation.formsemestre_validation_auto(
context, formsemestre_id, REQUEST
formsemestre_id, REQUEST
)
@bp.route("/do_formsemestre_validation_auto")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
@scodoc7func
def do_formsemestre_validation_auto(formsemestre_id, REQUEST):
"Formulaire saisie automatisee des decisions d'un semestre"
if not sco_permissions_check.can_validate_sem(formsemestre_id):
return scu.confirm_dialog(
@ -2110,16 +2087,16 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
)
return sco_formsemestre_validation.do_formsemestre_validation_auto(
context, formsemestre_id, REQUEST
formsemestre_id, REQUEST
)
@bp.route("/formsemestre_validation_suppress_etud", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def formsemestre_validation_suppress_etud(
context, formsemestre_id, etudid, REQUEST=None, dialog_confirmed=False
formsemestre_id, etudid, REQUEST=None, dialog_confirmed=False
):
"""Suppression des decisions de jury pour un etudiant."""
if not sco_permissions_check.can_validate_sem(formsemestre_id):
@ -2159,7 +2136,7 @@ def formsemestre_validation_suppress_etud(
)
sco_formsemestre_validation.formsemestre_validation_suppress_etud(
context, formsemestre_id, etudid
formsemestre_id, etudid
)
return flask.redirect(
scu.ScoURL()
@ -2358,8 +2335,8 @@ sco_publish(
@bp.route("/check_sem_integrity")
@scodoc
@permission_required(Permission.ScoImplement)
@scodoc7func(context)
def check_sem_integrity(context, formsemestre_id, REQUEST, fix=False):
@scodoc7func
def check_sem_integrity(formsemestre_id, REQUEST, fix=False):
"""Debug.
Check that ue and module formations are consistents
"""
@ -2427,8 +2404,8 @@ def check_sem_integrity(context, formsemestre_id, REQUEST, fix=False):
@bp.route("/check_form_integrity")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
@scodoc7func
def check_form_integrity(formation_id, fix=False, REQUEST=None):
"debug"
log("check_form_integrity: formation_id=%s fix=%s" % (formation_id, fix))
ues = sco_edit_ue.do_ue_list(args={"formation_id": formation_id})
@ -2455,7 +2432,7 @@ def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
log("check_form_integrity: formation_id=%s\ninconsistencies:" % formation_id)
log(txt)
# Notify by e-mail
sendAlarm(context, "Notes: formation incoherente !", txt)
sendAlarm("Notes: formation incoherente !", txt)
else:
txth = "OK"
log("ok")
@ -2465,8 +2442,8 @@ def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
@bp.route("/check_formsemestre_integrity")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
@scodoc7func
def check_formsemestre_integrity(formsemestre_id, REQUEST=None):
"debug"
log("check_formsemestre_integrity: formsemestre_id=%s" % (formsemestre_id))
# verifie que tous les moduleimpl d'un formsemestre
@ -2499,7 +2476,6 @@ def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
)
if diag:
sendAlarm(
context,
"Notes: formation incoherente dans semestre %s !" % formsemestre_id,
"\n".join(diag),
)
@ -2516,15 +2492,15 @@ def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
@bp.route("/check_integrity_all")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def check_integrity_all(context, REQUEST=None):
@scodoc7func
def check_integrity_all(REQUEST=None):
"debug: verifie tous les semestres et tt les formations"
# formations
for F in sco_formations.formation_list():
check_form_integrity(context, F["formation_id"], REQUEST=REQUEST)
check_form_integrity(F["formation_id"], REQUEST=REQUEST)
# semestres
for sem in sco_formsemestre.do_formsemestre_list():
check_formsemestre_integrity(context, sem["formsemestre_id"], REQUEST=REQUEST)
check_formsemestre_integrity(sem["formsemestre_id"], REQUEST=REQUEST)
return (
html_sco_header.sco_header()
+ "<p>empty page: see logs and mails</p>"
@ -2543,5 +2519,3 @@ sco_publish(
sco_moduleimpl.do_moduleimpl_withmodule_list,
Permission.ScoView,
)
context.populate(globals())

View File

@ -49,7 +49,6 @@ from config import Config
from app.decorators import (
scodoc,
scodoc7func,
ScoDoc7Context,
permission_required,
admin_required,
login_required,
@ -112,15 +111,12 @@ from app.scodoc import sco_up_to_date
from app.scodoc import sco_etud
context = ScoDoc7Context("scolar")
def sco_publish(route, function, permission, methods=["GET"]):
"""Declare a route for a python function,
protected by permission and called following ScoDoc 7 Zope standards.
"""
return bp.route(route, methods=methods)(
scodoc(permission_required(permission)(scodoc7func(context)(function)))
scodoc(permission_required(permission)(scodoc7func(function)))
)
@ -137,8 +133,8 @@ log("ScoDoc8 restarting...")
@bp.route("/about")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def about(context, REQUEST):
@scodoc7func
def about(REQUEST):
"version info"
H = [
"""<h2>Système de gestion scolarité</h2>
@ -172,8 +168,8 @@ def about(context, REQUEST):
@bp.route("/edit_preferences", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoChangePreferences)
@scodoc7func(context)
def edit_preferences(context, REQUEST):
@scodoc7func
def edit_preferences(REQUEST):
"""Edit global preferences (lien "Paramétrage" département)"""
return sco_preferences.get_base_preferences().edit(REQUEST=REQUEST)
@ -181,8 +177,8 @@ def edit_preferences(context, REQUEST):
@bp.route("/formsemestre_edit_preferences", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
@scodoc7func
def formsemestre_edit_preferences(formsemestre_id, REQUEST):
"""Edit preferences for a semestre"""
authuser = REQUEST.AUTHENTICATED_USER
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
@ -201,7 +197,7 @@ def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
@bp.route("/doc_preferences")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def doc_preferences(REQUEST):
"""List preferences for wiki documentation"""
REQUEST.RESPONSE.setHeader("content-type", "text/plain")
@ -218,12 +214,12 @@ def doc_preferences(REQUEST):
@bp.route("/showEtudLog")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def showEtudLog(context, etudid, format="html", REQUEST=None):
@scodoc7func
def showEtudLog(etudid, format="html", REQUEST=None):
"""Display log of operations on this student"""
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
ops = sco_etud.list_scolog(context, etudid)
ops = sco_etud.list_scolog(etudid)
tab = GenTable(
titles={
@ -257,8 +253,8 @@ def showEtudLog(context, etudid, format="html", REQUEST=None):
@bp.route("/kimo")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def kimo(context, REQUEST=None, showcodes=0, showsemtable=0):
@scodoc7func
def kimo(REQUEST=None, showcodes=0, showsemtable=0):
import time
return f"{time.time()} := {g.scodoc_dept}"
@ -268,10 +264,10 @@ def kimo(context, REQUEST=None, showcodes=0, showsemtable=0):
@bp.route("/index_html")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
@scodoc7func
def index_html(REQUEST=None, showcodes=0, showsemtable=0):
return sco_dept.index_html(
context, REQUEST=REQUEST, showcodes=showcodes, showsemtable=showsemtable
REQUEST=REQUEST, showcodes=showcodes, showsemtable=showsemtable
)
@ -306,10 +302,8 @@ sco_publish(
@bp.route("/getEtudInfo")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def getEtudInfo(
context, etudid=False, code_nip=False, filled=False, REQUEST=None, format=None
):
@scodoc7func
def getEtudInfo(etudid=False, code_nip=False, filled=False, REQUEST=None, format=None):
"""infos sur un etudiant (API)
On peut specifier etudid ou code_nip
ou bien cherche dans REQUEST.form: etudid, code_nip, code_ine
@ -341,8 +335,8 @@ sco_publish(
@bp.route("/XMLgetEtudInfos")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def etud_info(context, etudid=None, format="xml", REQUEST=None):
@scodoc7func
def etud_info(etudid=None, format="xml", REQUEST=None):
"Donne les informations sur un etudiant"
t0 = time.time()
args = sco_etud.make_etud_args(etudid=etudid, REQUEST=REQUEST)
@ -399,7 +393,7 @@ def etud_info(context, etudid=None, format="xml", REQUEST=None):
etud["civilite_str"]
) # exception: ne sort pas la civilite brute
d["sexe"] = d["civilite"] # backward compat pour anciens clients
d["photo_url"] = scu.quote_xml_attr(sco_photos.etud_photo_url(context, etud))
d["photo_url"] = scu.quote_xml_attr(sco_photos.etud_photo_url(etud))
sem = etud["cursem"]
if sem:
@ -515,7 +509,7 @@ sco_publish(
@bp.route("/doAddAnnotation", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudAddAnnotations)
@scodoc7func(context)
@scodoc7func
def doAddAnnotation(etudid, comment):
"ajoute annotation sur etudiant"
cnx = ndb.GetDBConnexion()
@ -536,8 +530,8 @@ def doAddAnnotation(etudid, comment):
@bp.route("/doSuppressAnnotation", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def doSuppressAnnotation(context, etudid, annotation_id, REQUEST):
@scodoc7func
def doSuppressAnnotation(etudid, annotation_id, REQUEST):
"""Suppression annotation."""
if not sco_permissions_check.can_suppress_annotation(annotation_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
@ -564,8 +558,8 @@ def doSuppressAnnotation(context, etudid, annotation_id, REQUEST):
@bp.route("/formChangeCoordonnees", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudChangeAdr)
@scodoc7func(context)
def formChangeCoordonnees(context, etudid, REQUEST):
@scodoc7func
def formChangeCoordonnees(etudid, REQUEST):
"edit coordonnees etudiant"
cnx = ndb.GetDBConnexion()
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
@ -625,7 +619,7 @@ def formChangeCoordonnees(context, etudid, REQUEST):
return flask.redirect(dest_url)
else:
if adrs:
sco_etud.adresse_edit(cnx, args=tf[2], context=context)
sco_etud.adresse_edit(cnx, args=tf[2])
else:
sco_etud.adresse_create(cnx, args=tf[2])
logdb(cnx, method="changeCoordonnees", etudid=etudid)
@ -728,9 +722,9 @@ sco_publish(
# @bp.route("/partition_create", methods=["GET", "POST"])
# @scodoc
# @permission_required(Permission.ScoView)
# @scodoc7func(context)
# @scodoc7func
# def partition_create(
# context,
#
# formsemestre_id,
# partition_name="",
# default=False,
@ -750,8 +744,8 @@ sco_publish("/etud_photo_html", sco_photos.etud_photo_html, Permission.ScoView)
@bp.route("/etud_photo_orig_page")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def etud_photo_orig_page(context, etudid=None, REQUEST=None):
@scodoc7func
def etud_photo_orig_page(etudid=None, REQUEST=None):
"Page with photo in orig. size"
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
H = [
@ -759,7 +753,7 @@ def etud_photo_orig_page(context, etudid=None, REQUEST=None):
"<h2>%s</h2>" % etud["nomprenom"],
'<div><a href="%s">'
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
sco_photos.etud_photo_orig_html(context, etud),
sco_photos.etud_photo_orig_html(etud),
"</a></div>",
html_sco_header.sco_footer(),
]
@ -769,11 +763,11 @@ def etud_photo_orig_page(context, etudid=None, REQUEST=None):
@bp.route("/formChangePhoto", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudChangeAdr)
@scodoc7func(context)
def formChangePhoto(context, etudid=None, REQUEST=None):
@scodoc7func
def formChangePhoto(etudid=None, REQUEST=None):
"""Formulaire changement photo étudiant"""
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
if sco_photos.etud_photo_is_local(context, etud):
if sco_photos.etud_photo_is_local(etud):
etud["photoloc"] = "dans ScoDoc"
else:
etud["photoloc"] = "externe"
@ -783,9 +777,7 @@ def formChangePhoto(context, etudid=None, REQUEST=None):
<p>Photo actuelle (%(photoloc)s):
"""
% etud,
sco_photos.etud_photo_html(
context, etud, title="photo actuelle", REQUEST=REQUEST
),
sco_photos.etud_photo_html(etud, title="photo actuelle", REQUEST=REQUEST),
"""</p><p>Le fichier ne doit pas dépasser 500Ko (recadrer l'image, format "portrait" de préférence).</p>
<p>L'image sera automagiquement réduite pour obtenir une hauteur de 90 pixels.</p>
""",
@ -818,7 +810,7 @@ def formChangePhoto(context, etudid=None, REQUEST=None):
return flask.redirect(dest_url)
else:
data = tf[2]["photofile"].read()
status, diag = sco_photos.store_photo(context, etud, data, REQUEST=REQUEST)
status, diag = sco_photos.store_photo(etud, data)
if status != 0:
return flask.redirect(dest_url)
else:
@ -829,8 +821,8 @@ def formChangePhoto(context, etudid=None, REQUEST=None):
@bp.route("/formSuppressPhoto")
@scodoc
@permission_required(Permission.ScoEtudChangeAdr)
@scodoc7func(context)
def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False):
@scodoc7func
def formSuppressPhoto(etudid=None, REQUEST=None, dialog_confirmed=False):
"""Formulaire suppression photo étudiant"""
etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
if not dialog_confirmed:
@ -843,7 +835,7 @@ def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False
parameters={"etudid": etudid},
)
sco_photos.suppress_photo(context, etud, REQUEST=REQUEST)
sco_photos.suppress_photo(etud, REQUEST=REQUEST)
return flask.redirect(
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
@ -854,11 +846,10 @@ def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False
@bp.route("/formDem")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def formDem(context, etudid, formsemestre_id, REQUEST):
@scodoc7func
def formDem(etudid, formsemestre_id, REQUEST):
"Formulaire Démission Etudiant"
return _formDem_of_Def(
context,
etudid,
formsemestre_id,
REQUEST=REQUEST,
@ -870,11 +861,10 @@ def formDem(context, etudid, formsemestre_id, REQUEST):
@bp.route("/formDef")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def formDef(context, etudid, formsemestre_id, REQUEST):
@scodoc7func
def formDef(etudid, formsemestre_id, REQUEST):
"Formulaire Défaillance Etudiant"
return _formDem_of_Def(
context,
etudid,
formsemestre_id,
REQUEST=REQUEST,
@ -884,7 +874,6 @@ def formDef(context, etudid, formsemestre_id, REQUEST):
def _formDem_of_Def(
context,
etudid,
formsemestre_id,
REQUEST=None,
@ -914,7 +903,7 @@ def _formDem_of_Def(
"""<form action="%s" method="get">
<b>Date de la %s (J/M/AAAA):&nbsp;</b>
"""
% (operation_method, scu.strlower(operation_name))
% (operation_method, operation_name.lower())
)
H.append(
"""
@ -932,11 +921,10 @@ def _formDem_of_Def(
@bp.route("/doDemEtudiant")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
@scodoc7func
def doDemEtudiant(etudid, formsemestre_id, event_date=None, REQUEST=None):
"Déclare la démission d'un etudiant dans le semestre"
return _do_dem_or_def_etud(
context,
etudid,
formsemestre_id,
event_date=event_date,
@ -950,11 +938,10 @@ def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=Non
@bp.route("/doDefEtudiant")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def doDefEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
@scodoc7func
def doDefEtudiant(etudid, formsemestre_id, event_date=None, REQUEST=None):
"Déclare la défaillance d'un etudiant dans le semestre"
return _do_dem_or_def_etud(
context,
etudid,
formsemestre_id,
event_date=event_date,
@ -966,7 +953,6 @@ def doDefEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=Non
def _do_dem_or_def_etud(
context,
etudid,
formsemestre_id,
event_date=None,
@ -991,7 +977,7 @@ def _do_dem_or_def_etud(
raise ScoException("etudiant non inscrit ?!")
ins["etat"] = etat_new
sco_formsemestre_inscriptions.do_formsemestre_inscription_edit(
context, args=ins, formsemestre_id=formsemestre_id
args=ins, formsemestre_id=formsemestre_id
)
logdb(cnx, method=operation_method, etudid=etudid)
sco_etud.scolar_events_create(
@ -1012,13 +998,12 @@ def _do_dem_or_def_etud(
@bp.route("/doCancelDem", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
@scodoc7func
def doCancelDem(
context, etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
):
"Annule une démission"
return _do_cancel_dem_or_def(
context,
etudid,
formsemestre_id,
dialog_confirmed=dialog_confirmed,
@ -1035,13 +1020,12 @@ def doCancelDem(
@bp.route("/doCancelDef", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
@scodoc7func
def doCancelDef(
context, etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
etudid, formsemestre_id, dialog_confirmed=False, args=None, REQUEST=None
):
"Annule la défaillance de l'étudiant"
return _do_cancel_dem_or_def(
context,
etudid,
formsemestre_id,
dialog_confirmed=dialog_confirmed,
@ -1056,7 +1040,6 @@ def doCancelDef(
def _do_cancel_dem_or_def(
context,
etudid,
formsemestre_id,
dialog_confirmed=False,
@ -1102,7 +1085,7 @@ def _do_cancel_dem_or_def(
ins["etat"] = etat_new
cnx = ndb.GetDBConnexion()
sco_formsemestre_inscriptions.do_formsemestre_inscription_edit(
context, args=ins, formsemestre_id=formsemestre_id
args=ins, formsemestre_id=formsemestre_id
)
logdb(cnx, method=operation_method, etudid=etudid)
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -1121,22 +1104,22 @@ def _do_cancel_dem_or_def(
@bp.route("/etudident_create_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def etudident_create_form(context, REQUEST=None):
@scodoc7func
def etudident_create_form(REQUEST=None):
"formulaire creation individuelle etudiant"
return _etudident_create_or_edit_form(context, REQUEST, edit=False)
return _etudident_create_or_edit_form(REQUEST, edit=False)
@bp.route("/etudident_edit_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def etudident_edit_form(context, REQUEST=None):
@scodoc7func
def etudident_edit_form(REQUEST=None):
"formulaire edition individuelle etudiant"
return _etudident_create_or_edit_form(context, REQUEST, edit=True)
return _etudident_create_or_edit_form(REQUEST, edit=True)
def _etudident_create_or_edit_form(context, REQUEST, edit):
def _etudident_create_or_edit_form(REQUEST, edit):
"Le formulaire HTML"
H = [html_sco_header.sco_header(init_jquery_ui=True)]
F = html_sco_header.sco_footer()
@ -1517,11 +1500,11 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
)
if not edit:
etud = sco_etud.create_etud(context, cnx, args=tf[2], REQUEST=REQUEST)
etud = sco_etud.create_etud(cnx, args=tf[2], REQUEST=REQUEST)
etudid = etud["etudid"]
else:
# modif d'un etudiant
sco_etud.etudident_edit(cnx, tf[2], context=context, REQUEST=REQUEST)
sco_etud.etudident_edit(cnx, tf[2], REQUEST=REQUEST)
etud = sco_etud.etudident_list(cnx, {"etudid": etudid})[0]
sco_etud.fill_etuds_info([etud])
# Inval semesters with this student:
@ -1537,8 +1520,8 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
@bp.route("/etudident_delete", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
@scodoc7func
def etudident_delete(etudid, dialog_confirmed=False, REQUEST=None):
"Delete a student"
cnx = ndb.GetDBConnexion()
etuds = sco_etud.etudident_list(cnx, {"etudid": etudid})
@ -1610,10 +1593,8 @@ def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
@bp.route("/check_group_apogee")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def check_group_apogee(
context, group_id, REQUEST=None, etat=None, fix=False, fixmail=False
):
@scodoc7func
def check_group_apogee(group_id, REQUEST=None, etat=None, fix=False, fixmail=False):
"""Verification des codes Apogee et mail de tout un groupe.
Si fix == True, change les codes avec Apogée.
@ -1661,7 +1642,6 @@ def check_group_apogee(
sco_etud.identite_edit(
cnx,
args={"etudid": etudid, "code_nip": nip_apogee},
context=context,
)
info_apogee = (
'<span style="color:green">copié %s</span>' % nip_apogee
@ -1688,7 +1668,7 @@ def check_group_apogee(
if adrs:
adr = adrs[0] # modif adr existante
args = {"adresse_id": adr["adresse_id"], "email": mail_apogee}
sco_etud.adresse_edit(cnx, args=args)
sco_etud.adresse_edit(cnx, args=args, disable_notify=True)
else:
# creation adresse
args = {"etudid": etudid, "email": mail_apogee}
@ -1761,8 +1741,8 @@ def check_group_apogee(
@bp.route("/form_students_import_excel", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def form_students_import_excel(context, REQUEST, formsemestre_id=None):
@scodoc7func
def form_students_import_excel(REQUEST, formsemestre_id=None):
"formulaire import xls"
if formsemestre_id:
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
@ -1895,7 +1875,6 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
return flask.redirect(dest_url)
else:
return sco_import_etuds.students_import_excel(
context,
tf[2]["csvfile"],
REQUEST=REQUEST,
formsemestre_id=formsemestre_id,
@ -1907,8 +1886,8 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
@bp.route("/import_generate_excel_sample")
@scodoc
@permission_required(Permission.ScoEtudInscrit)
@scodoc7func(context)
def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
@scodoc7func
def import_generate_excel_sample(REQUEST, with_codesemestre="1"):
"une feuille excel pour importation etudiants"
if with_codesemestre:
with_codesemestre = int(with_codesemestre)
@ -1916,7 +1895,7 @@ def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
with_codesemestre = 0
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
format, with_codesemestre, exclude_cols=["photo_filename"]
)
return sco_excel.send_excel_file(REQUEST, data, "ImportEtudiants" + scu.XLSX_SUFFIX)
@ -1925,8 +1904,8 @@ def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
@bp.route("/import_generate_admission_sample")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def import_generate_admission_sample(context, REQUEST, formsemestre_id):
@scodoc7func
def import_generate_admission_sample(REQUEST, formsemestre_id):
"une feuille excel pour importation données admissions"
group = sco_groups.get_group(sco_groups.get_default_group(formsemestre_id))
fmt = sco_import_etuds.sco_import_format()
@ -1935,8 +1914,6 @@ def import_generate_admission_sample(context, REQUEST, formsemestre_id):
only_tables=["identite", "admissions", "adresse"],
exclude_cols=["nationalite", "foto", "photo_filename"],
group_ids=[group["group_id"]],
context=context,
REQUEST=REQUEST,
)
return sco_excel.send_excel_file(
REQUEST, data, "AdmissionEtudiants" + scu.XLSX_SUFFIX
@ -1947,8 +1924,8 @@ def import_generate_admission_sample(context, REQUEST, formsemestre_id):
@bp.route("/form_students_import_infos_admissions", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None):
@scodoc7func
def form_students_import_infos_admissions(REQUEST, formsemestre_id=None):
"formulaire import xls"
authuser = REQUEST.AUTHENTICATED_USER
F = html_sco_header.sco_footer()
@ -2030,7 +2007,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">
"""
+ sco_import_etuds.adm_table_description_format(context).html()
+ sco_import_etuds.adm_table_description_format().html()
+ """</div>"""
)
@ -2044,7 +2021,6 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
)
else:
return sco_import_etuds.students_import_admission(
context,
tf[2]["csvfile"],
type_admission=tf[2]["type_admission"],
REQUEST=REQUEST,
@ -2055,9 +2031,9 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
@bp.route("/formsemestre_import_etud_admission")
@scodoc
@permission_required(Permission.ScoEtudChangeAdr)
@scodoc7func(context)
@scodoc7func
def formsemestre_import_etud_admission(
context, formsemestre_id, import_email=True, REQUEST=None
formsemestre_id, import_email=True, REQUEST=None
):
"""Reimporte donnees admissions par synchro Portail Apogée"""
(
@ -2065,7 +2041,7 @@ def formsemestre_import_etud_admission(
unknowns,
changed_mails,
) = sco_synchro_etuds.formsemestre_import_etud_admission(
context, formsemestre_id, import_identite=True, import_email=import_email
formsemestre_id, import_identite=True, import_email=import_email
)
H = [
html_sco_header.html_sem_header(REQUEST, "Reimport données admission"),
@ -2105,8 +2081,8 @@ sco_publish(
@bp.route("/stat_bac")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
def stat_bac(context, formsemestre_id):
@scodoc7func
def stat_bac(formsemestre_id):
"Renvoie statistisques sur nb d'etudiants par bac"
cnx = ndb.GetDBConnexion()
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
@ -2124,7 +2100,3 @@ def stat_bac(context, formsemestre_id):
sco_publish(
"/sco_dump_and_send_db", sco_dump_db.sco_dump_and_send_db, Permission.ScoView
)
#
context.populate(globals())

View File

@ -51,7 +51,6 @@ from app.models import Departement
from app.decorators import (
scodoc,
scodoc7func,
ScoDoc7Context,
permission_required,
)
@ -66,17 +65,13 @@ from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.views import users_bp as bp
context = ScoDoc7Context("users") # sco8
@bp.route("/")
@bp.route("/index_html")
@scodoc
@permission_required(Permission.ScoUsersView)
@scodoc7func(context)
def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="html"):
@scodoc7func
def index_html(REQUEST, all_depts=False, with_inactives=False, format="html"):
return sco_users.index_html(
context,
REQUEST=REQUEST,
all_depts=all_depts,
with_inactives=with_inactives,
@ -87,7 +82,7 @@ def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="
@bp.route("/user_info")
@scodoc
@permission_required(Permission.ScoUsersView)
@scodoc7func(context)
@scodoc7func
def user_info(user_name, format="json", REQUEST=None):
info = sco_users.user_info(user_name=user_name)
return scu.sendResult(REQUEST, info, name="user", format=format)
@ -96,8 +91,8 @@ def user_info(user_name, format="json", REQUEST=None):
@bp.route("/create_user_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoUsersAdmin)
@scodoc7func(context)
def create_user_form(context, REQUEST, user_name=None, edit=0):
@scodoc7func
def create_user_form(REQUEST, user_name=None, edit=0):
"form. creation ou edit utilisateur"
auth_dept = current_user.dept
initvalues = {}
@ -469,15 +464,15 @@ def import_users_form():
@bp.route("/user_info_page")
@scodoc
@permission_required(Permission.ScoUsersView)
@scodoc7func(context)
@scodoc7func
def user_info_page(user_name, REQUEST=None):
return sco_users.user_info_page(context, user_name=user_name, REQUEST=REQUEST)
return sco_users.user_info_page(user_name=user_name, REQUEST=REQUEST)
@bp.route("/get_user_list_xml")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def get_user_list_xml(dept=None, start="", limit=25, REQUEST=None):
"""Returns XML list of users with name (nomplogin) starting with start.
Used for forms auto-completion."""
@ -488,7 +483,7 @@ def get_user_list_xml(dept=None, start="", limit=25, REQUEST=None):
userlist = [
user
for user in userlist
if scu.suppress_accents(scu.strlower(user.nom or "")).startswith(start)
if scu.suppress_accents((user.nom or "").lower()).startswith(start)
]
if REQUEST:
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
@ -503,7 +498,7 @@ def get_user_list_xml(dept=None, start="", limit=25, REQUEST=None):
@bp.route("/form_change_password")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def form_change_password(REQUEST, user_name=None):
"""Formulaire de changement mot de passe de l'utilisateur user_name.
Un utilisateur peut toujours changer son propre mot de passe.
@ -542,7 +537,7 @@ def form_change_password(REQUEST, user_name=None):
@bp.route("/change_password", methods=["POST"])
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func(context)
@scodoc7func
def change_password(user_name, password, password2, REQUEST):
"Change the password for user given by user_name"
u = User.query.filter_by(user_name=user_name).first()
@ -602,7 +597,7 @@ def change_password(user_name, password, password2, REQUEST):
@bp.route("/delete_user_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoUsersAdmin)
@scodoc7func(context)
@scodoc7func
def delete_user_form(REQUEST, user_name, dialog_confirmed=False):
"delete user"
u = User.query.filter_by(user_name=user_name).first()

View File

@ -82,9 +82,9 @@ rules_source_file='%s'
def _fmt(s):
if not s:
return None
if scu.strlower(s) in ("ok", "oui", "o", "y", "yes"):
if s.upper() in ("ok", "oui", "o", "y", "yes"):
return True
if scu.strlower(s) in ("no", "non"):
if s.upper() in ("no", "non"):
return False
if s == "*":
return ALL

View File

@ -34,9 +34,7 @@ Fonction renvoyant du code HTML :
import random
# La variable context est définie par le script de lancement
# l'affecte ainsi pour évietr les warnins pylint:
context = context # pylint: disable=undefined-variable
REQUEST = REQUEST # pylint: disable=undefined-variable
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
import sco_abs
@ -44,7 +42,7 @@ import sco_abs_views
import sco_abs_notification
import ZAbsences
G = sco_fake_gen.ScoFake(context.Notes)
G = sco_fake_gen.ScoFake(xxx)
G.verbose = False
# --- Création d'étudiants
@ -84,19 +82,18 @@ for etud in etuds:
# --- Création d'un groupe
_ = sco_groups.partition_create(
context.Scolarite,
formsemestre_id=sem["formsemestre_id"],
partition_name="Eleve",
REQUEST=REQUEST,
)
li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"])
_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe 1")
li1 = sco_groups.get_partitions_list(sem["formsemestre_id"])
_ = sco_groups.createGroup(li1[0]["partition_id"], "Groupe 1")
# --- Affectation des élèves dans des groupes
li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0])
li_grp1 = sco_groups.get_partition_groups(li1[0])
for etud in etuds:
sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"])
sco_groups.set_group(etud["etudid"], li_grp1[0]["group_id"])
# --- Saisie absences
etudid = etuds[0]["etudid"]
@ -108,7 +105,6 @@ for debut, fin, demijournee in [
("22/01/2021", "22/01/2021", 1),
]:
sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
@ -117,7 +113,6 @@ for debut, fin, demijournee in [
)
_ = sco_abs_views.doSignaleAbsence(
context.Absences,
"22/01/2021",
"22/01/2021",
demijournee=1,
@ -133,7 +128,6 @@ for debut, fin, demijournee in [
("19/01/2021", "19/01/2021", 2),
]:
sco_abs_views.doJustifAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
@ -236,14 +230,14 @@ assert len(li_range) == 5
# --- Annulation d'absence
# context.Absences.AnnuleAbsencesDatesNoJust(etudid, dates="22/01/2021")
# context.Absences.AnnuleAbsencesDatesNoJust( dates="22/01/2021")
# --- Fonction renvoyant du code HTML
etat_abs = context.Absences.EtatAbsences(REQUEST=REQUEST)
# cal_abs = sco_abs_views.CalAbs(context.Absences, REQUEST=REQUEST) #<--- retourne html + need etudid : how?
# cal_abs = sco_abs_views.CalAbs( REQUEST=REQUEST) #<--- retourne html + need etudid : how?
sag = context.Absences.SignaleAbsenceGrSemestre(
datedebut="15/01/2021",
@ -265,13 +259,13 @@ grp_abs_d = context.Absences.EtatAbsencesDate(
billet_form = context.Absences.AddBilletAbsenceForm(etudid=etudid, REQUEST=REQUEST)
# an_abs = AnnuleAbsenceEtud(context.Absences, REQUEST=REQUEST) #<- retourne html + need etudid : how?
# an_abs = AnnuleAbsenceEtud( REQUEST=REQUEST) #<- retourne html + need etudid : how?
# proc = context.Absences.ProcessBilletAbsenceForm(billet_id=load_li_bi[0]["billet_id"], REQUEST=REQUEST) #error
# just_form = sco_abs_views.JustifAbsenceEtud(context.Absences, REQUEST=REQUEST)
# just_form = sco_abs_views.JustifAbsenceEtud( REQUEST=REQUEST)
# delete_just = sco_abs_views.doAnnuleJustif(context.Absences, datedebut0="22/01/2021", datefin0="22/01/2021", demijournee=2, REQUEST=REQUEST)
# delete_just = sco_abs_views.doAnnuleJustif( datedebut0="22/01/2021", datefin0="22/01/2021", demijournee=2, REQUEST=REQUEST)
"""

View File

@ -277,7 +277,6 @@ assert (
assert load_li_part[0]["partition_name"] == "Eleve 1ere annee"
vue_g1 = sco_groups_view.groups_view(
context.Scolarite,
group_ids=[li_grp1[0]["group_id"]],
format="json",
REQUEST=REQUEST,
@ -304,7 +303,6 @@ for debut, fin, demijournee in [
("19/01/2021", "19/01/2021", 0),
]:
sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
@ -318,13 +316,12 @@ nb_abs = context.Absences.CountAbs(
assert nb_abs == 2
liste_abs = sco_abs_views.ListeAbsEtud(
context.Absences, etuds[0]["etudid"], format="json", REQUEST=REQUEST
etuds[0]["etudid"], format="json", REQUEST=REQUEST
)
load_liste_abs = json.loads(liste_abs)
assert len(load_liste_abs) == 2
_ = sco_abs_views.doAnnuleAbsence(
context.Absences,
"15/01/2021",
"15/01/2021",
1,

View File

@ -49,7 +49,6 @@ etudid = etud["etudid"]
# --- Création d'une absence
sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut="22/01/2021",
datefin="22/01/2021",
demijournee=2,

View File

@ -25,7 +25,7 @@ G.verbose = False
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
# Deux modalités
# sco_modalites.do_modalite_create(context, {})
# sco_modalites.do_modalite_create( {})
# --- Mise en place formation 4 semestres
form_dut, ue_list, mod_list = G.setup_formation(

View File

@ -47,7 +47,6 @@ etudid = etud["etudid"]
# --- Création d'une absence
sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut="22/01/2021",
datefin="22/01/2021",
demijournee=2,

View File

@ -51,7 +51,7 @@ G.set_etud_notes_sem(sem, eval_list, etuds)
# Bulletins
bul = sco_bulletins.formsemestre_bulletinetud_dict(
context.Notes, sem["formsemestre_id"], etuds[0]["etudid"]
sem["formsemestre_id"], etuds[0]["etudid"]
)
print(bul["moy_gen"])
assert bul["ins"][0]["etat"] == "I"
@ -61,7 +61,7 @@ context.doDemEtudiant(
etuds[0]["etudid"], sem["formsemestre_id"], event_date="15/12/2021"
)
bul = sco_bulletins.formsemestre_bulletinetud_dict(
context.Notes, sem["formsemestre_id"], etuds[0]["etudid"]
sem["formsemestre_id"], etuds[0]["etudid"]
)
print(bul["moy_gen"])

Some files were not shown because too many files have changed in this diff Show More