Absences: option pour rendre le module concerné obligatoire

This commit is contained in:
viennet 2020-12-30 19:21:03 +01:00
parent 1ed7e3567e
commit e682b37494
3 changed files with 95 additions and 27 deletions

View File

@ -951,6 +951,7 @@ class ZAbsences(
) )
formsemestre_id = groups_infos.formsemestre_id formsemestre_id = groups_infos.formsemestre_id
require_module = self.get_preference("abs_require_module", formsemestre_id)
etuds = [ etuds = [
self.getEtudInfo(etudid=m["etudid"], filled=True)[0] self.getEtudInfo(etudid=m["etudid"], filled=True)[0]
for m in groups_infos.members for m in groups_infos.members
@ -1042,7 +1043,9 @@ class ZAbsences(
% {"menu_module": menu_module, "url": base_url, "sel": sel} % {"menu_module": menu_module, "url": base_url, "sel": sel}
) )
H += self._gen_form_saisie_groupe(etuds, datessem, destination, moduleimpl_id) H += self._gen_form_saisie_groupe(
etuds, datessem, destination, moduleimpl_id, require_module
)
H.append(self.sco_footer(REQUEST)) H.append(self.sco_footer(REQUEST))
return "\n".join(H) return "\n".join(H)
@ -1072,6 +1075,7 @@ class ZAbsences(
) )
formsemestre_id = groups_infos.formsemestre_id formsemestre_id = groups_infos.formsemestre_id
require_module = self.get_preference("abs_require_module", formsemestre_id)
etuds = [ etuds = [
self.getEtudInfo(etudid=m["etudid"], filled=True)[0] self.getEtudInfo(etudid=m["etudid"], filled=True)[0]
for m in groups_infos.members for m in groups_infos.members
@ -1200,19 +1204,32 @@ class ZAbsences(
sel = "selected" # aucun module specifie sel = "selected" # aucun module specifie
H.append( H.append(
"""<p> """<p>
Module concerné par ces absences (optionnel): <select id="moduleimpl_id" name="moduleimpl_id" onchange="document.location='%(url)s&amp;moduleimpl_id='+document.getElementById('moduleimpl_id').value"> Module concerné par ces absences (%(optionel_txt)s):
<select id="moduleimpl_id" name="moduleimpl_id"
onchange="document.location='%(url)s&amp;moduleimpl_id='+document.getElementById('moduleimpl_id').value">
<option value="" %(sel)s>non spécifié</option> <option value="" %(sel)s>non spécifié</option>
%(menu_module)s %(menu_module)s
</select> </select>
</p>""" </p>"""
% {"menu_module": menu_module, "url": base_url, "sel": sel} % {
"menu_module": menu_module,
"url": base_url,
"sel": sel,
"optionel_txt": '<span class="redboldtext">requis</span>'
if require_module
else "optionnel",
}
) )
H += self._gen_form_saisie_groupe(etuds, dates, destination, moduleimpl_id) H += self._gen_form_saisie_groupe(
etuds, dates, destination, moduleimpl_id, require_module
)
H.append(self.sco_footer(REQUEST)) H.append(self.sco_footer(REQUEST))
return "\n".join(H) return "\n".join(H)
def _gen_form_saisie_groupe(self, etuds, dates, destination="", moduleimpl_id=None): def _gen_form_saisie_groupe(
self, etuds, dates, destination="", moduleimpl_id=None, require_module=False
):
"""Formulaire saisie absences """Formulaire saisie absences
Args: Args:
@ -1223,6 +1240,9 @@ class ZAbsences(
H = [ H = [
""" """
<script type="text/javascript"> <script type="text/javascript">
$(function() {
$(".abs_form_table input").prop( "disabled", %s );
});
function colorize(obj) { function colorize(obj) {
if (obj.checked) { if (obj.checked) {
obj.parentNode.className = 'absent'; obj.parentNode.className = 'absent';
@ -1244,7 +1264,10 @@ class ZAbsences(
<table rules="cols" frame="box" class="abs_form_table"> <table rules="cols" frame="box" class="abs_form_table">
<tr><th class="formabs_contetud">%d étudiants</th> <tr><th class="formabs_contetud">%d étudiants</th>
""" """
% len(etuds) % (
"true" if (require_module and not moduleimpl_id) else "false",
len(etuds),
)
] ]
# Dates # Dates
odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates] odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates]
@ -1404,7 +1427,7 @@ class ZAbsences(
if x: if x:
return "matin" return "matin"
else: else:
return "après midi" return "après-midi"
def descr_exams(a): def descr_exams(a):
if not a.has_key("evals"): if not a.has_key("evals"):
@ -1817,12 +1840,12 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
if b["abs_begin"].hour < 12: if b["abs_begin"].hour < 12:
m = " matin" m = " matin"
else: else:
m = " après midi" m = " après-midi"
b["abs_begin_str"] = b["abs_begin"].strftime("%d/%m/%Y") + m b["abs_begin_str"] = b["abs_begin"].strftime("%d/%m/%Y") + m
if b["abs_end"].hour < 12: if b["abs_end"].hour < 12:
m = " matin" m = " matin"
else: else:
m = " après midi" m = " après-midi"
b["abs_end_str"] = b["abs_end"].strftime("%d/%m/%Y") + m b["abs_end_str"] = b["abs_end"].strftime("%d/%m/%Y") + m
if b["etat"] == 0: if b["etat"] == 0:
if b["justified"] == 0: if b["justified"] == 0:
@ -1949,7 +1972,7 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
def _ProcessBilletAbsence(self, billet, estjust, description, REQUEST): def _ProcessBilletAbsence(self, billet, estjust, description, REQUEST):
"""Traite un billet: ajoute absence(s) et éventuellement justificatifs, """Traite un billet: ajoute absence(s) et éventuellement justificatifs,
et change l'état du billet à 1. et change l'état du billet à 1.
NB: actuellement, les heures ne sont utilisées que pour déterminer si matin et/ou après midi. NB: actuellement, les heures ne sont utilisées que pour déterminer si matin et/ou après-midi.
""" """
cnx = self.GetDBConnexion() cnx = self.GetDBConnexion()
if billet["etat"] != 0: if billet["etat"] != 0:
@ -1961,7 +1984,7 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
datedebut = billet["abs_begin"].strftime("%d/%m/%Y") datedebut = billet["abs_begin"].strftime("%d/%m/%Y")
datefin = billet["abs_end"].strftime("%d/%m/%Y") datefin = billet["abs_end"].strftime("%d/%m/%Y")
dates = self.DateRangeISO(datedebut, datefin) dates = self.DateRangeISO(datedebut, datefin)
# commence apres midi ? # commence après-midi ?
if dates and billet["abs_begin"].hour > 11: if dates and billet["abs_begin"].hour > 11:
self._AddAbsence( self._AddAbsence(
billet["etudid"], dates[0], 0, estjust, REQUEST, description=description billet["etudid"], dates[0], 0, estjust, REQUEST, description=description

View File

@ -127,16 +127,47 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
# brute-force portage from very old dtml code ... # brute-force portage from very old dtml code ...
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
disabled = False
if not etud["cursem"]: if not etud["cursem"]:
menu_module = "" require_module = context.get_preference(
"abs_require_module"
) # on utilise la pref globale car pas de sem courant
if require_module:
menu_module = """<div class="ue_warning">Pas inscrit dans un semestre courant,
et l'indication du module est requise. Donc pas de saisie d'absence possible !</div>"""
disabled = True
else:
menu_module = ""
else: else:
formsemestre_id = etud["cursem"]["formsemestre_id"] formsemestre_id = etud["cursem"]["formsemestre_id"]
require_module = context.get_preference("abs_require_module", formsemestre_id)
nt = context.Notes._getNotesCache().get_NotesTable( nt = context.Notes._getNotesCache().get_NotesTable(
context.Notes, formsemestre_id context.Notes, formsemestre_id
) )
ues = nt.get_ues(etudid=etudid) ues = nt.get_ues(etudid=etudid)
menu_module = """<p><select name="moduleimpl_id"> if require_module:
<option value="NULL" selected>(Module)</option>""" menu_module = """
<script type="text/javascript">
function form_enable_disable() {
if ( $("select#sel_moduleimpl_id").val() == "NULL" ) {
$("#butsubmit").prop("disabled", true);
} else {
$("#butsubmit").prop("disabled", false);
};
}
$(document).ready(function() {
form_enable_disable();
});
</script>
<p>Module:
<select id="sel_moduleimpl_id" name="moduleimpl_id"
onChange="form_enable_disable();">"""
else:
menu_module = (
"""<p>Module: <select id="sel_moduleimpl_id" name="moduleimpl_id">"""
)
menu_module += """<option value="NULL" selected>(Module)</option>"""
for ue in ues: for ue in ues:
modimpls = nt.get_modimpls(ue_id=ue["ue_id"]) modimpls = nt.get_modimpls(ue_id=ue["ue_id"])
for modimpl in modimpls: for modimpl in modimpls:
@ -171,35 +202,40 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
<input type="hidden" name="etudid" value="%(etudid)s"> <input type="hidden" name="etudid" value="%(etudid)s">
<p> <p>
<table><tr> <table><tr>
<td>Date d&eacute;but : </td> <td>Date début : </td>
<td><input type="text" name="datedebut" size="10" class="datepicker"/> <em>j/m/a</em></td> <td><input type="text" name="datedebut" size="10" class="datepicker"/> <em>j/m/a</em></td>
<td>&nbsp;&nbsp;&nbsp;Date Fin (optionnel):</td> <td>&nbsp;&nbsp;&nbsp;Date fin (optionnelle):</td>
<td><input type="text" name="datefin" size="10" class="datepicker"/> <em>j/m/a</em></td> <td><input type="text" name="datefin" size="10" class="datepicker"/> <em>j/m/a</em></td>
</tr> </tr>
</table> </table>
<br/> <br/>
<input type="radio" name="demijournee" value="2" checked>journ&eacute;e(s) <input type="radio" name="demijournee" value="2" checked>Journée(s)
&nbsp;<input type="radio" name="demijournee" value="1">Matin(s) &nbsp;<input type="radio" name="demijournee" value="1">Matin(s)
&nbsp;<input type="radio" name="demijournee" value="0">Apr&egrave;s midi &nbsp;<input type="radio" name="demijournee" value="0">Après-midi
%(menu_module)s %(menu_module)s
<p> <p>
<input type="checkbox" name="estjust"/>Absence justifi&eacute;e. <input type="checkbox" name="estjust"/>Absence justifiée.
<br/> <br/>
Raison: <input type="text" name="description" size="42"/> (optionnel) Raison: <input type="text" name="description" size="42"/> (optionnel)
</p> </p>
<p> <p>
<input type="submit" value="Envoyer"/> <input id="butsubmit" type="submit" value="Envoyer" disable="%(disabled)s"/>
<em> <em>
<p>Seuls les modules du semestre en cours apparaissent.</p><p> Evitez de saisir une absence pour un module qui n'est pas en place à cette date.</p> <p>Seuls les modules du semestre en cours apparaissent.</p>
<p>Toutes les dates sont au format jour/mois/annee</p> <p>Évitez de saisir une absence pour un module qui n'est pas en place à cette date.</p>
<p>Toutes les dates sont au format jour/mois/annee.</p>
</em> </em>
</form> </form>
""" """
% {"etudid": etud["etudid"], "menu_module": menu_module}, % {
"etudid": etud["etudid"],
"menu_module": menu_module,
"disabled": "disabled" if disabled else "",
},
context.sco_footer(REQUEST), context.sco_footer(REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -311,7 +347,7 @@ def JustifAbsenceEtud(context, REQUEST=None): # etudid implied
</table> </table>
<br/> <br/>
<input type="radio" name="demijournee" value="2" checked>journ&eacute;e(s) <input type="radio" name="demijournee" value="2" checked>Journée(s)
&nbsp;<input type="radio" name="demijournee" value="1">Matin(s) &nbsp;<input type="radio" name="demijournee" value="1">Matin(s)
&nbsp;<input type="radio" name="demijournee" value="0">Apr&egrave;s midi &nbsp;<input type="radio" name="demijournee" value="0">Apr&egrave;s midi
@ -473,7 +509,7 @@ def doAnnuleJustif(
dates = context.DateRangeISO(datedebut0, datefin0) dates = context.DateRangeISO(datedebut0, datefin0)
nbadded = 0 nbadded = 0
for jour in dates: for jour in dates:
# Attention: supprime matin et après midi # Attention: supprime matin et après-midi
if demijournee == "2": if demijournee == "2":
context._AnnuleJustif(etudid, jour, False, REQUEST=REQUEST) context._AnnuleJustif(etudid, jour, False, REQUEST=REQUEST)
context._AnnuleJustif(etudid, jour, True, REQUEST=REQUEST) context._AnnuleJustif(etudid, jour, True, REQUEST=REQUEST)
@ -553,7 +589,6 @@ def formChoixSemestreGroupe(context, all=False):
if not sems: if not sems:
raise ScoValueError("aucun semestre !") raise ScoValueError("aucun semestre !")
H = ['<select name="group_ids">'] H = ['<select name="group_ids">']
nbgroups = 0
for sem in sems: for sem in sems:
for p in sco_groups.get_partitions_list(context, sem["formsemestre_id"]): for p in sco_groups.get_partitions_list(context, sem["formsemestre_id"]):
for group in sco_groups.get_partition_groups(context, p): for group in sco_groups.get_partition_groups(context, p):

View File

@ -305,6 +305,17 @@ PREFS = (
"only_global": True, # devrait etre par semestre, mais demanderait modif gestion absences "only_global": True, # devrait etre par semestre, mais demanderait modif gestion absences
}, },
), ),
(
"abs_require_module", # affecte l'UI mais pas les fonctions de base
{
"initvalue": 0,
"title": "Imposer l'indication du module lors de la saisie des absences",
"input_type": "boolcheckbox",
"labels": ["non", "oui"],
"category": "abs",
"only_global": False,
},
),
( (
"handle_billets_abs", "handle_billets_abs",
{ {
@ -369,7 +380,6 @@ PREFS = (
"title": "Notifier à:", "title": "Notifier à:",
"explanation": "e-mail à qui envoyer des notification d'absences (en sus des autres destinataires éventuels, comme le chef etc.)", "explanation": "e-mail à qui envoyer des notification d'absences (en sus des autres destinataires éventuels, comme le chef etc.)",
"size": 40, "size": 40,
"explanation": "utilisé pour envoi mail absences",
"category": "abs", "category": "abs",
}, },
), ),