Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
8 changed files with 222 additions and 51 deletions
Showing only changes of commit c6659db08a - Show all commits

View File

@ -171,6 +171,13 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"enabled": True, "enabled": True,
"helpmsg": "Tableau de bord du semestre", "helpmsg": "Tableau de bord du semestre",
}, },
{
"title": "Assiduités du semestre",
"endpoint": "assiduites.liste_assiduites_formsemestre",
"args": {"formsemestre_id": formsemestre_id},
"enabled": True,
"helpmsg": "Tableau des assiduités et des justificatifs du semestre",
},
{ {
"title": f"Voir la formation {formation.acronyme} (v{formation.version})", "title": f"Voir la formation {formation.acronyme} (v{formation.version})",
"endpoint": "notes.ue_table", "endpoint": "notes.ue_table",
@ -218,14 +225,6 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"enabled": True, "enabled": True,
"helpmsg": "", "helpmsg": "",
}, },
# TODO: Mettre à jour avec module Assiduités
# {
# "title": "Vérifier absences aux évaluations",
# "endpoint": "notes.formsemestre_check_absences_html",
# "args": {"formsemestre_id": formsemestre_id},
# "enabled": True,
# "helpmsg": "",
# },
{ {
"title": "Lister tous les enseignants", "title": "Lister tous les enseignants",
"endpoint": "notes.formsemestre_enseignants_list", "endpoint": "notes.formsemestre_enseignants_list",

View File

@ -33,11 +33,6 @@
</div> </div>
<script> <script>
function loadAll() {
generate(defAnnee)
}
let formsemestre_id = "{{formsemestre_id}}" let formsemestre_id = "{{formsemestre_id}}"
let group_id = "{{group_id}}" let group_id = "{{group_id}}"
@ -74,10 +69,14 @@
defAnnee = annee; defAnnee = annee;
getDeptJustificatifsFromPeriod() loadAll();
} }
function getJusti(action) {
try { getDeptJustificatifsFromPeriod(action) } catch (_) { }
}
function setterAnnee(annee) { function setterAnnee(annee) {
annee = parseInt(annee); annee = parseInt(annee);
document.querySelector('.annee span').textContent = `Année scolaire ${annee}-${annee + 1} Changer année: ` document.querySelector('.annee span').textContent = `Année scolaire ${annee}-${annee + 1} Changer année: `

View File

@ -0,0 +1,94 @@
{% block pageContent %}
<div class="pageContent">
<h3>Assiduites et justificatifs de <span class="rouge">{{sem}}</span> </h3>
{% include "assiduites/widgets/tableau_base.j2" %}
<h4>Assiduités :</h4>
<span class="iconline">
<a class="icon filter" onclick="filterAssi()"></a>
<a class="icon download" onclick="downloadAssi()"></a>
</span>
{% include "assiduites/widgets/tableau_assi.j2" %}
<h4>Justificatifs :</h4>
<span class="iconline">
<a class="icon filter" onclick="filterJusti()"></a>
<a class="icon download" onclick="downloadJusti()"></a>
</span>
{% include "assiduites/widgets/tableau_justi.j2" %}
</div>
<script>
const formsemestre_id = {{ formsemestre_id }};
function getFormSemestreAssiduites(action) {
const path = getUrl() + `/api/assiduites/formsemestre/${formsemestre_id}`
async_get(
path,
(data, status) => {
if (action) {
action(data)
} else {
assiduiteCallBack(data);
}
},
(data, status) => {
console.error(data, status)
errorAlert();
}
)
}
function getFormSemestreJustificatifs(action) {
const path = getUrl() + `/api/justificatifs/formsemestre/${formsemestre_id}`
async_get(
path,
(data, status) => {
if (action) {
action(data)
} else {
justificatifCallBack(data);
}
},
(data, status) => {
console.error(data, status)
errorAlert();
}
)
}
function getAssi(action) {
try { getFormSemestreAssiduites(action) } catch (_) { }
}
function getJusti(action) {
try { getFormSemestreJustificatifs(action) } catch (_) { }
}
window.addEventListener('load', () => {
filterJustificatifs = {
"columns": [
"etudid",
"entry_date",
"date_debut",
"date_fin",
"etat",
"raison",
"fichier"
],
"filters": {
}
}
filterAssiduites = {
columns: [
"etudid", "entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"
],
"filters": {
}
}
loadAll();
})
</script>
{% endblock pageContent %}

View File

@ -117,10 +117,12 @@
} }
}) })
try {
const conflicts = getAssiduitesConflict(etudid); const conflicts = getAssiduitesConflict(etudid);
if (conflicts.length > 0) { if (conflicts.length > 0) {
updateSelectedSelect(conflicts[0].moduleimpl_id); updateSelectedSelect(conflicts[0].moduleimpl_id);
} }
} catch { }
}, { once: true }); }, { once: true });

View File

@ -88,6 +88,10 @@
td.textContent = getModuleImpl(assiduite); td.textContent = getModuleImpl(assiduite);
} else if (k.indexOf('est_just') != -1) { } else if (k.indexOf('est_just') != -1) {
td.textContent = assiduite[k] ? "Oui" : "Non" td.textContent = assiduite[k] ? "Oui" : "Non"
} else if (k.indexOf('etudid') != -1) {
const e = getEtudiant(assiduite.etudid);
td.innerHTML = `<a class="etudinfo" id="line-${assiduite.etudid}" href="BilanEtud?etudid=${assiduite.etudid}">${e.prenom.capitalize()} ${e.nom.toUpperCase()}</a>`;
} else { } else {
td.textContent = assiduite[k].capitalize() td.textContent = assiduite[k].capitalize()
} }
@ -341,6 +345,10 @@
<option value="false">Non</option> <option value="false">Non</option>
</select> </select>
</span> </span>
<span class="filter-line">
<span class="filter-title" for="etud">Rechercher dans les étudiants</span>
<input type="text" name="etud" id="etud" placeholder="Anne Onymous" >
</span>
</div> </div>
`; `;
const span = document.createElement('span'); const span = document.createElement('span');
@ -349,7 +357,7 @@
const filterHead = html.querySelector('.filter-head'); const filterHead = html.querySelector('.filter-head');
filterHead.innerHTML = "" filterHead.innerHTML = ""
let cols = ["entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"]; let cols = ["etudid", "entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"];
cols.forEach((k) => { cols.forEach((k) => {
const label = document.createElement('label') const label = document.createElement('label')
@ -401,6 +409,8 @@
l.querySelector('#moduleimpl_id').value = filterAssiduites.filters[key]; l.querySelector('#moduleimpl_id').value = filterAssiduites.filters[key];
} else if (key.indexOf("est_just") != -1) { } else if (key.indexOf("est_just") != -1) {
l.querySelector('#est_just').value = filterAssiduites.filters[key]; l.querySelector('#est_just').value = filterAssiduites.filters[key];
} else if (key == "etud") {
l.querySelector('#etud').value = filterAssiduites.filters["etud"];
} }
}) })
@ -434,18 +444,23 @@
filterAssiduites.filters[key] = l.querySelector('#moduleimpl_id').value; filterAssiduites.filters[key] = l.querySelector('#moduleimpl_id').value;
} else if (key.indexOf("est_just") != -1) { } else if (key.indexOf("est_just") != -1) {
filterAssiduites.filters[key] = l.querySelector('#est_just').value; filterAssiduites.filters[key] = l.querySelector('#est_just').value;
} else if (key == "etud") {
filterAssiduites.filters["etud"] = l.querySelector('#etud').value;
} }
}) })
getAssi(assiduiteCallBack)
getAllAssiduitesFromEtud(etudid, assiduiteCallBack)
}, () => { }, "#7059FF"); }, () => { }, "#7059FF");
} }
function downloadAssi() { function downloadAssi() {
try { getAllAssiduitesFromEtud(etudid, (d) => { toCSV(d, filterAssiduites) }, true, true, assi_limit_annee) } catch (_) { } getAssi((d) => { toCSV(d, filterAssiduites) })
}
function getAssi(action) {
try { getAllAssiduitesFromEtud(etudid, action, true, true, assi_limit_annee) } catch (_) { }
} }
</script> </script>

View File

@ -60,8 +60,6 @@
deleteJustificatif(obj_id); deleteJustificatif(obj_id);
} }
loadAll(); loadAll();
} }
}); });
@ -105,6 +103,13 @@
if (k == "formsemestre") { if (k == "formsemestre") {
return f.formsemestre === "" || (el.hasOwnProperty("formsemestre") && el.formsemestre.title.replaceAll('-', ' ').indexOf(f.formsemestre) != -1); return f.formsemestre === "" || (el.hasOwnProperty("formsemestre") && el.formsemestre.title.replaceAll('-', ' ').indexOf(f.formsemestre) != -1);
} }
if (k == "etud") {
const e = getEtudiant(el.etudid);
const str = `${e.prenom.capitalize()} ${e.nom.toUpperCase()}`
return f.etud === "" || str.indexOf(f.etud) != -1;
}
return true; return true;
}) })
@ -246,8 +251,8 @@
} }
function loadAll() { function loadAll() {
try { getAllAssiduitesFromEtud(etudid, assiduiteCallBack, true, true, assi_limit_annee) } catch (_) { } try { getAssi(assiduiteCallBack) } catch { }
try { getAllJustificatifsFromEtud(etudid, justificatifCallBack, true, assi_limit_annee) } catch (_) { } try { getJusti(justificatifCallBack) } catch { }
} }
function order(keyword, callback = () => { }, el, assi = true) { function order(keyword, callback = () => { }, el, assi = true) {
@ -265,6 +270,13 @@
keyValueA = getModuleImpl(a); keyValueA = getModuleImpl(a);
keyValueB = getModuleImpl(b); keyValueB = getModuleImpl(b);
} }
if (keyword.indexOf("etudid") != -1) {
keyValueA = getEtudiant(a.etudid);
keyValueB = getEtudiant(b.etudid);
keyValueA = `${keyValueA.prenom.capitalize()} ${keyValueA.nom.toUpperCase()}`
keyValueB = `${keyValueB.prenom.capitalize()} ${keyValueB.nom.toUpperCase()}`
}
let orderDertermined = keyValueA > keyValueB; let orderDertermined = keyValueA > keyValueB;
@ -282,10 +294,10 @@
if (assi) { if (assi) {
orderAssiduites = !orderAssiduites; orderAssiduites = !orderAssiduites;
getAllAssiduitesFromEtud(etudid, (a) => { call(a, orderAssiduites) }) getAssi((a) => { call(a, orderAssiduites) });
} else { } else {
orderJustificatifs = !orderJustificatifs; orderJustificatifs = !orderJustificatifs;
getAllJustificatifsFromEtud(etudid, (a) => { call(a, orderJustificatifs) }) getJusti((a) => { call(a, orderJustificatifs) });
} }
} }
@ -333,7 +345,6 @@
li.addEventListener('click', () => { li.addEventListener('click', () => {
let obj_id = selectedRow.getAttribute('obj_id'); let obj_id = selectedRow.getAttribute('obj_id');
assiduite = Object.values(assiduites).flat().filter((a) => { return a.assiduite_id == obj_id }) assiduite = Object.values(assiduites).flat().filter((a) => { return a.assiduite_id == obj_id })
console.log(assiduite[0])
if (assiduite && !assiduite[0].est_just && assiduite[0].etat != "PRESENT") { if (assiduite && !assiduite[0].est_just && assiduite[0].etat != "PRESENT") {
fastJustify(assiduite[0]) fastJustify(assiduite[0])
} else { } else {
@ -412,6 +423,16 @@
askDownload(csv); askDownload(csv);
} }
function getEtudiant(id) {
if (id in etuds) {
return etuds[id];
}
getSingleEtud(id);
return etuds[id];
}
</script> </script>
<style> <style>

View File

@ -57,17 +57,6 @@
renderPaginationButtons(justi, false); renderPaginationButtons(justi, false);
} }
function getEtudiant(id) {
if (id in etuds) {
return etuds[id];
}
getSingleEtud(id);
return etuds[id];
}
function renderTableJustificatifs(page, justificatifs) { function renderTableJustificatifs(page, justificatifs) {
generateTableHead(filterJustificatifs.columns, false) generateTableHead(filterJustificatifs.columns, false)
@ -256,7 +245,7 @@
// The catch is getting called only for client-side errors. // The catch is getting called only for client-side errors.
// For example the throw in the first then-promise, which is the error that came from the server. // For example the throw in the first then-promise, which is the error that came from the server.
.catch((err) => { .catch((err) => {
console.log(err); console.error(err);
}); });
} }
@ -425,7 +414,6 @@
return el.parentElement.querySelector('a').textContent; return el.parentElement.querySelector('a').textContent;
}); });
console.log(justif_id, files);
sync_post( sync_post(
path, path,
{ {
@ -562,6 +550,10 @@
<input checked type="checkbox" name="etat_valide" id="etat_valide" class="" value="modifie"> <input checked type="checkbox" name="etat_valide" id="etat_valide" class="" value="modifie">
</label> </label>
</span> </span>
<span class="filter-line">
<span class="filter-title" for="etud">Rechercher dans les étudiants</span>
<input type="text" name="etud" id="etud" placeholder="Anne Onymous" >
</span>
${dept ? dept_html_body : ""} ${dept ? dept_html_body : ""}
</div> </div>
`; `;
@ -571,7 +563,9 @@
const filterHead = html.querySelector('.filter-head'); const filterHead = html.querySelector('.filter-head');
filterHead.innerHTML = "" filterHead.innerHTML = ""
let cols = ["formsemestre", "etudid", "entry_date", "date_debut", "date_fin", "etat", "raison", "fichier"]; let cols = ["etudid", "entry_date", "date_debut", "date_fin", "etat", "raison", "fichier"];
if (dept) { cols.push("formsemestre") }
cols.forEach((k) => { cols.forEach((k) => {
const label = document.createElement('label') const label = document.createElement('label')
@ -606,6 +600,8 @@
}) })
} else if (key == "formsemestre") { } else if (key == "formsemestre") {
l.querySelector('#formsemestre').value = filterJustificatifs.filters["formsemestre"]; l.querySelector('#formsemestre').value = filterJustificatifs.filters["formsemestre"];
} else if (key == "etudid") {
l.querySelector('#etudid').value = filterJustificatifs.filters["etud"];
} }
}) })
@ -637,23 +633,25 @@
filterJustificatifs.filters[key] = [...l.querySelectorAll("input:checked")].map((e) => e.value); filterJustificatifs.filters[key] = [...l.querySelectorAll("input:checked")].map((e) => e.value);
} else if (key == "formsemestre") { } else if (key == "formsemestre") {
filterJustificatifs.filters["formsemestre"] = l.querySelector('#formsemestre').value; filterJustificatifs.filters["formsemestre"] = l.querySelector('#formsemestre').value;
} else if (key == "etud") {
filterJustificatifs.filters["etud"] = l.querySelector('#etud').value;
} }
}) })
if (dept) {
loadAll(); loadAll();
} else {
getAllJustificatifsFromEtud(etudid, justificatifCallBack)
}
}, () => { }, "#7059FF"); }, () => { }, "#7059FF");
} }
function downloadJusti() { function downloadJusti() {
try { getAllJustificatifsFromEtud(etudid, (d) => { toCSV(d, filterJustificatifs) }, true, assi_limit_annee) } catch { getJusti((d) => { toCSV(d, filterJustificatifs) })
try { getDeptJustificatifsFromPeriod((d) => { toCSV(d, filterJustificatifs) }) } catch { }
} }
function getJusti(action) {
try { getAllJustificatifsFromEtud(etudid, action, true, assi_limit_annee) } catch (_) { }
} }
</script> </script>
<style> <style>

View File

@ -205,6 +205,49 @@ def bilan_dept():
return "\n".join(H) return "\n".join(H)
@bp.route("/ListeSemestre")
@scodoc
@permission_required(Permission.ScoView)
def liste_assiduites_formsemestre():
"""
liste_assiduites_etud Affichage de toutes les assiduites et justificatifs d'un etudiant
Args:
etudid (int): l'identifiant de l'étudiant
Returns:
str: l'html généré
"""
formsemestre_id = request.args.get("formsemestre_id", -1)
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
if formsemestre.dept_id != g.scodoc_dept_id:
abort(404, "FormSemestre inexistant dans ce département")
header: str = html_sco_header.sco_header(
page_title="Liste des assiduités du semestre",
init_qtip=True,
javascripts=[
"js/assiduites.js",
"libjs/moment.new.min.js",
"libjs/moment-timezone.js",
],
cssstyles=CSSSTYLES
+ [
"css/assiduites.css",
],
)
return HTMLBuilder(
header,
render_template(
"assiduites/pages/liste_semestre.j2",
sco=ScoData(formsemestre=formsemestre),
sem=formsemestre.titre_annee(),
formsemestre_id=formsemestre.id,
),
).build()
@bp.route("/SignaleAssiduiteEtud") @bp.route("/SignaleAssiduiteEtud")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.ScoAbsChange)