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:
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.... ------------------
def _isFarFutur(self, jour):
@ -691,65 +676,6 @@ class ZAbsences(
# 6 mois ~ 182 jours:
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
security.declareProtected(ScoAbsChange, "SignaleAbsenceGrHebdo")
@ -801,8 +727,8 @@ class ZAbsences(
# calcule dates jours de cette semaine
# liste de dates iso "yyyy-mm-dd"
datessem = [notesdb.DateDMYtoISO(datelundi)]
for _ in self.day_names()[1:]:
datessem.append(self.NextISODay(datessem[-1]))
for _ in sco_abs.day_names(self)[1:]:
datessem.append(sco_abs.next_iso_day(self, datessem[-1]))
#
if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en"
@ -944,12 +870,12 @@ class ZAbsences(
sem = sco_formsemestre.do_formsemestre_list(
self, {"formsemestre_id": formsemestre_id}
)[0]
jourdebut = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday())
jourfin = ddmmyyyy(datefin, work_saturday=self.is_work_saturday())
work_saturday = sco_abs.is_work_saturday(self)
jourdebut = ddmmyyyy(datedebut, work_saturday=work_saturday)
jourfin = ddmmyyyy(datefin, work_saturday=work_saturday)
today = ddmmyyyy(
time.strftime("%d/%m/%Y", time.localtime()),
work_saturday=self.is_work_saturday(),
work_saturday=work_saturday,
)
today.next()
if jourfin > today: # ne propose jamais les semaines dans le futur
@ -964,7 +890,7 @@ class ZAbsences(
)
# calcule dates
dates = [] # ddmmyyyy instances
d = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday())
d = ddmmyyyy(datedebut, work_saturday=work_saturday)
while d <= jourfin:
dates.append(d)
d = d.next(7) # avance d'une semaine
@ -982,7 +908,7 @@ class ZAbsences(
url_link_semaines += "&amp;moduleimpl_id=" + moduleimpl_id
#
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:
gr_tit = "en"
@ -1119,7 +1045,7 @@ class ZAbsences(
odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates]
# Titres colonnes
noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ]
jn = self.day_names()
jn = sco_abs.day_names(self)
for d in odates:
idx_jour = d.weekday()
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)
datedebut = billet["abs_begin"].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 ?
if dates and billet["abs_begin"].hour > 11:
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_inscriptions
import sco_formsemestre_custommenu
import sco_moduleimpl
import sco_moduleimpl_status
import sco_moduleimpl_inscriptions
import sco_evaluations
@ -839,7 +840,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
raise ScoLockedFormError()
# 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:
err_page = self.confirmDialog(
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):
"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)
security.declareProtected(ScoView, "module_is_locked")
@ -1207,158 +1208,12 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
else:
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
security.declareProtected(ScoView, "edit_enseignants_form")
def edit_enseignants_form(self, REQUEST, moduleimpl_id):
"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(
REQUEST,
@ -1453,8 +1308,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
% ens_id
)
else:
self.do_ens_create(
{"moduleimpl_id": moduleimpl_id, "ens_id": ens_id}
sco_moduleimpl.do_ens_create(
self, {"moduleimpl_id": moduleimpl_id, "ens_id": ens_id}
)
return REQUEST.RESPONSE.redirect(
"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
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 = [
self.html_sem_header(
REQUEST,
@ -1535,7 +1390,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
return REQUEST.RESPONSE.redirect(
"moduleimpl_status?moduleimpl_id=" + moduleimpl_id
)
self.do_moduleimpl_edit(
sco_moduleimpl.do_moduleimpl_edit(
self,
{"moduleimpl_id": moduleimpl_id, "responsable_id": responsable_id},
formsemestre_id=sem["formsemestre_id"],
)
@ -1572,7 +1428,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
"""Edition formule calcul moyenne 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 = [
self.html_sem_header(
REQUEST,
@ -1616,7 +1472,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
"moduleimpl_status?moduleimpl_id=" + moduleimpl_id
)
else:
self.do_moduleimpl_edit(
sco_moduleimpl.do_moduleimpl_edit(
self,
{
"moduleimpl_id": moduleimpl_id,
"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"):
"""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"])
debut_sem = DateDMYtoISO(sem["date_debut"])
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 = []
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)
# 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 = {}
for mod in mods:
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):
"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
ok = False
for ens in M["ens"]:
@ -1864,59 +1725,11 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
break
if not ok:
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(
"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
_formsemestre_inscriptionEditor = EditableTable(
"notes_formsemestre_inscription",
@ -2132,8 +1945,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
res = cursor.fetchall()
moduleimpl_inscription_ids = [x[0] for x in res]
for moduleimpl_inscription_id in moduleimpl_inscription_ids:
self.do_moduleimpl_inscription_delete(
moduleimpl_inscription_id, formsemestre_id=formsemestre_id
sco_moduleimpl.do_moduleimpl_inscription_delete(
self, moduleimpl_inscription_id, formsemestre_id=formsemestre_id
)
# -- desincription du semestre
self.do_formsemestre_inscription_delete(
@ -2164,123 +1977,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
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")
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
authuser = REQUEST.AUTHENTICATED_USER
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"])
if (
@ -2473,7 +2169,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
r = self._evaluationEditor.create(cnx, args)
# 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["moduleimpl_id"] = M["moduleimpl_id"]
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)
args["jour"] = 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"])
d, m, y = [int(x) for x in sem["date_debut"].split("/")]
date_debut = datetime.date(y, m, d)
@ -2548,7 +2244,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
if not El:
raise ValueError("Evalution inexistante ! (%s)" % evaluation_id)
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]
tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E
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):
"list evaluations in this formsemestre"
cnx = self.GetDBConnexion()
mods = self.do_moduleimpl_list(formsemestre_id=formsemestre_id)
mods = sco_moduleimpl.do_moduleimpl_list(self, formsemestre_id=formsemestre_id)
evals = []
for mod in mods:
evals += self.do_evaluation_list(
@ -2694,7 +2390,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
cnx = self.GetDBConnexion()
self._evaluationEditor.edit(cnx, args)
# 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(
formsemestre_id=M["formsemestre_id"]
) # > evaluation_edit (coef, ...)
@ -2770,42 +2466,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
security.declareProtected(ScoView, "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")
def dummy_ScoEditAllNotes(self):
@ -3088,21 +2748,6 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
) # > appreciation_add
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):
"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)
modimpls = self.do_moduleimpl_list(formsemestre_id=formsemestre_id)
modimpls = sco_moduleimpl.do_moduleimpl_list(
self, formsemestre_id=formsemestre_id
)
bad_ue = []
bad_sem = []
for modimpl in modimpls:
@ -3588,7 +3235,9 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
# de formations
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:
if mod["module"]["ue_id"] != mod["matiere"]["ue_id"]:
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 !')
# essai: liste des permissions
from AccessControl import getSecurityManager
from AccessControl.Permission import Permission
from AccessControl import getSecurityManager # pylint: disable=import-error
from AccessControl.Permission import Permission # pylint: disable=import-error
permissions = self.ac_inherited_permissions(1)
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('<select name="datedebut" class="noprint">')
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))
date = date.next()
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>")
else:
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(
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
% partition["partition_id"]
)
H.append("</p>")
if self.Notes.can_change_groups(REQUEST, formsemestre_id):
if sco_groups.can_change_groups(self, REQUEST, formsemestre_id):
H.append(
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
% 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)
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:
security.declareProtected(ScoView, "affectGroups")
affectGroups = sco_groups_edit.affectGroups

View File

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

View File

@ -4,11 +4,11 @@
# ScoDoc: suppression 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)
#
# 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
#
@ -17,7 +17,7 @@
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
usage() {
echo "$0 [-n DEPT]"
echo "(default to interactive mode)"
@ -60,10 +60,15 @@ then
# suppression de la base postgres
db_name=$(sed '/^dbname=*/!d; s///;q' < "$cfg_pathname")
echo "suppression de la base postgres $db_name"
su -c "dropdb $db_name" "$POSTGRES_SUPERUSER" || terminate "ne peux supprimer base de donnees $db_name"
if su -c "psql -lt" "$POSTGRES_SUPERUSER" | cut -d \| -f 1 | grep -wq SCORT
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
/bin/rm -f "$cfg_pathname" || terminate "ne peux supprimer $cfg_pathname"
/bin/rm -f "$cfg_pathname" || terminate "Ne peux supprimer $cfg_pathname"
# relance ScoDoc
if [ "$interactive" = 1 ]
then
@ -76,6 +81,7 @@ then
fi
exit 0
else
echo 'Erreur: pas de configuration trouvee pour "'"$DEPT"'"'
exit 1
echo 'Attention: pas de configuration trouvee pour "'"$DEPT"'"'
echo " => ne fait rien."
exit 0
fi

View File

@ -28,6 +28,8 @@
"""Various HTML generation functions
"""
import listhistogram
def horizontal_bargraph(value, 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)}
import listhistogram
def histogram_notes(notes):
"HTML code drawing histogram"
if not notes:
@ -70,3 +69,56 @@ def histogram_notes(notes):
)
D.append("</ul></li></ul>")
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
import sco_parcours_dut
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_compute_moy
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())
"""
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 = {}
for modimpl in modimpls:
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
def is_work_saturday(context):
"Vrai si le samedi est travaillé"
return int(context.get_preference("work_saturday"))
def MonthNbDays(month, year):
"returns nb of days in month"
if month > 7:
@ -173,6 +178,39 @@ class ddmmyyyy:
# 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(
@ -207,7 +245,7 @@ def YearTable(
events,
halfday,
dayattributes,
context.is_work_saturday(),
is_work_saturday(context),
pad_width=pad_width,
)
)

View File

@ -28,16 +28,21 @@
"""Pages HTML gestion absences
(la plupart portées du DTML)
"""
import datetime
from stripogram import html2text, html2safehtml
from gen_tables import GenTable
from notesdb import *
from sco_utils import *
from notesdb import DateISOtoDMY
import sco_utils as scu
from sco_exceptions import ScoValueError
from sco_permissions import ScoAbsChange
from notes_log import log
import sco_groups
import sco_find_etud
import sco_formsemestre
import sco_moduleimpl
import sco_photos
import sco_abs
@ -58,7 +63,7 @@ def doSignaleAbsence(
etudid = etud["etudid"]
description_abs = description
dates = context.DateRangeISO(datedebut, datefin)
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@ -82,7 +87,7 @@ def doSignaleAbsence(
J = "NON "
M = ""
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"]
nt = context.Notes._getNotesCache().get_NotesTable(
context.Notes, formsemestre_id
@ -248,7 +253,7 @@ def doJustifAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
description_abs = description
dates = context.DateRangeISO(datedebut, datefin)
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@ -371,7 +376,7 @@ def doAnnuleAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
dates = context.DateRangeISO(datedebut, datefin)
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@ -506,7 +511,7 @@ def doAnnuleJustif(
"""Annulation d'une justification"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
dates = context.DateRangeISO(datedebut0, datefin0)
dates = sco_abs.DateRangeISO(context, datedebut0, datefin0)
nbadded = 0
for jour in dates:
# Attention: supprime matin et après-midi
@ -571,7 +576,7 @@ def EtatAbsences(context, REQUEST=None):
</td></tr></table>
</form>"""
% (AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
% (scu.AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
context.sco_footer(REQUEST),
]
return "\n".join(H)
@ -610,7 +615,7 @@ def CalAbs(context, REQUEST=None): # etud implied
# crude portage from 1999 DTML
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
anneescolaire = int(AnneeScolaire(REQUEST))
anneescolaire = int(scu.AnneeScolaire(REQUEST))
datedebut = str(anneescolaire) + "-08-31"
datefin = str(anneescolaire + 1) + "-07-31"
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).
"""
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]
@ -714,7 +719,7 @@ def ListeAbsEtud(
html_class="table_leftalign",
table_id="tab_absnonjust",
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,
preferences=context.get_preferences(),
)
@ -725,7 +730,7 @@ def ListeAbsEtud(
html_class="table_leftalign",
table_id="tab_absjust",
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,
preferences=context.get_preferences(),
)
@ -830,7 +835,7 @@ def absences_index_html(context, REQUEST=None):
% REQUEST.URL0,
formChoixSemestreGroupe(context),
"</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
saisir les absences de toute cette semaine.</p>
</form>""",
@ -843,3 +848,16 @@ saisir les absences de toute cette semaine.</p>
H.append(context.sco_footer(REQUEST))
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.header import Header
import htmlutils, time
import time
from reportlab.lib.colors import Color
from sco_utils import *
from notes_table import *
import htmlutils
import sco_formsemestre
import sco_groups
import sco_pvjury
@ -1146,7 +1147,7 @@ def _formsemestre_bulletinetud_header_html(
]
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(
'<td> <a href="%s">%s</a></td>'

View File

@ -29,14 +29,24 @@
"""
import traceback
import pprint
from types import FloatType
from sco_utils import *
from notesdb import *
import sco_utils as scu
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
import sco_formsemestre
import sco_moduleimpl
import sco_groups
import sco_evaluations
from sco_formulas import *
import sco_formulas
import sco_abs
@ -67,7 +77,9 @@ def formsemestre_expressions_use_abscounts(context, formsemestre_id):
if expr and expr[0] != "#" and ab in expr:
return True
# 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"]:
return True
return False
@ -148,7 +160,7 @@ def compute_user_formula(
try:
formula = formula.replace("\n", "").replace("\r", "")
# 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)
if user_moy != "NA0" and user_moy != "NA":
user_moy = float(user_moy)
@ -188,10 +200,10 @@ def do_moduleimpl_moyennes(context, nt, mod):
"""
diag_info = {} # message d'erreur formule
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"])
etudids = context.do_moduleimpl_listeetuds(
moduleimpl_id
etudids = sco_moduleimpl.do_moduleimpl_listeetuds(
context, moduleimpl_id
) # tous, y compris demissions
# Inscrits au semestre (pour traiter les demissions):
inssem_set = set(
@ -256,7 +268,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
]
#
R = {}
formula = unescape_html(mod["computation_expr"])
formula = scu.unescape_html(mod["computation_expr"])
formula_use_abs = "abs" in formula
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,
liste des moduleimpls avec notes en attente.
"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
inscr = context.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id}
# sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# inscr = context.do_formsemestre_inscription_list(
# 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
D = {}
valid_evals = []

View File

@ -37,6 +37,7 @@ from gen_tables import GenTable
import sco_excel, sco_pdf
from sco_pdf import SU
import sco_formsemestre
import sco_moduleimpl
import sco_formsemestre_status
@ -60,7 +61,9 @@ def formsemestre_table_estim_cost(
"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
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 = []
for M in Mlist:
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
import sco_news
import sco_formsemestre
import sco_moduleimpl
import sco_groups
import sco_abs
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)
# 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
# news
mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
@ -165,7 +167,7 @@ def do_evaluation_etat(
last_modif = None
# ---- Liste des groupes complets et incomplets
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]
is_malus = Mod["module_type"] == scu.MODULE_MALUS # True si module de malus
formsemestre_id = M["formsemestre_id"]
@ -182,7 +184,9 @@ def do_evaluation_etat(
# (pour avoir l'etat et le groupe) et aussi les inscriptions
# au module (pour gerer les modules optionnels correctement)
insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
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])
# retire de insem ceux qui ne sont pas inscrits au module
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"]:
continue
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"
if e["heure_debut"]:
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
# au module (pour gerer les modules optionnels correctement)
# 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"]
# 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])
# retire de insem ceux qui ne sont pas inscrits au module
# 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()
T = []
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]
if (e["evaluation_type"] != scu.EVALUATION_NORMALE) or (
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]
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]
formsemestre_id = M["formsemestre_id"]
u = context.Users.user_info(M["responsable_id"])
resp = u["prenomnom"]
nomcomplet = u["nomcomplet"]
can_edit = context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False
can_edit = sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, moduleimpl_id, allow_ens=False
)
link = (
@ -810,7 +818,9 @@ def evaluation_create_form(
the_eval = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
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
formsemestre_id = M["formsemestre_id"]
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")
# ---------------------- 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):
"""recupere liste des codes etapes associés à ce semestre
:returns: liste d'instance de ApoEtapeVDI

View File

@ -74,7 +74,7 @@ def formsemestre_custommenu_html(context, formsemestre_id, base_url=""):
+ 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):

View File

@ -41,6 +41,7 @@ import sco_codes_parcours
import sco_compute_moy
import sco_modalites
import sco_formsemestre
import sco_moduleimpl
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'):
# REQUEST.form['inscrire_etudslist'] = []
# 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])
initvalues["tf-checked"] = [x["module_id"] 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,
"responsable_id": tf[2][module_id],
}
mid = context.do_moduleimpl_create(modargs)
mid = sco_moduleimpl.do_moduleimpl_create(context, modargs)
return REQUEST.RESPONSE.redirect(
"formsemestre_status?formsemestre_id=%s&amp;head_message=Nouveau%%20semestre%%20créé"
% formsemestre_id
@ -720,7 +723,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
# nouveaux modules
checkedmods = tf[2]["tf-checked"]
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]
mods_tocreate = [x for x in checkedmods if not x in existingmods]
# modules a existants a modifier
@ -735,7 +740,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"formsemestre_id": formsemestre_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]
msg += ["création de %s (%s)" % (mod["code"], mod["titre"])]
# INSCRIPTIONS DES ETUDIANTS
@ -771,8 +776,8 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
)
msg += diag
for module_id in mods_toedit:
moduleimpl_id = context.do_moduleimpl_list(
formsemestre_id=formsemestre_id, module_id=module_id
moduleimpl_id = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id, module_id=module_id
)[0]["moduleimpl_id"]
modargs = {
"moduleimpl_id": moduleimpl_id,
@ -780,7 +785,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"formsemestre_id": formsemestre_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]
if msg:
@ -814,8 +821,8 @@ def formsemestre_delete_moduleimpls(context, formsemestre_id, module_ids_to_del)
msg = []
for module_id in module_ids_to_del:
# get id
moduleimpl_id = context.do_moduleimpl_list(
formsemestre_id=formsemestre_id, module_id=module_id
moduleimpl_id = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id, module_id=module_id
)[0]["moduleimpl_id"]
mod = context.do_module_list({"module_id": module_id})[0]
# Evaluations dans ce module ?
@ -828,7 +835,9 @@ def formsemestre_delete_moduleimpls(context, formsemestre_id, module_ids_to_del)
ok = False
else:
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
@ -984,17 +993,21 @@ def do_formsemestre_clone(
formsemestre_id = context.do_formsemestre_create(args, REQUEST)
log("created formsemestre %s" % formsemestre_id)
# 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:
args = mod_orig.copy()
args["formsemestre_id"] = formsemestre_id
mid = context.do_moduleimpl_create(args)
mid = sco_moduleimpl.do_moduleimpl_create(context, args)
# 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:
args = e.copy()
args["moduleimpl_id"] = mid
context.do_ens_create(args)
sco_moduleimpl.do_ens_create(context, args)
# optionally, copy evaluations
if clone_evaluations:
evals = context.do_evaluation_list(
@ -1007,11 +1020,13 @@ def do_formsemestre_clone(
evaluation_id = context.do_evaluation_create(REQUEST=REQUEST, **args)
# 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:
args = obj.copy()
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)
@ -1177,7 +1192,9 @@ def _reassociate_moduleimpls(
et met à jour les décisions de jury (validations d'UE).
"""
# 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:
mod["module_id"] = modules_old2new[mod["module_id"]]
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.do_moduleimpl_delete(
mod["moduleimpl_id"], formsemestre_id=formsemestre_id
sco_moduleimpl.do_moduleimpl_delete(
context, mod["moduleimpl_id"], formsemestre_id=formsemestre_id
)
# --- Desinscription des etudiants
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):
"""Changement manuel des coefficients des UE capitalisées."""
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}
form = [("formsemestre_id", {"input_type": "hidden"})]
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"]}
)
if coefs:
@ -1564,7 +1567,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
msg = []
for ue in ues:
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"]}
)
if val == "" or val == "auto":
@ -1594,11 +1597,13 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
# apply modifications
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"]
)
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:
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)
def get_formsemestre_session_id(context, sem, F, parcours):
"""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"]})
for ue in ue_list:
# 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"]}
)
if uecoef:

View File

@ -37,6 +37,7 @@ from TrivialFormulator import TrivialFormulator, TF
# from notes_table import *
import sco_find_etud
import sco_formsemestre
import sco_moduleimpl
import sco_groups
@ -75,10 +76,13 @@ def do_formsemestre_inscription_with_modules(
gdone[group_id] = 1
# 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:
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},
REQUEST=REQUEST,
formsemestre_id=formsemestre_id,
@ -278,8 +282,10 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
]
# Cherche les moduleimpls et les inscriptions
mods = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
inscr = context.do_moduleimpl_inscription_list(etudid=etudid)
mods = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(context, etudid=etudid)
# Formulaire
modimpls_by_ue_ids = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ]
modimpls_by_ue_names = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_name ]
@ -502,13 +508,14 @@ def do_moduleimpl_incription_options(
# inscriptions
for moduleimpl_id in a_inscrire:
# 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:
raise ScoValueError(
"inscription: invalid moduleimpl_id: %s" % moduleimpl_id
)
mod = mods[0]
context.do_moduleimpl_inscription_create(
sco_moduleimpl.do_moduleimpl_inscription_create(
context,
{"moduleimpl_id": moduleimpl_id, "etudid": etudid},
REQUEST=REQUEST,
formsemestre_id=mod["formsemestre_id"],
@ -516,14 +523,14 @@ def do_moduleimpl_incription_options(
# desinscriptions
for moduleimpl_id in a_desinscrire:
# 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:
raise ScoValueError(
"desinscription: invalid moduleimpl_id: %s" % moduleimpl_id
)
mod = mods[0]
inscr = context.do_moduleimpl_inscription_list(
moduleimpl_id=moduleimpl_id, etudid=etudid
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=moduleimpl_id, etudid=etudid
)
if not inscr:
raise ScoValueError(
@ -531,8 +538,8 @@ def do_moduleimpl_incription_options(
% (etudid, moduleimpl_id)
)
oid = inscr[0]["moduleimpl_inscription_id"]
context.do_moduleimpl_inscription_delete(
oid, formsemestre_id=mod["formsemestre_id"]
sco_moduleimpl.do_moduleimpl_inscription_delete(
context, oid, formsemestre_id=mod["formsemestre_id"]
)
if REQUEST:

View File

@ -31,9 +31,18 @@
# Rewritten from ancient DTML code
from mx.DateTime import DateTime as mxDateTime
from notesdb import *
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 gen_tables import GenTable
import sco_archives
@ -41,64 +50,12 @@ import sco_groups
import sco_evaluations
import sco_formsemestre
import sco_formsemestre_edit
import sco_moduleimpl
import sco_compute_moy
import sco_codes_parcours
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">
# <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",
"url": "formsemestre_graph_parcours?formsemestre_id=" + formsemestre_id,
"enabled": WITH_PYDOT,
"enabled": scu.WITH_PYDOT,
},
{
"title": "Codes des parcours",
@ -364,7 +321,7 @@ def formsemestre_status_menubar(context, sem, REQUEST):
{
"title": "Créer/modifier les partitions...",
"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:
@ -372,7 +329,9 @@ def formsemestre_status_menubar(context, sem, REQUEST):
context, formsemestre_id, with_default=False
)
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:
submenu.append(
{
@ -453,12 +412,12 @@ def formsemestre_status_menubar(context, sem, REQUEST):
H = [
# <table><tr><td>',
'<ul id="sco_menu">',
makeMenu("Semestre", menuSemestre, base_url=base_url),
makeMenu("Inscriptions", menuInscriptions, base_url=base_url),
makeMenu("Groupes", menuGroupes, base_url=base_url),
makeMenu("Notes", menuNotes, base_url=base_url),
makeMenu("Jury", menuJury, base_url=base_url),
makeMenu("Statistiques", menuStats, base_url=base_url),
htmlutils.make_menu("Semestre", menuSemestre, base_url=base_url),
htmlutils.make_menu("Inscriptions", menuInscriptions, base_url=base_url),
htmlutils.make_menu("Groupes", menuGroupes, base_url=base_url),
htmlutils.make_menu("Notes", menuNotes, base_url=base_url),
htmlutils.make_menu("Jury", menuJury, base_url=base_url),
htmlutils.make_menu("Statistiques", menuStats, base_url=base_url),
formsemestre_custommenu_html(context, formsemestre_id, base_url=base_url),
"</ul>",
#'</td></tr></table>'
@ -476,8 +435,8 @@ def retreive_formsemestre_from_request(context, REQUEST):
if REQUEST.form.has_key("formsemestre_id"):
formsemestre_id = REQUEST.form["formsemestre_id"]
elif REQUEST.form.has_key("moduleimpl_id"):
modimpl = context.do_moduleimpl_list(
moduleimpl_id=REQUEST.form["moduleimpl_id"]
modimpl = sco_moduleimpl.do_moduleimpl_list(
context, moduleimpl_id=REQUEST.form["moduleimpl_id"]
)
if not modimpl:
return None # suppressed ?
@ -488,7 +447,9 @@ def retreive_formsemestre_from_request(context, REQUEST):
if not E:
return None # evaluation suppressed ?
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"]
elif REQUEST.form.has_key("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>""" % (
notes_url,
sem["formsemestre_id"],
icontag("lock_img", border="0", title="Semestre verrouillé"),
scu.icontag("lock_img", border="0", title="Semestre verrouillé"),
)
else:
sem["locklink"] = ""
if context.get_preference("bul_display_publication", formsemestre_id):
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:
eyeicon = icontag("eye_img", border="0", title="Bulletins publiés")
eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés")
sem["eyelink"] = (
"""<a href="%s/formsemestre_change_publication_bul?formsemestre_id=%s">%s</a>"""
% (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)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
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 = []
sum_coef = 0
@ -641,8 +604,8 @@ def formsemestre_description_table(
ue_info["Coef._class"] = "ue_coef"
R.append(ue_info)
ModInscrits = context.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"]
ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_id"]
)
enseignants = ", ".join(
[
@ -715,13 +678,13 @@ def formsemestre_description_table(
titles["coefficient"] = "Coef. éval."
titles["evalcomplete_str"] = "Complète"
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(
columns_ids=columns_ids,
rows=R,
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,
html_caption=title,
html_class="table_leftalign formsemestre_description",
@ -779,8 +742,8 @@ def html_expr_diagnostic(context, diagnostics):
last_id, last_msg = None, None
for diag in diagnostics:
if "moduleimpl_id" in diag:
mod = context.do_moduleimpl_withmodule_list(
moduleimpl_id=diag["moduleimpl_id"]
mod = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=diag["moduleimpl_id"]
)[0]
H.append(
'<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
cnx = context.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
Mlist = context.do_moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
inscrits = context.do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id}
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, formsemestre_id=formsemestre_id
)
# inscrits = context.do_formsemestre_inscription_list(
# args={"formsemestre_id": formsemestre_id}
# )
prev_ue_id = None
can_edit = sco_formsemestre_edit.can_edit_sem(
@ -926,8 +891,8 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
ModEns += " (resp.), " + ", ".join(
[context.Users.user_info(e["ens_id"])["nomcomplet"] for e in M["ens"]]
)
ModInscrits = context.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"]
ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_id"]
)
mails_enseignants.add(
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"])
)
H.append(
icontag(
scu.icontag(
"formula",
title="Mode calcul moyenne d'UE",
style="vertical-align:middle",
@ -976,7 +941,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
H.append("</td></tr>")
if M["ue"]["type"] != UE_STANDARD:
if M["ue"]["type"] != sco_codes_parcours.UE_STANDARD:
fontorange = " fontorange" # style css additionnel
else:
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">')
nb_evals = (
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>'
% M["moduleimpl_id"]
)
elif Mod["module_type"] == MODULE_MALUS:
elif Mod["module_type"] == scu.MODULE_MALUS:
nb_malus_notes = sum(
[
e["etat"]["nb_notes"]

View File

@ -1212,11 +1212,11 @@ def do_formsemestre_validate_previous_ue(
context, formsemestre_id
) # > get_etud_ue_status
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
)
else:
sco_formsemestre_edit.do_formsemestre_uecoef_delete(
sco_formsemestre.do_formsemestre_uecoef_delete(
context, cnx, formsemestre_id, ue_id
)
sco_parcours_dut.do_formsemestre_validate_ue(

View File

@ -28,16 +28,9 @@
"""Gestion des groupes, nouvelle mouture (juin/nov 2009)
TODO:
* Groupes:
- changement de groupe d'un seul etudiant:
formChangeGroupe: pour l'instant supprimé, pas vraiment utile ?
doChangeGroupe
Optimisation possible:
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
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(
groupName,
): # XXX unused: now allow any string as a group or partition name
@ -606,7 +613,7 @@ def setGroups(
"""
partition = get_partition(context, partition_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 !")
log("***setGroups: partition_id=%s" % partition_id)
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)
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 !")
#
if group_name:
@ -730,7 +737,7 @@ def suppressGroup(context, group_id, partition_id=None, REQUEST=None):
else:
partition_id = group["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 !")
log(
"suppressGroup: group_id=%s group_name=%s partition_name=%s"
@ -749,7 +756,7 @@ def partition_create(
redirect=1,
):
"""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 !")
if partition_name:
partition_name = partition_name.strip()
@ -793,7 +800,7 @@ def getArrowIconsTags(context, REQUEST):
def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
"""Form to create/suppress partitions"""
# 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 !")
partitions = get_partitions_list(context, formsemestre_id)
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
@ -805,7 +812,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
context.sco_header(
REQUEST, page_title="Partitions...", javascripts=["js/editPartitionForm.js"]
),
"""<script type="text/javascript">
r"""<script type="text/javascript">
function checkname() {
var val = document.editpart.partition_name.value.replace(/^\s+/, "").replace(/\s+$/, "");
if (val.length > 0) {
@ -816,7 +823,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
}
</script>
""",
"""<h2>Partitions du semestre</h2>
r"""<h2>Partitions du semestre</h2>
<form name="editpart" id="editpart" method="POST" action="partition_create">
<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>
@ -920,7 +927,7 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"]
if not 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 !")
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)"""
partition = get_partition(context, partition_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 !")
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)"""
partition = get_partition(context, partition_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 !")
#
redirect = int(redirect)
@ -1021,7 +1028,7 @@ def partition_rename(context, partition_id, REQUEST=None):
"""Form to rename a partition"""
partition = get_partition(context, partition_id)
formsemestre_id = partition["formsemestre_id"]
if not 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 !")
H = ["<h2>Renommer une partition</h2>"]
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
)
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 !")
redirect = int(redirect)
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:
raise ValueError("can't set a name to default group")
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 !")
redirect = int(redirect)
cnx = context.GetDBConnexion()
@ -1124,7 +1131,7 @@ def group_rename(context, group_id, REQUEST=None):
"""Form to rename a group"""
group = get_group(context, group_id)
formsemestre_id = group["formsemestre_id"]
if not 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 !")
H = ["<h2>Renommer un groupe de %s</h2>" % group["partition_name"]]
tf = TrivialFormulator(
@ -1170,7 +1177,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
"""
partition = get_partition(context, partition_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 !")
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)
partition = sco_groups.get_partition(context, partition_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")
H = [

View File

@ -30,14 +30,23 @@
"""
# 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
from gen_tables import GenTable
import scolars
import sco_abs
import sco_excel
import sco_formsemestre
import sco_moduleimpl
import sco_groups
import sco_trombino
import sco_portal_apogee
@ -308,7 +317,9 @@ class DisplayedGroupsInfos:
else:
group_ids = []
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:
raise ValueError("invalid moduleimpl_id")
formsemestre_id = mods[0]["formsemestre_id"]
@ -441,8 +452,6 @@ def groups_table(
# "enter groups_table %s: %s"
# % (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-"))
# )
authuser = REQUEST.AUTHENTICATED_USER
with_codes = int(with_codes)
with_paiement = int(with_paiement)
with_archives = int(with_archives)
@ -891,7 +900,7 @@ def form_choix_jour_saisie_hebdo(
FA.append("""<select name="datedebut">""")
date = first_monday
i = 0
for jour in context.Absences.day_names():
for jour in sco_abs.day_names(context):
if i == today_idx:
sel = "selected"
else:
@ -910,7 +919,6 @@ def form_choix_saisie_semaine(context, groups_infos, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(ScoAbsChange, context):
return ""
sem = groups_infos.formsemestre
# construit l'URL "destination"
# (a laquelle on revient apres saisie absences)
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 notes_table import *
import sco_formsemestre
import sco_moduleimpl
import sco_groups
import sco_evaluations
import htmlutils
@ -65,7 +66,7 @@ def do_evaluation_listenotes(context, REQUEST):
format = REQUEST.form.get("format", "html")
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"]
# description de l'evaluation
@ -224,7 +225,7 @@ def _make_table_notes(
return "<p>Aucune évaluation !</p>"
E = evals[0]
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]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
# (debug) check that all evals are in same module:
@ -711,7 +712,7 @@ def evaluation_check_absences(context, evaluation_id):
if not E["jour"]:
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"]
etudids = sco_groups.do_evaluation_listeetuds_groups(
context, evaluation_id, getallstudents=True
@ -871,7 +872,9 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
</p>""",
]
# 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:
evals = context.do_evaluation_list({"moduleimpl_id": M["moduleimpl_id"]})
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 notes_table import *
import sco_formsemestre
from sco_formsemestre_status import makeMenu
import sco_moduleimpl
import sco_groups
import htmlutils
def moduleimpl_inscriptions_edit(
@ -53,7 +54,7 @@ def moduleimpl_inscriptions_edit(
* 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"]
mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -95,7 +96,9 @@ def moduleimpl_inscriptions_edit(
)
ins["etud"] = etuds_info[0]
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])
#
partitions = sco_groups.get_partitions_list(context, formsemestre_id)
@ -176,8 +179,8 @@ def moduleimpl_inscriptions_edit(
H.append("""</table></form>""")
else: # SUBMISSION
# inscrit a ce module tous les etuds selectionnes
context.do_moduleimpl_inscrit_etuds(
moduleimpl_id, formsemestre_id, etuds, reset=True, REQUEST=REQUEST
sco_moduleimpl.do_moduleimpl_inscrit_etuds(
context, moduleimpl_id, formsemestre_id, etuds, reset=True, REQUEST=REQUEST
)
REQUEST.RESPONSE.redirect(
"moduleimpl_status?moduleimpl_id=%s" % (moduleimpl_id)
@ -187,37 +190,6 @@ def moduleimpl_inscriptions_edit(
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"):
"""Menu with list of all groups"""
items = [{"title": "Tous", "attr": "onclick=\"group_select('', -1, %s)\"" % check}]
@ -236,7 +208,7 @@ def _make_menu(context, partitions, title="", check="true"):
)
return (
'<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>"
)
@ -275,7 +247,9 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
can_change = authuser.has_permission(ScoEtudInscrit, context) and sem["etat"] == "1"
# 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:
commons = [] # modules communs a tous les etuds du semestre
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
):
"""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
non_inscrits = set_all - set_m
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()
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},
REQUEST=REQUEST,
formsemestre_id=formsemestre_id,

View File

@ -27,21 +27,30 @@
"""Tableau de bord module
"""
import time
import urllib
from notesdb import *
from sco_utils import *
import sco_utils as scu
from sco_utils import (
EVALUATION_NORMALE,
EVALUATION_RATTRAPAGE,
)
from sco_permissions import ScoEtudInscrit, ScoAbsChange
from notes_log import log
from TrivialFormulator import TrivialFormulator, TF
from notes_table import *
# from notes_table import *
import sco_groups
import sco_evaluations
import htmlutils
import sco_excel
from gen_tables import GenTable
from htmlutils import histogram_notes
import sco_moduleimpl
import sco_formsemestre
import sco_formsemestre_status
from sco_formsemestre_status import makeMenu
import htmlutils
import sco_saisie_notes
import sco_compute_moy
import sco_abs
@ -51,13 +60,15 @@ import sco_abs
def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"Menu avec actions sur une evaluation"
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"])
if (
context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
)
and nbnotes != 0
):
@ -69,30 +80,30 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
{
"title": "Saisir notes",
"url": "saisie_notes?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
"enabled": sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"]
),
},
{
"title": "Modifier évaluation",
"url": "evaluation_edit?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
"enabled": sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
),
},
{
"title": sup_label,
"url": "evaluation_delete?evaluation_id=" + evaluation_id,
"enabled": nbnotes == 0
and context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
and sco_saisie_notes.can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
),
},
{
"title": "Supprimer toutes les notes",
"url": "evaluation_suppress_alln?evaluation_id=" + evaluation_id,
"enabled": context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
"enabled": sco_saisie_notes.can_edit_notes(
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",
"url": "placement_eval_selectetuds?evaluation_id=" + evaluation_id,
"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",
@ -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):
"""Tableau de bord module (liste des evaluations etc)"""
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"]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
ModInscrits = context.do_moduleimpl_inscription_list(
moduleimpl_id=M["moduleimpl_id"]
ModInscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
context, moduleimpl_id=M["moduleimpl_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
#
caneditevals = context.can_edit_notes(
authuser, moduleimpl_id, allow_ens=sem["ens_can_edit_eval"]
caneditevals = sco_saisie_notes.can_edit_notes(
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)
#
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,
]
try:
context.can_change_module_resp(REQUEST, moduleimpl_id)
sco_moduleimpl.can_change_module_resp(context, REQUEST, moduleimpl_id)
H.append(
"""<a class="stdlink" href="edit_moduleimpl_resp?moduleimpl_id=%s">modifier</a>"""
% moduleimpl_id
@ -173,7 +186,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
)
H.append("""</td><td>""")
try:
context.can_change_ens(REQUEST, moduleimpl_id)
sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id)
H.append(
"""<a class="stdlink" href="edit_enseignants_form?moduleimpl_id=%s">modifier les enseignants</a>"""
% moduleimpl_id
@ -189,7 +202,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
else:
H.append("""</td><td>""")
if sem["etat"] != "1":
H.append(icontag("lock32_img", title="verrouillé"))
H.append(scu.icontag("lock32_img", title="verrouillé"))
H.append(
"""</td><td class="fichetitre2">Coef dans le semestre: %(coefficient)s</td><td></td></tr>"""
% 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>'
% 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(
'<span class="fl"><a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">modifier</a></span>'
% moduleimpl_id
@ -226,7 +241,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
H.append(
'<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(
' (<a class="stdlink" href="edit_moduleimpl_expr?moduleimpl_id=%s">changer</a>)'
% 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>"""
% (
eval["evaluation_id"],
icontag("edit_img", alt="modifier", title="Modifier informations"),
scu.icontag(
"edit_img", alt="modifier", title="Modifier informations"
),
)
)
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>"""
% (
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:
@ -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">"""
% eval
)
H.append(icontag("delete_img", alt="supprimer", title="Supprimer"))
H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer"))
if caneditevals:
H.append("""</a>""")
elif etat["evalcomplete"]:
H.append(
"""<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:
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>"""
% (
eval["evaluation_id"],
icontag(
scu.icontag(
"status_greenorange_img",
file_format="gif",
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>"""
% (
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":
H.append(
icontag(
scu.icontag(
"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":
H.append("""<tr><td colspan="8">""")
if sem["etat"] != "1":
H.append("""%s semestre verrouillé""" % icontag("lock32_img"))
H.append("""%s semestre verrouillé""" % scu.icontag("lock32_img"))
else:
H.append(top_table_links)
@ -582,12 +603,12 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
</p>
"""
% (
icontag("edit_img"),
icontag("notes_img"),
icontag("delete_img"),
icontag("status_orange_img"),
icontag("status_green_img"),
icontag("status_visible_img"),
scu.icontag("edit_img"),
scu.icontag("notes_img"),
scu.icontag("delete_img"),
scu.icontag("status_orange_img"),
scu.icontag("status_green_img"),
scu.icontag("status_visible_img"),
)
)
H.append(context.sco_footer(REQUEST))

View File

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

View File

@ -40,7 +40,7 @@ import sco_groups
import sco_formsemestre
from scolars import format_telephone, format_pays, make_etud_args
import sco_formsemestre_status
from sco_formsemestre_status import makeMenu
import htmlutils
from sco_bulletins import etud_descr_situation_semestre
import sco_parcours_dut
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):
@ -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
)

View File

@ -5,9 +5,6 @@
# 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"
ScoEditAllNotes = "Sco Modifier toutes notes"
ScoEditAllEvals = "Sco Modifier toutes les evaluations"

View File

@ -36,8 +36,10 @@ from sco_utils import *
from notes_log import log
import scolars
import sco_formsemestre
import sco_moduleimpl
import sco_groups
import sco_evaluations
import sco_saisie_notes
import sco_excel
from sco_excel import *
from gen_tables import GenTable
@ -46,15 +48,14 @@ import random
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"]
E = context.do_evaluation_list({"evaluation_id": evaluation_id})
if not E:
raise ScoValueError("invalid evaluation_id")
E = E[0]
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"]
# M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
# groupes
groups = sco_groups.do_evaluation_listegroupes(
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."
)
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
jour_iso = DateDMYtoISO(E["jour"])
# Check access
# (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 (
"<h2>Génération du placement impossible pour %s</h2>" % authusername
+ """<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", [])
groups = sco_groups.listgroups(context, group_ids)
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
getallstudents = True
@ -270,7 +270,7 @@ def do_placement(context, REQUEST):
if not etudids:
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]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
evalname = "%s-%s" % (Mod["code"], DateDMYtoISO(E["jour"]))

View File

@ -29,18 +29,28 @@
Formulaire revu en juillet 2016
"""
import time
import datetime
import psycopg2
from notesdb import *
from sco_utils import *
# from notesdb import *
import sco_utils as scu
from notes_log import log
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_moduleimpl
import sco_groups
import sco_groups_view
from sco_formsemestre_status import makeMenu
import sco_evaluations
import sco_parcours_dut
import sco_undo_notes
import htmlutils
import sco_excel
@ -49,10 +59,45 @@ import sco_news
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(
note,
note_max,
note_min=NOTES_MIN,
note_min=scu.NOTES_MIN,
etudid=None,
absents=[],
tosuppress=[],
@ -68,11 +113,11 @@ def convert_note_from_string(
note_value = None
absents.append(etudid)
elif note[:3] == "NEU" or note[:3] == "EXC":
note_value = NOTES_NEUTRALISE
note_value = scu.NOTES_NEUTRALISE
elif note[:3] == "ATT":
note_value = NOTES_ATTENTE
note_value = scu.NOTES_ATTENTE
elif note[:3] == "SUP":
note_value = NOTES_SUPPRESS
note_value = scu.NOTES_SUPPRESS
tosuppress.append(etudid)
else:
try:
@ -93,11 +138,11 @@ def _displayNote(val):
"""
if val is None:
val = "ABS"
elif val == NOTES_NEUTRALISE:
elif val == scu.NOTES_NEUTRALISE:
val = "EXC" # excuse, note neutralise
elif val == NOTES_ATTENTE:
elif val == scu.NOTES_ATTENTE:
val = "ATT" # attente, note neutralise
elif val == NOTES_SUPPRESS:
elif val == scu.NOTES_SUPPRESS:
val = "SUPR"
else:
val = "%g" % val
@ -111,9 +156,9 @@ def _check_notes(notes, evaluation, mod):
and 4 lists of etudid: invalids, withoutnotes, absents, tosuppress, existingjury
"""
note_max = evaluation["note_max"]
if mod["module_type"] == MODULE_STANDARD:
note_min = NOTES_MIN
elif mod["module_type"] == MODULE_MALUS:
if mod["module_type"] == scu.MODULE_STANDARD:
note_min = scu.NOTES_MIN
elif mod["module_type"] == scu.MODULE_MALUS:
note_min = -20.0
else:
raise ValueError("Invalid module type") # bug
@ -153,10 +198,12 @@ def do_evaluation_upload_xls(context, REQUEST):
evaluation_id = REQUEST.form["evaluation_id"]
comment = REQUEST.form["comment"]
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
# (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
raise AccessDenied("Modification des notes impossible pour %s" % authuser)
#
@ -168,7 +215,6 @@ def do_evaluation_upload_xls(context, REQUEST):
# -- search eval code
n = len(lines)
i = 0
ok = True
while i < n:
if not lines[i]:
diag.append("Erreur: format invalide (ligne vide ?)")
@ -231,9 +277,10 @@ def do_evaluation_upload_xls(context, REQUEST):
context, authuser, evaluation_id, L, comment
)
# news
cnx = context.GetDBConnexion()
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["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
@ -274,10 +321,12 @@ def do_evaluation_set_missing(
authuser = REQUEST.AUTHENTICATED_USER
evaluation_id = REQUEST.form["evaluation_id"]
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
# (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
raise AccessDenied("Modification des notes impossible pour %s" % authuser)
#
@ -323,8 +372,7 @@ def do_evaluation_set_missing(
context, authuser, evaluation_id, L, comment
)
# news
cnx = context.GetDBConnexion()
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["moduleimpl_id"] = M["moduleimpl_id"]
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
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
# recupere les etuds ayant une note
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
NotesDB = context._notes_getall(evaluation_id, by_uid=str(authuser))
else:
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:
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"]
]
# 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["moduleimpl_id"] = M["moduleimpl_id"]
cnx = context.GetDBConnexion()
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
sco_news.add(
context,
@ -450,7 +497,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
nb_changed = 0
nb_suppress = 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 = (
[]
) # 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
if not NotesDB.has_key(etudid):
# nouvelle note
if value != NOTES_SUPPRESS:
if value != scu.NOTES_SUPPRESS:
if do_it:
aa = {
"etudid": etudid,
@ -481,7 +528,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
if type(value) != type(oldval):
changed = True
elif type(value) == type(1.0) and (
abs(value - oldval) > NOTES_PRECISION
abs(value - oldval) > scu.NOTES_PRECISION
):
changed = True
elif value != oldval:
@ -502,7 +549,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"uid": uid,
}
quote_dict(aa)
if value != NOTES_SUPPRESS:
if value != scu.NOTES_SUPPRESS:
if do_it:
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",
@ -519,7 +566,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
aa,
)
# garde trace de la suppression dans l'historique:
aa["value"] = NOTES_SUPPRESS
aa["value"] = scu.NOTES_SUPPRESS
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)",
aa,
@ -553,9 +600,9 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals:
raise ScoValueError("invalid evaluation_id")
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"]
if not context.can_edit_notes(authuser, E["moduleimpl_id"]):
if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
return (
context.sco_header(REQUEST)
+ "<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>""")
if context.can_edit_notes(
REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
if can_edit_notes(
context, REQUEST.AUTHENTICATED_USER, E["moduleimpl_id"], allow_ens=False
):
H.append(
"""
@ -728,14 +775,14 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals:
raise ScoValueError("invalid evaluation_id")
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"]
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if E["jour"]:
indication_date = DateDMYtoISO(E["jour"])
else:
indication_date = sanitize_filename(E["description"])[:12]
indication_date = scu.sanitize_filename(E["description"])[:12]
evalname = "%s-%s" % (Mod["code"], indication_date)
if E["description"]:
@ -746,7 +793,7 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
evaltitre,
Mod["abbrev"],
Mod["code"],
strcapitalize(M["responsable_id"]),
scu.strcapitalize(M["responsable_id"]),
)
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(
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
L = []
@ -784,8 +829,8 @@ def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
L.append(
[
"%s" % etudid,
strupper(e["nom"]),
strcapitalize(strlower(e["prenom"])),
scu.strupper(e["nom"]),
scu.strcapitalize(scu.strlower(e["prenom"])),
e["inscr"]["etat"],
grc,
e["val"],
@ -831,11 +876,13 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
if not evals:
raise ScoValueError("invalid evaluation_id")
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"]
# Check access
# (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 (
context.sco_header(REQUEST)
+ "<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('</td><td style="padding-left: 35px;">')
H.append(
makeMenu(
htmlutils.make_menu(
"Autres opérations",
[
{
@ -1008,7 +1055,6 @@ def _form_saisie_notes(context, E, M, group_ids, REQUEST=None):
"""
evaluation_id = E["evaluation_id"]
formsemestre_id = M["formsemestre_id"]
groups = sco_groups.listgroups(context, group_ids)
etudids = sco_groups.do_evaluation_listeetuds_groups(
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}),
("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(
(
"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(
(
"s3",
@ -1186,12 +1232,12 @@ def save_note(
% (evaluation_id, etudid, authuser, value)
)
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["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % M
result = {"nbchanged": 0} # JSON
# 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"
else:
L, invalids, withoutnotes, absents, tosuppress = _check_notes(
@ -1219,9 +1265,7 @@ def save_note(
else:
result["history_menu"] = "" # no update needed
result["status"] = "ok"
# time.sleep(5)
return sendJSON(REQUEST, result)
return scu.sendJSON(REQUEST, result)
def get_note_history_menu(context, evaluation_id, etudid):

View File

@ -44,7 +44,7 @@ import sco_formsemestre
import sco_groups
import sco_groups_view
import sco_portal_apogee
from sco_formsemestre_status import makeMenu
import htmlutils
from sco_pdf import *
import ImportScolars
import sco_excel
@ -119,7 +119,9 @@ def trombino_html(context, groups_infos, REQUEST=None):
]
if groups_infos.members:
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("<div>")

View File

@ -58,6 +58,7 @@ from notesdb import *
from sco_utils import *
from notes_log import log
import sco_formsemestre
import sco_moduleimpl
import sco_edit_ue
import sco_saisie_notes
import sco_codes_parcours
@ -117,14 +118,15 @@ def external_ue_create(
REQUEST,
)
moduleimpl_id = context.do_moduleimpl_create(
moduleimpl_id = sco_moduleimpl.do_moduleimpl_create(
context,
{
"module_id": module_id,
"formsemestre_id": formsemestre_id,
"responsable_id": sem["responsables"][
0
], # affecte le 1er responsable du semestre comme resp. du module
}
},
)
return moduleimpl_id
@ -138,8 +140,8 @@ def external_ue_inscrit_et_note(
% (moduleimpl_id, notes_etuds)
)
# Inscription des étudiants
context.do_moduleimpl_inscrit_etuds(
moduleimpl_id, formsemestre_id, notes_etuds.keys(), REQUEST=REQUEST
sco_moduleimpl.do_moduleimpl_inscrit_etuds(
context, moduleimpl_id, formsemestre_id, notes_etuds.keys(), REQUEST=REQUEST
)
# 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 gen_tables import GenTable
import sco_formsemestre
import sco_moduleimpl
# 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:
@ -138,7 +138,7 @@ def list_operations(context, evaluation_id):
def evaluation_list_operations(context, REQUEST, evaluation_id):
"""Page listing operations on evaluation"""
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)

View File

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

View File

@ -27,6 +27,7 @@ import scolars
import sco_formsemestre
import sco_formsemestre_inscriptions
import sco_formsemestre_validation
import sco_moduleimpl
import sco_synchro_etuds
import sco_edit_formation
import sco_edit_ue
@ -233,8 +234,10 @@ class ScoFake:
formsemestre_id=None,
responsable_id=None,
):
oid = self.context.do_moduleimpl_create(locals())
oids = self.context.do_moduleimpl_list(moduleimpl_id=oid) # API inconsistency
oid = sco_moduleimpl.do_moduleimpl_create(self.context, locals())
oids = sco_moduleimpl.do_moduleimpl_list(
self.context, moduleimpl_id=oid
) # API inconsistency
if not oids:
raise ScoValueError("moduleimpl not created !")
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 sco_utils as scu
import sco_moduleimpl
G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable
G.verbose = False
@ -45,7 +46,10 @@ sem, eval_list = G.setup_formsemestre(
)
# --- 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 ;-)
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: