2023-09-04 09:58:55 +02:00
|
|
|
{% include "assiduites/widgets/toast.j2" %}
|
2023-06-20 15:50:56 +02:00
|
|
|
{% block pageContent %}
|
|
|
|
<div class="pageContent">
|
2023-09-19 23:04:46 +02:00
|
|
|
<h3>Justifier des absences ou retards</h3>
|
2023-06-20 15:50:56 +02:00
|
|
|
{% include "assiduites/widgets/tableau_base.j2" %}
|
2023-11-22 15:31:35 +01:00
|
|
|
|
2023-06-20 15:50:56 +02:00
|
|
|
|
2023-09-21 18:44:38 +02:00
|
|
|
<section class="justi-form page">
|
2023-06-20 15:50:56 +02:00
|
|
|
|
|
|
|
<fieldset>
|
|
|
|
<div class="justi-row">
|
|
|
|
<div class="justi-label">
|
|
|
|
<legend for="justi_date_debut" required>Date de début</legend>
|
2023-11-10 14:24:29 +01:00
|
|
|
<scodoc-datetime name="justi_date_debut" id="justi_date_debut"> </scodoc-datetime>
|
2023-11-14 16:38:07 +01:00
|
|
|
<span>Journée entière</span> <input type="checkbox" name="justi_journee" id="justi_journee">
|
2023-06-20 15:50:56 +02:00
|
|
|
</div>
|
2023-09-12 09:41:50 +02:00
|
|
|
<div class="justi-label" id="date_fin">
|
2023-06-20 15:50:56 +02:00
|
|
|
<legend for="justi_date_fin" required>Date de fin</legend>
|
2023-11-10 14:24:29 +01:00
|
|
|
<scodoc-datetime name="justi_date_fin" id="justi_date_fin"></scodoc-datetime>
|
2023-06-20 15:50:56 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="justi-row">
|
|
|
|
<div class="justi-label">
|
|
|
|
<legend for="justi_etat" required>Etat du justificatif</legend>
|
|
|
|
<select name="justi_etat" id="justi_etat">
|
|
|
|
<option value="attente" selected>En Attente de validation</option>
|
|
|
|
<option value="non_valide">Non Valide</option>
|
|
|
|
<option value="modifie">Modifié</option>
|
|
|
|
<option value="valide">Valide</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="justi-row">
|
|
|
|
<div class="justi-label">
|
|
|
|
<legend for="justi_raison">Raison</legend>
|
|
|
|
<textarea name="justi_raison" id="justi_raison" cols="50" rows="10" maxlength="500"></textarea>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="justi-row">
|
|
|
|
<div class="justi-sect">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div class="justi-label">
|
|
|
|
<legend for="justi_fich">Importer un fichier</legend>
|
|
|
|
<input type="file" name="justi_fich" id="justi_fich" multiple>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2023-11-14 16:38:07 +01:00
|
|
|
<div class="justi-row">
|
|
|
|
<button onclick="validerFormulaire(this)">Créer le justificatif</button>
|
|
|
|
<button onclick="effacerFormulaire()">Remettre à zero</button>
|
|
|
|
</div>
|
2023-06-20 15:50:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
</fieldset>
|
|
|
|
|
|
|
|
</section>
|
2023-11-22 15:31:35 +01:00
|
|
|
<section class="liste">
|
|
|
|
<a class="icon filter" onclick="filterJusti()"></a>
|
|
|
|
{% include "assiduites/widgets/tableau_justi.j2" %}
|
|
|
|
</section>
|
2023-06-20 15:50:56 +02:00
|
|
|
|
2023-06-30 14:38:56 +02:00
|
|
|
<div class="legende">
|
|
|
|
|
|
|
|
<h3>Gestion des justificatifs</h3>
|
|
|
|
<p>
|
|
|
|
Faites
|
|
|
|
<span style="font-style: italic;">clic droit</span> sur une ligne du tableau pour afficher le menu
|
|
|
|
contextuel :
|
|
|
|
<ul>
|
|
|
|
<li>Détails : Affiche les détails du justificatif sélectionné</li>
|
|
|
|
<li>Editer : Permet de modifier le justificatif (dates, etat, ajouter/supprimer fichier etc)</li>
|
|
|
|
<li>Supprimer : Permet de supprimer le justificatif (Action Irréversible)</li>
|
|
|
|
</ul>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<p>Cliquer sur l'icone d'entonoir afin de filtrer le tableau des justificatifs</p>
|
|
|
|
|
|
|
|
</div>
|
2023-06-20 15:50:56 +02:00
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.justi-row {
|
|
|
|
margin: 5px 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.justi-form fieldset {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: space-evenly;
|
|
|
|
}
|
|
|
|
|
|
|
|
.pageContent {
|
|
|
|
max-width: var(--sco-content-max-width);
|
|
|
|
margin-top: 15px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.justi-label {
|
|
|
|
margin: 0 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
[required]::after {
|
|
|
|
content: "*";
|
2023-11-20 16:55:26 +01:00
|
|
|
color: var(--color-error);
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
|
|
function validateFields() {
|
|
|
|
const field = document.querySelector('.justi-form')
|
2023-09-12 09:41:50 +02:00
|
|
|
const { deb, fin } = getDates()
|
2023-11-14 16:38:07 +01:00
|
|
|
const date_debut = new Date(deb);
|
|
|
|
const date_fin = new Date(fin);
|
2023-06-20 15:50:56 +02:00
|
|
|
|
2023-11-14 16:38:07 +01:00
|
|
|
if (deb == "" || fin == "" || !date_debut.isValid() || !date_fin.isValid()) {
|
2023-09-18 16:38:52 +02:00
|
|
|
openAlertModal("Erreur détéctée", document.createTextNode("Il faut indiquer une date de début et une date de fin valide."), "", color = "crimson");
|
2023-06-20 15:50:56 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (date_fin.isBefore(date_debut)) {
|
|
|
|
openAlertModal("Erreur détéctée", document.createTextNode("La date de fin doit se trouver après la date de début."), "", color = "crimson");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
function fieldsToJustificatif() {
|
2023-09-21 18:44:38 +02:00
|
|
|
const field = document.querySelector('.justi-form.page')
|
2023-06-20 15:50:56 +02:00
|
|
|
|
2023-09-12 09:41:50 +02:00
|
|
|
const { deb, fin } = getDates()
|
|
|
|
|
2023-06-20 15:50:56 +02:00
|
|
|
const etat = field.querySelector('#justi_etat').value;
|
|
|
|
const raison = field.querySelector('#justi_raison').value;
|
|
|
|
|
|
|
|
return {
|
2023-11-20 16:55:26 +01:00
|
|
|
date_debut: new Date(deb).toFakeIso(),
|
|
|
|
date_fin: new Date(fin).toFakeIso(),
|
2023-06-20 15:50:56 +02:00
|
|
|
etat: etat,
|
|
|
|
raison: raison,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function importFiles(justif_id) {
|
|
|
|
const field = document.querySelector('.justi-form')
|
|
|
|
|
|
|
|
const in_files = field.querySelector('#justi_fich');
|
|
|
|
const path = getUrl() + `/api/justificatif/${justif_id}/import`;
|
|
|
|
|
|
|
|
const requests = []
|
|
|
|
Array.from(in_files.files).forEach((f) => {
|
2023-11-16 14:25:06 +01:00
|
|
|
pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} commencée`), color = "var(--color-information)"));
|
2023-06-20 15:50:56 +02:00
|
|
|
const fd = new FormData();
|
|
|
|
fd.append('file', f);
|
|
|
|
requests.push(
|
|
|
|
$.ajax(
|
|
|
|
{
|
|
|
|
url: path,
|
|
|
|
type: 'POST',
|
|
|
|
data: fd,
|
|
|
|
dateType: 'json',
|
|
|
|
contentType: false,
|
|
|
|
processData: false,
|
2023-09-04 09:58:55 +02:00
|
|
|
success: () => {
|
|
|
|
pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} finie`)));
|
|
|
|
loadAll();
|
|
|
|
},
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-09-04 09:58:55 +02:00
|
|
|
});
|
|
|
|
if (in_files.files.length == 0) {
|
2023-06-23 16:12:36 +02:00
|
|
|
loadAll();
|
2023-09-04 09:58:55 +02:00
|
|
|
}
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
|
2023-09-04 09:58:55 +02:00
|
|
|
function validerFormulaire(btn) {
|
2023-06-20 15:50:56 +02:00
|
|
|
if (!validateFields()) return
|
|
|
|
|
|
|
|
const justificatif = fieldsToJustificatif();
|
|
|
|
let justif_id = null;
|
|
|
|
let couverture = null;
|
|
|
|
|
|
|
|
createJustificatif(justificatif, (data) => {
|
|
|
|
if (Object.keys(data.errors).length > 0) {
|
|
|
|
console.error(data.errors);
|
2023-07-25 19:59:47 +02:00
|
|
|
errorAlert();
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
if (Object.keys(data.success).length > 0) {
|
2023-08-11 16:59:53 +02:00
|
|
|
couverture = data.success[0].message.couverture
|
|
|
|
justif_id = data.success[0].message.justif_id;
|
2023-06-20 15:50:56 +02:00
|
|
|
importFiles(justif_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
})
|
2023-09-04 09:58:55 +02:00
|
|
|
|
|
|
|
btn.disabled = true;
|
|
|
|
setTimeout(() => {
|
|
|
|
btn.disabled = false;
|
|
|
|
}, 1000)
|
|
|
|
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function effacerFormulaire() {
|
|
|
|
const field = document.querySelector('.justi-form')
|
|
|
|
|
|
|
|
field.querySelector('#justi_date_debut').value = "";
|
|
|
|
field.querySelector('#justi_date_fin').value = "";
|
|
|
|
field.querySelector('#justi_etat').value = "attente";
|
|
|
|
field.querySelector('#justi_raison').value = "";
|
|
|
|
field.querySelector('#justi_fich').value = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-09-12 09:41:50 +02:00
|
|
|
function dayOnly() {
|
2023-11-14 16:38:07 +01:00
|
|
|
const date_deb = document.getElementById("justi_date_debut");
|
|
|
|
const date_fin = document.getElementById("justi_date_fin");
|
2023-09-12 09:41:50 +02:00
|
|
|
|
|
|
|
if (document.getElementById('justi_journee').checked) {
|
2023-11-14 16:38:07 +01:00
|
|
|
date_deb.setAttribute("show", "date")
|
|
|
|
date_fin.setAttribute("show", "date")
|
2023-11-22 15:31:35 +01:00
|
|
|
document.querySelector(`legend[for="justi_date_fin"]`).removeAttribute("required")
|
|
|
|
|
2023-09-12 09:41:50 +02:00
|
|
|
} else {
|
2023-11-14 16:38:07 +01:00
|
|
|
date_deb.removeAttribute("show")
|
|
|
|
date_fin.removeAttribute("show")
|
2023-11-22 15:31:35 +01:00
|
|
|
document.querySelector(`legend[for="justi_date_fin"]`).setAttribute("required", "")
|
2023-09-12 09:41:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getDates() {
|
2023-11-14 16:38:07 +01:00
|
|
|
const date_deb = document.querySelector(".page #justi_date_debut")
|
|
|
|
const date_fin = document.querySelector(".page #justi_date_fin")
|
|
|
|
const journee = document.querySelector('.page #justi_journee').checked
|
|
|
|
const deb = date_deb.valueAsObject.date + "T" + (journee ? assi_morning : date_deb.valueAsObject.time)
|
2023-11-22 15:31:35 +01:00
|
|
|
let fin = "T" + (journee ? assi_evening : date_fin.valueAsObject.time)
|
|
|
|
if (journee) {
|
|
|
|
fin = (date_fin.valueAsObject.date || date_deb.valueAsObject.date) + fin
|
|
|
|
} else {
|
|
|
|
fin = date_fin.valueAsObject.date + fin
|
|
|
|
}
|
2023-09-12 09:41:50 +02:00
|
|
|
return {
|
2023-11-14 16:38:07 +01:00
|
|
|
"deb": deb,
|
|
|
|
"fin": fin,
|
2023-09-12 09:41:50 +02:00
|
|
|
}
|
|
|
|
}
|
2023-06-20 15:50:56 +02:00
|
|
|
|
|
|
|
const etudid = {{ sco.etud.id }};
|
2023-09-12 09:37:03 +02:00
|
|
|
|
|
|
|
const assi_limit_annee = "{{ assi_limit_annee }}" == "True" ? true : false;
|
2023-09-12 09:41:50 +02:00
|
|
|
const assi_morning = '{{assi_morning}}';
|
|
|
|
const assi_evening = '{{assi_evening}}';
|
2023-09-12 09:37:03 +02:00
|
|
|
|
2023-06-20 15:50:56 +02:00
|
|
|
window.onload = () => {
|
|
|
|
loadAll();
|
2023-09-12 09:41:50 +02:00
|
|
|
document.getElementById('justi_journee').addEventListener('click', () => { dayOnly() });
|
|
|
|
dayOnly()
|
2023-11-14 16:38:07 +01:00
|
|
|
|
|
|
|
document.getElementById("justi_date_debut").valueAsObject = { time: assi_morning }
|
|
|
|
document.getElementById("justi_date_fin").valueAsObject = { time: assi_evening }
|
2023-06-20 15:50:56 +02:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
{% endblock pageContent %}
|