# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2020 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 # ############################################################################## """ Gestion des absences (v4) C'est la partie la plus ancienne de ScoDoc, et elle est à revoir. L'API de plus bas niveau est en gros: AnnuleAbsencesDatesNoJust(etudid, dates) CountAbs(etudid, debut, fin, matin=None, moduleimpl_id=None) CountAbsJust(etudid, debut, fin, matin=None, moduleimpl_id=None) ListeAbsJust(etudid, datedebut) [pas de fin ?] ListeAbsNonJust(etudid, datedebut) [pas de fin ?] ListeJustifs(etudid, datedebut, datefin=None, only_no_abs=True) ListeAbsJour(date, am=True, pm=True, is_abs=None, is_just=None) ListeAbsNonJustJour(date, am=True, pm=True) """ import urllib import datetime import jaxml # --------------- from sco_zope import * # --------------- import sco_utils as scu import notesdb from notes_log import log from scolog import logdb from sco_permissions import ScoAbsAddBillet, ScoAbsChange, ScoView from sco_exceptions import ScoValueError, ScoInvalidDateError from TrivialFormulator import TrivialFormulator, TF from gen_tables import GenTable import scolars import sco_formsemestre import sco_groups import sco_groups_view import sco_excel import sco_abs_notification, sco_abs_views import sco_compute_moy import string, re import time, calendar from mx.DateTime import DateTime as mxDateTime from mx.DateTime.ISO import ParseDateTimeUTC def _toboolean(x): "convert a value to boolean (ensure backward compat with OLD intranet code)" if type(x) == type(""): x = x.lower() if x and x != "false": # backward compat... return True else: return False def MonthNbDays(month, year): "returns nb of days in month" if month > 7: month = month + 1 if month % 2: return 31 elif month == 2: if calendar.isleap(year): return 29 else: return 28 else: return 30 class ddmmyyyy: """immutable dates""" def __init__(self, date=None, fmt="ddmmyyyy", work_saturday=False): self.work_saturday = work_saturday if date is None: return try: if fmt == "ddmmyyyy": self.day, self.month, self.year = string.split(date, "/") elif fmt == "iso": self.year, self.month, self.day = string.split(date, "-") else: raise ValueError("invalid format spec. (%s)" % fmt) self.year = string.atoi(self.year) self.month = string.atoi(self.month) self.day = string.atoi(self.day) except: raise ScoValueError("date invalide: %s" % date) # accept years YYYY or YY, uses 1970 as pivot if self.year < 1970: if self.year > 100: raise ScoInvalidDateError("Année invalide: %s" % self.year) if self.year < 70: self.year = self.year + 2000 else: self.year = self.year + 1900 if self.month < 1 or self.month > 12: raise ScoInvalidDateError("Mois invalide: %s" % self.month) if self.day < 1 or self.day > MonthNbDays(self.month, self.year): raise ScoInvalidDateError("Jour invalide: %s" % self.day) # weekday in 0-6, where 0 is monday self.weekday = calendar.weekday(self.year, self.month, self.day) self.time = time.mktime((self.year, self.month, self.day, 0, 0, 0, 0, 0, 0)) def iswork(self): "returns true if workable day" if self.work_saturday: nbdays = 6 else: nbdays = 5 if ( self.weekday >= 0 and self.weekday < nbdays ): # monday-friday or monday-saturday return 1 else: return 0 def __repr__(self): return "'%02d/%02d/%04d'" % (self.day, self.month, self.year) def __str__(self): return "%02d/%02d/%04d" % (self.day, self.month, self.year) def ISO(self): "iso8601 representation of the date" return "%04d-%02d-%02d" % (self.year, self.month, self.day) def next(self, days=1): "date for the next day (nota: may be a non workable day)" day = self.day + days month = self.month year = self.year while day > MonthNbDays(month, year): day = day - MonthNbDays(month, year) month = month + 1 if month > 12: month = 1 year = year + 1 return self.__class__( "%02d/%02d/%04d" % (day, month, year), work_saturday=self.work_saturday ) def prev(self, days=1): "date for previous day" day = self.day - days month = self.month year = self.year while day <= 0: month = month - 1 if month == 0: month = 12 year = year - 1 day = day + MonthNbDays(month, year) return self.__class__( "%02d/%02d/%04d" % (day, month, year), work_saturday=self.work_saturday ) def next_monday(self): "date of next monday" return self.next((7 - self.weekday) % 7) def prev_monday(self): "date of last monday, but on sunday, pick next monday" if self.weekday == 6: return self.next_monday() else: return self.prev(self.weekday) def __cmp__(self, other): """return a negative integer if self < other, zero if self == other, a positive integer if self > other""" return int(self.time - other.time) def __hash__(self): "we are immutable !" return hash(self.time) ^ hash(str(self)) # d = ddmmyyyy( '21/12/99' ) def YearTable( context, year, events=[], firstmonth=9, lastmonth=7, halfday=0, dayattributes="", pad_width=8, ): """Generate a calendar table events = list of tuples (date, text, color, href [,halfday]) where date is a string in ISO format (yyyy-mm-dd) halfday is boolean (true: morning, false: afternoon) text = text to put in calendar (must be short, 1-5 cars) (optional) if halfday, generate 2 cells per day (morning, afternoon) """ T = [ '
') T.append(MonthTableHead(month)) T.append( MonthTableBody( month, year, events, halfday, dayattributes, context.is_work_saturday(), pad_width=pad_width, ) ) T.append(MonthTableTail()) T.append(" | ") if month == lastmonth: break month = month + 1 if month > 12: month = 1 year = year + 1 T.append("
Saisie des absences %s %s, semaine du lundi %s
|
Justifs non utilisés: nombre de demi-journées avec justificatif mais sans absences relevées.
Cliquez sur un nom pour afficher le calendrier des absences
ou entrez une date pour visualiser les absents un jour donné :
Matin | Après-midi | |
---|---|---|
%(nomprenom)s | """ % etud ) # """ if nbabsam != 0: if nbabsjustam: H.append("Just.") t_nbabsjustam += 1 else: H.append("Abs.") t_nbabsam += 1 else: H.append("") H.append(' | ') if nbabspm != 0: if nbabsjustpm: H.append("Just.") t_nbabsjustam += 1 else: H.append("Abs.") t_nbabspm += 1 else: H.append("") H.append(" |
%d abs, %d just. | %d abs, %d just. |
Aucune absence !
") else: H.append( """L'étudiant pense pouvoir justifier cette absence.
Vérifiez le justificatif avant d'enregistrer.
Supprimer ce billet (utiliser en cas d'erreur, par ex. billet en double)
""" % billet_id ) F += 'Liste de tous les billets en attente
' return "\n".join(H) + "%s |