diff --git a/app/api/assiduites.py b/app/api/assiduites.py index a9451ae736..2e0c06c6cd 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -25,7 +25,11 @@ from app.models import ( Scolog, ) from flask_sqlalchemy.query import Query -from app.models.assiduites import get_assiduites_justif, get_justifs_from_date +from app.models.assiduites import ( + get_assiduites_justif, + get_justifs_from_date, + get_formsemestre_from_data, +) from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_permissions import Permission from app.scodoc.sco_utils import json_error @@ -694,6 +698,9 @@ def _delete_singular(assiduite_id: int, database): assiduite_unique: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first() if assiduite_unique is None: return (404, "Assiduite non existante") + if g.scodoc_dept is None and assiduite_unique.etudiant.dept_id is not None: + # route sans département + set_sco_dept(assiduite_unique.etudiant.departement.acronym) ass_dict = assiduite_unique.to_dict() log(f"delete_assiduite: {assiduite_unique.etudiant.id} {assiduite_unique}") Scolog.logdb( @@ -800,6 +807,9 @@ def assiduites_edit(): def _edit_singular(assiduite_unique, data): + if g.scodoc_dept is None and assiduite_unique.etudiant.dept_id is not None: + # route sans département + set_sco_dept(assiduite_unique.etudiant.departement.acronym) errors: list[str] = [] # Vérifications de data @@ -835,7 +845,6 @@ def _edit_singular(assiduite_unique, data): external_data = external_data if external_data is not None else {} external_data["module"] = "Autre" assiduite_unique.external_data = external_data - else: try: moduleimpl = ModuleImpl.query.filter_by( @@ -854,7 +863,20 @@ def _edit_singular(assiduite_unique, data): else: assiduite_unique.moduleimpl_id = moduleimpl_id else: - assiduite_unique.moduleimpl_id = None + formsemestre: FormSemestre = get_formsemestre_from_data( + assiduite_unique.to_dict() + ) + force: bool + + if formsemestre: + force = scu.is_assiduites_module_forced(formsemestre_id=formsemestre.id) + else: + force = scu.is_assiduites_module_forced(dept_id=etud.dept_id) + + if force: + errors.append( + "param 'moduleimpl_id' : le moduleimpl_id ne peut pas être nul" + ) # Cas 3 : desc desc = data.get("desc", False) diff --git a/app/models/assiduites.py b/app/models/assiduites.py index a78e709dfe..57b7dfb772 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -4,7 +4,7 @@ from datetime import datetime from app import db, log -from app.models import ModuleImpl, Scolog +from app.models import ModuleImpl, Scolog, FormSemestre, FormSemestreInscription from app.models.etudiants import Identite from app.auth.models import User from app.scodoc import sco_abs_notification @@ -13,6 +13,7 @@ from app.scodoc.sco_utils import ( EtatAssiduite, EtatJustificatif, localize_datetime, + is_assiduites_module_forced, ) from flask_sqlalchemy.query import Query @@ -162,6 +163,23 @@ class Assiduite(db.Model): moduleimpl_id = moduleimpl.id else: raise ScoValueError("L'étudiant n'est pas inscrit au module") + elif not ( + external_data is not None and external_data.get("module") is not None + ): + # Vérification si module forcé + formsemestre: FormSemestre = get_formsemestre_from_data( + {"etudid": etud.id, "date_debut": date_debut, "date_fin": date_fin} + ) + force: bool + + if formsemestre: + force = is_assiduites_module_forced(formsemestre_id=formsemestre.id) + else: + force = is_assiduites_module_forced(dept_id=etud.dept_id) + + if force: + raise ScoValueError("Module non renseigné") + nouv_assiduite = Assiduite( date_debut=date_debut, date_fin=date_fin, @@ -413,3 +431,18 @@ def get_justifs_from_date( justifs = justifs.filter(Justificatif.etat == EtatJustificatif.VALIDE) return [j.justif_id if not long else j.to_dict(True) for j in justifs] + + +def get_formsemestre_from_data(data: dict[str, datetime | int]) -> FormSemestre: + return ( + FormSemestre.query.join( + FormSemestreInscription, + FormSemestre.id == FormSemestreInscription.formsemestre_id, + ) + .filter( + data["date_debut"] <= FormSemestre.date_fin, + data["date_fin"] >= FormSemestre.date_debut, + FormSemestreInscription.etudid == data["etudid"], + ) + .first() + ) diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index bbf785a7c0..6faad0fbde 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -1448,3 +1448,22 @@ def is_entreprises_enabled(): from app.models import ScoDocSiteConfig return ScoDocSiteConfig.is_entreprises_enabled() + + +def is_assiduites_module_forced( + formsemestre_id: int = None, dept_id: int = None +) -> bool: + from app.scodoc import sco_preferences + + retour: bool + + if dept_id is None: + dept_id = g.scodoc_dept_id + + try: + retour = sco_preferences.get_preference( + "forcer_module", formsemestre_id=int(formsemestre_id) + ) + except (TypeError, ValueError): + retour = sco_preferences.get_preference("forcer_module", dept_id=dept_id) + return retour diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index ecc2ce5166..74c0c4b9ce 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -84,19 +84,19 @@ function validateSelectors(btn) { ); }); - // if (getModuleImplId() == null && window.forceModule) { - // const HTML = ` - //
Attention, le module doit obligatoirement être renseigné.
- //Cela vient de la configuration du semestre ou plus largement du département.
- //Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.
- // `; + if (getModuleImplId() == null && window.forceModule) { + const HTML = ` +Attention, le module doit obligatoirement être renseigné.
+Cela vient de la configuration du semestre ou plus largement du département.
+Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.
+ `; - // const content = document.createElement("div"); - // content.innerHTML = HTML; + const content = document.createElement("div"); + content.innerHTML = HTML; - // openAlertModal("Sélection du module", content); - // return; - // } + openAlertModal("Sélection du module", content); + return; + } getAssiduitesFromEtuds(true); @@ -905,6 +905,9 @@ function createAssiduite(etat, etudid) { } const path = getUrl() + `/api/assiduite/${etudid}/create`; + + let with_errors = false; + sync_post( path, [assiduite], @@ -913,14 +916,31 @@ function createAssiduite(etat, etudid) { if (data.success.length > 0) { let obj = data.success["0"].message.assiduite_id; } + if (data.errors.length > 0) { + console.error(data.errors["0"].message); + if (data.errors["0"].message == "Module non renseigné") { + const HTML = ` +Attention, le module doit obligatoirement être renseigné.
+Cela vient de la configuration du semestre ou plus largement du département.
+Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.
+ `; + + const content = document.createElement("div"); + content.innerHTML = HTML; + + openAlertModal("Sélection du module", content); + } + with_errors = true; + } }, (data, status) => { //error console.error(data, status); errorAlert(); + with_errors = true; } ); - return true; + return !with_errors; } /** @@ -1000,7 +1020,33 @@ function editAssiduite(assiduite_id, etat, assi) { (data, status) => { //error console.error(data, status); - errorAlert(); + try { + errorJson = data.responseJSON; + if (errorJson.message == "param 'moduleimpl_id': etud non inscrit") { + const html = ` +