Compare commits

...

3 Commits

Author SHA1 Message Date
IDK de7d66e8e8 Fix: bug display selected students on export apo 2021-02-05 19:06:42 +01:00
IDK 6d17f030e2 removed old mxDateTime 2021-02-05 18:21:34 +01:00
IDK 66be2a41c9 test absences 2021-02-04 23:16:18 +01:00
12 changed files with 117 additions and 72 deletions

View File

@ -44,17 +44,16 @@ L'API de plus bas niveau est en gros:
""" """
import urllib
import datetime
import jaxml
import cgi
import string import string
import re import re
import time import time
import datetime
import dateutil
import dateutil.parser
import calendar import calendar
import urllib
from mx.DateTime import DateTime as mxDateTime import cgi
from mx.DateTime.ISO import ParseDateTimeUTC import jaxml
# --------------- # ---------------
from sco_zope import * from sco_zope import *
@ -1542,8 +1541,8 @@ ou entrez une date pour visualiser les absents un jour donné :
return scu.log_unknown_etud(self, REQUEST=REQUEST) return scu.log_unknown_etud(self, REQUEST=REQUEST)
etud = etuds[0] etud = etuds[0]
# check dates # check dates
begin_date = ParseDateTimeUTC(begin) # may raises ValueError begin_date = dateutil.parser.isoparse(begin) # may raises ValueError
end_date = ParseDateTimeUTC(end) end_date = dateutil.parser.isoparse(end)
if begin_date > end_date: if begin_date > end_date:
raise ValueError("invalid dates") raise ValueError("invalid dates")
# #

View File

@ -96,8 +96,6 @@ apt-get -y install python-cracklib # was python-crack
apt-get -y install python-icalendar apt-get -y install python-icalendar
apt-get -y install python-requests apt-get -y install python-requests
apt-get -y install python-egenix-mxtools python-egenix-mxdatetime
# ------------ # ------------
SVNVERSION=$(cd ..; svnversion) SVNVERSION=$(cd ..; svnversion)

View File

@ -226,10 +226,8 @@ def user_nbdays_since_last_notif(context, email_addr, etudid):
) )
res = cursor.dictfetchone() res = cursor.dictfetchone()
if res: if res:
mxd = res["notification_date"] # mx.DateTime instance now = datetime.datetime.now(res["notification_date"].tzinfo)
lastdate = datetime.datetime(mxd.year, mxd.month, mxd.day) return (now - res["notification_date"]).days
now = datetime.datetime.now()
return (now - lastdate).days
else: else:
return None return None

View File

@ -56,10 +56,21 @@ def doSignaleAbsence(
demijournee=2, demijournee=2,
estjust=False, estjust=False,
description=None, description=None,
etudid=False,
REQUEST=None, REQUEST=None,
): # etudid implied ): # etudid implied
"""Signalement d'une absence""" """Signalement d'une absence.
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
Args:
datedebut: dd/mm/yyyy
datefin: dd/mm/yyyy (non incluse)
moduleimpl_id: module auquel imputer les absences
demijournee: 2 si journée complète, 1 matin, 0 après-midi
estjust: absence justifiée
description: str
etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form
"""
etud = context.getEtudInfo(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
@ -247,10 +258,25 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doJustifAbsence( def doJustifAbsence(
context, datedebut, datefin, demijournee, description=None, REQUEST=None context,
datedebut,
datefin,
demijournee,
description=None,
etudid=False,
REQUEST=None,
): # etudid implied ): # etudid implied
"""Justification d'une absence""" """Justification d'une absence
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
Args:
datedebut: dd/mm/yyyy
datefin: dd/mm/yyyy (non incluse)
demijournee: 2 si journée complète, 1 matin, 0 après-midi
estjust: absence justifiée
description: str
etudid: etudiant concerné. Si non spécifié, cherche dans REQUEST.form
"""
etud = context.getEtudInfo(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
description_abs = description description_abs = description
dates = sco_abs.DateRangeISO(context, datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)
@ -370,10 +396,10 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doAnnuleAbsence( def doAnnuleAbsence(
context, datedebut, datefin, demijournee, REQUEST=None context, datedebut, datefin, demijournee, etudid=False, REQUEST=None
): # etudid implied ): # etudid implied
"""Annulation des absences pour une demi journée""" """Annulation des absences pour une demi journée"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, etudid=etudid, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
dates = sco_abs.DateRangeISO(context, datedebut, datefin) dates = sco_abs.DateRangeISO(context, datedebut, datefin)

View File

@ -47,8 +47,7 @@
""" """
import os import os
import time import time
from mx.DateTime import DateTime as mxDateTime import datetime
import mx.DateTime
import re import re
import shutil import shutil
import glob import glob
@ -140,7 +139,7 @@ class BaseArchiver:
def get_archive_date(self, archive_id): def get_archive_date(self, archive_id):
"""Returns date (as a DateTime object) of an archive""" """Returns date (as a DateTime object) of an archive"""
dt = [int(x) for x in os.path.split(archive_id)[1].split("-")] dt = [int(x) for x in os.path.split(archive_id)[1].split("-")]
return mxDateTime(*dt) return datetime.datetime(*dt)
def list_archive(self, archive_id): def list_archive(self, archive_id):
"""Return list of filenames (without path) in archive""" """Return list of filenames (without path) in archive"""

View File

@ -90,6 +90,7 @@ l'inscrition de semestres décalés (S1 en septembre, ...).
Le filtrage s'effctue sur la date et non plus sur la parité du semestre (1-3/2-4). Le filtrage s'effctue sur la date et non plus sur la parité du semestre (1-3/2-4).
""" """
import json
from sco_portal_apogee import get_inscrits_etape from sco_portal_apogee import get_inscrits_etape
from notes_log import log from notes_log import log
@ -540,7 +541,7 @@ class EtapeBilan:
ind_col, ind_col,
comptage, comptage,
"", "",
self.titres[ind_col].replace("<br/>", " / "), json.dumps(self.titres[ind_col].replace("<br/>", " / "))[1:-1],
) )
elif ind_col == COL_CUMUL: elif ind_col == COL_CUMUL:
javascript = "doFiltrage(%s, %s, '.%s', '*', '%s', '%s', '%s');" % ( javascript = "doFiltrage(%s, %s, '.%s', '*', '%s', '%s', '%s');" % (
@ -548,7 +549,7 @@ class EtapeBilan:
self.all_cols_str, self.all_cols_str,
ind_row, ind_row,
" (%d étudiants)" % count, " (%d étudiants)" % count,
self.titres[ind_row], json.dumps(self.titres[ind_row])[1:-1],
"", "",
) )
else: else:
@ -558,10 +559,10 @@ class EtapeBilan:
ind_row, ind_row,
ind_col, ind_col,
comptage, comptage,
self.titres[ind_row], json.dumps(self.titres[ind_row])[1:-1],
self.titres[ind_col].replace("<br/>", " / "), json.dumps(self.titres[ind_col].replace("<br/>", " / "))[1:-1],
) )
return "<a href='#synthese' onclick=\"%s\">%d</a>" % (javascript, count) return '<a href="#synthese" onclick="%s">%d</a>' % (javascript, count)
def _diagtable(self): def _diagtable(self):
H = [] H = []

View File

@ -29,7 +29,6 @@
""" """
# Rewritten from ancient DTML code # Rewritten from ancient DTML code
from mx.DateTime import DateTime as mxDateTime
from notes_log import log from notes_log import log
import sco_utils as scu import sco_utils as scu

View File

@ -601,13 +601,13 @@ def _add_eval_columns(
coefs[evaluation_id] = "coef. %s" % e["coefficient"] coefs[evaluation_id] = "coef. %s" % e["coefficient"]
if note_sur_20: if note_sur_20:
nmx = 20.0 nmax = 20.0
else: else:
nmx = e["note_max"] nmax = e["note_max"]
if keep_numeric: if keep_numeric:
note_max[evaluation_id] = nmx note_max[evaluation_id] = nmax
else: else:
note_max[evaluation_id] = "/ %s" % nmx note_max[evaluation_id] = "/ %s" % nmax
if nb_notes > 0: if nb_notes > 0:
moys[evaluation_id] = "%.3g" % (sum_notes / nb_notes) moys[evaluation_id] = "%.3g" % (sum_notes / nb_notes)

View File

@ -34,9 +34,7 @@ import tempfile
import urllib import urllib
import re import re
import time import time
import mx import datetime
import mx.DateTime
from mx.DateTime import DateTime as mxDateTime
import sco_utils as scu import sco_utils as scu
import VERSION import VERSION
@ -435,8 +433,8 @@ def table_suivi_cohorte(
# tri les semestres par date de debut # tri les semestres par date de debut
for s in sems: for s in sems:
d, m, y = [int(x) for x in s["date_debut"].split("/")] d, m, y = [int(x) for x in s["date_debut"].split("/")]
s["date_debut_mx"] = mxDateTime(y, m, d) # pylint: disable=not-callable s["date_debut_dt"] = datetime.datetime(y, m, d)
sems.sort(lambda x, y: cmp(x["date_debut_mx"], y["date_debut_mx"])) sems.sort(lambda x, y: cmp(x["date_debut_dt"], y["date_debut_dt"]))
# 2-- Pour chaque semestre, trouve l'ensemble des etudiants venant de sem # 2-- Pour chaque semestre, trouve l'ensemble des etudiants venant de sem
logt("B: etuds sets") logt("B: etuds sets")
@ -467,21 +465,21 @@ def table_suivi_cohorte(
# semestre de depart: # semestre de depart:
porigin = periodsem() porigin = periodsem()
d, m, y = [int(x) for x in sem["date_debut"].split("/")] d, m, y = [int(x) for x in sem["date_debut"].split("/")]
porigin.datedebut = mxDateTime(y, m, d) # pylint: disable=not-callable porigin.datedebut = datetime.datetime(y, m, d)
porigin.sems = [sem] porigin.sems = [sem]
# #
tolerance = mx.DateTime.DateTimeDelta(45) # 45 days tolerance = datetime.timedelta(days=45)
for s in sems: for s in sems:
merged = False merged = False
for p in P: for p in P:
if abs(s["date_debut_mx"] - p.datedebut) < tolerance: if abs(s["date_debut_dt"] - p.datedebut) < tolerance:
p.sems.append(s) p.sems.append(s)
merged = True merged = True
break break
if not merged: if not merged:
p = periodsem() p = periodsem()
p.datedebut = s["date_debut_mx"] p.datedebut = s["date_debut_dt"]
p.sems = [s] p.sems = [s]
P.append(p) P.append(p)

View File

@ -543,15 +543,15 @@ class ScoDocJSONEncoder(json.JSONEncoder):
def default(self, o): # pylint: disable=E0202 def default(self, o): # pylint: disable=E0202
import sco_formsemestre import sco_formsemestre
# horrible hack pour encoder les dates mx # ScoDoc 7.22 n'utilise plus mx:
if str(type(o)) == "<type 'mx.DateTime.DateTime'>": if str(type(o)) == "<type 'mx.DateTime.DateTime'>":
log("Warning: mx.DateTime object detected !")
return o.strftime("%Y-%m-%dT%H:%M:%S") return o.strftime("%Y-%m-%dT%H:%M:%S")
if isinstance(o, (datetime.date, datetime.datetime)): if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat() return o.isoformat()
elif isinstance(o, sco_formsemestre.ApoEtapeVDI): elif isinstance(o, sco_formsemestre.ApoEtapeVDI):
return str(o) return str(o)
else: else:
log("not mx: %s" % type(o))
return json.JSONEncoder.default(self, o) return json.JSONEncoder.default(self, o)

View File

@ -13,6 +13,8 @@ import random
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
import sco_utils import sco_utils
import sco_abs
import sco_abs_views
G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable
G.verbose = False G.verbose = False
@ -64,3 +66,28 @@ for etud in etuds:
nb_changed, nb_suppress, existing_decisions = G.create_note( nb_changed, nb_suppress, existing_decisions = G.create_note(
evaluation=e, etud=etud, note=float(random.randint(0, 20)) evaluation=e, etud=etud, note=float(random.randint(0, 20))
) )
# --- Saisie absences
etudid = etuds[0]["etudid"]
_ = sco_abs_views.doSignaleAbsence(
context.Absences,
"15/01/2020",
"18/01/2020",
demijournee=2,
etudid=etudid,
REQUEST=REQUEST,
)
_ = sco_abs_views.doJustifAbsence(
context.Absences,
"17/01/2020",
"18/01/2020",
demijournee=2,
etudid=etudid,
REQUEST=REQUEST,
)
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid)
assert a.CountAbs() == 3
assert a.CountAbsJust() == 1

View File

@ -1,6 +1,6 @@
$(function() { $(function () {
$( "div#export_help" ).accordion( { $("div#export_help").accordion({
heightStyle: "content", heightStyle: "content",
collapsible: true, collapsible: true,
active: false, active: false,
@ -21,8 +21,8 @@ function display(r, c, row, col) {
function show_tag(all_rows, all_cols, tag) { function show_tag(all_rows, all_cols, tag) {
// Filtrer tous les étudiants // Filtrer tous les étudiants
all_rows.split(',').forEach(function(r) { all_rows.split(',').forEach(function (r) {
all_cols.split(',').forEach(function(c) { all_cols.split(',').forEach(function (c) {
etudiants = r + c.substring(1); etudiants = r + c.substring(1);
$(etudiants).css("display", "none"); $(etudiants).css("display", "none");
}) })
@ -34,36 +34,36 @@ function show_tag(all_rows, all_cols, tag) {
function show_filtres(effectifs, filtre_row, filtre_col) { function show_filtres(effectifs, filtre_row, filtre_col) {
$("#compte").html(effectifs); $("#compte").html(effectifs);
if ((filtre_row == '') && (filtre_col == '')) { if ((filtre_row == '') && (filtre_col == '')) {
$("#sans_filtre").css("display", ""); $("#sans_filtre").css("display", "");
$("#filtre_row").css("display", "none"); $("#filtre_row").css("display", "none");
$("#filtre_col").css("display", "none"); $("#filtre_col").css("display", "none");
} else { } else {
$("#sans_filtre").css("display", "none"); $("#sans_filtre").css("display", "none");
if (filtre_row == '') { if (filtre_row == '') {
$("#filtre_row").css("display", "none"); $("#filtre_row").css("display", "none");
$("#filtre_col").css("display", ""); $("#filtre_col").css("display", "");
$("#filtre_col").html("Filtre sur code étape: " + filtre_col); $("#filtre_col").html("Filtre sur code étape: " + filtre_col);
} else if (filtre_col == '') { } else if (filtre_col == '') {
$("#filtre_row").css("display", ""); $("#filtre_row").css("display", "");
$("#filtre_col").css("display", "none"); $("#filtre_col").css("display", "none");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row); $("#filtre_row").html("Filtre sur semestre: " + filtre_row);
} else { } else {
$("#filtre_row").css("display", ""); $("#filtre_row").css("display", "");
$("#filtre_col").css("display", ""); $("#filtre_col").css("display", "");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row); $("#filtre_row").html("Filtre sur semestre: " + filtre_row);
$("#filtre_col").html("Filtre sur code étape: " + filtre_col); $("#filtre_col").html("Filtre sur code étape: " + filtre_col);
} }
} }
} }
function doFiltrage(all_rows, all_cols, row, col, effectifs, filtre_row, filtre_col) { function doFiltrage(all_rows, all_cols, row, col, effectifs, filtre_row, filtre_col) {
show_filtres(effectifs, filtre_row, filtre_col) show_filtres(effectifs, filtre_row, filtre_col)
all_rows.split(',').forEach(function(r) { all_rows.split(',').forEach(function (r) {
all_cols.split(',').forEach(function(c) { all_cols.split(',').forEach(function (c) {
etudiants = r + c.substring(1); etudiants = r + c.substring(1);
$(etudiants).css("display", display(r, c, row, col)); $(etudiants).css("display", display(r, c, row, col));
}) });
}) });
$('.repartition td').css("background-color", ""); $('.repartition td').css("background-color", "");
$('.repartition th').css("background-color", ""); $('.repartition th').css("background-color", "");