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 re
import time
import datetime
import dateutil
import dateutil.parser
import calendar
from mx.DateTime import DateTime as mxDateTime
from mx.DateTime.ISO import ParseDateTimeUTC
import urllib
import cgi
import jaxml
# ---------------
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)
etud = etuds[0]
# check dates
begin_date = ParseDateTimeUTC(begin) # may raises ValueError
end_date = ParseDateTimeUTC(end)
begin_date = dateutil.parser.isoparse(begin) # may raises ValueError
end_date = dateutil.parser.isoparse(end)
if begin_date > end_date:
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-requests
apt-get -y install python-egenix-mxtools python-egenix-mxdatetime
# ------------
SVNVERSION=$(cd ..; svnversion)

View File

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

View File

@ -56,10 +56,21 @@ def doSignaleAbsence(
demijournee=2,
estjust=False,
description=None,
etudid=False,
REQUEST=None,
): # etudid implied
"""Signalement d'une absence"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
"""Signalement d'une absence.
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"]
description_abs = description
@ -247,10 +258,25 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doJustifAbsence(
context, datedebut, datefin, demijournee, description=None, REQUEST=None
context,
datedebut,
datefin,
demijournee,
description=None,
etudid=False,
REQUEST=None,
): # etudid implied
"""Justification d'une absence"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
"""Justification d'une absence
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"]
description_abs = description
dates = sco_abs.DateRangeISO(context, datedebut, datefin)
@ -370,10 +396,10 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
def doAnnuleAbsence(
context, datedebut, datefin, demijournee, REQUEST=None
context, datedebut, datefin, demijournee, etudid=False, REQUEST=None
): # etudid implied
"""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"]
dates = sco_abs.DateRangeISO(context, datedebut, datefin)

View File

@ -47,8 +47,7 @@
"""
import os
import time
from mx.DateTime import DateTime as mxDateTime
import mx.DateTime
import datetime
import re
import shutil
import glob
@ -140,7 +139,7 @@ class BaseArchiver:
def get_archive_date(self, archive_id):
"""Returns date (as a DateTime object) of an archive"""
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):
"""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).
"""
import json
from sco_portal_apogee import get_inscrits_etape
from notes_log import log
@ -540,7 +541,7 @@ class EtapeBilan:
ind_col,
comptage,
"",
self.titres[ind_col].replace("<br/>", " / "),
json.dumps(self.titres[ind_col].replace("<br/>", " / "))[1:-1],
)
elif ind_col == COL_CUMUL:
javascript = "doFiltrage(%s, %s, '.%s', '*', '%s', '%s', '%s');" % (
@ -548,7 +549,7 @@ class EtapeBilan:
self.all_cols_str,
ind_row,
" (%d étudiants)" % count,
self.titres[ind_row],
json.dumps(self.titres[ind_row])[1:-1],
"",
)
else:
@ -558,10 +559,10 @@ class EtapeBilan:
ind_row,
ind_col,
comptage,
self.titres[ind_row],
self.titres[ind_col].replace("<br/>", " / "),
json.dumps(self.titres[ind_row])[1:-1],
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):
H = []

View File

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

View File

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

View File

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

View File

@ -543,15 +543,15 @@ class ScoDocJSONEncoder(json.JSONEncoder):
def default(self, o): # pylint: disable=E0202
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'>":
log("Warning: mx.DateTime object detected !")
return o.strftime("%Y-%m-%dT%H:%M:%S")
if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat()
elif isinstance(o, sco_formsemestre.ApoEtapeVDI):
return str(o)
else:
log("not mx: %s" % type(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 sco_utils
import sco_abs
import sco_abs_views
G = sco_fake_gen.ScoFake(context.Notes) # pylint: disable=undefined-variable
G.verbose = False
@ -64,3 +66,28 @@ for etud in etuds:
nb_changed, nb_suppress, existing_decisions = G.create_note(
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() {
$( "div#export_help" ).accordion( {
$(function () {
$("div#export_help").accordion({
heightStyle: "content",
collapsible: true,
active: false,
@ -21,8 +21,8 @@ function display(r, c, row, col) {
function show_tag(all_rows, all_cols, tag) {
// Filtrer tous les étudiants
all_rows.split(',').forEach(function(r) {
all_cols.split(',').forEach(function(c) {
all_rows.split(',').forEach(function (r) {
all_cols.split(',').forEach(function (c) {
etudiants = r + c.substring(1);
$(etudiants).css("display", "none");
})
@ -34,36 +34,36 @@ function show_tag(all_rows, all_cols, tag) {
function show_filtres(effectifs, filtre_row, filtre_col) {
$("#compte").html(effectifs);
if ((filtre_row == '') && (filtre_col == '')) {
$("#sans_filtre").css("display", "");
$("#filtre_row").css("display", "none");
$("#filtre_col").css("display", "none");
$("#sans_filtre").css("display", "");
$("#filtre_row").css("display", "none");
$("#filtre_col").css("display", "none");
} else {
$("#sans_filtre").css("display", "none");
if (filtre_row == '') {
$("#filtre_row").css("display", "none");
$("#filtre_col").css("display", "");
$("#filtre_col").html("Filtre sur code étape: " + filtre_col);
} else if (filtre_col == '') {
$("#filtre_row").css("display", "");
$("#filtre_col").css("display", "none");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row);
} else {
$("#filtre_row").css("display", "");
$("#filtre_col").css("display", "");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row);
$("#filtre_col").html("Filtre sur code étape: " + filtre_col);
}
$("#sans_filtre").css("display", "none");
if (filtre_row == '') {
$("#filtre_row").css("display", "none");
$("#filtre_col").css("display", "");
$("#filtre_col").html("Filtre sur code étape: " + filtre_col);
} else if (filtre_col == '') {
$("#filtre_row").css("display", "");
$("#filtre_col").css("display", "none");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row);
} else {
$("#filtre_row").css("display", "");
$("#filtre_col").css("display", "");
$("#filtre_row").html("Filtre sur semestre: " + filtre_row);
$("#filtre_col").html("Filtre sur code étape: " + filtre_col);
}
}
}
function doFiltrage(all_rows, all_cols, row, col, effectifs, filtre_row, filtre_col) {
show_filtres(effectifs, filtre_row, filtre_col)
all_rows.split(',').forEach(function(r) {
all_cols.split(',').forEach(function(c) {
all_rows.split(',').forEach(function (r) {
all_cols.split(',').forEach(function (c) {
etudiants = r + c.substring(1);
$(etudiants).css("display", display(r, c, row, col));
})
})
});
});
$('.repartition td').css("background-color", "");
$('.repartition th').css("background-color", "");