forked from ScoDoc/ScoDoc
Merge branch 'main96' of https://scodoc.org/git/iziram/ScoDoc
This commit is contained in:
commit
885a4fc452
@ -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)
|
||||
|
@ -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()
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -84,19 +84,19 @@ function validateSelectors(btn) {
|
||||
);
|
||||
});
|
||||
|
||||
// if (getModuleImplId() == null && window.forceModule) {
|
||||
// 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>
|
||||
// `;
|
||||
if (getModuleImplId() == null && window.forceModule) {
|
||||
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;
|
||||
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 = `
|
||||
<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) => {
|
||||
//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 = `
|
||||
<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>
|
||||
{{moduleimpl_select | safe }}
|
||||
{% include "assiduites/widgets/moduleimpl_dynamic_selector.j2" %}
|
||||
<button class="btn" onclick="fastJustify(getCurrentAssiduite(etudid))" id="justif-rapide">Justifier</button>
|
||||
</div>
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
<label for="moduleimpl_select">
|
||||
Module
|
||||
<select id="moduleimpl_select" class="dynaSelect">
|
||||
<option value="" selected> Non spécifié </option>
|
||||
<option value="autre"> Autre </option>
|
||||
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||
</select>
|
||||
|
||||
<div id="saved" style="display: none;">
|
||||
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||
</div>
|
||||
</label>
|
||||
|
||||
|
||||
@ -70,7 +73,7 @@
|
||||
|
||||
function populateSelect(sems, selected, 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) => {
|
||||
const optGrp = document.createElement('optgroup');
|
||||
optGrp.label = label
|
||||
|
@ -1,7 +1,6 @@
|
||||
<select name="moduleimpl_select" id="moduleimpl_select">
|
||||
|
||||
<option value="" {{selected}}> Non spécifié </option>
|
||||
<option value="autre"> Autre </option>
|
||||
{% include "assiduites/widgets/simplemoduleimpl_select.j2" %}
|
||||
|
||||
{% for mod in modules %}
|
||||
{% 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"
|
||||
)
|
||||
|
||||
select = """
|
||||
select = f"""
|
||||
<select class="dynaSelect">
|
||||
<option value="" selected> Non spécifié </option>
|
||||
{render_template("assiduites/widgets/simplemoduleimpl_select.j2")}
|
||||
</select>
|
||||
"""
|
||||
|
||||
return HTMLBuilder(
|
||||
header,
|
||||
_mini_timeline(),
|
||||
@ -356,7 +355,6 @@ def signal_assiduites_etud():
|
||||
forcer_module=sco_preferences.get_preference(
|
||||
"forcer_module", dept_id=g.scodoc_dept_id
|
||||
),
|
||||
moduleimpl_select=_dynamic_module_selector(),
|
||||
diff=_differee(
|
||||
etudiants=[sco_etud.get_etud_info(etudid=etud.etudid, filled=True)[0]],
|
||||
moduleimpl_select=select,
|
||||
@ -630,10 +628,7 @@ def signal_assiduites_group():
|
||||
if formsemestre.dept_id != g.scodoc_dept_id:
|
||||
abort(404, "groupes inexistants dans ce département")
|
||||
|
||||
require_module = sco_preferences.get_preference(
|
||||
"abs_require_module", formsemestre_id
|
||||
)
|
||||
|
||||
require_module = sco_preferences.get_preference("forcer_module", formsemestre_id)
|
||||
etuds = [
|
||||
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
||||
for m in groups_infos.members
|
||||
@ -1380,7 +1375,9 @@ def _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:
|
||||
|
Loading…
Reference in New Issue
Block a user