1
0
forked from ScoDoc/ScoDoc

Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8

This commit is contained in:
Emmanuel Viennet 2021-01-17 23:04:55 +01:00
commit b76200ac87
40 changed files with 1518 additions and 1484 deletions

View File

@ -666,21 +666,6 @@ class ZAbsences(
if self.CountAbs(etudid, jour, jour, matin, moduleimpl_id) == 0: if self.CountAbs(etudid, jour, jour, matin, moduleimpl_id) == 0:
self._AddAbsence(etudid, jour, matin, 0, REQUEST, "", moduleimpl_id) self._AddAbsence(etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
#
security.declareProtected(ScoView, "CalSelectWeek")
def CalSelectWeek(self, year=None, REQUEST=None):
"display calendar allowing week selection"
if not year:
year = scu.AnneeScolaire(REQUEST)
sems = sco_formsemestre.do_formsemestre_list(self)
if not sems:
js = ""
else:
js = 'onmouseover="highlightweek(this);" onmouseout="deselectweeks();" onclick="wclick(this);"'
C = sco_abs.YearTable(self, int(year), dayattributes=js)
return C
# --- Misc tools.... ------------------ # --- Misc tools.... ------------------
def _isFarFutur(self, jour): def _isFarFutur(self, jour):
@ -691,65 +676,6 @@ class ZAbsences(
# 6 mois ~ 182 jours: # 6 mois ~ 182 jours:
return j - datetime.date.today() > datetime.timedelta(182) return j - datetime.date.today() > datetime.timedelta(182)
security.declareProtected(ScoView, "is_work_saturday")
def is_work_saturday(self):
"Vrai si le samedi est travaillé"
return int(self.get_preference("work_saturday"))
security.declareProtected(ScoView, "day_names")
def day_names(self):
"""Returns week day names.
If work_saturday property is set, include saturday
"""
if self.is_work_saturday():
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
else:
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]
security.declareProtected(ScoView, "ListMondays")
def ListMondays(self, year=None, REQUEST=None):
"""return list of mondays (ISO dates), from september to june"""
if not year:
year = scu.AnneeScolaire(REQUEST)
d = ddmmyyyy("1/9/%d" % year, work_saturday=self.is_work_saturday())
while d.weekday != 0:
d = d.next()
end = ddmmyyyy("1/7/%d" % (year + 1), work_saturday=self.is_work_saturday())
L = [d]
while d < end:
d = d.next(days=7)
L.append(d)
return map(lambda x: x.ISO(), L)
security.declareProtected(ScoView, "NextISODay")
def NextISODay(self, date):
"return date after date"
d = ddmmyyyy(date, fmt="iso", work_saturday=self.is_work_saturday())
return d.next().ISO()
security.declareProtected(ScoView, "DateRangeISO")
def DateRangeISO(self, date_beg, date_end, workable=1):
"""returns list of dates in [date_beg,date_end]
workable = 1 => keeps only workable days"""
if not date_beg:
raise ScoValueError("pas de date spécifiée !")
if not date_end:
date_end = date_beg
r = []
cur = ddmmyyyy(date_beg, work_saturday=self.is_work_saturday())
end = ddmmyyyy(date_end, work_saturday=self.is_work_saturday())
while cur <= end:
if (not workable) or cur.iswork():
r.append(cur)
cur = cur.next()
return map(lambda x: x.ISO(), r)
# ------------ HTML Interfaces # ------------ HTML Interfaces
security.declareProtected(ScoAbsChange, "SignaleAbsenceGrHebdo") security.declareProtected(ScoAbsChange, "SignaleAbsenceGrHebdo")
@ -801,8 +727,8 @@ class ZAbsences(
# calcule dates jours de cette semaine # calcule dates jours de cette semaine
# liste de dates iso "yyyy-mm-dd" # liste de dates iso "yyyy-mm-dd"
datessem = [notesdb.DateDMYtoISO(datelundi)] datessem = [notesdb.DateDMYtoISO(datelundi)]
for _ in self.day_names()[1:]: for _ in sco_abs.day_names(self)[1:]:
datessem.append(self.NextISODay(datessem[-1])) datessem.append(sco_abs.next_iso_day(self, datessem[-1]))
# #
if groups_infos.tous_les_etuds_du_sem: if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en" gr_tit = "en"
@ -944,12 +870,12 @@ class ZAbsences(
sem = sco_formsemestre.do_formsemestre_list( sem = sco_formsemestre.do_formsemestre_list(
self, {"formsemestre_id": formsemestre_id} self, {"formsemestre_id": formsemestre_id}
)[0] )[0]
work_saturday = sco_abs.is_work_saturday(self)
jourdebut = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday()) jourdebut = ddmmyyyy(datedebut, work_saturday=work_saturday)
jourfin = ddmmyyyy(datefin, work_saturday=self.is_work_saturday()) jourfin = ddmmyyyy(datefin, work_saturday=work_saturday)
today = ddmmyyyy( today = ddmmyyyy(
time.strftime("%d/%m/%Y", time.localtime()), time.strftime("%d/%m/%Y", time.localtime()),
work_saturday=self.is_work_saturday(), work_saturday=work_saturday,
) )
today.next() today.next()
if jourfin > today: # ne propose jamais les semaines dans le futur if jourfin > today: # ne propose jamais les semaines dans le futur
@ -964,7 +890,7 @@ class ZAbsences(
) )
# calcule dates # calcule dates
dates = [] # ddmmyyyy instances dates = [] # ddmmyyyy instances
d = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday()) d = ddmmyyyy(datedebut, work_saturday=work_saturday)
while d <= jourfin: while d <= jourfin:
dates.append(d) dates.append(d)
d = d.next(7) # avance d'une semaine d = d.next(7) # avance d'une semaine
@ -982,7 +908,7 @@ class ZAbsences(
url_link_semaines += "&amp;moduleimpl_id=" + moduleimpl_id url_link_semaines += "&amp;moduleimpl_id=" + moduleimpl_id
# #
dates = [x.ISO() for x in dates] dates = [x.ISO() for x in dates]
dayname = self.day_names()[jourdebut.weekday] dayname = sco_abs.day_names(self)[jourdebut.weekday]
if groups_infos.tous_les_etuds_du_sem: if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en" gr_tit = "en"
@ -1119,7 +1045,7 @@ class ZAbsences(
odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates] odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates]
# Titres colonnes # Titres colonnes
noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ] noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ]
jn = self.day_names() jn = sco_abs.day_names(self)
for d in odates: for d in odates:
idx_jour = d.weekday() idx_jour = d.weekday()
noms_jours.append(jn[idx_jour]) noms_jours.append(jn[idx_jour])
@ -1844,7 +1770,7 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
# 1-- ajout des absences (et justifs) # 1-- ajout des absences (et justifs)
datedebut = billet["abs_begin"].strftime("%d/%m/%Y") datedebut = billet["abs_begin"].strftime("%d/%m/%Y")
datefin = billet["abs_end"].strftime("%d/%m/%Y") datefin = billet["abs_end"].strftime("%d/%m/%Y")
dates = self.DateRangeISO(datedebut, datefin) dates = sco_abs.DateRangeISO(self, datedebut, datefin)
# commence après-midi ? # commence après-midi ?
if dates and billet["abs_begin"].hour > 11: if dates and billet["abs_begin"].hour > 11:
self._AddAbsence( self._AddAbsence(

File diff suppressed because it is too large Load Diff

421
ZNotes.py
View File

@ -52,6 +52,7 @@ import sco_formsemestre_edit
import sco_formsemestre_status import sco_formsemestre_status
import sco_formsemestre_inscriptions import sco_formsemestre_inscriptions
import sco_formsemestre_custommenu import sco_formsemestre_custommenu
import sco_moduleimpl
import sco_moduleimpl_status import sco_moduleimpl_status
import sco_moduleimpl_inscriptions import sco_moduleimpl_inscriptions
import sco_evaluations import sco_evaluations
@ -839,7 +840,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
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 !
mods = self.do_moduleimpl_list(module_id=oid) mods = sco_moduleimpl.do_moduleimpl_list(self, module_id=oid)
if mods: if mods:
err_page = self.confirmDialog( err_page = self.confirmDialog(
message="""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>""", message="""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>""",
@ -917,7 +918,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
def module_count_moduleimpls(self, module_id): def module_count_moduleimpls(self, module_id):
"Number of moduleimpls using this module" "Number of moduleimpls using this module"
mods = self.do_moduleimpl_list(module_id=module_id) mods = sco_moduleimpl.do_moduleimpl_list(self, module_id=module_id)
return len(mods) return len(mods)
security.declareProtected(ScoView, "module_is_locked") security.declareProtected(ScoView, "module_is_locked")
@ -1207,158 +1208,12 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
else: else:
return h return h
# --- Gestion des "Implémentations de Modules"
# Un "moduleimpl" correspond a la mise en oeuvre d'un module
# dans une formation spécifique, à une date spécifique.
_moduleimplEditor = EditableTable(
"notes_moduleimpl",
"moduleimpl_id",
(
"moduleimpl_id",
"module_id",
"formsemestre_id",
"responsable_id",
"computation_expr",
),
)
_modules_enseignantsEditor = EditableTable(
"notes_modules_enseignants",
"modules_enseignants_id",
("modules_enseignants_id", "moduleimpl_id", "ens_id"),
)
security.declareProtected(ScoImplement, "do_moduleimpl_create")
def do_moduleimpl_create(self, args):
"create a moduleimpl"
cnx = self.GetDBConnexion()
r = self._moduleimplEditor.create(cnx, args)
self._inval_cache(
formsemestre_id=args["formsemestre_id"]
) # > creation moduleimpl
return r
security.declareProtected(ScoImplement, "do_moduleimpl_delete")
def do_moduleimpl_delete(self, oid, formsemestre_id=None):
"delete moduleimpl (desinscrit tous les etudiants)"
cnx = self.GetDBConnexion()
# --- desinscription des etudiants
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
req = "DELETE FROM notes_moduleimpl_inscription WHERE moduleimpl_id=%(moduleimpl_id)s"
cursor.execute(req, {"moduleimpl_id": oid})
# --- suppression des enseignants
cursor.execute(
"DELETE FROM notes_modules_enseignants WHERE moduleimpl_id=%(moduleimpl_id)s",
{"moduleimpl_id": oid},
)
# --- suppression des references dans les absences
cursor.execute(
"UPDATE absences SET moduleimpl_id=NULL WHERE moduleimpl_id=%(moduleimpl_id)s",
{"moduleimpl_id": oid},
)
# --- destruction du moduleimpl
self._moduleimplEditor.delete(cnx, oid)
self._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_delete
security.declareProtected(ScoView, "do_moduleimpl_list")
def do_moduleimpl_list(
self, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None
):
"list moduleimpls"
args = locals()
cnx = self.GetDBConnexion()
modimpls = self._moduleimplEditor.list(cnx, args) # *args, **kw)
# Ajoute la liste des enseignants
for mo in modimpls:
mo["ens"] = self.do_ens_list(args={"moduleimpl_id": mo["moduleimpl_id"]})
return return_text_if_published(modimpls, REQUEST)
security.declareProtected(ScoImplement, "do_moduleimpl_edit")
def do_moduleimpl_edit(self, args, formsemestre_id=None, cnx=None):
"edit a moduleimpl"
if not cnx:
cnx = self.GetDBConnexion()
self._moduleimplEditor.edit(cnx, args)
self._inval_cache(formsemestre_id=formsemestre_id) # > modif moduleimpl
security.declareProtected(ScoView, "do_moduleimpl_withmodule_list")
def do_moduleimpl_withmodule_list(
self, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None
):
"""Liste les moduleimpls et ajoute dans chacun le module correspondant
Tri la liste par semestre/UE/numero_matiere/numero_module
"""
args = locals()
del args["self"]
del args["REQUEST"]
modimpls = self.do_moduleimpl_list(**args)
for mo in modimpls:
mo["module"] = self.do_module_list(args={"module_id": mo["module_id"]})[0]
mo["ue"] = self.do_ue_list(args={"ue_id": mo["module"]["ue_id"]})[0]
mo["matiere"] = self.do_matiere_list(
args={"matiere_id": mo["module"]["matiere_id"]}
)[0]
# tri par semestre/UE/numero_matiere/numero_module
extr = lambda x: (
x["ue"]["numero"],
x["ue"]["ue_id"],
x["matiere"]["numero"],
x["matiere"]["matiere_id"],
x["module"]["numero"],
x["module"]["code"],
)
modimpls.sort(lambda x, y: cmp(extr(x), extr(y)))
# log('after sort args=%s' % args)
# log( ',\n'.join( [ str(extr(m)) for m in modimpls ] ))
# log('after sort: Mlist=\n' + ',\n'.join( [ str(m) for m in modimpls ] ) + '\n')
return return_text_if_published(modimpls, REQUEST)
security.declareProtected(ScoView, "do_ens_list")
def do_ens_list(self, *args, **kw):
"liste les enseignants d'un moduleimpl (pas le responsable)"
cnx = self.GetDBConnexion()
ens = self._modules_enseignantsEditor.list(cnx, *args, **kw)
return ens
security.declareProtected(ScoImplement, "do_ens_edit")
def do_ens_edit(self, *args, **kw):
"edit ens"
cnx = self.GetDBConnexion()
self._modules_enseignantsEditor.edit(cnx, *args, **kw)
security.declareProtected(ScoImplement, "do_ens_create")
def do_ens_create(self, args):
"create ens"
cnx = self.GetDBConnexion()
r = self._modules_enseignantsEditor.create(cnx, args)
return r
security.declareProtected(ScoImplement, "do_ens_delete")
def do_ens_delete(self, oid):
"delete ens"
cnx = self.GetDBConnexion()
r = self._modules_enseignantsEditor.delete(cnx, oid)
return r
# --- dialogue modif enseignants/moduleimpl # --- dialogue modif enseignants/moduleimpl
security.declareProtected(ScoView, "edit_enseignants_form") security.declareProtected(ScoView, "edit_enseignants_form")
def edit_enseignants_form(self, REQUEST, moduleimpl_id): def edit_enseignants_form(self, REQUEST, moduleimpl_id):
"modif liste enseignants/moduleimpl" "modif liste enseignants/moduleimpl"
M, sem = self.can_change_ens(REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_ens(self, REQUEST, moduleimpl_id)
# -- # --
header = self.html_sem_header( header = self.html_sem_header(
REQUEST, REQUEST,
@ -1453,8 +1308,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
% ens_id % ens_id
) )
else: else:
self.do_ens_create( sco_moduleimpl.do_ens_create(
{"moduleimpl_id": moduleimpl_id, "ens_id": ens_id} self, {"moduleimpl_id": moduleimpl_id, "ens_id": ens_id}
) )
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"edit_enseignants_form?moduleimpl_id=%s" % moduleimpl_id "edit_enseignants_form?moduleimpl_id=%s" % moduleimpl_id
@ -1467,7 +1322,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
"""Changement d'un enseignant responsable de module """Changement d'un enseignant responsable de module
Accessible par Admin et dir des etud si flag resp_can_change_ens Accessible par Admin et dir des etud si flag resp_can_change_ens
""" """
M, sem = self.can_change_module_resp(REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_module_resp(self, REQUEST, moduleimpl_id)
H = [ H = [
self.html_sem_header( self.html_sem_header(
REQUEST, REQUEST,
@ -1535,7 +1390,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"moduleimpl_status?moduleimpl_id=" + moduleimpl_id "moduleimpl_status?moduleimpl_id=" + moduleimpl_id
) )
self.do_moduleimpl_edit( sco_moduleimpl.do_moduleimpl_edit(
self,
{"moduleimpl_id": moduleimpl_id, "responsable_id": responsable_id}, {"moduleimpl_id": moduleimpl_id, "responsable_id": responsable_id},
formsemestre_id=sem["formsemestre_id"], formsemestre_id=sem["formsemestre_id"],
) )
@ -1572,7 +1428,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
"""Edition formule calcul moyenne module """Edition formule calcul moyenne module
Accessible par Admin, dir des etud et responsable module Accessible par Admin, dir des etud et responsable module
""" """
M, sem = self.can_change_ens(REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_ens(self, REQUEST, moduleimpl_id)
H = [ H = [
self.html_sem_header( self.html_sem_header(
REQUEST, REQUEST,
@ -1616,7 +1472,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
"moduleimpl_status?moduleimpl_id=" + moduleimpl_id "moduleimpl_status?moduleimpl_id=" + moduleimpl_id
) )
else: else:
self.do_moduleimpl_edit( sco_moduleimpl.do_moduleimpl_edit(
self,
{ {
"moduleimpl_id": moduleimpl_id, "moduleimpl_id": moduleimpl_id,
"computation_expr": tf[2]["computation_expr"], "computation_expr": tf[2]["computation_expr"],
@ -1636,11 +1493,13 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
def view_module_abs(self, REQUEST, moduleimpl_id, format="html"): def view_module_abs(self, REQUEST, moduleimpl_id, format="html"):
"""Visualisation des absences a un module""" """Visualisation des absences a un module"""
M = self.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_withmodule_list(
self, moduleimpl_id=moduleimpl_id
)[0]
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
debut_sem = DateDMYtoISO(sem["date_debut"]) debut_sem = DateDMYtoISO(sem["date_debut"])
fin_sem = DateDMYtoISO(sem["date_fin"]) fin_sem = DateDMYtoISO(sem["date_fin"])
list_insc = self.do_moduleimpl_listeetuds(moduleimpl_id) list_insc = sco_moduleimpl.do_moduleimpl_listeetuds(self, moduleimpl_id)
T = [] T = []
for etudid in list_insc: for etudid in list_insc:
@ -1779,7 +1638,9 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
""" """
sem = sco_formsemestre.get_formsemestre(self, formsemestre_id) sem = sco_formsemestre.get_formsemestre(self, formsemestre_id)
# resp. de modules: # resp. de modules:
mods = self.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) mods = sco_moduleimpl.do_moduleimpl_withmodule_list(
self, formsemestre_id=formsemestre_id
)
sem_ens = {} sem_ens = {}
for mod in mods: for mod in mods:
if not mod["responsable_id"] in sem_ens: if not mod["responsable_id"] in sem_ens:
@ -1855,7 +1716,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
def edit_enseignants_form_delete(self, REQUEST, moduleimpl_id, ens_id): def edit_enseignants_form_delete(self, REQUEST, moduleimpl_id, ens_id):
"remove ens" "remove ens"
M, sem = self.can_change_ens(REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_ens(self, REQUEST, moduleimpl_id)
# search ens_id # search ens_id
ok = False ok = False
for ens in M["ens"]: for ens in M["ens"]:
@ -1864,59 +1725,11 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
break break
if not ok: if not ok:
raise ScoValueError("invalid ens_id (%s)" % ens_id) raise ScoValueError("invalid ens_id (%s)" % ens_id)
self.do_ens_delete(ens["modules_enseignants_id"]) sco_moduleimpl.do_ens_delete(self, ens["modules_enseignants_id"])
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"edit_enseignants_form?moduleimpl_id=%s" % moduleimpl_id "edit_enseignants_form?moduleimpl_id=%s" % moduleimpl_id
) )
security.declareProtected(ScoView, "can_change_ens")
def can_change_ens(self, REQUEST, moduleimpl_id, raise_exc=True):
"check if current user can modify ens list (raise exception if not)"
M = self.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
# -- check lock
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
if sem["etat"] != "1":
if raise_exc:
raise ScoValueError("Modification impossible: semestre verrouille")
else:
return False
# -- check access
authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser)
# admin, resp. module ou resp. semestre
if (
uid != M["responsable_id"]
and not authuser.has_permission(ScoImplement, self)
and (uid not in sem["responsables"])
):
if raise_exc:
raise AccessDenied("Modification impossible pour %s" % uid)
else:
return False
return M, sem
security.declareProtected(ScoView, "can_change_module_resp")
def can_change_module_resp(self, REQUEST, moduleimpl_id):
"""Check if current user can modify module resp. (raise exception if not).
= Admin, et dir des etud. (si option l'y autorise)
"""
M = self.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
# -- check lock
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
if sem["etat"] != "1":
raise ScoValueError("Modification impossible: semestre verrouille")
# -- check access
authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser)
# admin ou resp. semestre avec flag resp_can_change_resp
if not authuser.has_permission(ScoImplement, self) and (
(uid not in sem["responsables"]) or (not sem["resp_can_change_ens"])
):
raise AccessDenied("Modification impossible pour %s" % uid)
return M, sem
# --- Gestion des inscriptions aux modules # --- Gestion des inscriptions aux modules
_formsemestre_inscriptionEditor = EditableTable( _formsemestre_inscriptionEditor = EditableTable(
"notes_formsemestre_inscription", "notes_formsemestre_inscription",
@ -2132,8 +1945,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
res = cursor.fetchall() res = cursor.fetchall()
moduleimpl_inscription_ids = [x[0] for x in res] moduleimpl_inscription_ids = [x[0] for x in res]
for moduleimpl_inscription_id in moduleimpl_inscription_ids: for moduleimpl_inscription_id in moduleimpl_inscription_ids:
self.do_moduleimpl_inscription_delete( sco_moduleimpl.do_moduleimpl_inscription_delete(
moduleimpl_inscription_id, formsemestre_id=formsemestre_id self, moduleimpl_inscription_id, formsemestre_id=formsemestre_id
) )
# -- desincription du semestre # -- desincription du semestre
self.do_formsemestre_inscription_delete( self.do_formsemestre_inscription_delete(
@ -2164,123 +1977,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
commit=False, commit=False,
) )
# --- Inscriptions aux modules
_moduleimpl_inscriptionEditor = EditableTable(
"notes_moduleimpl_inscription",
"moduleimpl_inscription_id",
("moduleimpl_inscription_id", "etudid", "moduleimpl_id"),
)
security.declareProtected(ScoEtudInscrit, "do_moduleimpl_inscription_create")
def do_moduleimpl_inscription_create(
self, args, REQUEST=None, formsemestre_id=None
):
"create a moduleimpl_inscription"
cnx = self.GetDBConnexion()
log("do_moduleimpl_inscription_create: " + str(args))
r = self._moduleimpl_inscriptionEditor.create(cnx, args)
self._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription
if REQUEST:
logdb(
REQUEST,
cnx,
method="moduleimpl_inscription",
etudid=args["etudid"],
msg="inscription module %s" % args["moduleimpl_id"],
commit=False,
)
return r
security.declareProtected(ScoImplement, "do_moduleimpl_inscription_delete")
def do_moduleimpl_inscription_delete(self, oid, formsemestre_id=None):
"delete moduleimpl_inscription"
cnx = self.GetDBConnexion()
self._moduleimpl_inscriptionEditor.delete(cnx, oid)
self._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription
security.declareProtected(ScoView, "do_moduleimpl_inscription_list")
def do_moduleimpl_inscription_list(
self, moduleimpl_id=None, etudid=None, REQUEST=None
):
"list moduleimpl_inscriptions"
args = locals()
cnx = self.GetDBConnexion()
return return_text_if_published(
self._moduleimpl_inscriptionEditor.list(cnx, args), REQUEST
)
security.declareProtected(ScoView, "do_moduleimpl_listeetuds")
def do_moduleimpl_listeetuds(self, moduleimpl_id):
"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"
cnx = self.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(req, {"moduleimpl_id": moduleimpl_id})
res = cursor.fetchall()
return [x[0] for x in res]
security.declareProtected(ScoEtudInscrit, "do_moduleimpl_inscrit_tout_semestre")
def do_moduleimpl_inscrit_tout_semestre(self, moduleimpl_id, formsemestre_id):
"inscrit tous les etudiants inscrit au semestre a ce module"
cnx = self.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
req = """INSERT INTO notes_moduleimpl_inscription
(moduleimpl_id, etudid)
SELECT %(moduleimpl_id)s, I.etudid
FROM notes_formsemestre_inscription I
WHERE I.formsemestre_id=%(formsemestre_id)s"""
args = {"moduleimpl_id": moduleimpl_id, "formsemestre_id": formsemestre_id}
cursor.execute(req, args)
security.declareProtected(ScoEtudInscrit, "do_moduleimpl_inscrit_etuds")
def do_moduleimpl_inscrit_etuds(
self, moduleimpl_id, formsemestre_id, etudids, reset=False, REQUEST=None
):
"""Inscrit les etudiants (liste d'etudids) a ce module.
Si reset, desinscrit tous les autres.
"""
# Verifie qu'ils sont tous bien inscrits au semestre
for etudid in etudids:
insem = self.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id, "etudid": etudid}
)
if not insem:
raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid)
# Desinscriptions
if reset:
cnx = self.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(
"delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s",
{"moduleimpl_id": moduleimpl_id},
)
# Inscriptions au module:
inmod_set = set(
[
x["etudid"]
for x in self.do_moduleimpl_inscription_list(
moduleimpl_id=moduleimpl_id
)
]
)
for etudid in etudids:
# deja inscrit ?
if not etudid in inmod_set:
self.do_moduleimpl_inscription_create(
{"moduleimpl_id": moduleimpl_id, "etudid": etudid},
REQUEST=REQUEST,
formsemestre_id=formsemestre_id,
)
self._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscrit_etuds
security.declareProtected(ScoEtudInscrit, "etud_desinscrit_ue") security.declareProtected(ScoEtudInscrit, "etud_desinscrit_ue")
def etud_desinscrit_ue(self, etudid, formsemestre_id, ue_id, REQUEST=None): def etud_desinscrit_ue(self, etudid, formsemestre_id, ue_id, REQUEST=None):
@ -2397,7 +2093,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
raise ValueError("no moduleimpl specified") # bug raise ValueError("no moduleimpl specified") # bug
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser) uid = str(authuser)
M = self.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(self, moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
if ( if (
@ -2473,7 +2169,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
r = self._evaluationEditor.create(cnx, args) r = self._evaluationEditor.create(cnx, args)
# news # news
M = self.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(self, moduleimpl_id=moduleimpl_id)[0]
mod = self.do_module_list(args={"module_id": M["module_id"]})[0] mod = self.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"] mod["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
@ -2516,7 +2212,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
jour = args.get("jour", None) jour = args.get("jour", None)
args["jour"] = jour args["jour"] = jour
if jour: if jour:
M = self.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(self, moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
d, m, y = [int(x) for x in sem["date_debut"].split("/")] d, m, y = [int(x) for x in sem["date_debut"].split("/")]
date_debut = datetime.date(y, m, d) date_debut = datetime.date(y, m, d)
@ -2548,7 +2244,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
if not El: if not El:
raise ValueError("Evalution inexistante ! (%s)" % evaluation_id) raise ValueError("Evalution inexistante ! (%s)" % evaluation_id)
E = El[0] E = El[0]
M = self.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(self, moduleimpl_id=E["moduleimpl_id"])[0]
Mod = self.do_module_list(args={"module_id": M["module_id"]})[0] Mod = self.do_module_list(args={"module_id": M["module_id"]})[0]
tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E
etat = sco_evaluations.do_evaluation_etat(self, evaluation_id) etat = sco_evaluations.do_evaluation_etat(self, evaluation_id)
@ -2671,7 +2367,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
def do_evaluation_list_in_formsemestre(self, formsemestre_id): def do_evaluation_list_in_formsemestre(self, formsemestre_id):
"list evaluations in this formsemestre" "list evaluations in this formsemestre"
cnx = self.GetDBConnexion() cnx = self.GetDBConnexion()
mods = self.do_moduleimpl_list(formsemestre_id=formsemestre_id) mods = sco_moduleimpl.do_moduleimpl_list(self, formsemestre_id=formsemestre_id)
evals = [] evals = []
for mod in mods: for mod in mods:
evals += self.do_evaluation_list( evals += self.do_evaluation_list(
@ -2694,7 +2390,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
cnx = self.GetDBConnexion() cnx = self.GetDBConnexion()
self._evaluationEditor.edit(cnx, args) self._evaluationEditor.edit(cnx, args)
# inval cache pour ce semestre # inval cache pour ce semestre
M = self.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(self, moduleimpl_id=moduleimpl_id)[0]
self._inval_cache( self._inval_cache(
formsemestre_id=M["formsemestre_id"] formsemestre_id=M["formsemestre_id"]
) # > evaluation_edit (coef, ...) ) # > evaluation_edit (coef, ...)
@ -2770,42 +2466,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
security.declareProtected(ScoView, "evaluation_suppress_alln") security.declareProtected(ScoView, "evaluation_suppress_alln")
evaluation_suppress_alln = sco_saisie_notes.evaluation_suppress_alln evaluation_suppress_alln = sco_saisie_notes.evaluation_suppress_alln
security.declareProtected(ScoView, "can_edit_notes")
def can_edit_notes(self, 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 = self.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
if sem["etat"] != "1":
return False # semestre verrouillé
if sco_parcours_dut.formsemestre_has_decisions(self, sem["formsemestre_id"]):
# il y a des décisions de jury dans ce semestre !
return (
authuser.has_permission(ScoEditAllNotes, self)
or uid in sem["responsables"]
)
else:
if (
(not authuser.has_permission(ScoEditAllNotes, self))
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
security.declareProtected(ScoEditAllNotes, "dummy_ScoEditAllNotes") security.declareProtected(ScoEditAllNotes, "dummy_ScoEditAllNotes")
def dummy_ScoEditAllNotes(self): def dummy_ScoEditAllNotes(self):
@ -3088,21 +2748,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
) # > appreciation_add ) # > appreciation_add
return REQUEST.RESPONSE.redirect(bull_url) return REQUEST.RESPONSE.redirect(bull_url)
security.declareProtected(ScoView, "can_change_groups")
def can_change_groups(self, REQUEST, formsemestre_id):
"Vrai si utilisateur peut changer les groupes dans ce semestre"
sem = sco_formsemestre.get_formsemestre(self, formsemestre_id)
if sem["etat"] != "1":
return False # semestre verrouillé
authuser = REQUEST.AUTHENTICATED_USER
if authuser.has_permission(ScoEtudChangeGroups, self):
return True # admin, chef dept
uid = str(authuser)
if uid in sem["responsables"]:
return True
return False
def _can_edit_pv(self, REQUEST, formsemestre_id): def _can_edit_pv(self, REQUEST, formsemestre_id):
"Vrai si utilisateur peut editer un PV de jury de ce semestre" "Vrai si utilisateur peut editer un PV de jury de ce semestre"
@ -3514,7 +3159,9 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
""" """
sem = sco_formsemestre.get_formsemestre(self, formsemestre_id) sem = sco_formsemestre.get_formsemestre(self, formsemestre_id)
modimpls = self.do_moduleimpl_list(formsemestre_id=formsemestre_id) modimpls = sco_moduleimpl.do_moduleimpl_list(
self, formsemestre_id=formsemestre_id
)
bad_ue = [] bad_ue = []
bad_sem = [] bad_sem = []
for modimpl in modimpls: for modimpl in modimpls:
@ -3588,7 +3235,9 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
# de formations # de formations
diag = [] diag = []
Mlist = self.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
self, formsemestre_id=formsemestre_id
)
for mod in Mlist: for mod in Mlist:
if mod["module"]["ue_id"] != mod["matiere"]["ue_id"]: if mod["module"]["ue_id"] != mod["matiere"]["ue_id"]:
diag.append( diag.append(

View File

@ -277,8 +277,8 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
# raise NoteProcessError('test exception !') # raise NoteProcessError('test exception !')
# essai: liste des permissions # essai: liste des permissions
from AccessControl import getSecurityManager from AccessControl import getSecurityManager # pylint: disable=import-error
from AccessControl.Permission import Permission from AccessControl.Permission import Permission # pylint: disable=import-error
permissions = self.ac_inherited_permissions(1) permissions = self.ac_inherited_permissions(1)
scoperms = [p for p in permissions if p[0][:3] == "Sco"] scoperms = [p for p in permissions if p[0][:3] == "Sco"]
@ -599,7 +599,7 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
FA.append('<input type="submit" value="Saisir absences du" />') FA.append('<input type="submit" value="Saisir absences du" />')
FA.append('<select name="datedebut" class="noprint">') FA.append('<select name="datedebut" class="noprint">')
date = first_monday date = first_monday
for jour in self.Absences.day_names(): for jour in sco_abs.day_names(self):
FA.append('<option value="%s">%s</option>' % (date, jour)) FA.append('<option value="%s">%s</option>' % (date, jour))
date = date.next() date = date.next()
FA.append("</select>") FA.append("</select>")
@ -654,13 +654,13 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
H.append("</table>") H.append("</table>")
else: else:
H.append('<p class="help indent">Aucun groupe dans cette partition') H.append('<p class="help indent">Aucun groupe dans cette partition')
if self.Notes.can_change_groups(REQUEST, formsemestre_id): if sco_groups.can_change_groups(self, REQUEST, formsemestre_id):
H.append( H.append(
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)' ' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
% partition["partition_id"] % partition["partition_id"]
) )
H.append("</p>") H.append("</p>")
if self.Notes.can_change_groups(REQUEST, formsemestre_id): if sco_groups.can_change_groups(self, REQUEST, formsemestre_id):
H.append( H.append(
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>' '<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
% formsemestre_id % formsemestre_id
@ -1161,88 +1161,6 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
logdb(REQUEST, cnx, method="changeCoordonnees", etudid=etudid) logdb(REQUEST, cnx, method="changeCoordonnees", etudid=etudid)
REQUEST.RESPONSE.redirect("ficheEtud?etudid=" + etudid) REQUEST.RESPONSE.redirect("ficheEtud?etudid=" + etudid)
security.declareProtected(ScoView, "formChangeGroup")
def formChangeGroup(self, formsemestre_id, etudid, REQUEST):
"changement groupe etudiant dans semestre"
if not self.Notes.can_change_groups(REQUEST, formsemestre_id):
raise ScoValueError(
"Vous n'avez pas le droit d'effectuer cette opération !"
)
cnx = self.GetDBConnexion()
etud = self.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
sem = sco_formsemestre.do_formsemestre_list(self, formsemestre_id)
ins = self.Notes.do_formsemestre_inscription_list(
{"etudid": etudid, "formsemestre_id": formsemestre_id}
)[0]
#
# -- check lock
sem = sco_formsemestre.get_formsemestre(self, formsemestre_id)
if sem["etat"] != "1":
raise ScoValueError("Modification impossible: semestre verrouille")
#
etud["semtitre"] = sem["titremois"]
H = [
'<h2><font color="#FF0000">Changement de groupe de</font> %(nomprenom)s (semestre %(semtitre)s)</h2><p>'
% etud
]
header = self.sco_header(
REQUEST, page_title="Changement de groupe de %(nomprenom)s" % etud
)
# Liste des groupes existants
raise NotImplementedError # XXX utiliser form_group_choice ou supprimer completement ?
#
H.append("""<form action="doChangeGroup" method="get" name="cg">""")
H.append(
"""<input type="hidden" name="etudid" value="%s">
<input type="hidden" name="formsemestre_id" value="%s">
<p>
(attention, vérifier que les groupes sont compatibles, selon votre organisation)
</p>
<script type="text/javascript">
function tweakmenu( gname ) {
var gr = document.cg.newgroupname.value;
if (!gr) {
alert("nom de groupe vide !");
return false;
}
var menutd = document.getElementById(gname);
var newopt = document.createElement('option');
newopt.value = gr;
var textopt = document.createTextNode(gr);
newopt.appendChild(textopt);
menutd.appendChild(newopt);
var msg = document.getElementById("groupemsg");
msg.appendChild( document.createTextNode("groupe " + gr + " créé; ") );
document.cg.newgroupname.value = "";
}
</script>
<p>Créer un nouveau groupe:
<input type="text" id="newgroupname" size="8"/>
<input type="button" onClick="tweakmenu( 'groupetd' );" value="créer groupe de %s"/>
<input type="button" onClick="tweakmenu( 'groupeanglais' );" value="créer groupe de %s"/>
<input type="button" onClick="tweakmenu( 'groupetp' );" value="créer groupe de %s"/>
</p>
<p id="groupemsg" style="font-style: italic;"></p>
<input type="submit" value="Changer de groupe">
<input type="button" value="Annuler" onClick="window.location='%s'">
</form>"""
% (
etudid,
formsemestre_id,
sem["nomgroupetd"],
sem["nomgroupeta"],
sem["nomgroupetp"],
REQUEST.URL1,
)
)
return header + "\n".join(H) + self.sco_footer(REQUEST)
# --- Gestion des groupes: # --- Gestion des groupes:
security.declareProtected(ScoView, "affectGroups") security.declareProtected(ScoView, "affectGroups")
affectGroups = sco_groups_edit.affectGroups affectGroups = sco_groups_edit.affectGroups

View File

@ -9,6 +9,7 @@
# E. Viennet, Juin 2008 # E. Viennet, Juin 2008
# #
set -euo pipefail
source config.sh source config.sh
source utils.sh source utils.sh

View File

@ -4,11 +4,11 @@
# ScoDoc: suppression d'un departement # ScoDoc: suppression d'un departement
# #
# Ce script supprime la base de donnees ScoDoc d'un departement # Ce script supprime la base de donnees ScoDoc d'un departement
# *** le departement doit au prealable avoir <EFBFBD>t<EFBFBD> supprime via l'interface web ! *** # *** le departement doit au prealable avoir été supprime via l'interface web ! ***
# #
# Ne fonctionne que pour les configurations "standards" (dbname=xxx) # Ne fonctionne que pour les configurations "standards" (dbname=xxx)
# #
# Il doit <EFBFBD>tre lanc<6E> par l'utilisateur unix root dans le repertoire .../config # Il doit être lancé par l'utilisateur unix root dans le repertoire .../config
# ^^^^^^^^^^^^^^^^^^^^^ # ^^^^^^^^^^^^^^^^^^^^^
# E. Viennet, Sept 2008 # E. Viennet, Sept 2008
# #
@ -17,7 +17,7 @@
source config.sh source config.sh
source utils.sh source utils.sh
check_uid_root $0 check_uid_root "$0"
usage() { usage() {
echo "$0 [-n DEPT]" echo "$0 [-n DEPT]"
echo "(default to interactive mode)" echo "(default to interactive mode)"
@ -60,10 +60,15 @@ then
# suppression de la base postgres # suppression de la base postgres
db_name=$(sed '/^dbname=*/!d; s///;q' < "$cfg_pathname") db_name=$(sed '/^dbname=*/!d; s///;q' < "$cfg_pathname")
echo "suppression de la base postgres $db_name" if su -c "psql -lt" "$POSTGRES_SUPERUSER" | cut -d \| -f 1 | grep -wq SCORT
su -c "dropdb $db_name" "$POSTGRES_SUPERUSER" || terminate "ne peux supprimer base de donnees $db_name" then
echo "Suppression de la base postgres $db_name ..."
su -c "dropdb $db_name" "$POSTGRES_SUPERUSER" || terminate "ne peux supprimer base de donnees $db_name"
else
echo "la base postgres $db_name n'existe pas."
fi
# suppression du fichier de config # suppression du fichier de config
/bin/rm -f "$cfg_pathname" || terminate "ne peux supprimer $cfg_pathname" /bin/rm -f "$cfg_pathname" || terminate "Ne peux supprimer $cfg_pathname"
# relance ScoDoc # relance ScoDoc
if [ "$interactive" = 1 ] if [ "$interactive" = 1 ]
then then
@ -76,6 +81,7 @@ then
fi fi
exit 0 exit 0
else else
echo 'Erreur: pas de configuration trouvee pour "'"$DEPT"'"' echo 'Attention: pas de configuration trouvee pour "'"$DEPT"'"'
exit 1 echo " => ne fait rien."
exit 0
fi fi

View File

@ -28,6 +28,8 @@
"""Various HTML generation functions """Various HTML generation functions
""" """
import listhistogram
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
@ -42,9 +44,6 @@ def horizontal_bargraph(value, mark):
return tmpl % {"value": int(value), "mark": int(mark)} return tmpl % {"value": int(value), "mark": int(mark)}
import listhistogram
def histogram_notes(notes): def histogram_notes(notes):
"HTML code drawing histogram" "HTML code drawing histogram"
if not notes: if not notes:
@ -70,3 +69,56 @@ def histogram_notes(notes):
) )
D.append("</ul></li></ul>") D.append("</ul></li></ul>")
return "\n".join(D) return "\n".join(D)
def make_menu(title, items, css_class="", base_url="", alone=False):
"""HTML snippet to render a simple drop down menu.
items is a list of dicts:
{ 'title' :
'url' :
'id' :
'attr' : "" # optionnal html <a> attributes
'enabled' : # True by default
'helpmsg' :
'submenu' : [ list of sub-items ]
}
"""
def gen_menu_items(items):
H.append("<ul>")
for item in items:
if not item.get("enabled", True):
cls = ' class="ui-state-disabled"'
else:
cls = ""
the_id = item.get("id", "")
if the_id:
li_id = 'id="%s" ' % the_id
else:
li_id = ""
if base_url and "url" in item:
item["urlq"] = base_url + item["url"]
else:
item["urlq"] = item.get("url", "#")
item["attr"] = item.get("attr", "")
submenu = item.get("submenu", None)
H.append(
"<li "
+ li_id
+ cls
+ '><a href="%(urlq)s" %(attr)s>%(title)s</a>' % item
)
if submenu:
gen_menu_items(submenu)
H.append("</li>")
H.append("</ul>")
H = []
if alone:
H.append('<ul class="sco_dropdown_menu %s">' % css_class)
H.append("""<li><a href="#">%s</a>""" % title)
gen_menu_items(items)
H.append("</li>")
if alone:
H.append("</ul>")
return "".join(H)

View File

@ -41,7 +41,8 @@ from sco_parcours_dut import formsemestre_get_etud_capitalisation
from sco_parcours_dut import list_formsemestre_utilisateurs_uecap from sco_parcours_dut import list_formsemestre_utilisateurs_uecap
import sco_parcours_dut import sco_parcours_dut
import sco_formsemestre import sco_formsemestre
from sco_formsemestre_edit import formsemestre_uecoef_list, formsemestre_uecoef_create from sco_formsemestre import formsemestre_uecoef_list, formsemestre_uecoef_create
import sco_moduleimpl
import sco_evaluations import sco_evaluations
import sco_compute_moy import sco_compute_moy
from sco_formulas import NoteVector from sco_formulas import NoteVector
@ -85,7 +86,9 @@ def get_sem_ues_modimpls(context, formsemestre_id, modimpls=None):
(utilisé quand on ne peut pas construire nt et faire nt.get_ues()) (utilisé quand on ne peut pas construire nt et faire nt.get_ues())
""" """
if modimpls is None: if modimpls is None:
modimpls = context.do_moduleimpl_list(formsemestre_id=formsemestre_id) modimpls = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
)
uedict = {} uedict = {}
for modimpl in modimpls: for modimpl in modimpls:
mod = context.do_module_list(args={"module_id": modimpl["module_id"]})[0] mod = context.do_module_list(args={"module_id": modimpl["module_id"]})[0]

View File

@ -43,6 +43,11 @@ import sco_formsemestre
import sco_compute_moy import sco_compute_moy
def is_work_saturday(context):
"Vrai si le samedi est travaillé"
return int(context.get_preference("work_saturday"))
def MonthNbDays(month, year): def MonthNbDays(month, year):
"returns nb of days in month" "returns nb of days in month"
if month > 7: if month > 7:
@ -173,6 +178,39 @@ class ddmmyyyy:
# d = ddmmyyyy( '21/12/99' ) # d = ddmmyyyy( '21/12/99' )
def DateRangeISO(context, date_beg, date_end, workable=1):
"""returns list of dates in [date_beg,date_end]
workable = 1 => keeps only workable days"""
if not date_beg:
raise ScoValueError("pas de date spécifiée !")
if not date_end:
date_end = date_beg
r = []
work_saturday = is_work_saturday(context)
cur = ddmmyyyy(date_beg, work_saturday=work_saturday)
end = ddmmyyyy(date_end, work_saturday=work_saturday)
while cur <= end:
if (not workable) or cur.iswork():
r.append(cur)
cur = cur.next()
return map(lambda x: x.ISO(), r)
def day_names(context):
"""Returns week day names.
If work_saturday property is set, include saturday
"""
if is_work_saturday(context):
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
else:
return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]
def next_iso_day(context, date):
"return date after date"
d = ddmmyyyy(date, fmt="iso", work_saturday=is_work_saturday(context))
return d.next().ISO()
def YearTable( def YearTable(
@ -207,7 +245,7 @@ def YearTable(
events, events,
halfday, halfday,
dayattributes, dayattributes,
context.is_work_saturday(), is_work_saturday(context),
pad_width=pad_width, pad_width=pad_width,
) )
) )

View File

@ -28,16 +28,21 @@
"""Pages HTML gestion absences """Pages HTML gestion absences
(la plupart portées du DTML) (la plupart portées du DTML)
""" """
import datetime
from stripogram import html2text, html2safehtml from stripogram import html2text, html2safehtml
from gen_tables import GenTable from gen_tables import GenTable
from notesdb import * from notesdb import DateISOtoDMY
from sco_utils import * import sco_utils as scu
from sco_exceptions import ScoValueError
from sco_permissions import ScoAbsChange
from notes_log import log from notes_log import log
import sco_groups import sco_groups
import sco_find_etud import sco_find_etud
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_photos import sco_photos
import sco_abs import sco_abs
@ -58,7 +63,7 @@ def doSignaleAbsence(
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
dates = context.DateRangeISO(datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0 nbadded = 0
for jour in dates: for jour in dates:
if demijournee == "2": if demijournee == "2":
@ -82,7 +87,7 @@ def doSignaleAbsence(
J = "NON " J = "NON "
M = "" M = ""
if moduleimpl_id and moduleimpl_id != "NULL": if moduleimpl_id and moduleimpl_id != "NULL":
mod = context.Notes.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = mod["formsemestre_id"] formsemestre_id = mod["formsemestre_id"]
nt = context.Notes._getNotesCache().get_NotesTable( nt = context.Notes._getNotesCache().get_NotesTable(
context.Notes, formsemestre_id context.Notes, formsemestre_id
@ -248,7 +253,7 @@ def doJustifAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
dates = context.DateRangeISO(datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0 nbadded = 0
for jour in dates: for jour in dates:
if demijournee == "2": if demijournee == "2":
@ -371,7 +376,7 @@ def doAnnuleAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
dates = context.DateRangeISO(datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0 nbadded = 0
for jour in dates: for jour in dates:
if demijournee == "2": if demijournee == "2":
@ -506,7 +511,7 @@ def doAnnuleJustif(
"""Annulation d'une justification""" """Annulation d'une justification"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
dates = context.DateRangeISO(datedebut0, datefin0) dates = sco_abs.DateRangeISO(context, datedebut0, datefin0)
nbadded = 0 nbadded = 0
for jour in dates: for jour in dates:
# Attention: supprime matin et après-midi # Attention: supprime matin et après-midi
@ -571,7 +576,7 @@ def EtatAbsences(context, REQUEST=None):
</td></tr></table> </td></tr></table>
</form>""" </form>"""
% (AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")), % (scu.AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
context.sco_footer(REQUEST), context.sco_footer(REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -610,7 +615,7 @@ def CalAbs(context, REQUEST=None): # etud implied
# crude portage from 1999 DTML # crude portage from 1999 DTML
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
anneescolaire = int(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 = context.CountAbs(etudid=etudid, debut=datedebut, fin=datefin)
@ -693,7 +698,7 @@ def ListeAbsEtud(
En format 'text': texte avec liste d'absences (pour mails). En format 'text': texte avec liste d'absences (pour mails).
""" """
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" % AnneeScolaire(REQUEST) datedebut = "%s-08-31" % scu.AnneeScolaire(REQUEST)
etud = context.getEtudInfo(etudid=etudid, filled=True)[0] etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
@ -714,7 +719,7 @@ def ListeAbsEtud(
html_class="table_leftalign", html_class="table_leftalign",
table_id="tab_absnonjust", table_id="tab_absnonjust",
base_url=base_url_nj, base_url=base_url_nj,
filename="abs_" + make_filename(etud["nomprenom"]), filename="abs_" + scu.make_filename(etud["nomprenom"]),
caption="Absences non justifiées de %(nomprenom)s" % etud, caption="Absences non justifiées de %(nomprenom)s" % etud,
preferences=context.get_preferences(), preferences=context.get_preferences(),
) )
@ -725,7 +730,7 @@ def ListeAbsEtud(
html_class="table_leftalign", html_class="table_leftalign",
table_id="tab_absjust", table_id="tab_absjust",
base_url=base_url_j, base_url=base_url_j,
filename="absjust_" + make_filename(etud["nomprenom"]), filename="absjust_" + scu.make_filename(etud["nomprenom"]),
caption="Absences justifiées de %(nomprenom)s" % etud, caption="Absences justifiées de %(nomprenom)s" % etud,
preferences=context.get_preferences(), preferences=context.get_preferences(),
) )
@ -830,7 +835,7 @@ def absences_index_html(context, REQUEST=None):
% REQUEST.URL0, % REQUEST.URL0,
formChoixSemestreGroupe(context), formChoixSemestreGroupe(context),
"</p>", "</p>",
context.CalSelectWeek(REQUEST=REQUEST), cal_select_week(context, REQUEST=REQUEST),
"""<p class="help">Sélectionner le groupe d'étudiants, puis cliquez sur une semaine pour """<p class="help">Sélectionner le groupe d'étudiants, puis cliquez sur une semaine pour
saisir les absences de toute cette semaine.</p> saisir les absences de toute cette semaine.</p>
</form>""", </form>""",
@ -843,3 +848,16 @@ saisir les absences de toute cette semaine.</p>
H.append(context.sco_footer(REQUEST)) H.append(context.sco_footer(REQUEST))
return "\n".join(H) return "\n".join(H)
def cal_select_week(context, year=None, REQUEST=None):
"display calendar allowing week selection"
if not year:
year = scu.AnneeScolaire(REQUEST)
sems = sco_formsemestre.do_formsemestre_list(context)
if not sems:
js = ""
else:
js = 'onmouseover="highlightweek(this);" onmouseout="deselectweeks();" onclick="wclick(this);"'
C = sco_abs.YearTable(context, int(year), dayattributes=js)
return C

View File

@ -34,11 +34,12 @@ from email.mime.text import MIMEText
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
from email.header import Header from email.header import Header
import htmlutils, time import time
from reportlab.lib.colors import Color from reportlab.lib.colors import Color
from sco_utils import * from sco_utils import *
from notes_table import * from notes_table import *
import htmlutils
import sco_formsemestre import sco_formsemestre
import sco_groups import sco_groups
import sco_pvjury import sco_pvjury
@ -1146,7 +1147,7 @@ def _formsemestre_bulletinetud_header_html(
] ]
H.append("""<td class="bulletin_menubar"><div class="bulletin_menubar">""") H.append("""<td class="bulletin_menubar"><div class="bulletin_menubar">""")
H.append(sco_formsemestre_status.makeMenu("Autres opérations", menuBul, alone=True)) H.append(htmlutils.make_menu("Autres opérations", menuBul, alone=True))
H.append("""</div></td>""") H.append("""</div></td>""")
H.append( H.append(
'<td> <a href="%s">%s</a></td>' '<td> <a href="%s">%s</a></td>'

View File

@ -29,14 +29,24 @@
""" """
import traceback import traceback
import pprint
from types import FloatType
from sco_utils import * import sco_utils as scu
from notesdb import * from sco_utils import (
NOTES_ATTENTE,
NOTES_NEUTRALISE,
EVALUATION_NORMALE,
EVALUATION_RATTRAPAGE,
)
from sco_exceptions import ScoException
from notesdb import EditableTable, quote_html
from notes_log import log, sendAlarm from notes_log import log, sendAlarm
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_evaluations import sco_evaluations
from sco_formulas import * import sco_formulas
import sco_abs import sco_abs
@ -67,7 +77,9 @@ def formsemestre_expressions_use_abscounts(context, formsemestre_id):
if expr and expr[0] != "#" and ab in expr: if expr and expr[0] != "#" and ab in expr:
return True return True
# 2- moyennes de modules # 2- moyennes de modules
for mod in context.Notes.do_moduleimpl_list(formsemestre_id=formsemestre_id): for mod in sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
):
if moduleimpl_has_expression(context, mod) and ab in mod["computation_expr"]: if moduleimpl_has_expression(context, mod) and ab in mod["computation_expr"]:
return True return True
return False return False
@ -148,7 +160,7 @@ def compute_user_formula(
try: try:
formula = formula.replace("\n", "").replace("\r", "") formula = formula.replace("\n", "").replace("\r", "")
# log('expression : %s\nvariables=%s\n' % (formula, variables)) # XXX debug # log('expression : %s\nvariables=%s\n' % (formula, variables)) # XXX debug
user_moy = eval_user_expression(context, formula, variables) user_moy = sco_formulas.eval_user_expression(context, formula, variables)
# log('user_moy=%s' % user_moy) # log('user_moy=%s' % user_moy)
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)
@ -188,10 +200,10 @@ def do_moduleimpl_moyennes(context, nt, mod):
""" """
diag_info = {} # message d'erreur formule diag_info = {} # message d'erreur formule
moduleimpl_id = mod["moduleimpl_id"] moduleimpl_id = mod["moduleimpl_id"]
is_malus = mod["module"]["module_type"] == MODULE_MALUS is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS
sem = sco_formsemestre.get_formsemestre(context, mod["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, mod["formsemestre_id"])
etudids = context.do_moduleimpl_listeetuds( etudids = sco_moduleimpl.do_moduleimpl_listeetuds(
moduleimpl_id context, moduleimpl_id
) # tous, y compris demissions ) # tous, y compris demissions
# Inscrits au semestre (pour traiter les demissions): # Inscrits au semestre (pour traiter les demissions):
inssem_set = set( inssem_set = set(
@ -256,7 +268,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
] ]
# #
R = {} R = {}
formula = unescape_html(mod["computation_expr"]) formula = scu.unescape_html(mod["computation_expr"])
formula_use_abs = "abs" in formula formula_use_abs = "abs" in formula
for etudid in insmod_set: # inscrits au semestre et au module for etudid in insmod_set: # inscrits au semestre et au module
@ -353,12 +365,14 @@ def do_formsemestre_moyennes(context, nt, formsemestre_id):
la liste des moduleimpls, la liste des evaluations valides, la liste des moduleimpls, la liste des evaluations valides,
liste des moduleimpls avec notes en attente. liste des moduleimpls avec notes en attente.
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) # sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
inscr = context.do_formsemestre_inscription_list( # inscr = context.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} # args={"formsemestre_id": formsemestre_id}
# )
# etudids = [x["etudid"] for x in inscr]
modimpls = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
) )
etudids = [x["etudid"] for x in inscr]
modimpls = context.do_moduleimpl_list(formsemestre_id=formsemestre_id)
# recupere les moyennes des etudiants de tous les modules # recupere les moyennes des etudiants de tous les modules
D = {} D = {}
valid_evals = [] valid_evals = []

View File

@ -37,6 +37,7 @@ from gen_tables import GenTable
import sco_excel, sco_pdf import sco_excel, sco_pdf
from sco_pdf import SU from sco_pdf import SU
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_formsemestre_status import sco_formsemestre_status
@ -60,7 +61,9 @@ def formsemestre_table_estim_cost(
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
sco_formsemestre_status.fill_formsemestre(context, sem, REQUEST=REQUEST) sco_formsemestre_status.fill_formsemestre(context, sem, REQUEST=REQUEST)
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
T = [] T = []
for M in Mlist: for M in Mlist:
Mod = M["module"] Mod = M["module"]

326
sco_entreprises.py Normal file
View File

@ -0,0 +1,326 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Fonctions sur les entreprises
"""
# codes anciens déplacés de ZEntreprise
import datetime
import sco_utils as scu
from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO
def _format_nom(nom):
"formatte nom (filtre en entree db) d'une entreprise"
if not nom:
return nom
nom = nom.decode(scu.SCO_ENCODING)
return (nom[0].upper() + nom[1:]).encode(scu.SCO_ENCODING)
class EntreprisesEditor(EditableTable):
def delete(self, cnx, oid):
"delete correspondants and contacts, then self"
# first, delete all correspondants and contacts
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(
"delete from entreprise_contact where entreprise_id=%(entreprise_id)s",
{"entreprise_id": oid},
)
cursor.execute(
"delete from entreprise_correspondant where entreprise_id=%(entreprise_id)s",
{"entreprise_id": oid},
)
cnx.commit()
EditableTable.delete(self, cnx, oid)
def list(
self,
cnx,
args={},
operator="and",
test="=",
sortkey=None,
sort_on_contact=False,
context=None,
limit="",
offset="",
):
# list, then sort on date of last contact
R = EditableTable.list(
self,
cnx,
args=args,
operator=operator,
test=test,
sortkey=sortkey,
limit=limit,
offset=offset,
)
if sort_on_contact:
for r in R:
c = do_entreprise_contact_list(
context,
args={"entreprise_id": r["entreprise_id"]},
disable_formatting=True,
)
if c:
r["date"] = max([x["date"] or datetime.date.min for x in c])
else:
r["date"] = datetime.date.min
# sort
R.sort(lambda r1, r2: cmp(r2["date"], r1["date"]))
for r in R:
r["date"] = DateISOtoDMY(r["date"])
return R
def list_by_etud(
self, cnx, args={}, sort_on_contact=False, disable_formatting=False
):
"cherche rentreprise ayant eu contact avec etudiant"
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(
"select E.*, I.nom as etud_nom, I.prenom as etud_prenom, C.date from entreprises E, entreprise_contact C, identite I where C.entreprise_id = E.entreprise_id and C.etudid = I.etudid and I.nom ~* %(etud_nom)s ORDER BY E.nom",
args,
)
_, res = [x[0] for x in cursor.description], cursor.dictfetchall()
R = []
for r in res:
r["etud_prenom"] = r["etud_prenom"] or ""
d = {}
for key in r:
v = r[key]
# format value
if not disable_formatting and self.output_formators.has_key(key):
v = self.output_formators[key](v)
d[key] = v
R.append(d)
# sort
if sort_on_contact:
R.sort(
lambda r1, r2: cmp(
r2["date"] or datetime.date.min, r1["date"] or datetime.date.min
)
)
for r in R:
r["date"] = DateISOtoDMY(r["date"] or datetime.date.min)
return R
_entreprisesEditor = EntreprisesEditor(
"entreprises",
"entreprise_id",
(
"entreprise_id",
"nom",
"adresse",
"ville",
"codepostal",
"pays",
"contact_origine",
"secteur",
"privee",
"localisation",
"qualite_relation",
"plus10salaries",
"note",
"date_creation",
),
sortkey="nom",
input_formators={"nom": _format_nom},
)
# ----------- Correspondants
_entreprise_correspEditor = EditableTable(
"entreprise_correspondant",
"entreprise_corresp_id",
(
"entreprise_corresp_id",
"entreprise_id",
"civilite",
"nom",
"prenom",
"fonction",
"phone1",
"phone2",
"mobile",
"fax",
"mail1",
"mail2",
"note",
),
sortkey="nom",
)
# ----------- Contacts
_entreprise_contactEditor = EditableTable(
"entreprise_contact",
"entreprise_contact_id",
(
"entreprise_contact_id",
"date",
"type_contact",
"entreprise_id",
"entreprise_corresp_id",
"etudid",
"description",
"enseignant",
),
sortkey="date",
output_formators={"date": DateISOtoDMY},
input_formators={"date": DateDMYtoISO},
)
def do_entreprise_create(context, args):
"entreprise_create"
cnx = context.GetDBConnexion()
r = _entreprisesEditor.create(cnx, args)
return r
def do_entreprise_delete(context, oid):
"entreprise_delete"
cnx = context.GetDBConnexion()
_entreprisesEditor.delete(cnx, oid)
def do_entreprise_list(context, **kw):
"entreprise_list"
cnx = context.GetDBConnexion()
kw["context"] = context
return _entreprisesEditor.list(cnx, **kw)
def do_entreprise_list_by_etud(context, **kw):
"entreprise_list_by_etud"
cnx = context.GetDBConnexion()
return _entreprisesEditor.list_by_etud(cnx, **kw)
def do_entreprise_edit(context, *args, **kw):
"entreprise_edit"
cnx = context.GetDBConnexion()
_entreprisesEditor.edit(cnx, *args, **kw)
def do_entreprise_correspondant_create(context, args):
"entreprise_correspondant_create"
cnx = context.GetDBConnexion()
r = _entreprise_correspEditor.create(cnx, args)
return r
def do_entreprise_correspondant_delete(context, oid):
"entreprise_correspondant_delete"
cnx = context.GetDBConnexion()
_entreprise_correspEditor.delete(cnx, oid)
def do_entreprise_correspondant_list(context, **kw):
"entreprise_correspondant_list"
cnx = context.GetDBConnexion()
return _entreprise_correspEditor.list(cnx, **kw)
def do_entreprise_correspondant_edit(context, *args, **kw):
"entreprise_correspondant_edit"
cnx = context.GetDBConnexion()
_entreprise_correspEditor.edit(cnx, *args, **kw)
def do_entreprise_correspondant_listnames(context, args={}):
"-> liste des noms des correspondants (pour affichage menu)"
C = do_entreprise_correspondant_list(context, args=args)
return [(x["prenom"] + " " + x["nom"], str(x["entreprise_corresp_id"])) for x in C]
def do_entreprise_contact_delete(context, oid):
"entreprise_contact_delete"
cnx = context.GetDBConnexion()
_entreprise_contactEditor.delete(cnx, oid)
def do_entreprise_contact_list(context, **kw):
"entreprise_contact_list"
cnx = context.GetDBConnexion()
return _entreprise_contactEditor.list(cnx, **kw)
def do_entreprise_contact_edit(context, *args, **kw):
"entreprise_contact_edit"
cnx = context.GetDBConnexion()
_entreprise_contactEditor.edit(cnx, *args, **kw)
def do_entreprise_contact_create(context, args):
"entreprise_contact_create"
cnx = context.GetDBConnexion()
r = _entreprise_contactEditor.create(cnx, args)
return r
def do_entreprise_check_etudiant(context, etudiant):
"""Si etudiant est vide, ou un ETUDID valide, ou un nom unique,
retourne (1, ETUDID).
Sinon, retourne (0, 'message explicatif')
"""
etudiant = etudiant.strip().translate(
None, "'()"
) # suppress parens and quote from name
if not etudiant:
return 1, None
cnx = context.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(
"select etudid, nom, prenom from identite where upper(nom) ~ upper(%(etudiant)s) or etudid=%(etudiant)s",
{"etudiant": etudiant},
)
r = cursor.fetchall()
if len(r) < 1:
return 0, 'Aucun etudiant ne correspond à "%s"' % etudiant
elif len(r) > 10:
return (
0,
"<b>%d etudiants</b> correspondent à ce nom (utilisez le code)" % len(r),
)
elif len(r) > 1:
e = ['<ul class="entreprise_etud_list">']
for x in r:
e.append(
"<li>%s %s (code %s)</li>"
% (scu.strupper(x[1]), x[2] or "", x[0].strip())
)
e.append("</ul>")
return (
0,
"Les étudiants suivants correspondent: préciser le nom complet ou le code\n"
+ "\n".join(e),
)
else: # une seule reponse !
return 1, r[0][0].strip()

View File

@ -41,9 +41,11 @@ from gen_tables import GenTable
from TrivialFormulator import TrivialFormulator from TrivialFormulator import TrivialFormulator
import sco_news import sco_news
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_abs import sco_abs
import sco_evaluations import sco_evaluations
import sco_saisie_notes
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# #
@ -101,7 +103,7 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
context._evaluationEditor.delete(cnx, evaluation_id) context._evaluationEditor.delete(cnx, evaluation_id)
# inval cache pour ce semestre # inval cache pour ce semestre
M = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
context._inval_cache(formsemestre_id=M["formsemestre_id"]) # > eval delete context._inval_cache(formsemestre_id=M["formsemestre_id"]) # > eval delete
# news # news
mod = context.do_module_list(args={"module_id": M["module_id"]})[0] mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
@ -165,7 +167,7 @@ def do_evaluation_etat(
last_modif = None last_modif = None
# ---- Liste des groupes complets et incomplets # ---- Liste des groupes complets et incomplets
E = context.do_evaluation_list(args={"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list(args={"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
is_malus = Mod["module_type"] == scu.MODULE_MALUS # True si module de malus is_malus = Mod["module_type"] == scu.MODULE_MALUS # True si module de malus
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
@ -182,7 +184,9 @@ def do_evaluation_etat(
# (pour avoir l'etat et le groupe) et aussi les inscriptions # (pour avoir l'etat et le groupe) et aussi les inscriptions
# au module (pour gerer les modules optionnels correctement) # au module (pour gerer les modules optionnels correctement)
insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id) insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"]) insmod = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=E["moduleimpl_id"]
)
insmodset = set([x["etudid"] for x in insmod]) insmodset = set([x["etudid"] for x in insmod])
# retire de insem ceux qui ne sont pas inscrits au module # retire de insem ceux qui ne sont pas inscrits au module
ins = [i for i in insem if i["etudid"] in insmodset] ins = [i for i in insem if i["etudid"] in insmodset]
@ -451,7 +455,9 @@ def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None):
if not e["jour"]: if not e["jour"]:
continue continue
day = e["jour"].strftime("%Y-%m-%d") day = e["jour"].strftime("%Y-%m-%d")
mod = context.do_moduleimpl_withmodule_list(moduleimpl_id=e["moduleimpl_id"])[0] mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=e["moduleimpl_id"]
)[0]
txt = mod["module"]["code"] or mod["module"]["abbrev"] or "eval" txt = mod["module"]["code"] or mod["module"]["abbrev"] or "eval"
if e["heure_debut"]: if e["heure_debut"]:
debut = e["heure_debut"].strftime("%Hh%M") debut = e["heure_debut"].strftime("%Hh%M")
@ -524,10 +530,10 @@ def evaluation_date_first_completion(context, evaluation_id):
# (pour avoir l'etat et le groupe) et aussi les inscriptions # (pour avoir l'etat et le groupe) et aussi les inscriptions
# au module (pour gerer les modules optionnels correctement) # au module (pour gerer les modules optionnels correctement)
# E = context.do_evaluation_list(args={"evaluation_id": evaluation_id})[0] # E = context.do_evaluation_list(args={"evaluation_id": evaluation_id})[0]
# M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] # M = sco_moduleimpl.do_moduleimpl_list(context,moduleimpl_id=E["moduleimpl_id"])[0]
# formsemestre_id = M["formsemestre_id"] # formsemestre_id = M["formsemestre_id"]
# insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id) # insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
# insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"]) # insmod = sco_moduleimpl.do_moduleimpl_inscription_list(context,moduleimpl_id=E["moduleimpl_id"])
# insmodset = set([x["etudid"] for x in insmod]) # insmodset = set([x["etudid"] for x in insmod])
# retire de insem ceux qui ne sont pas inscrits au module # retire de insem ceux qui ne sont pas inscrits au module
# ins = [i for i in insem if i["etudid"] in insmodset] # ins = [i for i in insem if i["etudid"] in insmodset]
@ -566,7 +572,9 @@ def formsemestre_evaluations_delai_correction(
evals = nt.get_sem_evaluation_etat_list() evals = nt.get_sem_evaluation_etat_list()
T = [] T = []
for e in evals: for e in evals:
M = context.do_moduleimpl_list(moduleimpl_id=e["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=e["moduleimpl_id"]
)[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
if (e["evaluation_type"] != scu.EVALUATION_NORMALE) or ( if (e["evaluation_type"] != scu.EVALUATION_NORMALE) or (
Mod["module_type"] == scu.MODULE_MALUS Mod["module_type"] == scu.MODULE_MALUS
@ -732,14 +740,14 @@ def evaluation_describe(context, evaluation_id="", edit_in_place=True, REQUEST=N
""" """
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
moduleimpl_id = E["moduleimpl_id"] moduleimpl_id = E["moduleimpl_id"]
M = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
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 = context.can_edit_notes( can_edit = sco_saisie_notes.can_edit_notes(
REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False context, REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False
) )
link = ( link = (
@ -810,7 +818,9 @@ def evaluation_create_form(
the_eval = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] the_eval = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
moduleimpl_id = the_eval["moduleimpl_id"] moduleimpl_id = the_eval["moduleimpl_id"]
# #
M = context.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=moduleimpl_id
)[0]
is_malus = M["module"]["module_type"] == scu.MODULE_MALUS # True si module de malus is_malus = M["module"]["module_type"] == scu.MODULE_MALUS # True si module de malus
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible

View File

@ -241,6 +241,53 @@ def write_formsemestre_responsables(context, sem):
return _write_formsemestre_aux(context, sem, "responsables", "responsable_id") return _write_formsemestre_aux(context, sem, "responsables", "responsable_id")
# ---------------------- Coefs des UE
_formsemestre_uecoef_editor = EditableTable(
"notes_formsemestre_uecoef",
"formsemestre_uecoef_id",
("formsemestre_uecoef_id", "formsemestre_id", "ue_id", "coefficient"),
)
formsemestre_uecoef_create = _formsemestre_uecoef_editor.create
formsemestre_uecoef_edit = _formsemestre_uecoef_editor.edit
formsemestre_uecoef_list = _formsemestre_uecoef_editor.list
formsemestre_uecoef_delete = _formsemestre_uecoef_editor.delete
def do_formsemestre_uecoef_edit_or_create(context, cnx, formsemestre_id, ue_id, coef):
"modify or create the coef"
coefs = formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue_id}
)
if coefs:
formsemestre_uecoef_edit(
cnx,
args={
"formsemestre_uecoef_id": coefs[0]["formsemestre_uecoef_id"],
"coefficient": coef,
},
)
else:
formsemestre_uecoef_create(
cnx,
args={
"formsemestre_id": formsemestre_id,
"ue_id": ue_id,
"coefficient": coef,
},
)
def do_formsemestre_uecoef_delete(context, cnx, formsemestre_id, ue_id):
"delete coef for this (ue,sem)"
coefs = formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue_id}
)
if coefs:
formsemestre_uecoef_delete(cnx, coefs[0]["formsemestre_uecoef_id"])
def read_formsemestre_etapes(context, formsemestre_id): def read_formsemestre_etapes(context, formsemestre_id):
"""recupere liste des codes etapes associés à ce semestre """recupere liste des codes etapes associés à ce semestre
:returns: liste d'instance de ApoEtapeVDI :returns: liste d'instance de ApoEtapeVDI

View File

@ -74,7 +74,7 @@ def formsemestre_custommenu_html(context, formsemestre_id, base_url=""):
+ formsemestre_id, + formsemestre_id,
} }
) )
return sco_formsemestre_status.makeMenu("Liens", menu) return sco_formsemestre_status.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

@ -41,6 +41,7 @@ import sco_codes_parcours
import sco_compute_moy import sco_compute_moy
import sco_modalites import sco_modalites
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
from sco_formsemestre import ApoEtapeVDI from sco_formsemestre import ApoEtapeVDI
@ -155,7 +156,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
# if REQUEST.form.get('tf-submitted',False) and not REQUEST.form.has_key('inscrire_etudslist'): # if REQUEST.form.get('tf-submitted',False) and not REQUEST.form.has_key('inscrire_etudslist'):
# REQUEST.form['inscrire_etudslist'] = [] # REQUEST.form['inscrire_etudslist'] = []
# add associated modules to tf-checked # add associated modules to tf-checked
ams = context.do_moduleimpl_list(formsemestre_id=formsemestre_id) ams = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
)
sem_module_ids = set([x["module_id"] for x in ams]) sem_module_ids = set([x["module_id"] for x in ams])
initvalues["tf-checked"] = [x["module_id"] for x in ams] initvalues["tf-checked"] = [x["module_id"] for x in ams]
for x in ams: for x in ams:
@ -706,7 +709,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": tf[2][module_id], "responsable_id": tf[2][module_id],
} }
mid = context.do_moduleimpl_create(modargs) mid = sco_moduleimpl.do_moduleimpl_create(context, modargs)
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"formsemestre_status?formsemestre_id=%s&amp;head_message=Nouveau%%20semestre%%20créé" "formsemestre_status?formsemestre_id=%s&amp;head_message=Nouveau%%20semestre%%20créé"
% formsemestre_id % formsemestre_id
@ -720,7 +723,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
# nouveaux modules # nouveaux modules
checkedmods = tf[2]["tf-checked"] checkedmods = tf[2]["tf-checked"]
sco_formsemestre.do_formsemestre_edit(context, tf[2]) sco_formsemestre.do_formsemestre_edit(context, tf[2])
ams = context.do_moduleimpl_list(formsemestre_id=formsemestre_id) ams = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
)
existingmods = [x["module_id"] for x in ams] existingmods = [x["module_id"] for x in ams]
mods_tocreate = [x for x in checkedmods if not x in existingmods] mods_tocreate = [x for x in checkedmods if not x in existingmods]
# modules a existants a modifier # modules a existants a modifier
@ -735,7 +740,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": tf[2][module_id], "responsable_id": tf[2][module_id],
} }
moduleimpl_id = context.do_moduleimpl_create(modargs) moduleimpl_id = sco_moduleimpl.do_moduleimpl_create(context, modargs)
mod = context.do_module_list({"module_id": module_id})[0] mod = context.do_module_list({"module_id": module_id})[0]
msg += ["création de %s (%s)" % (mod["code"], mod["titre"])] msg += ["création de %s (%s)" % (mod["code"], mod["titre"])]
# INSCRIPTIONS DES ETUDIANTS # INSCRIPTIONS DES ETUDIANTS
@ -771,8 +776,8 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
) )
msg += diag msg += diag
for module_id in mods_toedit: for module_id in mods_toedit:
moduleimpl_id = context.do_moduleimpl_list( moduleimpl_id = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=formsemestre_id, module_id=module_id context, formsemestre_id=formsemestre_id, module_id=module_id
)[0]["moduleimpl_id"] )[0]["moduleimpl_id"]
modargs = { modargs = {
"moduleimpl_id": moduleimpl_id, "moduleimpl_id": moduleimpl_id,
@ -780,7 +785,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": tf[2][module_id], "responsable_id": tf[2][module_id],
} }
context.do_moduleimpl_edit(modargs, formsemestre_id=formsemestre_id) sco_moduleimpl.do_moduleimpl_edit(
context, modargs, formsemestre_id=formsemestre_id
)
mod = context.do_module_list({"module_id": module_id})[0] mod = context.do_module_list({"module_id": module_id})[0]
if msg: if msg:
@ -814,8 +821,8 @@ def formsemestre_delete_moduleimpls(context, formsemestre_id, module_ids_to_del)
msg = [] msg = []
for module_id in module_ids_to_del: for module_id in module_ids_to_del:
# get id # get id
moduleimpl_id = context.do_moduleimpl_list( moduleimpl_id = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=formsemestre_id, module_id=module_id context, formsemestre_id=formsemestre_id, module_id=module_id
)[0]["moduleimpl_id"] )[0]["moduleimpl_id"]
mod = context.do_module_list({"module_id": module_id})[0] mod = context.do_module_list({"module_id": module_id})[0]
# Evaluations dans ce module ? # Evaluations dans ce module ?
@ -828,7 +835,9 @@ def formsemestre_delete_moduleimpls(context, formsemestre_id, module_ids_to_del)
ok = False ok = False
else: else:
msg += ["suppression de %s (%s)" % (mod["code"], mod["titre"])] msg += ["suppression de %s (%s)" % (mod["code"], mod["titre"])]
context.do_moduleimpl_delete(moduleimpl_id, formsemestre_id=formsemestre_id) sco_moduleimpl.do_moduleimpl_delete(
context, moduleimpl_id, formsemestre_id=formsemestre_id
)
return ok, msg return ok, msg
@ -984,17 +993,21 @@ def do_formsemestre_clone(
formsemestre_id = context.do_formsemestre_create(args, REQUEST) formsemestre_id = context.do_formsemestre_create(args, REQUEST)
log("created formsemestre %s" % formsemestre_id) log("created formsemestre %s" % formsemestre_id)
# 2- create moduleimpls # 2- create moduleimpls
mods_orig = context.do_moduleimpl_list(formsemestre_id=orig_formsemestre_id) mods_orig = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=orig_formsemestre_id
)
for mod_orig in mods_orig: for mod_orig in mods_orig:
args = mod_orig.copy() args = mod_orig.copy()
args["formsemestre_id"] = formsemestre_id args["formsemestre_id"] = formsemestre_id
mid = context.do_moduleimpl_create(args) mid = sco_moduleimpl.do_moduleimpl_create(context, args)
# copy notes_modules_enseignants # copy notes_modules_enseignants
ens = context.do_ens_list(args={"moduleimpl_id": mod_orig["moduleimpl_id"]}) ens = sco_moduleimpl.do_ens_list(
context, args={"moduleimpl_id": mod_orig["moduleimpl_id"]}
)
for e in ens: for e in ens:
args = e.copy() args = e.copy()
args["moduleimpl_id"] = mid args["moduleimpl_id"] = mid
context.do_ens_create(args) sco_moduleimpl.do_ens_create(context, args)
# optionally, copy evaluations # optionally, copy evaluations
if clone_evaluations: if clone_evaluations:
evals = context.do_evaluation_list( evals = context.do_evaluation_list(
@ -1007,11 +1020,13 @@ def do_formsemestre_clone(
evaluation_id = context.do_evaluation_create(REQUEST=REQUEST, **args) evaluation_id = context.do_evaluation_create(REQUEST=REQUEST, **args)
# 3- copy uecoefs # 3- copy uecoefs
objs = formsemestre_uecoef_list(cnx, args={"formsemestre_id": orig_formsemestre_id}) objs = sco_formsemestre.formsemestre_uecoef_list(
cnx, args={"formsemestre_id": orig_formsemestre_id}
)
for obj in objs: for obj in objs:
args = obj.copy() args = obj.copy()
args["formsemestre_id"] = formsemestre_id args["formsemestre_id"] = formsemestre_id
c = formsemestre_uecoef_create(cnx, args) c = sco_formsemestre.formsemestre_uecoef_create(cnx, args)
# NB: don't copy notes_formsemestre_custommenu (usually specific) # NB: don't copy notes_formsemestre_custommenu (usually specific)
@ -1177,7 +1192,9 @@ def _reassociate_moduleimpls(
et met à jour les décisions de jury (validations d'UE). et met à jour les décisions de jury (validations d'UE).
""" """
# re-associate moduleimpls to new modules: # re-associate moduleimpls to new modules:
modimpls = context.do_moduleimpl_list(formsemestre_id=formsemestre_id) modimpls = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id
)
for mod in modimpls: for mod in modimpls:
mod["module_id"] = modules_old2new[mod["module_id"]] mod["module_id"] = modules_old2new[mod["module_id"]]
context.do_moduleimpl_edit(mod, formsemestre_id=formsemestre_id, cnx=cnx) context.do_moduleimpl_edit(mod, formsemestre_id=formsemestre_id, cnx=cnx)
@ -1314,8 +1331,8 @@ def do_formsemestre_delete(context, formsemestre_id, REQUEST):
) )
context.get_evaluations_cache().inval_cache(key=e["evaluation_id"]) context.get_evaluations_cache().inval_cache(key=e["evaluation_id"])
context.do_moduleimpl_delete( sco_moduleimpl.do_moduleimpl_delete(
mod["moduleimpl_id"], formsemestre_id=formsemestre_id context, mod["moduleimpl_id"], formsemestre_id=formsemestre_id
) )
# --- Desinscription des etudiants # --- Desinscription des etudiants
cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor = cnx.cursor(cursor_factory=ScoDocCursor)
@ -1465,20 +1482,6 @@ def formsemestre_change_publication_bul(
) )
# ---------------------- Coefs des UE
_formsemestre_uecoef_editor = EditableTable(
"notes_formsemestre_uecoef",
"formsemestre_uecoef_id",
("formsemestre_uecoef_id", "formsemestre_id", "ue_id", "coefficient"),
)
formsemestre_uecoef_create = _formsemestre_uecoef_editor.create
formsemestre_uecoef_edit = _formsemestre_uecoef_editor.edit
formsemestre_uecoef_list = _formsemestre_uecoef_editor.list
formsemestre_uecoef_delete = _formsemestre_uecoef_editor.delete
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."""
context = context.Notes # si appele d'en haut, eg par exception ScoValueError context = context.Notes # si appele d'en haut, eg par exception ScoValueError
@ -1527,7 +1530,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
initvalues = {"formsemestre_id": formsemestre_id} initvalues = {"formsemestre_id": formsemestre_id}
form = [("formsemestre_id", {"input_type": "hidden"})] form = [("formsemestre_id", {"input_type": "hidden"})]
for ue in ues: for ue in ues:
coefs = formsemestre_uecoef_list( coefs = sco_formsemestre.formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]} cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]}
) )
if coefs: if coefs:
@ -1564,7 +1567,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
msg = [] msg = []
for ue in ues: for ue in ues:
val = tf[2]["ue_" + ue["ue_id"]] val = tf[2]["ue_" + ue["ue_id"]]
coefs = formsemestre_uecoef_list( coefs = sco_formsemestre.formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]} cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]}
) )
if val == "" or val == "auto": if val == "" or val == "auto":
@ -1594,11 +1597,13 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
# apply modifications # apply modifications
for ue in ue_modified: for ue in ue_modified:
do_formsemestre_uecoef_edit_or_create( sco_formsemestre.do_formsemestre_uecoef_edit_or_create(
context, cnx, formsemestre_id, ue["ue_id"], ue["coef"] context, cnx, formsemestre_id, ue["ue_id"], ue["coef"]
) )
for ue in ue_deleted: for ue in ue_deleted:
do_formsemestre_uecoef_delete(context, cnx, formsemestre_id, ue["ue_id"]) sco_formsemestre.do_formsemestre_uecoef_delete(
context, cnx, formsemestre_id, ue["ue_id"]
)
if ue_modified or ue_deleted: if ue_modified or ue_deleted:
z = ["""<h3>Modification effectuées</h3>"""] z = ["""<h3>Modification effectuées</h3>"""]
@ -1630,39 +1635,6 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
) )
def do_formsemestre_uecoef_edit_or_create(context, cnx, formsemestre_id, ue_id, coef):
"modify or create the coef"
coefs = formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue_id}
)
if coefs:
formsemestre_uecoef_edit(
cnx,
args={
"formsemestre_uecoef_id": coefs[0]["formsemestre_uecoef_id"],
"coefficient": coef,
},
)
else:
formsemestre_uecoef_create(
cnx,
args={
"formsemestre_id": formsemestre_id,
"ue_id": ue_id,
"coefficient": coef,
},
)
def do_formsemestre_uecoef_delete(context, cnx, formsemestre_id, ue_id):
"delete coef for this (ue,sem)"
coefs = formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue_id}
)
if coefs:
formsemestre_uecoef_delete(cnx, coefs[0]["formsemestre_uecoef_id"])
# ----- identification externe des sessions (pour SOJA et autres logiciels) # ----- identification externe des sessions (pour SOJA et autres logiciels)
def get_formsemestre_session_id(context, sem, F, parcours): def get_formsemestre_session_id(context, sem, F, parcours):
"""Identifiant de session pour ce semestre """Identifiant de session pour ce semestre

View File

@ -436,7 +436,7 @@ def _list_ue_with_coef_and_validations(context, sem, etudid):
ue_list = context.do_ue_list({"formation_id": sem["formation_id"]}) ue_list = context.do_ue_list({"formation_id": sem["formation_id"]})
for ue in ue_list: for ue in ue_list:
# add coefficient # add coefficient
uecoef = sco_formsemestre_edit.formsemestre_uecoef_list( uecoef = sco_formsemestre.formsemestre_uecoef_list(
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]} cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]}
) )
if uecoef: if uecoef:

View File

@ -37,6 +37,7 @@ from TrivialFormulator import TrivialFormulator, TF
# from notes_table import * # from notes_table import *
import sco_find_etud import sco_find_etud
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
@ -75,10 +76,13 @@ def do_formsemestre_inscription_with_modules(
gdone[group_id] = 1 gdone[group_id] = 1
# inscription a tous les modules de ce semestre # inscription a tous les modules de ce semestre
modimpls = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) modimpls = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
for mod in modimpls: for mod in modimpls:
if mod["ue"]["type"] != UE_SPORT: if mod["ue"]["type"] != UE_SPORT:
context.do_moduleimpl_inscription_create( sco_moduleimpl.do_moduleimpl_inscription_create(
context,
{"moduleimpl_id": mod["moduleimpl_id"], "etudid": etudid}, {"moduleimpl_id": mod["moduleimpl_id"], "etudid": etudid},
REQUEST=REQUEST, REQUEST=REQUEST,
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
@ -278,8 +282,10 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
] ]
# Cherche les moduleimpls et les inscriptions # Cherche les moduleimpls et les inscriptions
mods = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) mods = sco_moduleimpl.do_moduleimpl_withmodule_list(
inscr = context.do_moduleimpl_inscription_list(etudid=etudid) context, formsemestre_id=formsemestre_id
)
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(context, etudid=etudid)
# Formulaire # Formulaire
modimpls_by_ue_ids = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ] modimpls_by_ue_ids = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ]
modimpls_by_ue_names = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_name ] modimpls_by_ue_names = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_name ]
@ -502,13 +508,14 @@ def do_moduleimpl_incription_options(
# inscriptions # inscriptions
for moduleimpl_id in a_inscrire: for moduleimpl_id in a_inscrire:
# verifie que ce module existe bien # verifie que ce module existe bien
mods = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id) mods = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)
if len(mods) != 1: if len(mods) != 1:
raise ScoValueError( raise ScoValueError(
"inscription: invalid moduleimpl_id: %s" % moduleimpl_id "inscription: invalid moduleimpl_id: %s" % moduleimpl_id
) )
mod = mods[0] mod = mods[0]
context.do_moduleimpl_inscription_create( sco_moduleimpl.do_moduleimpl_inscription_create(
context,
{"moduleimpl_id": moduleimpl_id, "etudid": etudid}, {"moduleimpl_id": moduleimpl_id, "etudid": etudid},
REQUEST=REQUEST, REQUEST=REQUEST,
formsemestre_id=mod["formsemestre_id"], formsemestre_id=mod["formsemestre_id"],
@ -516,14 +523,14 @@ def do_moduleimpl_incription_options(
# desinscriptions # desinscriptions
for moduleimpl_id in a_desinscrire: for moduleimpl_id in a_desinscrire:
# verifie que ce module existe bien # verifie que ce module existe bien
mods = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id) mods = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)
if len(mods) != 1: if len(mods) != 1:
raise ScoValueError( raise ScoValueError(
"desinscription: invalid moduleimpl_id: %s" % moduleimpl_id "desinscription: invalid moduleimpl_id: %s" % moduleimpl_id
) )
mod = mods[0] mod = mods[0]
inscr = context.do_moduleimpl_inscription_list( inscr = sco_moduleimpl.do_moduleimpl_inscription_list(
moduleimpl_id=moduleimpl_id, etudid=etudid context, moduleimpl_id=moduleimpl_id, etudid=etudid
) )
if not inscr: if not inscr:
raise ScoValueError( raise ScoValueError(
@ -531,8 +538,8 @@ def do_moduleimpl_incription_options(
% (etudid, moduleimpl_id) % (etudid, moduleimpl_id)
) )
oid = inscr[0]["moduleimpl_inscription_id"] oid = inscr[0]["moduleimpl_inscription_id"]
context.do_moduleimpl_inscription_delete( sco_moduleimpl.do_moduleimpl_inscription_delete(
oid, formsemestre_id=mod["formsemestre_id"] context, oid, formsemestre_id=mod["formsemestre_id"]
) )
if REQUEST: if REQUEST:

View File

@ -31,9 +31,18 @@
# Rewritten from ancient DTML code # Rewritten from ancient DTML code
from mx.DateTime import DateTime as mxDateTime from mx.DateTime import DateTime as mxDateTime
from notesdb import *
from notes_log import log from notes_log import log
from sco_utils import * import sco_utils as scu
from sco_permissions import (
ScoImplement,
ScoChangeFormation,
ScoEtudInscrit,
ScoView,
ScoEtudChangeAdr,
)
from sco_exceptions import ScoValueError
import VERSION
import htmlutils
from sco_formsemestre_custommenu import formsemestre_custommenu_html from sco_formsemestre_custommenu import formsemestre_custommenu_html
from gen_tables import GenTable from gen_tables import GenTable
import sco_archives import sco_archives
@ -41,64 +50,12 @@ import sco_groups
import sco_evaluations import sco_evaluations
import sco_formsemestre import sco_formsemestre
import sco_formsemestre_edit import sco_formsemestre_edit
import sco_moduleimpl
import sco_compute_moy import sco_compute_moy
import sco_codes_parcours import sco_codes_parcours
import sco_bulletins import sco_bulletins
def makeMenu(title, items, css_class="", base_url="", alone=False):
"""HTML snippet to render a simple drop down menu.
items is a list of dicts:
{ 'title' :
'url' :
'id' :
'attr' : "" # optionnal html <a> attributes
'enabled' : # True by default
'helpmsg' :
'submenu' : [ list of sub-items ]
}
"""
def gen_menu_items(items):
H.append("<ul>")
for item in items:
if not item.get("enabled", True):
cls = ' class="ui-state-disabled"'
else:
cls = ""
the_id = item.get("id", "")
if the_id:
li_id = 'id="%s" ' % the_id
else:
li_id = ""
if base_url and "url" in item:
item["urlq"] = base_url + item["url"]
else:
item["urlq"] = item.get("url", "#")
item["attr"] = item.get("attr", "")
submenu = item.get("submenu", None)
H.append(
"<li "
+ li_id
+ cls
+ '><a href="%(urlq)s" %(attr)s>%(title)s</a>' % item
)
if submenu:
gen_menu_items(submenu)
H.append("</li>")
H.append("</ul>")
H = []
if alone:
H.append('<ul class="sco_dropdown_menu %s">' % css_class)
H.append("""<li><a href="#">%s</a>""" % title)
gen_menu_items(items)
H.append("</li>")
if alone:
H.append("</ul>")
return "".join(H)
# H = [ """<span class="barrenav"><ul class="nav"> # H = [ """<span class="barrenav"><ul class="nav">
# <li onmouseover="MenuDisplay(this)" onmouseout="MenuHide(this)"><a href="#" class="menu %s">%s</a><ul>""" % (cssclass, title) # <li onmouseover="MenuDisplay(this)" onmouseout="MenuHide(this)"><a href="#" class="menu %s">%s</a><ul>""" % (cssclass, title)
# ] # ]
@ -130,7 +87,7 @@ def defMenuStats(context, formsemestre_id):
{ {
"title": "Graphe des parcours", "title": "Graphe des parcours",
"url": "formsemestre_graph_parcours?formsemestre_id=" + formsemestre_id, "url": "formsemestre_graph_parcours?formsemestre_id=" + formsemestre_id,
"enabled": WITH_PYDOT, "enabled": scu.WITH_PYDOT,
}, },
{ {
"title": "Codes des parcours", "title": "Codes des parcours",
@ -364,7 +321,7 @@ def formsemestre_status_menubar(context, sem, REQUEST):
{ {
"title": "Créer/modifier les partitions...", "title": "Créer/modifier les partitions...",
"url": "editPartitionForm?formsemestre_id=" + formsemestre_id, "url": "editPartitionForm?formsemestre_id=" + formsemestre_id,
"enabled": context.can_change_groups(REQUEST, formsemestre_id), "enabled": sco_groups.can_change_groups(context, REQUEST, formsemestre_id),
}, },
] ]
# 1 item / partition: # 1 item / partition:
@ -372,7 +329,9 @@ def formsemestre_status_menubar(context, sem, REQUEST):
context, formsemestre_id, with_default=False context, formsemestre_id, with_default=False
) )
submenu = [] submenu = []
enabled = context.can_change_groups(REQUEST, formsemestre_id) and partitions enabled = (
sco_groups.can_change_groups(context, REQUEST, formsemestre_id) and partitions
)
for partition in partitions: for partition in partitions:
submenu.append( submenu.append(
{ {
@ -453,12 +412,12 @@ def formsemestre_status_menubar(context, sem, REQUEST):
H = [ H = [
# <table><tr><td>', # <table><tr><td>',
'<ul id="sco_menu">', '<ul id="sco_menu">',
makeMenu("Semestre", menuSemestre, base_url=base_url), htmlutils.make_menu("Semestre", menuSemestre, base_url=base_url),
makeMenu("Inscriptions", menuInscriptions, base_url=base_url), htmlutils.make_menu("Inscriptions", menuInscriptions, base_url=base_url),
makeMenu("Groupes", menuGroupes, base_url=base_url), htmlutils.make_menu("Groupes", menuGroupes, base_url=base_url),
makeMenu("Notes", menuNotes, base_url=base_url), htmlutils.make_menu("Notes", menuNotes, base_url=base_url),
makeMenu("Jury", menuJury, base_url=base_url), htmlutils.make_menu("Jury", menuJury, base_url=base_url),
makeMenu("Statistiques", menuStats, base_url=base_url), htmlutils.make_menu("Statistiques", menuStats, base_url=base_url),
formsemestre_custommenu_html(context, formsemestre_id, base_url=base_url), formsemestre_custommenu_html(context, formsemestre_id, base_url=base_url),
"</ul>", "</ul>",
#'</td></tr></table>' #'</td></tr></table>'
@ -476,8 +435,8 @@ def retreive_formsemestre_from_request(context, REQUEST):
if REQUEST.form.has_key("formsemestre_id"): if REQUEST.form.has_key("formsemestre_id"):
formsemestre_id = REQUEST.form["formsemestre_id"] formsemestre_id = REQUEST.form["formsemestre_id"]
elif REQUEST.form.has_key("moduleimpl_id"): elif REQUEST.form.has_key("moduleimpl_id"):
modimpl = context.do_moduleimpl_list( modimpl = sco_moduleimpl.do_moduleimpl_list(
moduleimpl_id=REQUEST.form["moduleimpl_id"] context, moduleimpl_id=REQUEST.form["moduleimpl_id"]
) )
if not modimpl: if not modimpl:
return None # suppressed ? return None # suppressed ?
@ -488,7 +447,9 @@ def retreive_formsemestre_from_request(context, REQUEST):
if not E: if not E:
return None # evaluation suppressed ? return None # evaluation suppressed ?
E = E[0] E = E[0]
modimpl = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] modimpl = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
formsemestre_id = modimpl["formsemestre_id"] formsemestre_id = modimpl["formsemestre_id"]
elif REQUEST.form.has_key("group_id"): elif REQUEST.form.has_key("group_id"):
group = sco_groups.get_group(context, REQUEST.form["group_id"]) group = sco_groups.get_group(context, REQUEST.form["group_id"])
@ -557,15 +518,15 @@ def fill_formsemestre(context, sem, REQUEST=None):
] = """<a href="%s/formsemestre_change_lock?formsemestre_id=%s">%s</a>""" % ( ] = """<a href="%s/formsemestre_change_lock?formsemestre_id=%s">%s</a>""" % (
notes_url, notes_url,
sem["formsemestre_id"], sem["formsemestre_id"],
icontag("lock_img", border="0", title="Semestre verrouillé"), scu.icontag("lock_img", border="0", title="Semestre verrouillé"),
) )
else: else:
sem["locklink"] = "" sem["locklink"] = ""
if context.get_preference("bul_display_publication", formsemestre_id): if context.get_preference("bul_display_publication", formsemestre_id):
if sem["bul_hide_xml"] != "0": if sem["bul_hide_xml"] != "0":
eyeicon = icontag("hide_img", border="0", title="Bulletins NON publiés") eyeicon = scu.icontag("hide_img", border="0", title="Bulletins NON publiés")
else: else:
eyeicon = icontag("eye_img", border="0", title="Bulletins publiés") eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés")
sem["eyelink"] = ( sem["eyelink"] = (
"""<a href="%s/formsemestre_change_publication_bul?formsemestre_id=%s">%s</a>""" """<a href="%s/formsemestre_change_publication_bul?formsemestre_id=%s">%s</a>"""
% (notes_url, sem["formsemestre_id"], eyeicon) % (notes_url, sem["formsemestre_id"], eyeicon)
@ -614,7 +575,9 @@ def formsemestre_description_table(
use_ue_coefs = context.get_preference("use_ue_coefs", formsemestre_id) use_ue_coefs = context.get_preference("use_ue_coefs", formsemestre_id)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0] F = context.formation_list(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"])
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
R = [] R = []
sum_coef = 0 sum_coef = 0
@ -641,8 +604,8 @@ def formsemestre_description_table(
ue_info["Coef._class"] = "ue_coef" ue_info["Coef._class"] = "ue_coef"
R.append(ue_info) R.append(ue_info)
ModInscrits = context.do_moduleimpl_inscription_list( ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"] context, moduleimpl_id=M["moduleimpl_id"]
) )
enseignants = ", ".join( enseignants = ", ".join(
[ [
@ -715,13 +678,13 @@ def formsemestre_description_table(
titles["coefficient"] = "Coef. éval." titles["coefficient"] = "Coef. éval."
titles["evalcomplete_str"] = "Complète" titles["evalcomplete_str"] = "Complète"
titles["publish_incomplete_str"] = "Toujours Utilisée" titles["publish_incomplete_str"] = "Toujours Utilisée"
title = "%s %s" % (strcapitalize(parcours.SESSION_NAME), sem["titremois"]) title = "%s %s" % (scu.strcapitalize(parcours.SESSION_NAME), sem["titremois"])
return GenTable( return GenTable(
columns_ids=columns_ids, columns_ids=columns_ids,
rows=R, rows=R,
titles=titles, titles=titles,
origin="Généré par %s le " % VERSION.SCONAME + timedate_human_repr() + "", origin="Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr() + "",
caption=title, caption=title,
html_caption=title, html_caption=title,
html_class="table_leftalign formsemestre_description", html_class="table_leftalign formsemestre_description",
@ -779,8 +742,8 @@ def html_expr_diagnostic(context, diagnostics):
last_id, last_msg = None, None last_id, last_msg = None, None
for diag in diagnostics: for diag in diagnostics:
if "moduleimpl_id" in diag: if "moduleimpl_id" in diag:
mod = context.do_moduleimpl_withmodule_list( mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
moduleimpl_id=diag["moduleimpl_id"] context, moduleimpl_id=diag["moduleimpl_id"]
)[0] )[0]
H.append( H.append(
'<li>module <a href="moduleimpl_status?moduleimpl_id=%s">%s</a>: %s</li>' '<li>module <a href="moduleimpl_status?moduleimpl_id=%s">%s</a>: %s</li>'
@ -875,10 +838,12 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
# porté du DTML # porté du DTML
cnx = context.GetDBConnexion() cnx = context.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
inscrits = context.do_formsemestre_inscription_list( context, formsemestre_id=formsemestre_id
args={"formsemestre_id": formsemestre_id}
) )
# inscrits = context.do_formsemestre_inscription_list(
# args={"formsemestre_id": formsemestre_id}
# )
prev_ue_id = None prev_ue_id = None
can_edit = sco_formsemestre_edit.can_edit_sem( can_edit = sco_formsemestre_edit.can_edit_sem(
@ -926,8 +891,8 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
ModEns += " (resp.), " + ", ".join( ModEns += " (resp.), " + ", ".join(
[context.Users.user_info(e["ens_id"])["nomcomplet"] for e in M["ens"]] [context.Users.user_info(e["ens_id"])["nomcomplet"] for e in M["ens"]]
) )
ModInscrits = context.do_moduleimpl_inscription_list( ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"] context, moduleimpl_id=M["moduleimpl_id"]
) )
mails_enseignants.add( mails_enseignants.add(
context.Users.user_info(M["responsable_id"], REQUEST)["email"] context.Users.user_info(M["responsable_id"], REQUEST)["email"]
@ -960,7 +925,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
% (formsemestre_id, ue["ue_id"]) % (formsemestre_id, ue["ue_id"])
) )
H.append( H.append(
icontag( scu.icontag(
"formula", "formula",
title="Mode calcul moyenne d'UE", title="Mode calcul moyenne d'UE",
style="vertical-align:middle", style="vertical-align:middle",
@ -976,7 +941,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
H.append("</td></tr>") H.append("</td></tr>")
if M["ue"]["type"] != UE_STANDARD: if M["ue"]["type"] != sco_codes_parcours.UE_STANDARD:
fontorange = " fontorange" # style css additionnel fontorange = " fontorange" # style css additionnel
else: else:
fontorange = "" fontorange = ""
@ -1011,7 +976,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
) )
) )
if Mod["module_type"] == MODULE_STANDARD: if Mod["module_type"] == scu.MODULE_STANDARD:
H.append('<td class="evals">') H.append('<td class="evals">')
nb_evals = ( nb_evals = (
etat["nb_evals_completes"] etat["nb_evals_completes"]
@ -1033,7 +998,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
' <span><a class="redlink" href="moduleimpl_status?moduleimpl_id=%s" title="Il y a des notes en attente">[en attente]</a></span>' ' <span><a class="redlink" href="moduleimpl_status?moduleimpl_id=%s" title="Il y a des notes en attente">[en attente]</a></span>'
% M["moduleimpl_id"] % M["moduleimpl_id"]
) )
elif Mod["module_type"] == MODULE_MALUS: elif Mod["module_type"] == scu.MODULE_MALUS:
nb_malus_notes = sum( nb_malus_notes = sum(
[ [
e["etat"]["nb_notes"] e["etat"]["nb_notes"]

View File

@ -1212,11 +1212,11 @@ def do_formsemestre_validate_previous_ue(
context, formsemestre_id context, formsemestre_id
) # > get_etud_ue_status ) # > get_etud_ue_status
if ue_coefficient != None: if ue_coefficient != None:
sco_formsemestre_edit.do_formsemestre_uecoef_edit_or_create( sco_formsemestre.do_formsemestre_uecoef_edit_or_create(
context, cnx, formsemestre_id, ue_id, ue_coefficient context, cnx, formsemestre_id, ue_id, ue_coefficient
) )
else: else:
sco_formsemestre_edit.do_formsemestre_uecoef_delete( sco_formsemestre.do_formsemestre_uecoef_delete(
context, cnx, formsemestre_id, ue_id context, cnx, formsemestre_id, ue_id
) )
sco_parcours_dut.do_formsemestre_validate_ue( sco_parcours_dut.do_formsemestre_validate_ue(

View File

@ -28,16 +28,9 @@
"""Gestion des groupes, nouvelle mouture (juin/nov 2009) """Gestion des groupes, nouvelle mouture (juin/nov 2009)
TODO: TODO:
* Groupes:
- changement de groupe d'un seul etudiant:
formChangeGroupe: pour l'instant supprimé, pas vraiment utile ?
doChangeGroupe
Optimisation possible: Optimisation possible:
revoir do_evaluation_listeetuds_groups() pour extraire aussi les groupes (de chaque etudiant) revoir do_evaluation_listeetuds_groups() pour extraire aussi les groupes (de chaque etudiant)
et eviter ainsi l'appel ulterieur à get_etud_groups() dans _make_table_notes et éviter ainsi l'appel ulterieur à get_etud_groups() dans _make_table_notes
""" """
@ -58,6 +51,20 @@ import scolars
import sco_parcours_dut import sco_parcours_dut
def can_change_groups(context, REQUEST, formsemestre_id):
"Vrai si l'utilisateur peut changer les groupes dans ce semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1":
return False # semestre verrouillé
authuser = REQUEST.AUTHENTICATED_USER
if authuser.has_permission(ScoEtudChangeGroups, context):
return True # admin, chef dept
uid = str(authuser)
if uid in sem["responsables"]:
return True
return False
def checkGroupName( def checkGroupName(
groupName, groupName,
): # XXX unused: now allow any string as a group or partition name ): # XXX unused: now allow any string as a group or partition name
@ -606,7 +613,7 @@ def setGroups(
""" """
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
log("***setGroups: partition_id=%s" % partition_id) log("***setGroups: partition_id=%s" % partition_id)
log("groupsLists=%s" % groupsLists) log("groupsLists=%s" % groupsLists)
@ -693,7 +700,7 @@ def createGroup(context, partition_id, group_name="", default=False, REQUEST=Non
""" """
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if REQUEST and not context.Notes.can_change_groups(REQUEST, formsemestre_id): if REQUEST and not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
# #
if group_name: if group_name:
@ -730,7 +737,7 @@ def suppressGroup(context, group_id, partition_id=None, REQUEST=None):
else: else:
partition_id = group["partition_id"] partition_id = group["partition_id"]
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
if not context.Notes.can_change_groups(REQUEST, partition["formsemestre_id"]): if not can_change_groups(context, REQUEST, partition["formsemestre_id"]):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
log( log(
"suppressGroup: group_id=%s group_name=%s partition_name=%s" "suppressGroup: group_id=%s group_name=%s partition_name=%s"
@ -749,7 +756,7 @@ def partition_create(
redirect=1, redirect=1,
): ):
"""Create a new partition""" """Create a new partition"""
if REQUEST and not context.Notes.can_change_groups(REQUEST, formsemestre_id): if REQUEST and not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
if partition_name: if partition_name:
partition_name = partition_name.strip() partition_name = partition_name.strip()
@ -793,7 +800,7 @@ def getArrowIconsTags(context, REQUEST):
def editPartitionForm(context, formsemestre_id=None, REQUEST=None): def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
"""Form to create/suppress partitions""" """Form to create/suppress partitions"""
# ad-hoc form # ad-hoc form
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
partitions = get_partitions_list(context, formsemestre_id) partitions = get_partitions_list(context, formsemestre_id)
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST) arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
@ -805,7 +812,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
context.sco_header( context.sco_header(
REQUEST, page_title="Partitions...", javascripts=["js/editPartitionForm.js"] REQUEST, page_title="Partitions...", javascripts=["js/editPartitionForm.js"]
), ),
"""<script type="text/javascript"> r"""<script type="text/javascript">
function checkname() { function checkname() {
var val = document.editpart.partition_name.value.replace(/^\s+/, "").replace(/\s+$/, ""); var val = document.editpart.partition_name.value.replace(/^\s+/, "").replace(/\s+$/, "");
if (val.length > 0) { if (val.length > 0) {
@ -816,7 +823,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
} }
</script> </script>
""", """,
"""<h2>Partitions du semestre</h2> r"""<h2>Partitions du semestre</h2>
<form name="editpart" id="editpart" method="POST" action="partition_create"> <form name="editpart" id="editpart" method="POST" action="partition_create">
<div id="epmsg"></div> <div id="epmsg"></div>
<table><tr class="eptit"><th></th><th></th><th></th><th>Partition</th><th>Groupes</th><th></th><th></th><th></th></tr> <table><tr class="eptit"><th></th><th></th><th></th><th>Partition</th><th>Groupes</th><th></th><th></th><th></th></tr>
@ -920,7 +927,7 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
log("partition_set_attr(%s, %s, %s)" % (partition_id, attr, value)) log("partition_set_attr(%s, %s, %s)" % (partition_id, attr, value))
@ -943,7 +950,7 @@ def partition_delete(
default partition cannot be suppressed (unless force)""" default partition cannot be suppressed (unless force)"""
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
if not partition["partition_name"] and not force: if not partition["partition_name"] and not force:
@ -986,7 +993,7 @@ def partition_move(context, partition_id, after=0, REQUEST=None, redirect=1):
"""Move before/after previous one (decrement/increment numero)""" """Move before/after previous one (decrement/increment numero)"""
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
# #
redirect = int(redirect) redirect = int(redirect)
@ -1021,7 +1028,7 @@ def partition_rename(context, partition_id, REQUEST=None):
"""Form to rename a partition""" """Form to rename a partition"""
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
H = ["<h2>Renommer une partition</h2>"] H = ["<h2>Renommer une partition</h2>"]
tf = TrivialFormulator( tf = TrivialFormulator(
@ -1082,7 +1089,7 @@ def partition_set_name(context, partition_id, partition_name, REQUEST=None, redi
"Partition %s déjà existante dans ce semestre !" % partition_name "Partition %s déjà existante dans ce semestre !" % partition_name
) )
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
redirect = int(redirect) redirect = int(redirect)
cnx = context.GetDBConnexion() cnx = context.GetDBConnexion()
@ -1107,7 +1114,7 @@ def group_set_name(context, group_id, group_name, REQUEST=None, redirect=1):
if group["group_name"] is None: if group["group_name"] is None:
raise ValueError("can't set a name to default group") raise ValueError("can't set a name to default group")
formsemestre_id = group["formsemestre_id"] formsemestre_id = group["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
redirect = int(redirect) redirect = int(redirect)
cnx = context.GetDBConnexion() cnx = context.GetDBConnexion()
@ -1124,7 +1131,7 @@ def group_rename(context, group_id, REQUEST=None):
"""Form to rename a group""" """Form to rename a group"""
group = get_group(context, group_id) group = get_group(context, group_id)
formsemestre_id = group["formsemestre_id"] formsemestre_id = group["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]] H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]]
tf = TrivialFormulator( tf = TrivialFormulator(
@ -1170,7 +1177,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
""" """
partition = get_partition(context, partition_id) partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)

View File

@ -44,7 +44,7 @@ def affectGroups(context, partition_id, REQUEST=None):
# Ported from DTML and adapted to new group management (nov 2009) # Ported from DTML and adapted to new group management (nov 2009)
partition = sco_groups.get_partition(context, partition_id) partition = sco_groups.get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
if not context.Notes.can_change_groups(REQUEST, formsemestre_id): if not sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération") raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
H = [ H = [

View File

@ -30,14 +30,23 @@
""" """
# Re-ecriture en 2014 (re-organisation de l'interface, modernisation du code) # Re-ecriture en 2014 (re-organisation de l'interface, modernisation du code)
import datetime
import cgi
import urllib
import time
import collections
import operator
from sco_utils import * import sco_utils as scu
from sco_permissions import ScoEtudInscrit, ScoEtudAddAnnotations, ScoAbsChange
from sco_exceptions import ScoValueError
import html_sco_header import html_sco_header
from gen_tables import GenTable from gen_tables import GenTable
import scolars import scolars
import sco_abs import sco_abs
import sco_excel import sco_excel
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_trombino import sco_trombino
import sco_portal_apogee import sco_portal_apogee
@ -308,7 +317,9 @@ class DisplayedGroupsInfos:
else: else:
group_ids = [] group_ids = []
if not formsemestre_id and moduleimpl_id: if not formsemestre_id and moduleimpl_id:
mods = context.Notes.do_moduleimpl_list(moduleimpl_id=moduleimpl_id) mods = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=moduleimpl_id
)
if len(mods) != 1: if len(mods) != 1:
raise ValueError("invalid moduleimpl_id") raise ValueError("invalid moduleimpl_id")
formsemestre_id = mods[0]["formsemestre_id"] formsemestre_id = mods[0]["formsemestre_id"]
@ -441,8 +452,6 @@ def groups_table(
# "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", "-"))
# ) # )
authuser = REQUEST.AUTHENTICATED_USER
with_codes = int(with_codes) with_codes = int(with_codes)
with_paiement = int(with_paiement) with_paiement = int(with_paiement)
with_archives = int(with_archives) with_archives = int(with_archives)
@ -891,7 +900,7 @@ def form_choix_jour_saisie_hebdo(
FA.append("""<select name="datedebut">""") FA.append("""<select name="datedebut">""")
date = first_monday date = first_monday
i = 0 i = 0
for jour in context.Absences.day_names(): for jour in sco_abs.day_names(context):
if i == today_idx: if i == today_idx:
sel = "selected" sel = "selected"
else: else:
@ -910,7 +919,6 @@ def form_choix_saisie_semaine(context, groups_infos, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(ScoAbsChange, context): if not authuser.has_permission(ScoAbsChange, context):
return "" return ""
sem = groups_infos.formsemestre
# construit l'URL "destination" # construit l'URL "destination"
# (a laquelle on revient apres saisie absences) # (a laquelle on revient apres saisie absences)
query_args = cgi.parse_qs(REQUEST.QUERY_STRING) query_args = cgi.parse_qs(REQUEST.QUERY_STRING)

View File

@ -34,6 +34,7 @@ from notes_log import log
from TrivialFormulator import TrivialFormulator, TF from TrivialFormulator import TrivialFormulator, TF
from notes_table import * from notes_table import *
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_evaluations import sco_evaluations
import htmlutils import htmlutils
@ -65,7 +66,7 @@ def do_evaluation_listenotes(context, REQUEST):
format = REQUEST.form.get("format", "html") format = REQUEST.form.get("format", "html")
E = evals[0] # il y a au moins une evaluation E = evals[0] # il y a au moins une evaluation
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
# description de l'evaluation # description de l'evaluation
@ -224,7 +225,7 @@ def _make_table_notes(
return "<p>Aucune évaluation !</p>" return "<p>Aucune évaluation !</p>"
E = evals[0] E = evals[0]
moduleimpl_id = E["moduleimpl_id"] moduleimpl_id = E["moduleimpl_id"]
M = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
# (debug) check that all evals are in same module: # (debug) check that all evals are in same module:
@ -711,7 +712,7 @@ def evaluation_check_absences(context, evaluation_id):
if not E["jour"]: if not E["jour"]:
return [], [], [], [], [] # evaluation sans date return [], [], [], [], [] # evaluation sans date
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
etudids = sco_groups.do_evaluation_listeetuds_groups( etudids = sco_groups.do_evaluation_listeetuds_groups(
context, evaluation_id, getallstudents=True context, evaluation_id, getallstudents=True
@ -871,7 +872,9 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
</p>""", </p>""",
] ]
# Modules, dans l'ordre # Modules, dans l'ordre
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
for M in Mlist: for M in Mlist:
evals = context.do_evaluation_list({"moduleimpl_id": M["moduleimpl_id"]}) evals = context.do_evaluation_list({"moduleimpl_id": M["moduleimpl_id"]})
if evals: if evals:

330
sco_moduleimpl.py Normal file
View File

@ -0,0 +1,330 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Fonctions sur les moduleimpl
"""
# codes anciens déplacés de ZEntreprise
import datetime
import sco_utils as scu
from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO
from sco_permissions import ScoImplement
from sco_exceptions import ScoValueError, AccessDenied
from notes_log import log
import scolog
import sco_formsemestre
# --- Gestion des "Implémentations de Modules"
# Un "moduleimpl" correspond a la mise en oeuvre d'un module
# dans une formation spécifique, à une date spécifique.
_moduleimplEditor = EditableTable(
"notes_moduleimpl",
"moduleimpl_id",
(
"moduleimpl_id",
"module_id",
"formsemestre_id",
"responsable_id",
"computation_expr",
),
)
_modules_enseignantsEditor = EditableTable(
"notes_modules_enseignants",
"modules_enseignants_id",
("modules_enseignants_id", "moduleimpl_id", "ens_id"),
)
def do_moduleimpl_create(context, args):
"create a moduleimpl"
cnx = context.GetDBConnexion()
r = _moduleimplEditor.create(cnx, args)
context._inval_cache(
formsemestre_id=args["formsemestre_id"]
) # > creation moduleimpl
return r
def do_moduleimpl_delete(context, oid, formsemestre_id=None):
"delete moduleimpl (desinscrit tous les etudiants)"
cnx = context.GetDBConnexion()
# --- desinscription des etudiants
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
req = (
"DELETE FROM notes_moduleimpl_inscription WHERE moduleimpl_id=%(moduleimpl_id)s"
)
cursor.execute(req, {"moduleimpl_id": oid})
# --- suppression des enseignants
cursor.execute(
"DELETE FROM notes_modules_enseignants WHERE moduleimpl_id=%(moduleimpl_id)s",
{"moduleimpl_id": oid},
)
# --- suppression des references dans les absences
cursor.execute(
"UPDATE absences SET moduleimpl_id=NULL WHERE moduleimpl_id=%(moduleimpl_id)s",
{"moduleimpl_id": oid},
)
# --- destruction du moduleimpl
_moduleimplEditor.delete(cnx, oid)
context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_delete
def do_moduleimpl_list(
context, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None
):
"list moduleimpls"
args = locals()
cnx = context.GetDBConnexion()
modimpls = _moduleimplEditor.list(cnx, args) # *args, **kw)
# Ajoute la liste des enseignants
for mo in modimpls:
mo["ens"] = do_ens_list(context, args={"moduleimpl_id": mo["moduleimpl_id"]})
return scu.return_text_if_published(modimpls, REQUEST)
def do_moduleimpl_edit(context, args, formsemestre_id=None, cnx=None):
"edit a moduleimpl"
if not cnx:
cnx = context.GetDBConnexion()
_moduleimplEditor.edit(cnx, args)
context._inval_cache(formsemestre_id=formsemestre_id) # > modif moduleimpl
def do_moduleimpl_withmodule_list(
context, moduleimpl_id=None, formsemestre_id=None, module_id=None, REQUEST=None
):
"""Liste les moduleimpls et ajoute dans chacun le module correspondant
Tri la liste par semestre/UE/numero_matiere/numero_module
"""
args = locals()
del args["context"]
del args["REQUEST"]
modimpls = do_moduleimpl_list(context, **args)
for mo in modimpls:
mo["module"] = context.do_module_list(args={"module_id": mo["module_id"]})[0]
mo["ue"] = context.do_ue_list(args={"ue_id": mo["module"]["ue_id"]})[0]
mo["matiere"] = context.do_matiere_list(
args={"matiere_id": mo["module"]["matiere_id"]}
)[0]
# tri par semestre/UE/numero_matiere/numero_module
extr = lambda x: (
x["ue"]["numero"],
x["ue"]["ue_id"],
x["matiere"]["numero"],
x["matiere"]["matiere_id"],
x["module"]["numero"],
x["module"]["code"],
)
modimpls.sort(lambda x, y: cmp(extr(x), extr(y)))
return scu.return_text_if_published(modimpls, REQUEST)
def do_moduleimpl_inscription_list(
context, moduleimpl_id=None, etudid=None, REQUEST=None
):
"list moduleimpl_inscriptions"
args = locals()
cnx = context.GetDBConnexion()
return scu.return_text_if_published(
_moduleimpl_inscriptionEditor.list(cnx, args), REQUEST
)
def do_moduleimpl_listeetuds(context, moduleimpl_id):
"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"
cnx = context.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(req, {"moduleimpl_id": moduleimpl_id})
res = cursor.fetchall()
return [x[0] for x in res]
def do_moduleimpl_inscrit_tout_semestre(context, moduleimpl_id, formsemestre_id):
"inscrit tous les etudiants inscrit au semestre a ce module"
# UNUSED
cnx = context.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
req = """INSERT INTO notes_moduleimpl_inscription
(moduleimpl_id, etudid)
SELECT %(moduleimpl_id)s, I.etudid
FROM notes_formsemestre_inscription I
WHERE I.formsemestre_id=%(formsemestre_id)s"""
args = {"moduleimpl_id": moduleimpl_id, "formsemestre_id": formsemestre_id}
cursor.execute(req, args)
# --- Inscriptions aux modules
_moduleimpl_inscriptionEditor = EditableTable(
"notes_moduleimpl_inscription",
"moduleimpl_inscription_id",
("moduleimpl_inscription_id", "etudid", "moduleimpl_id"),
)
def do_moduleimpl_inscription_create(context, args, REQUEST=None, formsemestre_id=None):
"create a moduleimpl_inscription"
cnx = context.GetDBConnexion()
log("do_moduleimpl_inscription_create: " + str(args))
r = _moduleimpl_inscriptionEditor.create(cnx, args)
context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription
if REQUEST:
scolog.logdb(
REQUEST,
cnx,
method="moduleimpl_inscription",
etudid=args["etudid"],
msg="inscription module %s" % args["moduleimpl_id"],
commit=False,
)
return r
def do_moduleimpl_inscription_delete(context, oid, formsemestre_id=None):
"delete moduleimpl_inscription"
cnx = context.GetDBConnexion()
_moduleimpl_inscriptionEditor.delete(cnx, oid)
context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscription
def do_moduleimpl_inscrit_etuds(
context, moduleimpl_id, formsemestre_id, etudids, reset=False, REQUEST=None
):
"""Inscrit les etudiants (liste d'etudids) a ce module.
Si reset, desinscrit tous les autres.
"""
# Verifie qu'ils sont tous bien inscrits au semestre
for etudid in etudids:
insem = context.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id, "etudid": etudid}
)
if not insem:
raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid)
# Desinscriptions
if reset:
cnx = context.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
cursor.execute(
"delete from notes_moduleimpl_inscription where moduleimpl_id = %(moduleimpl_id)s",
{"moduleimpl_id": moduleimpl_id},
)
# Inscriptions au module:
inmod_set = set(
[
x["etudid"]
for x in context.do_moduleimpl_inscription_list(moduleimpl_id=moduleimpl_id)
]
)
for etudid in etudids:
# deja inscrit ?
if not etudid in inmod_set:
do_moduleimpl_inscription_create(
context,
{"moduleimpl_id": moduleimpl_id, "etudid": etudid},
REQUEST=REQUEST,
formsemestre_id=formsemestre_id,
)
context._inval_cache(formsemestre_id=formsemestre_id) # > moduleimpl_inscrit_etuds
def do_ens_list(context, *args, **kw):
"liste les enseignants d'un moduleimpl (pas le responsable)"
cnx = context.GetDBConnexion()
ens = _modules_enseignantsEditor.list(cnx, *args, **kw)
return ens
def do_ens_edit(context, *args, **kw):
"edit ens"
cnx = context.GetDBConnexion()
_modules_enseignantsEditor.edit(cnx, *args, **kw)
def do_ens_create(context, args):
"create ens"
cnx = context.GetDBConnexion()
r = _modules_enseignantsEditor.create(cnx, args)
return r
def do_ens_delete(context, oid):
"delete ens"
cnx = context.GetDBConnexion()
r = _modules_enseignantsEditor.delete(cnx, oid)
return r
def can_change_module_resp(context, REQUEST, moduleimpl_id):
"""Check if current user can modify module resp. (raise exception if not).
= Admin, et dir des etud. (si option l'y autorise)
"""
M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0]
# -- check lock
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1":
raise ScoValueError("Modification impossible: semestre verrouille")
# -- check access
authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser)
# admin ou resp. semestre avec flag resp_can_change_resp
if not authuser.has_permission(ScoImplement, context) and (
(uid not in sem["responsables"]) or (not sem["resp_can_change_ens"])
):
raise AccessDenied("Modification impossible pour %s" % uid)
return M, sem
def can_change_ens(context, REQUEST, moduleimpl_id, raise_exc=True):
"check if current user can modify ens list (raise exception if not)"
M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0]
# -- check lock
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1":
if raise_exc:
raise ScoValueError("Modification impossible: semestre verrouille")
else:
return False
# -- check access
authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser)
# admin, resp. module ou resp. semestre
if (
uid != M["responsable_id"]
and not authuser.has_permission(ScoImplement, context)
and (uid not in sem["responsables"])
):
if raise_exc:
raise AccessDenied("Modification impossible pour %s" % uid)
else:
return False
return M, sem

View File

@ -35,8 +35,9 @@ from notes_log import log
from scolog import logdb from scolog import logdb
from notes_table import * from notes_table import *
import sco_formsemestre import sco_formsemestre
from sco_formsemestre_status import makeMenu import sco_moduleimpl
import sco_groups import sco_groups
import htmlutils
def moduleimpl_inscriptions_edit( def moduleimpl_inscriptions_edit(
@ -53,7 +54,7 @@ def moduleimpl_inscriptions_edit(
* Si pas les droits: idem en readonly * Si pas les droits: idem en readonly
""" """
M = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
mod = context.do_module_list(args={"module_id": M["module_id"]})[0] mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -95,7 +96,9 @@ def moduleimpl_inscriptions_edit(
) )
ins["etud"] = etuds_info[0] ins["etud"] = etuds_info[0]
inscrits.sort(lambda x, y: cmp(x["etud"]["nom"], y["etud"]["nom"])) inscrits.sort(lambda x, y: cmp(x["etud"]["nom"], y["etud"]["nom"]))
in_m = context.do_moduleimpl_inscription_list(moduleimpl_id=M["moduleimpl_id"]) in_m = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_id"]
)
in_module = set([x["etudid"] for x in in_m]) in_module = set([x["etudid"] for x in in_m])
# #
partitions = sco_groups.get_partitions_list(context, formsemestre_id) partitions = sco_groups.get_partitions_list(context, formsemestre_id)
@ -176,8 +179,8 @@ def moduleimpl_inscriptions_edit(
H.append("""</table></form>""") H.append("""</table></form>""")
else: # SUBMISSION else: # SUBMISSION
# inscrit a ce module tous les etuds selectionnes # inscrit a ce module tous les etuds selectionnes
context.do_moduleimpl_inscrit_etuds( sco_moduleimpl.do_moduleimpl_inscrit_etuds(
moduleimpl_id, formsemestre_id, etuds, reset=True, REQUEST=REQUEST context, moduleimpl_id, formsemestre_id, etuds, reset=True, REQUEST=REQUEST
) )
REQUEST.RESPONSE.redirect( REQUEST.RESPONSE.redirect(
"moduleimpl_status?moduleimpl_id=%s" % (moduleimpl_id) "moduleimpl_status?moduleimpl_id=%s" % (moduleimpl_id)
@ -187,37 +190,6 @@ def moduleimpl_inscriptions_edit(
return "\n".join(H) return "\n".join(H)
def _make_menu_old_xxx(context, partitions, title="", check="true"):
H = [
"""<div class="barrenav"><ul class="nav">
<li onmouseover="MenuDisplay(this)" onmouseout="MenuHide(this)"><a href="#" class="menu custommenu">%s</a><ul>"""
% title
]
# 'tous'
H.append(
"""<li><a href="#" onclick="group_select('', -1, %s)">Tous</a></li>""" % (check)
)
p_idx = 0
for partition in partitions:
if partition["partition_name"] != None:
p_idx += 1
for group in sco_groups.get_partition_groups(context, partition):
H.append(
"""<li><a href="#" onclick="group_select('%s', %s, %s)">%s %s</a></li>"""
% (
group["group_name"],
p_idx,
check,
partition["partition_name"],
group["group_name"],
)
)
H.append("</ul></ul></div>")
return "".join(H)
def _make_menu(context, partitions, title="", check="true"): def _make_menu(context, partitions, title="", check="true"):
"""Menu with list of all groups""" """Menu with list of all groups"""
items = [{"title": "Tous", "attr": "onclick=\"group_select('', -1, %s)\"" % check}] items = [{"title": "Tous", "attr": "onclick=\"group_select('', -1, %s)\"" % check}]
@ -236,7 +208,7 @@ def _make_menu(context, partitions, title="", check="true"):
) )
return ( return (
'<td class="inscr_addremove_menu">' '<td class="inscr_addremove_menu">'
+ makeMenu(title, items, base_url=context.absolute_url(), alone=True) + htmlutils.make_menu(title, items, base_url=context.absolute_url(), alone=True)
+ "</td>" + "</td>"
) )
@ -275,7 +247,9 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
can_change = authuser.has_permission(ScoEtudInscrit, context) and sem["etat"] == "1" can_change = authuser.has_permission(ScoEtudInscrit, context) and sem["etat"] == "1"
# Liste des modules # Liste des modules
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id) Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
# Decrit les inscriptions aux modules: # Decrit les inscriptions aux modules:
commons = [] # modules communs a tous les etuds du semestre commons = [] # modules communs a tous les etuds du semestre
options = [] # modules ou seuls quelques etudiants sont inscrits options = [] # modules ou seuls quelques etudiants sont inscrits
@ -423,7 +397,9 @@ def descr_inscrs_module(
context, sem, moduleimpl_id, set_all, partitions, partitions_etud_groups context, sem, moduleimpl_id, set_all, partitions, partitions_etud_groups
): ):
"""returns tous_inscrits, nb_inscrits, descr""" """returns tous_inscrits, nb_inscrits, descr"""
ins = context.do_moduleimpl_inscription_list(moduleimpl_id=moduleimpl_id) ins = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=moduleimpl_id
)
set_m = set([x["etudid"] for x in ins]) # ens. des inscrits au module set_m = set([x["etudid"] for x in ins]) # ens. des inscrits au module
non_inscrits = set_all - set_m non_inscrits = set_all - set_m
if len(non_inscrits) == 0: if len(non_inscrits) == 0:
@ -580,7 +556,8 @@ def do_etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
) )
res = cursor.dictfetchall() res = cursor.dictfetchall()
for moduleimpl_id in [x["moduleimpl_id"] for x in res]: for moduleimpl_id in [x["moduleimpl_id"] for x in res]:
context.do_moduleimpl_inscription_create( sco_moduleimpl.do_moduleimpl_inscription_create(
context,
{"moduleimpl_id": moduleimpl_id, "etudid": etudid}, {"moduleimpl_id": moduleimpl_id, "etudid": etudid},
REQUEST=REQUEST, REQUEST=REQUEST,
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,

View File

@ -27,21 +27,30 @@
"""Tableau de bord module """Tableau de bord module
""" """
import time
import urllib
from notesdb import * import sco_utils as scu
from sco_utils import * from sco_utils import (
EVALUATION_NORMALE,
EVALUATION_RATTRAPAGE,
)
from sco_permissions import ScoEtudInscrit, ScoAbsChange
from notes_log import log from notes_log import log
from TrivialFormulator import TrivialFormulator, TF from TrivialFormulator import TrivialFormulator, TF
from notes_table import *
# from notes_table import *
import sco_groups import sco_groups
import sco_evaluations import sco_evaluations
import htmlutils import htmlutils
import sco_excel import sco_excel
from gen_tables import GenTable from gen_tables import GenTable
from htmlutils import histogram_notes from htmlutils import histogram_notes
import sco_moduleimpl
import sco_formsemestre import sco_formsemestre
import sco_formsemestre_status import sco_formsemestre_status
from sco_formsemestre_status import makeMenu import htmlutils
import sco_saisie_notes
import sco_compute_moy import sco_compute_moy
import sco_abs import sco_abs
@ -51,13 +60,15 @@ import sco_abs
def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None): def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"Menu avec actions sur une evaluation" "Menu avec actions sur une evaluation"
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
modimpl = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] modimpl = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
group_id = sco_groups.get_default_group(context, modimpl["formsemestre_id"]) group_id = sco_groups.get_default_group(context, modimpl["formsemestre_id"])
if ( if (
context.can_edit_notes( sco_saisie_notes.can_edit_notes(
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
): ):
@ -69,30 +80,30 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
{ {
"title": "Saisir notes", "title": "Saisir notes",
"url": "saisie_notes?evaluation_id=" + evaluation_id, "url": "saisie_notes?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes( "enabled": sco_saisie_notes.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"] context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
), ),
}, },
{ {
"title": "Modifier évaluation", "title": "Modifier évaluation",
"url": "evaluation_edit?evaluation_id=" + evaluation_id, "url": "evaluation_edit?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes( "enabled": sco_saisie_notes.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
{ {
"title": sup_label, "title": sup_label,
"url": "evaluation_delete?evaluation_id=" + evaluation_id, "url": "evaluation_delete?evaluation_id=" + evaluation_id,
"enabled": nbnotes == 0 "enabled": nbnotes == 0
and context.can_edit_notes( and sco_saisie_notes.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
{ {
"title": "Supprimer toutes les notes", "title": "Supprimer toutes les notes",
"url": "evaluation_suppress_alln?evaluation_id=" + evaluation_id, "url": "evaluation_suppress_alln?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes( "enabled": sco_saisie_notes.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
), ),
}, },
{ {
@ -104,7 +115,9 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"title": "Placement étudiants", "title": "Placement étudiants",
"url": "placement_eval_selectetuds?evaluation_id=" + evaluation_id, "url": "placement_eval_selectetuds?evaluation_id=" + evaluation_id,
"enabled": nbnotes == 0 "enabled": nbnotes == 0
and context.can_edit_notes(REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]), and sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
),
}, },
{ {
"title": "Absences ce jour", "title": "Absences ce jour",
@ -119,19 +132,19 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
}, },
] ]
return makeMenu("actions", menuEval, alone=True) return htmlutils.make_menu("actions", menuEval, alone=True)
def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=None): def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=None):
"""Tableau de bord module (liste des evaluations etc)""" """Tableau de bord module (liste des evaluations etc)"""
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
M = context.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0] F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
ModInscrits = context.do_moduleimpl_inscription_list( ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"] context, moduleimpl_id=M["moduleimpl_id"]
) )
nt = context._getNotesCache().get_NotesTable(context, formsemestre_id) nt = context._getNotesCache().get_NotesTable(context, formsemestre_id)
@ -141,10 +154,10 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
) # la plus RECENTE en tête ) # la plus RECENTE en tête
# #
caneditevals = context.can_edit_notes( caneditevals = sco_saisie_notes.can_edit_notes(
authuser, moduleimpl_id, allow_ens=sem["ens_can_edit_eval"] context, authuser, moduleimpl_id, allow_ens=sem["ens_can_edit_eval"]
) )
caneditnotes = context.can_edit_notes(authuser, moduleimpl_id) caneditnotes = sco_saisie_notes.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 = [
@ -160,7 +173,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<span class="blacktt">(%(responsable_id)s)</span>""" % M, """<span class="blacktt">(%(responsable_id)s)</span>""" % M,
] ]
try: try:
context.can_change_module_resp(REQUEST, moduleimpl_id) sco_moduleimpl.can_change_module_resp(context, REQUEST, moduleimpl_id)
H.append( H.append(
"""<a class="stdlink" href="edit_moduleimpl_resp?moduleimpl_id=%s">modifier</a>""" """<a class="stdlink" href="edit_moduleimpl_resp?moduleimpl_id=%s">modifier</a>"""
% moduleimpl_id % moduleimpl_id
@ -173,7 +186,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
) )
H.append("""</td><td>""") H.append("""</td><td>""")
try: try:
context.can_change_ens(REQUEST, moduleimpl_id) sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id)
H.append( H.append(
"""<a class="stdlink" href="edit_enseignants_form?moduleimpl_id=%s">modifier les enseignants</a>""" """<a class="stdlink" href="edit_enseignants_form?moduleimpl_id=%s">modifier les enseignants</a>"""
% moduleimpl_id % moduleimpl_id
@ -189,7 +202,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
else: else:
H.append("""</td><td>""") H.append("""</td><td>""")
if sem["etat"] != "1": if sem["etat"] != "1":
H.append(icontag("lock32_img", title="verrouillé")) H.append(scu.icontag("lock32_img", title="verrouillé"))
H.append( H.append(
"""</td><td class="fichetitre2">Coef dans le semestre: %(coefficient)s</td><td></td></tr>""" """</td><td class="fichetitre2">Coef dans le semestre: %(coefficient)s</td><td></td></tr>"""
% Mod % Mod
@ -216,7 +229,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
'<tr><td class="fichetitre2" colspan="4">Règle de calcul: <span class="formula" title="mode de calcul de la moyenne du module">moyenne=<tt>%s</tt></span>' '<tr><td class="fichetitre2" colspan="4">Règle de calcul: <span class="formula" title="mode de calcul de la moyenne du module">moyenne=<tt>%s</tt></span>'
% M["computation_expr"] % M["computation_expr"]
) )
if context.can_change_ens(REQUEST, moduleimpl_id, raise_exc=False): if sco_moduleimpl.can_change_ens(
context, REQUEST, moduleimpl_id, raise_exc=False
):
H.append( H.append(
'<span class="fl"><a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">modifier</a></span>' '<span class="fl"><a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">modifier</a></span>'
% moduleimpl_id % moduleimpl_id
@ -226,7 +241,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
H.append( H.append(
'<tr><td colspan="4"><em title="mode de calcul de la moyenne du module">règle de calcul standard</em>' '<tr><td colspan="4"><em title="mode de calcul de la moyenne du module">règle de calcul standard</em>'
) )
if context.can_change_ens(REQUEST, moduleimpl_id, raise_exc=False): if sco_moduleimpl.can_change_ens(
context, REQUEST, moduleimpl_id, raise_exc=False
):
H.append( H.append(
' (<a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">changer</a>)' ' (<a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">changer</a>)'
% moduleimpl_id % moduleimpl_id
@ -407,7 +424,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<a class="smallbutton" href="evaluation_edit?evaluation_id=%s">%s</a>""" """<a class="smallbutton" href="evaluation_edit?evaluation_id=%s">%s</a>"""
% ( % (
eval["evaluation_id"], eval["evaluation_id"],
icontag("edit_img", alt="modifier", title="Modifier informations"), scu.icontag(
"edit_img", alt="modifier", title="Modifier informations"
),
) )
) )
if caneditnotes: if caneditnotes:
@ -415,7 +434,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<a class="smallbutton" href="saisie_notes?evaluation_id=%s">%s</a>""" """<a class="smallbutton" href="saisie_notes?evaluation_id=%s">%s</a>"""
% ( % (
eval["evaluation_id"], eval["evaluation_id"],
icontag("notes_img", alt="saisie notes", title="Saisie des notes"), scu.icontag(
"notes_img", alt="saisie notes", title="Saisie des notes"
),
) )
) )
if etat["nb_notes"] == 0: if etat["nb_notes"] == 0:
@ -424,13 +445,13 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<a class="smallbutton" href="evaluation_delete?evaluation_id=%(evaluation_id)s">""" """<a class="smallbutton" href="evaluation_delete?evaluation_id=%(evaluation_id)s">"""
% eval % eval
) )
H.append(icontag("delete_img", alt="supprimer", title="Supprimer")) H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer"))
if caneditevals: if caneditevals:
H.append("""</a>""") H.append("""</a>""")
elif etat["evalcomplete"]: elif etat["evalcomplete"]:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" """<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>"""
% (eval["evaluation_id"], icontag("status_green_img", title="ok")) % (eval["evaluation_id"], scu.icontag("status_green_img", title="ok"))
) )
else: else:
if etat["evalattente"]: if etat["evalattente"]:
@ -438,7 +459,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" """<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>"""
% ( % (
eval["evaluation_id"], eval["evaluation_id"],
icontag( scu.icontag(
"status_greenorange_img", "status_greenorange_img",
file_format="gif", file_format="gif",
title="notes en attente", title="notes en attente",
@ -450,13 +471,13 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" """<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>"""
% ( % (
eval["evaluation_id"], eval["evaluation_id"],
icontag("status_orange_img", title="il manque des notes"), scu.icontag("status_orange_img", title="il manque des notes"),
) )
) )
# #
if eval["visibulletin"] == "1": if eval["visibulletin"] == "1":
H.append( H.append(
icontag( scu.icontag(
"status_visible_img", title="visible dans bulletins intermédiaires" "status_visible_img", title="visible dans bulletins intermédiaires"
) )
) )
@ -556,7 +577,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
if caneditevals or sem["etat"] != "1": if caneditevals or sem["etat"] != "1":
H.append("""<tr><td colspan="8">""") H.append("""<tr><td colspan="8">""")
if sem["etat"] != "1": if sem["etat"] != "1":
H.append("""%s semestre verrouillé""" % icontag("lock32_img")) H.append("""%s semestre verrouillé""" % scu.icontag("lock32_img"))
else: else:
H.append(top_table_links) H.append(top_table_links)
@ -582,12 +603,12 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
</p> </p>
""" """
% ( % (
icontag("edit_img"), scu.icontag("edit_img"),
icontag("notes_img"), scu.icontag("notes_img"),
icontag("delete_img"), scu.icontag("delete_img"),
icontag("status_orange_img"), scu.icontag("status_orange_img"),
icontag("status_green_img"), scu.icontag("status_green_img"),
icontag("status_visible_img"), scu.icontag("status_visible_img"),
) )
) )
H.append(context.sco_footer(REQUEST)) H.append(context.sco_footer(REQUEST))

View File

@ -28,7 +28,7 @@
"""Gestions des "nouvelles" """Gestions des "nouvelles"
""" """
import PyRSS2Gen import PyRSS2Gen # pylint: disable=import-error
from cStringIO import StringIO from cStringIO import StringIO
import datetime, re import datetime, re
import time import time
@ -42,6 +42,7 @@ from notes_log import log
import scolars import scolars
from sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE from sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
_scolar_news_editor = EditableTable( _scolar_news_editor = EditableTable(
"scolar_news", "scolar_news",
@ -163,7 +164,7 @@ def _get_formsemestre_infos_from_news(context, n):
formsemestre_id = n["object"] formsemestre_id = n["object"]
elif n["type"] == NEWS_NOTE: elif n["type"] == NEWS_NOTE:
moduleimpl_id = n["object"] moduleimpl_id = n["object"]
mods = context.Notes.do_moduleimpl_list(moduleimpl_id=moduleimpl_id) mods = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)
if not mods: if not mods:
return {} # module does not exists anymore return {} # module does not exists anymore
mod = mods[0] mod = mods[0]

View File

@ -40,7 +40,7 @@ import sco_groups
import sco_formsemestre import sco_formsemestre
from scolars import format_telephone, format_pays, make_etud_args from scolars import format_telephone, format_pays, make_etud_args
import sco_formsemestre_status import sco_formsemestre_status
from sco_formsemestre_status import makeMenu import htmlutils
from sco_bulletins import etud_descr_situation_semestre from sco_bulletins import etud_descr_situation_semestre
import sco_parcours_dut import sco_parcours_dut
from sco_formsemestre_validation import formsemestre_recap_parcours_table from sco_formsemestre_validation import formsemestre_recap_parcours_table
@ -135,7 +135,9 @@ def _menuScolarite(context, authuser, sem, etudid):
}, },
] ]
return makeMenu("Scolarité", items, css_class="direction_etud", alone=True) return htmlutils.make_menu(
"Scolarité", items, css_class="direction_etud", alone=True
)
def ficheEtud(context, etudid=None, REQUEST=None): def ficheEtud(context, etudid=None, REQUEST=None):
@ -521,7 +523,7 @@ def menus_etud(context, REQUEST=None):
}, },
] ]
return makeMenu( return htmlutils.make_menu(
"Etudiant", menuEtud, base_url=context.absolute_url() + "/", alone=True "Etudiant", menuEtud, base_url=context.absolute_url() + "/", alone=True
) )

View File

@ -5,9 +5,6 @@
# prefix all permissions by "Sco" to group them in Zope management tab # prefix all permissions by "Sco" to group them in Zope management tab
# Attention: si on change ces valeurs, il faut verifier les codes
# DTML qui utilisent directement les chaines de caractères...
ScoChangeFormation = "Sco Change Formation" ScoChangeFormation = "Sco Change Formation"
ScoEditAllNotes = "Sco Modifier toutes notes" ScoEditAllNotes = "Sco Modifier toutes notes"
ScoEditAllEvals = "Sco Modifier toutes les evaluations" ScoEditAllEvals = "Sco Modifier toutes les evaluations"

View File

@ -36,8 +36,10 @@ from sco_utils import *
from notes_log import log from notes_log import log
import scolars import scolars
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_evaluations import sco_evaluations
import sco_saisie_notes
import sco_excel import sco_excel
from sco_excel import * from sco_excel import *
from gen_tables import GenTable from gen_tables import GenTable
@ -46,15 +48,14 @@ import random
def do_placement_selectetuds(context, REQUEST): def do_placement_selectetuds(context, REQUEST):
""" """
Choisi les etudiants et les infos sur la salle pour le placement des etudiants Choisi les étudiants et les infos sur la salle pour leur placement.
""" """
evaluation_id = REQUEST.form["evaluation_id"] evaluation_id = REQUEST.form["evaluation_id"]
E = context.do_evaluation_list({"evaluation_id": evaluation_id}) E = context.do_evaluation_list({"evaluation_id": evaluation_id})
if not E: if not E:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
E = E[0] E = E[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] # M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"]
# groupes # groupes
groups = sco_groups.do_evaluation_listegroupes( groups = sco_groups.do_evaluation_listegroupes(
context, evaluation_id, include_default=True context, evaluation_id, include_default=True
@ -230,11 +231,10 @@ def do_placement(context, REQUEST):
"Formulaire incomplet ! Vous avez sans doute attendu trop longtemps, veuillez vous reconnecter. Si le problème persiste, contacter l'administrateur. Merci." "Formulaire incomplet ! Vous avez sans doute attendu trop longtemps, veuillez vous reconnecter. Si le problème persiste, contacter l'administrateur. Merci."
) )
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
jour_iso = DateDMYtoISO(E["jour"])
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not sco_saisie_notes.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
@ -256,7 +256,7 @@ def do_placement(context, REQUEST):
group_ids = REQUEST.form.get("group_ids", []) group_ids = REQUEST.form.get("group_ids", [])
groups = sco_groups.listgroups(context, group_ids) groups = sco_groups.listgroups(context, group_ids)
gr_title_filename = sco_groups.listgroups_filename(groups) gr_title_filename = sco_groups.listgroups_filename(groups)
gr_title = sco_groups.listgroups_abbrev(groups) # gr_title = sco_groups.listgroups_abbrev(groups)
if None in [g["group_name"] for g in groups]: # tous les etudiants if None in [g["group_name"] for g in groups]: # tous les etudiants
getallstudents = True getallstudents = True
@ -270,7 +270,7 @@ def do_placement(context, REQUEST):
if not etudids: if not etudids:
return "<p>Aucun groupe sélectionné !</p>" return "<p>Aucun groupe sélectionné !</p>"
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
evalname = "%s-%s" % (Mod["code"], DateDMYtoISO(E["jour"])) evalname = "%s-%s" % (Mod["code"], DateDMYtoISO(E["jour"]))

View File

@ -29,18 +29,28 @@
Formulaire revu en juillet 2016 Formulaire revu en juillet 2016
""" """
import time
import datetime import datetime
import psycopg2
from notesdb import * # from notesdb import *
from sco_utils import * import sco_utils as scu
from notes_log import log from notes_log import log
from TrivialFormulator import TrivialFormulator, TF from TrivialFormulator import TrivialFormulator, TF
from notes_table import * from notesdb import ScoDocCursor, quote_dict, DateISOtoDMY, DateDMYtoISO
from sco_exceptions import (
InvalidNoteValue,
AccessDenied,
NoteProcessError,
ScoValueError,
)
from sco_permissions import ScoEditAllNotes
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_groups import sco_groups
import sco_groups_view import sco_groups_view
from sco_formsemestre_status import makeMenu
import sco_evaluations import sco_evaluations
import sco_parcours_dut
import sco_undo_notes import sco_undo_notes
import htmlutils import htmlutils
import sco_excel import sco_excel
@ -49,10 +59,45 @@ import sco_news
from sco_news import NEWS_INSCR, NEWS_NOTE, NEWS_FORM, NEWS_SEM, NEWS_MISC from sco_news import NEWS_INSCR, NEWS_NOTE, NEWS_FORM, NEWS_SEM, NEWS_MISC
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(ScoEditAllNotes, context)
or uid in sem["responsables"]
)
else:
if (
(not authuser.has_permission(ScoEditAllNotes, context))
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 convert_note_from_string( def convert_note_from_string(
note, note,
note_max, note_max,
note_min=NOTES_MIN, note_min=scu.NOTES_MIN,
etudid=None, etudid=None,
absents=[], absents=[],
tosuppress=[], tosuppress=[],
@ -68,11 +113,11 @@ def convert_note_from_string(
note_value = None note_value = None
absents.append(etudid) absents.append(etudid)
elif note[:3] == "NEU" or note[:3] == "EXC": elif note[:3] == "NEU" or note[:3] == "EXC":
note_value = NOTES_NEUTRALISE note_value = scu.NOTES_NEUTRALISE
elif note[:3] == "ATT": elif note[:3] == "ATT":
note_value = NOTES_ATTENTE note_value = scu.NOTES_ATTENTE
elif note[:3] == "SUP": elif note[:3] == "SUP":
note_value = NOTES_SUPPRESS note_value = scu.NOTES_SUPPRESS
tosuppress.append(etudid) tosuppress.append(etudid)
else: else:
try: try:
@ -93,11 +138,11 @@ def _displayNote(val):
""" """
if val is None: if val is None:
val = "ABS" val = "ABS"
elif val == NOTES_NEUTRALISE: elif val == scu.NOTES_NEUTRALISE:
val = "EXC" # excuse, note neutralise val = "EXC" # excuse, note neutralise
elif val == NOTES_ATTENTE: elif val == scu.NOTES_ATTENTE:
val = "ATT" # attente, note neutralise val = "ATT" # attente, note neutralise
elif val == NOTES_SUPPRESS: elif val == scu.NOTES_SUPPRESS:
val = "SUPR" val = "SUPR"
else: else:
val = "%g" % val val = "%g" % val
@ -111,9 +156,9 @@ def _check_notes(notes, evaluation, mod):
and 4 lists of etudid: invalids, withoutnotes, absents, tosuppress, existingjury and 4 lists of etudid: invalids, withoutnotes, absents, tosuppress, existingjury
""" """
note_max = evaluation["note_max"] note_max = evaluation["note_max"]
if mod["module_type"] == MODULE_STANDARD: if mod["module_type"] == scu.MODULE_STANDARD:
note_min = NOTES_MIN note_min = scu.NOTES_MIN
elif mod["module_type"] == MODULE_MALUS: elif mod["module_type"] == scu.MODULE_MALUS:
note_min = -20.0 note_min = -20.0
else: else:
raise ValueError("Invalid module type") # bug raise ValueError("Invalid module type") # bug
@ -153,10 +198,12 @@ def do_evaluation_upload_xls(context, REQUEST):
evaluation_id = REQUEST.form["evaluation_id"] evaluation_id = REQUEST.form["evaluation_id"]
comment = REQUEST.form["comment"] comment = REQUEST.form["comment"]
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
# XXX imaginer un redirect + msg erreur # XXX imaginer un redirect + msg erreur
raise AccessDenied("Modification des notes impossible pour %s" % authuser) raise AccessDenied("Modification des notes impossible pour %s" % authuser)
# #
@ -168,7 +215,6 @@ def do_evaluation_upload_xls(context, REQUEST):
# -- search eval code # -- search eval code
n = len(lines) n = len(lines)
i = 0 i = 0
ok = True
while i < n: while i < n:
if not lines[i]: if not lines[i]:
diag.append("Erreur: format invalide (ligne vide ?)") diag.append("Erreur: format invalide (ligne vide ?)")
@ -231,9 +277,10 @@ def do_evaluation_upload_xls(context, REQUEST):
context, authuser, evaluation_id, L, comment context, authuser, evaluation_id, L, comment
) )
# news # news
cnx = context.GetDBConnexion()
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
mod = context.do_module_list(args={"module_id": M["module_id"]})[0] mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"] mod["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
@ -274,10 +321,12 @@ def do_evaluation_set_missing(
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
evaluation_id = REQUEST.form["evaluation_id"] evaluation_id = REQUEST.form["evaluation_id"]
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
# XXX imaginer un redirect + msg erreur # XXX imaginer un redirect + msg erreur
raise AccessDenied("Modification des notes impossible pour %s" % authuser) raise AccessDenied("Modification des notes impossible pour %s" % authuser)
# #
@ -323,8 +372,7 @@ def do_evaluation_set_missing(
context, authuser, evaluation_id, L, comment context, authuser, evaluation_id, L, comment
) )
# news # news
cnx = context.GetDBConnexion() M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
mod = context.do_module_list(args={"module_id": M["module_id"]})[0] mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"] mod["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
@ -356,17 +404,17 @@ def evaluation_suppress_alln(context, evaluation_id, REQUEST, dialog_confirmed=F
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
if context.can_edit_notes(authuser, E["moduleimpl_id"], allow_ens=False): if can_edit_notes(context, authuser, E["moduleimpl_id"], allow_ens=False):
# On a le droit de modifier toutes les notes # On a le droit de modifier toutes les notes
# recupere les etuds ayant une note # recupere les etuds ayant une note
NotesDB = context._notes_getall(evaluation_id) NotesDB = context._notes_getall(evaluation_id)
elif context.can_edit_notes(authuser, E["moduleimpl_id"], allow_ens=True): elif can_edit_notes(context, authuser, E["moduleimpl_id"], allow_ens=True):
# Enseignant associé au module: ne peut supprimer que les notes qu'il a saisi # Enseignant associé au module: ne peut supprimer que les notes qu'il a saisi
NotesDB = context._notes_getall(evaluation_id, by_uid=str(authuser)) NotesDB = context._notes_getall(evaluation_id, by_uid=str(authuser))
else: else:
raise AccessDenied("Modification des notes impossible pour %s" % authuser) raise AccessDenied("Modification des notes impossible pour %s" % authuser)
notes = [(etudid, NOTES_SUPPRESS) for etudid in NotesDB.keys()] notes = [(etudid, scu.NOTES_SUPPRESS) for etudid in NotesDB.keys()]
if not dialog_confirmed: if not dialog_confirmed:
nb_changed, nb_suppress, existing_decisions = _notes_add( nb_changed, nb_suppress, existing_decisions = _notes_add(
@ -399,10 +447,9 @@ def evaluation_suppress_alln(context, evaluation_id, REQUEST, dialog_confirmed=F
% E["moduleimpl_id"] % E["moduleimpl_id"]
] ]
# news # news
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
mod = context.do_module_list(args={"module_id": M["module_id"]})[0] mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"] mod["moduleimpl_id"] = M["moduleimpl_id"]
cnx = context.GetDBConnexion()
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
sco_news.add( sco_news.add(
context, context,
@ -450,7 +497,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
nb_changed = 0 nb_changed = 0
nb_suppress = 0 nb_suppress = 0
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
existing_decisions = ( existing_decisions = (
[] []
) # etudids pour lesquels il y a une decision de jury et que la note change ) # etudids pour lesquels il y a une decision de jury et que la note change
@ -459,7 +506,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
changed = False changed = False
if not NotesDB.has_key(etudid): if not NotesDB.has_key(etudid):
# nouvelle note # nouvelle note
if value != NOTES_SUPPRESS: if value != scu.NOTES_SUPPRESS:
if do_it: if do_it:
aa = { aa = {
"etudid": etudid, "etudid": etudid,
@ -481,7 +528,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
if type(value) != type(oldval): if type(value) != type(oldval):
changed = True changed = True
elif type(value) == type(1.0) and ( elif type(value) == type(1.0) and (
abs(value - oldval) > NOTES_PRECISION abs(value - oldval) > scu.NOTES_PRECISION
): ):
changed = True changed = True
elif value != oldval: elif value != oldval:
@ -502,7 +549,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"uid": uid, "uid": uid,
} }
quote_dict(aa) quote_dict(aa)
if value != NOTES_SUPPRESS: if value != scu.NOTES_SUPPRESS:
if do_it: if do_it:
cursor.execute( cursor.execute(
"update notes_notes set value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s where etudid=%(etudid)s and evaluation_id=%(evaluation_id)s", "update notes_notes set value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s where etudid=%(etudid)s and evaluation_id=%(evaluation_id)s",
@ -519,7 +566,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
aa, aa,
) )
# garde trace de la suppression dans l'historique: # garde trace de la suppression dans l'historique:
aa["value"] = NOTES_SUPPRESS aa["value"] = scu.NOTES_SUPPRESS
cursor.execute( cursor.execute(
"insert into notes_notes_log (etudid,evaluation_id,value,comment,date,uid) values (%(etudid)s, %(evaluation_id)s, %(value)s, %(comment)s, %(date)s, %(uid)s)", "insert into notes_notes_log (etudid,evaluation_id,value,comment,date,uid) values (%(etudid)s, %(evaluation_id)s, %(value)s, %(comment)s, %(date)s, %(uid)s)",
aa, aa,
@ -553,9 +600,9 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals: if not evals:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
E = evals[0] E = evals[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
return ( return (
context.sco_header(REQUEST) context.sco_header(REQUEST)
+ "<h2>Modification des notes impossible pour %s</h2>" % authusername + "<h2>Modification des notes impossible pour %s</h2>" % authusername
@ -673,8 +720,8 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
) )
# #
H.append("""</div><h3>Autres opérations</h3><ul>""") H.append("""</div><h3>Autres opérations</h3><ul>""")
if context.can_edit_notes( if can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
): ):
H.append( H.append(
""" """
@ -728,14 +775,14 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals: if not evals:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
E = evals[0] E = evals[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if E["jour"]: if E["jour"]:
indication_date = DateDMYtoISO(E["jour"]) indication_date = DateDMYtoISO(E["jour"])
else: else:
indication_date = sanitize_filename(E["description"])[:12] indication_date = scu.sanitize_filename(E["description"])[:12]
evalname = "%s-%s" % (Mod["code"], indication_date) evalname = "%s-%s" % (Mod["code"], indication_date)
if E["description"]: if E["description"]:
@ -746,7 +793,7 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
evaltitre, evaltitre,
Mod["abbrev"], Mod["abbrev"],
Mod["code"], Mod["code"],
strcapitalize(M["responsable_id"]), scu.strcapitalize(M["responsable_id"]),
) )
groups_infos = sco_groups_view.DisplayedGroupsInfos( groups_infos = sco_groups_view.DisplayedGroupsInfos(
@ -769,8 +816,6 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
etudids = sco_groups.do_evaluation_listeetuds_groups( etudids = sco_groups.do_evaluation_listeetuds_groups(
context, evaluation_id, groups, getallstudents=getallstudents, include_dems=True context, evaluation_id, groups, getallstudents=getallstudents, include_dems=True
) )
# Notes existantes
NotesDB = context._notes_getall(evaluation_id)
# une liste de liste de chaines: lignes de la feuille de calcul # une liste de liste de chaines: lignes de la feuille de calcul
L = [] L = []
@ -784,8 +829,8 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
L.append( L.append(
[ [
"%s" % etudid, "%s" % etudid,
strupper(e["nom"]), scu.strupper(e["nom"]),
strcapitalize(strlower(e["prenom"])), scu.strcapitalize(scu.strlower(e["prenom"])),
e["inscr"]["etat"], e["inscr"]["etat"],
grc, grc,
e["val"], e["val"],
@ -831,11 +876,13 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals: if not evals:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
E = evals[0] E = evals[0]
M = context.do_moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=E["moduleimpl_id"]
)[0]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
return ( return (
context.sco_header(REQUEST) context.sco_header(REQUEST)
+ "<h2>Modification des notes impossible pour %s</h2>" % authusername + "<h2>Modification des notes impossible pour %s</h2>" % authusername
@ -880,7 +927,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
H.append(sco_groups_view.form_groups_choice(context, groups_infos)) H.append(sco_groups_view.form_groups_choice(context, groups_infos))
H.append('</td><td style="padding-left: 35px;">') H.append('</td><td style="padding-left: 35px;">')
H.append( H.append(
makeMenu( htmlutils.make_menu(
"Autres opérations", "Autres opérations",
[ [
{ {
@ -1008,7 +1055,6 @@ def _form_saisie_notes(context, E, M, group_ids, REQUEST=None):
""" """
evaluation_id = E["evaluation_id"] evaluation_id = E["evaluation_id"]
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
groups = sco_groups.listgroups(context, group_ids)
etudids = sco_groups.do_evaluation_listeetuds_groups( etudids = sco_groups.do_evaluation_listeetuds_groups(
context, evaluation_id, getallstudents=True, include_dems=True context, evaluation_id, getallstudents=True, include_dems=True
@ -1035,7 +1081,7 @@ def _form_saisie_notes(context, E, M, group_ids, REQUEST=None):
("comment", {"size": 44, "title": "Commentaire", "return_focus_next": True}), ("comment", {"size": 44, "title": "Commentaire", "return_focus_next": True}),
("changed", {"default": "0", "input_type": "hidden"}), # changed in JS ("changed", {"default": "0", "input_type": "hidden"}), # changed in JS
] ]
if M["module"]["module_type"] == MODULE_STANDARD: if M["module"]["module_type"] == scu.MODULE_STANDARD:
descr.append( descr.append(
( (
"s3", "s3",
@ -1048,7 +1094,7 @@ def _form_saisie_notes(context, E, M, group_ids, REQUEST=None):
}, },
) )
) )
elif M["module"]["module_type"] == MODULE_MALUS: elif M["module"]["module_type"] == scu.MODULE_MALUS:
descr.append( descr.append(
( (
"s3", "s3",
@ -1186,12 +1232,12 @@ def save_note(
% (evaluation_id, etudid, authuser, value) % (evaluation_id, etudid, authuser, value)
) )
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0] Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
Mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % M Mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % M
result = {"nbchanged": 0} # JSON result = {"nbchanged": 0} # JSON
# Check access: admin, respformation, or responsable_id # Check access: admin, respformation, or responsable_id
if not context.can_edit_notes(authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
result["status"] = "unauthorized" result["status"] = "unauthorized"
else: else:
L, invalids, withoutnotes, absents, tosuppress = _check_notes( L, invalids, withoutnotes, absents, tosuppress = _check_notes(
@ -1219,9 +1265,7 @@ def save_note(
else: else:
result["history_menu"] = "" # no update needed result["history_menu"] = "" # no update needed
result["status"] = "ok" result["status"] = "ok"
return scu.sendJSON(REQUEST, result)
# time.sleep(5)
return sendJSON(REQUEST, result)
def get_note_history_menu(context, evaluation_id, etudid): def get_note_history_menu(context, evaluation_id, etudid):

View File

@ -44,7 +44,7 @@ import sco_formsemestre
import sco_groups import sco_groups
import sco_groups_view import sco_groups_view
import sco_portal_apogee import sco_portal_apogee
from sco_formsemestre_status import makeMenu import htmlutils
from sco_pdf import * from sco_pdf import *
import ImportScolars import ImportScolars
import sco_excel import sco_excel
@ -119,7 +119,9 @@ def trombino_html(context, groups_infos, REQUEST=None):
] ]
if groups_infos.members: if groups_infos.members:
H.append( H.append(
"<td>" + makeMenu("Gérer les photos", menuTrombi, alone=True) + "</td>" "<td>"
+ htmlutils.make_menu("Gérer les photos", menuTrombi, alone=True)
+ "</td>"
) )
H.append("</tr></table>") H.append("</tr></table>")
H.append("<div>") H.append("<div>")

View File

@ -58,6 +58,7 @@ from notesdb import *
from sco_utils import * from sco_utils import *
from notes_log import log from notes_log import log
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
import sco_edit_ue import sco_edit_ue
import sco_saisie_notes import sco_saisie_notes
import sco_codes_parcours import sco_codes_parcours
@ -117,14 +118,15 @@ def external_ue_create(
REQUEST, REQUEST,
) )
moduleimpl_id = context.do_moduleimpl_create( moduleimpl_id = sco_moduleimpl.do_moduleimpl_create(
context,
{ {
"module_id": module_id, "module_id": module_id,
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": sem["responsables"][ "responsable_id": sem["responsables"][
0 0
], # affecte le 1er responsable du semestre comme resp. du module ], # affecte le 1er responsable du semestre comme resp. du module
} },
) )
return moduleimpl_id return moduleimpl_id
@ -138,8 +140,8 @@ def external_ue_inscrit_et_note(
% (moduleimpl_id, notes_etuds) % (moduleimpl_id, notes_etuds)
) )
# Inscription des étudiants # Inscription des étudiants
context.do_moduleimpl_inscrit_etuds( sco_moduleimpl.do_moduleimpl_inscrit_etuds(
moduleimpl_id, formsemestre_id, notes_etuds.keys(), REQUEST=REQUEST context, moduleimpl_id, formsemestre_id, notes_etuds.keys(), REQUEST=REQUEST
) )
# Création d'une évaluation si il n'y en a pas déjà: # Création d'une évaluation si il n'y en a pas déjà:

View File

@ -53,7 +53,7 @@ from notesdb import *
from notes_log import log from notes_log import log
from gen_tables import GenTable from gen_tables import GenTable
import sco_formsemestre import sco_formsemestre
import sco_moduleimpl
# deux notes (de même uid) sont considérées comme de la même opération si # deux notes (de même uid) sont considérées comme de la même opération si
# elles sont séparées de moins de 2*tolerance: # elles sont séparées de moins de 2*tolerance:
@ -138,7 +138,7 @@ def list_operations(context, evaluation_id):
def evaluation_list_operations(context, REQUEST, evaluation_id): def evaluation_list_operations(context, REQUEST, evaluation_id):
"""Page listing operations on evaluation""" """Page listing operations on evaluation"""
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
Ops = list_operations(context, evaluation_id) Ops = list_operations(context, evaluation_id)

View File

@ -27,14 +27,24 @@
""" Accès donnees etudiants """ Accès donnees etudiants
""" """
import time
from sco_utils import * import sco_utils as scu
from sco_utils import SCO_ENCODING
from notesdb import * 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 from TrivialFormulator import TrivialFormulator
import safehtml import safehtml
from scolog import logdb from scolog import logdb
from notes_table import *
# from notes_table import *
import sco_news import sco_news
# XXXXXXXXX HACK: zope 2.7.7 bug turaround ? # XXXXXXXXX HACK: zope 2.7.7 bug turaround ?
@ -110,7 +120,7 @@ def format_etud_ident(etud):
def force_uppercase(s): def force_uppercase(s):
if s: if s:
s = strupper(s) s = scu.strupper(s)
return s return s
@ -144,13 +154,13 @@ def format_nom(s, uppercase=True):
if not s: if not s:
return "" return ""
if uppercase: if uppercase:
return strupper(s) return scu.strupper(s)
else: else:
return format_prenom(s) return format_prenom(s)
def format_sexe(sexe): def format_sexe(sexe):
sexe = strlower(sexe) sexe = scu.strlower(sexe)
if sexe == "mr" or sexe == "m." or sexe == "m": if sexe == "mr" or sexe == "m." or sexe == "m":
return "M." return "M."
else: else:
@ -159,7 +169,7 @@ def format_sexe(sexe):
def normalize_sexe(sexe): def normalize_sexe(sexe):
"returns 'MR' ou 'MME'" "returns 'MR' ou 'MME'"
sexe = strupper(sexe).strip() sexe = scu.strupper(sexe).strip()
if sexe in ("M.", "M", "MR", "H"): if sexe in ("M.", "M", "MR", "H"):
return "MR" return "MR"
elif sexe in ("MLLE", "MLLE.", "MELLE", "MME", "F"): elif sexe in ("MLLE", "MLLE.", "MELLE", "MME", "F"):
@ -169,7 +179,7 @@ def normalize_sexe(sexe):
def format_lycee(nomlycee): def format_lycee(nomlycee):
nomlycee = nomlycee.strip() nomlycee = nomlycee.strip()
s = strlower(nomlycee) s = scu.strlower(nomlycee)
if s[:5] == "lycee" or s[:5] == "lycée": if s[:5] == "lycee" or s[:5] == "lycée":
return nomlycee[5:] return nomlycee[5:]
else: else:
@ -199,7 +209,7 @@ def format_telephone(n):
def format_pays(s): def format_pays(s):
"laisse le pays seulement si != FRANCE" "laisse le pays seulement si != FRANCE"
if strupper(s) != "FRANCE": if scu.strupper(s) != "FRANCE":
return s return s
else: else:
return "" return ""
@ -278,13 +288,13 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
Returns: Returns:
True | False, NbHomonyms True | False, NbHomonyms
""" """
if not nom or (not prenom and not CONFIG.ALLOW_NULL_PRENOM): if not nom or (not prenom and not scu.CONFIG.ALLOW_NULL_PRENOM):
return False, 0 return False, 0
nom = nom.decode(SCO_ENCODING).lower().strip().encode(SCO_ENCODING) nom = nom.decode(SCO_ENCODING).lower().strip().encode(SCO_ENCODING)
if prenom: if prenom:
prenom = prenom.decode(SCO_ENCODING).lower().strip().encode(SCO_ENCODING) prenom = prenom.decode(SCO_ENCODING).lower().strip().encode(SCO_ENCODING)
# Don't allow some special cars (eg used in sql regexps) # Don't allow some special cars (eg used in sql regexps)
if FORBIDDEN_CHARS_EXP.search(nom) or 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=ScoDocCursor)
@ -539,7 +549,7 @@ _admissionEditor = EditableTable(
"classement": int_null_is_null, "classement": int_null_is_null,
"apb_classsment_gr": int_null_is_null, "apb_classsment_gr": int_null_is_null,
}, },
output_formators={"type_admission": lambda x: x or 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,
) )
@ -574,7 +584,7 @@ class EtudIdentEditor:
# print "*** pas d'info admission pour %s" % str(i) # print "*** pas d'info admission pour %s" % str(i)
void_adm = { void_adm = {
k: None k: None
for k in scolars._admissionEditor.dbfields for k in _admissionEditor.dbfields
if k != "etudid" and k != "adm_id" if k != "etudid" and k != "adm_id"
} }
res[-1].update(void_adm) res[-1].update(void_adm)
@ -656,7 +666,7 @@ def create_etud(context, cnx, args={}, REQUEST=None):
etudid=etudid, etudid=etudid,
msg="creation initiale", msg="creation initiale",
) )
etud = scolars.etudident_list(cnx, {"etudid": etudid})[0] etud = etudident_list(cnx, {"etudid": etudid})[0]
context.fillEtudsInfo([etud]) context.fillEtudsInfo([etud])
etud["url"] = "ficheEtud?etudid=%(etudid)s" % etud etud["url"] = "ficheEtud?etudid=%(etudid)s" % etud
sco_news.add( sco_news.add(
@ -765,7 +775,7 @@ appreciations_edit = _appreciationsEditor.edit
# -------- Noms des Lycées à partir du code # -------- Noms des Lycées à partir du code
def read_etablissements(): def read_etablissements():
filename = SCO_SRC_DIR + "/" + CONFIG.ETABL_FILENAME filename = scu.SCO_SRC_DIR + "/" + scu.CONFIG.ETABL_FILENAME
log("reading %s" % filename) log("reading %s" % filename)
f = open(filename) f = open(filename)
L = [x[:-1].split(";") for x in f] L = [x[:-1].split(";") for x in f]

View File

@ -27,6 +27,7 @@ import scolars
import sco_formsemestre import sco_formsemestre
import sco_formsemestre_inscriptions import sco_formsemestre_inscriptions
import sco_formsemestre_validation import sco_formsemestre_validation
import sco_moduleimpl
import sco_synchro_etuds import sco_synchro_etuds
import sco_edit_formation import sco_edit_formation
import sco_edit_ue import sco_edit_ue
@ -233,8 +234,10 @@ class ScoFake:
formsemestre_id=None, formsemestre_id=None,
responsable_id=None, responsable_id=None,
): ):
oid = self.context.do_moduleimpl_create(locals()) oid = sco_moduleimpl.do_moduleimpl_create(self.context, locals())
oids = self.context.do_moduleimpl_list(moduleimpl_id=oid) # API inconsistency oids = sco_moduleimpl.do_moduleimpl_list(
self.context, moduleimpl_id=oid
) # API inconsistency
if not oids: if not oids:
raise ScoValueError("moduleimpl not created !") raise ScoValueError("moduleimpl not created !")
return oids[0] return oids[0]

View File

@ -14,6 +14,7 @@ Utiliser comme:
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
import sco_utils as scu import sco_utils as scu
import sco_moduleimpl
G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable
G.verbose = False G.verbose = False
@ -45,7 +46,10 @@ sem, eval_list = G.setup_formsemestre(
) )
# --- Recupère le module de malus # --- Recupère le module de malus
modimpls = context.Notes.do_moduleimpl_list(formsemestre_id=sem["formsemestre_id"]) modimpls = sco_moduleimpl.do_moduleimpl_list(
context, # pylint: disable=undefined-variable
formsemestre_id=sem["formsemestre_id"],
)
# de façon tout à fait inefficace ;-) # de façon tout à fait inefficace ;-)
moduleimpl_malus = [m for m in modimpls if m["module_id"] == mod_malus["module_id"]][0] moduleimpl_malus = [m for m in modimpls if m["module_id"] == mod_malus["module_id"]][0]
# et l'évaluation de malus, de la même façon: # et l'évaluation de malus, de la même façon: