# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2024 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 # ############################################################################## """Vérification des absences à une évaluation """ from flask import url_for, g from flask_sqlalchemy.query import Query from app import db from app.models import Evaluation, FormSemestre, Identite, Assiduite import app.scodoc.sco_utils as scu from app.scodoc import html_sco_header from app.scodoc import sco_evaluations from app.scodoc import sco_evaluation_db from app.scodoc import sco_groups def evaluation_check_absences(evaluation: Evaluation): """Vérifie les absences au moment de cette évaluation. Cas incohérents que l'on peut rencontrer pour chaque étudiant: note et absent ABS et pas noté absent ABS et absent justifié EXC et pas noté absent EXC et pas justifie Ramene 5 listes d'etudid """ if not evaluation.date_debut or not evaluation.date_fin: return [], [], [], [], [] # evaluation sans date etudids = [ etudid for etudid, _ in sco_groups.do_evaluation_listeetuds_groups( evaluation.id, getallstudents=True ) ] deb, fin = scu.localize_datetime(evaluation.date_debut), scu.localize_datetime( evaluation.date_fin ) assiduites: Query = Assiduite.query.filter( Assiduite.etudid.in_(etudids), Assiduite.etat == scu.EtatAssiduite.ABSENT, fin >= Assiduite.date_debut, deb <= Assiduite.date_fin, ) abs_etudids = {assi.etudid for assi in assiduites} abs_nj_etudids = {assi.etudid for assi in assiduites if assi.est_just is False} just_etudids = {assi.etudid for assi in assiduites if assi.est_just is True} # Les notes: notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation.id) note_but_abs = [] # une note mais noté absent abs_non_signalee = [] # note ABS mais pas noté absent exc_non_signalee = [] # note EXC mais pas noté absent exc_non_just = [] # note EXC mais absent non justifie abs_but_exc = [] # note ABS mais justifié for etudid in etudids: if etudid in notes_db: val = notes_db[etudid]["value"] if ( val is not None and val != scu.NOTES_NEUTRALISE and val != scu.NOTES_ATTENTE ) and etudid in abs_etudids: # note valide et absent note_but_abs.append(etudid) if val is None and not etudid in abs_etudids: # absent mais pas signale comme tel abs_non_signalee.append(etudid) if val == scu.NOTES_NEUTRALISE and not etudid in abs_etudids: # Neutralisé mais pas signale absent exc_non_signalee.append(etudid) if val == scu.NOTES_NEUTRALISE and etudid in abs_nj_etudids: # EXC mais pas justifié exc_non_just.append(etudid) if val is None and etudid in just_etudids: # ABS mais justificatif abs_but_exc.append(etudid) return note_but_abs, abs_non_signalee, exc_non_signalee, exc_non_just, abs_but_exc def evaluation_check_absences_html( evaluation: Evaluation, with_header=True, show_ok=True ): """Affiche état vérification absences d'une évaluation""" ( note_but_abs, # une note alors qu'il était signalé abs abs_non_signalee, # note ABS alors que pas signalé abs exc_non_signalee, # note EXC alors que pas signalé abs exc_non_just, # note EXC alors que pas de justif abs_but_exc, # note ABS alors qu'il y a un justif ) = evaluation_check_absences(evaluation) if with_header: H = [ html_sco_header.html_sem_header( "Vérification absences à l'évaluation", formsemestre_id=evaluation.moduleimpl.formsemestre_id, ), sco_evaluations.evaluation_describe(evaluation_id=evaluation.id), """

Vérification de la cohérence entre les notes saisies et les absences signalées.

""", ] else: # pas de header, mais un titre H = [ f"""

{ evaluation.description or "évaluation" } du { evaluation.date_debut.strftime(scu.DATE_FMT) if evaluation.date_debut else "" } """ ] if ( not note_but_abs and not abs_non_signalee and not exc_non_signalee and not exc_non_just ): H.append(': ok') H.append("

") def etudlist(etudids: list[int], linkabs=False): H.append("") if note_but_abs or show_ok: H.append( "

Étudiants ayant une note alors qu'ils sont signalés absents:

" ) etudlist(note_but_abs) if abs_non_signalee or show_ok: H.append( """

Étudiants avec note "ABS" alors qu'ils ne sont pas signalés absents:

""" ) etudlist(abs_non_signalee, linkabs=True) if exc_non_signalee or show_ok: H.append( """

Étudiants avec note "EXC" alors qu'ils ne sont pas signalés absents:

""" ) etudlist(exc_non_signalee) if exc_non_just or show_ok: H.append( """

Étudiants avec note "EXC" alors qu'ils sont absents non justifiés:

""" ) etudlist(exc_non_just) if abs_but_exc or show_ok: H.append( """

Étudiants avec note "ABS" alors qu'ils ont une justification:

""" ) etudlist(abs_but_exc) if with_header: H.append(html_sco_header.sco_footer()) return "\n".join(H) def formsemestre_check_absences_html(formsemestre_id): """Affiche etat verification absences pour toutes les evaluations du semestre !""" formsemestre: FormSemestre = FormSemestre.query.filter_by( dept_id=g.scodoc_dept_id, id=formsemestre_id ).first_or_404() H = [ html_sco_header.html_sem_header( "Vérification absences aux évaluations de ce semestre", ), """

Vérification de la cohérence entre les notes saisies et les absences signalées. Sont listés tous les modules avec des évaluations.
Aucune action n'est effectuée: il vous appartient de corriger les erreurs détectées si vous le jugez nécessaire.

""", ] # Modules, dans l'ordre for modimpl in formsemestre.modimpls_sorted: if modimpl.evaluations.count() > 0: H.append( f"""

{modimpl.module.code or ""}: {modimpl.module.abbrev or ""}

""" ) for evaluation in modimpl.evaluations: H.append( evaluation_check_absences_html( evaluation, with_header=False, show_ok=False, ) ) H.append("
") H.append(html_sco_header.sco_footer()) return "\n".join(H)