Assiduité: ajouts de commentaires et très léger refactoring

This commit is contained in:
Emmanuel Viennet 2023-09-20 22:38:01 +02:00
parent 7a9c399812
commit 104b5f2f95
2 changed files with 78 additions and 43 deletions

View File

@ -383,7 +383,7 @@ class ScoDocSiteConfig(db.Model):
cls.set("personalized_links", "") cls.set("personalized_links", "")
raise ScoValueError( raise ScoValueError(
"Attention: liens personnalisés erronés: ils ont été effacés." "Attention: liens personnalisés erronés: ils ont été effacés."
) ) from exc
return [PersonalizedLink(**item) for item in links_dict] return [PersonalizedLink(**item) for item in links_dict]
@classmethod @classmethod
@ -395,6 +395,24 @@ class ScoDocSiteConfig(db.Model):
data_links = json.dumps(links_dict) data_links = json.dumps(links_dict)
cls.set("personalized_links", data_links) cls.set("personalized_links", data_links)
@classmethod
def assi_get_rounded_time(cls, label: str, default: str) -> float:
"Donne l'heure stockée dans la config globale sous label, en float arrondi au quart d'heure"
_round_time_str_to_quarter(cls.get(label, default))
def _round_time_str_to_quarter(string: str) -> float:
"""Prend une heure iso '12:20:23', et la converti en un nombre d'heures
en arrondissant au quart d'heure: (les secondes sont ignorées)
"12:20:00" -> 12.25
"12:29:00" -> 12.25
"12:30:00" -> 12.5
"""
parts = [*map(float, string.split(":"))]
hour = parts[0]
minutes = round(parts[1] / 60 * 4) / 4
return hour + minutes
class PersonalizedLink: class PersonalizedLink:
def __init__(self, title: str = "", url: str = "", with_args: bool = False): def __init__(self, title: str = "", url: str = "", with_args: bool = False):

View File

@ -1,3 +1,29 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2023 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
# module codé par Matthias Hartmann, 2023
#
##############################################################################
import datetime import datetime
from flask import g, request, render_template, flash from flask import g, request, render_template, flash
@ -18,7 +44,6 @@ from app.models import (
Assiduite, Assiduite,
Justificatif, Justificatif,
Departement, Departement,
FormSemestreInscription,
Evaluation, Evaluation,
) )
from app.views import assiduites_bp as bp from app.views import assiduites_bp as bp
@ -304,9 +329,11 @@ def signal_assiduites_etud():
# Gestion des horaires (journée, matin, soir) # Gestion des horaires (journée, matin, soir)
morning = get_time("assi_morning_time", "08:00:00") morning = ScoDocSiteConfig.assi_get_rounded_time("assi_morning_time", "08:00:00")
lunch = get_time("assi_lunch_time", "13:00:00") lunch = ScoDocSiteConfig.assi_get_rounded_time("assi_lunch_time", "13:00:00")
afternoon = get_time("assi_afternoon_time", "18:00:00") afternoon = ScoDocSiteConfig.assi_get_rounded_time(
"assi_afternoon_time", "18:00:00"
)
select = """ select = """
<select class="dynaSelect"> <select class="dynaSelect">
@ -1360,8 +1387,8 @@ def _dynamic_module_selector():
def _timeline(formsemestre_id=None) -> HTMLElement: def _timeline(formsemestre_id=None) -> HTMLElement:
return render_template( return render_template(
"assiduites/widgets/timeline.j2", "assiduites/widgets/timeline.j2",
t_start=get_time("assi_morning_time", "08:00:00"), t_start=ScoDocSiteConfig.assi_get_rounded_time("assi_morning_time", "08:00:00"),
t_end=get_time("assi_afternoon_time", "18:00:00"), t_end=ScoDocSiteConfig.assi_get_rounded_time("assi_afternoon_time", "18:00:00"),
tick_time=ScoDocSiteConfig.get("assi_tick_time", 15), tick_time=ScoDocSiteConfig.get("assi_tick_time", 15),
periode_defaut=sco_preferences.get_preference( periode_defaut=sco_preferences.get_preference(
"periode_defaut", formsemestre_id "periode_defaut", formsemestre_id
@ -1372,49 +1399,39 @@ def _timeline(formsemestre_id=None) -> HTMLElement:
def _mini_timeline() -> HTMLElement: def _mini_timeline() -> HTMLElement:
return render_template( return render_template(
"assiduites/widgets/minitimeline.j2", "assiduites/widgets/minitimeline.j2",
t_start=get_time("assi_morning_time", "08:00:00"), t_start=ScoDocSiteConfig.assi_get_rounded_time("assi_morning_time", "08:00:00"),
t_end=get_time("assi_afternoon_time", "18:00:00"), t_end=ScoDocSiteConfig.assi_get_rounded_time("assi_afternoon_time", "18:00:00"),
) )
def _non_work_days(): def _non_work_days() -> str:
non_travail = sco_preferences.get_preference("non_travail", None) """Abbréviation des jours non travaillés: "'sam','dim'".
donnés par les préférences du département
"""
non_travail = sco_preferences.get_preference("non_travail")
non_travail = non_travail.replace(" ", "").split(",") non_travail = non_travail.replace(" ", "").split(",")
return ",".join([f"'{i.lower()}'" for i in non_travail]) return ",".join([f"'{i.lower()}'" for i in non_travail])
def _str_to_num(string: str): def _get_seuil() -> int:
parts = [*map(float, string.split(":"))] """Seuil d'alerte des absences (en unité de la métrique),
hour = parts[0] tel que fixé dans les préférences du département."""
minutes = round(parts[1] / 60 * 4) / 4
return hour + minutes
def get_time(label: str, default: str):
return _str_to_num(ScoDocSiteConfig.get(label, default))
def _get_seuil():
return sco_preferences.get_preference("assi_seuil", dept_id=g.scodoc_dept_id) return sco_preferences.get_preference("assi_seuil", dept_id=g.scodoc_dept_id)
def _get_etuds_dem_def(formsemestre): def _get_etuds_dem_def(formsemestre) -> str:
etuds_dem_def = [ """Une chaine json donnant les étudiants démissionnaires ou défaillants
(f.etudid, f.etat) du formsemestre, sous la forme
for f in FormSemestreInscription.query.filter( '{"516" : "D", ... }'
FormSemestreInscription.formsemestre_id == formsemestre.id, """
FormSemestreInscription.etat != "I", return (
).all() "{"
] + ", ".join(
[
template: str = '"£" : "$",' f'"{ins.etudid}" : "{ins.etat}"'
for ins in formsemestre.inscriptions
json_str: str = "{" if ins.etat != scu.INSCRIT
]
for etud in etuds_dem_def: )
json_str += template.replace("£", str(etud[0])).replace("$", etud[1]) + "}"
)
if json_str != "{":
json_str = json_str[:-1]
return json_str + "}"