diff --git a/ZAbsences.py b/ZAbsences.py index 049875327..e9cd2f378 100644 --- a/ZAbsences.py +++ b/ZAbsences.py @@ -67,6 +67,7 @@ from sco_permissions import ScoAbsAddBillet, ScoAbsChange, ScoView from sco_exceptions import ScoValueError, ScoInvalidDateError from TrivialFormulator import TrivialFormulator, TF from gen_tables import GenTable +import html_sco_header import scolars import sco_formsemestre import sco_moduleimpl @@ -78,6 +79,8 @@ import sco_compute_moy import sco_abs from sco_abs import ddmmyyyy +CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS + def _toboolean(x): "convert a value to boolean (ensure backward compat with OLD intranet code)" @@ -343,11 +346,17 @@ class ZAbsences( ) cnx.commit() - security.declareProtected(ScoView, "CountAbs") + def ListAbsInRange( + self, etudid, debut, fin, matin=None, moduleimpl_id=None, cursor=None + ): + """Liste des absences entre deux dates. - def CountAbs(self, etudid, debut, fin, matin=None, moduleimpl_id=None): - """CountAbs - matin= 1 ou 0. + Args: + etudid + debut string iso date ("2020-03-12") + end string iso date ("2020-03-12") + matin None, True, False + moduleimpl_id """ if matin != None: matin = _toboolean(matin) @@ -358,10 +367,11 @@ class ZAbsences( modul = " AND A.MODULEIMPL_ID = %(moduleimpl_id)s " else: modul = "" - cnx = self.GetDBConnexion() - cursor = cnx.cursor(cursor_factory=notesdb.ScoDocCursor) + if not cursor: + cnx = self.GetDBConnexion() + cursor = cnx.cursor(cursor_factory=notesdb.ScoDocCursor) cursor.execute( - """SELECT COUNT(*) AS NbAbs FROM ( + """ SELECT DISTINCT A.JOUR, A.MATIN FROM ABSENCES A WHERE A.ETUDID = %(etudid)s @@ -370,13 +380,27 @@ class ZAbsences( + modul + """ AND A.JOUR BETWEEN %(debut)s AND %(fin)s - ) AS tmp """, vars(), ) - res = cursor.fetchone()[0] + res = cursor.dictfetchall() return res + security.declareProtected(ScoView, "CountAbs") + + def CountAbs(self, etudid, debut, fin, matin=None, moduleimpl_id=None): + """CountAbs + matin= 1 ou 0. + + Returns: + An integer. + """ + return len( + self.ListAbsInRange( + etudid, debut, fin, matin=matin, moduleimpl_id=moduleimpl_id + ) + ) + security.declareProtected(ScoView, "CountAbsJust") def CountAbsJust(self, etudid, debut, fin, matin=None, moduleimpl_id=None): @@ -743,27 +767,48 @@ class ZAbsences( else: p = "du groupe" gr_tit = ( - p + '' + groups_infos.groups_titles + "" + p + ' ' + groups_infos.groups_titles + "" ) H = [ self.sco_header( page_title="Saisie hebdomadaire des absences", init_qtip=True, - javascripts=["js/etud_info.js", "js/abs_ajax.js"], + javascripts=html_sco_header.BOOTSTRAP_MULTISELECT_JS + + [ + "js/etud_info.js", + "js/abs_ajax.js", + "js/groups_view.js", + ], + cssstyles=CSSSTYLES, no_side_bar=1, REQUEST=REQUEST, ), """' ) i = 1 + cnx = self.GetDBConnexion() + cursor = cnx.cursor(cursor_factory=notesdb.ScoDocCursor) for etud in etuds: i += 1 etudid = etud["etudid"] @@ -1101,17 +1149,20 @@ class ZAbsences( '' % (tr_class, etudid, etudid, etud["nomprenom"], capstr) ) - for date in dates: + etud_abs = self.ListAbsInRange( + etudid, begin, end, moduleimpl_id=moduleimpl_id, cursor=cursor + ) + for d in odates: + date = d.strftime("%Y-%m-%d") # matin - if self.CountAbs(etudid, date, date, True, moduleimpl_id=moduleimpl_id): + is_abs = {"jour": d, "matin": True} in etud_abs + if is_abs: checked = "checked" else: checked = "" # bulle lors du passage souris - coljour = sco_abs.DAYNAMES[ - (calendar.weekday(int(date[:4]), int(date[5:7]), int(date[8:]))) - ] - datecol = coljour + " " + date[8:] + "/" + date[5:7] + "/" + date[:4] + coljour = sco_abs.DAYNAMES[(calendar.weekday(d.year, d.month, d.day))] + datecol = coljour + " " + d.strftime("%d/%m/%Y") bulle_am = '"' + etud["nomprenom"] + " - " + datecol + ' (matin)"' bulle_pm = '"' + etud["nomprenom"] + " - " + datecol + ' (ap.midi)"' @@ -1127,9 +1178,8 @@ class ZAbsences( ) ) # après-midi - if self.CountAbs( - etudid, date, date, False, moduleimpl_id=moduleimpl_id - ): + is_abs = {"jour": d, "matin": False} in etud_abs + if is_abs: checked = "checked" else: checked = "" diff --git a/gen_tables.py b/gen_tables.py index fbd8309c7..4e013c678 100644 --- a/gen_tables.py +++ b/gen_tables.py @@ -534,14 +534,6 @@ class GenTable: ) ] pdf_style_list += self.pdf_table_style - # log('len(Pt)=%s' % len(Pt)) - # log( 'line lens=%s' % [ len(x) for x in Pt ] ) - # log( 'style=\n%s' % pdf_style_list) - # col_min = min([x[1][0] for x in pdf_style_list]) - # col_max = max([x[2][0] for x in pdf_style_list]) - # lin_min = min([x[1][1] for x in pdf_style_list]) - # lin_max = max([x[2][1] for x in pdf_style_list]) - # log('col_min=%s col_max=%s lin_min=%s lin_max=%s' % (col_min, col_max, lin_min, lin_max)) T = Table(Pt, repeatRows=1, colWidths=self.pdf_col_widths, style=pdf_style_list) objects = [] diff --git a/static/js/abs_ajax.js b/static/js/abs_ajax.js index 5b8f030f2..a6f99fe8b 100644 --- a/static/js/abs_ajax.js +++ b/static/js/abs_ajax.js @@ -2,20 +2,20 @@ // JS Ajax code for SignaleAbsenceGrSemestre // Contributed by YLB -function ajaxFunction(mod, etudid, dat){ +function ajaxFunction(mod, etudid, dat) { var ajaxRequest; // The variable that makes Ajax possible! - - try{ + + try { // Opera 8.0+, Firefox, Safari ajaxRequest = new XMLHttpRequest(); - } catch (e){ + } catch (e) { // Internet Explorer Browsers - try{ + try { ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { - try{ + try { ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e){ + } catch (e) { // Something went wrong alert("Your browser broke!"); return false; @@ -23,22 +23,26 @@ function ajaxFunction(mod, etudid, dat){ } } // Create a function that will receive data sent from the server - ajaxRequest.onreadystatechange = function(){ - if(ajaxRequest.readyState == 4 && ajaxRequest.status == 200){ - document.getElementById("AjaxDiv").innerHTML=ajaxRequest.responseText; + ajaxRequest.onreadystatechange = function () { + if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200) { + document.getElementById("AjaxDiv").innerHTML = ajaxRequest.responseText; } } ajaxRequest.open("POST", "doSignaleAbsenceGrSemestre", true); - ajaxRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded"); - oForm = document.forms[0]; + ajaxRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + oForm = document.forms[1]; oSelectOne = oForm.elements["moduleimpl_id"]; index = oSelectOne.selectedIndex; - modul_id = oSelectOne.options[index].value; + modul_id = oSelectOne.options[index].value; if (mod == 'add') { - ajaxRequest.send("reply=0&moduleimpl_id=" + modul_id +"&abslist:list=" + etudid + ":" + dat); + ajaxRequest.send("reply=0&moduleimpl_id=" + modul_id + "&abslist:list=" + etudid + ":" + dat); } if (mod == 'remove') { - ajaxRequest.send("reply=0&moduleimpl_id=" + modul_id +"&etudids=" + etudid + "&dates=" + dat); + ajaxRequest.send("reply=0&moduleimpl_id=" + modul_id + "&etudids=" + etudid + "&dates=" + dat); } } +// ----- +function change_moduleimpl(url) { + document.location = url + '&moduleimpl_id=' + document.getElementById('moduleimpl_id').value; +}
-

Saisie des absences %s %s, - semaine du lundi %s

- -

Annuler

- -

-

- """ - % (gr_tit, sem["titre_num"], datelundi, REQUEST.URL0), +

Saisie des absences %s %s, + semaine du lundi %s

+
+ + + + + + Groupes: %s + +
+ """ + % ( + gr_tit, + sem["titre_num"], + datelundi, + groups_infos.formsemestre_id, + datelundi, + destination, + moduleimpl_id or "", + sco_groups_view.menu_groups_choice( + self, groups_infos, submit_on_change=True + ), + ), ] # modimpls_list = [] @@ -802,12 +847,12 @@ class ZAbsences( sel = "selected" # aucun module specifie H.append( - """ - Module concerné par ces absences (optionnel): -

""" + """Module concerné: + +
""" % {"menu_module": menu_module, "url": base_url, "sel": sel} ) @@ -831,7 +876,6 @@ class ZAbsences( REQUEST=None, ): """Saisie des absences sur une journée sur un semestre (ou intervalle de dates) entier""" - # log('SignaleAbsenceGrSemestre: moduleimpl_id=%s destination=%s' % (moduleimpl_id, destination)) groups_infos = sco_groups_view.DisplayedGroupsInfos( self, group_ids, REQUEST=REQUEST ) @@ -1011,7 +1055,7 @@ class ZAbsences( Args: etuds: liste des étudiants - dates: liste de dates iso, par exemple: [ '2020-12-24', ... ] + dates: liste ordonnée de dates iso, par exemple: [ '2020-12-24', ... ] moduleimpl_id: optionnel, module concerné. """ H = [ @@ -1048,6 +1092,8 @@ class ZAbsences( ] # Dates odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates] + begin = dates[0] + end = dates[-1] # Titres colonnes noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ] jn = sco_abs.day_names(self) @@ -1076,6 +1122,8 @@ class ZAbsences( '
Aucun étudiant inscrit !
%s%s