Massive refactoring/reorganization of imports. Work in progress.

This commit is contained in:
Emmanuel Viennet 2021-06-19 23:21:37 +02:00
parent 3e225c9fda
commit 14d329fb0f
122 changed files with 4670 additions and 6487 deletions

View File

@ -1,2 +1,6 @@
[[MESSAGES CONTROL]
# pylint and black disagree...
disable=bad-continuation
[TYPECHECK] [TYPECHECK]
ignored-classes=Permission ignored-classes=Permission

View File

@ -56,15 +56,3 @@ Installer le bon vieux `pyExcelerator` dans l'environnement:
### Méthodes qui ne devraient plus être publiées: ### Méthodes qui ne devraient plus être publiées:

View File

@ -48,14 +48,17 @@ class ZRequest(object):
self.REQUEST_METHOD = request.method.encode("utf-8") self.REQUEST_METHOD = request.method.encode("utf-8")
self.AUTHENTICATED_USER = current_user self.AUTHENTICATED_USER = current_user
if request.method == "POST": if request.method == "POST":
self.form = request.form self.form = request.form # xxx encode en utf-8 !
# Encode en utf-8 pour ScoDoc8 #sco8
self.form = {k: v.encode("utf-8") for (k, v) in request.form.items()}
if request.files: if request.files:
# Add files in form: must copy to get a mutable version # Add files in form: must copy to get a mutable version
# request.form is a werkzeug.datastructures.ImmutableMultiDict # request.form is a werkzeug.datastructures.ImmutableMultiDict
self.form = self.form.copy() # self.form = self.form.copy()
self.form.update(request.files) self.form.update(request.files)
elif request.method == "GET": elif request.method == "GET":
self.form = request.args # Encode en utf-8 pour ScoDoc8 #sco8
self.form = {k: v.encode("utf-8") for (k, v) in request.args.items()}
self.RESPONSE = ZResponse() self.RESPONSE = ZResponse()
def __str__(self): def __str__(self):
@ -157,6 +160,10 @@ def scodoc7func(context):
pos_arg_values.append(REQUEST) pos_arg_values.append(REQUEST)
elif arg_name == "context": elif arg_name == "context":
pos_arg_values.append(context) pos_arg_values.append(context)
else:
# XXX Convert to regular string for ScoDoc8/Python 2
if type(req_args[arg_name]) == types.UnicodeType:
pos_arg_values.append(req_args[arg_name].encode("utf-8"))
else: else:
pos_arg_values.append(req_args[arg_name]) pos_arg_values.append(req_args[arg_name])
current_app.logger.info("pos_arg_values=%s" % pos_arg_values) current_app.logger.info("pos_arg_values=%s" % pos_arg_values)
@ -167,6 +174,10 @@ def scodoc7func(context):
kwargs[arg_name] = REQUEST kwargs[arg_name] = REQUEST
elif arg_name in req_args: elif arg_name in req_args:
# set argument kw optionnel # set argument kw optionnel
# XXX Convert to regular string for ScoDoc8/Python 2
if type(req_args[arg_name]) == types.UnicodeType:
kwargs[arg_name] = req_args[arg_name].encode("utf-8")
else:
kwargs[arg_name] = req_args[arg_name] kwargs[arg_name] = req_args[arg_name]
current_app.logger.info( current_app.logger.info(
"scodoc7func_decorator: top_level=%s, pos_arg_values=%s, kwargs=%s" "scodoc7func_decorator: top_level=%s, pos_arg_values=%s, kwargs=%s"

View File

@ -36,12 +36,14 @@ import collections
import types import types
import re import re
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from sco_formsemestre_inscriptions import do_formsemestre_inscription_with_modules from app.scodoc.sco_formsemestre_inscriptions import (
from gen_tables import GenTable do_formsemestre_inscription_with_modules,
from sco_exceptions import ( )
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_exceptions import (
AccessDenied, AccessDenied,
FormatError, FormatError,
ScoException, ScoException,
@ -50,14 +52,14 @@ from sco_exceptions import (
ScoLockedFormError, ScoLockedFormError,
ScoGenError, ScoGenError,
) )
import html_sco_header from app.scodoc import html_sco_header
import scolars from app.scodoc import sco_etud
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_excel from app.scodoc import sco_excel
import sco_groups_view from app.scodoc import sco_groups_view
import sco_news from app.scodoc import sco_news
import sco_preferences from app.scodoc import sco_preferences
# format description (relative to Product directory)) # format description (relative to Product directory))
FORMAT_FILE = "misc/format_import_etudiants.txt" FORMAT_FILE = "misc/format_import_etudiants.txt"
@ -199,7 +201,7 @@ def sco_import_generate_excel_sample(
# rempli table avec données actuelles # rempli table avec données actuelles
lines = [] lines = []
for i in members: for i in members:
etud = scolars.get_etud_info(etudid=i["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(etudid=i["etudid"], filled=True)[0]
l = [] l = []
for field in titles: for field in titles:
if field == "groupes": if field == "groupes":
@ -371,7 +373,7 @@ def scolars_import_excel_file(
# xxx Ad-hoc checks (should be in format description) # xxx Ad-hoc checks (should be in format description)
if scu.strlower(titleslist[i]) == "sexe": if scu.strlower(titleslist[i]) == "sexe":
try: try:
val = scolars.input_civilite(val) val = sco_etud.input_civilite(val)
except: except:
raise ScoValueError( raise ScoValueError(
"valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s" "valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s"
@ -405,7 +407,7 @@ def scolars_import_excel_file(
if values["code_ine"] and not is_new_ine: if values["code_ine"] and not is_new_ine:
raise ScoValueError("Code INE dupliqué (%s)" % values["code_ine"]) raise ScoValueError("Code INE dupliqué (%s)" % values["code_ine"])
# Check nom/prenom # Check nom/prenom
ok, NbHomonyms = scolars.check_nom_prenom( ok, NbHomonyms = sco_etud.check_nom_prenom(
cnx, nom=values["nom"], prenom=values["prenom"] cnx, nom=values["nom"], prenom=values["prenom"]
) )
if not ok: if not ok:
@ -513,16 +515,16 @@ def _import_one_student(
) )
# Identite # Identite
args = values.copy() args = values.copy()
etudid = scolars.identite_create(cnx, args, context=context, REQUEST=REQUEST) etudid = sco_etud.identite_create(cnx, args, context=context, REQUEST=REQUEST)
created_etudids.append(etudid) created_etudids.append(etudid)
# Admissions # Admissions
args["etudid"] = etudid args["etudid"] = etudid
args["annee"] = annee_courante args["annee"] = annee_courante
_ = scolars.admission_create(cnx, args) _ = sco_etud.admission_create(cnx, args)
# Adresse # Adresse
args["typeadresse"] = "domicile" args["typeadresse"] = "domicile"
args["description"] = "(infos admission)" args["description"] = "(infos admission)"
_ = scolars.adresse_create(cnx, args) _ = sco_etud.adresse_create(cnx, args)
# Inscription au semestre # Inscription au semestre
args["etat"] = "I" # etat insc. semestre args["etat"] = "I" # etat insc. semestre
if formsemestre_id: if formsemestre_id:
@ -561,7 +563,7 @@ def _import_one_student(
def _is_new_ine(cnx, code_ine): def _is_new_ine(cnx, code_ine):
"True if this code is not in DB" "True if this code is not in DB"
etuds = scolars.identite_list(cnx, {"code_ine": code_ine}) etuds = sco_etud.identite_list(cnx, {"code_ine": code_ine})
return not etuds return not etuds
@ -642,7 +644,7 @@ def scolars_import_admission(
) )
else: else:
etud = etuds_by_nomprenom[(nom, prenom)] etud = etuds_by_nomprenom[(nom, prenom)]
cur_adm = scolars.admission_list(cnx, args={"etudid": etud["etudid"]})[0] cur_adm = sco_etud.admission_list(cnx, args={"etudid": etud["etudid"]})[0]
# peuple les champs presents dans le tableau # peuple les champs presents dans le tableau
args = {} args = {}
for idx in fields: for idx in fields:
@ -665,17 +667,17 @@ def scolars_import_admission(
# Type admission: traitement particulier # Type admission: traitement particulier
if not cur_adm["type_admission"] and not args.get("type_admission"): if not cur_adm["type_admission"] and not args.get("type_admission"):
args["type_admission"] = type_admission args["type_admission"] = type_admission
scolars.etudident_edit(cnx, args) sco_etud.etudident_edit(cnx, args)
adr = scolars.adresse_list(cnx, args={"etudid": etud["etudid"]}) adr = sco_etud.adresse_list(cnx, args={"etudid": etud["etudid"]})
if adr: if adr:
args["adresse_id"] = adr[0]["adresse_id"] args["adresse_id"] = adr[0]["adresse_id"]
scolars.adresse_edit( sco_etud.adresse_edit(
cnx, args cnx, args
) # ne passe pas le contexte: pas de notification ici ) # ne passe pas le contexte: pas de notification ici
else: else:
args["typeadresse"] = "domicile" args["typeadresse"] = "domicile"
args["description"] = "(infos admission)" args["description"] = "(infos admission)"
adresse_id = scolars.adresse_create(cnx, args) adresse_id = sco_etud.adresse_create(cnx, args)
# log('import_adm: %s' % args ) # log('import_adm: %s' % args )
# Change les groupes si nécessaire: # Change les groupes si nécessaire:
if args["groupes"]: if args["groupes"]:

View File

@ -485,7 +485,7 @@ class TF:
lem.append("<table>") lem.append("<table>")
for i in range(len(labels)): for i in range(len(labels)):
if input_type == "checkbox": if input_type == "checkbox":
# from notes_log import log # debug only # from app.scodoc.notes_log import log # debug only
# log('checkbox: values[%s] = "%s"' % (field,repr(values[field]) )) # log('checkbox: values[%s] = "%s"' % (field,repr(values[field]) ))
# log("descr['allowed_values'][%s] = '%s'" % (i, repr(descr['allowed_values'][i]))) # log("descr['allowed_values'][%s] = '%s'" % (i, repr(descr['allowed_values'][i])))
if descr["allowed_values"][i] in values[field]: if descr["allowed_values"][i] in values[field]:

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-
from email.Header import Header # pylint: disable=no-name-in-module,import-error from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error from email import Encoders # pylint: disable=no-name-in-module,import-error
from sco_zope import ( from app.scodoc.sco_zope import (
ObjectManager, ObjectManager,
PropertyManager, PropertyManager,
RoleManager, RoleManager,
@ -72,13 +72,13 @@ try:
except: except:
import ZPsycopgDA.DA as ZopeDA # interp.py import ZPsycopgDA.DA as ZopeDA # interp.py
import sco_utils as scu import app.scodoc.sco_utils as scu
import VERSION from app.scodoc import VERSION
import mails import mails
from notes_log import log from app.scodoc.notes_log import log
import sco_find_etud from app.scodoc import sco_find_etud
import sco_users from app.scodoc import sco_users
from sco_permissions import ( from app.scodoc.sco_permissions import (
ScoView, ScoView,
ScoEnsView, ScoEnsView,
ScoImplement, ScoImplement,
@ -94,8 +94,13 @@ from sco_permissions import (
ScoEditApo, ScoEditApo,
ScoSuperAdmin, ScoSuperAdmin,
) )
from sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError, AccessDenied from app.scodoc.sco_exceptions import (
import html_sco_header ScoValueError,
ScoLockedFormError,
ScoGenError,
AccessDenied,
)
from app.scodoc import html_sco_header
class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit): class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit):
@ -803,7 +808,7 @@ ErrorType: %(error_type)s
last_dept = None last_dept = None
last_date = None last_date = None
for (dept, etuds) in depts_etud: for (dept, etuds) in depts_etud:
scolars.fillEtudsInfo(self, etuds) sco_etud.fill_etuds_info(self, etuds)
etud = etuds[0] etud = etuds[0]
if etud["sems"]: if etud["sems"]:
if (not last_date) or (etud["sems"][0]["date_fin_iso"] > last_date): if (not last_date) or (etud["sems"][0]["date_fin_iso"] > last_date):

View File

@ -34,23 +34,23 @@ import md5
import base64 import base64
import jaxml import jaxml
from sco_zope import * # pylint: disable=unused-wildcard-import from app.scodoc.sco_zope import * # pylint: disable=unused-wildcard-import
# --------------- # ---------------
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
from scolars import format_prenom, format_nom from scolars import format_prenom, format_nom
import sco_import_users from app.scodoc import sco_import_users
import sco_excel from app.scodoc import sco_excel
from TrivialFormulator import TrivialFormulator, TF, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, TF, tf_error_message
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import scolars from app.scodoc import sco_etud
import sco_cache from app.scodoc import sco_cache
import sco_users from app.scodoc import sco_users
from sco_exceptions import ( from app.scodoc.sco_exceptions import (
AccessDenied, AccessDenied,
ScoException, ScoException,
ScoValueError, ScoValueError,
@ -305,7 +305,7 @@ class ZScoUsers(
info["prenomnom"] = (prenom_abbrv + " " + n).strip() info["prenomnom"] = (prenom_abbrv + " " + n).strip()
# nom_fmt et prenom_fmt: minuscule capitalisé # nom_fmt et prenom_fmt: minuscule capitalisé
info["nom_fmt"] = n info["nom_fmt"] = n
info["prenom_fmt"] = scolars.format_prenom(p) info["prenom_fmt"] = sco_etud.format_prenom(p)
# nomcomplet est le prenom et le nom complets # nomcomplet est le prenom et le nom complets
info["nomcomplet"] = info["prenom_fmt"] + " " + info["nom_fmt"] info["nomcomplet"] = info["prenom_fmt"] + " " + info["nom_fmt"]
# nomplogin est le nom en majuscules suivi du prénom et du login # nomplogin est le nom en majuscules suivi du prénom et du login

View File

@ -27,4 +27,3 @@
"""ScoDoc core package """ScoDoc core package
""" """
# from app.scodoc import sco_core

View File

@ -34,25 +34,37 @@ nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_i
import pdb # pylint: disable=unused-import import pdb # pylint: disable=unused-import
import pprint import pprint
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb # pylint: disable=unused-import
from app.scodoc.notesdb import * # pylint: disable=unused-wildcard-import from app.scodoc.notesdb import * # pylint: disable=wildcard-import,unused-wildcard-import
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import * # pylint: disable=unused-wildcard-import from app.scodoc.sco_utils import * # pylint: disable=wildcard-import, unused-wildcard-import
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_archives from app.scodoc import html_sco_header
import sco_groups from app.scodoc import sco_archives
import sco_evaluations from app.scodoc import sco_bulletins
import sco_formsemestre from app.scodoc import sco_bulletins_xml
import sco_formsemestre_edit from app.scodoc import sco_codes_parcours
import sco_compute_moy from app.scodoc import sco_compute_moy
import sco_parcours_dut from app.scodoc import sco_core
import sco_codes_parcours from app.scodoc import sco_edit_matiere
import sco_bulletins from app.scodoc import sco_edit_module
import sco_excel from app.scodoc import sco_edit_ue
import sco_formsemestre_status from app.scodoc import sco_excel
import sco_bulletins_xml 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 # Prend le premier departement comme context

View File

@ -4,7 +4,7 @@
# #
# Command: ./csv2rules.py misc/parcoursDUT.csv # Command: ./csv2rules.py misc/parcoursDUT.csv
# #
from sco_codes_parcours import ( from app.scodoc.sco_codes_parcours import (
DUTRule, DUTRule,
ADC, ADC,
ADJ, ADJ,

View File

@ -54,11 +54,11 @@ from reportlab.lib import styles
from reportlab.lib.units import inch, cm, mm from reportlab.lib.units import inch, cm, mm
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_excel import app.scodoc.sco_excel
import sco_pdf import app.scodoc.sco_pdf
from sco_pdf import SU from app.scodoc.sco_pdf import SU
from notes_log import log from app.scodoc.notes_log import log
def mark_paras(L, tags): def mark_paras(L, tags):
@ -71,6 +71,8 @@ def mark_paras(L, tags):
class DEFAULT_TABLE_PREFERENCES: class DEFAULT_TABLE_PREFERENCES:
"""Default preferences for tables created without preferences argument"""
values = { values = {
"SCOLAR_FONT": "Helvetica", # used for PDF, overriden by preferences argument "SCOLAR_FONT": "Helvetica", # used for PDF, overriden by preferences argument
"SCOLAR_FONT_SIZE": 10, "SCOLAR_FONT_SIZE": 10,

View File

@ -25,16 +25,15 @@
# #
############################################################################## ##############################################################################
"""HTML Header/Footer for ScoDoc pages
"""
import cgi import cgi
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import html_sidebar from app.scodoc import html_sidebar
import VERSION from app.scodoc import VERSION
"""
HTML Header/Footer for ScoDoc pages
"""
# Some constants: # Some constants:
@ -155,6 +154,7 @@ def sco_header(
user_check=True, # verifie passwords temporaires user_check=True, # verifie passwords temporaires
): ):
"Main HTML page header for ScoDoc" "Main HTML page header for ScoDoc"
from app.scodoc.sco_formsemestre_status import formsemestre_page_title
# context est une instance de ZScolar. container est une instance qui "acquiert" ZScolar # context est une instance de ZScolar. container est une instance qui "acquiert" ZScolar
if container: if container:
@ -364,6 +364,3 @@ def html_sem_header(
return h + """<h2 class="formsemestre">%s</h2>""" % (title) return h + """<h2 class="formsemestre">%s</h2>""" % (title)
else: else:
return h return h
from sco_formsemestre_status import formsemestre_page_title

View File

@ -25,16 +25,14 @@
# #
############################################################################## ##############################################################################
import sco_utils as scu
import sco_preferences
from sco_abs import getAbsSemEtud
from app.scodoc.sco_permissions import Permission
import scolars
""" """
Génération de la "sidebar" (marge gauche des pages HTML) Génération de la "sidebar" (marge gauche des pages HTML)
""" """
import app.scodoc.sco_utils as scu
from app.scodoc import sco_preferences
from app.scodoc.sco_permissions import Permission
def sidebar_common(context, REQUEST=None): def sidebar_common(context, REQUEST=None):
"partie commune a toutes les sidebar" "partie commune a toutes les sidebar"
@ -78,6 +76,9 @@ def sidebar_common(context, REQUEST=None):
def sidebar(context, REQUEST=None): def sidebar(context, REQUEST=None):
"Main HTML page sidebar" "Main HTML page sidebar"
# rewritten from legacy DTML code # rewritten from legacy DTML code
from app.scodoc.sco_abs import getAbsSemEtud
from app.scodoc import sco_etud
params = {"ScoURL": scu.ScoURL(), "SCO_USER_MANUAL": scu.SCO_USER_MANUAL} params = {"ScoURL": scu.ScoURL(), "SCO_USER_MANUAL": scu.SCO_USER_MANUAL}
H = ['<div class="sidebar">', sidebar_common(context, REQUEST)] H = ['<div class="sidebar">', sidebar_common(context, REQUEST)]
@ -94,7 +95,7 @@ def sidebar(context, REQUEST=None):
# ---- s'il y a un etudiant selectionné: # ---- s'il y a un etudiant selectionné:
if REQUEST.form.has_key("etudid"): if REQUEST.form.has_key("etudid"):
etudid = REQUEST.form["etudid"] etudid = REQUEST.form["etudid"]
etud = scolars.get_etud_info(filled=1, etudid=etudid)[0] etud = sco_etud.get_etud_info(filled=1, etudid=etudid)[0]
params.update(etud) params.update(etud)
# compte les absences du semestre en cours # compte les absences du semestre en cours
H.append( H.append(

View File

@ -31,6 +31,8 @@ from flask import g, url_for
import listhistogram import listhistogram
import app.scodoc.sco_utils as scu
def horizontal_bargraph(value, mark): def horizontal_bargraph(value, mark):
"""html drawing an horizontal bar and a mark """html drawing an horizontal bar and a mark
@ -102,7 +104,7 @@ def make_menu(title, items, css_class="", alone=False):
args = item.get("args", {}) args = item.get("args", {})
item["urlq"] = url_for( item["urlq"] = url_for(
item["endpoint"], scodoc_dept=g.scodoc_dept, **args item["endpoint"], scodoc_dept=g.scodoc_dept, **args
) ).encode(scu.SCO_ENCODING)
else: else:
item["urlq"] = "#" item["urlq"] = "#"
item["attr"] = item.get("attr", "") item["attr"] = item.get("attr", "")

View File

@ -39,8 +39,8 @@ from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-
from email.Header import Header # pylint: disable=no-name-in-module,import-error from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error from email import Encoders # pylint: disable=no-name-in-module,import-error
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8 def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8

View File

@ -31,10 +31,10 @@
NOTA: inutilisable dans une instance Zope (can't pickle functions) NOTA: inutilisable dans une instance Zope (can't pickle functions)
""" """
from notes_log import log from app.scodoc.notes_log import log
class CacheFunc: class CacheFunc(object):
"""gestion rudimentaire de cache pour une fonction """gestion rudimentaire de cache pour une fonction
func doit etre sans effet de bord, et sans arguments nommés func doit etre sans effet de bord, et sans arguments nommés
""" """

View File

@ -1,8 +1,6 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pdb
import sys
import os import os
import re import re
import inspect import inspect
@ -10,18 +8,8 @@ import time
import traceback import traceback
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header from email.header import Header
from email.MIMEMultipart import ( # pylint: disable=no-name-in-module,import-error
MIMEMultipart,
)
from email.MIMEText import MIMEText # pylint: disable=no-name-in-module,import-error
from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-error
from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error
# Simple & stupid file logguer, used only to debug # Simple & stupid file logguer, used only to debug
# (logging to SQL is done in scolog) # (logging to SQL is done in scolog)

View File

@ -32,34 +32,42 @@ import time
import pdb import pdb
import inspect import inspect
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log, logCallStack from app.scodoc.notes_log import log, logCallStack
from sco_formulas import NoteVector from app.scodoc.sco_formulas import NoteVector
from sco_exceptions import ( from app.scodoc.sco_exceptions import (
AccessDenied, AccessDenied,
NoteProcessError, NoteProcessError,
ScoException, ScoException,
ScoValueError, ScoValueError,
) )
from sco_formsemestre import formsemestre_uecoef_list, formsemestre_uecoef_create from app.scodoc.sco_formsemestre import (
from sco_codes_parcours import DEF, UE_SPORT, UE_is_fondamentale, UE_is_professionnelle formsemestre_uecoef_list,
from sco_parcours_dut import formsemestre_get_etud_capitalisation formsemestre_uecoef_create,
import sco_codes_parcours )
import sco_compute_moy from app.scodoc.sco_codes_parcours import (
import sco_core DEF,
import sco_edit_matiere UE_SPORT,
import sco_edit_module UE_is_fondamentale,
import sco_edit_ue UE_is_professionnelle,
import sco_evaluations )
import sco_formations from app.scodoc.sco_parcours_dut import formsemestre_get_etud_capitalisation
import sco_formsemestre from app.scodoc import sco_codes_parcours
import sco_formsemestre_inscriptions from app.scodoc import sco_compute_moy
import sco_groups from app.scodoc import sco_core
import sco_moduleimpl from app.scodoc import sco_edit_matiere
import sco_parcours_dut from app.scodoc import sco_edit_module
import sco_preferences from app.scodoc import sco_edit_ue
import scolars from app.scodoc import sco_evaluations
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
# Support for old user-written "bonus" functions with 2 args: # Support for old user-written "bonus" functions with 2 args:
@ -193,7 +201,7 @@ class NotesTable:
self.identdict = {} # { etudid : ident } self.identdict = {} # { etudid : ident }
self.inscrdict = {} # { etudid : inscription } self.inscrdict = {} # { etudid : inscription }
for x in self.inscrlist: for x in self.inscrlist:
i = scolars.etudident_list(cnx, {"etudid": x["etudid"]})[0] i = sco_etud.etudident_list(cnx, {"etudid": x["etudid"]})[0]
self.identdict[x["etudid"]] = i self.identdict[x["etudid"]] = i
self.inscrdict[x["etudid"]] = x self.inscrdict[x["etudid"]] = x
x["nomp"] = (i["nom_usuel"] or i["nom"]) + i["prenom"] # pour tri x["nomp"] = (i["nom_usuel"] or i["nom"]) + i["prenom"] # pour tri
@ -405,7 +413,7 @@ class NotesTable:
def get_nom_long(self, etudid): def get_nom_long(self, etudid):
"formatte nom d'un etud: M. Pierre DUPONT" "formatte nom d'un etud: M. Pierre DUPONT"
etud = self.identdict[etudid] etud = self.identdict[etudid]
return scolars.format_nomprenom(etud) return sco_etud.format_nomprenom(etud)
def get_displayed_etud_code(self, etudid): def get_displayed_etud_code(self, etudid):
'code à afficher sur les listings "anonymes"' 'code à afficher sur les listings "anonymes"'
@ -1084,7 +1092,7 @@ class NotesTable:
"Warning: %s capitalized an UE %s which is not part of current sem %s" "Warning: %s capitalized an UE %s which is not part of current sem %s"
% (etudid, ue_id, self.formsemestre_id) % (etudid, ue_id, self.formsemestre_id)
) )
ue = self.sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0] ue = sco_edit_ue.do_ue_list(self.context, args={"ue_id": ue_id})[0]
self.uedict[ue_id] = ue # record this UE self.uedict[ue_id] = ue # record this UE
if ue_id not in self._uecoef: if ue_id not in self._uecoef:
cl = formsemestre_uecoef_list( cl = formsemestre_uecoef_list(
@ -1185,7 +1193,7 @@ class NotesTable:
"comp_ue_capitalisees: recomputing UE moy (etudid=%s, ue_id=%s formsemestre_id=%s)" "comp_ue_capitalisees: recomputing UE moy (etudid=%s, ue_id=%s formsemestre_id=%s)"
% (etudid, ue_cap["ue_id"], ue_cap["formsemestre_id"]) % (etudid, ue_cap["ue_id"], ue_cap["formsemestre_id"])
) )
nt_cap = sco_core.get_notes_cache(context).get_NotesTable( nt_cap = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, ue_cap["formsemestre_id"] self.context, ue_cap["formsemestre_id"]
) # > UE capitalisees par un etud ) # > UE capitalisees par un etud
moy_ue_cap = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"])[ moy_ue_cap = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"])[

View File

@ -8,9 +8,9 @@ import psycopg2.pool
import psycopg2.extras import psycopg2.extras
import thread import thread
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from sco_exceptions import ScoException, ScoValueError, NoteProcessError from app.scodoc.sco_exceptions import ScoException, ScoValueError, NoteProcessError
from types import StringType from types import StringType
from cgi import escape from cgi import escape
import datetime import datetime

View File

@ -33,17 +33,17 @@
import os import os
import codecs import codecs
import re import re
import scolars from app.scodoc import pe_jurype
import pe_jurype, pe_tagtable, pe_tools from app.scodoc import pe_tagtable
from app.scodoc import pe_tools
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import scolars from app.scodoc.gen_tables import GenTable, SeqGenTable
import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_etud
import pe_jurype, pe_tagtable, pe_tools
from gen_tables import GenTable, SeqGenTable
DEBUG = False # Pour debug et repérage des prints à changer en Log DEBUG = False # Pour debug et repérage des prints à changer en Log
@ -243,7 +243,7 @@ def get_annotation_PE(context, etudid, tag_annotation_pe):
""" """
if tag_annotation_pe: if tag_annotation_pe:
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
annotations = scolars.etud_annotations_list( annotations = sco_etud.etud_annotations_list(
cnx, args={"etudid": etudid} cnx, args={"etudid": etudid}
) # Les annotations de l'étudiant ) # Les annotations de l'étudiant
annotationsPE = [] annotationsPE = []

View File

@ -54,19 +54,25 @@ except:
from zipfile import ZipFile, BadZipfile from zipfile import ZipFile, BadZipfile
import pprint import pprint
from gen_tables import GenTable, SeqGenTable from app.scodoc.gen_tables import GenTable, SeqGenTable
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant from app.scodoc import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant
import sco_report
import pe_tagtable, pe_tools, pe_avislatex, pe_semestretag, pe_settag from app.scodoc import pe_tagtable
from app.scodoc import pe_tools
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(context, sem):
"""Le nom a afficher pour titrer un semestre """Le nom a afficher pour titrer un semestre
par exemple: "semestre 2 FI 2015" par exemple: "semestre 2 FI 2015"
""" """
F = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] from app.scodoc import sco_formations
F = sco_formations.formation_list(
context, args={"formation_id": sem["formation_id"]}
)[0]
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
return "%s %s %s %s" % ( return "%s %s %s %s" % (
parcours.SESSION_NAME, # eg "semestre" parcours.SESSION_NAME, # eg "semestre"
@ -456,6 +462,8 @@ class JuryPE:
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
def est_un_etudiant_reoriente_ou_demissionnaire(self, etudid): def est_un_etudiant_reoriente_ou_demissionnaire(self, etudid):
"""Renvoie True si l'étudiant est réorienté (NAR) ou démissionnaire (DEM)""" """Renvoie True si l'étudiant est réorienté (NAR) ou démissionnaire (DEM)"""
from app.scodoc import sco_report
reponse = False reponse = False
etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid) etud = self.get_cache_etudInfo_d_un_etudiant(self.context, etudid)
(_, parcours) = sco_report.get_codeparcoursetud(self.context.Notes, etud) (_, parcours) = sco_report.get_codeparcoursetud(self.context.Notes, etud)
@ -518,6 +526,8 @@ class JuryPE:
"""Renvoie le n° (semestre_id) du dernier semestre validé par un étudiant fourni par son etudid """Renvoie le n° (semestre_id) du dernier semestre validé par un étudiant fourni par son etudid
et None si aucun semestre n'a été validé et None si aucun semestre n'a été validé
""" """
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(self.context, etudid)
(code, parcours) = sco_report.get_codeparcoursetud( (code, parcours) = sco_report.get_codeparcoursetud(
self.context.Notes, etud self.context.Notes, etud
@ -1117,7 +1127,7 @@ class JuryPE:
ETUDINFO_DICT si mémorisée soit en les chargeant et en les mémorisant ETUDINFO_DICT si mémorisée soit en les chargeant et en les mémorisant
""" """
if etudid not in self.ETUDINFO_DICT: if etudid not in self.ETUDINFO_DICT:
self.ETUDINFO_DICT[etudid] = scolars.get_etud_info( self.ETUDINFO_DICT[etudid] = sco_etud.get_etud_info(
etudid=etudid, filled=True etudid=etudid, filled=True
)[0] )[0]
return self.ETUDINFO_DICT[etudid] return self.ETUDINFO_DICT[etudid]
@ -1139,7 +1149,7 @@ class JuryPE:
def get_semestresDUT_d_un_etudiant(self, etudid, semestre_id=None): def get_semestresDUT_d_un_etudiant(self, etudid, semestre_id=None):
"""Renvoie la liste des semestres DUT d'un étudiant """Renvoie la liste des semestres DUT d'un étudiant
pour un semestre_id (parmi 1,2,3,4) donné pour un semestre_id (parmi 1,2,3,4) donné
en fonction de ses infos d'etud (cf. scolars.get_etud_info( etudid=etudid, filled=True)[0]), 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. les semestres étant triés par ordre décroissant.
Si semestre_id == None renvoie tous les semestres""" 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(self.context, etudid)

View File

@ -35,15 +35,11 @@ Created on Fri Sep 9 09:15:05 2016
@author: barasc @author: barasc
""" """
import datetime
from notes_log import log from app.scodoc.notes_log import log
import notes_table from app.scodoc import sco_codes_parcours
import sco_codes_parcours from app.scodoc import sco_tag_module
import sco_tag_module from app.scodoc import pe_tagtable
import sco_utils
import pe_tagtable
import pe_jurype
class SemestreTag(pe_tagtable.TableTag): class SemestreTag(pe_tagtable.TableTag):

View File

@ -36,12 +36,8 @@ Created on Fri Sep 9 09:15:05 2016
@author: barasc @author: barasc
""" """
from pe_tools import pe_print, PE_DEBUG from app.scodoc.pe_tools import pe_print, PE_DEBUG
from app.scodoc import pe_tagtable
import pe_tagtable
import pe_semestretag
import notes_table
import pe_jurype
class SetTag(pe_tagtable.TableTag): class SetTag(pe_tagtable.TableTag):

View File

@ -37,9 +37,9 @@ Created on Thu Sep 8 09:36:33 2016
@author: barasc @author: barasc
""" """
import notes_table
import datetime import datetime
import codecs
from app.scodoc import notes_table
class TableTag: class TableTag:

View File

@ -39,13 +39,11 @@ from __future__ import print_function
import os import os
import datetime import datetime
import operator
import re import re
import unicodedata import unicodedata
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import notes_table
PE_DEBUG = 0 PE_DEBUG = 0

View File

@ -35,23 +35,15 @@
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import html_sco_header
import sco_formsemestre_status from app.scodoc import sco_preferences
import notes_table
from gen_tables import GenTable
import html_sco_header
import sco_codes_parcours
import sco_preferences
import pe_tools from app.scodoc import pe_tools
from pe_tools import PE_LATEX_ENCODING from app.scodoc.pe_tools import PE_LATEX_ENCODING
import pe_tagtable from app.scodoc import pe_jurype
import pe_semestretag from app.scodoc import pe_avislatex
import pe_settag
import pe_jurype
import pe_avislatex
def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None): def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None):

View File

@ -31,19 +31,35 @@
# Anciennement dans ZAbscences.py, séparé pour migration # Anciennement dans ZAbscences.py, séparé pour migration
import string import string
import datetime
import re
import time import time
import datetime
import calendar import calendar
import cgi import cgi
import notesdb
from scodoc_manager import sco_mgr from scodoc_manager import sco_mgr
from sco_exceptions import ScoValueError, ScoInvalidDateError from app.scodoc import notesdb as ndb
import sco_formsemestre from app.scodoc.scolog import logdb
import sco_compute_moy from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
import sco_preferences from app.scodoc import sco_abs_notification
import scolars from app.scodoc import sco_formsemestre
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
# --- Misc tools.... ------------------
def _isFarFutur(jour):
# check si jour est dans le futur "lointain"
# pour autoriser les saisies dans le futur mais pas a plus de 6 mois
y, m, d = [int(x) for x in jour.split("-")]
j = datetime.date(y, m, d)
# 6 mois ~ 182 jours:
return j - datetime.date.today() > datetime.timedelta(182)
def _toboolean(x):
"convert a value to boolean"
return x # not necessary anymore !
def is_work_saturday(context): def is_work_saturday(context):
@ -264,9 +280,419 @@ def YearTable(
return string.join(T, "\n") return string.join(T, "\n")
def list_abs_in_range(
context, etudid, debut, fin, matin=None, moduleimpl_id=None, cursor=None
):
"""Liste des absences entre deux dates.
Args:
etudid
debut string iso date ("2020-03-12")
end string iso date ("2020-03-12")
matin None, True, False
moduleimpl_id
"""
if matin != None:
matin = _toboolean(matin)
ismatin = " AND A.MATIN = %(matin)s "
else:
ismatin = ""
if moduleimpl_id:
modul = " AND A.MODULEIMPL_ID = %(moduleimpl_id)s "
else:
modul = ""
if not cursor:
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""
SELECT DISTINCT A.JOUR, A.MATIN
FROM ABSENCES A
WHERE A.ETUDID = %(etudid)s
AND A.ESTABS"""
+ ismatin
+ modul
+ """
AND A.JOUR BETWEEN %(debut)s AND %(fin)s
""",
{"etudid": etudid, "debut": debut, "fin": fin, "moduleimpl_id": moduleimpl_id},
)
res = cursor.dictfetchall()
return res
def CountAbs(context, etudid, debut, fin, matin=None, moduleimpl_id=None):
"""CountAbs
matin= 1 ou 0.
Returns:
An integer.
"""
return len(
list_abs_in_range(
context, etudid, debut, fin, matin=matin, moduleimpl_id=moduleimpl_id
)
)
def CountAbsJust(context, etudid, debut, fin, matin=None, moduleimpl_id=None):
"Count just. abs"
if matin != None:
matin = _toboolean(matin)
ismatin = " AND A.MATIN = %(matin)s "
else:
ismatin = ""
if moduleimpl_id:
modul = " AND A.MODULEIMPL_ID = %(moduleimpl_id)s "
else:
modul = ""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT COUNT(*) AS NbAbsJust FROM (
SELECT DISTINCT A.JOUR, A.MATIN
FROM ABSENCES A, ABSENCES B
WHERE A.ETUDID = %(etudid)s
AND A.ETUDID = B.ETUDID
AND A.JOUR = B.JOUR AND A.MATIN = B.MATIN
AND A.JOUR BETWEEN %(debut)s AND %(fin)s
AND A.ESTABS AND (A.ESTJUST OR B.ESTJUST)"""
+ ismatin
+ modul
+ """
) AS tmp
""",
vars(),
)
res = cursor.fetchone()[0]
return res
def ListeAbsDate(context, etudid, beg_date, end_date):
"""Liste des absences et justifs entre deux dates (inclues)."""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT jour, matin, estabs, estjust, description FROM ABSENCES A
WHERE A.ETUDID = %(etudid)s
AND A.jour >= %(beg_date)s
AND A.jour <= %(end_date)s
""",
vars(),
)
Abs = cursor.dictfetchall()
# remove duplicates
A = {} # { (jour, matin) : abs }
for a in Abs:
jour, matin = a["jour"], a["matin"]
if (jour, matin) in A:
# garde toujours la description
a["description"] = a["description"] or A[(jour, matin)]["description"]
# et la justif:
a["estjust"] = a["estjust"] or A[(jour, matin)]["estjust"]
a["estabs"] = a["estabs"] or A[(jour, matin)]["estabs"]
A[(jour, matin)] = a
else:
A[(jour, matin)] = a
if A[(jour, matin)]["description"] is None:
A[(jour, matin)]["description"] = ""
# add hours: matin = 8:00 - 12:00, apresmidi = 12:00 - 18:00
dat = "%04d-%02d-%02d" % (a["jour"].year, a["jour"].month, a["jour"].day)
if a["matin"]:
A[(jour, matin)]["begin"] = dat + " 08:00:00"
A[(jour, matin)]["end"] = dat + " 11:59:59"
else:
A[(jour, matin)]["begin"] = dat + " 12:00:00"
A[(jour, matin)]["end"] = dat + " 17:59:59"
# sort
R = A.values()
R.sort(key=lambda x: (x["begin"]))
return R
def GetAbsDescription(context, a, cursor=None):
"Description associee a l'absence"
from app.scodoc import sco_moduleimpl
if not cursor:
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
a = a.copy()
# a['jour'] = a['jour'].date()
if a["matin"]: # devrait etre booleen... :-(
a["matin"] = True
else:
a["matin"] = False
cursor.execute(
"""select * from absences where etudid=%(etudid)s and jour=%(jour)s and matin=%(matin)s order by entry_date desc""",
a,
)
A = cursor.dictfetchall()
desc = None
module = ""
for a in A:
if a["description"]:
desc = a["description"]
if a["moduleimpl_id"] and a["moduleimpl_id"] != "NULL":
# Trouver le nom du module
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context.Notes, moduleimpl_id=a["moduleimpl_id"]
)
if Mlist:
M = Mlist[0]
module += "%s " % M["module"]["code"]
if desc:
return "(%s) %s" % (desc, module)
if module:
return module
return ""
def ListeAbsJour(context, date, am=True, pm=True, is_abs=True, is_just=None):
"""Liste des absences et/ou justificatifs ce jour.
is_abs: None (peu importe), True, False
is_just: idem
"""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = """SELECT DISTINCT etudid, jour, matin FROM ABSENCES A
WHERE A.jour = %(date)s
"""
if is_abs != None:
req += " AND A.estabs = %(is_abs)s"
if is_just != None:
req += " AND A.estjust = %(is_just)s"
if not am:
req += " AND NOT matin "
if not pm:
req += " AND matin"
cursor.execute(req, {"date": date, "is_just": is_just, "is_abs": is_abs})
A = cursor.dictfetchall()
for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor)
return A
def ListeAbsNonJustJour(context, date, am=True, pm=True):
"Liste des absences non justifiees ce jour"
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
reqa = ""
if not am:
reqa += " AND NOT matin "
if not pm:
reqa += " AND matin "
req = (
"""SELECT etudid, jour, matin FROM ABSENCES A
WHERE A.estabs
AND A.jour = %(date)s
"""
+ reqa
+ """EXCEPT SELECT etudid, jour, matin FROM ABSENCES B
WHERE B.estjust AND B.jour = %(date)s"""
+ reqa
)
cursor.execute(req, {"date": date})
A = cursor.dictfetchall()
for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor)
return A
def ListeAbsNonJust(context, etudid, datedebut):
"Liste des absences NON justifiees (par ordre chronologique)"
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT ETUDID, JOUR, MATIN FROM ABSENCES A
WHERE A.ETUDID = %(etudid)s
AND A.estabs
AND A.jour >= %(datedebut)s
EXCEPT SELECT ETUDID, JOUR, MATIN FROM ABSENCES B
WHERE B.estjust
AND B.ETUDID = %(etudid)s
ORDER BY JOUR
""",
vars(),
)
A = cursor.dictfetchall()
for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor)
return A
def ListeAbsJust(context, etudid, datedebut):
"Liste des absences justifiees (par ordre chronologique)"
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"""SELECT DISTINCT A.ETUDID, A.JOUR, A.MATIN FROM ABSENCES A, ABSENCES B
WHERE A.ETUDID = %(etudid)s
AND A.ETUDID = B.ETUDID
AND A.JOUR = B.JOUR AND A.MATIN = B.MATIN AND A.JOUR >= %(datedebut)s
AND A.ESTABS AND (A.ESTJUST OR B.ESTJUST)
ORDER BY A.JOUR
""",
vars(),
)
A = cursor.dictfetchall()
for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor)
return A
def ListeJustifs(context, etudid, datedebut, datefin=None, only_no_abs=False):
"""Liste des justificatifs (sans absence relevée) à partir d'une date,
ou, si datefin spécifié, entre deux dates.
Si only_no_abs: seulement les justificatifs correspondant aux jours sans absences relevées.
"""
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = """SELECT DISTINCT ETUDID, JOUR, MATIN FROM ABSENCES A
WHERE A.ETUDID = %(etudid)s
AND A.ESTJUST
AND A.JOUR >= %(datedebut)s"""
if datefin:
req += """AND A.JOUR <= %(datefin)s"""
if only_no_abs:
req += """
EXCEPT SELECT ETUDID, JOUR, MATIN FROM ABSENCES B
WHERE B.estabs
AND B.ETUDID = %(etudid)s
"""
cursor.execute(req, vars())
A = cursor.dictfetchall()
for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor)
return A
def add_absence(
context,
etudid,
jour,
matin,
estjust,
REQUEST,
description=None,
moduleimpl_id=None,
):
"Ajoute une absence dans la bd"
if _isFarFutur(jour):
raise ScoValueError("date absence trop loin dans le futur !")
estjust = _toboolean(estjust)
matin = _toboolean(matin)
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"insert into absences (etudid,jour,estabs,estjust,matin,description, moduleimpl_id) values (%(etudid)s, %(jour)s, TRUE, %(estjust)s, %(matin)s, %(description)s, %(moduleimpl_id)s )",
vars(),
)
logdb(
REQUEST,
cnx,
"AddAbsence",
etudid=etudid,
msg="JOUR=%(jour)s,MATIN=%(matin)s,ESTJUST=%(estjust)s,description=%(description)s,moduleimpl_id=%(moduleimpl_id)s"
% vars(),
)
cnx.commit()
invalidateAbsEtudDate(context, etudid, jour)
sco_abs_notification.abs_notify(context, etudid, jour)
def add_justif(context, etudid, jour, matin, REQUEST, description=None):
"Ajoute un justificatif dans la base"
# unpublished
if _isFarFutur(jour):
raise ScoValueError("date justificatif trop loin dans le futur !")
matin = _toboolean(matin)
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"insert into absences (etudid,jour,estabs,estjust,matin, description) values (%(etudid)s,%(jour)s, FALSE, TRUE, %(matin)s, %(description)s )",
vars(),
)
logdb(
REQUEST,
cnx,
"AddJustif",
etudid=etudid,
msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(),
)
cnx.commit()
invalidateAbsEtudDate(context, etudid, jour)
def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None):
for a in abslist:
etudid, jour, ampm = a.split(":")
if ampm == "am":
matin = 1
elif ampm == "pm":
matin = 0
else:
raise ValueError("invalid ampm !")
# ajoute abs si pas deja absent
if CountAbs(context, etudid, jour, jour, matin, moduleimpl_id) == 0:
add_absence(context, etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
def annule_absence(context, etudid, jour, matin, moduleimpl_id=None, REQUEST=None):
"""Annule une absence ds base
Si moduleimpl_id, n'annule que pour ce module
"""
# unpublished
matin = _toboolean(matin)
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = "delete from absences where jour=%(jour)s and matin=%(matin)s and etudid=%(etudid)s and estabs"
if moduleimpl_id:
req += " and moduleimpl_id=%(moduleimpl_id)s"
cursor.execute(req, vars())
logdb(
REQUEST,
cnx,
"AnnuleAbsence",
etudid=etudid,
msg="JOUR=%(jour)s,MATIN=%(matin)s,moduleimpl_id=%(moduleimpl_id)s" % vars(),
)
cnx.commit()
invalidateAbsEtudDate(context, etudid, jour)
def annule_justif(context, etudid, jour, matin, REQUEST=None):
"Annule un justificatif"
# unpublished
matin = _toboolean(matin)
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(
"delete from absences where jour=%(jour)s and matin=%(matin)s and etudid=%(etudid)s and ESTJUST AND NOT ESTABS",
vars(),
)
cursor.execute(
"update absences set estjust=false where jour=%(jour)s and matin=%(matin)s and etudid=%(etudid)s",
vars(),
)
logdb(
REQUEST,
cnx,
"AnnuleJustif",
etudid=etudid,
msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(),
)
cnx.commit()
invalidateAbsEtudDate(context, etudid, jour)
# ---- BILLETS # ---- BILLETS
_billet_absenceEditor = notesdb.EditableTable( _billet_absenceEditor = ndb.EditableTable(
"billet_absence", "billet_absence",
"billet_id", "billet_id",
( (
@ -563,14 +989,14 @@ class CAbsSemEtud:
self.sem = sco_formsemestre.get_formsemestre( self.sem = sco_formsemestre.get_formsemestre(
self.context, self.sem["formsemestre_id"] self.context, self.sem["formsemestre_id"]
) )
debut_sem = notesdb.DateDMYtoISO(self.sem["date_debut"]) debut_sem = ndb.DateDMYtoISO(self.sem["date_debut"])
fin_sem = notesdb.DateDMYtoISO(self.sem["date_fin"]) fin_sem = ndb.DateDMYtoISO(self.sem["date_fin"])
self._CountAbs = self.context.Absences.CountAbs( self._CountAbs = self.sco_abs.CountAbs(
etudid=self.etudid, debut=debut_sem, fin=fin_sem context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
) )
self._CountAbsJust = self.context.Absences.CountAbsJust( self._CountAbsJust = self.sco_abs.CountAbsJust(
etudid=self.etudid, debut=debut_sem, fin=fin_sem context, etudid=self.etudid, debut=debut_sem, fin=fin_sem
) )
self._loaded = True self._loaded = True
@ -606,8 +1032,10 @@ def invalidateAbsEtudDate(context, etudid, date):
Invalide cache absence et PDF bulletins si nécessaire. Invalide cache absence et PDF bulletins si nécessaire.
date: date au format ISO date: date au format ISO
""" """
import sco_compute_moy
# Semestres a cette date: # Semestres a cette date:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
sems = [ sems = [
sem sem
for sem in etud["sems"] for sem in etud["sems"]

View File

@ -37,15 +37,14 @@ from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
import mails from app.scodoc import mails
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
import sco_bulletins from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_preferences
import sco_preferences from app.scodoc import sco_etud
import scolars
def abs_notify(context, etudid, date): def abs_notify(context, etudid, date):
@ -54,13 +53,15 @@ def abs_notify(context, etudid, date):
(s'il n'y a pas de semestre courant, ne fait rien, (s'il n'y a pas de semestre courant, ne fait rien,
car l'etudiant n'est pas inscrit au moment de l'absence!). car l'etudiant n'est pas inscrit au moment de l'absence!).
""" """
from app.scodoc import sco_abs
sem = retreive_current_formsemestre(context, etudid, date) sem = retreive_current_formsemestre(context, etudid, date)
if not sem: if not sem:
return # non inscrit a la date, pas de notification return # non inscrit a la date, pas de notification
debut_sem = ndb.DateDMYtoISO(sem["date_debut"]) debut_sem = ndb.DateDMYtoISO(sem["date_debut"])
fin_sem = ndb.DateDMYtoISO(sem["date_fin"]) fin_sem = ndb.DateDMYtoISO(sem["date_fin"])
nbabs = context.CountAbs(etudid, debut=debut_sem, fin=fin_sem) nbabs = sco_abs.CountAbs(context, etudid, debut=debut_sem, fin=fin_sem)
nbabsjust = context.CountAbsJust(etudid, debut=debut_sem, fin=fin_sem) nbabsjust = context.CountAbsJust(etudid, debut=debut_sem, fin=fin_sem)
do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust) do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust)
@ -154,7 +155,7 @@ def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsj
if prefs["abs_notify_email"]: if prefs["abs_notify_email"]:
destinations.append(prefs["abs_notify_email"]) destinations.append(prefs["abs_notify_email"])
if prefs["abs_notify_etud"]: if prefs["abs_notify_etud"]:
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
if etud["email_default"]: if etud["email_default"]:
destinations.append(etud["email_default"]) destinations.append(etud["email_default"])
@ -238,7 +239,9 @@ def abs_notification_message(context, sem, prefs, etudid, nbabs, nbabsjust):
"""Mime notification message based on template. """Mime notification message based on template.
returns None if sending should be canceled (emplty template). returns None if sending should be canceled (emplty template).
""" """
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] from app.scodoc import sco_bulletins
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
# Variables accessibles dans les balises du template: %(nom_variable)s : # 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(context, sem, etud)

View File

@ -32,22 +32,23 @@ import datetime
from stripogram import html2text, html2safehtml from stripogram import html2text, html2safehtml
from gen_tables import GenTable
from notesdb import DateISOtoDMY import app.scodoc.sco_utils as scu
import sco_utils as scu from app.scodoc import notesdb as ndb
from sco_exceptions import ScoValueError from app.scodoc.scolog import logdb
from sco_permissions import Permission from app.scodoc.gen_tables import GenTable
from notes_log import log from app.scodoc import html_sco_header
import html_sco_header from app.scodoc import sco_abs
import sco_abs from app.scodoc import sco_etud
import sco_find_etud from app.scodoc import sco_find_etud
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_moduleimpl from app.scodoc import sco_moduleimpl
import sco_photos from app.scodoc import sco_photos
import sco_preferences from app.scodoc import sco_preferences
import scolars from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission
def doSignaleAbsence( def doSignaleAbsence(
@ -72,7 +73,7 @@ def doSignaleAbsence(
description: str description: str
etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form
""" """
etud = scolars.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
@ -81,15 +82,30 @@ def doSignaleAbsence(
demijournee = int(demijournee) demijournee = int(demijournee)
for jour in dates: for jour in dates:
if demijournee == 2: if demijournee == 2:
context._AddAbsence( sco_abs.add_absence(
etudid, jour, False, estjust, REQUEST, description_abs, moduleimpl_id context,
etudid,
jour,
False,
estjust,
REQUEST,
description_abs,
moduleimpl_id,
) )
context._AddAbsence( sco_abs.add_absence(
etudid, jour, True, estjust, REQUEST, description_abs, moduleimpl_id context,
etudid,
jour,
True,
estjust,
REQUEST,
description_abs,
moduleimpl_id,
) )
nbadded += 2 nbadded += 2
else: else:
context._AddAbsence( sco_abs.add_absence(
context,
etudid, etudid,
jour, jour,
demijournee, demijournee,
@ -151,7 +167,7 @@ def doSignaleAbsence(
def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
"""Formulaire individuel simple de signalement d'une absence""" """Formulaire individuel simple de signalement d'une absence"""
# brute-force portage from very old dtml code ... # brute-force portage from very old dtml code ...
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
disabled = False disabled = False
if not etud["cursem"]: if not etud["cursem"]:
@ -290,7 +306,7 @@ def doJustifAbsence(
description: str description: str
etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form
""" """
etud = scolars.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
dates = sco_abs.DateRangeISO(context, datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
@ -298,14 +314,16 @@ def doJustifAbsence(
demijournee = int(demijournee) demijournee = int(demijournee)
for jour in dates: for jour in dates:
if demijournee == 2: if demijournee == 2:
context._AddJustif( sco_abs.add_justif(
context,
etudid=etudid, etudid=etudid,
jour=jour, jour=jour,
matin=False, matin=False,
REQUEST=REQUEST, REQUEST=REQUEST,
description=description_abs, description=description_abs,
) )
context._AddJustif( sco_abs.add_justif(
context,
etudid=etudid, etudid=etudid,
jour=jour, jour=jour,
matin=True, matin=True,
@ -314,7 +332,8 @@ def doJustifAbsence(
) )
nbadded += 2 nbadded += 2
else: else:
context._AddJustif( sco_abs.add_justif(
context,
etudid=etudid, etudid=etudid,
jour=jour, jour=jour,
matin=demijournee, matin=demijournee,
@ -359,7 +378,7 @@ def doJustifAbsence(
def JustifAbsenceEtud(context, REQUEST=None): # etudid implied def JustifAbsenceEtud(context, REQUEST=None): # etudid implied
"""Formulaire individuel simple de justification d'une absence""" """Formulaire individuel simple de justification d'une absence"""
# brute-force portage from very old dtml code ... # brute-force portage from very old dtml code ...
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(
@ -417,7 +436,7 @@ def doAnnuleAbsence(
context, datedebut, datefin, demijournee, etudid=False, REQUEST=None context, datedebut, datefin, demijournee, etudid=False, REQUEST=None
): # etudid implied ): # etudid implied
"""Annulation des absences pour une demi journée""" """Annulation des absences pour une demi journée"""
etud = scolars.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
dates = sco_abs.DateRangeISO(context, datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
@ -425,11 +444,11 @@ def doAnnuleAbsence(
demijournee = int(demijournee) demijournee = int(demijournee)
for jour in dates: for jour in dates:
if demijournee == 2: if demijournee == 2:
context._AnnuleAbsence(etudid, jour, False, REQUEST=REQUEST) sco_abs.annule_absence(context, etudid, jour, False, REQUEST=REQUEST)
context._AnnuleAbsence(etudid, jour, True, REQUEST=REQUEST) sco_abs.annule_absence(context, etudid, jour, True, REQUEST=REQUEST)
nbadded += 2 nbadded += 2
else: else:
context._AnnuleAbsence(etudid, jour, demijournee, REQUEST=REQUEST) sco_abs.annule_absence(context, etudid, jour, demijournee, REQUEST=REQUEST)
nbadded += 1 nbadded += 1
# #
H = [ H = [
@ -468,7 +487,7 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
"""Formulaire individuel simple d'annulation d'une absence""" """Formulaire individuel simple d'annulation d'une absence"""
# brute-force portage from very old dtml code ... # brute-force portage from very old dtml code ...
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
H = [ H = [
@ -557,7 +576,7 @@ def doAnnuleJustif(
context, datedebut0, datefin0, demijournee, REQUEST=None context, datedebut0, datefin0, demijournee, REQUEST=None
): # etudid implied ): # etudid implied
"""Annulation d'une justification""" """Annulation d'une justification"""
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
dates = sco_abs.DateRangeISO(context, datedebut0, datefin0) dates = sco_abs.DateRangeISO(context, datedebut0, datefin0)
nbadded = 0 nbadded = 0
@ -565,11 +584,11 @@ def doAnnuleJustif(
for jour in dates: for jour in dates:
# Attention: supprime matin et après-midi # Attention: supprime matin et après-midi
if demijournee == 2: if demijournee == 2:
context._AnnuleJustif(etudid, jour, False, REQUEST=REQUEST) sco_abs.annule_justif(context, etudid, jour, False, REQUEST=REQUEST)
context._AnnuleJustif(etudid, jour, True, REQUEST=REQUEST) sco_abs.annule_justif(context, etudid, jour, True, REQUEST=REQUEST)
nbadded += 2 nbadded += 2
else: else:
context._AnnuleJustif(etudid, jour, demijournee, REQUEST=REQUEST) sco_abs.annule_justif(context, etudid, jour, demijournee, REQUEST=REQUEST)
nbadded += 1 nbadded += 1
# #
H = [ H = [
@ -605,6 +624,59 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
return "\n".join(H) return "\n".join(H)
def AnnuleAbsencesDatesNoJust(context, etudid, dates, moduleimpl_id=None, REQUEST=None):
"""Supprime les absences aux dates indiquées
mais ne supprime pas les justificatifs.
"""
# log('AnnuleAbsencesDatesNoJust: moduleimpl_id=%s' % moduleimpl_id)
if not dates:
return
date0 = dates[0]
if len(date0.split(":")) == 2:
# am/pm is present
for date in dates:
jour, ampm = date.split(":")
if ampm == "am":
matin = 1
elif ampm == "pm":
matin = 0
else:
raise ValueError("invalid ampm !")
sco_abs.annule_absence(context, etudid, jour, matin, moduleimpl_id, REQUEST)
return
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
# supr les absences non justifiees
for date in dates:
cursor.execute(
"delete from absences where etudid=%(etudid)s and (not estjust) and jour=%(date)s and moduleimpl_id=%(moduleimpl_id)s",
vars(),
)
sco_abs.invalidateAbsEtudDate(context, etudid, date)
# s'assure que les justificatifs ne sont pas "absents"
for date in dates:
cursor.execute(
"update absences set estabs=FALSE where etudid=%(etudid)s and jour=%(date)s and moduleimpl_id=%(moduleimpl_id)s",
vars(),
)
if dates:
date0 = dates[0]
else:
date0 = None
if len(dates) > 1:
date1 = dates[1]
else:
date1 = None
logdb(
REQUEST,
cnx,
"AnnuleAbsencesDatesNoJust",
etudid=etudid,
msg="%s - %s - %s" % (date0, date1, moduleimpl_id),
)
cnx.commit()
def EtatAbsences(context, REQUEST=None): def EtatAbsences(context, REQUEST=None):
"""Etat des absences: choix du groupe""" """Etat des absences: choix du groupe"""
# crude portage from 1999 DTML # crude portage from 1999 DTML
@ -660,26 +732,26 @@ def formChoixSemestreGroupe(context, all=False):
def CalAbs(context, REQUEST=None): # etud implied def CalAbs(context, REQUEST=None): # etud implied
"""Calendrier des absences d un etudiant""" """Calendrier des absences d'un etudiant"""
# crude portage from 1999 DTML # crude portage from 1999 DTML
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
anneescolaire = int(scu.AnneeScolaire(REQUEST)) anneescolaire = int(scu.AnneeScolaire(REQUEST))
datedebut = str(anneescolaire) + "-08-31" datedebut = str(anneescolaire) + "-08-31"
datefin = str(anneescolaire + 1) + "-07-31" datefin = str(anneescolaire + 1) + "-07-31"
nbabs = context.CountAbs(etudid=etudid, debut=datedebut, fin=datefin) nbabs = sco_abs.CountAbs(context, etudid=etudid, debut=datedebut, fin=datefin)
nbabsjust = context.CountAbsJust(etudid=etudid, debut=datedebut, fin=datefin) nbabsjust = context.CountAbsJust(etudid=etudid, debut=datedebut, fin=datefin)
events = [] events = []
for a in context.ListeAbsJust(etudid=etudid, datedebut=datedebut): for a in sco_abs.ListeAbsJust(context, etudid=etudid, datedebut=datedebut):
events.append( events.append(
(str(a["jour"]), "a", "#F8B7B0", "", a["matin"], a["description"]) (str(a["jour"]), "a", "#F8B7B0", "", a["matin"], a["description"])
) )
for a in context.ListeAbsNonJust(etudid=etudid, datedebut=datedebut): for a in sco_abs.ListeAbsNonJust(context, etudid=etudid, datedebut=datedebut):
events.append( events.append(
(str(a["jour"]), "A", "#EE0000", "", a["matin"], a["description"]) (str(a["jour"]), "A", "#EE0000", "", a["matin"], a["description"])
) )
justifs_noabs = context.ListeJustifs( justifs_noabs = sco_abs.ListeJustifs(
etudid=etudid, datedebut=datedebut, only_no_abs=True context, etudid=etudid, datedebut=datedebut, only_no_abs=True
) )
for a in justifs_noabs: for a in justifs_noabs:
events.append( events.append(
@ -750,11 +822,11 @@ def ListeAbsEtud(
absjust_only = int(absjust_only) # si vrai, table absjust seule (export xls ou pdf) absjust_only = int(absjust_only) # si vrai, table absjust seule (export xls ou pdf)
datedebut = "%s-08-31" % scu.AnneeScolaire(REQUEST) datedebut = "%s-08-31" % scu.AnneeScolaire(REQUEST)
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
# Liste des absences et titres colonnes tables: # Liste des absences et titres colonnes tables:
titles, columns_ids, absnonjust, absjust = context.Absences._TablesAbsEtud( titles, columns_ids, absnonjust, absjust = _TablesAbsEtud(
etudid, datedebut, with_evals=with_evals, format=format context, etudid, datedebut, with_evals=with_evals, format=format
) )
if REQUEST: if REQUEST:
base_url_nj = "%s?etudid=%s&absjust_only=0" % (REQUEST.URL0, etudid) base_url_nj = "%s?etudid=%s&absjust_only=0" % (REQUEST.URL0, etudid)
@ -805,7 +877,7 @@ def ListeAbsEtud(
) )
H.append( H.append(
"""<h2>Absences de %s (à partir du %s)</h2>""" """<h2>Absences de %s (à partir du %s)</h2>"""
% (etud["nomprenom"], DateISOtoDMY(datedebut)) % (etud["nomprenom"], ndb.DateISOtoDMY(datedebut))
) )
if len(absnonjust): if len(absnonjust):
@ -826,12 +898,12 @@ def ListeAbsEtud(
if not len(absnonjust) and not len(absjust): if not len(absnonjust) and not len(absjust):
T.append( T.append(
"""--- Pas d'absences enregistrées depuis le %s""" """--- Pas d'absences enregistrées depuis le %s"""
% DateISOtoDMY(datedebut) % ndb.DateISOtoDMY(datedebut)
) )
else: else:
T.append( T.append(
"""--- Absences enregistrées à partir du %s:""" """--- Absences enregistrées à partir du %s:"""
% DateISOtoDMY(datedebut) % ndb.DateISOtoDMY(datedebut)
) )
T.append("\n") T.append("\n")
if len(absnonjust): if len(absnonjust):
@ -845,6 +917,136 @@ def ListeAbsEtud(
raise ValueError("Invalid format !") raise ValueError("Invalid format !")
def _TablesAbsEtud(
context,
etudid,
datedebut,
with_evals=True,
format="html",
absjust_only=0,
REQUEST=None,
):
"""Tables des absences justifiees et non justifiees d'un étudiant sur l'année en cours"""
absjust = sco_abs.ListeAbsJust(context, etudid=etudid, datedebut=datedebut)
absnonjust = sco_abs.ListeAbsNonJust(context, etudid=etudid, datedebut=datedebut)
# examens ces jours là ?
if with_evals:
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
for a in absnonjust + absjust:
cursor.execute(
"""select eval.*
from notes_evaluation eval, notes_moduleimpl_inscription mi, notes_moduleimpl m
where eval.jour = %(jour)s and eval.moduleimpl_id = m.moduleimpl_id
and mi.moduleimpl_id = m.moduleimpl_id and mi.etudid = %(etudid)s""",
{"jour": a["jour"].strftime("%Y-%m-%d"), "etudid": etudid},
)
a["evals"] = cursor.dictfetchall()
cursor.execute(
"""SELECT mi.moduleimpl_id
from absences abs, notes_moduleimpl_inscription mi, notes_moduleimpl m
where abs.matin = %(matin)s and abs.jour = %(jour)s and abs.etudid=%(etudid)s and abs.moduleimpl_id=mi.moduleimpl_id and mi.moduleimpl_id=m.moduleimpl_id
and mi.etudid = %(etudid)s""",
{
"matin": bool(a["matin"]),
"jour": a["jour"].strftime("%Y-%m-%d"),
"etudid": etudid,
},
)
a["absent"] = cursor.dictfetchall()
def matin(x):
if x:
return "matin"
else:
return "après-midi"
def descr_exams(a):
if not a.has_key("evals"):
return ""
ex = []
for ev in a["evals"]:
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
context.Notes, moduleimpl_id=ev["moduleimpl_id"]
)[0]
if format == "html":
ex.append(
'<a href="Notes/moduleimpl_status?moduleimpl_id=%s">%s</a>'
% (mod["moduleimpl_id"], mod["module"]["code"])
)
else:
ex.append(mod["module"]["code"])
if ex:
return ", ".join(ex)
return ""
def descr_abs(a):
ex = []
for ev in a.get("absent", []):
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
context.Notes, moduleimpl_id=ev["moduleimpl_id"]
)[0]
if format == "html":
ex.append(
'<a href="Notes/moduleimpl_status?moduleimpl_id=%s">%s</a>'
% (mod["moduleimpl_id"], mod["module"]["code"])
)
else:
ex.append(mod["module"]["code"])
if ex:
return ", ".join(ex)
return ""
# ajoute date formatée et évaluations
for L in (absnonjust, absjust):
for a in L:
if with_evals:
a["exams"] = descr_exams(a)
a["datedmy"] = a["jour"].strftime("%d/%m/%Y")
a["ampm"] = int(a["matin"])
a["matin"] = matin(a["matin"])
index = a["description"].find(")")
if index != -1:
a["motif"] = a["description"][1:index]
else:
a["motif"] = ""
a["description"] = descr_abs(a) or ""
# ajoute lien pour justifier
if format == "html":
for a in absnonjust:
a["justlink"] = "<em>justifier</em>"
a[
"_justlink_target"
] = "doJustifAbsence?etudid=%s&datedebut=%s&datefin=%s&demijournee=%s" % (
etudid,
a["datedmy"],
a["datedmy"],
a["ampm"],
)
#
titles = {
"datedmy": "Date",
"matin": "",
"exams": "Examens ce jour",
"justlink": "",
"description": "Modules",
"motif": "Motif",
}
columns_ids = ["datedmy", "matin"]
if format in ("json", "xml"):
columns_ids += ["jour", "ampm"]
if with_evals:
columns_ids.append("exams")
columns_ids.append("description")
columns_ids.append("motif")
if format == "html":
columns_ids.append("justlink")
return titles, columns_ids, absnonjust, absjust
def index_html(context, REQUEST=None): def index_html(context, REQUEST=None):
"""Gestionnaire absences, page principale""" """Gestionnaire absences, page principale"""
# crude portage from 1999 DTML # crude portage from 1999 DTML

View File

@ -44,15 +44,12 @@ Pour chaque étudiant commun:
""" """
from collections import OrderedDict from app.scodoc.notes_log import log
from app.scodoc import sco_apogee_csv
import sco_utils as scu from app.scodoc.gen_tables import GenTable
from notes_log import log from app.scodoc.sco_exceptions import ScoValueError
import sco_apogee_csv from app.scodoc import html_sco_header
from gen_tables import GenTable from app.scodoc import sco_preferences
from sco_exceptions import ScoValueError
import html_sco_header
import sco_preferences
_help_txt = """ _help_txt = """
<div class="help"> <div class="help">

View File

@ -95,19 +95,32 @@ try:
except: except:
chardet_detect = None chardet_detect = None
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from sco_exceptions import ScoValueError, FormatError from app.scodoc.sco_exceptions import ScoValueError, FormatError
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from sco_formsemestre import ApoEtapeVDI from app.scodoc.sco_formsemestre import ApoEtapeVDI
from sco_codes_parcours import code_semestre_validant from app.scodoc.sco_codes_parcours import code_semestre_validant
from sco_codes_parcours import ATT, ATB, ADM, ADC, ADJ, ATJ, ATB, AJ, CMP, NAR, RAT, DEF from app.scodoc.sco_codes_parcours import (
import sco_codes_parcours ADC,
import sco_formsemestre ADJ,
import sco_formsemestre_status ADM,
import sco_parcours_dut AJ,
import scolars ATB,
ATJ,
ATT,
CMP,
DEF,
NAR,
RAT,
)
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_etud
APO_PORTAL_ENCODING = ( APO_PORTAL_ENCODING = (
"utf8" # encodage du fichier CSV Apogée (était 'ISO-8859-1' avant jul. 2016) "utf8" # encodage du fichier CSV Apogée (était 'ISO-8859-1' avant jul. 2016)
@ -286,7 +299,7 @@ class ApoEtud(dict):
return "ApoEtud( nom='%s', nip='%s' )" % (self["nom"], self["nip"]) return "ApoEtud( nom='%s', nip='%s' )" % (self["nom"], self["nip"])
def lookup_scodoc(self, context, etape_formsemestre_ids): def lookup_scodoc(self, context, etape_formsemestre_ids):
etuds = scolars.get_etud_info(code_nip=self["nip"], filled=True) etuds = sco_etud.get_etud_info(code_nip=self["nip"], filled=True)
if not etuds: if not etuds:
# pas dans ScoDoc # pas dans ScoDoc
self.etud = None self.etud = None
@ -971,9 +984,9 @@ class ApoData:
s.add(code) s.add(code)
continue continue
# associé à une UE: # associé à une UE:
nt = self.sco_core.get_notes_cache( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
context, self.context, sem["formsemestre_id"]
).get_NotesTable(self.context, sem["formsemestre_id"]) )
for ue in nt.get_ues(): for ue in nt.get_ues():
if ue["code_apogee"] == code: if ue["code_apogee"] == code:
s.add(code) s.add(code)

View File

@ -52,24 +52,22 @@ import re
import shutil import shutil
import glob import glob
import sco_utils as scu import app.scodoc.sco_utils as scu
from config import Config from config import Config
import notesdb as ndb from app.scodoc.notes_log import log
from notes_log import log from app.scodoc.TrivialFormulator import TrivialFormulator
from sco_recapcomplet import make_formsemestre_recapcomplet from app.scodoc.sco_exceptions import (
from TrivialFormulator import TrivialFormulator
from sco_exceptions import (
AccessDenied, AccessDenied,
) )
import html_sco_header from app.scodoc import html_sco_header
import sco_bulletins_pdf from app.scodoc import sco_bulletins_pdf
import sco_excel from app.scodoc import sco_excel
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_groups_view from app.scodoc import sco_groups_view
import sco_permissions from app.scodoc import sco_permissions_check
import sco_pvjury from app.scodoc import sco_pvjury
import sco_pvpdf from app.scodoc import sco_pvpdf
class BaseArchiver: class BaseArchiver:
@ -276,6 +274,8 @@ def do_formsemestre_archive(
Store: Store:
- tableau recap (xls), pv jury (xls et pdf), bulletins (xml et pdf), lettres individuelles (pdf) - tableau recap (xls), pv jury (xls et pdf), bulletins (xml et pdf), lettres individuelles (pdf)
""" """
from app.scodoc.sco_recapcomplet import make_formsemestre_recapcomplet
archive_id = PVArchive.create_obj_archive(context, formsemestre_id, description) archive_id = PVArchive.create_obj_archive(context, formsemestre_id, description)
date = PVArchive.get_archive_date(archive_id).strftime("%d/%m/%Y à %H:%M") date = PVArchive.get_archive_date(archive_id).strftime("%d/%m/%Y à %H:%M")
@ -370,7 +370,7 @@ def formsemestre_archive(context, REQUEST, formsemestre_id, group_ids=[]):
"""Make and store new archive for this formsemestre. """Make and store new archive for this formsemestre.
(all students or only selected groups) (all students or only selected groups)
""" """
if not sco_permissions.can_edit_pv(context, REQUEST, formsemestre_id): if not sco_permissions_check.can_edit_pv(context, REQUEST, formsemestre_id):
raise AccessDenied( raise AccessDenied(
"opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER) "opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER)
) )
@ -553,7 +553,7 @@ def formsemestre_delete_archive(
context, REQUEST, formsemestre_id, archive_name, dialog_confirmed=False context, REQUEST, formsemestre_id, archive_name, dialog_confirmed=False
): ):
"""Delete an archive""" """Delete an archive"""
if not sco_permissions.can_edit_pv(context, REQUEST, formsemestre_id): if not sco_permissions_check.can_edit_pv(context, REQUEST, formsemestre_id):
raise AccessDenied( raise AccessDenied(
"opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER) "opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER)
) )

View File

@ -30,19 +30,17 @@
les dossiers d'admission et autres pièces utiles. les dossiers d'admission et autres pièces utiles.
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc import ImportScolars
import ImportScolars from app.scodoc import sco_groups
import sco_formsemestre from app.scodoc import sco_trombino
import sco_groups from app.scodoc import sco_excel
import sco_trombino from app.scodoc import sco_archives
import sco_excel from app.scodoc.sco_permissions import Permission
import sco_archives from app.scodoc.sco_exceptions import AccessDenied
from sco_permissions import Permission from app.scodoc.TrivialFormulator import TrivialFormulator
from sco_exceptions import AccessDenied from app.scodoc import html_sco_header
from TrivialFormulator import TrivialFormulator from app.scodoc import sco_etud
import html_sco_header
import scolars
class EtudsArchiver(sco_archives.BaseArchiver): class EtudsArchiver(sco_archives.BaseArchiver):
@ -131,7 +129,7 @@ def etud_upload_file_form(context, REQUEST, etudid):
raise AccessDenied( raise AccessDenied(
"opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER) "opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER)
) )
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(
context, context,
@ -196,7 +194,7 @@ def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed
raise AccessDenied( raise AccessDenied(
"opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER) "opération non autorisée pour %s" % str(REQUEST.AUTHENTICATED_USER)
) )
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
archive_id = EtudsArchive.get_id_from_name(context, etudid, archive_name) archive_id = EtudsArchive.get_id_from_name(context, etudid, archive_name)
dest_url = "ficheEtud?etudid=%s" % etudid dest_url = "ficheEtud?etudid=%s" % etudid
if not dialog_confirmed: if not dialog_confirmed:

View File

@ -32,7 +32,7 @@ import time
from types import StringType from types import StringType
import pprint import pprint
import urllib import urllib
import htmlutils from app.scodoc import htmlutils
import email import email
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
@ -41,27 +41,38 @@ from email.header import Header
from reportlab.lib.colors import Color from reportlab.lib.colors import Color
import mails from app.scodoc import mails
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from sco_exceptions import AccessDenied from app.scodoc.sco_exceptions import AccessDenied
import sco_abs from app.scodoc import html_sco_header
import sco_abs_views from app.scodoc import sco_abs_views
import sco_bulletins_generator from app.scodoc import sco_bulletins_generator
import sco_bulletins_json from app.scodoc import sco_bulletins_json
import sco_bulletins_xml from app.scodoc import sco_bulletins_xml
import sco_codes_parcours from app.scodoc import sco_codes_parcours
import sco_core from app.scodoc import sco_core
import sco_formations from app.scodoc import sco_evaluations
import sco_formsemestre from app.scodoc import sco_formations
import sco_formsemestre_status from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_photos from app.scodoc import sco_photos
import sco_preferences from app.scodoc import sco_permissions_check
import sco_pvjury from app.scodoc import sco_preferences
import scolars from app.scodoc import sco_pvjury
from app.scodoc import sco_etud
# ----- CLASSES DE BULLETINS DE NOTES
import sco_bulletins_standard
import sco_bulletins_legacy
# import sco_bulletins_example # format exemple (à désactiver en production)
# ... ajouter ici vos modules ...
import sco_bulletins_ucac # format expérimental UCAC Cameroun
def make_context_dict(context, sem, etud): def make_context_dict(context, sem, etud):
@ -85,7 +96,8 @@ def make_context_dict(context, sem, etud):
C["anneesem"] = annee C["anneesem"] = annee
C.update(etud) C.update(etud)
# copie preferences # copie preferences
for name in sco_preferences.PREFS_NAMES: # XXX devrait acceder directement à un dict de preferences, à revoir
for name in sco_preferences.get_base_preferences(context).prefs_name:
C[name] = sco_preferences.get_preference(context, name, sem["formsemestre_id"]) C[name] = sco_preferences.get_preference(context, name, sem["formsemestre_id"])
# ajoute groupes et group_0, group_1, ... # ajoute groupes et group_0, group_1, ...
@ -114,6 +126,8 @@ def formsemestre_bulletinetud_dict(
Cette fonction est utilisée pour les bulletins HTML et PDF, mais pas ceux en XML. Cette fonction est utilisée pour les bulletins HTML et PDF, mais pas ceux en XML.
""" """
from app.scodoc import sco_abs
if not version in ("short", "long", "selectedevals"): if not version in ("short", "long", "selectedevals"):
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
@ -139,7 +153,7 @@ def formsemestre_bulletinetud_dict(
I["formation"]["type_parcours"] I["formation"]["type_parcours"]
) )
# Infos sur l'etudiant # Infos sur l'etudiant
I["etud"] = scolars.get_etud_info(etudid=etudid, filled=1)[0] I["etud"] = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
I["descr_situation"] = I["etud"]["inscriptionstr"] I["descr_situation"] = I["etud"]["inscriptionstr"]
if I["etud"]["inscription_formsemestre_id"]: if I["etud"]["inscription_formsemestre_id"]:
I[ I[
@ -200,7 +214,7 @@ def formsemestre_bulletinetud_dict(
# --- Appreciations # --- Appreciations
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
apprecs = scolars.appreciations_list( apprecs = sco_etud.appreciations_list(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id} cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
) )
I["appreciations_list"] = apprecs I["appreciations_list"] = apprecs
@ -427,13 +441,15 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS
if bul_show_abs_modules: if bul_show_abs_modules:
mod_abs = [ mod_abs = [
context.Absences.CountAbs( sco_abs.CountAbs(
context,
etudid=etudid, etudid=etudid,
debut=debut_sem, debut=debut_sem,
fin=fin_sem, fin=fin_sem,
moduleimpl_id=modimpl["moduleimpl_id"], moduleimpl_id=modimpl["moduleimpl_id"],
), ),
context.Absences.CountAbsJust( sco_abs.CountAbsJust(
context,
etudid=etudid, etudid=etudid,
debut=debut_sem, debut=debut_sem,
fin=fin_sem, fin=fin_sem,
@ -662,7 +678,7 @@ def etud_descr_situation_semestre(
# --- Situation et décisions jury # --- Situation et décisions jury
# demission/inscription ? # demission/inscription ?
events = scolars.scolar_events_list( events = sco_etud.scolar_events_list(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id} cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
) )
date_inscr = None date_inscr = None
@ -680,7 +696,7 @@ def etud_descr_situation_semestre(
"etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid=%s !" "etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid=%s !"
% etudid % etudid
) )
scolars.scolar_events_delete(cnx, event["event_id"]) sco_etud.scolar_events_delete(cnx, event["event_id"])
else: else:
date_inscr = event["event_date"] date_inscr = event["event_date"]
elif event_type == "DEMISSION": elif event_type == "DEMISSION":
@ -690,7 +706,7 @@ def etud_descr_situation_semestre(
"etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid=%s !" "etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid=%s !"
% etudid % etudid
) )
scolars.scolar_events_delete(cnx, event["event_id"]) sco_etud.scolar_events_delete(cnx, event["event_id"])
else: else:
date_dem = event["event_date"] date_dem = event["event_date"]
elif event_type == "DEFAILLANCE": elif event_type == "DEFAILLANCE":
@ -699,7 +715,7 @@ def etud_descr_situation_semestre(
"etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid=%s !" "etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid=%s !"
% etudid % etudid
) )
scolars.scolar_events_delete(cnx, event["event_id"]) sco_etud.scolar_events_delete(cnx, event["event_id"])
else: else:
date_def = event["event_date"] date_def = event["event_date"]
if show_date_inscr: if show_date_inscr:
@ -781,7 +797,7 @@ def formsemestre_bulletinetud(
): ):
"page bulletin de notes" "page bulletin de notes"
try: try:
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
except: except:
return scu.log_unknown_etud(context, REQUEST, format=format) return scu.log_unknown_etud(context, REQUEST, format=format)
@ -1092,6 +1108,7 @@ def _formsemestre_bulletinetud_header_html(
H.append("""</select></td>""") H.append("""</select></td>""")
# Menu # Menu
endpoint = "notes.formsemestre_bulletinetud" endpoint = "notes.formsemestre_bulletinetud"
url = REQUEST.URL0
qurl = urllib.quote_plus(url + "?" + REQUEST.QUERY_STRING) qurl = urllib.quote_plus(url + "?" + REQUEST.QUERY_STRING)
menuBul = [ menuBul = [
@ -1182,7 +1199,7 @@ def _formsemestre_bulletinetud_header_html(
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"etudid": etudid, "etudid": etudid,
}, },
"enabled": sco_permcan_validate_semdate_sem( "enabled": sco_permissions_check.can_validate_sem(
context, REQUEST, formsemestre_id context, REQUEST, formsemestre_id
), ),
}, },
@ -1193,7 +1210,7 @@ def _formsemestre_bulletinetud_header_html(
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"etudid": etudid, "etudid": etudid,
}, },
"enabled": sco_permcan_validate_semdate_sem( "enabled": sco_permissions_check.can_validate_sem(
context, REQUEST, formsemestre_id context, REQUEST, formsemestre_id
), ),
}, },
@ -1204,7 +1221,7 @@ def _formsemestre_bulletinetud_header_html(
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"etudid": etudid, "etudid": etudid,
}, },
"enabled": sco_permcan_validate_semdate_sem( "enabled": sco_permissions_check.can_validate_sem(
context, REQUEST, formsemestre_id context, REQUEST, formsemestre_id
), ),
}, },

View File

@ -27,16 +27,12 @@
"""Generation bulletins de notes: exemple minimal pour les programmeurs """Generation bulletins de notes: exemple minimal pour les programmeurs
""" """
import VERSION
import sco_utils as scu
import sco_pdf
import sco_preferences
from notes_log import log
import sco_bulletins_generator
import sco_bulletins_standard
from reportlab.platypus import Paragraph from reportlab.platypus import Paragraph
from app.scodoc import sco_pdf
from app.scodoc import sco_bulletins_generator
from app.scodoc import sco_bulletins_standard
class BulletinGeneratorExample(sco_bulletins_standard.BulletinGeneratorStandard): class BulletinGeneratorExample(sco_bulletins_standard.BulletinGeneratorStandard):
"""Un exemple simple de bulletin de notes en version PDF seulement. """Un exemple simple de bulletin de notes en version PDF seulement.

View File

@ -50,18 +50,16 @@ import reportlab
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
import sco_utils from app.scodoc import sco_utils
import VERSION from app.scodoc import VERSION
from sco_exceptions import NoteProcessError from app.scodoc.sco_exceptions import NoteProcessError
import sco_preferences from app.scodoc.notes_log import log
from notes_log import log from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_pdf
import sco_pdf from app.scodoc.sco_pdf import PDFLOCK
from sco_pdf import PDFLOCK
BULLETIN_CLASSES = ( # Liste des types des classes de générateurs de bulletins PDF:
collections.OrderedDict() BULLETIN_CLASSES = collections.OrderedDict()
) # liste des types des classes de générateurs de bulletins PDF
def register_bulletin_class(klass): def register_bulletin_class(klass):
@ -87,6 +85,8 @@ def bulletin_get_class(class_name):
def bulletin_get_class_name_displayed(context, formsemestre_id): def bulletin_get_class_name_displayed(context, formsemestre_id):
"""Le nom du générateur utilisé, en clair""" """Le nom du générateur utilisé, en clair"""
from app.scodoc import sco_preferences
bul_class_name = sco_preferences.get_preference( bul_class_name = sco_preferences.get_preference(
context, "bul_class_name", formsemestre_id context, "bul_class_name", formsemestre_id
) )
@ -113,6 +113,8 @@ class BulletinGenerator:
filigranne=None, filigranne=None,
server_name=None, server_name=None,
): ):
from app.scodoc import sco_preferences
if not version in ("short", "long", "selectedevals"): if not version in ("short", "long", "selectedevals"):
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
self.context = context self.context = context
@ -191,6 +193,8 @@ class BulletinGenerator:
Sinon, renvoie juste une liste d'objets PLATYPUS pour intégration Sinon, renvoie juste une liste d'objets PLATYPUS pour intégration
dans un autre document. dans un autre document.
""" """
from app.scodoc import sco_preferences
formsemestre_id = self.infos["formsemestre_id"] formsemestre_id = self.infos["formsemestre_id"]
# partie haute du bulletin # partie haute du bulletin
@ -273,6 +277,8 @@ def make_formsemestre_bulletinetud(
selon les préférences du semestre. selon les préférences du semestre.
""" """
from app.scodoc import sco_preferences
if not version in ("short", "long", "selectedevals"): if not version in ("short", "long", "selectedevals"):
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
@ -325,15 +331,3 @@ def make_formsemestre_bulletinetud(
filename = bul_generator.get_filename() filename = bul_generator.get_filename()
return data, filename return data, filename
# ---------------------------------------------------------------------------
# Classes de bulletins:
import sco_bulletins_standard
import sco_bulletins_legacy
# import sco_bulletins_example # format exemple (à désactiver en production)
# ... ajouter ici vos modules ...
import sco_bulletins_ucac # format expérimental UCAC Cameroun

View File

@ -31,18 +31,17 @@
import datetime import datetime
import json import json
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_abs from app.scodoc import sco_abs
import sco_bulletins from app.scodoc import sco_core
import sco_core from app.scodoc import sco_edit_ue
import sco_edit_ue from app.scodoc import sco_evaluations
import sco_evaluations from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_groups
import sco_groups from app.scodoc import sco_photos
import sco_photos from app.scodoc import sco_preferences
import sco_preferences from app.scodoc import sco_etud
import scolars
# -------- Bulletin en JSON # -------- Bulletin en JSON
@ -90,6 +89,7 @@ def formsemestre_bulletinetud_published_dict(
"""Dictionnaire representant les informations _publiees_ du bulletin de notes """Dictionnaire representant les informations _publiees_ du bulletin de notes
Utilisé pour JSON, devrait l'être aussi pour XML. (todo) Utilisé pour JSON, devrait l'être aussi pour XML. (todo)
""" """
from app.scodoc import sco_bulletins
d = {} d = {}
@ -120,7 +120,7 @@ def formsemestre_bulletinetud_published_dict(
d.update(**el) d.update(**el)
# Infos sur l'etudiant # Infos sur l'etudiant
etudinfo = scolars.get_etud_info(etudid=etudid, filled=1)[0] etudinfo = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
d["etudiant"] = dict( d["etudiant"] = dict(
etudid=etudid, etudid=etudid,
@ -405,7 +405,7 @@ def formsemestre_bulletinetud_published_dict(
# --- Appreciations # --- Appreciations
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
apprecs = scolars.appreciations_list( apprecs = sco_etud.appreciations_list(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id} cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
) )
d["appreciation"] = [] d["appreciation"] = []

View File

@ -35,17 +35,16 @@
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
from sco_permissions import Permission from app.scodoc.sco_permissions import Permission
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_pdf from app.scodoc import sco_pdf
from sco_pdf import Color, Paragraph, Spacer, Table from app.scodoc.sco_pdf import Color, Paragraph, Spacer, Table
from sco_pdf import blue, cm, mm from app.scodoc.sco_pdf import blue, cm, mm
from sco_pdf import SU from app.scodoc.sco_pdf import SU
import sco_preferences from app.scodoc import sco_preferences
from notes_log import log from app.scodoc import sco_bulletins_generator
import sco_bulletins_generator from app.scodoc import sco_bulletins_pdf
import sco_bulletins_pdf
# Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences) # Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences)
class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator): class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
@ -320,7 +319,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
# le dir. des etud peut ajouter des appreciations, # le dir. des etud peut ajouter des appreciations,
# mais aussi le chef (perm. ScoEtudInscrit) # mais aussi le chef (perm. ScoEtudInscrit)
can_edit_app = (str(authuser) in self.infos["responsables"]) or ( can_edit_app = (str(authuser) in self.infos["responsables"]) or (
authuser.has_permission(Permission.ScoEtudInscrit, self.context) authuser.has_permission(Permission.ScoEtudInscrit)
) )
H.append('<div class="bull_appreciations">') H.append('<div class="bull_appreciations">')
if I["appreciations_list"]: if I["appreciations_list"]:

View File

@ -50,24 +50,22 @@ Pour définir un nouveau type de bulletin:
Chaque semestre peut si nécessaire utiliser un type de bulletin différent. Chaque semestre peut si nécessaire utiliser un type de bulletin différent.
""" """
import htmlutils
import time import time
import pprint
import traceback import traceback
import re import re
import os import os
import cStringIO import cStringIO
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
import VERSION from app.scodoc import VERSION
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import sco_bulletins from app.scodoc import sco_core
import sco_core from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_pdf
import sco_pdf from app.scodoc import sco_preferences
import sco_preferences from app.scodoc import sco_etud
import scolars
def pdfassemblebulletins( def pdfassemblebulletins(
@ -167,6 +165,8 @@ def get_formsemestre_bulletins_pdf(
context, formsemestre_id, REQUEST, version="selectedevals" context, formsemestre_id, REQUEST, version="selectedevals"
): ):
"document pdf et filename" "document pdf et filename"
from app.scodoc import sco_bulletins
cached = sco_core.get_notes_cache( cached = sco_core.get_notes_cache(
context, context,
).get_bulletins_pdf(formsemestre_id, version) ).get_bulletins_pdf(formsemestre_id, version)
@ -229,7 +229,9 @@ def get_formsemestre_bulletins_pdf(
def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"): def get_etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
"Bulletins pdf de tous les semestres de l'étudiant, et filename" "Bulletins pdf de tous les semestres de l'étudiant, et filename"
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] from app.scodoc import sco_bulletins
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
fragments = [] fragments = []
bookmarks = {} bookmarks = {}
filigrannes = {} filigrannes = {}

View File

@ -46,33 +46,25 @@ de la forme %(XXX)s sont remplacées par la valeur de XXX, pour XXX dans:
Balises img: actuellement interdites. Balises img: actuellement interdites.
""" """
import datetime
import traceback
import re
import jaxml
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_formsemestre from app.scodoc.sco_pdf import Color, Paragraph, Spacer, Table
import sco_pdf from app.scodoc.sco_pdf import blue, cm, mm
from sco_pdf import Color, Paragraph, Spacer, Table from app.scodoc.sco_pdf import SU
from sco_pdf import blue, cm, mm from app.scodoc import sco_preferences
from sco_pdf import SU from app.scodoc.sco_permissions import Permission
import sco_preferences from app.scodoc.sco_codes_parcours import (
from notes_log import log
from sco_permissions import Permission
from sco_codes_parcours import (
UE_COLORS, UE_COLORS,
UE_DEFAULT_COLOR, UE_DEFAULT_COLOR,
UE_ELECTIVE, UE_ELECTIVE,
UE_SPORT, UE_SPORT,
UE_STANDARD, UE_STANDARD,
) )
import sco_bulletins_generator from app.scodoc import sco_bulletins_generator
import sco_bulletins_pdf from app.scodoc import sco_bulletins_pdf
import sco_groups from app.scodoc import sco_groups
import sco_evaluations from app.scodoc import sco_evaluations
import gen_tables from app.scodoc import gen_tables
import sco_codes_parcours
# Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences) # Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences)
class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator): class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
@ -153,7 +145,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
# le dir. des etud peut ajouter des appreciations, # le dir. des etud peut ajouter des appreciations,
# mais aussi le chef (perm. ScoEtudInscrit) # mais aussi le chef (perm. ScoEtudInscrit)
can_edit_app = (str(self.authuser) in self.infos["responsables"]) or ( can_edit_app = (str(self.authuser) in self.infos["responsables"]) or (
self.authuser.has_permission(Permission.ScoEtudInscrit, self.context) self.authuser.has_permission(Permission.ScoEtudInscrit)
) )
H.append('<div class="bull_appreciations">') H.append('<div class="bull_appreciations">')
for app in self.infos["appreciations_list"]: for app in self.infos["appreciations_list"]:

View File

@ -33,18 +33,15 @@ On redéfini la table centrale du bulletin de note et hérite de tout le reste d
E. Viennet, juillet 2011 E. Viennet, juillet 2011
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_formsemestre from app.scodoc.sco_pdf import blue, cm, mm
import sco_pdf from app.scodoc.sco_pdf import Color, Paragraph, Spacer, Table
from sco_pdf import blue, cm, mm
from sco_pdf import Color, Paragraph, Spacer, Table
import sco_preferences from app.scodoc import sco_preferences
from notes_log import log from app.scodoc import sco_bulletins_generator
import sco_bulletins_generator from app.scodoc import sco_bulletins_standard
import sco_bulletins_standard from app.scodoc import gen_tables
import gen_tables
class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard): class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):

View File

@ -40,19 +40,19 @@ Je propose de considérer le XMl comme "deprecated" et de ne plus le modifier, s
import datetime import datetime
import jaxml import jaxml
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import sco_abs from app.scodoc import sco_abs
import sco_bulletins from app.scodoc import sco_codes_parcours
import sco_codes_parcours from app.scodoc import sco_core
import sco_core from app.scodoc import sco_edit_ue
import sco_evaluations from app.scodoc import sco_evaluations
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_photos from app.scodoc import sco_photos
import sco_preferences from app.scodoc import sco_preferences
import scolars from app.scodoc import sco_etud
# -------- Bulletin en XML # -------- Bulletin en XML
# (fonction séparée: n'utilise pas formsemestre_bulletinetud_dict() # (fonction séparée: n'utilise pas formsemestre_bulletinetud_dict()
@ -70,6 +70,8 @@ def make_xml_formsemestre_bulletinetud(
version="long", version="long",
): ):
"bulletin au format XML" "bulletin au format XML"
from app.scodoc import sco_bulletins
log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid)) log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid))
if REQUEST: if REQUEST:
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
@ -102,7 +104,7 @@ def make_xml_formsemestre_bulletinetud(
doc.bulletinetud(**el) doc.bulletinetud(**el)
# Infos sur l'etudiant # Infos sur l'etudiant
etudinfo = scolars.get_etud_info(etudid=etudid, filled=1)[0] etudinfo = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
doc._push() doc._push()
doc.etudiant( doc.etudiant(
etudid=etudid, etudid=etudid,
@ -416,7 +418,7 @@ def make_xml_formsemestre_bulletinetud(
doc._pop() doc._pop()
# --- Appreciations # --- Appreciations
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
apprecs = scolars.appreciations_list( apprecs = sco_etud.appreciations_list(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id} cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
) )
for app in apprecs: for app in apprecs:

View File

@ -29,8 +29,7 @@
""" """
from notes_log import log import time
import thread, time
# Cache data # Cache data
class simpleCache: class simpleCache:

View File

@ -32,26 +32,24 @@ import traceback
import pprint import pprint
from types import FloatType from types import FloatType
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from sco_utils import ( from app.scodoc.sco_utils import (
NOTES_ATTENTE, NOTES_ATTENTE,
NOTES_NEUTRALISE, NOTES_NEUTRALISE,
EVALUATION_NORMALE, EVALUATION_NORMALE,
EVALUATION_RATTRAPAGE, EVALUATION_RATTRAPAGE,
EVALUATION_SESSION2, EVALUATION_SESSION2,
) )
from sco_exceptions import ScoException from app.scodoc.sco_exceptions import ScoException
from notesdb import EditableTable, quote_html from app.scodoc.notes_log import log
from notes_log import log, sendAlarm from app.scodoc import sco_abs
import sco_abs from app.scodoc import sco_edit_module
import sco_edit_module from app.scodoc import sco_evaluations
import sco_evaluations from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_formulas
import sco_formulas from app.scodoc import sco_moduleimpl
import sco_groups from app.scodoc import sco_etud
import sco_moduleimpl
import scolars
def moduleimpl_has_expression(context, mod): def moduleimpl_has_expression(context, mod):
@ -89,7 +87,7 @@ def formsemestre_expressions_use_abscounts(context, formsemestre_id):
return False return False
_formsemestre_ue_computation_exprEditor = EditableTable( _formsemestre_ue_computation_exprEditor = ndb.EditableTable(
"notes_formsemestre_ue_computation_expr", "notes_formsemestre_ue_computation_expr",
"notes_formsemestre_ue_computation_expr_id", "notes_formsemestre_ue_computation_expr_id",
( (
@ -117,7 +115,7 @@ def get_ue_expression(formsemestre_id, ue_id, cnx, html_quote=False):
expr = el[0]["computation_expr"].strip() expr = el[0]["computation_expr"].strip()
if expr and expr[0] != "#": if expr and expr[0] != "#":
if html_quote: if html_quote:
expr = quote_html(expr) expr = ndb.quote_html(expr)
return expr return expr
else: else:
return None return None
@ -169,7 +167,7 @@ def compute_user_formula(
if user_moy != "NA0" and user_moy != "NA": if user_moy != "NA0" and user_moy != "NA":
user_moy = float(user_moy) user_moy = float(user_moy)
if (user_moy > 20) or (user_moy < 0): if (user_moy > 20) or (user_moy < 0):
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
raise ScoException( raise ScoException(
"""valeur moyenne %s hors limite pour <a href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s">%s</a>""" """valeur moyenne %s hors limite pour <a href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s">%s</a>"""
@ -231,8 +229,8 @@ def do_moduleimpl_moyennes(context, nt, mod):
eval_rattr = None eval_rattr = None
for e in evals: for e in evals:
e["nb_inscrits"] = e["etat"]["nb_inscrits"] e["nb_inscrits"] = e["etat"]["nb_inscrits"]
NotesDB = context._notes_getall( NotesDB = sco_evaluations.do_evaluation_get_all_notes(
e["evaluation_id"] context, e["evaluation_id"]
) # toutes, y compris demissions ) # toutes, y compris demissions
# restreint aux étudiants encore inscrits à ce module # restreint aux étudiants encore inscrits à ce module
notes = [ notes = [

View File

@ -7,7 +7,7 @@
""" """
from attrdict import AttrDict from attrdict import AttrDict
import bonus_sport from app.scodoc import bonus_sport
CONFIG = AttrDict() CONFIG = AttrDict()

View File

@ -6,8 +6,8 @@
import os import os
import sys import sys
from notes_log import log from app.scodoc.notes_log import log
import sco_config from app.scodoc import sco_config
# scodoc_local defines a CONFIG object # scodoc_local defines a CONFIG object
# here we check if there is a local config file # here we check if there is a local config file

View File

@ -6,35 +6,12 @@
import time import time
import thread import thread
import types
from flask import url_for
import sco_utils as scu
from notes_log import log
from scodoc_manager import sco_mgr from scodoc_manager import sco_mgr
from sco_exceptions import ScoInvalidDept, NoteProcessError import app.scodoc.sco_utils as scu
from sco_parcours_dut import list_formsemestre_utilisateurs_uecap from app.scodoc.notes_log import log
import sco_cache from app.scodoc.sco_exceptions import NoteProcessError
import sco_core from app.scodoc import sco_cache
def sco_get_version(context, REQUEST=None):
"""Une fonction typique de ScoDoc7"""
return """<html><body><p>%s</p></body></html>""" % scu.SCOVERSION
# def test_refactor(context, x=1):
# x = context.toto()
# y = ("context=" + sco_edit_module.module_is_locked(context, "alpha")) + "23"
# z = html_sco_header.sco_header(
# context,
# a_long_argument_hahahahaha=1,
# another_very_long_arggggggggggggg=2,
# z=6,
# u=99,
# kkkkkk=1,
# )
# #
@ -134,6 +111,8 @@ class CacheNotesTable:
def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # > def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # >
"expire cache pour un semestre (ou tous si pas d'argument)" "expire cache pour un semestre (ou tous si pas d'argument)"
from app.scodoc import sco_parcours_dut
log( log(
"inval_cache, formsemestre_id=%s pdfonly=%s (id=%s)" "inval_cache, formsemestre_id=%s pdfonly=%s (id=%s)"
% (formsemestre_id, pdfonly, id(self)) # > % (formsemestre_id, pdfonly, id(self)) # >
@ -151,14 +130,16 @@ class CacheNotesTable:
self.cache = {} self.cache = {}
self.pdfcache = {} self.pdfcache = {}
self._call_all_listeners() self._call_all_listeners()
sco_core.get_evaluations_cache( get_evaluations_cache(
context, context,
).inval_cache() ).inval_cache()
else: else:
# formsemestre_id modifié: # formsemestre_id modifié:
# on doit virer formsemestre_id et tous les semestres # on doit virer formsemestre_id et tous les semestres
# susceptibles d'utiliser des UE capitalisées de ce semestre. # susceptibles d'utiliser des UE capitalisées de ce semestre.
to_trash = [formsemestre_id] + list_formsemestre_utilisateurs_uecap( to_trash = [
formsemestre_id
] + sco_parcours_dut.list_formsemestre_utilisateurs_uecap(
context, formsemestre_id context, formsemestre_id
) )
if not pdfonly: if not pdfonly:
@ -170,7 +151,7 @@ class CacheNotesTable:
) )
del self.cache[formsemestre_id] del self.cache[formsemestre_id]
self._call_listeners(formsemestre_id) self._call_listeners(formsemestre_id)
sco_core.get_evaluations_cache( get_evaluations_cache(
context, context,
).inval_cache() ).inval_cache()

View File

@ -30,16 +30,13 @@
(coût théorique en heures équivalent TD) (coût théorique en heures équivalent TD)
""" """
import notesdb as ndb import app.scodoc.sco_utils as scu
import sco_utils as scu from app.scodoc.gen_tables import GenTable
from notes_log import log from app.scodoc import sco_formsemestre
from gen_tables import GenTable from app.scodoc import sco_moduleimpl
import sco_excel, sco_pdf from app.scodoc import sco_formsemestre_status
from sco_pdf import SU from app.scodoc import VERSION
import sco_formsemestre from app.scodoc import sco_preferences
import sco_moduleimpl
import sco_formsemestre_status
import VERSION
def formsemestre_table_estim_cost( def formsemestre_table_estim_cost(

View File

@ -31,16 +31,19 @@ Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudi
from types import StringType from types import StringType
import safehtml import safehtml
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import VERSION from app.scodoc import VERSION
from sco_exceptions import AccessDenied from app.scodoc.sco_exceptions import AccessDenied
from scolog import logdb from app.scodoc.scolog import logdb
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_formsemestre from app.scodoc import html_sco_header
import sco_groups from app.scodoc import sco_core
import sco_tag_module from app.scodoc import sco_permissions_check
from app.scodoc import sco_preferences
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(context, start_year=None, format="html", REQUEST=None):
@ -104,7 +107,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True):
"""Rapport pour ces etudiants""" """Rapport pour ces etudiants"""
L = [] L = []
for etudid in etudids: for etudid in etudids:
etud = scolars.get_etud_info(filled=1, etudid=etudid)[0] etud = sco_etud.get_etud_info(filled=1, etudid=etudid)[0]
# retrouve le "dernier" semestre (au sens de la date de fin) # retrouve le "dernier" semestre (au sens de la date de fin)
sems = etud["sems"] sems = etud["sems"]
es = [(sems[i]["date_fin_iso"], i) for i in range(len(sems))] es = [(sems[i]["date_fin_iso"], i) for i in range(len(sems))]
@ -211,12 +214,12 @@ def report_debouche_ask_date(context, REQUEST=None):
# def debouche_set(context, object, value, REQUEST=None): # def debouche_set(context, object, value, REQUEST=None):
# """Set debouche (field in admission table, may be deprecated ?) # """Set debouche (field in admission table, may be deprecated ?)
# """ # """
# if not sco_permissions.can_edit_suivi(context, REQUEST): # if not sco_permissions_check.can_edit_suivi(context, REQUEST):
# raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") # raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
# adm_id = object # adm_id = object
# debouche = value.strip('-_ \t') # debouche = value.strip('-_ \t')
# cnx = ndb.GetDBConnexion() # cnx = ndb.GetDBConnexion()
# adms = scolars.admission_list(cnx, {'etudid' : etudid}) # adms = sco_etud.admission_list(cnx, {'etudid' : etudid})
# if not adms: # if not adms:
# raise ValueError('no admission info for %s !' % etudid) # raise ValueError('no admission info for %s !' % etudid)
# adm = adms[0] # adm = adms[0]
@ -263,7 +266,7 @@ def itemsuivi_get(cnx, itemsuivi_id, ignore_errors=False):
def itemsuivi_suppress(context, itemsuivi_id, REQUEST=None): def itemsuivi_suppress(context, itemsuivi_id, REQUEST=None):
"""Suppression d'un item""" """Suppression d'un item"""
if not sco_permissions.can_edit_suivi(context, REQUEST): if not sco_permissions_check.can_edit_suivi(context, REQUEST):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
item = itemsuivi_get(cnx, itemsuivi_id, ignore_errors=True) item = itemsuivi_get(cnx, itemsuivi_id, ignore_errors=True)
@ -277,7 +280,7 @@ def itemsuivi_create(
context, etudid, item_date=None, situation="", REQUEST=None, format=None context, etudid, item_date=None, situation="", REQUEST=None, format=None
): ):
"""Creation d'un item""" """Creation d'un item"""
if not sco_permissions.can_edit_suivi(context, REQUEST): if not sco_permissions_check.can_edit_suivi(context, REQUEST):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
itemsuivi_id = _itemsuivi_create( itemsuivi_id = _itemsuivi_create(
@ -295,7 +298,7 @@ def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None):
"""set item date """set item date
item_date is a string dd/mm/yyyy item_date is a string dd/mm/yyyy
""" """
if not sco_permissions.can_edit_suivi(context, REQUEST): if not sco_permissions_check.can_edit_suivi(context, REQUEST):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
# log('itemsuivi_set_date %s : %s' % (itemsuivi_id, item_date)) # log('itemsuivi_set_date %s : %s' % (itemsuivi_id, item_date))
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
@ -306,7 +309,7 @@ def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None):
def itemsuivi_set_situation(context, object, value, REQUEST=None): def itemsuivi_set_situation(context, object, value, REQUEST=None):
"""set situation""" """set situation"""
if not sco_permissions.can_edit_suivi(context, REQUEST): if not sco_permissions_check.can_edit_suivi(context, REQUEST):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
itemsuivi_id = object itemsuivi_id = object
situation = value.strip("-_ \t") situation = value.strip("-_ \t")
@ -364,7 +367,7 @@ def itemsuivi_tag_set(context, itemsuivi_id="", taglist=[], REQUEST=None):
a string with tag names separated by commas ("un;deux") a string with tag names separated by commas ("un;deux")
or a list of strings (["un", "deux"]) or a list of strings (["un", "deux"])
""" """
if not sco_permissions.can_edit_suivi(context, REQUEST): if not sco_permissions_check.can_edit_suivi(context, REQUEST):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
if not taglist: if not taglist:
taglist = [] taglist = []

View File

@ -27,17 +27,16 @@
"""Page accueil département (liste des semestres, etc) """Page accueil département (liste des semestres, etc)
""" """
import notesdb as ndb import app.scodoc.sco_utils as scu
import sco_utils as scu from app.scodoc.gen_tables import GenTable
from notes_log import log from app.scodoc.sco_permissions import Permission
import sco_modalites from app.scodoc import html_sco_header
import sco_news from app.scodoc import sco_formsemestre
import sco_up_to_date from app.scodoc import sco_formsemestre_inscriptions
import sco_formsemestre from app.scodoc import sco_modalites
from gen_tables import GenTable from app.scodoc import sco_news
from sco_permissions import Permission, ScoEtudInscrit, ScoEditApo from app.scodoc import sco_preferences
import html_sco_header from app.scodoc import sco_up_to_date
import sco_formsemestre_inscriptions
def index_html(context, REQUEST=None, showcodes=0, showsemtable=0): def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):

View File

@ -51,22 +51,23 @@ import fcntl
import subprocess import subprocess
import requests import requests
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from sco_exceptions import ScoValueError from app.scodoc import html_sco_header
from app.scodoc import sco_preferences
from app.scodoc import VERSION
from app.scodoc.sco_exceptions import ScoValueError
SCO_DUMP_LOCK = "/tmp/scodump.lock" SCO_DUMP_LOCK = "/tmp/scodump.lock"
def sco_dump_and_send_db(context, REQUEST=None): def sco_dump_and_send_db(context, REQUEST=None):
"""Dump base de données du département courant et l'envoie anonymisée pour debug""" """Dump base de données du département courant et l'envoie anonymisée pour debug"""
H = [html_sco_header.sco_header(context, REQUEST, page_title="Assistance technique")] H = [
html_sco_header.sco_header(context, REQUEST, page_title="Assistance technique")
]
# get currect (dept) DB name: # get currect (dept) DB name:
cursor = ndb.SimpleQuery(context, "SELECT current_database()", {}) cursor = ndb.SimpleQuery(context, "SELECT current_database()", {})
db_name = cursor.fetchone()[0] db_name = cursor.fetchone()[0]
@ -194,7 +195,7 @@ def _send_db(context, REQUEST, ano_db_name):
"sent_by": context.Users.user_info(str(REQUEST.AUTHENTICATED_USER))[ "sent_by": context.Users.user_info(str(REQUEST.AUTHENTICATED_USER))[
"nomcomplet" "nomcomplet"
], ],
"sco_version": scu.SCOVERSION, "sco_version": VERSION.SCOVERSION,
"sco_fullversion": scu.get_scodoc_version(), "sco_fullversion": scu.get_scodoc_version(),
}, },
) )

View File

@ -28,16 +28,19 @@
"""Ajout/Modification/Supression formations """Ajout/Modification/Supression formations
(portage from DTML) (portage from DTML)
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
import sco_codes_parcours from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
import sco_edit_module from app.scodoc import html_sco_header
import sco_edit_ue from app.scodoc import sco_codes_parcours
import sco_formsemestre from app.scodoc import sco_core
from sco_exceptions import ScoValueError from app.scodoc import sco_edit_module
import sco_formations from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_news
def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None): def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None):
@ -105,7 +108,7 @@ def do_formation_delete(context, oid, REQUEST):
# delete all UE in this formation # delete all UE in this formation
ues = sco_edit_ue.do_ue_list(context, {"formation_id": oid}) ues = sco_edit_ue.do_ue_list(context, {"formation_id": oid})
for ue in ues: for ue in ues:
do_ue_delete(ue["ue_id"], REQUEST=REQUEST, force=True) sco_edit_ue.do_ue_delete(context, ue["ue_id"], REQUEST=REQUEST, force=True)
sco_formations._formationEditor.delete(cnx, oid) sco_formations._formationEditor.delete(cnx, oid)
@ -113,7 +116,7 @@ def do_formation_delete(context, oid, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=oid, object=oid,
text="Suppression de la formation %(acronyme)s" % F, text="Suppression de la formation %(acronyme)s" % F,
) )
@ -277,7 +280,7 @@ def do_formation_create(context, args, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
text="Création de la formation %(titre)s (%(acronyme)s)" % args, text="Création de la formation %(titre)s (%(acronyme)s)" % args,
) )
return r return r

View File

@ -28,14 +28,13 @@
"""Ajout/Modification/Supression matieres """Ajout/Modification/Supression matieres
(portage from DTML) (portage from DTML)
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
import sco_edit_ue from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
import sco_formsemestre from app.scodoc import html_sco_header
import sco_news from app.scodoc import sco_core
from sco_exceptions import ScoValueError
_matiereEditor = ndb.EditableTable( _matiereEditor = ndb.EditableTable(
"notes_matieres", "notes_matieres",
@ -56,10 +55,8 @@ def do_matiere_edit(context, *args, **kw):
"edit a matiere" "edit a matiere"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check # check
mat = sco_edit_matiere.do_matiere_list( mat = do_matiere_list(context, {"matiere_id": args[0]["matiere_id"]})[0]
context, {"matiere_id": args[0]["matiere_id"]} if matiere_is_locked(context, mat["matiere_id"]):
)[0]
if sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# edit # edit
_matiereEditor.edit(cnx, *args, **kw) _matiereEditor.edit(cnx, *args, **kw)
@ -68,6 +65,10 @@ def do_matiere_edit(context, *args, **kw):
def do_matiere_create(context, args, REQUEST): def do_matiere_create(context, args, REQUEST):
"create a matiere" "create a matiere"
from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations
from app.scodoc import sco_news
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check # check
ue = sco_edit_ue.do_ue_list(context, {"ue_id": args["ue_id"]})[0] ue = sco_edit_ue.do_ue_list(context, {"ue_id": args["ue_id"]})[0]
@ -81,7 +82,7 @@ def do_matiere_create(context, args, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=ue["formation_id"], object=ue["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -90,6 +91,8 @@ def do_matiere_create(context, args, REQUEST):
def matiere_create(context, ue_id=None, REQUEST=None): def matiere_create(context, ue_id=None, REQUEST=None):
"""Creation d'une matiere""" """Creation d'une matiere"""
from app.scodoc import sco_edit_ue
UE = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0] UE = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0]
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(
@ -151,11 +154,16 @@ associé.
def do_matiere_delete(context, oid, REQUEST): def do_matiere_delete(context, oid, REQUEST):
"delete matiere and attached modules" "delete matiere and attached modules"
from app.scodoc import sco_formations
from app.scodoc import sco_edit_ue
from app.scodoc import sco_edit_module
from app.scodoc import sco_news
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check # check
mat = do_matiere_list(context, {"matiere_id": oid})[0] mat = do_matiere_list(context, {"matiere_id": oid})[0]
ue = sco_edit_ue.do_ue_list(context, {"ue_id": mat["ue_id"]})[0] ue = sco_edit_ue.do_ue_list(context, {"ue_id": mat["ue_id"]})[0]
locked = sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"]) locked = matiere_is_locked(context, mat["matiere_id"])
if locked: if locked:
log("do_matiere_delete: mat=%s" % mat) log("do_matiere_delete: mat=%s" % mat)
log("do_matiere_delete: ue=%s" % ue) log("do_matiere_delete: ue=%s" % ue)
@ -175,7 +183,7 @@ def do_matiere_delete(context, oid, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=ue["formation_id"], object=ue["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -183,6 +191,8 @@ def do_matiere_delete(context, oid, REQUEST):
def matiere_delete(context, matiere_id=None, REQUEST=None): def matiere_delete(context, matiere_id=None, REQUEST=None):
"""Delete an UE""" """Delete an UE"""
from app.scodoc import sco_edit_ue
M = do_matiere_list(context, args={"matiere_id": matiere_id})[0] M = do_matiere_list(context, args={"matiere_id": matiere_id})[0]
UE = sco_edit_ue.do_ue_list(context, args={"ue_id": M["ue_id"]})[0] UE = sco_edit_ue.do_ue_list(context, args={"ue_id": M["ue_id"]})[0]
H = [ H = [
@ -212,6 +222,9 @@ def matiere_delete(context, matiere_id=None, REQUEST=None):
def matiere_edit(context, matiere_id=None, REQUEST=None): def matiere_edit(context, matiere_id=None, REQUEST=None):
"""Edit matiere""" """Edit matiere"""
from app.scodoc import sco_formations
from app.scodoc import sco_edit_ue
F = do_matiere_list(context, args={"matiere_id": matiere_id}) F = do_matiere_list(context, args={"matiere_id": matiere_id})
if not F: if not F:
raise ScoValueError("Matière inexistante !") raise ScoValueError("Matière inexistante !")

View File

@ -25,19 +25,22 @@
# #
############################################################################## ##############################################################################
"""Ajout/Modification/Supression modules """Ajout/Modification/Suppression modules
(portage from DTML) (portage from DTML)
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import sco_codes_parcours from app.scodoc.TrivialFormulator import TrivialFormulator
from TrivialFormulator import TrivialFormulator, TF from app.scodoc.sco_permissions import Permission
import sco_formsemestre from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError
import sco_edit_ue from app.scodoc import html_sco_header
import sco_tag_module from app.scodoc import sco_codes_parcours
from sco_permissions import ScoChangeFormation from app.scodoc import sco_core
from sco_exceptions import ScoValueError from app.scodoc import sco_edit_matiere
from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_news
_MODULE_HELP = """<p class="help"> _MODULE_HELP = """<p class="help">
Les modules sont décrits dans le programme pédagogique. Un module est pour ce Les modules sont décrits dans le programme pédagogique. Un module est pour ce
@ -98,6 +101,8 @@ def do_module_list(context, *args, **kw):
def do_module_create(context, args, REQUEST): def do_module_create(context, args, REQUEST):
"create a module" "create a module"
# create # create
from app.scodoc import sco_formations
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
r = _moduleEditor.create(cnx, args) r = _moduleEditor.create(cnx, args)
@ -108,7 +113,7 @@ def do_module_create(context, args, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=args["formation_id"], object=args["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -117,6 +122,9 @@ def do_module_create(context, args, REQUEST):
def module_create(context, matiere_id=None, REQUEST=None): def module_create(context, matiere_id=None, REQUEST=None):
"""Creation d'un module""" """Creation d'un module"""
from app.scodoc import sco_formations
from app.scodoc import sco_edit_ue
if not matiere_id: if not matiere_id:
raise ScoValueError("invalid matiere !") raise ScoValueError("invalid matiere !")
M = sco_edit_matiere.do_matiere_list(context, args={"matiere_id": matiere_id})[0] M = sco_edit_matiere.do_matiere_list(context, args={"matiere_id": matiere_id})[0]
@ -241,8 +249,10 @@ def module_create(context, matiere_id=None, REQUEST=None):
def do_module_delete(context, oid, REQUEST): def do_module_delete(context, oid, REQUEST):
"delete module" "delete module"
from app.scodoc import sco_formations
mod = do_module_list(context, {"module_id": oid})[0] mod = do_module_list(context, {"module_id": oid})[0]
if sco_edit_module.module_is_locked(context, mod["module_id"]): if module_is_locked(context, mod["module_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# S'il y a des moduleimpls, on ne peut pas detruire le module ! # S'il y a des moduleimpls, on ne peut pas detruire le module !
@ -268,7 +278,7 @@ def do_module_delete(context, oid, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=mod["formation_id"], object=mod["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -341,6 +351,9 @@ def check_module_code_unicity(code, field, formation_id, context, module_id=None
def module_edit(context, module_id=None, REQUEST=None): def module_edit(context, module_id=None, REQUEST=None):
"""Edit a module""" """Edit a module"""
from app.scodoc import sco_formations
from app.scodoc import sco_tag_module
if not module_id: if not module_id:
raise ScoValueError("invalid module !") raise ScoValueError("invalid module !")
Mod = do_module_list(context, args={"module_id": module_id}) Mod = do_module_list(context, args={"module_id": module_id})
@ -532,6 +545,8 @@ def module_list(context, formation_id, REQUEST=None):
"""Liste des modules de la formation """Liste des modules de la formation
(XXX inutile ou a revoir) (XXX inutile ou a revoir)
""" """
from app.scodoc import sco_formations
if not formation_id: if not formation_id:
raise ScoValueError("invalid formation !") raise ScoValueError("invalid formation !")
F = sco_formations.formation_list(context, args={"formation_id": formation_id})[0] F = sco_formations.formation_list(context, args={"formation_id": formation_id})[0]
@ -581,6 +596,8 @@ def module_count_moduleimpls(context, module_id):
def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None): def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None):
"""Création d'un module de "malus" dans chaque UE d'une formation""" """Création d'un module de "malus" dans chaque UE d'une formation"""
from app.scodoc import sco_edit_ue
ue_list = sco_edit_ue.do_ue_list(context, args={"formation_id": formation_id}) ue_list = sco_edit_ue.do_ue_list(context, args={"formation_id": formation_id})
for ue in ue_list: for ue in ue_list:
@ -601,6 +618,8 @@ def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None)
def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None): def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None):
"""Add a malus module in this ue""" """Add a malus module in this ue"""
from app.scodoc import sco_edit_ue
ue = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0] ue = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0]
if titre is None: if titre is None:

View File

@ -28,18 +28,27 @@
"""Ajout/Modification/Suppression UE """Ajout/Modification/Suppression UE
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF from app.scodoc.TrivialFormulator import TrivialFormulator, TF
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_groups from app.scodoc.sco_permissions import Permission
import sco_formsemestre from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
import sco_formsemestre_validation
import sco_codes_parcours from app.scodoc import html_sco_header
import sco_tag_module from app.scodoc import sco_codes_parcours
from sco_permissions import ScoChangeFormation, ScoEditFormationTags, ScoImplement from app.scodoc import sco_core
from sco_exceptions import ScoValueError, ScoLockedFormError from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_news
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
_ueEditor = ndb.EditableTable( _ueEditor = ndb.EditableTable(
"notes_ue", "notes_ue",
@ -75,6 +84,8 @@ def do_ue_list(context, *args, **kw):
def do_ue_create(context, args, REQUEST): def do_ue_create(context, args, REQUEST):
"create an ue" "create an ue"
from app.scodoc import sco_formations
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check duplicates # check duplicates
ues = do_ue_list( ues = do_ue_list(
@ -92,7 +103,7 @@ def do_ue_create(context, args, REQUEST):
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=args["formation_id"], object=args["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -100,7 +111,10 @@ def do_ue_create(context, args, REQUEST):
def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=False): def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=False):
"delete UE and attached matieres (but not modules (it should ?))" "delete UE and attached matieres (but not modules)"
from app.scodoc import sco_formations
from app.scodoc import sco_parcours_dut
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
log("do_ue_delete: ue_id=%s, delete_validations=%s" % (ue_id, delete_validations)) log("do_ue_delete: ue_id=%s, delete_validations=%s" % (ue_id, delete_validations))
# check # check
@ -108,7 +122,7 @@ def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=F
if not ue: if not ue:
raise ScoValueError("UE inexistante !") raise ScoValueError("UE inexistante !")
ue = ue[0] ue = ue[0]
if sco_edit_ue.ue_is_locked(context, ue["ue_id"]): if ue_is_locked(context, ue["ue_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# Il y a-t-il des etudiants ayant validé cette UE ? # Il y a-t-il des etudiants ayant validé cette UE ?
# si oui, propose de supprimer les validations # si oui, propose de supprimer les validations
@ -158,7 +172,7 @@ def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=F
sco_news.add( sco_news.add(
context, context,
REQUEST, REQUEST,
typ=NEWS_FORM, typ=sco_news.NEWS_FORM,
object=ue["formation_id"], object=ue["formation_id"],
text="Modification de la formation %(acronyme)s" % F, text="Modification de la formation %(acronyme)s" % F,
) )
@ -178,6 +192,8 @@ def ue_create(context, formation_id=None, REQUEST=None):
def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None): def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
"""Modification ou creation d'une UE""" """Modification ou creation d'une UE"""
from app.scodoc import sco_formations
create = int(create) create = int(create)
if not create: if not create:
U = do_ue_list(context, args={"ue_id": ue_id}) U = do_ue_list(context, args={"ue_id": ue_id})
@ -419,6 +435,9 @@ def ue_list(context, formation_id=None, msg="", REQUEST=None):
"""Liste des matières et modules d'une formation, avec liens pour """Liste des matières et modules d'une formation, avec liens pour
editer (si non verrouillée). editer (si non verrouillée).
""" """
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre_validation
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
F = sco_formations.formation_list(context, args={"formation_id": formation_id}) F = sco_formations.formation_list(context, args={"formation_id": formation_id})
@ -816,6 +835,8 @@ def ue_sharing_code(context, ue_code=None, ue_id=None, hide_ue_id=None):
"""HTML list of UE sharing this code """HTML list of UE sharing this code
Either ue_code or ue_id may be specified. Either ue_code or ue_id may be specified.
""" """
from app.scodoc import sco_formations
if ue_id: if ue_id:
ue = do_ue_list(context, args={"ue_id": ue_id})[0] ue = do_ue_list(context, args={"ue_id": ue_id})[0]
if not ue_code: if not ue_code:
@ -946,6 +967,8 @@ def ue_is_locked(context, ue_id):
# ---- Table recap formation # ---- Table recap formation
def formation_table_recap(context, formation_id, format="html", REQUEST=None): def formation_table_recap(context, formation_id, format="html", REQUEST=None):
"""Table recapitulant formation.""" """Table recapitulant formation."""
from app.scodoc import sco_formations
F = sco_formations.formation_list(context, args={"formation_id": formation_id}) F = sco_formations.formation_list(context, args={"formation_id": formation_id})
if not F: if not F:
raise ScoValueError("invalid formation_id") raise ScoValueError("invalid formation_id")

View File

@ -38,11 +38,13 @@ import traceback
import icalendar import icalendar
import pprint import pprint
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import sco_formsemestre from app.scodoc import html_sco_header
import sco_groups from app.scodoc import sco_formsemestre
import sco_groups_view from app.scodoc import sco_groups
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(context, sem):
@ -52,7 +54,9 @@ def formsemestre_get_ics_url(context, sem):
Par exemple: Par exemple:
https://example.fr/agenda/{sem[etapes][0]} https://example.fr/agenda/{sem[etapes][0]}
""" """
ics_url_tmpl = sco_preferences.get_preference(context, "edt_sem_ics_url", sem["formsemestre_id"]) ics_url_tmpl = sco_preferences.get_preference(
context, "edt_sem_ics_url", sem["formsemestre_id"]
)
if not ics_url_tmpl: if not ics_url_tmpl:
return None return None
try: try:
@ -163,7 +167,8 @@ def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=
"""experimental page""" """experimental page"""
return "\n".join( return "\n".join(
[ [
html_sco_header.sco_header(context, html_sco_header.sco_header(
context,
REQUEST, REQUEST,
javascripts=[ javascripts=[
"libjs/purl.js", "libjs/purl.js",

View File

@ -30,8 +30,8 @@
# codes anciens déplacés de ZEntreprise # codes anciens déplacés de ZEntreprise
import datetime import datetime
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO

View File

@ -77,15 +77,10 @@
import re import re
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc import sco_archives
import sco_formsemestre from app.scodoc import sco_apogee_csv
import notes_table from app.scodoc.sco_exceptions import ScoValueError
import sco_groups
import sco_groups_view
import sco_archives
import sco_apogee_csv
from sco_exceptions import ScoValueError
class ApoCSVArchiver(sco_archives.BaseArchiver): class ApoCSVArchiver(sco_archives.BaseArchiver):
@ -365,12 +360,12 @@ def apo_csv_retreive_etuds_by_nip(context, semset, nips):
Tests: Tests:
from debug import * from debug import *
import sco_groups from app.scodoc import sco_groups
import sco_groups_view from app.scodoc import sco_groups_view
import sco_formsemestre from app.scodoc import sco_formsemestre
from sco_etape_apogee import * from app.scodoc.sco_etape_apogee import *
from sco_apogee_csv import * from app.scodoc.sco_apogee_csv import *
from sco_semset import * from app.scodoc.sco_semset import *
context = go_dept(app, 'RT').Notes context = go_dept(app, 'RT').Notes
csv_data = open('/opt/misc/VDTRT_V1RT.TXT').read() csv_data = open('/opt/misc/VDTRT_V1RT.TXT').read()
@ -413,7 +408,7 @@ self=e
col_id='apoL_c0129' col_id='apoL_c0129'
# -- # --
import sco_portal_apogee from app.scodoc import sco_portal_apogee
context = go_dept(app, 'GEA').Notes context = go_dept(app, 'GEA').Notes
#csv_data = sco_portal_apogee.get_maquette_apogee(context, etape='V1GE', annee_scolaire=2015) #csv_data = sco_portal_apogee.get_maquette_apogee(context, etape='V1GE', annee_scolaire=2015)
csv_data = open('/tmp/V1GE.txt').read() csv_data = open('/tmp/V1GE.txt').read()
@ -424,12 +419,12 @@ apo_data = sco_apogee_csv.ApoData(csv_data, periode=1)
# les elements inconnus: # les elements inconnus:
from debug import * from debug import *
import sco_groups from app.scodoc import sco_groups
import sco_groups_view from app.scodoc import sco_groups_view
import sco_formsemestre from app.scodoc import sco_formsemestre
from sco_etape_apogee import * from app.scodoc.sco_etape_apogee import *
from sco_apogee_csv import * from app.scodoc.sco_apogee_csv import *
from sco_semset import * from app.scodoc.sco_semset import *
context = go_dept(app, 'RT').Notes context = go_dept(app, 'RT').Notes
csv_data = open('/opt/misc/V2RT.csv').read() csv_data = open('/opt/misc/V2RT.csv').read()
@ -447,12 +442,12 @@ for e in apo_data.etuds:
# ------ # ------
# test export jury intermediaire # test export jury intermediaire
from debug import * from debug import *
import sco_groups from app.scodoc import sco_groups
import sco_groups_view from app.scodoc import sco_groups_view
import sco_formsemestre from app.scodoc import sco_formsemestre
from sco_etape_apogee import * from app.scodoc.sco_etape_apogee import *
from sco_apogee_csv import * from app.scodoc.sco_apogee_csv import *
from sco_semset import * from app.scodoc.sco_semset import *
context = go_dept(app, 'CJ').Notes context = 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() csv_data = open('/opt/scodoc/var/scodoc/archives/apo_csv/CJ/2016-1/2017-03-06-21-46-32/V1CJ.csv').read()

View File

@ -31,19 +31,23 @@
from cStringIO import StringIO from cStringIO import StringIO
from zipfile import ZipFile from zipfile import ZipFile
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import sco_formsemestre from app.scodoc import html_sco_header
import sco_formsemestre_status from app.scodoc import notes_table
import notes_table from app.scodoc import sco_apogee_csv
from gen_tables import GenTable from app.scodoc import sco_archives
import sco_semset from app.scodoc import sco_etape_apogee
import sco_etape_apogee from app.scodoc import sco_formations
import sco_apogee_csv from app.scodoc import sco_formsemestre
import sco_portal_apogee from app.scodoc import sco_formsemestre_status
from sco_apogee_csv import APO_PORTAL_ENCODING, APO_INPUT_ENCODING from app.scodoc import sco_portal_apogee
import sco_archives from app.scodoc import sco_preferences
from sco_exceptions import ScoValueError from app.scodoc import sco_semset
from app.scodoc import sco_etud
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_apogee_csv import APO_PORTAL_ENCODING, APO_INPUT_ENCODING
from app.scodoc.sco_exceptions import ScoValueError
def apo_semset_maq_status( def apo_semset_maq_status(
@ -342,7 +346,10 @@ def apo_semset_maq_status(
if missing: if missing:
formation_ids = {sem["formation_id"] for sem in semset.sems} formation_ids = {sem["formation_id"] for sem in semset.sems}
formations = [sco_formations.formation_list(context, formation_id=i)[0] for i in formation_ids] formations = [
sco_formations.formation_list(context, formation_id=i)[0]
for i in formation_ids
]
# log('formations=%s' % formations) # log('formations=%s' % formations)
H.append( H.append(
'<div class="apo_csv_status_missing_elems"><span class="fontred">Elements Apogée absents dans ScoDoc: </span><span class="apo_elems fontred">%s</span>' '<div class="apo_csv_status_missing_elems"><span class="fontred">Elements Apogée absents dans ScoDoc: </span><span class="apo_elems fontred">%s</span>'
@ -498,7 +505,7 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST
etuds = sco_etape_apogee.apo_csv_retreive_etuds_by_nip(context, semset, nips) etuds = sco_etape_apogee.apo_csv_retreive_etuds_by_nip(context, semset, nips)
# Ils sont parfois dans ScoDoc même si pas dans le semestre: essaie de les retrouver # Ils sont parfois dans ScoDoc même si pas dans le semestre: essaie de les retrouver
for etud in etuds.values(): for etud in etuds.values():
etud_sco = scolars.get_etud_info(code_nip=etud["nip"], filled=True) etud_sco = sco_etud.get_etud_info(code_nip=etud["nip"], filled=True)
if etud_sco: if etud_sco:
e = etud_sco[0] e = etud_sco[0]
etud["inscriptions_scodoc"] = ", ".join( etud["inscriptions_scodoc"] = ", ".join(
@ -529,12 +536,12 @@ def view_scodoc_etuds(
if type(etudids) != type([]): if type(etudids) != type([]):
etudids = [etudids] etudids = [etudids]
etuds = [ etuds = [
scolars.get_etud_info(etudid=etudid, filled=True)[0] for etudid in etudids sco_etud.get_etud_info(etudid=etudid, filled=True)[0] for etudid in etudids
] ]
elif nips is not None: elif nips is not None:
if type(nips) != type([]): if type(nips) != type([]):
nips = [nips] nips = [nips]
etuds = [scolars.get_etud_info(code_nip=nip, filled=True)[0] for nip in nips] etuds = [sco_etud.get_etud_info(code_nip=nip, filled=True)[0] for nip in nips]
else: else:
raise ValueError("etudid or NIP must be specified") raise ValueError("etudid or NIP must be specified")
@ -752,7 +759,7 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
e["in_scodoc_str"] = {True: "oui", False: "non"}[e["in_scodoc"]] e["in_scodoc_str"] = {True: "oui", False: "non"}[e["in_scodoc"]]
if e["in_scodoc"]: if e["in_scodoc"]:
e["_in_scodoc_str_target"] = "ficheEtud?code_nip=" + e["nip"] e["_in_scodoc_str_target"] = "ficheEtud?code_nip=" + e["nip"]
e.update(scolars.get_etud_info(code_nip=e["nip"], filled=True)[0]) e.update(sco_etud.get_etud_info(code_nip=e["nip"], filled=True)[0])
e["_nom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"],) e["_nom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"],)
e["_prenom_td_attrs"] = 'id="pre-%s" class="etudinfo"' % (e["etudid"],) e["_prenom_td_attrs"] = 'id="pre-%s" class="etudinfo"' % (e["etudid"],)
else: else:

View File

@ -92,10 +92,10 @@ Le filtrage s'effctue sur la date et non plus sur la parité du semestre (1-3/2-
import json import json
from sco_portal_apogee import get_inscrits_etape from app.scodoc.sco_portal_apogee import get_inscrits_etape
from notes_log import log from app.scodoc.notes_log import log
from sco_utils import annee_scolaire_debut from app.scodoc.sco_utils import annee_scolaire_debut
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
COL_PREFIX = "COL_" COL_PREFIX = "COL_"

View File

@ -27,54 +27,45 @@
""" Accès donnees etudiants """ Accès donnees etudiants
""" """
# Ancien module "scolars"
import time import time
import mails
import sco_utils as scu
from sco_utils import SCO_ENCODING
import notesdb as ndb
from sco_exceptions import ScoGenError, ScoValueError
from notesdb import (
EditableTable,
ScoDocCursor,
DateDMYtoISO,
DateISOtoDMY,
int_null_is_null,
)
from notes_log import log
from TrivialFormulator import TrivialFormulator
import safehtml
from scolog import logdb
# from notes_table import *
import sco_news
# XXXXXXXXX HACK: zope 2.7.7 bug turaround ?
import locale
locale.setlocale(locale.LC_ALL, ("en_US", SCO_ENCODING))
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
abbrvmonthsnames = [ from app.scodoc import mails
import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import SCO_ENCODING
import app.scodoc.notesdb as ndb
from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
from app.scodoc.notes_log import log
from app.scodoc.TrivialFormulator import TrivialFormulator
from app.scodoc import safehtml
from app.scodoc import sco_formsemestre
from app.scodoc import sco_preferences
from app.scodoc.scolog import logdb
MONTH_NAMES_ABBREV = [
"Jan ", "Jan ",
"Fev ", "Fév ",
"Mars", "Mars",
"Avr ", "Avr ",
"Mai ", "Mai ",
"Juin", "Juin",
"Jul ", "Jul ",
"Aout", "Août",
"Sept", "Sept",
"Oct ", "Oct ",
"Nov ", "Nov ",
"Dec ", "Déc ",
] ]
monthsnames = [ MONTH_NAMES = [
"janvier", "janvier",
"février", "février",
"mars", "mars",
@ -82,7 +73,7 @@ monthsnames = [
"mai", "mai",
"juin", "juin",
"juillet", "juillet",
"aout", "août",
"septembre", "septembre",
"octobre", "octobre",
"novembre", "novembre",
@ -252,7 +243,7 @@ def pivot_year(y):
return y return y
_identiteEditor = EditableTable( _identiteEditor = ndb.EditableTable(
"identite", "identite",
"etudid", "etudid",
( (
@ -277,9 +268,9 @@ _identiteEditor = EditableTable(
"nom": force_uppercase, "nom": force_uppercase,
"prenom": force_uppercase, "prenom": force_uppercase,
"civilite": input_civilite, "civilite": input_civilite,
"date_naissance": DateDMYtoISO, "date_naissance": ndb.DateDMYtoISO,
}, },
output_formators={"date_naissance": DateISOtoDMY}, output_formators={"date_naissance": ndb.DateISOtoDMY},
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,
allow_set_id=True, # car on specifie le code Apogee a la creation allow_set_id=True, # car on specifie le code Apogee a la creation
) )
@ -320,7 +311,7 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
if scu.FORBIDDEN_CHARS_EXP.search(nom) or scu.FORBIDDEN_CHARS_EXP.search(prenom): if scu.FORBIDDEN_CHARS_EXP.search(nom) or scu.FORBIDDEN_CHARS_EXP.search(prenom):
return False, 0 return False, 0
# Now count homonyms: # Now count homonyms:
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = "select etudid from identite where lower(nom) ~ %(nom)s and lower(prenom) ~ %(prenom)s" req = "select etudid from identite where lower(nom) ~ %(nom)s and lower(prenom) ~ %(prenom)s"
if etudid: if etudid:
req += " and etudid <> %(etudid)s" req += " and etudid <> %(etudid)s"
@ -400,7 +391,7 @@ def identite_edit(cnx, args, context=None, REQUEST=None):
# Notification du changement par e-mail: # Notification du changement par e-mail:
if notify_to: if notify_to:
etud = getEtudInfo(context, etudid=args["etudid"], filled=True)[0] etud = get_etud_info(etudid=args["etudid"], filled=True)[0]
after = identite_list(cnx, {"etudid": args["etudid"]})[0] after = identite_list(cnx, {"etudid": args["etudid"]})[0]
notify_etud_change( notify_etud_change(
context, context,
@ -467,7 +458,7 @@ def notify_etud_change(context, email_addr, etud, before, after, subject):
# Note: la table adresse n'est pas dans dans la table "identite" # Note: la table adresse n'est pas dans dans la table "identite"
# car on prevoit plusieurs adresses par etudiant (ie domicile, entreprise) # car on prevoit plusieurs adresses par etudiant (ie domicile, entreprise)
_adresseEditor = EditableTable( _adresseEditor = ndb.EditableTable(
"adresse", "adresse",
"adresse_id", "adresse_id",
( (
@ -514,7 +505,7 @@ def adresse_edit(cnx, args, context=None):
# Notification du changement par e-mail: # Notification du changement par e-mail:
if notify_to: if notify_to:
etud = getEtudInfo(context, etudid=args["etudid"], filled=True)[0] etud = get_etud_info(etudid=args["etudid"], filled=True)[0]
after = adresse_list(cnx, {"etudid": args["etudid"]})[0] after = adresse_list(cnx, {"etudid": args["etudid"]})[0]
notify_etud_change( notify_etud_change(
context, context,
@ -536,7 +527,7 @@ def getEmail(cnx, etudid):
# --------- # ---------
_admissionEditor = EditableTable( _admissionEditor = ndb.EditableTable(
"admissions", "admissions",
"adm_id", "adm_id",
( (
@ -572,8 +563,8 @@ _admissionEditor = EditableTable(
"bac": force_uppercase, "bac": force_uppercase,
"specialite": force_uppercase, "specialite": force_uppercase,
"annee_bac": pivot_year, "annee_bac": pivot_year,
"classement": int_null_is_null, "classement": ndb.int_null_is_null,
"apb_classsment_gr": int_null_is_null, "apb_classement_gr": ndb.int_null_is_null,
}, },
output_formators={"type_admission": lambda x: x or scu.TYPE_ADMISSION_DEFAULT}, output_formators={"type_admission": lambda x: x or scu.TYPE_ADMISSION_DEFAULT},
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,
@ -663,10 +654,10 @@ def get_etud_info(etudid=False, code_nip=False, filled=False, REQUEST=None):
return [] return []
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
args = make_etud_args(etudid=etudid, code_nip=code_nip, REQUEST=REQUEST) args = make_etud_args(etudid=etudid, code_nip=code_nip, REQUEST=REQUEST)
etud = scolars.etudident_list(cnx, args=args) etud = etudident_list(cnx, args=args)
if filled: if filled:
fillEtudsInfo(context, etud) fill_etuds_info(etud)
return etud return etud
@ -679,6 +670,8 @@ def create_etud(context, cnx, args={}, REQUEST=None):
Returns: Returns:
etud, l'étudiant créé. etud, l'étudiant créé.
""" """
from app.scodoc import sco_news
# creation d'un etudiant # creation d'un etudiant
etudid = etudident_create(cnx, args, context=context, REQUEST=REQUEST) etudid = etudident_create(cnx, args, context=context, REQUEST=REQUEST)
# crée une adresse vide (chaque etudiant doit etre dans la table "adresse" !) # crée une adresse vide (chaque etudiant doit etre dans la table "adresse" !)
@ -710,7 +703,7 @@ def create_etud(context, cnx, args={}, REQUEST=None):
msg="creation initiale", msg="creation initiale",
) )
etud = etudident_list(cnx, {"etudid": etudid})[0] etud = etudident_list(cnx, {"etudid": etudid})[0]
fillEtudsInfo(context, [etud]) fill_etuds_info([etud])
etud["url"] = "ficheEtud?etudid=%(etudid)s" % etud etud["url"] = "ficheEtud?etudid=%(etudid)s" % etud
sco_news.add( sco_news.add(
context, context,
@ -724,7 +717,7 @@ def create_etud(context, cnx, args={}, REQUEST=None):
# ---------- "EVENTS" # ---------- "EVENTS"
_scolar_eventsEditor = EditableTable( _scolar_eventsEditor = ndb.EditableTable(
"scolar_events", "scolar_events",
"event_id", "event_id",
( (
@ -738,8 +731,8 @@ _scolar_eventsEditor = EditableTable(
), ),
sortkey="event_date", sortkey="event_date",
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,
output_formators={"event_date": DateISOtoDMY}, output_formators={"event_date": ndb.DateISOtoDMY},
input_formators={"event_date": DateDMYtoISO}, input_formators={"event_date": ndb.DateDMYtoISO},
) )
# scolar_events_create = _scolar_eventsEditor.create # scolar_events_create = _scolar_eventsEditor.create
@ -754,7 +747,7 @@ def scolar_events_create(cnx, args):
# -------- # --------
_etud_annotationsEditor = EditableTable( _etud_annotationsEditor = ndb.EditableTable(
"etud_annotations", "etud_annotations",
"id", "id",
( (
@ -768,7 +761,7 @@ _etud_annotationsEditor = EditableTable(
), ),
sortkey="date desc", sortkey="date desc",
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,
output_formators={"comment": safehtml.HTML2SafeHTML, "date": DateISOtoDMY}, output_formators={"comment": safehtml.HTML2SafeHTML, "date": ndb.DateISOtoDMY},
) )
@ -792,7 +785,7 @@ def add_annotations_to_etud_list(context, etuds):
# -------- APPRECIATIONS (sur bulletins) ------------------- # -------- APPRECIATIONS (sur bulletins) -------------------
# Les appreciations sont dans la table postgres notes_appreciations # Les appreciations sont dans la table postgres notes_appreciations
_appreciationsEditor = EditableTable( _appreciationsEditor = ndb.EditableTable(
"notes_appreciations", "notes_appreciations",
"id", "id",
( (
@ -807,7 +800,7 @@ _appreciationsEditor = EditableTable(
), ),
sortkey="date desc", sortkey="date desc",
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,
output_formators={"comment": safehtml.HTML2SafeHTML, "date": DateISOtoDMY}, output_formators={"comment": safehtml.HTML2SafeHTML, "date": ndb.DateISOtoDMY},
) )
appreciations_create = _appreciationsEditor.create appreciations_create = _appreciationsEditor.create
@ -903,11 +896,14 @@ def list_scolog(context, etudid):
return cursor.dictfetchall() return cursor.dictfetchall()
def fillEtudsInfo(context, etuds): def fill_etuds_info(etuds):
"""etuds est une liste d'etudiants (mappings) """etuds est une liste d'etudiants (mappings)
Pour chaque etudiant, ajoute ou formatte les champs Pour chaque etudiant, ajoute ou formatte les champs
-> informations pour fiche etudiant ou listes diverses -> informations pour fiche etudiant ou listes diverses
""" """
from app.scodoc import sco_formsemestre_inscriptions
context = None # XXX en attendant la suppression du context ScoDoc7
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# open('/tmp/t','w').write( str(etuds) ) # open('/tmp/t','w').write( str(etuds) )
for etud in etuds: for etud in etuds:
@ -921,12 +917,14 @@ def fillEtudsInfo(context, etuds):
else: else:
adr = adrs[0] adr = adrs[0]
if len(adrs) > 1: if len(adrs) > 1:
log("fillEtudsInfo: etudid=%s a %d adresses" % (etudid, len(adrs))) log("fill_etuds_info: etudid=%s a %d adresses" % (etudid, len(adrs)))
etud.update(adr) etud.update(adr)
format_etud_ident(etud) format_etud_ident(etud)
# Semestres dans lesquel il est inscrit # Semestres dans lesquel il est inscrit
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, {"etudid": etudid}) ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
context, {"etudid": etudid}
)
etud["ins"] = ins etud["ins"] = ins
sems = [] sems = []
cursem = None # semestre "courant" ou il est inscrit cursem = None # semestre "courant" ou il est inscrit
@ -1020,7 +1018,7 @@ def descr_situation_etud(context, etudid, ne=""):
if r["etat"] == "I": if r["etat"] == "I":
situation = "inscrit%s en %s" % (ne, sem["titremois"]) situation = "inscrit%s en %s" % (ne, sem["titremois"])
# Cherche la date d'inscription dans scolar_events: # Cherche la date d'inscription dans scolar_events:
events = scolars.scolar_events_list( events = scolar_events_list(
cnx, cnx,
args={ args={
"etudid": etudid, "etudid": etudid,
@ -1040,7 +1038,7 @@ def descr_situation_etud(context, etudid, ne=""):
else: else:
situation = "démission de %s" % sem["titremois"] situation = "démission de %s" % sem["titremois"]
# Cherche la date de demission dans scolar_events: # Cherche la date de demission dans scolar_events:
events = scolars.scolar_events_list( events = scolar_events_list(
cnx, cnx,
args={ args={
"etudid": etudid, "etudid": etudid,

View File

@ -32,21 +32,25 @@ import urllib
import operator import operator
import datetime import datetime
from notes_log import log, logCallStack from app.scodoc.notes_log import log, logCallStack
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notesdb import ScoDocCursor from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
from sco_exceptions import AccessDenied, ScoValueError from app.scodoc import VERSION
import VERSION from app.scodoc.gen_tables import GenTable
from gen_tables import GenTable from app.scodoc.TrivialFormulator import TrivialFormulator
from TrivialFormulator import TrivialFormulator from app.scodoc import html_sco_header
import sco_news from app.scodoc import sco_abs
import sco_formsemestre from app.scodoc import sco_core
import sco_moduleimpl from app.scodoc import sco_edit_module
import sco_groups from app.scodoc import sco_edit_ue
import sco_abs from app.scodoc import sco_formsemestre
import sco_evaluations from app.scodoc import sco_groups
import sco_saisie_notes from app.scodoc import sco_moduleimpl
from app.scodoc import sco_news
from app.scodoc import sco_permissions_check
from app.scodoc import sco_preferences
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# #
@ -170,7 +174,7 @@ def do_evaluation_list_in_formsemestre(context, formsemestre_id):
mods = sco_moduleimpl.do_moduleimpl_list(context, formsemestre_id=formsemestre_id) mods = sco_moduleimpl.do_moduleimpl_list(context, formsemestre_id=formsemestre_id)
evals = [] evals = []
for mod in mods: for mod in mods:
evals += sco_evaluations.do_evaluation_list( evals += do_evaluation_list(
context, args={"moduleimpl_id": mod["moduleimpl_id"]} context, args={"moduleimpl_id": mod["moduleimpl_id"]}
) )
return evals return evals
@ -201,7 +205,7 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
if not the_evals: if not the_evals:
raise ValueError("evaluation inexistante !") raise ValueError("evaluation inexistante !")
NotesDB = context._notes_getall(evaluation_id) # { etudid : value } NotesDB = do_evaluation_get_all_notes(context, evaluation_id) # { etudid : value }
notes = [x["value"] for x in NotesDB.values()] notes = [x["value"] for x in NotesDB.values()]
if notes: if notes:
raise ScoValueError( raise ScoValueError(
@ -251,7 +255,7 @@ def do_evaluation_etat(
context, evaluation_id, getallstudents=True context, evaluation_id, getallstudents=True
) )
) )
NotesDB = context._notes_getall(evaluation_id) # { etudid : value } NotesDB = do_evaluation_get_all_notes(context, evaluation_id) # { etudid : value }
notes = [x["value"] for x in NotesDB.values()] notes = [x["value"] for x in NotesDB.values()]
nb_abs = len([x for x in notes if x is None]) nb_abs = len([x for x in notes if x is None])
nb_neutre = len([x for x in notes if x == scu.NOTES_NEUTRALISE]) nb_neutre = len([x for x in notes if x == scu.NOTES_NEUTRALISE])
@ -458,7 +462,7 @@ def do_evaluation_list_in_sem(context, formsemestre_id):
""" """
req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id order by moduleimpl_id, numero desc, jour desc, heure_debut desc" req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id order by moduleimpl_id, numero desc, jour desc, heure_debut desc"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(req, {"formsemestre_id": formsemestre_id}) cursor.execute(req, {"formsemestre_id": formsemestre_id})
res = cursor.dictfetchall() res = cursor.dictfetchall()
# etat de chaque evaluation: # etat de chaque evaluation:
@ -469,15 +473,44 @@ def do_evaluation_list_in_sem(context, formsemestre_id):
return res return res
# remplacé par nt.get_sem_evaluation_etat_list() # ancien _notes_getall
# def do_evaluation_get_all_notes(
# def formsemestre_evaluations_list(context, formsemestre_id): context, evaluation_id, table="notes_notes", filter_suppressed=True, by_uid=None
# """Liste (non triée) des evals pour ce semestre""" ):
# req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id" """Toutes les notes pour une evaluation: { etudid : { 'value' : value, 'date' : date ... }}
# cnx = ndb.GetDBConnexion() Attention: inclut aussi les notes des étudiants qui ne sont plus inscrits au module.
# cursor = cnx.cursor(cursor_factory=ScoDocCursor) """
# cursor.execute( req, { 'formsemestre_id' : formsemestre_id } ) # log('do_evaluation_get_all_notes( e=%s fs=%s )' % (evaluation_id, filter_suppressed))
# return cursor.dictfetchall() do_cache = (
filter_suppressed and table == "notes_notes" and (by_uid is None)
) # pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant
if do_cache:
cache = sco_core.get_evaluations_cache(context)
r = cache.get(evaluation_id)
if r != None:
return r
cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cond = " where evaluation_id=%(evaluation_id)s"
if by_uid:
cond += " and uid=%(by_uid)s"
cursor.execute(
"select * from " + table + cond,
{"evaluation_id": evaluation_id, "by_uid": by_uid},
)
res = cursor.dictfetchall()
d = {}
if filter_suppressed:
for x in res:
if x["value"] != scu.NOTES_SUPPRESS:
d[x["etudid"]] = x
else:
for x in res:
d[x["etudid"]] = x
if do_cache:
cache.set(evaluation_id, d)
return d
def _eval_etat(evals): def _eval_etat(evals):
@ -601,7 +634,7 @@ def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None):
e[2] = color_futur e[2] = color_futur
CalHTML = sco_abs.YearTable( CalHTML = sco_abs.YearTable(
context.Absences, year, events=events.values(), halfday=False, pad_width=None context, year, events=events.values(), halfday=False, pad_width=None
) )
H = [ H = [
@ -649,9 +682,11 @@ def evaluation_date_first_completion(context, evaluation_id):
# retire de insem ceux qui ne sont pas inscrits au module # retire de insem ceux qui ne sont pas inscrits au module
# ins = [i for i in insem if i["etudid"] in insmodset] # ins = [i for i in insem if i["etudid"] in insmodset]
notes = context._notes_getall(evaluation_id, filter_suppressed=False).values() notes = do_evaluation_get_all_notes(
notes_log = context._notes_getall( context, evaluation_id, filter_suppressed=False
evaluation_id, filter_suppressed=False, table="notes_notes_log" ).values()
notes_log = do_evaluation_get_all_notes(
context, evaluation_id, filter_suppressed=False, table="notes_notes_log"
).values() ).values()
date_premiere_note = {} # etudid : date date_premiere_note = {} # etudid : date
for note in notes + notes_log: for note in notes + notes_log:
@ -853,6 +888,8 @@ def evaluation_describe(context, evaluation_id="", edit_in_place=True, REQUEST=N
"""HTML description of evaluation, for page headers """HTML description of evaluation, for page headers
edit_in_place: allow in-place editing when permitted (not implemented) edit_in_place: allow in-place editing when permitted (not implemented)
""" """
from app.scodoc import sco_saisie_notes
E = do_evaluation_list(context, {"evaluation_id": evaluation_id})[0] E = do_evaluation_list(context, {"evaluation_id": evaluation_id})[0]
moduleimpl_id = E["moduleimpl_id"] moduleimpl_id = E["moduleimpl_id"]
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
@ -861,7 +898,7 @@ def evaluation_describe(context, evaluation_id="", edit_in_place=True, REQUEST=N
u = context.Users.user_info(M["responsable_id"]) u = context.Users.user_info(M["responsable_id"])
resp = u["prenomnom"] resp = u["prenomnom"]
nomcomplet = u["nomcomplet"] nomcomplet = u["nomcomplet"]
can_edit = sco_saisie_notes.can_edit_notes( can_edit = sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False context, REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False
) )
@ -1038,9 +1075,7 @@ def evaluation_create_form(
if not readonly: if not readonly:
H = ["<h3>%svaluation en %s</h3>" % (action, mod_descr)] H = ["<h3>%svaluation en %s</h3>" % (action, mod_descr)]
else: else:
return sco_evaluations.evaluation_describe( return evaluation_describe(context, evaluation_id, REQUEST=REQUEST)
context, evaluation_id, REQUEST=REQUEST
)
heures = ["%02dh%02d" % (h, m) for h in range(8, 19) for m in (0, 30)] heures = ["%02dh%02d" % (h, m) for h in range(8, 19) for m in (0, 30)]
# #

View File

@ -28,18 +28,17 @@
""" Excel file handling """ Excel file handling
""" """
import time, datetime
from types import StringType, IntType, FloatType, LongType
from pyExcelerator import * from pyExcelerator import *
from notes_log import log import app.scodoc.sco_utils as scu
from scolog import logdb from app.scodoc import notesdb
from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb
from app.scodoc.sco_exceptions import ScoValueError
from sco_exceptions import ScoValueError
import sco_utils as scu
import notesdb
import time, datetime
from types import StringType, IntType, FloatType, LongType
# colors, voir exemple format.py # colors, voir exemple format.py
COLOR_CODES = { COLOR_CODES = {

View File

@ -29,20 +29,20 @@
""" """
from types import ListType from types import ListType
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
import scolars from app.scodoc import html_sco_header
import sco_bac from app.scodoc import sco_bac
import sco_formsemestre from app.scodoc import sco_codes_parcours
import sco_parcours_dut from app.scodoc import sco_core
import sco_codes_parcours from app.scodoc import sco_formations
from sco_codes_parcours import NO_SEMESTRE_ID from app.scodoc import sco_preferences
import sco_excel from app.scodoc import sco_pvjury
from gen_tables import GenTable from app.scodoc import sco_etud
import sco_pvjury from app.scodoc import VERSION
import html_sco_header from app.scodoc.gen_tables import GenTable
import VERSION 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(context, start_date=None, end_date=None, types_parcours=[]):
@ -62,8 +62,8 @@ def _build_results_table(context, start_date=None, end_date=None, types_parcours
semlist = [dpv["formsemestre"] for dpv in dpv_by_sem.values() if dpv] semlist = [dpv["formsemestre"] for dpv in dpv_by_sem.values() if dpv]
semlist_parcours = [] semlist_parcours = []
for sem in semlist: for sem in semlist:
sem["formation"] = sco_formations.formation_list(context, sem["formation"] = sco_formations.formation_list(
args={"formation_id": sem["formation_id"]} context, args={"formation_id": sem["formation_id"]}
)[0] )[0]
sem["parcours"] = sco_codes_parcours.get_parcours_from_code( sem["parcours"] = sco_codes_parcours.get_parcours_from_code(
sem["formation"]["type_parcours"] sem["formation"]["type_parcours"]
@ -83,7 +83,7 @@ def _build_results_table(context, start_date=None, end_date=None, types_parcours
etudids = nt.get_etudids() etudids = nt.get_etudids()
for etudid in etudids: for etudid in etudids:
if etudid not in etuds_infos: # pas encore traité ? if etudid not in etuds_infos: # pas encore traité ?
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
for sem in etud["sems"]: # le plus récent d'abord for sem in etud["sems"]: # le plus récent d'abord
if sem["formsemestre_id"] in formsemestre_ids_parcours: if sem["formsemestre_id"] in formsemestre_ids_parcours:
etuds_infos[etudid] = { etuds_infos[etudid] = {
@ -337,10 +337,10 @@ _DATE_FORM = """
""" """
# /opt/scodoc/bin/zopectl debug # /opt/scodoc/bin/zopectl debug
from debug import * from debug import *
from sco_export_results import * from app.scodoc.sco_export_results import *
context = go_dept(app, 'RT').Notes context = go_dept(app, 'RT').Notes
etudid = 'EID27764' etudid = 'EID27764'
etud = scolars.get_etud_info( etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info( etudid=etudid, filled=True)[0]
start_date='2015-08-15' start_date='2015-08-15'
end_date='2017-08-31' end_date='2017-08-31'

View File

@ -27,19 +27,15 @@
"""Recherche d'étudiants """Recherche d'étudiants
""" """
from types import ListType
import xml.dom.minidom
import sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
import notesdb as ndb from app.scodoc.gen_tables import GenTable
from notes_log import log from app.scodoc import html_sco_header
from gen_tables import GenTable from app.scodoc import sco_etud
import html_sco_header from app.scodoc import sco_groups
import scolars from app.scodoc.sco_permissions import Permission
import sco_formsemestre from app.scodoc import sco_preferences
import sco_groups
from sco_permissions import ScoView
def form_search_etud( def form_search_etud(
@ -110,7 +106,7 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
""" """
dest_url = "ficheEtud" dest_url = "ficheEtud"
if len(expnom) > 1: if len(expnom) > 1:
etuds = scolars.get_etud_info(filled=1, etudid=expnom, REQUEST=REQUEST) etuds = sco_etud.get_etud_info(filled=1, etudid=expnom, REQUEST=REQUEST)
if len(etuds) != 1: if len(etuds) != 1:
if scu.is_valid_code_nip(expnom): if scu.is_valid_code_nip(expnom):
etuds = search_etuds_infos(context, code_nip=expnom, REQUEST=REQUEST) etuds = search_etuds_infos(context, code_nip=expnom, REQUEST=REQUEST)
@ -194,14 +190,14 @@ def search_etuds_infos(context, expnom=None, code_nip=None, REQUEST=None):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
if expnom and not may_be_nip: if expnom and not may_be_nip:
expnom = scu.strupper(expnom) # les noms dans la BD sont en uppercase expnom = scu.strupper(expnom) # les noms dans la BD sont en uppercase
etuds = scolars.etudident_list(cnx, args={"nom": expnom}, test="~") etuds = sco_etud.etudident_list(cnx, args={"nom": expnom}, test="~")
else: else:
code_nip = code_nip or expnom code_nip = code_nip or expnom
if code_nip: if code_nip:
etuds = scolars.etudident_list(cnx, args={"code_nip": code_nip}) etuds = sco_etud.etudident_list(cnx, args={"code_nip": code_nip})
else: else:
etuds = [] etuds = []
scolars.fillEtudsInfo(context, etuds) sco_etud.fill_etuds_info(etuds)
return etuds return etuds
@ -230,7 +226,7 @@ def search_etud_by_name(context, term, REQUEST=None):
data = [ data = [
{ {
"label": "%s %s %s" "label": "%s %s %s"
% (x["code_nip"], x["nom"], scolars.format_prenom(x["prenom"])), % (x["code_nip"], x["nom"], sco_etud.format_prenom(x["prenom"])),
"value": x["code_nip"], "value": x["code_nip"],
} }
for x in r for x in r
@ -244,7 +240,7 @@ def search_etud_by_name(context, term, REQUEST=None):
data = [ data = [
{ {
"label": "%s %s" % (x["nom"], scolars.format_prenom(x["prenom"])), "label": "%s %s" % (x["nom"], sco_etud.format_prenom(x["prenom"])),
"value": x["etudid"], "value": x["etudid"],
} }
for x in r for x in r

View File

@ -30,19 +30,21 @@
from operator import itemgetter from operator import itemgetter
import xml.dom.minidom import xml.dom.minidom
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import sco_codes_parcours from app.scodoc import sco_codes_parcours
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_tag_module from app.scodoc import sco_tag_module
import sco_preferences from app.scodoc import sco_preferences
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from sco_permissions import ScoChangeFormation from app.scodoc.sco_permissions import Permission
from sco_permissions import Permission from app.scodoc import VERSION
import VERSION from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue
_formationEditor = ndb.EditableTable( _formationEditor = ndb.EditableTable(
"notes_formations", "notes_formations",

View File

@ -29,14 +29,16 @@
""" """
import time import time
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_codes_parcours from app.scodoc import sco_codes_parcours
from sco_codes_parcours import NO_SEMESTRE_ID from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
from sco_exceptions import ScoValueError from app.scodoc import sco_core
from app.scodoc import sco_preferences
from app.scodoc.sco_exceptions import ScoValueError
_formsemestreEditor = ndb.EditableTable( _formsemestreEditor = ndb.EditableTable(
"notes_formsemestre", "notes_formsemestre",
@ -129,7 +131,7 @@ def formsemestre_enrich(context, sem):
"""Ajoute champs souvent utiles: titre + annee et dateord (pour tris)""" """Ajoute champs souvent utiles: titre + annee et dateord (pour tris)"""
# imports ici pour eviter refs circulaires # imports ici pour eviter refs circulaires
import sco_formsemestre_edit import sco_formsemestre_edit
import scolars import sco_etud
from app.views import notes from app.views import notes
F = notes.formation_list(context, args={"formation_id": sem["formation_id"]})[0] F = notes.formation_list(context, args={"formation_id": sem["formation_id"]})[0]
@ -184,7 +186,7 @@ def formsemestre_enrich(context, sem):
sem["titreannee"] += "-" + annee_fin sem["titreannee"] += "-" + annee_fin
sem["annee"] += "-" + annee_fin sem["annee"] += "-" + annee_fin
# et les dates sous la forme "oct 2007 - fev 2008" # et les dates sous la forme "oct 2007 - fev 2008"
months = scolars.abbrvmonthsnames months = sco_etud.MONTH_NAMES_ABBREV
if mois_debut: if mois_debut:
mois_debut = months[int(mois_debut) - 1] mois_debut = months[int(mois_debut) - 1]
if mois_fin: if mois_fin:

View File

@ -29,13 +29,13 @@
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.TrivialFormulator import TrivialFormulator
from TrivialFormulator import TrivialFormulator, TF from app.scodoc import html_sco_header
import sco_formsemestre from app.scodoc import htmlutils
import sco_formsemestre_status from app.scodoc import sco_formsemestre
import sco_edt_cal from app.scodoc import sco_edt_cal
_custommenuEditor = ndb.EditableTable( _custommenuEditor = ndb.EditableTable(
"notes_formsemestre_custommenu", "notes_formsemestre_custommenu",
@ -73,7 +73,7 @@ def formsemestre_custommenu_html(context, formsemestre_id):
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
} }
) )
return sco_formsemestre_status.htmlutils.make_menu("Liens", menu) return htmlutils.make_menu("Liens", menu)
def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None): def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None):

View File

@ -28,25 +28,31 @@
"""Form choix modules / responsables et creation formsemestre """Form choix modules / responsables et creation formsemestre
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_core from app.scodoc import sco_core
import sco_groups from app.scodoc import sco_groups
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF from app.scodoc.TrivialFormulator import TrivialFormulator, TF
import notes_table from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
from sco_exceptions import AccessDenied, ScoValueError from app.scodoc.sco_formsemestre import ApoEtapeVDI
from sco_formsemestre import ApoEtapeVDI from app.scodoc.sco_permissions import Permission
from sco_permissions import Permission from app.scodoc import html_sco_header
import sco_codes_parcours from app.scodoc import sco_codes_parcours
import sco_compute_moy from app.scodoc import sco_compute_moy
import sco_formsemestre from app.scodoc import sco_edit_matiere
import sco_modalites from app.scodoc import sco_edit_module
import sco_moduleimpl from app.scodoc import sco_edit_ue
import sco_parcours_dut from app.scodoc import sco_evaluations
import sco_portal_apogee from app.scodoc import sco_formations
import sco_preferences from app.scodoc import sco_formsemestre
import scolars from app.scodoc import sco_modalites
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_permissions_check
from app.scodoc import sco_portal_apogee
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
def _default_sem_title(F): def _default_sem_title(F):
@ -1219,11 +1225,11 @@ def _reassociate_moduleimpls(
mod["module_id"] = modules_old2new[mod["module_id"]] mod["module_id"] = modules_old2new[mod["module_id"]]
sco_moduleimpl.do_moduleimpl_edit(context, mod, formsemestre_id=formsemestre_id) sco_moduleimpl.do_moduleimpl_edit(context, mod, formsemestre_id=formsemestre_id)
# update decisions: # update decisions:
events = scolars.scolar_events_list(cnx, args={"formsemestre_id": formsemestre_id}) events = sco_etud.scolar_events_list(cnx, args={"formsemestre_id": formsemestre_id})
for e in events: for e in events:
if e["ue_id"]: if e["ue_id"]:
e["ue_id"] = ues_old2new[e["ue_id"]] e["ue_id"] = ues_old2new[e["ue_id"]]
scolars.scolar_events_edit(cnx, e) sco_etud.scolar_events_edit(cnx, e)
validations = sco_parcours_dut.scolar_formsemestre_validation_list( validations = sco_parcours_dut.scolar_formsemestre_validation_list(
cnx, args={"formsemestre_id": formsemestre_id} cnx, args={"formsemestre_id": formsemestre_id}
) )
@ -1421,7 +1427,9 @@ def formsemestre_edit_options(context, formsemestre_id, target_url=None, REQUEST
(accessible par ScoImplement ou dir. etudes) (accessible par ScoImplement ou dir. etudes)
""" """
log("formsemestre_edit_options") log("formsemestre_edit_options")
ok, err = context._check_access_diretud(formsemestre_id, REQUEST) ok, err = sco_permissions_check.check_access_diretud(
context, formsemestre_id, REQUEST
)
if not ok: if not ok:
return err return err
return sco_preferences.SemPreferences(context, formsemestre_id).edit( return sco_preferences.SemPreferences(context, formsemestre_id).edit(
@ -1435,7 +1443,9 @@ def formsemestre_change_lock(
"""Change etat (verrouille si ouvert, déverrouille si fermé) """Change etat (verrouille si ouvert, déverrouille si fermé)
nota: etat (1 ouvert, 0 fermé) nota: etat (1 ouvert, 0 fermé)
""" """
ok, err = context._check_access_diretud(formsemestre_id, REQUEST) ok, err = sco_permissions_check.check_access_diretud(
context, formsemestre_id, REQUEST
)
if not ok: if not ok:
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -1475,7 +1485,9 @@ def formsemestre_change_publication_bul(
context, formsemestre_id, REQUEST=None, dialog_confirmed=False context, formsemestre_id, REQUEST=None, dialog_confirmed=False
): ):
"""Change etat publication bulletins sur portail""" """Change etat publication bulletins sur portail"""
ok, err = context._check_access_diretud(formsemestre_id, REQUEST) ok, err = sco_permissions_check.check_access_diretud(
context, formsemestre_id, REQUEST
)
if not ok: if not ok:
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -1515,8 +1527,12 @@ def formsemestre_change_publication_bul(
def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=None): def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=None):
"""Changement manuel des coefficients des UE capitalisées.""" """Changement manuel des coefficients des UE capitalisées."""
from app.scodoc import notes_table
context = context.Notes # si appele d'en haut, eg par exception ScoValueError context = context.Notes # si appele d'en haut, eg par exception ScoValueError
ok, err = context._check_access_diretud(formsemestre_id, REQUEST) ok, err = sco_permissions_check.check_access_diretud(
context, formsemestre_id, REQUEST
)
if not ok: if not ok:
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)

View File

@ -31,29 +31,33 @@ On va créer/gérer des semestres de la même formation que le semestre ScoDoc
est inscrit l'étudiant, leur attribuer la modalité 'EXT'. est inscrit l'étudiant, leur attribuer la modalité 'EXT'.
Ces semestres n'auront qu'un seul inscrit ! Ces semestres n'auront qu'un seul inscrit !
""" """
import TrivialFormulator
import sco_formsemestre
import sco_formsemestre_inscriptions
import sco_formsemestre_edit
import sco_formsemestre_validation
import sco_parcours_dut
import notesdb as ndb
from sco_utils import log
import pprint
import time import time
import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
from app.scodoc.sco_utils import log
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc import html_sco_header
from app.scodoc import sco_core
from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_validation
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(context, etudid, sem_params, REQUEST=None):
"""Crée un formsemestre exterieur et y inscrit l'étudiant. """Crée un formsemestre exterieur et y inscrit l'étudiant.
sem_params: dict nécessaire à la création du formsemestre sem_params: dict nécessaire à la création du formsemestre
""" """
# Check args # Check args
_formation = sco_formations.formation_list(context, _formation = sco_formations.formation_list(
args={"formation_id": sem_params["formation_id"]} context, args={"formation_id": sem_params["formation_id"]}
)[0] )[0]
if etudid: if etudid:
_etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] _etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
# Create formsemestre # Create formsemestre
sem_params["modalite"] = "EXT" sem_params["modalite"] = "EXT"
@ -75,7 +79,7 @@ def formsemestre_ext_create(context, etudid, sem_params, REQUEST=None):
def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None): def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None):
"""Formulaire creation/inscription à un semestre extérieur""" """Formulaire creation/inscription à un semestre extérieur"""
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
H = [ H = [
html_sco_header.sco_header(context, REQUEST), html_sco_header.sco_header(context, REQUEST),
"""<h2>Enregistrement d'une inscription antérieure dans un autre établissement</h2> """<h2>Enregistrement d'une inscription antérieure dans un autre établissement</h2>
@ -100,8 +104,8 @@ def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None)
# et seulement si pas inscrit au même semestre_id d'un semestre ordinaire ScoDoc. # et seulement si pas inscrit au même semestre_id d'un semestre ordinaire ScoDoc.
# Les autres situations (eg redoublements en changeant d'établissement) # Les autres situations (eg redoublements en changeant d'établissement)
# doivent être gérées par les validations de semestres "antérieurs" # doivent être gérées par les validations de semestres "antérieurs"
insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
args={"etudid": etudid, "etat": "I"} context, args={"etudid": etudid, "etat": "I"}
) )
semlist = [ semlist = [
sco_formsemestre.get_formsemestre(context, i["formsemestre_id"]) for i in insem sco_formsemestre.get_formsemestre(context, i["formsemestre_id"]) for i in insem
@ -172,7 +176,7 @@ def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None)
), ),
] ]
tf = TrivialFormulator.TrivialFormulator( tf = TrivialFormulator(
REQUEST.URL0, REQUEST.URL0,
REQUEST.form, REQUEST.form,
descr, descr,
@ -214,7 +218,7 @@ def formsemestre_ext_edit_ue_validations(
mais pas enregistrée. mais pas enregistrée.
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
ue_list = _list_ue_with_coef_and_validations(context, sem, etudid) ue_list = _list_ue_with_coef_and_validations(context, sem, etudid)
descr = _ue_form_description(context, ue_list, REQUEST.form) descr = _ue_form_description(context, ue_list, REQUEST.form)
if REQUEST and REQUEST.method == "GET": if REQUEST and REQUEST.method == "GET":
@ -223,7 +227,7 @@ def formsemestre_ext_edit_ue_validations(
} }
else: else:
initvalues = {} initvalues = {}
tf = TrivialFormulator.TrivialFormulator( tf = TrivialFormulator(
REQUEST.URL0, REQUEST.URL0,
REQUEST.form, REQUEST.form,
descr, descr,
@ -267,7 +271,7 @@ def _make_page(context, etud, sem, tf, message="", REQUEST=None):
page_title="Validation des UE d'un semestre extérieur", page_title="Validation des UE d'un semestre extérieur",
javascripts=["js/formsemestre_ext_edit_ue_validations.js"], javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
), ),
TrivialFormulator.tf_error_message(message), tf_error_message(message),
"""<p><b>%(nomprenom)s</b> est inscrit%(ne)s à ce semestre extérieur.</p> """<p><b>%(nomprenom)s</b> est inscrit%(ne)s à ce semestre extérieur.</p>
<p>Voici les UE entregistrées avec leur notes et coefficients. <p>Voici les UE entregistrées avec leur notes et coefficients.
</p> </p>

View File

@ -27,22 +27,25 @@
"""Opérations d'inscriptions aux semestres et modules """Opérations d'inscriptions aux semestres et modules
""" """
import time
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from sco_exceptions import ScoValueError from app.scodoc.scolog import logdb
from sco_permissions import ScoEtudInscrit from app.scodoc.sco_exceptions import ScoValueError
from sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME from app.scodoc.sco_permissions import Permission
import notesdb as ndb from app.scodoc.sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME
from notesdb import ScoDocCursor, DateISOtoDMY, DateDMYtoISO import app.scodoc.notesdb as ndb
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
from app.scodoc import sco_find_etud
from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_groups
from app.scodoc import sco_etud
from app.scodoc import sco_core
from app.scodoc import sco_formsemestre_edit
from app.scodoc import html_sco_header
from TrivialFormulator import TrivialFormulator, TF
# from notes_table import *
import sco_find_etud
import sco_formsemestre
import sco_moduleimpl
import sco_groups
# --- Gestion des inscriptions aux semestres # --- Gestion des inscriptions aux semestres
_formsemestre_inscriptionEditor = ndb.EditableTable( _formsemestre_inscriptionEditor = ndb.EditableTable(
@ -75,7 +78,7 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
# #
r = _formsemestre_inscriptionEditor.create(cnx, args) r = _formsemestre_inscriptionEditor.create(cnx, args)
# Evenement # Evenement
scolars.scolar_events_create( sco_etud.scolar_events_create(
cnx, cnx,
args={ args={
"etudid": args["etudid"], "etudid": args["etudid"],
@ -135,8 +138,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
"desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)" "desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)"
) )
insem = do_formsemestre_inscription_list(context, insem = do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id, "etudid": etudid} context, args={"formsemestre_id": formsemestre_id, "etudid": etudid}
) )
if not insem: if not insem:
raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid)
@ -160,8 +163,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
) )
# --- Semestre extérieur # --- Semestre extérieur
if sem["modalite"] == "EXT": if sem["modalite"] == "EXT":
inscrits = do_formsemestre_inscription_list(context, inscrits = do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
) )
nbinscrits = len(inscrits) nbinscrits = len(inscrits)
if nbinscrits == 0: if nbinscrits == 0:
@ -259,7 +262,7 @@ def formsemestre_inscription_with_modules_form(
"""Formulaire inscription de l'etud dans l'un des semestres existants. """Formulaire inscription de l'etud dans l'un des semestres existants.
Si only_ext, ne montre que les semestre extérieurs. Si only_ext, ne montre que les semestre extérieurs.
""" """
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
H = [ H = [
html_sco_header.sco_header(context, REQUEST), html_sco_header.sco_header(context, REQUEST),
"<h2>Inscription de %s" % etud["nomprenom"], "<h2>Inscription de %s" % etud["nomprenom"],
@ -275,8 +278,8 @@ def formsemestre_inscription_with_modules_form(
) )
F = html_sco_header.sco_footer(context, REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
sems = sco_formsemestre.do_formsemestre_list(context, args={"etat": "1"}) sems = sco_formsemestre.do_formsemestre_list(context, args={"etat": "1"})
insem = do_formsemestre_inscription_list(context, insem = do_formsemestre_inscription_list(
args={"etudid": etudid, "etat": "I"} context, args={"etudid": etudid, "etat": "I"}
) )
if sems: if sems:
H.append("<ul>") H.append("<ul>")
@ -318,7 +321,7 @@ def formsemestre_inscription_with_modules(
if multiple_ok: if multiple_ok:
multiple_ok = int(multiple_ok) multiple_ok = int(multiple_ok)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
H = [ H = [
html_sco_header.html_sem_header( html_sco_header.html_sem_header(
context, context,
@ -416,7 +419,7 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
if sem["etat"] != "1": if sem["etat"] != "1":
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(context).get_NotesTable(
context, formsemestre_id context, formsemestre_id
) # > get_etud_ue_status ) # > get_etud_ue_status
@ -480,7 +483,7 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
sem_origin["formsemestre_id"], sem_origin["formsemestre_id"],
etudid, etudid,
sem_origin["titreannee"], sem_origin["titreannee"],
DateISOtoDMY(ue_status["event_date"]), ndb.DateISOtoDMY(ue_status["event_date"]),
) )
descr.append( descr.append(
( (
@ -709,15 +712,15 @@ def est_inscrit_ailleurs(context, etudid, formsemestre_id):
temps que celui indiqué (par formsemestre_id). temps que celui indiqué (par formsemestre_id).
Retourne la liste des semestres concernés (ou liste vide). Retourne la liste des semestres concernés (ou liste vide).
""" """
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
debut_s = sem["dateord"] debut_s = sem["dateord"]
fin_s = DateDMYtoISO(sem["date_fin"]) fin_s = ndb.DateDMYtoISO(sem["date_fin"])
r = [] r = []
for s in etud["sems"]: for s in etud["sems"]:
if s["formsemestre_id"] != formsemestre_id: if s["formsemestre_id"] != formsemestre_id:
debut = s["dateord"] debut = s["dateord"]
fin = DateDMYtoISO(s["date_fin"]) fin = ndb.DateDMYtoISO(s["date_fin"])
if debut < fin_s and fin > debut_s: if debut < fin_s and fin > debut_s:
r.append(s) # intersection r.append(s) # intersection
return r return r
@ -754,7 +757,7 @@ def formsemestre_inscrits_ailleurs(context, formsemestre_id, REQUEST=None):
insd = list_inscrits_ailleurs(context, formsemestre_id) insd = list_inscrits_ailleurs(context, formsemestre_id)
# liste ordonnée par nom # liste ordonnée par nom
etudlist = [ etudlist = [
scolars.get_etud_info(etudid=etudid, filled=1)[0] sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
for etudid in insd.keys() for etudid in insd.keys()
if insd[etudid] if insd[etudid]
] ]

View File

@ -28,33 +28,38 @@
"""Tableau de bord semestre """Tableau de bord semestre
""" """
import urllib
import cgi
# Rewritten from ancient DTML code # Rewritten from ancient DTML code
from flask import current_app from flask import current_app
from notes_log import log from app.scodoc.notes_log import log
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
import VERSION from app.scodoc import VERSION
import htmlutils from app.scodoc import html_sco_header
from sco_formsemestre_custommenu import formsemestre_custommenu_html from app.scodoc import htmlutils
from gen_tables import GenTable from app.scodoc import sco_abs
import html_sco_header from app.scodoc import sco_archives
import sco_archives from app.scodoc import sco_bulletins
import sco_bulletins from app.scodoc import sco_codes_parcours
import sco_codes_parcours from app.scodoc import sco_compute_moy
import sco_core from app.scodoc import sco_core
import sco_compute_moy from app.scodoc import sco_edit_ue
import sco_evaluations from app.scodoc import sco_evaluations
import sco_formations from app.scodoc import sco_formations
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_formsemestre_edit from app.scodoc import sco_formsemestre_edit
import sco_groups from app.scodoc import sco_formsemestre_inscriptions
import sco_moduleimpl from app.scodoc import sco_groups
import sco_formsemestre_inscriptions from app.scodoc import sco_moduleimpl
import sco_permissions from app.scodoc import sco_permissions_check
import sco_preferences from app.scodoc import sco_preferences
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_formsemestre_custommenu import formsemestre_custommenu_html
# H = [ """<span class="barrenav"><ul class="nav"> # H = [ """<span class="barrenav"><ul class="nav">
@ -124,7 +129,7 @@ def defMenuStats(context, formsemestre_id):
}, },
{ {
"title": "Estimation du coût de la formation", "title": "Estimation du coût de la formation",
"endpoint": "notes.formsemestre_estim_cost?formsemestre_id", "endpoint": "notes.formsemestre_estim_cost",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": True, "enabled": True,
}, },
@ -162,9 +167,11 @@ def formsemestre_status_menubar(context, sem, REQUEST):
}, },
{ {
"title": "Modifier le semestre", "title": "Modifier le semestre",
"endpoint": "notes.formsemestre_editwithmodules?formation_id=%(formation_id)s&formsemestre_id=%(formsemestre_id)s" "endpoint": "notes.formsemestre_editwithmodules",
% sem, "args": {
"args": {"formsemestre_id": formsemestre_id}, "formation_id": sem["formation_id"],
"formsemestre_id": formsemestre_id,
},
"enabled": ( "enabled": (
authuser.has_permission(Permission.ScoImplement) authuser.has_permission(Permission.ScoImplement)
or ( or (
@ -177,7 +184,7 @@ def formsemestre_status_menubar(context, sem, REQUEST):
}, },
{ {
"title": "Préférences du semestre", "title": "Préférences du semestre",
"endpoint": "notes.formsemestre_edit_preferences", "endpoint": "scolar.formsemestre_edit_preferences",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": ( "enabled": (
authuser.has_permission(Permission.ScoImplement) authuser.has_permission(Permission.ScoImplement)
@ -292,27 +299,27 @@ def formsemestre_status_menubar(context, sem, REQUEST):
}, },
{ {
"title": "Importer des étudiants dans ce semestre (table Excel)", "title": "Importer des étudiants dans ce semestre (table Excel)",
"endpoint": "notes.form_students_import_excel", "endpoint": "scolar.form_students_import_excel",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": authuser.has_permission(Permission.ScoEtudInscrit) "enabled": authuser.has_permission(Permission.ScoEtudInscrit)
and (sem["etat"] == "1"), and (sem["etat"] == "1"),
}, },
{ {
"title": "Import/export des données admission", "title": "Import/export des données admission",
"endpoint": "notes.form_students_import_infos_admissions", "endpoint": "scolar.form_students_import_infos_admissions",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": authuser.has_permission(Permission.ScoView), "enabled": authuser.has_permission(Permission.ScoView),
}, },
{ {
"title": "Resynchroniser données identité", "title": "Resynchroniser données identité",
"endpoint": "notes.formsemestre_import_etud_admission", "endpoint": "scolar.formsemestre_import_etud_admission",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": authuser.has_permission(Permission.ScoEtudChangeAdr) "enabled": authuser.has_permission(Permission.ScoEtudChangeAdr)
and sco_preferences.get_preference(context, "portal_url"), and sco_preferences.get_preference(context, "portal_url"),
}, },
{ {
"title": "Exporter table des étudiants", "title": "Exporter table des étudiants",
"endpoint": "notes.groups_view", "endpoint": "scolar.groups_view",
"args": { "args": {
"format": "allxls", "format": "allxls",
"group_ids": sco_groups.get_default_group( "group_ids": sco_groups.get_default_group(
@ -330,14 +337,14 @@ def formsemestre_status_menubar(context, sem, REQUEST):
menuGroupes = [ menuGroupes = [
{ {
"title": "Listes, photos, feuilles...", "title": "Listes, photos, feuilles...",
"endpoint": "notes.groups_view", "endpoint": "scolar.groups_view",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": True, "enabled": True,
"helpmsg": "Accès aux listes des groupes d'étudiants", "helpmsg": "Accès aux listes des groupes d'étudiants",
}, },
{ {
"title": "Créer/modifier les partitions...", "title": "Créer/modifier les partitions...",
"endpoint": "notes.editPartitionForm", "endpoint": "scolar.editPartitionForm",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": sco_groups.can_change_groups(context, REQUEST, formsemestre_id), "enabled": sco_groups.can_change_groups(context, REQUEST, formsemestre_id),
}, },
@ -354,7 +361,7 @@ def formsemestre_status_menubar(context, sem, REQUEST):
submenu.append( submenu.append(
{ {
"title": "%s" % partition["partition_name"], "title": "%s" % partition["partition_name"],
"endpoint": "notes.affectGroups", "endpoint": "scolar.affectGroups",
"args": {"partition_id": partition["partition_id"]}, "args": {"partition_id": partition["partition_id"]},
"enabled": enabled, "enabled": enabled,
} }
@ -422,7 +429,7 @@ def formsemestre_status_menubar(context, sem, REQUEST):
"hidebac": 1, "hidebac": 1,
"pref_override": 0, "pref_override": 0,
}, },
"enabled": sco_permissions.can_validate_sem( "enabled": sco_permissions_check.can_validate_sem(
context, REQUEST, formsemestre_id context, REQUEST, formsemestre_id
), ),
}, },
@ -430,7 +437,9 @@ def formsemestre_status_menubar(context, sem, REQUEST):
"title": "Editer les PV et archiver les résultats", "title": "Editer les PV et archiver les résultats",
"endpoint": "notes.formsemestre_archive", "endpoint": "notes.formsemestre_archive",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": sco_permissions.can_edit_pv(context, REQUEST, formsemestre_id), "enabled": sco_permissions_check.can_edit_pv(
context, REQUEST, formsemestre_id
),
}, },
{ {
"title": "Documents archivés", "title": "Documents archivés",

View File

@ -29,22 +29,28 @@
""" """
import urllib, time, datetime import urllib, time, datetime
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
import notes_table from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.sco_exceptions import ScoValueError
from sco_exceptions import ScoValueError from app.scodoc.sco_abs import getAbsSemEtud
from sco_abs import getAbsSemEtud
import sco_formsemestre from app.scodoc.sco_codes_parcours import *
import sco_formsemestre_edit from app.scodoc import html_sco_header
import sco_formsemestre_status from app.scodoc import sco_codes_parcours
import sco_parcours_dut from app.scodoc import sco_core
import sco_codes_parcours from app.scodoc import sco_edit_ue
from sco_codes_parcours import * from app.scodoc import sco_etud
import sco_pvjury from app.scodoc import sco_formsemestre
import sco_photos from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_photos
from app.scodoc import sco_preferences
from app.scodoc import sco_pvjury
# ------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------
def formsemestre_validation_etud_form( def formsemestre_validation_etud_form(
@ -91,7 +97,7 @@ def formsemestre_validation_etud_form(
if readonly: if readonly:
check = True check = True
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if Se.sem["etat"] != "1": if Se.sem["etat"] != "1":
raise ScoValueError("validation: semestre verrouille") raise ScoValueError("validation: semestre verrouille")
@ -108,13 +114,13 @@ def formsemestre_validation_etud_form(
Footer = ["<p>"] Footer = ["<p>"]
# Navigation suivant/precedent # Navigation suivant/precedent
if etud_index_prev != None: if etud_index_prev != None:
etud_p = scolars.get_etud_info(etudid=T[etud_index_prev][-1], filled=True)[0] etud_p = sco_etud.get_etud_info(etudid=T[etud_index_prev][-1], filled=True)[0]
Footer.append( Footer.append(
'<span><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. précédent (%s)</a></span>' '<span><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. précédent (%s)</a></span>'
% (formsemestre_id, etud_index_prev, etud_p["nomprenom"]) % (formsemestre_id, etud_index_prev, etud_p["nomprenom"])
) )
if etud_index_next != None: if etud_index_next != None:
etud_n = scolars.get_etud_info(etudid=T[etud_index_next][-1], filled=True)[0] etud_n = sco_etud.get_etud_info(etudid=T[etud_index_next][-1], filled=True)[0]
Footer.append( Footer.append(
'<span style="padding-left: 50px;"><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. suivant (%s)</a></span>' '<span style="padding-left: 50px;"><a href="formsemestre_validation_etud_form?formsemestre_id=%s&etud_index=%s">Etud. suivant (%s)</a></span>'
% (formsemestre_id, etud_index_next, etud_n["nomprenom"]) % (formsemestre_id, etud_index_next, etud_n["nomprenom"])
@ -333,22 +339,22 @@ def formsemestre_validation_etud(
REQUEST=None, REQUEST=None,
): ):
"""Enregistre validation""" """Enregistre validation"""
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
# retrouve la decision correspondant au code: # retrouve la decision correspondant au code:
choices = Se.get_possible_choices(assiduite=True) choices = Se.get_possible_choices(assiduite=True)
choices += Se.get_possible_choices(assiduite=False) choices += Se.get_possible_choices(assiduite=False)
found = False selected_choice = None
for choice in choices: for choice in choices:
if choice.codechoice == codechoice: if choice.codechoice == codechoice:
found = True selected_choice = choice
break break
if not found: if not selected_choice:
raise ValueError("code choix invalide ! (%s)" % codechoice) raise ValueError("code choix invalide ! (%s)" % codechoice)
# #
Se.valide_decision(choice, REQUEST) # enregistre Se.valide_decision(selected_choice, REQUEST) # enregistre
return _redirect_valid_choice( return _redirect_valid_choice(
formsemestre_id, etudid, Se, choice, desturl, sortcol, REQUEST formsemestre_id, etudid, Se, selected_choice, desturl, sortcol, REQUEST
) )
@ -368,7 +374,7 @@ def formsemestre_validation_etud_manu(
"""Enregistre validation""" """Enregistre validation"""
if assidu: if assidu:
assidu = 1 assidu = 1
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if code_etat in Se.parcours.UNUSED_CODES: if code_etat in Se.parcours.UNUSED_CODES:
raise ScoValueError("code decision invalide dans ce parcours") raise ScoValueError("code decision invalide dans ce parcours")
@ -862,10 +868,10 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
nb_valid = 0 nb_valid = 0
conflicts = [] # liste des etudiants avec decision differente déjà saisie conflicts = [] # liste des etudiants avec decision differente déjà saisie
for etudid in etudids: for etudid in etudids:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": formsemestre_id} context, {"etudid": etudid, "formsemestre_id": formsemestre_id}
)[0] )[0]
# Conditions pour validation automatique: # Conditions pour validation automatique:
@ -964,10 +970,10 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
modifs = [] # liste d'étudiants modifiés modifs = [] # liste d'étudiants modifiés
cnx = context.GetDBConnexion(autocommit=False) cnx = context.GetDBConnexion(autocommit=False)
for etudid in etudids: for etudid in etudids:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": formsemestre_id} context, {"etudid": etudid, "formsemestre_id": formsemestre_id}
)[0] )[0]
decision_sem = nt.get_etud_decision_sem(etudid) decision_sem = nt.get_etud_decision_sem(etudid)
if not decision_sem: if not decision_sem:
@ -1071,9 +1077,13 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
"""Form. saisie UE validée hors ScoDoc """Form. saisie UE validée hors ScoDoc
(pour étudiants arrivant avec un UE antérieurement validée). (pour étudiants arrivant avec un UE antérieurement validée).
""" """
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] from app.scodoc import sco_formations
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
Fo = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] Fo = sco_formations.formation_list(
context, args={"formation_id": sem["formation_id"]}
)[0]
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(

View File

@ -29,14 +29,10 @@
""" """
import operator import operator
import traceback
from types import FloatType, IntType, LongType, StringType from types import FloatType, IntType, LongType, StringType
import sco_utils as scu
from notes_log import log
class NoteVector(object):
class NoteVector:
"""Vecteur de notes (ou coefficients) utilisé pour les formules définies par l'utilisateur. """Vecteur de notes (ou coefficients) utilisé pour les formules définies par l'utilisateur.
Les éléments sont accessibles soit par index v[i], soit par leur nom v['nom'] s'il en ont un. Les éléments sont accessibles soit par index v[i], soit par leur nom v['nom'] s'il en ont un.
Les éléments sont toujours numériques (float). Les valeurs non numériques ('NI', ...) sont Les éléments sont toujours numériques (float). Les valeurs non numériques ('NI', ...) sont

View File

@ -43,17 +43,18 @@ import operator
import jaxml import jaxml
import xml.dom.minidom import xml.dom.minidom
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
from TrivialFormulator import TrivialFormulator, TF from app.scodoc import html_sco_header
import sco_formsemestre from app.scodoc import sco_codes_parcours
import scolars from app.scodoc import sco_core
import sco_parcours_dut from app.scodoc import sco_etud
import sco_codes_parcours from app.scodoc import sco_formsemestre
from sco_permissions import ScoEtudChangeGroups from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError
from sco_exceptions import ScoException, AccessDenied, ScoValueError from app.scodoc.sco_permissions import Permission
from app.scodoc.TrivialFormulator import TrivialFormulator
def can_change_groups(context, REQUEST, formsemestre_id): def can_change_groups(context, REQUEST, formsemestre_id):
@ -244,7 +245,7 @@ def get_group_members(context, group_id, etat=None):
r = ndb.SimpleDictFetch(context, req, {"group_id": group_id, "etat": etat}) r = ndb.SimpleDictFetch(context, req, {"group_id": group_id, "etat": etat})
for etud in r: for etud in r:
scolars.format_etud_ident(etud) sco_etud.format_etud_ident(etud)
r.sort(key=operator.itemgetter("nom_disp", "prenom")) # tri selon nom_usuel ou nom r.sort(key=operator.itemgetter("nom_disp", "prenom")) # tri selon nom_usuel ou nom
@ -285,7 +286,7 @@ def get_group_infos(context, group_id, etat=None): # was _getlisteetud
if t["etat"] == "I": if t["etat"] == "I":
t["etath"] = "" # etudiant inscrit, ne l'indique pas dans la liste HTML t["etath"] = "" # etudiant inscrit, ne l'indique pas dans la liste HTML
elif t["etat"] == "D": elif t["etat"] == "D":
events = scolars.scolar_events_list( events = sco_etud.scolar_events_list(
cnx, cnx,
args={ args={
"etudid": t["etudid"], "etudid": t["etudid"],
@ -469,14 +470,14 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
group_name=group["group_name"], group_name=group["group_name"],
) )
for e in get_group_members(context, group["group_id"]): for e in get_group_members(context, group["group_id"]):
etud = scolars.get_etud_info(etudid=e["etudid"], filled=1)[0] etud = sco_etud.get_etud_info(etudid=e["etudid"], filled=1)[0]
doc._push() doc._push()
doc.etud( doc.etud(
etudid=e["etudid"], etudid=e["etudid"],
civilite=etud["civilite_str"], civilite=etud["civilite_str"],
sexe=etud["civilite_str"], # compat sexe=etud["civilite_str"], # compat
nom=scolars.format_nom(etud["nom"]), nom=sco_etud.format_nom(etud["nom"]),
prenom=scolars.format_prenom(etud["prenom"]), prenom=sco_etud.format_prenom(etud["prenom"]),
origin=comp_origin(etud, sem), origin=comp_origin(etud, sem),
) )
if e["etudid"] in etuds_set: if e["etudid"] in etuds_set:
@ -494,13 +495,13 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
group_name="", group_name="",
) )
for etudid in etuds_set: for etudid in etuds_set:
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
doc._push() doc._push()
doc.etud( doc.etud(
etudid=etud["etudid"], etudid=etud["etudid"],
sexe=etud["civilite_str"], sexe=etud["civilite_str"],
nom=scolars.format_nom(etud["nom"]), nom=sco_etud.format_nom(etud["nom"]),
prenom=scolars.format_prenom(etud["prenom"]), prenom=sco_etud.format_prenom(etud["prenom"]),
origin=comp_origin(etud, sem), origin=comp_origin(etud, sem),
) )
doc._pop() doc._pop()
@ -1297,9 +1298,9 @@ def get_prev_moy(context, etudid, formsemestre_id):
"""Donne la derniere moyenne generale calculee pour cette étudiant, """Donne la derniere moyenne generale calculee pour cette étudiant,
ou 0 si on n'en trouve pas (nouvel inscrit,...). ou 0 si on n'en trouve pas (nouvel inscrit,...).
""" """
import sco_parcours_dut from app.scodoc import sco_parcours_dut
info = scolars.get_etud_info(etudid=etudid, filled=True) info = sco_etud.get_etud_info(etudid=etudid, filled=True)
if not info: if not info:
raise ScoValueError("etudiant invalide: etudid=%s" % etudid) raise ScoValueError("etudiant invalide: etudid=%s" % etudid)
etud = info[0] etud = info[0]
@ -1320,9 +1321,11 @@ def create_etapes_partition(context, formsemestre_id, partition_name="apo_etapes
Si la partition existe déjà, ses groupes sont mis à jour (les groupes devenant Si la partition existe déjà, ses groupes sont mis à jour (les groupes devenant
vides ne sont pas supprimés). vides ne sont pas supprimés).
""" """
from app.scodoc import sco_formsemestre_inscriptions
log("create_etapes_partition(%s)" % formsemestre_id) log("create_etapes_partition(%s)" % formsemestre_id)
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
) )
etapes = {i["etape"] for i in ins if i["etape"]} etapes = {i["etape"] for i in ins if i["etape"]}
partitions = get_partitions_list(context, formsemestre_id, with_default=False) partitions = get_partitions_list(context, formsemestre_id, with_default=False)

View File

@ -28,14 +28,9 @@
"""Formulaires gestion des groupes """Formulaires gestion des groupes
""" """
import re from app.scodoc import html_sco_header
from app.scodoc import sco_groups
import sco_utils as scu from app.scodoc.sco_exceptions import AccessDenied
import notesdb as ndb
from notes_log import log
import sco_formsemestre
import sco_groups
from sco_exceptions import AccessDenied
def affectGroups(context, partition_id, REQUEST=None): def affectGroups(context, partition_id, REQUEST=None):
@ -49,7 +44,8 @@ def affectGroups(context, partition_id, REQUEST=None):
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération") raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
H = [ H = [
html_sco_header.sco_header(context, html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="Affectation aux groupes", page_title="Affectation aux groupes",
javascripts=["js/groupmgr.js"], javascripts=["js/groupmgr.js"],

View File

@ -37,21 +37,20 @@ import time
import collections import collections
import operator import operator
import sco_utils as scu import app.scodoc.sco_utils as scu
from sco_permissions import ScoEtudInscrit, ScoEtudAddAnnotations, ScoAbsChange from app.scodoc import html_sco_header
from sco_exceptions import ScoValueError from app.scodoc import sco_abs
import html_sco_header from app.scodoc import sco_excel
from gen_tables import GenTable from app.scodoc import sco_formsemestre
import scolars from app.scodoc import sco_groups
import sco_abs from app.scodoc import sco_moduleimpl
import sco_excel from app.scodoc import sco_parcours_dut
import sco_formsemestre from app.scodoc import sco_portal_apogee
import sco_moduleimpl from app.scodoc import sco_preferences
import sco_groups from app.scodoc import sco_etud
import sco_trombino from app.scodoc.gen_tables import GenTable
import sco_portal_apogee from app.scodoc.sco_exceptions import ScoValueError
import sco_parcours_dut from app.scodoc.sco_permissions import Permission
import sco_report
JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + [ JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + [
"js/etud_info.js", "js/etud_info.js",
@ -452,6 +451,8 @@ def groups_table(
format: csv, json, xml, xls, allxls, xlsappel, moodlecsv, pdf format: csv, json, xml, xls, allxls, xlsappel, moodlecsv, pdf
Si with_codes, ajoute 4 colonnes avec les codes etudid, NIP, INE et etape Si with_codes, ajoute 4 colonnes avec les codes etudid, NIP, INE et etape
""" """
from app.scodoc import sco_report
# log( # log(
# "enter groups_table %s: %s" # "enter groups_table %s: %s"
# % (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-")) # % (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-"))
@ -515,7 +516,7 @@ def groups_table(
sco_archives_etud.add_archives_info_to_etud_list(context, groups_infos.members) sco_archives_etud.add_archives_info_to_etud_list(context, groups_infos.members)
columns_ids += ["etudarchive"] columns_ids += ["etudarchive"]
if with_annotations: if with_annotations:
scolars.add_annotations_to_etud_list(context, groups_infos.members) sco_etud.add_annotations_to_etud_list(context, groups_infos.members)
columns_ids += ["annotations_str"] columns_ids += ["annotations_str"]
if groups_infos.formsemestre["semestre_id"] >= 0: if groups_infos.formsemestre["semestre_id"] >= 0:
@ -785,9 +786,9 @@ def groups_table(
# remplis infos lycee si on a que le code lycée # remplis infos lycee si on a que le code lycée
# et ajoute infos inscription # et ajoute infos inscription
for m in groups_infos.members: for m in groups_infos.members:
etud = scolars.get_etud_info(m["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(m["etudid"], filled=True)[0]
m.update(etud) m.update(etud)
scolars.etud_add_lycee_infos(etud) sco_etud.etud_add_lycee_infos(etud)
# et ajoute le parcours # et ajoute le parcours
Se = sco_parcours_dut.SituationEtudParcours( Se = sco_parcours_dut.SituationEtudParcours(
context.Notes, etud, groups_infos.formsemestre_id context.Notes, etud, groups_infos.formsemestre_id
@ -873,6 +874,8 @@ def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
def tab_photos_html(context, groups_infos, etat=None, REQUEST=None): def tab_photos_html(context, groups_infos, etat=None, REQUEST=None):
"""contenu du tab "photos" """ """contenu du tab "photos" """
from app.scodoc import sco_trombino
if not groups_infos.members: if not groups_infos.members:
return '<div class="tab-content"><h3>Aucun étudiant !</h3></div>' return '<div class="tab-content"><h3>Aucun étudiant !</h3></div>'
@ -974,7 +977,7 @@ def export_groups_as_moodle_csv(context, formsemestre_id=None, REQUEST=None):
partition = sco_groups.get_partition(context, partition_id) partition = sco_groups.get_partition(context, partition_id)
members = partitions_etud_groups[partition_id] members = partitions_etud_groups[partition_id]
for etudid in members: for etudid in members:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
group_name = members[etudid]["group_name"] group_name = members[etudid]["group_name"]
elts = [moodle_sem_name] elts = [moodle_sem_name]
if partition["partition_name"]: if partition["partition_name"]:

View File

@ -27,20 +27,16 @@
"""Import d'utilisateurs via fichier Excel """Import d'utilisateurs via fichier Excel
""" """
import email
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
import mails from app.scodoc import mails
import notesdb as ndb import app.scodoc.sco_utils as scu
import sco_utils as scu from app.scodoc.notes_log import log
from notes_log import log from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoException
from TrivialFormulator import TrivialFormulator, TF from app.scodoc import sco_excel
import sco_news from app.scodoc import sco_preferences
import sco_excel
from sco_exceptions import AccessDenied, ScoValueError, ScoException
TITLES = ("user_name", "nom", "prenom", "email", "roles", "dept") TITLES = ("user_name", "nom", "prenom", "email", "roles", "dept")

View File

@ -30,18 +30,20 @@
""" """
import datetime import datetime
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_codes_parcours from app.scodoc import html_sco_header
import sco_pvjury from app.scodoc import sco_codes_parcours
import sco_formsemestre from app.scodoc import sco_preferences
import sco_formsemestre_inscriptions from app.scodoc import sco_pvjury
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_formsemestre_inscriptions
import scolars from app.scodoc import sco_formations
from sco_exceptions import ScoValueError from app.scodoc import sco_groups
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(context, sem, delai=274):
@ -59,7 +61,7 @@ def list_authorized_etuds_by_sem(context, sem, delai=274):
for e in liste: for e in liste:
# Filtre ceux qui se sont déjà inscrit dans un semestre APRES le semestre src # Filtre ceux qui se sont déjà inscrit dans un semestre APRES le semestre src
auth_used = False # autorisation deja utilisée ? auth_used = False # autorisation deja utilisée ?
etud = scolars.get_etud_info(etudid=e["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(etudid=e["etudid"], filled=True)[0]
for isem in etud["sems"]: for isem in etud["sems"]:
if ndb.DateDMYtoISO(isem["date_debut"]) >= ndb.DateDMYtoISO( if ndb.DateDMYtoISO(isem["date_debut"]) >= ndb.DateDMYtoISO(
src["date_fin"] src["date_fin"]
@ -110,11 +112,13 @@ def list_inscrits(context, formsemestre_id, with_dems=False):
) # optimized ) # optimized
else: else:
args = {"formsemestre_id": formsemestre_id} args = {"formsemestre_id": formsemestre_id}
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, args=args) ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
context, args=args
)
inscr = {} inscr = {}
for i in ins: for i in ins:
etudid = i["etudid"] etudid = i["etudid"]
inscr[etudid] = scolars.get_etud_info(etudid=etudid, filled=True)[0] inscr[etudid] = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
return inscr return inscr
@ -172,7 +176,7 @@ def do_inscrit(context, sem, etudids, REQUEST=None, inscrit_groupes=False):
# (mise en correspondance à partir du nom du groupe, sans tenir compte # (mise en correspondance à partir du nom du groupe, sans tenir compte
# du nom de la partition: évidemment, cela ne marche pas si on a les # du nom de la partition: évidemment, cela ne marche pas si on a les
# même noms de groupes dans des partitions différentes) # même noms de groupes dans des partitions différentes)
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
log("cherche groupes de %(nom)s" % etud) log("cherche groupes de %(nom)s" % etud)
# recherche le semestre origine (il serait plus propre de l'avoir conservé!) # recherche le semestre origine (il serait plus propre de l'avoir conservé!)
@ -242,7 +246,9 @@ def list_source_sems(context, sem, delai=None):
if s["semestre_id"] == sco_codes_parcours.NO_SEMESTRE_ID: if s["semestre_id"] == sco_codes_parcours.NO_SEMESTRE_ID:
continue continue
# #
F = sco_formations.formation_list(context, args={"formation_id": s["formation_id"]})[0] F = sco_formations.formation_list(
context, args={"formation_id": s["formation_id"]}
)[0]
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
if not parcours.ALLOW_SEM_SKIP: if not parcours.ALLOW_SEM_SKIP:
if s["semestre_id"] < (sem["semestre_id"] - 1): if s["semestre_id"] < (sem["semestre_id"] - 1):
@ -569,7 +575,7 @@ def etuds_select_boxes(
c = " inscrailleurs" c = " inscrailleurs"
else: else:
c = "" c = ""
scolars.format_etud_ident(etud) sco_etud.format_etud_ident(etud)
if etud["etudid"]: if etud["etudid"]:
elink = ( elink = (
"""<a class="discretelink %s" href="ficheEtud?etudid=%s">%s</a>""" """<a class="discretelink %s" href="ficheEtud?etudid=%s">%s</a>"""

View File

@ -30,19 +30,26 @@
import urllib import urllib
from types import StringType from types import StringType
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF from app.scodoc.TrivialFormulator import TrivialFormulator
import sco_formsemestre from app.scodoc import htmlutils
import sco_moduleimpl from app.scodoc import html_sco_header
import sco_groups from app.scodoc import sco_abs
import sco_evaluations from app.scodoc import sco_core
import htmlutils from app.scodoc import sco_edit_module
import sco_excel from app.scodoc import sco_evaluations
from gen_tables import GenTable from app.scodoc import sco_excel
from htmlutils import histogram_notes from app.scodoc import sco_formsemestre
import VERSION from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
from app.scodoc import VERSION
from app.scodoc.gen_tables import GenTable
from app.scodoc.htmlutils import histogram_notes
def do_evaluation_listenotes(context, REQUEST): def do_evaluation_listenotes(context, REQUEST):
@ -55,11 +62,15 @@ def do_evaluation_listenotes(context, REQUEST):
if REQUEST.form.has_key("evaluation_id"): if REQUEST.form.has_key("evaluation_id"):
evaluation_id = REQUEST.form["evaluation_id"] evaluation_id = REQUEST.form["evaluation_id"]
mode = "eval" mode = "eval"
evals = sco_evaluations.do_evaluation_list(context, {"evaluation_id": evaluation_id}) evals = sco_evaluations.do_evaluation_list(
context, {"evaluation_id": evaluation_id}
)
if REQUEST.form.has_key("moduleimpl_id"): if REQUEST.form.has_key("moduleimpl_id"):
moduleimpl_id = REQUEST.form["moduleimpl_id"] moduleimpl_id = REQUEST.form["moduleimpl_id"]
mode = "module" mode = "module"
evals = sco_evaluations.do_evaluation_list(context, {"moduleimpl_id": moduleimpl_id}) evals = sco_evaluations.do_evaluation_list(
context, {"moduleimpl_id": moduleimpl_id}
)
if not mode: if not mode:
raise ValueError("missing argument: evaluation or module") raise ValueError("missing argument: evaluation or module")
if not evals: if not evals:
@ -284,10 +295,10 @@ def _make_table_notes(
for etudid in etudids: for etudid in etudids:
css_row_class = None css_row_class = None
# infos identite etudiant # infos identite etudiant
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
# infos inscription # infos inscription
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": M["formsemestre_id"]} context, {"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
)[0] )[0]
if inscr["etat"] == "I": # si inscrit, indique groupe if inscr["etat"] == "I": # si inscrit, indique groupe
@ -540,7 +551,7 @@ def _add_eval_columns(
sum_notes = 0 sum_notes = 0
notes = [] # liste des notes numeriques, pour calcul histogramme uniquement notes = [] # liste des notes numeriques, pour calcul histogramme uniquement
evaluation_id = e["evaluation_id"] evaluation_id = e["evaluation_id"]
NotesDB = context._notes_getall(evaluation_id) NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
for row in rows: for row in rows:
etudid = row["etudid"] etudid = row["etudid"]
if NotesDB.has_key(etudid): if NotesDB.has_key(etudid):
@ -717,17 +728,17 @@ def evaluation_check_absences(context, evaluation_id):
am, pm, demijournee = _eval_demijournee(E) am, pm, demijournee = _eval_demijournee(E)
# Liste les absences à ce moment: # Liste les absences à ce moment:
A = context.Absences.ListeAbsJour(ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm) A = sco_abs.ListeAbsJour(context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm)
As = set([x["etudid"] for x in A]) # ensemble des etudiants absents As = set([x["etudid"] for x in A]) # ensemble des etudiants absents
NJ = context.Absences.ListeAbsNonJustJour(ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm) NJ = sco_abs.ListeAbsNonJustJour(context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm)
NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies
Just = context.Absences.ListeAbsJour( Just = sco_abs.ListeAbsJour(
ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True
) )
Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif
# Les notes: # Les notes:
NotesDB = context._notes_getall(evaluation_id) NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
ValButAbs = [] # une note mais noté absent ValButAbs = [] # une note mais noté absent
AbsNonSignalee = [] # note ABS mais pas noté absent AbsNonSignalee = [] # note ABS mais pas noté absent
ExcNonSignalee = [] # note EXC mais pas noté absent ExcNonSignalee = [] # note EXC mais pas noté absent
@ -803,7 +814,7 @@ def evaluation_check_absences_html(
if not etudids and show_ok: if not etudids and show_ok:
H.append("<li>aucun</li>") H.append("<li>aucun</li>")
for etudid in etudids: for etudid in etudids:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
H.append( H.append(
'<li><a class="discretelink" href="ficheEtud?etudid=%(etudid)s">%(nomprenom)s</a>' '<li><a class="discretelink" href="ficheEtud?etudid=%(etudid)s">%(nomprenom)s</a>'
% etud % etud
@ -877,7 +888,9 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
context, formsemestre_id=formsemestre_id context, formsemestre_id=formsemestre_id
) )
for M in Mlist: for M in Mlist:
evals = sco_evaluations.do_evaluation_list(context, {"moduleimpl_id": M["moduleimpl_id"]}) evals = sco_evaluations.do_evaluation_list(
context, {"moduleimpl_id": M["moduleimpl_id"]}
)
if evals: if evals:
H.append( H.append(
'<div class="module_check_absences"><h2><a href="moduleimpl_status?moduleimpl_id=%s">%s: %s</a></h2>' '<div class="module_check_absences"><h2><a href="moduleimpl_status?moduleimpl_id=%s">%s: %s</a></h2>'

View File

@ -30,16 +30,14 @@
- suivi cohortes - suivi cohortes
""" """
import tempfile, urllib, re import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header
import sco_utils as scu from app.scodoc import sco_formsemestre
from notes_log import log from app.scodoc import sco_preferences
import scolars from app.scodoc import sco_report
import sco_groups from app.scodoc import sco_etud
import sco_report from app.scodoc import VERSION
from gen_tables import GenTable from app.scodoc.gen_tables import GenTable
import sco_formsemestre
import VERSION
def formsemestre_table_etuds_lycees( def formsemestre_table_etuds_lycees(
@ -106,7 +104,7 @@ def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
def _table_etuds_lycees( def _table_etuds_lycees(
context, etuds, group_lycees, title, preferences, no_links=False context, etuds, group_lycees, title, preferences, no_links=False
): ):
etuds = [scolars.etud_add_lycee_infos(e) for e in etuds] etuds = [sco_etud.etud_add_lycee_infos(e) for e in etuds]
etuds_by_lycee = scu.group_by_key(etuds, "codelycee") etuds_by_lycee = scu.group_by_key(etuds, "codelycee")
# #
if group_lycees: if group_lycees:

View File

@ -33,11 +33,9 @@ Elle n'est pas utilisée pour les parcours, ni pour rien d'autre
(c'est donc un attribut "cosmétique"). (c'est donc un attribut "cosmétique").
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from TrivialFormulator import TrivialFormulator, TF
import sco_codes_parcours
def list_formsemestres_modalites(context, sems): def list_formsemestres_modalites(context, sems):

View File

@ -28,24 +28,20 @@
"""Fonctions sur les moduleimpl """Fonctions sur les moduleimpl
""" """
# codes anciens déplacés de ZEntreprise # codes anciens déplacés de ZEntreprise
import datetime
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO from app.scodoc.sco_permissions import Permission
from sco_permissions import ScoImplement from app.scodoc.sco_exceptions import ScoValueError, AccessDenied
from sco_exceptions import ScoValueError, AccessDenied from app.scodoc.notes_log import log
from notes_log import log from app.scodoc import scolog
import scolog from app.scodoc import sco_formsemestre
import sco_edit_matiere from app.scodoc import sco_core
import sco_edit_module
import sco_edit_ue
import sco_formsemestre
# --- Gestion des "Implémentations de Modules" # --- Gestion des "Implémentations de Modules"
# Un "moduleimpl" correspond a la mise en oeuvre d'un module # Un "moduleimpl" correspond a la mise en oeuvre d'un module
# dans une formation spécifique, à une date spécifique. # dans une formation spécifique, à une date spécifique.
_moduleimplEditor = EditableTable( _moduleimplEditor = ndb.EditableTable(
"notes_moduleimpl", "notes_moduleimpl",
"moduleimpl_id", "moduleimpl_id",
( (
@ -57,7 +53,7 @@ _moduleimplEditor = EditableTable(
), ),
) )
_modules_enseignantsEditor = EditableTable( _modules_enseignantsEditor = ndb.EditableTable(
"notes_modules_enseignants", "notes_modules_enseignants",
"modules_enseignants_id", "modules_enseignants_id",
("modules_enseignants_id", "moduleimpl_id", "ens_id"), ("modules_enseignants_id", "moduleimpl_id", "ens_id"),
@ -78,7 +74,7 @@ def do_moduleimpl_delete(context, oid, formsemestre_id=None):
"delete moduleimpl (desinscrit tous les etudiants)" "delete moduleimpl (desinscrit tous les etudiants)"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# --- desinscription des etudiants # --- desinscription des etudiants
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = ( req = (
"DELETE FROM notes_moduleimpl_inscription WHERE moduleimpl_id=%(moduleimpl_id)s" "DELETE FROM notes_moduleimpl_inscription WHERE moduleimpl_id=%(moduleimpl_id)s"
) )
@ -106,7 +102,7 @@ def do_moduleimpl_list(
"list moduleimpls" "list moduleimpls"
args = locals() args = locals()
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
modimpls = _moduleimplEditor.list(cnx, args) # *args, **kw) modimpls = _moduleimplEditor.list(cnx, args)
# Ajoute la liste des enseignants # Ajoute la liste des enseignants
for mo in modimpls: for mo in modimpls:
mo["ens"] = do_ens_list(context, args={"moduleimpl_id": mo["moduleimpl_id"]}) mo["ens"] = do_ens_list(context, args={"moduleimpl_id": mo["moduleimpl_id"]})
@ -130,10 +126,21 @@ def do_moduleimpl_withmodule_list(
Attention: Cette fonction fait partie de l'API ScoDoc 7 et est publiée. Attention: Cette fonction fait partie de l'API ScoDoc 7 et est publiée.
""" """
from app.scodoc import sco_edit_ue
from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
args = locals() args = locals()
del args["context"] del args["context"]
del args["REQUEST"] del args["REQUEST"]
modimpls = do_moduleimpl_list(context, **args) modimpls = do_moduleimpl_list(
context,
**{
"moduleimpl_id": moduleimpl_id,
"formsemestre_id": formsemestre_id,
"module_id": module_id,
}
)
for mo in modimpls: for mo in modimpls:
mo["module"] = sco_edit_module.do_module_list( mo["module"] = sco_edit_module.do_module_list(
context, args={"module_id": mo["module_id"]} context, args={"module_id": mo["module_id"]}
@ -174,7 +181,7 @@ def do_moduleimpl_listeetuds(context, moduleimpl_id):
"retourne liste des etudids inscrits a ce module" "retourne liste des etudids inscrits a ce module"
req = "select distinct Im.etudid from notes_moduleimpl_inscription Im, notes_formsemestre_inscription Isem, notes_moduleimpl M where Isem.etudid=Im.etudid and Im.moduleimpl_id=M.moduleimpl_id and M.moduleimpl_id = %(moduleimpl_id)s" req = "select distinct Im.etudid from notes_moduleimpl_inscription Im, notes_formsemestre_inscription Isem, notes_moduleimpl M where Isem.etudid=Im.etudid and Im.moduleimpl_id=M.moduleimpl_id and M.moduleimpl_id = %(moduleimpl_id)s"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(req, {"moduleimpl_id": moduleimpl_id}) cursor.execute(req, {"moduleimpl_id": moduleimpl_id})
res = cursor.fetchall() res = cursor.fetchall()
return [x[0] for x in res] return [x[0] for x in res]
@ -184,7 +191,7 @@ def do_moduleimpl_inscrit_tout_semestre(context, moduleimpl_id, formsemestre_id)
"inscrit tous les etudiants inscrit au semestre a ce module" "inscrit tous les etudiants inscrit au semestre a ce module"
# UNUSED # UNUSED
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
req = """INSERT INTO notes_moduleimpl_inscription req = """INSERT INTO notes_moduleimpl_inscription
(moduleimpl_id, etudid) (moduleimpl_id, etudid)
SELECT %(moduleimpl_id)s, I.etudid SELECT %(moduleimpl_id)s, I.etudid
@ -195,7 +202,7 @@ def do_moduleimpl_inscrit_tout_semestre(context, moduleimpl_id, formsemestre_id)
# --- Inscriptions aux modules # --- Inscriptions aux modules
_moduleimpl_inscriptionEditor = EditableTable( _moduleimpl_inscriptionEditor = ndb.EditableTable(
"notes_moduleimpl_inscription", "notes_moduleimpl_inscription",
"moduleimpl_inscription_id", "moduleimpl_inscription_id",
("moduleimpl_inscription_id", "etudid", "moduleimpl_id"), ("moduleimpl_inscription_id", "etudid", "moduleimpl_id"),
@ -237,6 +244,8 @@ def do_moduleimpl_inscrit_etuds(
"""Inscrit les etudiants (liste d'etudids) a ce module. """Inscrit les etudiants (liste d'etudids) a ce module.
Si reset, desinscrit tous les autres. Si reset, desinscrit tous les autres.
""" """
from app.scodoc import sco_formsemestre_inscriptions
# Verifie qu'ils sont tous bien inscrits au semestre # Verifie qu'ils sont tous bien inscrits au semestre
for etudid in etudids: for etudid in etudids:
insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
@ -248,7 +257,7 @@ def do_moduleimpl_inscrit_etuds(
# Desinscriptions # Desinscriptions
if reset: if reset:
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s", "delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s",
{"moduleimpl_id": moduleimpl_id}, {"moduleimpl_id": moduleimpl_id},

View File

@ -29,16 +29,22 @@
""" """
import notesdb as ndb import app.scodoc.notesdb as ndb
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
import sco_formsemestre from app.scodoc import html_sco_header
import sco_moduleimpl from app.scodoc import htmlutils
import sco_groups from app.scodoc import sco_core
import htmlutils from app.scodoc import sco_edit_module
from sco_permissions import ScoEtudInscrit from app.scodoc import sco_edit_ue
from sco_exceptions import ScoValueError from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_etud
from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission
def moduleimpl_inscriptions_edit( def moduleimpl_inscriptions_edit(
@ -87,7 +93,7 @@ def moduleimpl_inscriptions_edit(
# Liste des inscrits à ce semestre # Liste des inscrits à ce semestre
inscrits = context.Notes.do_formsemestre_inscription_listinscrits(formsemestre_id) inscrits = context.Notes.do_formsemestre_inscription_listinscrits(formsemestre_id)
for ins in inscrits: for ins in inscrits:
etuds_info = scolars.get_etud_info(etudid=ins["etudid"], filled=1) etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
if not etuds_info: if not etuds_info:
log( log(
"moduleimpl_inscriptions_edit: incoherency for etudid=%s !" "moduleimpl_inscriptions_edit: incoherency for etudid=%s !"
@ -238,8 +244,8 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
) )
set_all = set([x["etudid"] for x in inscrits]) set_all = set([x["etudid"] for x in inscrits])
partitions, partitions_etud_groups = sco_groups.get_formsemestre_groups( partitions, partitions_etud_groups = sco_groups.get_formsemestre_groups(
@ -334,7 +340,10 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
UECaps = get_etuds_with_capitalized_ue(context, formsemestre_id) UECaps = get_etuds_with_capitalized_ue(context, formsemestre_id)
if UECaps: if UECaps:
H.append('<h3>Etudiants avec UEs capitalisées:</h3><ul class="ue_inscr_list">') H.append('<h3>Etudiants avec UEs capitalisées:</h3><ul class="ue_inscr_list">')
ues = [sco_edit_ue.do_ue_list(context, {"ue_id": ue_id})[0] for ue_id in UECaps.keys()] ues = [
sco_edit_ue.do_ue_list(context, {"ue_id": ue_id})[0]
for ue_id in UECaps.keys()
]
ues.sort(key=lambda u: u["numero"]) ues.sort(key=lambda u: u["numero"])
for ue in ues: for ue in ues:
H.append( H.append(
@ -342,7 +351,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
) )
H.append("<ul>") H.append("<ul>")
for info in UECaps[ue["ue_id"]]: for info in UECaps[ue["ue_id"]]:
etud = scolars.get_etud_info(etudid=info["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(etudid=info["etudid"], filled=True)[0]
H.append( H.append(
'<li class="etud"><a class="discretelink" href="ficheEtud?etudid=%(etudid)s">%(nomprenom)s</a>' '<li class="etud"><a class="discretelink" href="ficheEtud?etudid=%(etudid)s">%(nomprenom)s</a>'
% etud % etud
@ -446,7 +455,7 @@ def _fmt_etud_set(context, ins, max_list_size=7):
return "%d étudiants" % len(ins) return "%d étudiants" % len(ins)
etuds = [] etuds = []
for etudid in ins: for etudid in ins:
etuds.append(scolars.get_etud_info(etudid=etudid, filled=True)[0]) etuds.append(sco_etud.get_etud_info(etudid=etudid, filled=True)[0])
etuds.sort(lambda x, y: cmp(x["nom"], y["nom"])) etuds.sort(lambda x, y: cmp(x["nom"], y["nom"]))
return ", ".join( return ", ".join(
[ [
@ -465,8 +474,8 @@ def get_etuds_with_capitalized_ue(context, formsemestre_id):
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(context).get_NotesTable(
context, formsemestre_id context, formsemestre_id
) # > get_ues, get_etud_ue_status ) # > get_ues, get_etud_ue_status
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
) )
ues = nt.get_ues() ues = nt.get_ues()
for ue in ues: for ue in ues:
@ -544,8 +553,8 @@ def do_etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None)
def do_etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None): def do_etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
"""Incrit l'etudiant de tous les modules de cette UE dans ce semestre.""" """Incrit l'etudiant de tous les modules de cette UE dans ce semestre."""
# Verifie qu'il est bien inscrit au semestre # Verifie qu'il est bien inscrit au semestre
insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, insem = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id, "etudid": etudid} context, args={"formsemestre_id": formsemestre_id, "etudid": etudid}
) )
if not insem: if not insem:
raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid)

View File

@ -28,31 +28,25 @@
"""Tableau de bord module """Tableau de bord module
""" """
import time import time
import urllib
import sco_utils as scu import app.scodoc.sco_utils as scu
from sco_utils import ( from app.scodoc.sco_permissions import Permission
EVALUATION_NORMALE,
EVALUATION_RATTRAPAGE,
EVALUATION_SESSION2,
)
from sco_permissions import ScoEtudInscrit, ScoAbsChange
from notes_log import log
from TrivialFormulator import TrivialFormulator, TF
# from notes_table import * from app.scodoc import html_sco_header
import sco_groups from app.scodoc import htmlutils
import sco_evaluations from app.scodoc import sco_abs
import htmlutils from app.scodoc import sco_compute_moy
import sco_excel from app.scodoc import sco_core
from gen_tables import GenTable from app.scodoc import sco_edit_module
from htmlutils import histogram_notes from app.scodoc import sco_evaluations
import sco_moduleimpl from app.scodoc import sco_formations
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_formsemestre_status from app.scodoc import sco_formsemestre_status
import htmlutils from app.scodoc import sco_groups
import sco_saisie_notes from app.scodoc import sco_moduleimpl
import sco_compute_moy from app.scodoc import sco_permissions_check
import sco_abs from app.scodoc import sco_saisie_notes
# ported from old DTML code in oct 2009 # ported from old DTML code in oct 2009
@ -67,7 +61,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
group_id = sco_groups.get_default_group(context, modimpl["formsemestre_id"]) group_id = sco_groups.get_default_group(context, modimpl["formsemestre_id"])
if ( if (
sco_saisie_notes.can_edit_notes( sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
) )
and nbnotes != 0 and nbnotes != 0
@ -83,7 +77,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"args": { "args": {
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
}, },
"enabled": sco_saisie_notes.can_edit_notes( "enabled": sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"] context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
), ),
}, },
@ -93,7 +87,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"args": { "args": {
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
}, },
"enabled": sco_saisie_notes.can_edit_notes( "enabled": sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
@ -104,7 +98,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
}, },
"enabled": nbnotes == 0 "enabled": nbnotes == 0
and sco_saisie_notes.can_edit_notes( and sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
@ -114,7 +108,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"args": { "args": {
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
}, },
"enabled": sco_saisie_notes.can_edit_notes( "enabled": sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
@ -133,14 +127,17 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
}, },
"enabled": nbnotes == 0 "enabled": nbnotes == 0
and sco_saisie_notes.can_edit_notes( and sco_permissions_check.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"] context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
), ),
}, },
{ {
"title": "Absences ce jour", "title": "Absences ce jour",
"endpoint": "absences.EtatAbsencesDate?date=%s&group_ids=%s" "endpoint": "absences.EtatAbsencesDate",
% (endpointlib.quote(E["jour"], safe=""), group_id), "args": {
"date": urllib.quote(E["jour"], safe=""),
"group_ids": group_id,
},
"enabled": E["jour"], "enabled": E["jour"],
}, },
{ {
@ -163,7 +160,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
Mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0] Mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
F = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] F = sco_formations.formation_list(
context, args={"formation_id": sem["formation_id"]}
)[0]
ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list( ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_id"] context, moduleimpl_id=M["moduleimpl_id"]
) )
@ -171,16 +170,20 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
nt = sco_core.get_notes_cache( nt = sco_core.get_notes_cache(
context, context,
).get_NotesTable(context, formsemestre_id) ).get_NotesTable(context, formsemestre_id)
ModEvals = sco_evaluations.do_evaluation_list(context, {"moduleimpl_id": moduleimpl_id}) ModEvals = sco_evaluations.do_evaluation_list(
context, {"moduleimpl_id": moduleimpl_id}
)
ModEvals.sort( ModEvals.sort(
key=lambda x: (x["numero"], x["jour"], x["heure_debut"]), reverse=True key=lambda x: (x["numero"], x["jour"], x["heure_debut"]), reverse=True
) # la plus RECENTE en tête ) # la plus RECENTE en tête
# #
caneditevals = sco_saisie_notes.can_edit_notes( caneditevals = sco_permissions_check.can_edit_notes(
context, authuser, moduleimpl_id, allow_ens=sem["ens_can_edit_eval"] context, authuser, moduleimpl_id, allow_ens=sem["ens_can_edit_eval"]
) )
caneditnotes = sco_saisie_notes.can_edit_notes(context, authuser, moduleimpl_id) caneditnotes = sco_permissions_check.can_edit_notes(
context, authuser, moduleimpl_id
)
arrow_up, arrow_down, arrow_none = sco_groups.getArrowIconsTags(context, REQUEST) arrow_up, arrow_down, arrow_none = sco_groups.getArrowIconsTags(context, REQUEST)
# #
H = [ H = [
@ -281,7 +284,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
# Adapté à partir d'une suggestion de DS (Le Havre) # Adapté à partir d'une suggestion de DS (Le Havre)
# Liens saisies absences seulement si permission et date courante dans le semestre # Liens saisies absences seulement si permission et date courante dans le semestre
if authuser.has_permission( if authuser.has_permission(
ScoAbsChange, context Permission.ScoAbsChange
) and sco_formsemestre.sem_est_courant(context, sem): ) and sco_formsemestre.sem_est_courant(context, sem):
datelundi = sco_abs.ddmmyyyy(time.strftime("%d/%m/%Y")).prev_monday() datelundi = sco_abs.ddmmyyyy(time.strftime("%d/%m/%Y")).prev_monday()
group_id = sco_groups.get_default_group(context, formsemestre_id) group_id = sco_groups.get_default_group(context, formsemestre_id)
@ -366,7 +369,10 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
partition_id=partition_id, partition_id=partition_id,
select_first_partition=True, select_first_partition=True,
) )
if eval["evaluation_type"] in (EVALUATION_RATTRAPAGE, EVALUATION_SESSION2): if eval["evaluation_type"] in (
scu.EVALUATION_RATTRAPAGE,
scu.EVALUATION_SESSION2,
):
tr_class = "mievr mievr_rattr" tr_class = "mievr mievr_rattr"
else: else:
tr_class = "mievr" tr_class = "mievr"
@ -385,11 +391,11 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
% eval % eval
) )
H.append("&nbsp;&nbsp;&nbsp; <em>%(description)s</em>" % eval) H.append("&nbsp;&nbsp;&nbsp; <em>%(description)s</em>" % eval)
if eval["evaluation_type"] == EVALUATION_RATTRAPAGE: if eval["evaluation_type"] == scu.EVALUATION_RATTRAPAGE:
H.append( H.append(
"""<span class="mievr_rattr" title="remplace si meilleure note">rattrapage</span>""" """<span class="mievr_rattr" title="remplace si meilleure note">rattrapage</span>"""
) )
elif eval["evaluation_type"] == EVALUATION_SESSION2: elif eval["evaluation_type"] == scu.EVALUATION_SESSION2:
H.append( H.append(
"""<span class="mievr_rattr" title="remplace autres notes">session 2</span>""" """<span class="mievr_rattr" title="remplace autres notes">session 2</span>"""
) )

View File

@ -27,23 +27,24 @@
"""Gestions des "nouvelles" """Gestions des "nouvelles"
""" """
import datetime
import PyRSS2Gen # pylint: disable=import-error import re
from cStringIO import StringIO
import datetime, re
import time import time
from stripogram import html2text, html2safehtml from cStringIO import StringIO
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
from stripogram import html2text
import PyRSS2Gen # pylint: disable=import-error
import notesdb as ndb import app.scodoc.sco_utils as scu
from notes_log import log import app.scodoc.notesdb as ndb
import mails from app.scodoc.notes_log import log
import scolars from app.scodoc import mails
from sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE from app.scodoc.sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_preferences
_scolar_news_editor = ndb.EditableTable( _scolar_news_editor = ndb.EditableTable(
"scolar_news", "scolar_news",
@ -109,6 +110,7 @@ def scolar_news_summary(context, n=5):
"""Return last n news. """Return last n news.
News are "compressed", ie redondant events are joined. News are "compressed", ie redondant events are joined.
""" """
from app.scodoc import sco_etud
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -140,7 +142,7 @@ def scolar_news_summary(context, n=5):
n[k] = _scolar_news_editor.output_formators[k](n[k]) n[k] = _scolar_news_editor.output_formators[k](n[k])
# date resumee # date resumee
j, m = n["date"].split("/")[:2] j, m = n["date"].split("/")[:2]
mois = scolars.abbrvmonthsnames[int(m) - 1] mois = sco_etud.MONTH_NAMES_ABBREV[int(m) - 1]
n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"]) n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"])
# indication semestre si ajout notes: # indication semestre si ajout notes:
infos = _get_formsemestre_infos_from_news(context, n) infos = _get_formsemestre_infos_from_news(context, n)

View File

@ -31,31 +31,26 @@
""" """
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import scolars from app.scodoc import html_sco_header
import sco_bac from app.scodoc import htmlutils
import sco_photos from app.scodoc import sco_archives_etud
import sco_groups from app.scodoc import sco_bac
import sco_formsemestre from app.scodoc import sco_codes_parcours
from scolars import format_telephone, format_pays, make_etud_args from app.scodoc import sco_formsemestre
import sco_formsemestre_status from app.scodoc import sco_formsemestre_status
import htmlutils from app.scodoc import sco_groups
import html_sco_header from app.scodoc import sco_parcours_dut
from sco_bulletins import etud_descr_situation_semestre from app.scodoc import sco_permissions_check
import sco_parcours_dut from app.scodoc import sco_photos
import sco_codes_parcours from app.scodoc import sco_report
from sco_formsemestre_validation import formsemestre_recap_parcours_table from app.scodoc import sco_etud
import sco_archives_etud from app.scodoc.sco_bulletins import etud_descr_situation_semestre
import sco_report from app.scodoc.sco_exceptions import ScoValueError
from sco_permissions import ( from app.scodoc.sco_formsemestre_validation import formsemestre_recap_parcours_table
ScoEtudChangeGroups, from app.scodoc.sco_permissions import Permission
ScoEtudInscrit,
ScoImplement,
ScoEtudChangeAdr,
)
from sco_exceptions import ScoValueError
def _menuScolarite(context, authuser, sem, etudid): def _menuScolarite(context, authuser, sem, etudid):
@ -67,7 +62,7 @@ def _menuScolarite(context, authuser, sem, etudid):
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
return lockicon # no menu return lockicon # no menu
if not authuser.has_permission( if not authuser.has_permission(
ScoEtudInscrit, context Permission.ScoEtudInscrit
) and not authuser.has_permission(Permission.ScoEtudChangeGroups): ) and not authuser.has_permission(Permission.ScoEtudChangeGroups):
return "" # no menu return "" # no menu
ins = sem["ins"] ins = sem["ins"]
@ -147,14 +142,14 @@ def ficheEtud(context, etudid=None, REQUEST=None):
# la sidebar est differente s'il y a ou pas un etudid # la sidebar est differente s'il y a ou pas un etudid
# voir html_sidebar.sidebar() # voir html_sidebar.sidebar()
REQUEST.form["etudid"] = etudid REQUEST.form["etudid"] = etudid
args = make_etud_args(etudid=etudid, REQUEST=REQUEST) args = sco_etud.make_etud_args(etudid=etudid, REQUEST=REQUEST)
etuds = scolars.etudident_list(cnx, args) etuds = sco_etud.etudident_list(cnx, args)
if not etuds: if not etuds:
log("ficheEtud: etudid=%s REQUEST.form=%s" % (etudid, REQUEST.form)) log("ficheEtud: etudid=%s REQUEST.form=%s" % (etudid, REQUEST.form))
raise ScoValueError("Etudiant inexistant !") raise ScoValueError("Etudiant inexistant !")
etud = etuds[0] etud = etuds[0]
etudid = etud["etudid"] etudid = etud["etudid"]
scolars.fillEtudsInfo(context, [etud]) sco_etud.fill_etuds_info([etud])
# #
info = etud info = etud
info["ScoURL"] = scu.ScoURL() info["ScoURL"] = scu.ScoURL()
@ -172,7 +167,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
): ):
info["domicile"] = "<em>inconnue</em>" info["domicile"] = "<em>inconnue</em>"
if info["paysdomicile"]: if info["paysdomicile"]:
pays = format_pays(info["paysdomicile"]) pays = sco_etud.format_pays(info["paysdomicile"])
if pays: if pays:
info["paysdomicile"] = "(%s)" % pays info["paysdomicile"] = "(%s)" % pays
else: else:
@ -273,9 +268,9 @@ def ficheEtud(context, etudid=None, REQUEST=None):
# Liste des annotations # Liste des annotations
alist = [] alist = []
annos = scolars.etud_annotations_list(cnx, args={"etudid": etudid}) annos = sco_etud.etud_annotations_list(cnx, args={"etudid": etudid})
for a in annos: for a in annos:
if not sco_permissions.can_suppress_annotation(context, a["id"], REQUEST): if not sco_permissions_check.can_suppress_annotation(context, a["id"], REQUEST):
a["dellink"] = "" a["dellink"] = ""
else: else:
a[ a[
@ -351,7 +346,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
# Devenir de l'étudiant: # Devenir de l'étudiant:
has_debouche = True # info['debouche'] has_debouche = True # info['debouche']
if sco_permissions.can_edit_suivi(context, REQUEST): if sco_permissions_check.can_edit_suivi(context, REQUEST):
suivi_readonly = "0" suivi_readonly = "0"
link_add_suivi = """<li class="adddebouche"> link_add_suivi = """<li class="adddebouche">
<a id="adddebouchelink" class="stdlink" href="#">ajouter une ligne</a> <a id="adddebouchelink" class="stdlink" href="#">ajouter une ligne</a>
@ -496,7 +491,7 @@ def menus_etud(context, REQUEST=None):
return "" return ""
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
menuEtud = [ menuEtud = [
{ {
@ -550,7 +545,7 @@ def etud_info_html(context, etudid, with_photo="1", REQUEST=None, debug=False):
# log('etud_info_html: formsemestre_id=%s' % formsemestre_id) # log('etud_info_html: formsemestre_id=%s' % formsemestre_id)
with_photo = int(with_photo) with_photo = int(with_photo)
etud = scolars.get_etud_info(filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(filled=1, REQUEST=REQUEST)[0]
photo_html = sco_photos.etud_photo_html( photo_html = sco_photos.etud_photo_html(
context, etud, title="fiche de " + etud["nom"], REQUEST=REQUEST context, etud, title="fiche de " + etud["nom"], REQUEST=REQUEST
) )

View File

@ -29,13 +29,14 @@
""" """
from types import FloatType from types import FloatType
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
from scolog import logdb from app.scodoc.scolog import logdb
import sco_formsemestre from app.scodoc import sco_core
from app.scodoc import sco_formsemestre
from sco_codes_parcours import ( from app.scodoc import sco_formations
from app.scodoc.sco_codes_parcours import (
CMP, CMP,
ADC, ADC,
ADJ, ADJ,
@ -58,8 +59,8 @@ from sco_codes_parcours import (
code_semestre_attente, code_semestre_attente,
code_semestre_validant, code_semestre_validant,
) )
from dutrules import DUTRules # regles generees a partir du CSV from app.scodoc.dutrules import DUTRules # regles generees a partir du CSV
from sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
class DecisionSem: class DecisionSem:
@ -120,7 +121,7 @@ class SituationEtudParcoursGeneric:
def __init__(self, context, etud, formsemestre_id, nt): def __init__(self, context, etud, formsemestre_id, nt):
""" """
etud: dict filled by fillEtudsInfo() etud: dict filled by fill_etuds_info()
""" """
self.context = context self.context = context
self.etud = etud self.etud = etud
@ -295,7 +296,7 @@ class SituationEtudParcoursGeneric:
sem["semestre_id"] == n1 sem["semestre_id"] == n1
and sem["formation_code"] == self.formation["formation_code"] and sem["formation_code"] == self.formation["formation_code"]
): ):
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
@ -311,7 +312,7 @@ class SituationEtudParcoursGeneric:
sont validés. En sortie, sem_idx_set contient ceux qui n'ont pas été validés.""" sont validés. En sortie, sem_idx_set contient ceux qui n'ont pas été validés."""
for sem in self.get_semestres(): for sem in self.get_semestres():
if sem["formation_code"] == self.formation["formation_code"]: if sem["formation_code"] == self.formation["formation_code"]:
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
@ -322,14 +323,14 @@ class SituationEtudParcoursGeneric:
return not sem_idx_set return not sem_idx_set
def _comp_semestres(self): def _comp_semestres(self):
# etud['sems'] est trie par date decroissante (voir fillEtudsInfo) # etud['sems'] est trie par date decroissante (voir fill_etuds_info)
sems = self.etud["sems"][:] # copy sems = self.etud["sems"][:] # copy
sems.reverse() sems.reverse()
# Nb max d'UE et acronymes # Nb max d'UE et acronymes
ue_acros = {} # acronyme ue : 1 ue_acros = {} # acronyme ue : 1
nb_max_ue = 0 nb_max_ue = 0
for sem in sems: for sem in sems:
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) # > get_ues ) # > get_ues
ues = nt.get_ues(filter_sport=True) ues = nt.get_ues(filter_sport=True)
@ -339,8 +340,8 @@ class SituationEtudParcoursGeneric:
if nb_ue > nb_max_ue: if nb_ue > nb_max_ue:
nb_max_ue = nb_ue nb_max_ue = nb_ue
# add formation_code to each sem: # add formation_code to each sem:
sem["formation_code"] = self.sco_formations.formation_list(context, sem["formation_code"] = sco_formations.formation_list(
args={"formation_id": sem["formation_id"]} self.context, args={"formation_id": sem["formation_id"]}
)[0]["formation_code"] )[0]["formation_code"]
# si sem peut servir à compenser le semestre courant, positionne # si sem peut servir à compenser le semestre courant, positionne
# can_compensate # can_compensate
@ -399,7 +400,7 @@ class SituationEtudParcoursGeneric:
if not sem: if not sem:
code = "" # non inscrit à ce semestre code = "" # non inscrit à ce semestre
else: else:
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
@ -471,7 +472,7 @@ class SituationEtudParcoursGeneric:
# Verifications basiques: # Verifications basiques:
# ? # ?
# Code etat du semestre precedent: # Code etat du semestre precedent:
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, prev["formsemestre_id"] self.context, prev["formsemestre_id"]
) # > get_etud_decision_sem, get_etud_moy_gen, etud_check_conditions_ues ) # > get_etud_decision_sem, get_etud_moy_gen, etud_check_conditions_ues
self.prev_decision = nt.get_etud_decision_sem(self.etudid) self.prev_decision = nt.get_etud_decision_sem(self.etudid)
@ -530,7 +531,7 @@ class SituationEtudParcoursGeneric:
sem["formation_code"] == self.formation["formation_code"] sem["formation_code"] == self.formation["formation_code"]
and sem["semestre_id"] == s and sem["semestre_id"] == s
): ):
nt = self.sco_core.get_notes_cache(context).get_NotesTable( nt = sco_core.get_notes_cache(self.context).get_NotesTable(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
@ -629,8 +630,8 @@ class SituationEtudParcoursGeneric:
REQUEST=REQUEST, REQUEST=REQUEST,
) )
self.sco_core.inval_cache( sco_core.inval_cache(
context, formsemestre_id=self.prev["formsemestre_id"] self.context, formsemestre_id=self.prev["formsemestre_id"]
) # > modif decisions jury (sem, UE) ) # > modif decisions jury (sem, UE)
# -- supprime autorisations venant de ce formsemestre # -- supprime autorisations venant de ce formsemestre
@ -659,17 +660,18 @@ class SituationEtudParcoursGeneric:
except: except:
cnx.rollback() cnx.rollback()
raise raise
self.sco_core.inval_cache( sco_core.inval_cache(
context, formsemestre_id=self.formsemestre_id self.context, formsemestre_id=self.formsemestre_id
) # > modif decisions jury et autorisations inscription ) # > modif decisions jury et autorisations inscription
if decision.formsemestre_id_utilise_pour_compenser: if decision.formsemestre_id_utilise_pour_compenser:
# inval aussi le semestre utilisé pour compenser: # inval aussi le semestre utilisé pour compenser:
self.sco_core.inval_cache( sco_core.inval_cache(
context, formsemestre_id=decision.formsemestre_id_utilise_pour_compenser self.context,
formsemestre_id=decision.formsemestre_id_utilise_pour_compenser,
) # > modif decision jury ) # > modif decision jury
for formsemestre_id in to_invalidate: for formsemestre_id in to_invalidate:
self.sco_core.inval_cache( sco_core.inval_cache(
context, formsemestre_id=formsemestre_id self.context, formsemestre_id=formsemestre_id
) # > modif decision jury ) # > modif decision jury
@ -1098,7 +1100,9 @@ def list_formsemestre_utilisateurs_uecap(context, formsemestre_id):
semestre): meme code formation, meme semestre_id, date posterieure""" semestre): meme code formation, meme semestre_id, date posterieure"""
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
F = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] F = sco_formations.formation_list(
context, args={"formation_id": sem["formation_id"]}
)[0]
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"""select sem.formsemestre_id """select sem.formsemestre_id

View File

@ -52,12 +52,17 @@ from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import styles from reportlab.lib import styles
from reportlab.lib.pagesizes import letter, A4, landscape from reportlab.lib.pagesizes import letter, A4, landscape
import sco_utils as scu import app.scodoc.sco_utils as scu
from sco_utils import CONFIG, SCO_ENCODING, SCODOC_LOGOS_DIR, LOGOS_IMAGES_ALLOWED_TYPES from app.scodoc.sco_utils import (
from notes_log import log CONFIG,
from sco_exceptions import ScoGenError SCO_ENCODING,
SCODOC_LOGOS_DIR,
LOGOS_IMAGES_ALLOWED_TYPES,
)
from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoGenError
from SuppressAccents import suppression_diacritics from SuppressAccents import suppression_diacritics
import VERSION from app.scodoc import VERSION
from VERSION import SCOVERSION, SCONAME from VERSION import SCOVERSION, SCONAME
PAGE_HEIGHT = defaultPageSize[1] PAGE_HEIGHT = defaultPageSize[1]

View File

@ -57,67 +57,3 @@ class Permission:
Permission.init_permissions() Permission.init_permissions()
import notesdb as ndb
import scolars
import sco_formsemestre
def can_suppress_annotation(context, annotation_id, REQUEST):
"""True if current user can suppress this annotation
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
une annotation.
"""
cnx = ndb.GetDBConnexion()
annos = scolars.etud_annotations_list(cnx, args={"id": annotation_id})
if len(annos) != 1:
raise ScoValueError("annotation inexistante !")
anno = annos[0]
authuser = REQUEST.AUTHENTICATED_USER
# note: les anciennes installations n'ont pas le role ScoEtudSupprAnnotations
# c'est pourquoi on teste aussi ScoEtudInscrit (normalement détenue par le chef)
return (
(str(authuser) == anno["zope_authenticated_user"])
or authuser.has_permission(Permission.ScoEtudSupprAnnotations)
or authuser.has_permission(Permission.ScoEtudInscrit)
)
def can_edit_suivi(context, REQUEST=None):
"""Vrai si l'utilisateur peut modifier les informations de suivi sur la page etud" """
authuser = REQUEST.AUTHENTICATED_USER
return authuser.has_permission(Permission.ScoEtudChangeAdr)
def can_validate_sem(context, REQUEST, formsemestre_id):
"Vrai si utilisateur peut saisir decision de jury dans ce semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1":
return False # semestre verrouillé
return is_chef_or_diretud(context, REQUEST, sem)
def can_edit_pv(context, REQUEST, formsemestre_id):
"Vrai si utilisateur peut editer un PV de jury de ce semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if is_chef_or_diretud(context, REQUEST, sem):
return True
# Autorise les secrétariats, repérés via la permission ScoEtudChangeAdr
# (ceci nous évite d'ajouter une permission Zope aux installations existantes)
authuser = REQUEST.AUTHENTICATED_USER
return authuser.has_permission(Permission.ScoEtudChangeAdr)
def is_chef_or_diretud(context, REQUEST, sem):
"Vrai si utilisateur est admin, chef dept ou responsable du semestre"
authuser = REQUEST.AUTHENTICATED_USER
if authuser.has_permission(Permission.ScoImplement):
return True # admin, chef dept
uid = str(authuser)
if uid in sem["responsables"]:
return True
return False

View File

@ -0,0 +1,139 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Functions checking permissions for some common operations
"""
import app.scodoc.notesdb as ndb
from app.scodoc.sco_permissions import Permission
from app.scodoc import html_sco_header
from app.scodoc import sco_etud
from app.scodoc import sco_exceptions
from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_parcours_dut
def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
"""True if authuser can enter or edit notes in this module.
If allow_ens, grant access to all ens in this module
Si des décisions de jury ont déjà été saisies dans ce semestre,
seul le directeur des études peut saisir des notes (et il ne devrait pas).
"""
uid = str(authuser)
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1":
return False # semestre verrouillé
if sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"]):
# il y a des décisions de jury dans ce semestre !
return (
authuser.has_permission(Permission.ScoEditAllNotes)
or uid in sem["responsables"]
)
else:
if (
(not authuser.has_permission(Permission.ScoEditAllNotes))
and uid != M["responsable_id"]
and uid not in sem["responsables"]
):
# enseignant (chargé de TD) ?
if allow_ens:
for ens in M["ens"]:
if ens["ens_id"] == uid:
return True
return False
else:
return True
def can_suppress_annotation(context, annotation_id, REQUEST):
"""True if current user can suppress this annotation
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
une annotation.
"""
cnx = ndb.GetDBConnexion()
annos = sco_etud.etud_annotations_list(cnx, args={"id": annotation_id})
if len(annos) != 1:
raise sco_exceptions.ScoValueError("annotation inexistante !")
anno = annos[0]
authuser = REQUEST.AUTHENTICATED_USER
# note: les anciennes installations n'ont pas le role ScoEtudSupprAnnotations
# c'est pourquoi on teste aussi ScoEtudInscrit (normalement détenue par le chef)
return (
(str(authuser) == anno["zope_authenticated_user"])
or authuser.has_permission(Permission.ScoEtudSupprAnnotations)
or authuser.has_permission(Permission.ScoEtudInscrit)
)
def can_edit_suivi(context, REQUEST=None):
"""Vrai si l'utilisateur peut modifier les informations de suivi sur la page etud" """
authuser = REQUEST.AUTHENTICATED_USER
return authuser.has_permission(Permission.ScoEtudChangeAdr)
def can_validate_sem(context, REQUEST, formsemestre_id):
"Vrai si utilisateur peut saisir decision de jury dans ce semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1":
return False # semestre verrouillé
return is_chef_or_diretud(context, REQUEST, sem)
def can_edit_pv(context, REQUEST, formsemestre_id):
"Vrai si utilisateur peut editer un PV de jury de ce semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if is_chef_or_diretud(context, REQUEST, sem):
return True
# Autorise les secrétariats, repérés via la permission ScoEtudChangeAdr
# (ceci nous évite d'ajouter une permission Zope aux installations existantes)
authuser = REQUEST.AUTHENTICATED_USER
return authuser.has_permission(Permission.ScoEtudChangeAdr)
def is_chef_or_diretud(context, REQUEST, sem):
"Vrai si utilisateur est admin, chef dept ou responsable du semestre"
authuser = REQUEST.AUTHENTICATED_USER
if authuser.has_permission(Permission.ScoImplement):
return True # admin, chef dept
uid = str(authuser)
if uid in sem["responsables"]:
return True
return False
def check_access_diretud(
context, formsemestre_id, REQUEST, required_permission=Permission.ScoImplement
):
"""Check if access granted: responsable or ScoImplement
Return True|False, HTML_error_page
"""
authuser = REQUEST.AUTHENTICATED_USER
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
header = html_sco_header.sco_header(
context, page_title="Accès interdit", REQUEST=REQUEST
)
footer = html_sco_header.sco_footer(context, REQUEST)
if (str(authuser) not in sem["responsables"]) and not authuser.has_permission(
required_permission
):
return (
False,
"\n".join(
[
header,
"<h2>Opération non autorisée pour %s</h2>" % authuser,
"<p>Responsable de ce semestre : <b>%s</b></p>"
% ", ".join(sem["responsables"]),
footer,
]
),
)
else:
return True, ""

View File

@ -54,17 +54,18 @@ from cStringIO import StringIO
import glob import glob
from config import Config from config import Config
from sco_utils import CONFIG, SCO_SRC_DIR
import notesdb as ndb
from notes_log import log
import scolars import app.scodoc.sco_utils as scu
import sco_portal_apogee import app.scodoc.notesdb as ndb
from scolog import logdb from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb
from app.scodoc import sco_portal_apogee
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
# Full paths on server's filesystem. Something like "/opt/scodoc/var/scodoc/photos" # Full paths on server's filesystem. Something like "/opt/scodoc/var/scodoc/photos"
PHOTO_DIR = os.path.join(Config.INSTANCE_HOME, "var", "scodoc", "photos") PHOTO_DIR = os.path.join(Config.INSTANCE_HOME, "var", "scodoc", "photos")
ICONS_DIR = os.path.join(SCO_SRC_DIR, "app", "static", "icons") ICONS_DIR = os.path.join(scu.SCO_SRC_DIR, "app", "static", "icons")
UNKNOWN_IMAGE_PATH = os.path.join(ICONS_DIR, "unknown.jpg") UNKNOWN_IMAGE_PATH = os.path.join(ICONS_DIR, "unknown.jpg")
UNKNOWN_IMAGE_URL = "get_photo_image?etudid=" # with empty etudid => unknown face image UNKNOWN_IMAGE_URL = "get_photo_image?etudid=" # with empty etudid => unknown face image
IMAGE_EXT = ".jpg" IMAGE_EXT = ".jpg"
@ -104,7 +105,7 @@ def etud_photo_url(context, etud, size="small", fast=False, REQUEST=None):
if not new_path: if not new_path:
# copy failed, can we use external url ? # copy failed, can we use external url ?
# nb: rarement utile, car le portail est rarement accessible sans authentification # nb: rarement utile, car le portail est rarement accessible sans authentification
if CONFIG.PUBLISH_PORTAL_PHOTO_URL: if scu.CONFIG.PUBLISH_PORTAL_PHOTO_URL:
photo_url = ext_url photo_url = ext_url
else: else:
photo_url = UNKNOWN_IMAGE_URL photo_url = UNKNOWN_IMAGE_URL
@ -118,7 +119,7 @@ def get_photo_image(context, etudid=None, size="small", REQUEST=None):
if not etudid: if not etudid:
filename = UNKNOWN_IMAGE_PATH filename = UNKNOWN_IMAGE_PATH
else: else:
etud = scolars.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
filename = photo_pathname(context, etud, size=size) filename = photo_pathname(context, etud, size=size)
if not filename: if not filename:
filename = UNKNOWN_IMAGE_PATH filename = UNKNOWN_IMAGE_PATH
@ -173,7 +174,7 @@ def etud_photo_html(
""" """
if not etud: if not etud:
if etudid: if etudid:
etud = scolars.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
else: else:
raise ValueError("etud_photo_html: either etud or etudid must be specified") 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(context, etud, size=size, REQUEST=REQUEST)
@ -247,7 +248,7 @@ def store_photo(context, etud, data, REQUEST=None):
etud["foto"] = None etud["foto"] = None
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
scolars.identite_edit_nocheck(cnx, etud) sco_etud.identite_edit_nocheck(cnx, etud)
cnx.commit() cnx.commit()
# #
if REQUEST: if REQUEST:
@ -263,7 +264,7 @@ def suppress_photo(context, etud, REQUEST=None):
# 1- remove ref. from database # 1- remove ref. from database
etud["photo_filename"] = None etud["photo_filename"] = None
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
scolars.identite_edit_nocheck(cnx, etud) sco_etud.identite_edit_nocheck(cnx, etud)
cnx.commit() cnx.commit()
# 2- erase images files # 2- erase images files
if rel_path: if rel_path:
@ -341,7 +342,7 @@ def copy_portal_photo_to_fs(context, etud, REQUEST=None):
"""Copy the photo from portal (distant website) to local fs. """Copy the photo from portal (distant website) to local fs.
Returns rel. path or None if copy failed, with a diagnotic message Returns rel. path or None if copy failed, with a diagnotic message
""" """
scolars.format_etud_ident(etud) sco_etud.format_etud_ident(etud)
url = photo_portal_url(context, etud) url = photo_portal_url(context, etud)
if not url: if not url:
return None, "%(nomprenom)s: pas de code NIP" % etud return None, "%(nomprenom)s: pas de code NIP" % etud

View File

@ -33,20 +33,25 @@ Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016
import urllib import urllib
import random import random
import sco_utils as scu import app.scodoc.sco_utils as scu
import notesdb as ndb import app.scodoc.notesdb as ndb
from notes_log import log from app.scodoc.notes_log import log
import scolars from app.scodoc import html_sco_header
import sco_formsemestre from app.scodoc import sco_edit_module
import sco_moduleimpl from app.scodoc import sco_evaluations
import sco_groups from app.scodoc import sco_excel
import sco_evaluations from app.scodoc import sco_formsemestre
import sco_saisie_notes from app.scodoc import sco_formsemestre_inscriptions
import sco_excel from app.scodoc import sco_groups
from sco_excel import * from app.scodoc import sco_moduleimpl
from TrivialFormulator import TrivialFormulator from app.scodoc import sco_permissions_check
from gen_tables import GenTable from app.scodoc import sco_preferences
import VERSION 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.TrivialFormulator import TrivialFormulator
def do_placement_selectetuds(context, REQUEST): def do_placement_selectetuds(context, REQUEST):
@ -240,7 +245,7 @@ def do_placement(context, REQUEST):
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not sco_saisie_notes.can_edit_notes(context, authuser, E["moduleimpl_id"]): if not sco_permissions_check.can_edit_notes(context, authuser, E["moduleimpl_id"]):
return ( return (
"<h2>Génération du placement impossible pour %s</h2>" % authusername "<h2>Génération du placement impossible pour %s</h2>" % authusername
+ """<p>(vérifiez que le semestre n'est pas verrouillé et que vous + """<p>(vérifiez que le semestre n'est pas verrouillé et que vous
@ -294,12 +299,12 @@ def do_placement(context, REQUEST):
listetud = [] # liste de couples (nom,prenom) listetud = [] # liste de couples (nom,prenom)
for etudid in etudids: for etudid in etudids:
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant) # infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
ident = scolars.etudident_list(cnx, {"etudid": etudid})[ ident = sco_etud.etudident_list(cnx, {"etudid": etudid})[
0 0
] # XXX utiliser ZScolar (parent) ] # XXX utiliser ZScolar (parent)
# infos inscription # infos inscription
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": M["formsemestre_id"]} context, {"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
)[0] )[0]
if inscr["etat"] != "D": if inscr["etat"] != "D":
nom = scu.strupper(ident["nom"]) nom = scu.strupper(ident["nom"])
@ -395,7 +400,9 @@ def do_placement(context, REQUEST):
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None): def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
"""Dialogue placement etudiants: choix methode et localisation""" """Dialogue placement etudiants: choix methode et localisation"""
evals = sco_evaluations.do_evaluation_list(context, {"evaluation_id": evaluation_id}) evals = sco_evaluations.do_evaluation_list(
context, {"evaluation_id": evaluation_id}
)
if not evals: if not evals:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
theeval = evals[0] theeval = evals[0]

View File

@ -35,11 +35,10 @@ import xml.sax.saxutils
import xml.dom.minidom import xml.dom.minidom
import datetime import datetime
import sco_utils as scu import app.scodoc.sco_utils as scu
from sco_utils import SCO_ENCODING from app.scodoc.notes_log import log
from sco_permissions import ScoEtudInscrit from app.scodoc.sco_exceptions import ScoValueError
from sco_exceptions import ScoValueError from app.scodoc import sco_preferences
from notes_log import log
SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml") SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml")
@ -247,7 +246,9 @@ def xml_to_list_of_dicts(doc, req=None):
if e.nodeType == e.ELEMENT_NODE: if e.nodeType == e.ELEMENT_NODE:
childs = e.childNodes childs = e.childNodes
if len(childs): if len(childs):
d[str(e.nodeName)] = childs[0].nodeValue.encode(SCO_ENCODING) d[str(e.nodeName)] = childs[0].nodeValue.encode(
scu.SCO_ENCODING
)
infos.append(d) infos.append(d)
except: except:
log("*** invalid XML response from Etudiant Web Service") log("*** invalid XML response from Etudiant Web Service")
@ -260,7 +261,7 @@ def xml_to_list_of_dicts(doc, req=None):
def get_infos_apogee_allaccents(context, nom, prenom): def get_infos_apogee_allaccents(context, nom, prenom):
"essai recup infos avec differents codages des accents" "essai recup infos avec differents codages des accents"
if nom: if nom:
unom = unicode(nom, SCO_ENCODING) unom = unicode(nom, scu.SCO_ENCODING)
nom_noaccents = str(scu.suppression_diacritics(unom)) nom_noaccents = str(scu.suppression_diacritics(unom))
nom_utf8 = unom.encode("utf-8") nom_utf8 = unom.encode("utf-8")
else: else:
@ -268,7 +269,7 @@ def get_infos_apogee_allaccents(context, nom, prenom):
nom_utf8 = nom nom_utf8 = nom
if prenom: if prenom:
uprenom = unicode(prenom, SCO_ENCODING) uprenom = unicode(prenom, scu.SCO_ENCODING)
prenom_noaccents = str(scu.suppression_diacritics(uprenom)) prenom_noaccents = str(scu.suppression_diacritics(uprenom))
prenom_utf8 = uprenom.encode("utf-8") prenom_utf8 = uprenom.encode("utf-8")
else: else:
@ -336,7 +337,7 @@ def get_etud_apogee(context, code_nip):
def get_default_etapes(context): def get_default_etapes(context):
"""Liste par défaut, lue du fichier de config""" """Liste par défaut, lue du fichier de config"""
filename = SCO_TOOLS_DIR + "/default-etapes.txt" filename = scu.SCO_TOOLS_DIR + "/default-etapes.txt"
log("get_default_etapes: reading %s" % filename) log("get_default_etapes: reading %s" % filename)
f = open(filename) f = open(filename)
etapes = {} etapes = {}
@ -366,7 +367,7 @@ def _parse_etapes_from_xml(context, doc):
# Ancien format XML avec des sections par departement: # Ancien format XML avec des sections par departement:
for d in dom.childNodes[0].childNodes: for d in dom.childNodes[0].childNodes:
if d.nodeType == d.ELEMENT_NODE: if d.nodeType == d.ELEMENT_NODE:
dept = d.nodeName.encode(SCO_ENCODING) dept = d.nodeName.encode(scu.SCO_ENCODING)
_xml_list_codes(infos, dept, d.childNodes) _xml_list_codes(infos, dept, d.childNodes)
else: else:
# Toutes les étapes: # Toutes les étapes:
@ -415,8 +416,8 @@ def get_etapes_apogee(context):
def _xml_list_codes(target_dict, dept, nodes): def _xml_list_codes(target_dict, dept, nodes):
for e in nodes: for e in nodes:
if e.nodeType == e.ELEMENT_NODE: if e.nodeType == e.ELEMENT_NODE:
intitule = e.childNodes[0].nodeValue.encode(SCO_ENCODING) intitule = e.childNodes[0].nodeValue.encode(scu.SCO_ENCODING)
code = e.attributes["code"].value.encode(SCO_ENCODING) code = e.attributes["code"].value.encode(scu.SCO_ENCODING)
if target_dict.has_key(dept): if target_dict.has_key(dept):
target_dict[dept][code] = intitule target_dict[dept][code] = intitule
else: else:

View File

@ -31,14 +31,16 @@ Recapitule tous les semestres validés dans une feuille excel.
""" """
import collections import collections
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc import sco_abs
from gen_tables import GenTable from app.scodoc import sco_core
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_groups from app.scodoc import sco_groups
import sco_abs from app.scodoc import sco_preferences
from sco_codes_parcours import code_semestre_validant, code_semestre_attente from app.scodoc import sco_etud
import VERSION from app.scodoc import VERSION
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(context, sem, etud):
@ -158,7 +160,7 @@ def _getEtudInfoGroupes(context, group_ids, etat=None):
for group_id in group_ids: for group_id in group_ids:
members = sco_groups.get_group_members(context, group_id, etat=etat) members = sco_groups.get_group_members(context, group_id, etat=etat)
for m in members: for m in members:
etud = scolars.get_etud_info(etudid=m["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
etuds.append(etud) etuds.append(etud)
return etuds return etuds

View File

@ -25,17 +25,6 @@
# #
############################################################################## ##############################################################################
"""ScoDoc preferences (replaces old Zope properties)
"""
import sco_utils as scu
import notesdb as ndb
from notes_log import log
from TrivialFormulator import TrivialFormulator, TF
import sco_formsemestre
import sco_bulletins_generator
from sco_exceptions import ScoValueError, ScoException
"""Global/Semestre Preferences for ScoDoc (version dec 2008) """Global/Semestre Preferences for ScoDoc (version dec 2008)
Preferences (paramètres) communs à tous les utilisateurs. Preferences (paramètres) communs à tous les utilisateurs.
@ -96,10 +85,10 @@ sinon, elle ne concerne que le semestre indiqué.
PREF_CATEGORIES : définition des catégories de préférences (pour PREF_CATEGORIES : définition des catégories de préférences (pour
dialogues édition) dialogues édition)
PREFS : pour chaque pref, donne infos pour édition (titre, type...) et prefs_definition : pour chaque pref, donne infos pour édition (titre, type...) et
valeur par défaut. valeur par défaut.
class sco_base_preferences class BasePreferences
Une instance unique par site (département, repéré par URL). Une instance unique par site (département, repéré par URL).
- charge les preferences pour tous le semestres depuis la BD. - charge les preferences pour tous le semestres depuis la BD.
.get(formsemestre_id, name) .get(formsemestre_id, name)
@ -111,16 +100,42 @@ Une instance unique par site (département, repéré par URL).
class SemPreferences(context,formsemestre_id) class SemPreferences(context,formsemestre_id)
Une instance par semestre, et une instance pour prefs globales. Une instance par semestre, et une instance pour prefs globales.
L'attribut .base_prefs point sur sco_base_preferences. L'attribut .base_prefs point sur BasePreferences.
.__getitem__ [name] .__getitem__ [name]
.is_global(name) .is_global(name)
.edit(categories=[]) .edit(categories=[])
get_base_preferences(context, formsemestre_id) get_base_preferences(context, formsemestre_id)
Return base preferences for this context (instance sco_base_preferences) Return base preferences for this context (instance BasePreferences)
""" """
from flask import g
import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError, ScoException
from app.scodoc.TrivialFormulator import TrivialFormulator
_SCO_BASE_PREFERENCES = {} # { URL: BasePreferences instance }
def get_base_preferences(context):
"""Return global preferences for the current department"""
dept = g.scodoc_dept
if not dept in _SCO_BASE_PREFERENCES:
_SCO_BASE_PREFERENCES[dept] = BasePreferences(context)
return _SCO_BASE_PREFERENCES[dept]
def get_preference(context, name, formsemestre_id=None):
"""Returns value of named preference.
All preferences have a sensible default value, so this
function always returns a usable value for all defined preferences names.
"""
return get_base_preferences(context).get(formsemestre_id, name)
PREF_CATEGORIES = ( PREF_CATEGORIES = (
# sur page "Paramètres" # sur page "Paramètres"
@ -175,7 +190,29 @@ PREF_CATEGORIES = (
) )
PREFS = ( class BasePreferences(object):
"""Global preferences"""
_editor = ndb.EditableTable(
"sco_prefs",
"pref_id",
("pref_id", "name", "value", "formsemestre_id"),
sortkey="name",
convert_null_outputs_to_empty=False,
allow_set_id=True,
html_quote=False, # car markup pdf reportlab (<b> etc)
filter_nulls=False,
)
def __init__(self, context):
self.context = context
self.init()
self.load()
def init(self):
from app.scodoc import sco_bulletins_generator
self.prefs_definition = (
( (
"DeptName", "DeptName",
{ {
@ -1739,27 +1776,11 @@ Année scolaire: %(anneescolaire)s
), ),
) )
PREFS_NAMES = set([x[0] for x in PREFS]) self.prefs_name = set([x[0] for x in self.prefs_definition])
PREFS_ONLY_GLOBAL = set([x[0] for x in PREFS if x[1].get("only_global", False)]) self.prefs_only_global = set(
[x[0] for x in self.prefs_definition if x[1].get("only_global", False)]
PREFS_DICT = dict(PREFS)
class sco_base_preferences:
_editor = ndb.EditableTable(
"sco_prefs",
"pref_id",
("pref_id", "name", "value", "formsemestre_id"),
sortkey="name",
convert_null_outputs_to_empty=False,
allow_set_id=True,
html_quote=False, # car markup pdf reportlab (<b> etc)
filter_nulls=False,
) )
self.prefs_dict = dict(self.prefs_definition)
def __init__(self, context):
self.context = context
self.load()
def load(self): def load(self):
"""Load all preferences from db""" """Load all preferences from db"""
@ -1775,8 +1796,10 @@ class sco_base_preferences:
self.prefs[p["formsemestre_id"]] = {} self.prefs[p["formsemestre_id"]] = {}
# Convert types: # Convert types:
if p["name"] in PREFS_DICT and PREFS_DICT[p["name"]].has_key("type"): if p["name"] in self.prefs_dict and self.prefs_dict[p["name"]].has_key(
typ = PREFS_DICT[p["name"]]["type"] "type"
):
typ = self.prefs_dict[p["name"]]["type"]
if typ == "float": if typ == "float":
# special case for float values (where NULL means 0) # special case for float values (where NULL means 0)
if p["value"]: if p["value"]:
@ -1787,8 +1810,9 @@ class sco_base_preferences:
func = eval(typ) func = eval(typ)
p["value"] = func(p["value"]) p["value"] = func(p["value"])
if ( if (
p["name"] in PREFS_DICT p["name"] in self.prefs_dict
and PREFS_DICT[p["name"]].get("input_type", None) == "boolcheckbox" and self.prefs_dict[p["name"]].get("input_type", None)
== "boolcheckbox"
): ):
if p["value"]: if p["value"]:
p["value"] = int(p["value"]) # boolcheckboxes are always 0/1 p["value"] = int(p["value"]) # boolcheckboxes are always 0/1
@ -1796,22 +1820,11 @@ class sco_base_preferences:
p["value"] = 0 # NULL (backward compat) p["value"] = 0 # NULL (backward compat)
self.prefs[p["formsemestre_id"]][p["name"]] = p["value"] self.prefs[p["formsemestre_id"]][p["name"]] = p["value"]
# log('prefs=%s' % self.prefs)
# add defaults for missing prefs # add defaults for missing prefs
for pref in PREFS: for pref in self.prefs_definition:
name = pref[0] name = pref[0]
# search preferences in configuration file
# Migration from previous ScoDoc installations (before june 2008) if name and name[0] != "_" and name not in self.prefs[None]:
# search preferences in Zope properties and in configuration file
if name and name[0] != "_" and not name in self.prefs[None]:
try:
value = getattr(self.context, name)
log(
"sco_preferences: found default value in Zope for %s=%s"
% (name, value)
)
except:
# search in scu.CONFIG # search in scu.CONFIG
if hasattr(scu.CONFIG, name): if hasattr(scu.CONFIG, name):
value = getattr(scu.CONFIG, name) value = getattr(scu.CONFIG, name)
@ -1911,9 +1924,9 @@ class sco_base_preferences:
scu.GSL.release() scu.GSL.release()
def set(self, formsemestre_id, name, value): def set(self, formsemestre_id, name, value):
if not name or name[0] == "_" or name not in PREFS_NAMES: if not name or name[0] == "_" or name not in self.prefs_name:
raise ValueError("invalid preference name: %s" % name) raise ValueError("invalid preference name: %s" % name)
if formsemestre_id and name in PREFS_ONLY_GLOBAL: if formsemestre_id and name in self.prefs_only_global:
raise ValueError("pref %s is always defined globaly") raise ValueError("pref %s is always defined globaly")
if not formsemestre_id in self.prefs: if not formsemestre_id in self.prefs:
self.prefs[formsemestre_id] = {} self.prefs[formsemestre_id] = {}
@ -1940,14 +1953,16 @@ class sco_base_preferences:
def edit(self, REQUEST): def edit(self, REQUEST):
"""HTML dialog: edit global preferences""" """HTML dialog: edit global preferences"""
from app.scodoc import html_sco_header
H = [ H = [
self.html_sco_header.sco_header(context, REQUEST, page_title="Préférences"), html_sco_header.sco_header(self.context, REQUEST, page_title="Préférences"),
"<h2>Préférences globales pour %s</h2>" % self.scu.ScoURL(), "<h2>Préférences globales pour %s</h2>" % scu.ScoURL(),
"""<p class="help">Ces paramètres s'appliquent par défaut à tous les semestres, sauf si ceux-ci définissent des valeurs spécifiques.</p> """<p class="help">Ces paramètres s'appliquent par défaut à tous les semestres, sauf si ceux-ci définissent des valeurs spécifiques.</p>
<p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p> <p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p>
""", """,
] ]
form = _build_form(self, global_edit=True) form = self.build_tf_form()
tf = TrivialFormulator( tf = TrivialFormulator(
REQUEST.URL0, REQUEST.URL0,
REQUEST.form, REQUEST.form,
@ -1957,31 +1972,90 @@ class sco_base_preferences:
) )
if tf[0] == 0: if tf[0] == 0:
return ( return (
"\n".join(H) + tf[1] + self.html_sco_header.sco_footer(context, REQUEST) "\n".join(H) + tf[1] + html_sco_header.sco_footer(self.context, REQUEST)
) )
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(scu.ScoURL()) # cancel return REQUEST.RESPONSE.redirect(scu.ScoURL()) # cancel
else: else:
for pref in PREFS: for pref in self.prefs_definition:
self.prefs[None][pref[0]] = tf[2][pref[0]] self.prefs[None][pref[0]] = tf[2][pref[0]]
self.save() self.save()
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
scu.ScoURL() + "?head_message=Préférences modifiées" scu.ScoURL() + "?head_message=Préférences modifiées"
) )
def build_tf_form(self, categories=[], formsemestre_id=None):
"""Build list of elements for TrivialFormulator.
If formsemestre_id is not specified, edit global prefs.
"""
form = []
for cat, cat_descr in PREF_CATEGORIES:
if categories and cat not in categories:
continue # skip this category
#
cat_elems = []
for pref_name, pref in self.prefs_definition:
if pref["category"] == cat:
if pref.get("only_global", False) and formsemestre_id:
continue # saute les prefs seulement globales
descr = pref.copy()
descr["comment"] = descr.get("explanation", None)
if "explanation" in descr:
del descr["explanation"]
if formsemestre_id:
descr["explanation"] = (
"""ou <span class="spanlink" onclick="set_global_pref(this, '%s');">utiliser paramètre global</span>"""
% pref_name
)
# if descr.get('only_global',False):
# # pas modifiable, donne juste la valeur courante
# descr['readonly'] = True
# descr['explanation'] = '(valeur globale, non modifiable)'
# elif
if formsemestre_id and self.is_global(formsemestre_id, pref_name):
# valeur actuelle globale (ou vient d'etre supprimee localement):
# montre la valeur et menus pour la rendre locale
descr["readonly"] = True
menu_global = (
"""<select class="tf-selglobal" onchange="sel_global(this, '%s');">
<option value="">Valeur définie globalement</option>
<option value="create">Spécifier valeur pour ce semestre seulement</option>
</select>
"""
% pref_name
)
# <option value="changeglobal">Changer paramètres globaux</option>
descr["explanation"] = menu_global
_SCO_BASE_PREFERENCES = {} # { URL: sco_base_preferences instance } cat_elems.append((pref_name, descr))
if cat_elems:
# category titles:
title = cat_descr.get("title", None)
if title:
form.append(
(
"sep_%s" % cat,
{"input_type": "separator", "title": "<h3>%s</h3>" % title},
)
)
subtitle = cat_descr.get("subtitle", None)
if subtitle:
form.append(
(
"sepsub_%s" % cat,
{
"input_type": "separator",
"title": '<p class="help">%s</p>' % subtitle,
},
)
)
form.extend(cat_elems)
return form
def get_base_preferences(context): class SemPreferences(object):
"""Return global preferences for this context""" """Preferences for a formsemestre"""
u = scu.ScoURL()
if not u in _SCO_BASE_PREFERENCES:
_SCO_BASE_PREFERENCES[u] = sco_base_preferences(context)
return _SCO_BASE_PREFERENCES[u]
class SemPreferences:
def __init__(self, context, formsemestre_id=None): def __init__(self, context, formsemestre_id=None):
self.context = context self.context = context
self.formsemestre_id = formsemestre_id self.formsemestre_id = formsemestre_id
@ -2008,6 +2082,9 @@ class SemPreferences:
# The dialog # The dialog
def edit(self, categories=[], REQUEST=None): def edit(self, categories=[], REQUEST=None):
"""Dialog to edit semestre preferences in given categories""" """Dialog to edit semestre preferences in given categories"""
from app.scodoc import html_sco_header
from app.scodoc import sco_formsemestre
if not self.formsemestre_id: if not self.formsemestre_id:
raise ScoValueError( raise ScoValueError(
"sem_preferences.edit doit etre appele sur un semestre !" "sem_preferences.edit doit etre appele sur un semestre !"
@ -2049,7 +2126,9 @@ function set_global_pref(el, pref_name) {
""", """,
] ]
# build the form: # build the form:
form = _build_form(self, categories=categories) form = self.base_prefs.build_tf_form(
categories=categories, formsemestre_id=self.formsemestre_id
)
form.append(("suppress", {"input_type": "hidden"})) form.append(("suppress", {"input_type": "hidden"}))
form.append(("create_local", {"input_type": "hidden"})) form.append(("create_local", {"input_type": "hidden"}))
form.append(("destination", {"input_type": "hidden"})) form.append(("destination", {"input_type": "hidden"}))
@ -2063,12 +2142,12 @@ function set_global_pref(el, pref_name) {
submitlabel="Enregistrer les modifications", submitlabel="Enregistrer les modifications",
) )
dest_url = ( dest_url = (
self.scu.NotesURL() scu.NotesURL()
+ "/formsemestre_status?formsemestre_id=%s" % self.formsemestre_id + "/formsemestre_status?formsemestre_id=%s" % self.formsemestre_id
) )
if tf[0] == 0: if tf[0] == 0:
return ( return (
"\n".join(H) + tf[1] + self.html_sco_header.sco_footer(context, REQUEST) "\n".join(H) + tf[1] + html_sco_header.sco_footer(self.context, REQUEST)
) )
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
@ -2085,7 +2164,7 @@ function set_global_pref(el, pref_name) {
self.formsemestre_id, tf[2]["create_local"], cur_value self.formsemestre_id, tf[2]["create_local"], cur_value
) )
# Modifie valeurs: # Modifie valeurs:
for (pref_name, descr) in PREFS: for (pref_name, descr) in self.base_prefs.prefs_definition:
if ( if (
pref_name in tf[2] pref_name in tf[2]
and not descr.get("only_global", False) and not descr.get("only_global", False)
@ -2115,83 +2194,7 @@ function set_global_pref(el, pref_name) {
REQUEST.URL0 + "?formsemestre_id=" + self.formsemestre_id REQUEST.URL0 + "?formsemestre_id=" + self.formsemestre_id
) )
elif destination == "global": elif destination == "global":
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(scu.ScoURL() + "/edit_preferences")
self.scu.ScoURL() + "/edit_preferences"
)
# Build list of elements for TrivialFormulator...
def _build_form(self, categories=[], global_edit=False):
form = []
for cat, cat_descr in PREF_CATEGORIES:
if categories and cat not in categories:
continue # skip this category
#
cat_elems = []
for pref_name, pref in PREFS:
if pref["category"] == cat:
if pref.get("only_global", False) and not global_edit:
continue # saute les prefs seulement globales
descr = pref.copy()
descr["comment"] = descr.get("explanation", None)
if "explanation" in descr:
del descr["explanation"]
if not global_edit:
descr["explanation"] = (
"""ou <span class="spanlink" onclick="set_global_pref(this, '%s');">utiliser paramètre global</span>"""
% pref_name
)
# if descr.get('only_global',False):
# # pas modifiable, donne juste la valeur courante
# descr['readonly'] = True
# descr['explanation'] = '(valeur globale, non modifiable)'
# elif
if not global_edit and self.is_global(pref_name):
# valeur actuelle globale (ou vient d'etre supprimee localement):
# montre la valeur et menus pour la rendre locale
descr["readonly"] = True
menu_global = (
"""<select class="tf-selglobal" onchange="sel_global(this, '%s');">
<option value="">Valeur définie globalement</option>
<option value="create">Spécifier valeur pour ce semestre seulement</option>
</select>
"""
% pref_name
)
# <option value="changeglobal">Changer paramètres globaux</option>
descr["explanation"] = menu_global
cat_elems.append((pref_name, descr))
if cat_elems:
# category titles:
title = cat_descr.get("title", None)
if title:
form.append(
(
"sep_%s" % cat,
{"input_type": "separator", "title": "<h3>%s</h3>" % title},
)
)
subtitle = cat_descr.get("subtitle", None)
if subtitle:
form.append(
(
"sepsub_%s" % cat,
{
"input_type": "separator",
"title": '<p class="help">%s</p>' % subtitle,
},
)
)
form.extend(cat_elems)
return form
def get_preference(context, name, formsemestre_id=None):
"""Returns value of named preference.
All preferences have a sensible default value, so this function always returns a usable value for all defined preferences names.
"""
return get_base_preferences(context).get(formsemestre_id, name)
# #
@ -2204,7 +2207,7 @@ def doc_preferences(context):
L.append([""]) L.append([""])
L.append(["Nom", "&nbsp;", "&nbsp;"]) L.append(["Nom", "&nbsp;", "&nbsp;"])
L.append(["----", "----", "----"]) L.append(["----", "----", "----"])
for pref_name, pref in PREFS: for pref_name, pref in get_base_preferences(context).prefs_definition:
if pref["category"] == cat: if pref["category"] == cat:
L.append( L.append(
["`" + pref_name + "`", pref["title"], pref.get("explanation", "")] ["`" + pref_name + "`", pref["title"], pref.get("explanation", "")]

View File

@ -29,17 +29,17 @@
""" """
import time import time
import sco_utils as scu import app.scodoc.sco_utils as scu
from notes_log import log from app.scodoc import sco_groups
import notes_table from app.scodoc import sco_core
import sco_groups from app.scodoc import sco_excel
import sco_excel from app.scodoc import sco_formsemestre
import sco_formsemestre from app.scodoc import sco_parcours_dut
import sco_parcours_dut from app.scodoc import sco_codes_parcours
import sco_codes_parcours from app.scodoc.sco_abs import getAbsSemEtud
from scolars import format_nom, format_prenom, format_civilite, format_lycee from app.scodoc import VERSION
from sco_abs import getAbsSemEtud from app.scodoc import sco_etud
import VERSION from app.scodoc import sco_preferences
def feuille_preparation_jury(context, formsemestre_id, REQUEST): def feuille_preparation_jury(context, formsemestre_id, REQUEST):
@ -71,7 +71,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
nbabs = {} nbabs = {}
nbabsjust = {} nbabsjust = {}
for etudid in etudids: for etudid in etudids:
info = scolars.get_etud_info(etudid=etudid, filled=True) info = sco_etud.get_etud_info(etudid=etudid, filled=True)
if not info: if not info:
continue # should not occur... continue # should not occur...
etud = info[0] etud = info[0]
@ -230,8 +230,8 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
l += [ l += [
etudid, etudid,
etud["civilite_str"], etud["civilite_str"],
format_nom(etud["nom"]), sco_etud.format_nom(etud["nom"]),
format_prenom(etud["prenom"]), sco_etud.format_prenom(etud["prenom"]),
etud["date_naissance"], etud["date_naissance"],
etud["bac"], etud["bac"],
etud["specialite"], etud["specialite"],

View File

@ -26,29 +26,8 @@
############################################################################## ##############################################################################
"""Edition des PV de jury """Edition des PV de jury
"""
import time
from reportlab.platypus import Paragraph
from reportlab.lib import styles
import sco_utils as scu PV Jury IUTV 2006: on détaillait 8 cas:
import notesdb as ndb
from notes_log import log
import scolars
import sco_formsemestre
import sco_groups
import sco_groups_view
import sco_parcours_dut
import sco_codes_parcours
from sco_codes_parcours import NO_SEMESTRE_ID
import sco_excel
from TrivialFormulator import TrivialFormulator
from gen_tables import GenTable
import sco_pvpdf
import sco_pdf
from sco_pdf import PDFLOCK
"""PV Jury IUTV 2006: on détaillait 8 cas:
Jury de semestre n Jury de semestre n
On a 8 types de décisions: On a 8 types de décisions:
Passages: Passages:
@ -67,6 +46,31 @@ Jury de semestre n
8. non validation de Sn-1 et Sn et non redoublement 8. non validation de Sn-1 et Sn et non redoublement
""" """
import time
from reportlab.platypus import Paragraph
from reportlab.lib import styles
import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log
from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core
from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups
from app.scodoc import sco_groups_view
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_pdf
from app.scodoc import sco_preferences
from app.scodoc import sco_pvpdf
from app.scodoc import sco_etud
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_codes_parcours import NO_SEMESTRE_ID
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(context, nt, etudid, decisions_ue, decision_sem):
"""Liste des UE validées dans ce semestre""" """Liste des UE validées dans ce semestre"""
@ -87,7 +91,6 @@ def _descr_decisions_ues(context, nt, etudid, decisions_ue, decision_sem):
uelist.append(ue) uelist.append(ue)
except: except:
log("descr_decisions_ues: ue_id=%s decisions_ue=%s" % (ue_id, decisions_ue)) log("descr_decisions_ues: ue_id=%s decisions_ue=%s" % (ue_id, decisions_ue))
pass
# Les UE capitalisées dans d'autres semestres: # Les UE capitalisées dans d'autres semestres:
for ue in nt.ue_capitalisees[etudid]: for ue in nt.ue_capitalisees[etudid]:
try: try:
@ -226,7 +229,7 @@ def dict_pvjury(
L = [] L = []
D = {} # même chose que L, mais { etudid : dec } D = {} # même chose que L, mais { etudid : dec }
for etudid in etudids: for etudid in etudids:
etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
semestre_non_terminal = semestre_non_terminal or Se.semestre_non_terminal semestre_non_terminal = semestre_non_terminal or Se.semestre_non_terminal
d = {} d = {}
@ -327,7 +330,7 @@ def dict_pvjury(
max_date = date max_date = date
# Code semestre precedent # Code semestre precedent
if with_prev: # optionnel car un peu long... if with_prev: # optionnel car un peu long...
info = scolars.get_etud_info(etudid=etudid, filled=True) info = sco_etud.get_etud_info(etudid=etudid, filled=True)
if not info: if not info:
continue # should not occur continue # should not occur
etud = info[0] etud = info[0]
@ -353,9 +356,9 @@ def dict_pvjury(
"formsemestre": sem, "formsemestre": sem,
"has_prev": has_prev, "has_prev": has_prev,
"semestre_non_terminal": semestre_non_terminal, "semestre_non_terminal": semestre_non_terminal,
"formation": sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[ "formation": sco_formations.formation_list(
0 context, args={"formation_id": sem["formation_id"]}
], )[0],
"decisions": L, "decisions": L,
"decisions_dict": D, "decisions_dict": D,
} }
@ -427,7 +430,7 @@ def pvjury_table(
lines = [] lines = []
for e in dpv["decisions"]: for e in dpv["decisions"]:
scolars.format_etud_ident(e["identite"]) sco_etud.format_etud_ident(e["identite"])
l = { l = {
"etudid": e["identite"]["etudid"], "etudid": e["identite"]["etudid"],
"code_nip": e["identite"]["code_nip"], "code_nip": e["identite"]["code_nip"],
@ -614,7 +617,7 @@ def formsemestre_pvjury_pdf(
groups_infos = None groups_infos = None
if etudid: if etudid:
# PV pour ce seul étudiant: # PV pour ce seul étudiant:
etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
etuddescr = '<a class="discretelink" href="ficheEtud?etudid=%s">%s</a>' % ( etuddescr = '<a class="discretelink" href="ficheEtud?etudid=%s">%s</a>' % (
etudid, etudid,
etud["nomprenom"], etud["nomprenom"],

View File

@ -42,16 +42,16 @@ from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib import styles from reportlab.lib import styles
from reportlab.lib.colors import Color from reportlab.lib.colors import Color
import sco_utils as scu import app.scodoc.sco_utils as scu
import sco_pdf from app.scodoc import sco_bulletins_pdf
from sco_pdf import SU from app.scodoc import sco_codes_parcours
import sco_formsemestre from app.scodoc import sco_formsemestre
import sco_pvjury from app.scodoc import sco_pdf
import sco_codes_parcours from app.scodoc import sco_preferences
from sco_pdf import PDFLOCK from app.scodoc import sco_etud
import sco_preferences from app.scodoc import VERSION
import sco_bulletins_pdf from app.scodoc.sco_pdf import PDFLOCK
import VERSION from app.scodoc.sco_pdf import SU
LOGO_FOOTER_ASPECT = scu.CONFIG.LOGO_FOOTER_ASPECT # XXX A AUTOMATISER LOGO_FOOTER_ASPECT = scu.CONFIG.LOGO_FOOTER_ASPECT # XXX A AUTOMATISER
LOGO_FOOTER_HEIGHT = scu.CONFIG.LOGO_FOOTER_HEIGHT * mm LOGO_FOOTER_HEIGHT = scu.CONFIG.LOGO_FOOTER_HEIGHT * mm
@ -337,6 +337,7 @@ def pdf_lettres_individuelles(
(tous ceux du semestre, ou la liste indiquée par etudids) (tous ceux du semestre, ou la liste indiquée par etudids)
Renvoie pdf data ou chaine vide si aucun etudiant avec décision de jury. Renvoie pdf data ou chaine vide si aucun etudiant avec décision de jury.
""" """
from app.scodoc import sco_pvjury
dpv = sco_pvjury.dict_pvjury( dpv = sco_pvjury.dict_pvjury(
context, formsemestre_id, etudids=etudids, with_prev=True context, formsemestre_id, etudids=etudids, with_prev=True
@ -345,7 +346,7 @@ def pdf_lettres_individuelles(
return "" return ""
# Ajoute infos sur etudiants # Ajoute infos sur etudiants
etuds = [x["identite"] for x in dpv["decisions"]] etuds = [x["identite"] for x in dpv["decisions"]]
scolars.fillEtudsInfo(context, etuds) sco_etud.fill_etuds_info(etuds)
# #
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
prefs = sco_preferences.SemPreferences(context, formsemestre_id) prefs = sco_preferences.SemPreferences(context, formsemestre_id)
@ -357,7 +358,7 @@ def pdf_lettres_individuelles(
"htab2": "1cm", "htab2": "1cm",
} }
# copie preferences # copie preferences
for name in sco_preferences.PREFS_NAMES: for name in sco_preferences.get_base_preferences(context).prefs_name:
params[name] = sco_preferences.get_preference( params[name] = sco_preferences.get_preference(
context, name, sem["formsemestre_id"] context, name, sem["formsemestre_id"]
) )
@ -367,7 +368,7 @@ def pdf_lettres_individuelles(
npages = 0 npages = 0
for e in dpv["decisions"]: for e in dpv["decisions"]:
if e["decision_sem"]: # decision prise if e["decision_sem"]: # decision prise
etud = scolars.get_etud_info(e["identite"]["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(e["identite"]["etudid"], filled=True)[0]
params["nomEtud"] = etud["nomprenom"] params["nomEtud"] = etud["nomprenom"]
bookmarks[npages + 1] = scu.suppress_accents(etud["nomprenom"]) bookmarks[npages + 1] = scu.suppress_accents(etud["nomprenom"])
objects += pdf_lettre_individuelle( objects += pdf_lettre_individuelle(
@ -705,6 +706,8 @@ def _pvjury_pdf_type(
"""Doc PDF récapitulant les décisions de jury pour un type de jury (passage ou delivrance) """Doc PDF récapitulant les décisions de jury pour un type de jury (passage ou delivrance)
dpv: result of dict_pvjury dpv: result of dict_pvjury
""" """
from app.scodoc import sco_pvjury
# Jury de diplome si sem. terminal OU que l'on demande les diplomés d'un semestre antérieur # Jury de diplome si sem. terminal OU que l'on demande les diplomés d'un semestre antérieur
diplome = (not dpv["semestre_non_terminal"]) or only_diplome diplome = (not dpv["semestre_non_terminal"]) or only_diplome

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