Assiduite : fixe forcer module Fix #798
This commit is contained in:
parent
5a41f9c1c3
commit
97e75e9ac9
@ -25,7 +25,11 @@ from app.models import (
|
|||||||
Scolog,
|
Scolog,
|
||||||
)
|
)
|
||||||
from flask_sqlalchemy.query import Query
|
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_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_utils import json_error
|
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()
|
assiduite_unique: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first()
|
||||||
if assiduite_unique is None:
|
if assiduite_unique is None:
|
||||||
return (404, "Assiduite non existante")
|
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()
|
ass_dict = assiduite_unique.to_dict()
|
||||||
log(f"delete_assiduite: {assiduite_unique.etudiant.id} {assiduite_unique}")
|
log(f"delete_assiduite: {assiduite_unique.etudiant.id} {assiduite_unique}")
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
@ -800,6 +807,9 @@ def assiduites_edit():
|
|||||||
|
|
||||||
|
|
||||||
def _edit_singular(assiduite_unique, data):
|
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] = []
|
errors: list[str] = []
|
||||||
|
|
||||||
# Vérifications de data
|
# 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 = external_data if external_data is not None else {}
|
||||||
external_data["module"] = "Autre"
|
external_data["module"] = "Autre"
|
||||||
assiduite_unique.external_data = external_data
|
assiduite_unique.external_data = external_data
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
moduleimpl = ModuleImpl.query.filter_by(
|
moduleimpl = ModuleImpl.query.filter_by(
|
||||||
@ -854,7 +863,20 @@ def _edit_singular(assiduite_unique, data):
|
|||||||
else:
|
else:
|
||||||
assiduite_unique.moduleimpl_id = moduleimpl_id
|
assiduite_unique.moduleimpl_id = moduleimpl_id
|
||||||
else:
|
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
|
# Cas 3 : desc
|
||||||
desc = data.get("desc", False)
|
desc = data.get("desc", False)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from app import db, log
|
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.models.etudiants import Identite
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
from app.scodoc import sco_abs_notification
|
from app.scodoc import sco_abs_notification
|
||||||
@ -13,6 +13,7 @@ from app.scodoc.sco_utils import (
|
|||||||
EtatAssiduite,
|
EtatAssiduite,
|
||||||
EtatJustificatif,
|
EtatJustificatif,
|
||||||
localize_datetime,
|
localize_datetime,
|
||||||
|
is_assiduites_module_forced,
|
||||||
)
|
)
|
||||||
|
|
||||||
from flask_sqlalchemy.query import Query
|
from flask_sqlalchemy.query import Query
|
||||||
@ -162,6 +163,23 @@ class Assiduite(db.Model):
|
|||||||
moduleimpl_id = moduleimpl.id
|
moduleimpl_id = moduleimpl.id
|
||||||
else:
|
else:
|
||||||
raise ScoValueError("L'étudiant n'est pas inscrit au module")
|
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(
|
nouv_assiduite = Assiduite(
|
||||||
date_debut=date_debut,
|
date_debut=date_debut,
|
||||||
date_fin=date_fin,
|
date_fin=date_fin,
|
||||||
@ -413,3 +431,18 @@ def get_justifs_from_date(
|
|||||||
justifs = justifs.filter(Justificatif.etat == EtatJustificatif.VALIDE)
|
justifs = justifs.filter(Justificatif.etat == EtatJustificatif.VALIDE)
|
||||||
|
|
||||||
return [j.justif_id if not long else j.to_dict(True) for j in justifs]
|
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()
|
||||||
|
)
|
||||||
|
@ -1448,3 +1448,22 @@ def is_entreprises_enabled():
|
|||||||
from app.models import ScoDocSiteConfig
|
from app.models import ScoDocSiteConfig
|
||||||
|
|
||||||
return ScoDocSiteConfig.is_entreprises_enabled()
|
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
|
||||||
|
@ -84,19 +84,19 @@ function validateSelectors(btn) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// if (getModuleImplId() == null && window.forceModule) {
|
if (getModuleImplId() == null && window.forceModule) {
|
||||||
// const HTML = `
|
const HTML = `
|
||||||
// <p>Attention, le module doit obligatoirement être renseigné.</p>
|
<p>Attention, le module doit obligatoirement être renseigné.</p>
|
||||||
// <p>Cela vient de la configuration du semestre ou plus largement du département.</p>
|
<p>Cela vient de la configuration du semestre ou plus largement du département.</p>
|
||||||
// <p>Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.</p>
|
<p>Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.</p>
|
||||||
// `;
|
`;
|
||||||
|
|
||||||
// const content = document.createElement("div");
|
const content = document.createElement("div");
|
||||||
// content.innerHTML = HTML;
|
content.innerHTML = HTML;
|
||||||
|
|
||||||
// openAlertModal("Sélection du module", content);
|
openAlertModal("Sélection du module", content);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
getAssiduitesFromEtuds(true);
|
getAssiduitesFromEtuds(true);
|
||||||
|
|
||||||
@ -905,6 +905,9 @@ function createAssiduite(etat, etudid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const path = getUrl() + `/api/assiduite/${etudid}/create`;
|
const path = getUrl() + `/api/assiduite/${etudid}/create`;
|
||||||
|
|
||||||
|
let with_errors = false;
|
||||||
|
|
||||||
sync_post(
|
sync_post(
|
||||||
path,
|
path,
|
||||||
[assiduite],
|
[assiduite],
|
||||||
@ -913,14 +916,31 @@ function createAssiduite(etat, etudid) {
|
|||||||
if (data.success.length > 0) {
|
if (data.success.length > 0) {
|
||||||
let obj = data.success["0"].message.assiduite_id;
|
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 = `
|
||||||
|
<p>Attention, le module doit obligatoirement être renseigné.</p>
|
||||||
|
<p>Cela vient de la configuration du semestre ou plus largement du département.</p>
|
||||||
|
<p>Si c'est une erreur, veuillez voir avec le ou les responsables de votre scodoc.</p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const content = document.createElement("div");
|
||||||
|
content.innerHTML = HTML;
|
||||||
|
|
||||||
|
openAlertModal("Sélection du module", content);
|
||||||
|
}
|
||||||
|
with_errors = true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(data, status) => {
|
(data, status) => {
|
||||||
//error
|
//error
|
||||||
console.error(data, status);
|
console.error(data, status);
|
||||||
errorAlert();
|
errorAlert();
|
||||||
|
with_errors = true;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return true;
|
return !with_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1000,7 +1020,33 @@ function editAssiduite(assiduite_id, etat, assi) {
|
|||||||
(data, status) => {
|
(data, status) => {
|
||||||
//error
|
//error
|
||||||
console.error(data, status);
|
console.error(data, status);
|
||||||
errorAlert();
|
try {
|
||||||
|
errorJson = data.responseJSON;
|
||||||
|
if (errorJson.message == "param 'moduleimpl_id': etud non inscrit") {
|
||||||
|
const html = `
|
||||||
|
<h3>L'étudiant n'est pas inscrit à ce module</h3>
|
||||||
|
`;
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.innerHTML = html;
|
||||||
|
openAlertModal("Erreur Module", div);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
errorJson.message ==
|
||||||
|
"param 'moduleimpl_id' : le moduleimpl_id ne peut pas être nul"
|
||||||
|
) {
|
||||||
|
const html = `
|
||||||
|
<h3>Un module doit être spécifié</h3>
|
||||||
|
`;
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.innerHTML = html;
|
||||||
|
openAlertModal("Erreur Module", div);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
//errorAlert();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{moduleimpl_select | safe }}
|
{% include "assiduites/widgets/moduleimpl_dynamic_selector.j2" %}
|
||||||
<button class="btn" onclick="fastJustify(getCurrentAssiduite(etudid))" id="justif-rapide">Justifier</button>
|
<button class="btn" onclick="fastJustify(getCurrentAssiduite(etudid))" id="justif-rapide">Justifier</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
<label for="moduleimpl_select">
|
<label for="moduleimpl_select">
|
||||||
Module
|
Module
|
||||||
<select id="moduleimpl_select" class="dynaSelect">
|
<select id="moduleimpl_select" class="dynaSelect">
|
||||||
<option value="" selected> Non spécifié </option>
|
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||||
<option value="autre"> Autre </option>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<div id="saved" style="display: none;">
|
||||||
|
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
||||||
@ -70,7 +73,7 @@
|
|||||||
|
|
||||||
function populateSelect(sems, selected, query) {
|
function populateSelect(sems, selected, query) {
|
||||||
const select = document.querySelector(query);
|
const select = document.querySelector(query);
|
||||||
select.innerHTML = `<option value=""> Non spécifié </option><option value="autre"> Autre </option>`
|
select.innerHTML = document.getElementById('saved').innerHTML
|
||||||
sems.forEach((mods, label) => {
|
sems.forEach((mods, label) => {
|
||||||
const optGrp = document.createElement('optgroup');
|
const optGrp = document.createElement('optgroup');
|
||||||
optGrp.label = label
|
optGrp.label = label
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<select name="moduleimpl_select" id="moduleimpl_select">
|
<select name="moduleimpl_select" id="moduleimpl_select">
|
||||||
|
|
||||||
<option value="" {{selected}}> Non spécifié </option>
|
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||||
<option value="autre"> Autre </option>
|
|
||||||
|
|
||||||
{% for mod in modules %}
|
{% for mod in modules %}
|
||||||
{% if mod.moduleimpl_id == moduleimpl_id %}
|
{% if mod.moduleimpl_id == moduleimpl_id %}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{% if scu.is_assiduites_module_forced(request.args.get('formsemestre_id', None))%}
|
||||||
|
<option value="" selected disabled> Saisir Module</option>
|
||||||
|
{% else %}
|
||||||
|
<option value="" selected> Non spécifié </option>
|
||||||
|
{% endif %}
|
||||||
|
<option value="autre"> Tout module </option>
|
@ -335,12 +335,11 @@ def signal_assiduites_etud():
|
|||||||
"assi_afternoon_time", "18:00:00"
|
"assi_afternoon_time", "18:00:00"
|
||||||
)
|
)
|
||||||
|
|
||||||
select = """
|
select = f"""
|
||||||
<select class="dynaSelect">
|
<select class="dynaSelect">
|
||||||
<option value="" selected> Non spécifié </option>
|
{render_template("assiduites/widgets/simplemoduleimpl_select.j2")}
|
||||||
</select>
|
</select>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return HTMLBuilder(
|
return HTMLBuilder(
|
||||||
header,
|
header,
|
||||||
_mini_timeline(),
|
_mini_timeline(),
|
||||||
@ -356,7 +355,6 @@ def signal_assiduites_etud():
|
|||||||
forcer_module=sco_preferences.get_preference(
|
forcer_module=sco_preferences.get_preference(
|
||||||
"forcer_module", dept_id=g.scodoc_dept_id
|
"forcer_module", dept_id=g.scodoc_dept_id
|
||||||
),
|
),
|
||||||
moduleimpl_select=_dynamic_module_selector(),
|
|
||||||
diff=_differee(
|
diff=_differee(
|
||||||
etudiants=[sco_etud.get_etud_info(etudid=etud.etudid, filled=True)[0]],
|
etudiants=[sco_etud.get_etud_info(etudid=etud.etudid, filled=True)[0]],
|
||||||
moduleimpl_select=select,
|
moduleimpl_select=select,
|
||||||
@ -630,10 +628,7 @@ def signal_assiduites_group():
|
|||||||
if formsemestre.dept_id != g.scodoc_dept_id:
|
if formsemestre.dept_id != g.scodoc_dept_id:
|
||||||
abort(404, "groupes inexistants dans ce département")
|
abort(404, "groupes inexistants dans ce département")
|
||||||
|
|
||||||
require_module = sco_preferences.get_preference(
|
require_module = sco_preferences.get_preference("forcer_module", formsemestre_id)
|
||||||
"abs_require_module", formsemestre_id
|
|
||||||
)
|
|
||||||
|
|
||||||
etuds = [
|
etuds = [
|
||||||
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
||||||
for m in groups_infos.members
|
for m in groups_infos.members
|
||||||
@ -1380,7 +1375,9 @@ def _module_selector(
|
|||||||
|
|
||||||
|
|
||||||
def _dynamic_module_selector():
|
def _dynamic_module_selector():
|
||||||
return render_template("assiduites/widgets/moduleimpl_dynamic_selector.j2")
|
return render_template(
|
||||||
|
"assiduites/widgets/moduleimpl_dynamic_selector.j2",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _timeline(formsemestre_id=None) -> HTMLElement:
|
def _timeline(formsemestre_id=None) -> HTMLElement:
|
||||||
|
Loading…
Reference in New Issue
Block a user