Compare commits

...

10 Commits

25 changed files with 384 additions and 204 deletions

View File

@ -247,9 +247,9 @@ class GroupDescr(db.Model):
d["partition"] = self.partition.to_dict(with_groups=False)
return d
def get_edt_id(self) -> str:
"l'id pour l'emploi du temps: à défaut, le nom scodoc du groupe"
return self.edt_id or self.group_name or ""
def get_edt_ids(self) -> list[str]:
"les ids pour l'emploi du temps: à défaut, le nom scodoc du groupe"
return scu.split_id(self.edt_id) or [self.group_name] or []
def get_nb_inscrits(self) -> int:
"""Nombre inscrits à ce group et au formsemestre.

View File

@ -213,6 +213,7 @@ def sco_header(
window.onload=function(){{enableTooltips("gtrcontent")}};
const SCO_URL="{scu.ScoURL()}";
const SCO_TIMEZONE="{scu.TIME_ZONE}";
</script>"""
)

View File

@ -157,10 +157,15 @@ class JustificatifArchiver(BaseArchiver):
Si trace == True : sauvegarde le nom du/des fichier(s) supprimé(s)
dans la trace de l'étudiant
"""
print("debug : ", archive_name, filename, has_trace)
if str(etud.id) not in self.list_oids(etud.dept_id):
raise ValueError(f"Aucune archive pour etudid[{etud.id}]")
archive_id = self.get_id_from_name(etud.id, archive_name, dept_id=etud.dept_id)
try:
archive_id = self.get_id_from_name(
etud.id, archive_name, dept_id=etud.dept_id
)
except ScoValueError:
raise ValueError(f"Archive Inconnue [{archive_name}]")
if filename is not None:
if filename not in self.list_archive(archive_id, dept_id=etud.dept_id):

View File

@ -55,6 +55,7 @@ def formsemestre_load_calendar(
"""Load ics data, return raw ics and decoded calendar.
Raises ScoValueError if not configured or not available or invalid format.
"""
edt_ids = []
if edt_id is None and formsemestre:
edt_ids = formsemestre.get_edt_ids()
if not edt_ids:
@ -408,6 +409,7 @@ def formsemestre_retreive_groups_from_edt_id(
"""Construit un dict donnant le groupe de chaque edt_id"""
edt2group = {}
for partition in formsemestre.partitions:
edt2group.update({g.get_edt_id(): g for g in partition.groups})
edt2group.pop("", None)
for g in partition.groups:
for edt_id in g.get_edt_ids():
edt2group[edt_id] = g
return edt2group

View File

@ -101,7 +101,8 @@ def group_rename(group_id):
"allow_null": True,
"explanation": """optionnel : identifiant du groupe dans le logiciel
d'emploi du temps, pour le cas où les noms de groupes ne seraient pas
les mêmes dans ScoDoc et dans l'emploi du temps.""",
les mêmes dans ScoDoc et dans l'emploi du temps (si plusieurs ids,
les séparer par des virgules).""",
},
),
),

View File

@ -305,8 +305,8 @@ function executeMassActionQueue() {
*/
const tlTimes = getTimeLineTimes();
let assiduite = {
date_debut: tlTimes.deb.toIsoUtcString(),
date_fin: tlTimes.fin.toIsoUtcString(),
date_debut: tlTimes.deb.toFakeIso(),
date_fin: tlTimes.fin.toFakeIso(),
};
assiduite = setModuleImplId(assiduite);
@ -601,7 +601,10 @@ function toTime(time) {
* @returns
*/
function formatDate(date, styles = { dateStyle: "full" }) {
return new Intl.DateTimeFormat("fr-FR", styles).format(date);
return new Intl.DateTimeFormat("fr-FR", {
...{ timeZone: SCO_TIMEZONE },
...styles,
}).format(date);
}
/**
@ -610,19 +613,25 @@ function formatDate(date, styles = { dateStyle: "full" }) {
function updateDate() {
const dateInput = document.querySelector("#tl_date");
let date = $(dateInput).datepicker("getDate");
if (date == null) {
date = new Date(Date.fromFRA(dateInput.value));
}
const intlOptions = {
dateStyle: "full",
timeZone: SCO_TIMEZONE,
};
let dateStr = "";
if (!isNonWorkDay(date.getDay(), nonWorkDays)) {
dateStr = formatDate(date).capitalize();
if (!isNonWorkDay(date, nonWorkDays)) {
dateStr = formatDate(date, intlOptions).capitalize();
} else {
// On se rend au dernier jour travaillé disponible
const lastWorkDay = getNearestWorkDay(date);
const att = document.createTextNode(
`Le jour sélectionné (${formatDate(date)}) n'est pas un jour travaillé.`
`Le jour sélectionné (${formatDate(
date,
intlOptions
)}) n'est pas un jour travaillé.`
);
const div = document.createElement("div");
div.appendChild(att);
@ -630,22 +639,23 @@ function updateDate() {
div.appendChild(
document.createTextNode(
`Le dernier jour travaillé disponible a été sélectionné : ${formatDate(
lastWorkDay
lastWorkDay,
intlOptions
)}.`
)
);
openAlertModal("Attention", div, "", "#eec660");
const date_fra = Date.toFRA(lastWorkDay.toIsoUtcString().split("T")[0]);
$(dateInput).datepicker("setDate", date_fra);
dateInput.value = date_fra;
date = lastWorkDay;
dateStr = formatDate(lastWorkDay).capitalize();
dateStr = formatDate(lastWorkDay, {
dateStyle: "full",
timeZone: SCO_TIMEZONE,
}).capitalize();
}
console.warn(dateStr, date, date.toIsoUtcString());
document.querySelector("#datestr").textContent = dateStr;
return true;
}
@ -654,7 +664,7 @@ function getNearestWorkDay(date) {
const aDay = 86400000; // 24 * 3600 * 1000 | H * s * ms
let day = date;
let count = 0;
while (isNonWorkDay(day.getDay(), nonWorkDays) && count++ < 7) {
while (isNonWorkDay(day, nonWorkDays) && count++ < 7) {
day = new Date(day - aDay);
}
return day;
@ -712,31 +722,12 @@ function formatDateModal(str, separator = " ") {
* Renvoie Vrai si le jour est non travaillé
*/
function isNonWorkDay(day, nonWorkdays) {
let d = "";
switch (day) {
case 0:
d = "dim";
break;
case 1:
d = "lun";
break;
case 2:
d = "mar";
break;
case 3:
d = "mer";
break;
case 4:
d = "jeu";
break;
case 5:
d = "ven";
break;
case 6:
d = "sam";
break;
}
const d = Intl.DateTimeFormat("fr-FR", {
timeZone: SCO_TIMEZONE,
weekday: "short",
})
.format(day)
.replace(".", "");
return nonWorkdays.indexOf(d) != -1;
}
@ -783,8 +774,8 @@ function getTimeLineTimes() {
function isConflictSameAsPeriod(conflict, period = undefined) {
const tlTimes = period == undefined ? getTimeLineTimes() : period;
const clTimes = {
deb: new Date(conflict.date_debut),
fin: new Date(conflict.date_fin),
deb: new Date(Date.removeUTC(conflict.date_debut)),
fin: new Date(Date.removeUTC(conflict.date_fin)),
};
return tlTimes.deb.isSame(clTimes.deb) && tlTimes.fin.isSame(clTimes.fin);
}
@ -850,8 +841,8 @@ function numberTimeToDate(nb) {
function getAssiduitesFromEtuds(clear, deb, fin) {
const etudIds = Object.keys(etuds).join(",");
const date_debut = deb ? deb : getPrevDate().toIsoUtcString();
const date_fin = fin ? fin : getNextDate().toIsoUtcString();
const date_debut = deb ? deb : getPrevDate().toFakeIso();
const date_fin = fin ? fin : getNextDate().toFakeIso();
if (clear) {
assiduites = {};
@ -894,8 +885,8 @@ function getAssiduitesFromEtuds(clear, deb, fin) {
function createAssiduite(etat, etudid) {
const tlTimes = getTimeLineTimes();
let assiduite = {
date_debut: tlTimes.deb.toIsoUtcString(),
date_fin: tlTimes.fin.toIsoUtcString(),
date_debut: tlTimes.deb.toFakeIso(),
date_fin: tlTimes.fin.toFakeIso(),
etat: etat,
};
@ -937,6 +928,19 @@ function createAssiduite(etat, etudid) {
openAlertModal("Sélection du module", content);
}
if (
data.errors["0"].message == "L'étudiant n'est pas inscrit au module"
) {
const HTML = `
<p>Attention, l'étudiant n'est pas inscrit à ce module.</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;
}
},
@ -1076,8 +1080,8 @@ function getAssiduitesConflict(etudid, periode) {
return etudAssiduites.filter((assi) => {
const interval = {
deb: new Date(assi.date_debut),
fin: new Date(assi.date_fin),
deb: new Date(Date.removeUTC(assi.date_debut)),
fin: new Date(Date.removeUTC(assi.date_fin)),
};
const test = hasTimeConflict(periode, interval);
return test;
@ -1101,15 +1105,15 @@ function getLastAssiduiteOfPrevDate(etudid) {
const prevAssiduites = etudAssiduites
.filter((assi) => {
const interval = {
deb: new Date(assi.date_debut),
fin: new Date(assi.date_fin),
deb: new Date(Date.removeUTC(assi.date_debut)),
fin: new Date(Date.removeUTC(assi.date_fin)),
};
return hasTimeConflict(period, interval);
})
.sort((a, b) => {
const a_fin = new Date(a.date_fin);
const b_fin = new Date(b.date_fin);
const a_fin = new Date(Date.removeUTC(a.date_fin));
const b_fin = new Date(Date.removeUTC(b.date_fin));
return b_fin < a_fin;
});
@ -1144,8 +1148,8 @@ function getAssiduiteValue(field) {
* @param {String | Number} etudid identifiant de l'étudiant
*/
function actualizeEtudAssiduite(etudid) {
const date_debut = getPrevDate().toIsoUtcString();
const date_fin = getNextDate().toIsoUtcString();
const date_debut = getPrevDate().toFakeIso();
const date_fin = getNextDate().toFakeIso();
const url_api =
getUrl() +
@ -1391,8 +1395,8 @@ function insertEtudRow(etud, index, output = false) {
assiduite.etatAssiduite = conflict[0].etat;
assiduite.id = conflict[0].assiduite_id;
assiduite.date_debut = conflict[0].date_debut;
assiduite.date_fin = conflict[0].date_fin;
assiduite.date_debut = Date.removeUTC(conflict[0].date_debut);
assiduite.date_fin = Date.removeUTC(conflict[0].date_fin);
if (isConflictSameAsPeriod(conflict[0])) {
assiduite.type = "édition";
} else {
@ -1623,9 +1627,7 @@ function getJustificatifFromPeriod(date, etudid, update) {
getUrl() +
`/api/justificatifs/${etudid}/query?date_debut=${date.deb
.add(1, "seconds")
.toIsoUtcString()}&date_fin=${date.fin
.add(-1, "seconds")
.toIsoUtcString()}`,
.toFakeIso()}&date_fin=${date.fin.add(-1, "seconds").toFakeIso()}`,
success: (data) => {
update(data);
},
@ -1657,8 +1659,8 @@ function fastJustify(assiduite) {
}
const period = {
deb: new Date(assiduite.date_debut),
fin: new Date(assiduite.date_fin),
deb: new Date(Date.removeUTC(assiduite.date_debut)),
fin: new Date(Date.removeUTC(assiduite.date_fin)),
};
const action = (justifs) => {
//créer un nouveau justificatif
@ -1671,8 +1673,8 @@ function fastJustify(assiduite) {
//créer justificatif
const justif = {
date_debut: new Date(assiduite.date_debut).toIsoUtcString(),
date_fin: new Date(assiduite.date_fin).toIsoUtcString(),
date_debut: new Date(Date.removeUTC(assiduite.date_debut)).toFakeIso(),
date_fin: new Date(Date.removeUTC(assiduite.date_fin)).toFakeIso(),
raison: raison,
etat: etat,
};

View File

@ -59,6 +59,11 @@ Date.intersect = function (period, interval) {
return period.deb <= interval.fin && period.fin >= interval.deb;
};
Date.removeUTC = function (isoString) {
const reg = new RegExp(/[+-][\d:]+$/);
return isoString.replace(reg, "");
};
Object.defineProperty(Date.prototype, "isValid", {
value: function () {
return !Number.isNaN(this.getTime());
@ -198,13 +203,29 @@ Object.defineProperty(Date.prototype, "toIsoUtcString", {
* @returns date au format iso utc (yyyy-mm-ddThh:MM±oo:oo:oo)
*/
value: function () {
// Formater la date et l'heure
const date = this;
var tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? "+" : "-",
pad = function (num) {
return (num < 10 ? "0" : "") + num;
};
return (
this.toFakeIso() +
dif +
pad(Math.floor(Math.abs(tzo) / 60)) +
":" +
pad(Math.abs(tzo) % 60)
);
},
});
Object.defineProperty(Date.prototype, "toFakeIso", {
value: function () {
const date = this;
pad = function (num) {
return (num < 10 ? "0" : "") + num;
};
return (
date.getFullYear() +
"-" +
@ -216,11 +237,7 @@ Object.defineProperty(Date.prototype, "toIsoUtcString", {
":" +
pad(date.getMinutes()) +
":" +
pad(date.getSeconds()) +
dif +
pad(Math.floor(Math.abs(tzo) / 60)) +
":" +
pad(Math.abs(tzo) % 60)
pad(date.getSeconds())
);
},
});
@ -246,6 +263,7 @@ Object.defineProperty(Date.prototype, "format", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
timeZone: SCO_TIMEZONE,
});
case "DD/MM/YYYY HH:mm":
return this.toLocaleString("fr-FR", {
@ -255,6 +273,7 @@ Object.defineProperty(Date.prototype, "format", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
timeZone: SCO_TIMEZONE,
});
case "YYYY-MM-DDTHH:mm":
@ -264,7 +283,7 @@ Object.defineProperty(Date.prototype, "format", {
case "YYYY-MM-DD":
return iso.slice(0, iso.indexOf("T"));
default:
return this.toIsoUtcString();
return this.toFakeIso();
}
},
});

View File

@ -0,0 +1,198 @@
const studentsdemo = [
{ "name": "Alice", "wait": 500, "sems": [0, 2] },
{ "name": "Bob", "wait": 500, "sems": [1, 2, 3]}
];
const semsdemo = [
{ "id": 0, "wait": 4, "notes": {"Alice": 13 } },
{ "id": 1, "wait": 3, "notes": {"Bob": 6 } },
{ "id": 2, "wait": 8, "notes": {"Alice": 11, "Bob": 18 } },
{ "id": 3, "wait": 7, "notes": {"Bob": 17 } },
];
/*
getStudents <= [ "Alice", #Bob" ]
getSems("Alice") <= [ 1, 3]
getSems("Bob") <= [ 2, 3, 4]
getMarks(1) <= {"Alice": 13 }
getMarks(2) <= {"Alice": 13 }...
getMarks(3) <= {"Alice": 13 }
getMarks(4) <= {"Alice": 13 }
*/
const api = {
getStudents() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(studentsdemo);
}, 500);
});
},
getStudentSems(student) {
return new Promise(
resolve => { setTimeout(resolve, student.wait, student.sems); }
);
},
getMarks(sem_id) {
return new Promise(
resolve => { setTimeout(resolve, semsdemo[sem_id].wait, semsdemo[sem_id].notes ); }
)
}
}
$(document).ready(function() {
$("#ok").click(function(){
do_export();
});
});
function getData() {
// let students = api.getStudents()
// console.log(students);
// let promises =
// students.map((student) => api.getStudentSems(student));
// return Promise.all(promises);
}
async function asyncCall() {
// const sem_requests = new Map();
console.log('***************** start *****************');
const students = await api.getStudents();
console.log('***************** got students *****************');
console.log(students)
console.log('***************** seeking sems and marks *****************');
const student_requests = students.map((student) => {
return api.getStudentSems(student);
});
const sems = await Promise.all(student_requests);
const full_sem = sems.flat();
const set_sem = [...new Set(full_sem)];
const studentsGrades = await Promise.all(set_sem.map(sem => api.getMarks(sem)));
debugger;
/*
console.log("lookup for " + student.name + "'s sems.");
const sems = api.getStudentSems(student)
console.log(`***************** got ${student.name}'s sems *****************`);
console.log(sems);
return sems;
});
const sems.forEach((sem) => {
console.log(`looking for mark for sem ${sem}`);
console.log("** current sems requests");
console.log(sem_requests)
if (sem_requests[sem] === 'undefined') {
console.log(`seeking ${sem} marks`)
sem_requests[sem] = api.getMarks(sem);
}
})
sems.forEach((sem) => {
console.log(`looking for mark for sem ${sem}`);
console.log("** current sems requests");
console.log(sem_requests)
if (sem_requests[sem] === 'undefined') {
console.log(`seeking ${sem} marks`)
sem_requests[sem] = api.getMarks(sem);
}
})
let result_sems = await Promise.all(sem_requests)
console.log('***************** sems ok *****************');
console.log(result_sems);
console.log('***************** stop *****************');
*/
// Expected output: "resolved"
}
function do_export() {
event.preventDefault();
// students = getData();
// console.log(students);
asyncCall();
}
// let loaded_sems = [];
//
// async function doit() {
// getStudents()
// .then(students => {
// return Promise.all(students.map(student => {
// api.getStudentSems(student)
// .then(sems_id => {
// sem_requests = []
// sems_id.forEach(sem_id => {
// if (typeof sem_requests[sem_id] === 'undefined') {
// sem_requests[sem_id](api.getMarks(sem_id));
// });
// });
// then(allMarks => {
// console.log(allMarks);
// });
// });
// }
/*
let dataSrc = "/ScoDoc/{{dept}}/api/formsemestre/{{formsemestre.id}}/etudiants/long";
let formsemestres = [];
fetch(dataSrc)
.then(r => { return r.json(); })
.then(json => {
let etudiants = json;
promises_etud_semestres = []
promises_semestres = []
etudiants.forEach((etudiant) => {
let url =`/ScoDoc/{{dept}}/api/etudiant/nip/${etudiant.code_nip}/formsemestres`;
console.log(url);
promises_etud_semestres.push(
fetch(url)
.then(r => { return r.json(); })
.then(semestre => {
formsemestre_id = semestre.formsemestre_id;
})
)
// etudiant.formsemestres_id = [];
fetch(url)
.then(r => {return r.json; })
.then(json => {
let forms = json;
console.log(etudiant.code_nip + " " + forms.formsemestre_id);
// forms.forEach((formsem) => {
// if (formsem.is_apc) {
// etudiant.formsemestres_id.push(formsem.formsemestre_id);
// if (formsem.formsemestre_id in_array()) {
// }
// }
// });
});
});
//let releve = document.querySelector("releve-but");
//releve.showData = json;
// Style custom à ajouter
// let style = document.createElement("style");
// style.textContent = `
// .module>div,
// .dateInscription,
// .numerosEtudiant,
// .dateNaissance{
// display: none;
// }`;
//releve.shadowRoot.appendChild(style);
})
.catch(error => { console.log(error)});
// .catch(error => {
// let div = document.createElement("div");
// div.innerText = "Une erreur s'est produite lors du transfert des données.";
// div.style.fontSize = "24px";
// div.style.color = "#d93030";
// let releve = document.querySelector("releve-but");
// releve.after(div);
// releve.remove();
// throw 'Fin du script - données invalides';
// });
*/

View File

@ -103,7 +103,7 @@
[required]::after {
content: "*";
color: crimson;
color: var(--color-error);
}
</style>
<script>
@ -137,8 +137,8 @@
const raison = field.querySelector('#justi_raison').value;
return {
date_debut: new Date(deb).toIsoUtcString(),
date_fin: new Date(fin).toIsoUtcString(),
date_debut: new Date(deb).toFakeIso(),
date_fin: new Date(fin).toFakeIso(),
etat: etat,
raison: raison,
}

View File

@ -167,7 +167,7 @@
margin: 5px 0;
border-radius: 7px;
background-color: crimson;
background-color: var(--color-error);
}

View File

@ -101,7 +101,7 @@
openAlertModal("Dates invalides", document.createTextNode('La date de début se situe après la date de fin.'));
return;
}
countAssiduites(date_debut.toIsoUtcString(), date_fin.toIsoUtcString())
countAssiduites(date_debut.toFakeIso(), date_fin.toFakeIso())
}
@ -366,7 +366,7 @@
margin: 5px 0;
border-radius: 7px;
background-color: crimson;
background-color: var(--color-error);
}

View File

@ -453,17 +453,17 @@
let dayOfWeek = momentDate.getDay();
dayOfWeek = days[dayOfWeek];
let isNonWorkDay = nonWorkdays.includes(dayOfWeek.toLowerCase());
let isNonWorkDayVar = nonWorkdays.includes(dayOfWeek.toLowerCase());
const day = document.createElement('div');
day.className = `day`;
if (isNonWorkDay) {
if (isNonWorkDayVar) {
color = "nonwork";
} else if (!options.mode_demi) {
day.className = `day ${est_just}`;
}
if (options.mode_demi && !isNonWorkDay) {
if (options.mode_demi && !isNonWorkDayVar) {
est_just = []
// affichage n° jour + matin + aprem
@ -560,7 +560,7 @@
day.classList.add(color);
}
if (isNonWorkDay) {
if (isNonWorkDayVar) {
const span_jour = document.createElement("span")
span_jour.textContent = dayOfWeek[0] + dayOfMonth;
day.appendChild(span_jour);
@ -570,7 +570,6 @@
}
console.warn(day.classList, day.classList.length)
if (!nonWorkdays.includes(dayOfWeek.toLowerCase()) && dayAssiduities.length > 0) {

View File

@ -41,7 +41,7 @@
if (defaultDates != null) {
defaultDates.forEach((dateString) => {
d = new Date(dateString).getDay();
d = new Date(dateString);
if (isNonWorkDay(d, nonWorkDays)) return;
@ -70,4 +70,4 @@
{% include "assiduites/widgets/alert.j2" %}
{% include "assiduites/widgets/prompt.j2" %}
{% include "assiduites/widgets/conflict.j2" %}
{% include "assiduites/widgets/toast.j2" %}
{% include "assiduites/widgets/toast.j2" %}

View File

@ -105,13 +105,13 @@
updateJustifyBtn();
});
updateDate();
getSingleEtud({{ sco.etud.id }});
actualizeEtud({{ sco.etud.id }});
updateSelect()
updateJustifyBtn();
window.addEventListener("DOMContentLoaded", () => {
updateDate();
getSingleEtud(etudid);
actualizeEtud(etudid);
updateSelect()
updateJustifyBtn();
})
function setTimeLineTimes(a, b) {

View File

@ -270,14 +270,14 @@
) {
const assiduite_avant = {
etat: this.selectedAssiduite.etat,
date_debut: assiduite_debut.toIsoUtcString()(),
date_fin: separtorDate.toIsoUtcString()(),
date_debut: assiduite_debut.toFakeIso(),
date_fin: separtorDate.toFakeIso(),
};
const assiduite_apres = {
etat: this.selectedAssiduite.etat,
date_debut: separtorDate.toIsoUtcString()(),
date_fin: assiduite_fin.toIsoUtcString()(),
date_debut: separtorDate.toFakeIso(),
date_fin: assiduite_fin.toFakeIso(),
};
if (this.selectedAssiduite.moduleimpl_id) {

View File

@ -285,10 +285,10 @@
let currentDate = "{{date}}";
if (currentDate == "") {
currentDate = new Date();
currentDate = currentDate.format("YYYY-MM-DDTHH:mm");
currentDate = currentDate.toFakeIso();
} else {
currentDate = new Date(currentDate);
currentDate = currentDate.format("YYYY-MM-DDTHH:mm");
currentDate = currentDate.toFakeIso();
}
@ -439,7 +439,7 @@
date = new Date(currentDate);
const start = typeof mt_start !== 'undefined' ? mt_start : 0
date.setHours(start);
date = date.format("YYYY-MM-DDTHH:mm")
date = date.toFakeIso()
} else {
date = last.value;
}
@ -555,14 +555,14 @@
}
if (get) {
getAssiduitesFromEtuds(false, d_debut.toIsoUtcString(), d_fin.toIsoUtcString())
getAssiduitesFromEtuds(false, d_debut.toFakeIso(), d_fin.toFakeIso())
return 0x0;
}
return {
moduleimpl: moduleSelect,
deb: d_debut.toIsoUtcString(),
fin: d_fin.toIsoUtcString(),
deb: d_debut.toFakeIso(),
fin: d_fin.toFakeIso(),
}
@ -653,6 +653,10 @@
colIds.forEach((colid) => {
getAndUpdateCol(colid)
})
if (isSingleEtud()) {
actualizeEtud(etudid);
}
}
function launchToast(etudid, etat) {

View File

@ -13,14 +13,13 @@
*/
function createMiniTimeline(assiduitesArray, day = null) {
const array = [...assiduitesArray];
const dateiso = day == null ? getDate().format("YYYY-MM-DD") : day;
const date = day == null ? getDate() : new Date(day);
const timeline = document.createElement("div");
timeline.className = "mini-timeline";
if (isSingleEtud()) {
timeline.classList.add("single");
}
const timelineDate = new Date(dateiso).startOf("day");
const timelineDate = date.startOf("day");
const dayStart = timelineDate.clone().add(mt_start, "hours");
const dayEnd = timelineDate.clone().add(mt_end, "hours");
const dayDuration = new Duration(dayStart, dayEnd).minutes;
@ -36,12 +35,12 @@
date_fin: tlTimes.fin.format(),
etat: "CRENEAU",
});
}
array.forEach((assiduité) => {
let startDate = new Date(assiduité.date_debut);
let endDate = new Date(assiduité.date_fin);
let startDate = new Date(Date.removeUTC(assiduité.date_debut));
let endDate = new Date(Date.removeUTC(assiduité.date_fin));
if (startDate.isBefore(dayStart)) {
startDate = dayEnd.clone().startOf("day").add(mt_start, "hours");
}
@ -52,11 +51,12 @@
const block = document.createElement("div");
block.className = "mini-timeline-block";
const duration = new Duration(startDate, endDate).minutes;
const startOffset = new Duration(dayStart, startDate).minutes;
const duration = (new Duration(startDate, endDate)).minutes;
const startOffset = (new Duration(dayStart, startDate)).minutes;
const leftPercentage = (startOffset / dayDuration) * 100;
const widthPercentage = (duration / dayDuration) * 100;
block.style.left = `${leftPercentage}%`;
block.style.width = `${widthPercentage}%`;

View File

@ -21,9 +21,9 @@
}
function filterFormSemestres(semestres, dateIso) {
const date = new Date(dateIso);
const date = new Date(Date.removeUTC(dateIso));
semestres = semestres.filter((fm) => {
return date.isBetween(new Date(fm.date_debut_iso), new Date(fm.date_fin_iso), '[]');
return date.isBetween(new Date(Date.removeUTC(fm.date_debut_iso)), new Date(Date.removeUTC(fm.date_fin_iso)), '[]');
})
return semestres;

View File

@ -83,7 +83,7 @@
filterAssiduites.columns.forEach((k) => {
const td = document.createElement('td');
if (k.indexOf('date') != -1) {
td.textContent = new Date(assiduite[k]).format(`DD/MM/Y HH:mm`)
td.textContent = new Date(Date.removeUTC(assiduite[k])).format(`DD/MM/Y HH:mm`)
} else if (k.indexOf("module") != -1) {
td.textContent = getModuleImpl(assiduite);
} else if (k.indexOf('est_just') != -1) {
@ -115,9 +115,9 @@
const user = getUser(data);
const module = getModuleImpl(data);
const date_debut = new Date(data.date_debut).format("DD/MM/YYYY HH:mm");
const date_fin = new Date(data.date_fin).format("DD/MM/YYYY HH:mm");
const entry_date = new Date(data.entry_date).format("DD/MM/YYYY HH:mm");
const date_debut = new Date(Date.removeUTC(data.date_debut)).format("DD/MM/YYYY HH:mm");
const date_fin = new Date(Date.removeUTC(data.date_fin)).format("DD/MM/YYYY HH:mm");
const entry_date = new Date(Date.removeUTC(data.entry_date)).format("DD/MM/YYYY HH:mm");
const etat = data.etat.capitalize();
const desc = data.desc == null ? "" : data.desc;
@ -433,7 +433,7 @@
if (l.querySelector(`#${key}_time`).value != "") {
filterAssiduites.filters[key] = {
pref: pref,
time: new Date(time)
time: new Date(Date.removeUTC(time))
}
}
} else if (key.indexOf('etat') != -1) {

View File

@ -75,7 +75,7 @@
}
}
if (k.indexOf('date') != -1) {
const assi_time = new Date(el[k]);
const assi_time = new Date(Date.removeUTC(el[k]));
const filter_time = f[k].time;
switch (f[k].pref) {
@ -262,8 +262,8 @@
let keyValueB = b[keyword];
if (keyword.indexOf("date") != -1) {
keyValueA = new Date(keyValueA)
keyValueB = new Date(keyValueB)
keyValueA = new Date(Date.removeUTC(keyValueA))
keyValueB = new Date(Date.removeUTC(keyValueB))
}
if (keyword.indexOf("module") != -1) {

View File

@ -82,7 +82,7 @@
filterJustificatifs.columns.forEach((k) => {
const td = document.createElement('td');
if (k.indexOf('date') != -1) {
td.textContent = new Date(justificatif[k]).format(`DD/MM/Y HH:mm`)
td.textContent = new Date(Date.removeUTC(justificatif[k])).format(`DD/MM/Y HH:mm`)
} else if (k.indexOf('fichier') != -1) {
td.textContent = justificatif.fichier ? "Oui" : "Non";
} else if (k.indexOf('etudid') != -1) {
@ -120,9 +120,9 @@
path,
(data) => {
const user = getUser(data);
const date_debut = new Date(data.date_debut).format("DD/MM/YYYY HH:mm");
const date_fin = new Date(data.date_fin).format("DD/MM/YYYY HH:mm");
const entry_date = new Date(data.entry_date).format("DD/MM/YYYY HH:mm");
const date_debut = new Date(Date.removeUTC(data.date_debut)).format("DD/MM/YYYY HH:mm");
const date_fin = new Date(Date.removeUTC(data.date_fin)).format("DD/MM/YYYY HH:mm");
const entry_date = new Date(Date.removeUTC(data.entry_date)).format("DD/MM/YYYY HH:mm");
const etat = data.etat.capitalize();
const desc = data.raison == null ? "" : data.raison;
@ -305,8 +305,8 @@
assiEdit.querySelector('#justi_etat').value = data.etat.toLowerCase();
assiEdit.querySelector('#justi_raison').value = desc;
const d_deb = new Date(data.date_debut).format("YYYY-MM-DDTHH:mm")
const d_fin = new Date(data.date_fin).format("YYYY-MM-DDTHH:mm")
const d_deb = new Date(Date.removeUTC(data.date_debut)).format("YYYY-MM-DDTHH:mm")
const d_fin = new Date(Date.removeUTC(data.date_fin)).format("YYYY-MM-DDTHH:mm")
assiEdit.querySelector('#justi_date_debut').value = d_deb
assiEdit.querySelector('#justi_date_fin').value = d_fin
@ -356,8 +356,8 @@
openAlertModal("Dates erronées", document.createTextNode('Les dates sont invalides'));
return true
}
date_debut = new Date(date_debut)
date_fin = new Date(date_fin)
date_debut = new Date(Date.removeUTC(date_debut))
date_fin = new Date(Date.removeUTC(date_fin))
if (date_debut >= date_fin) {
openAlertModal("Dates erronées", document.createTextNode('La date de fin doit être après la date de début'));
@ -625,7 +625,7 @@
if (l.querySelector(`#${key}_time`).value != "") {
filterJustificatifs.filters[key] = {
pref: pref,
time: new Date(time)
time: new Date(Date.removeUTC(time))
}
}
} else if (key.indexOf('etat') != -1) {

View File

@ -72,7 +72,7 @@
</div>
<script>
setTimeout(function() {
setTimeout(function () {
var flashes = document.getElementsByClassName("flashes")[0];
if (flashes) {
flashes.style.display = "none";
@ -93,5 +93,6 @@
<script src="{{scu.STATIC_DIR}}/js/scodoc.js"></script>
<script>
const SCO_URL = "{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)[:-11] }}";
const SCO_TIMEZONE = {{ scu.TIME_ZONE }}
</script>
{% endblock %}
{% endblock %}

View File

@ -18,8 +18,12 @@
Bulletin
<span class="bull_liensemestre">
{{formsemestre.html_link_status() | safe}}
{% if formsemestre.etuds_inscriptions[etud.id].parcour %}
<span class="parcours">Parcours {{formsemestre.etuds_inscriptions[etud.id].parcour.code}}</span>
{% if etud.id in formsemestre.etuds_inscriptions %}
{% if formsemestre.etuds_inscriptions[etud.id].parcour %}
<span class="parcours">Parcours {{formsemestre.etuds_inscriptions[etud.id].parcour.code}}</span>
{% endif %}
{% else %}
<span class="parcours">{{scu.EMO_WARNING|safe}} non inscrit !?</span>
{% endif %}
</span>
</div>
@ -67,8 +71,8 @@
)}}">version courte spéciale BUT</a>
{% endif %}
<a style="margin-left: 32px;" class="stdlink"
href="{{url_for('notes.validation_rcues',
scodoc_dept=g.scodoc_dept, etudid=etud.id,
href="{{url_for('notes.validation_rcues',
scodoc_dept=g.scodoc_dept, etudid=etud.id,
formsemestre_id=formsemestre.id
)}}">visualiser les compétences BUT</a>
</div>

View File

@ -9,80 +9,24 @@
<H1>Export xlsx de fichier de jury</H1>
<form onsubmit="do_export()">
Formsemestre: {{ formsemestre.id }}
API root: {{ api_root }}
<button>Exporter</button>
<form>
<p>Formsemestre: {{ formsemestre.id }}</p><br/>
<p>API root: /ScoDoc/{{dept}}/api/</p><br/>
<button id="ok">Exporter</button>
</form>
{% endblock %}
{% block scripts %}
{{super()}}
<script>
let formsemestre_id = {{ formsemestre.id }};
let dept = "{{ dept }}";
</script>
<script src="{{scu.STATIC_DIR}}/js/export-jury-but.js"></script>
<script>
let dataSrc = "/ScoDoc/{{dept}}/api/formsemestre/{{formsemestre.id}}/etudiants/long";
let formsemestres = [];
fetch(dataSrc)
.then(r => { return r.json(); })
.then(json => {
let etudiants = json;
promises_etud_semestres = []
promises_semestres = []
etudiants.forEach((etudiant) => {
let url =`/ScoDoc/{{dept}}/api/etudiant/nip/${etudiant.code_nip}/formsemestres`;
console.log(url);
promises_etud_semestres.push(
fetch(url)
.then(r => { return r.json(); })
.then(semestre => {
formsemestre_id = semestre.formsemestre_id;
})
)
// etudiant.formsemestres_id = [];
fetch(url)
.then(r => {return r.json; })
.then(json => {
let forms = json;
console.log(etudiant.code_nip + " " + forms.formsemestre_id);
// forms.forEach((formsem) => {
// if (formsem.is_apc) {
// etudiant.formsemestres_id.push(formsem.formsemestre_id);
// if (formsem.formsemestre_id in_array()) {
// }
// }
// });
});
});
//let releve = document.querySelector("releve-but");
//releve.showData = json;
// Style custom à ajouter
// let style = document.createElement("style");
// style.textContent = `
// .module>div,
// .dateInscription,
// .numerosEtudiant,
// .dateNaissance{
// display: none;
// }`;
//releve.shadowRoot.appendChild(style);
})
.catch(error => { console.log(error)});
// .catch(error => {
// let div = document.createElement("div");
// div.innerText = "Une erreur s'est produite lors du transfert des données.";
// div.style.fontSize = "24px";
// div.style.color = "#d93030";
// let releve = document.querySelector("releve-but");
// releve.after(div);
// releve.remove();
// throw 'Fin du script - données invalides';
// });
document.querySelector("html").style.scrollBehavior = "smooth";
</script>

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "9.6.58"
SCOVERSION = "9.6.60"
SCONAME = "ScoDoc"