# -*- 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 # ############################################################################## """Saisie et gestion des semestres extérieurs à ScoDoc dans un parcours. On va créer/gérer des semestres de la même formation que le semestre ScoDoc où est inscrit l'étudiant, leur attribuer la modalité 'EXT'. Ces semestres n'auront qu'un seul inscrit ! """ import time import flask from flask import flash, g, render_template, request, url_for from flask_login import current_user from app.comp import res_sem from app.comp.res_compat import NotesTableCompat from app.models import ( Formation, FormSemestre, FormSemestreUECoef, Identite, ScolarFormSemestreValidation, UniteEns, ) import app.scodoc.sco_utils as scu from app import log from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_validation from app.scodoc.codes_cursus import UE_SPORT def formsemestre_ext_create(etud: Identite | None, sem_params: dict) -> FormSemestre: """Crée un formsemestre exterieur et y inscrit l'étudiant. sem_params: dict nécessaire à la création du formsemestre """ # Check args _ = Formation.query.get_or_404(sem_params["formation_id"]) # Create formsemestre sem_params["modalite"] = "EXT" sem_params["etapes"] = None sem_params["responsables"] = [current_user.id] formsemestre = FormSemestre.create_formsemestre(sem_params, silent=True) # nota: le semestre est créé vide: pas de modules # Inscription au semestre if etud: sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules( formsemestre.id, etud.id, method="formsemestre_ext_create", ) return formsemestre def formsemestre_ext_create_form(etudid, formsemestre_id): """Formulaire création/inscription à un semestre extérieur""" etud = Identite.get_etud(etudid) formsemestre = FormSemestre.get_formsemestre(formsemestre_id) H = [ f"""
Cette opération crée un semestre extérieur ("ancien") de la même formation que le semestre courant, et y inscrit juste cet étudiant. La décision de jury peut ensuite y être saisie.
Notez que si un semestre extérieur similaire a déjà été créé pour un autre étudiant, il est préférable d'utiliser la fonction " inscrire à un autre semestre"
L'étudiant est déjà inscrit dans des semestres ScoDoc de rangs: { sorted(list(existing_semestre_ids)) }
""" ) if not semestre_ids: H.append( f"""pas de semestres extérieurs possibles (indices entre {min_semestre_id} et {max_semestre_id}, semestre courant.)
""" ) return render_template("sco_page.j2", content="\n".join(H)) # Formulaire semestre_ids_list = sorted(semestre_ids) semestre_ids_labels = [f"S{x}" for x in semestre_ids_list] descr = [ ("formsemestre_id", {"input_type": "hidden"}), ("etudid", {"input_type": "hidden"}), ( "semestre_id", { "input_type": "menu", "title": "Indice du semestre dans le cursus", "allowed_values": semestre_ids_list, "labels": semestre_ids_labels, }, ), ( "titre", { "size": 40, "title": "Nom de ce semestre extérieur", "explanation": """par exemple: établissement. N'indiquez pas les dates, ni le semestre, ni la modalité dans le titre: ils seront automatiquement ajoutés""", }, ), ( "date_debut", { "title": "Date de début", # j/m/a "input_type": "datedmy", "explanation": "j/m/a (peut être approximatif)", "size": 9, "allow_null": False, }, ), ( "date_fin", { "title": "Date de fin", # j/m/a "input_type": "datedmy", "explanation": "j/m/a (peut être approximatif)", "size": 9, "allow_null": False, }, ), ( "elt_help_ue", { "title": """Les notes et coefficients des UE capitalisées seront saisis ensuite""", "input_type": "separator", }, ), ] tf = TrivialFormulator( request.base_url, scu.get_request_args(), descr, cancelbutton="Annuler", method="post", submitlabel="Créer semestre extérieur et y inscrire l'étudiant", cssclass="inscription", name="tf", ) if tf[0] == 0: H.append( """Ce formulaire sert à enregistrer un semestre antérieur dans la formation effectué dans un autre établissement.
""" ) return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1]) if tf[0] == -1: return flask.redirect( url_for( "notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, etudid=etud.id, ) ) # Le semestre extérieur est créé dans la même formation que le semestre courant tf[2]["formation_id"] = formsemestre.formation_id formsemestre_ext_create(etud, tf[2]) return flask.redirect( url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id) ) def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid): """Edition des validations d'UE et de semestre (jury) pour un semestre extérieur. On peut saisir pour chaque UE du programme de formation sa validation, son code jury, sa note, son coefficient (sauf en BUT où le coef. des UE est toujours égal aux ECTS). La moyenne générale indicative du semestre est calculée et affichée, mais pas enregistrée. """ formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) etud = Identite.get_etud(etudid) ues = formsemestre.formation.ues.filter(UniteEns.type != UE_SPORT).order_by( UniteEns.semestre_idx, UniteEns.numero ) if formsemestre.formation.is_apc(): ues = ues.filter_by(semestre_idx=formsemestre.semestre_id) descr = _ue_form_description(formsemestre, etud, ues, scu.get_request_args()) initvalues = {} if request.method == "GET": for ue in ues: validation = ScolarFormSemestreValidation.query.filter_by( ue_id=ue.id, etudid=etud.id, formsemestre_id=formsemestre.id ).first() initvalues[f"note_{ue.id}"] = validation.moy_ue if validation else "" tf = TrivialFormulator( request.base_url, scu.get_request_args(), descr, submitlabel="Enregistrer ces validations", cancelbutton="Annuler", initvalues=initvalues, cssclass=( "tf_ext_edit_ue_validations ext_apc" if formsemestre.formation.is_apc() else "tf_ext_edit_ue_validations" ), # En APC, stocke les coefficients pour l'affichage de la moyenne en direct form_attrs=( f"""data-ue_coefs='[{', '.join(str(ue.ects or 0) for ue in ues)}]'""" if formsemestre.formation.is_apc() else "" ), ) if tf[0] == -1: flash("annulation") return flask.redirect( url_for( "notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, etudid=etudid, ) ) else: H = _make_page(etud, formsemestre, tf) if tf[0] == 0: # premier affichage return render_template( "sco_page.j2", title="Validation des UE d'un semestre extérieur", javascripts=["js/formsemestre_ext_edit_ue_validations.js"], content="\n".join(H), ) else: # soumission # simule erreur ok, message = _check_values(formsemestre, ues, tf[2]) if not ok: H = _make_page(etud, formsemestre, tf, message=message) return render_template( "sco_page.j2", title="Validation des UE d'un semestre extérieur", javascripts=["js/formsemestre_ext_edit_ue_validations.js"], content="\n".join(H), ) else: # Submit _record_ue_validations_and_coefs(formsemestre, etud, ues, tf[2]) return flask.redirect( url_for( "notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, etudid=etudid, ) ) def _make_page(etud: Identite, formsemestre: FormSemestre, tf, message="") -> list[str]: """html formulaire saisie""" nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) moy_gen = nt.get_etud_moy_gen(etud.id) H = [ tf_error_message(message), f"""{etud.nomprenom} est inscrit{etud.e} à ce semestre extérieur.
Voici ses UE enregistrées avec leur notes { "et coefficients" if not formsemestre.formation.is_apc() else " (en BUT, les coefficients sont égaux aux ECTS)"}.
""", f"""La moyenne de ce semestre serait: {moy_gen} / 20
""", '