diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index 90ed21d642..f4f98cc7c5 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -32,6 +32,17 @@ Object.defineProperty(String.prototype, "capitalize", { }, enumerable: false, }); + +const DatePrecisions = [ + "year", + "month", + "day", + "hour", + "minute", + "second", + "millisecond", +]; + // <<== Outils ==>> Object.defineProperty(Array.prototype, "reversed", { value: function () { @@ -40,6 +51,132 @@ Object.defineProperty(Array.prototype, "reversed", { enumerable: false, }); +// <= Gestion des dates => + +Object.defineProperty(Date.prototype, "isBetween", { + /** + * Vérifie si la date est comprise dans une période avec une précision et une inclusivité optionnelles + * @param {Date} deb - La date de début de la période + * @param {Date} fin - La date de fin de la période + * @param {String} precision - La précision pour la comparaison (année, mois, jour, etc.) + * @param {String} bornes - L'inclusivité/exclusivité de la comparaison ("[]", "()", "[)", "(]") + */ + value: function (deb, fin, precision, bornes = "[]") { + // Ajuste la date actuelle, la date de début et la date de fin à la précision spécifiée + const thisPrecision = this.toPrecision(precision); + const debPrecision = deb.toPrecision(precision); + const finPrecision = fin.toPrecision(precision); + + // Vérifie les bornes en fonction de l'inclusivité/exclusivité spécifiée dans 'bornes' + const check_deb = + bornes[0] === "(" + ? thisPrecision > debPrecision + : thisPrecision >= debPrecision; + const check_fin = + bornes[1] === ")" + ? finPrecision > thisPrecision + : finPrecision >= thisPrecision; + + return check_deb && check_fin; + }, +}); + +Object.defineProperty(Date.prototype, "toPrecision", { + /** + * Ajuste la date à la précision donnée. + * @param {String} precision - La précision désirée (année, mois, jour, etc.) + */ + value: function (precision) { + const newDate = new Date(this.getTime()); + + // Trouve l'indice de la précision spécifiée dans le tableau des précisions + const precisionsIndex = + precision != undefined + ? DatePrecisions.indexOf(precision) + : DatePrecisions.length - 1; + + // Réinitialise toutes les parties de la date moins significatives que la précision spécifiée + for (let i = precisionsIndex + 1; i < DatePrecisions.length; i++) { + const p = DatePrecisions[i]; + switch (p) { + case "month": + // Les mois en JavaScript sont indexés à partir de 0, donc on met 0 pour janvier + newDate.setMonth(0); + break; + case "day": + // Les jours en JavaScript commencent à 1, donc on met 1 pour le premier jour du mois + newDate.setDate(1); + break; + case "hour": + newDate.setHours(0); + break; + case "minute": + newDate.setMinutes(0); + break; + case "second": + newDate.setSeconds(0); + break; + case "millisecond": + newDate.setMilliseconds(0); + break; + } + } + + return newDate; + }, +}); + +Object.defineProperty(Date.prototype, "isBefore", { + value: function (date) { + return this < date; + }, +}); +Object.defineProperty(Date.prototype, "isAfter", { + value: function (date) { + return this > date; + }, +}); + +Object.defineProperty(Date.prototype, "isSame", { + /** + * Retourne vrai si les dates sont les mêmes + * @param {Date} date + * @returns boolean + */ + value: function (date) { + return this == date; + }, +}); + +Object.defineProperty(Date.prototype, "toIsoUtcString", { + value: function () { + const date = this; + var tzo = -date.getTimezoneOffset(), + dif = tzo >= 0 ? "+" : "-", + pad = function (num) { + return (num < 10 ? "0" : "") + num; + }; + + return ( + date.getFullYear() + + "-" + + pad(date.getMonth() + 1) + + "-" + + pad(date.getDate()) + + "T" + + pad(date.getHours()) + + ":" + + pad(date.getMinutes()) + + ":" + + pad(date.getSeconds()) + + dif + + pad(Math.floor(Math.abs(tzo) / 60)) + + ":" + + pad(Math.abs(tzo) % 60) + ); + }, +}); + /** * Ajout des évents sur les boutons d'assiduité * @param {Document | HTMLFieldSetElement} parent par défaut le document, un field sinon @@ -126,7 +263,7 @@ function validateSelectors(btn) { } function onlyAbs() { - if (getDate() > moment()) { + if (getDate() > Date.now()) { document .querySelectorAll(".rbtn.present, .rbtn.retard") .forEach((el) => el.remove()); @@ -268,8 +405,8 @@ function executeMassActionQueue() { */ const tlTimes = getTimeLineTimes(); let assiduite = { - date_debut: tlTimes.deb.format(), - date_fin: tlTimes.fin.format(), + date_debut: tlTimes.deb.toIsoUtcString(), + date_fin: tlTimes.fin.toIsoUtcString(), }; assiduite = setModuleImplId(assiduite); @@ -613,19 +750,11 @@ function getNearestWorkDay(date) { } function verifyDateInSemester() { - const date = new moment.tz( - document.querySelector("#tl_date").value, - TIMEZONE - ); + const date = getDate(); const periodSemester = getFormSemestreDates(); - return date.isBetween( - periodSemester.deb, - periodSemester.fin, - undefined, - "[]" - ); + return date.isBetween(periodSemester.deb, periodSemester.fin, "[]"); } /** @@ -664,8 +793,8 @@ function getAssiduitesOnDateChange() { * @param {String} separator le séparateur de la date intelligible (01/01/2000 {separtor} 10:00) * @returns {String} la date intelligible */ -function formatDateModal(str, separator = "·") { - return new moment.tz(str, TIMEZONE).format(`DD/MM/Y ${separator} HH:mm`); +function formatDateModal(str) { + return new Date(str).toLocaleString("fr-FR"); } /** @@ -705,8 +834,8 @@ function verifyNonWorkDays(day, nonWorkdays) { * Fonction qui vérifie si une période est dans un interval * Objet période / interval * { - * deb: moment.tz(), - * fin: moment.tz(), + * deb: Date, + * fin: Date, * } * @param {object} period * @param {object} interval @@ -718,7 +847,7 @@ function hasTimeConflict(period, interval) { /** * On récupère la période de la timeline - * @returns {deb : moment.tz(), fin: moment.tz()} + * @returns {deb : Date, fin: Date)} */ function getTimeLineTimes() { //getPeriodValues() -> retourne la position de la timeline [a,b] avec a et b des number @@ -726,11 +855,11 @@ function getTimeLineTimes() { //On récupère la date const dateiso = document.querySelector("#tl_date").value; - //On génère des objets temps (moment.tz) + //On génère des objets temps values = values.map((el) => { el = toTime(el).replace("h", ":"); el = `${dateiso}T${el}`; - return moment.tz(el, TIMEZONE); + return new Date(el); }); return { deb: values[0], fin: values[1] }; @@ -744,8 +873,8 @@ function getTimeLineTimes() { function isConflictSameAsPeriod(conflict, period = undefined) { const tlTimes = period == undefined ? getTimeLineTimes() : period; const clTimes = { - deb: moment.tz(conflict.date_debut, TIMEZONE), - fin: moment.tz(conflict.date_fin, TIMEZONE), + deb: new Date(conflict.date_debut), + fin: new Date(conflict.date_fin), }; return tlTimes.deb.isSame(clTimes.deb) && tlTimes.fin.isSame(clTimes.fin); } @@ -815,9 +944,9 @@ function toIsoString(date) { } /** - * Transforme un temps numérique en une date moment.tz + * Transforme un temps numérique en une date * @param {number} nb - * @returns {moment.tz} Une date formée du temps donné et de la date courante + * @returns {Date} Une date formée du temps donné et de la date courante */ function numberTimeToDate(nb) { time = toTime(nb).replace("h", ":"); @@ -825,7 +954,7 @@ function numberTimeToDate(nb) { datetime = `${date}T${time}`; - return moment.tz(datetime, TIMEZONE); + return new Date(datetime); } // <<== Gestion des assiduités ==>> @@ -885,8 +1014,8 @@ function getAssiduitesFromEtuds(clear, deb, fin) { function createAssiduite(etat, etudid) { const tlTimes = getTimeLineTimes(); let assiduite = { - date_debut: tlTimes.deb.format(), - date_fin: tlTimes.fin.format(), + date_debut: tlTimes.deb.toIsoUtcString(), + date_fin: tlTimes.fin.toIsoUtcString(), etat: etat, }; @@ -1067,8 +1196,8 @@ function getAssiduitesConflict(etudid, periode) { return etudAssiduites.filter((assi) => { const interval = { - deb: moment.tz(assi.date_debut, TIMEZONE), - fin: moment.tz(assi.date_fin, TIMEZONE), + deb: new Date(assi.date_debut), + fin: new Date(assi.date_debut), }; return hasTimeConflict(periode, interval); }); @@ -1085,21 +1214,21 @@ function getLastAssiduiteOfPrevDate(etudid) { return ""; } const period = { - deb: moment.tz(getPrevDate(), TIMEZONE), - fin: moment.tz(getDate(), TIMEZONE), + deb: getPrevDate(), + fin: getDate(), }; const prevAssiduites = etudAssiduites .filter((assi) => { const interval = { - deb: moment.tz(assi.date_debut, TIMEZONE), - fin: moment.tz(assi.date_fin, TIMEZONE), + deb: new Date(assi.date_debut), + fin: new Date(assi.date_fin), }; return hasTimeConflict(period, interval); }) .sort((a, b) => { - const a_fin = moment.tz(a.date_fin, TIMEZONE); - const b_fin = moment.tz(b.date_fin, TIMEZONE); + const a_fin = new Date(a.date_fin); + const b_fin = new Date(b.date_fin); return b_fin < a_fin; }); @@ -1232,8 +1361,8 @@ function assiduiteAction(element) { assiduites[etudid], getTimeLineTimes(), { - deb: new moment.tz(getDate(), TIMEZONE), - fin: new moment.tz(getNextDate(), TIMEZONE), + deb: getDate(), + fin: getNextDate(), } ); const update = (assi) => { @@ -1545,8 +1674,8 @@ function getFormSemestreDates() { const dateFin = document.getElementById("formsemestre_date_fin").textContent; return { - deb: dateDeb, - fin: dateFin, + deb: new Date(dateDeb), + fin: new Date(dateFin), }; } @@ -1614,7 +1743,9 @@ function getJustificatifFromPeriod(date, etudid, update) { getUrl() + `/api/justificatifs/${etudid}/query?date_debut=${date.deb .add(1, "s") - .format()}&date_fin=${date.fin.subtract(1, "s").format()}`, + .toIsoUtcString()}&date_fin=${date.fin + .subtract(1, "s") + .toIsoUtcString()}`, success: (data) => { update(data); }, @@ -1646,8 +1777,8 @@ function fastJustify(assiduite) { } const period = { - deb: new moment.tz(assiduite.date_debut, TIMEZONE), - fin: new moment.tz(assiduite.date_fin, TIMEZONE), + deb: new Date(assiduite.date_debut), + fin: new Date(assiduite.date_fin), }; const action = (justifs) => { //créer un nouveau justificatif @@ -1660,8 +1791,8 @@ function fastJustify(assiduite) { //créer justificatif const justif = { - date_debut: new moment.tz(assiduite.date_debut, TIMEZONE).format(), - date_fin: new moment.tz(assiduite.date_fin, TIMEZONE).format(), + date_debut: new Date(assiduite.date_debut).toIsoUtcString(), + date_fin: new Date(assiduite.date_fin).toIsoUtcString(), raison: raison, etat: etat, }; diff --git a/app/templates/assiduites/pages/ajout_justificatif.j2 b/app/templates/assiduites/pages/ajout_justificatif.j2 index c4885b3f8e..83e7366c3e 100644 --- a/app/templates/assiduites/pages/ajout_justificatif.j2 +++ b/app/templates/assiduites/pages/ajout_justificatif.j2 @@ -118,8 +118,8 @@ return false; } - const date_debut = moment.tz(deb, TIMEZONE); - const date_fin = moment.tz(fin, TIMEZONE); + const date_debut = new Date(deb); + const date_fin = new Date(fin); 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"); @@ -138,8 +138,8 @@ const raison = field.querySelector('#justi_raison').value; return { - date_debut: moment.tz(deb, TIMEZONE).format(), - date_fin: moment.tz(fin, TIMEZONE).format(), + date_debut: new Date(deb).toIsoUtcString(), + date_fin: new Date(fin).toIsoUtcString(), etat: etat, raison: raison, } diff --git a/app/templates/assiduites/pages/bilan_etud.j2 b/app/templates/assiduites/pages/bilan_etud.j2 index dad94d274e..bba1dae0ee 100644 --- a/app/templates/assiduites/pages/bilan_etud.j2 +++ b/app/templates/assiduites/pages/bilan_etud.j2 @@ -93,8 +93,8 @@ return; } - const date_debut = new moment.tz(dd_val + "T00:00", TIMEZONE); - const date_fin = new moment.tz(df_val + "T23:59", TIMEZONE); + const date_debut = new Date(dd_val + "T00:00"); + const date_fin = new Date(df_val + "T23:59"); if (date_debut.valueOf() > date_fin.valueOf()) { openAlertModal("Dates invalides", document.createTextNode('La date de début se situe après la date de fin.')); @@ -102,7 +102,7 @@ } - countAssiduites(date_debut.format(), date_fin.format()) + countAssiduites(date_debut.toIsoUtcString()(), date_fin.toIsoUtcString()()) } diff --git a/app/templates/assiduites/pages/calendrier.j2 b/app/templates/assiduites/pages/calendrier.j2 index d976f2cadc..e4e793d39d 100644 --- a/app/templates/assiduites/pages/calendrier.j2 +++ b/app/templates/assiduites/pages/calendrier.j2 @@ -126,7 +126,7 @@ let datesByMonth = {}; dates.forEach((date) => { - let month = date.format("MMMM"); // Obtenir le mois + let month = date.toLocaleString('fr-FR', { month: "short" }); // Obtenir le mois if (!datesByMonth[month]) { datesByMonth[month] = []; @@ -135,6 +135,7 @@ datesByMonth[month].push(date); }); + console.log(Object.keys(datesByMonth)) return datesByMonth; } @@ -146,18 +147,18 @@ datesByMonth[month].forEach((date) => { let dayAssiduities = assiduities.filter((assiduity) => { - return moment.tz(date, TIMEZONE).isBetween( - moment.tz(assiduity.date_debut, TIMEZONE), - moment.tz(assiduity.date_fin, TIMEZONE), + return new Date(date).isBetween( + new Date(assiduity.date_debut), + new Date(assiduity.date_fin), "day", "[]" ) }); let dayJustificatifs = justificatifs.filter((justif) => { - return moment.tz(date, TIMEZONE).isBetween( - moment.tz(justif.date_debut, TIMEZONE), - moment.tz(justif.date_fin, TIMEZONE), + return new Date(date).isBetween( + new Date(justif.date_debut), + new Date(justif.date_fin), "day", "[]" ) @@ -250,7 +251,7 @@ } else if (dayJustificatifs.some((j) => j.etat.toLowerCase() !== "valide")) { est_just = "est_just invalide"; } - const momentDate = moment.tz(date, TIMEZONE); + const momentDate = new Date(date); let dayOfMonth = momentDate.format("D"); let dayOfWeek = momentDate.format("ddd");