385 lines
12 KiB
JavaScript
385 lines
12 KiB
JavaScript
document.addEventListener("DOMContentLoaded", async function () {
|
|
// Fetch data from the server
|
|
//// parse TOken
|
|
const token = localStorage.getItem("jwtToken");
|
|
|
|
if (!token) {
|
|
throw new Error("Aucun token trouvé dans le localStorage.");
|
|
}
|
|
|
|
const userData = parseJwt(token);
|
|
|
|
if (!userData) {
|
|
displayError("Erreur lors de l'extraction des données utilisateur à partir du token.");
|
|
|
|
return;
|
|
}
|
|
|
|
const { userAuthGroupe, userMatricule } = userData;
|
|
const isAdmin = userAuthGroupe === "ADMIN";
|
|
const matriculeUser = userMatricule;
|
|
|
|
let regionUser;
|
|
let tableData = [];
|
|
|
|
const checkAdmin = document.querySelector('#checkRegionAdmin');
|
|
|
|
if (isAdmin) {
|
|
checkAdmin.style.display = "flex";
|
|
}
|
|
|
|
try {
|
|
const userResponse = await fetchUserDetails(matriculeUser);
|
|
regionUser = userResponse?.user["@expand"].region?.nom || null;
|
|
} catch (error) {
|
|
displayError("Erreur lors de la récupération des données utilisateur.");
|
|
|
|
return;
|
|
}
|
|
|
|
const checkboxWrappers = Array.from(document.querySelectorAll('[class^="checkbox-wrapper-"]'));
|
|
const checkboxes = checkboxWrappers.map(wrapper => wrapper.querySelector('input[type="checkbox"]'));
|
|
const regions = checkboxWrappers.map(wrapper => wrapper.querySelector('.checkboxRegion').textContent);
|
|
|
|
// Initialize checkboxes
|
|
checkboxes.forEach((checkbox, index) => {
|
|
if (regions[index] === regionUser) {
|
|
checkbox.checked = true;
|
|
}
|
|
});
|
|
|
|
// Fetch initial data
|
|
try {
|
|
const response = await fetch(`/historiqueParcours/${regionUser}`);
|
|
const dataResponse = await response.json();
|
|
|
|
if (dataResponse.valid) {
|
|
tableData = dataResponse.data;
|
|
populateParcoursTable(tableData);
|
|
} else {
|
|
displayError("Erreur lors de la récupération des parcours");
|
|
}
|
|
} catch (error) {
|
|
displayError("Failed to fetch data. Please try again later.");
|
|
}
|
|
|
|
// Add event listeners to checkboxes
|
|
checkboxes.forEach((checkbox, index) => {
|
|
checkbox.addEventListener('change', async (e) => {
|
|
const region = regions[index];
|
|
|
|
if (checkbox.checked) {
|
|
try {
|
|
const response = await fetch(`/historiqueParcours/${region}`);
|
|
const dataResponse = await response.json();
|
|
|
|
if (dataResponse.valid) {
|
|
tableData.push(...dataResponse.data);
|
|
populateParcoursTable(tableData);
|
|
} else {
|
|
displayError("Erreur lors de la récupération des parcours");
|
|
}
|
|
} catch (error) {
|
|
displayError("Failed to fetch data. Please try again later.");
|
|
}
|
|
} else {
|
|
removeRegionFromTableData(region);
|
|
populateParcoursTable(tableData);
|
|
}
|
|
});
|
|
});
|
|
|
|
const removeRegionFromTableData = (region) => {
|
|
tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== (region === regionUser ? regionUser : region));
|
|
};
|
|
});
|
|
|
|
const removeRegionFromTableData = (region) => {
|
|
if (region === regionUser) {
|
|
tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== regionUser);
|
|
} else {
|
|
tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== region);
|
|
}
|
|
};
|
|
|
|
async function fetchUserDetails(matriculeUser) {
|
|
try {
|
|
const response = await fetch(`/user/read/matricule/${matriculeUser}`);
|
|
const data = await response.json();
|
|
|
|
return data.valid ? data : null;
|
|
} catch (error) {
|
|
displayError(`Erreur lors de la récupération du contrat avec le matricule ${matriculeUser} :`, error);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function populateParcoursTable(parcoursData) {
|
|
//initialise
|
|
const table = $("#historiqueParcours").DataTable({
|
|
searching: true,
|
|
paging: true,
|
|
orderCellsTop: true,
|
|
fixedHeader: true,
|
|
responsive: true,
|
|
pageLength: 5,
|
|
retrieve: true,
|
|
columnDefs: [
|
|
{
|
|
type: "date-uk",
|
|
targets: 10
|
|
},
|
|
{
|
|
type: "date-eu",
|
|
targets: 4
|
|
},
|
|
],
|
|
order: [[0, "desc"]],
|
|
language: {
|
|
search: "Rechercher",
|
|
lengthMenu: "Afficher _MENU_ entrées par page",
|
|
info: "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
|
infoEmpty: "Affichage de 0 à 0 sur 0 entrée",
|
|
infoFiltered: "(filtré de _MAX_ entrées au total)",
|
|
paginate: {
|
|
first: "Début",
|
|
previous: "Précédent",
|
|
next: "Suivant",
|
|
last: "Fin",
|
|
},
|
|
},
|
|
initComplete: function () {
|
|
const table = this.api();
|
|
$("#historiqueParcours thead tr:eq(1) th").each(function (i) {
|
|
$("input", this).on("keyup change", function () {
|
|
if (table.column(i).search() !== this.value) {
|
|
table.column(i).search(this.value).draw();
|
|
}
|
|
});
|
|
});
|
|
table.on("responsive-resize", function (e, datatable, columns) {
|
|
// Loop over each column to see if it's visible
|
|
for (let i = 0; i < columns.length; i++) {
|
|
if (columns[i]) {
|
|
$(table.column(i).header()).show();
|
|
$(table.column(i).footer()).show();
|
|
$($("#historiqueParcours thead tr:eq(1) th")[i]).show();
|
|
} else {
|
|
$(table.column(i).header()).hide();
|
|
$(table.column(i).footer()).hide();
|
|
$($("#historiqueParcours thead tr:eq(1) th")[i]).hide();
|
|
}
|
|
}
|
|
});
|
|
$("#divToggleSearch").on("click", function () {
|
|
$("#historiqueParcours thead tr:eq(1)").toggle();
|
|
});
|
|
|
|
$("#historiqueParcours thead tr:eq(1)").hide();
|
|
},
|
|
});
|
|
|
|
//clear existing data
|
|
table.clear();
|
|
let row = null;
|
|
let tableRow = null;
|
|
|
|
//generate Project
|
|
//loop on parcours
|
|
parcoursData.forEach((parcours) => {
|
|
const contratId = parcours["@expand"]?.contrat?.id;
|
|
const contrat = contratId ? parcours["@expand"].contrat : null;
|
|
const client = contrat ? contrat.client : null;
|
|
const lastUser = parcours["@expand"]?.dernierUtilisateur;
|
|
const region = lastUser["@expand"]?.region;
|
|
const produit = contrat ? (contrat.produit ? contrat.produit : "NC") : "NC"
|
|
|
|
row = [
|
|
parcours.numParcours,
|
|
new Date(parcours.created).toLocaleDateString("fr-FR", {
|
|
day: "numeric",
|
|
month: "numeric",
|
|
year: "numeric"
|
|
}),
|
|
parcours["@expand"].dernierUtilisateur?.matricule || "NC",
|
|
parcours["@expand"].dernierUtilisateur ? `${parcours["@expand"].dernierUtilisateur.prenom} ${parcours["@expand"].dernierUtilisateur.nom}` : "NC",
|
|
region ? region.nom : "NC",
|
|
contrat ? (contrat.numSaisine ? contrat.numSaisine : "NC") : "NC",
|
|
contrat ? (contrat.numContrat ? contrat.numContrat : "NC") : "NC",
|
|
contrat ? (contrat.produit ? contrat.produit : "NC") : "NC",
|
|
contrat ? (contrat.type ? contrat.type : "NC") : "NC",
|
|
contrat ? contrat["@expand"]?.intermediaire?.numPortefeuille || "NC" : "NC",
|
|
contrat ? contrat["@expand"]?.intermediaire?.nom || "NC" : "NC",
|
|
client ? client.numClient || "NC" : "NC",
|
|
client ? client.nom || "NC" : "NC",
|
|
`<button type="button" id="btnReprendre" class="btn" ${(!contrat || (!contrat.numSaisine && !contrat.numContrat)) ? 'disabled' : ''} onclick="window.location.href='/navParcours?numParcours=${parcours.numParcours}&submenu=client'">
|
|
<i class="fas fa-arrow-right"></i></button>`,
|
|
`<button type="button" id="btnGenerate" class="btn" data-produit="${produit}" data-num-parcours="${parcours.numParcours}" ${(!contrat || contrat.produit == "" || (contrat.fac == "" && contrat.rc == "" && contrat.tppc == "") || contrat.client == "" || contrat.intermediaire == "") ? 'disabled' : ''}>
|
|
<i class="fa-solid fa-file-arrow-down"></i></button>`,
|
|
];
|
|
tableRow = table.row.add(row).node();
|
|
|
|
// add class NC to style "Non communiqué"
|
|
$(tableRow)
|
|
.find("td")
|
|
.each(function (colIndex) {
|
|
if ($(this).text() === "NC") {
|
|
$(this).addClass("nc-value");
|
|
}
|
|
});
|
|
});
|
|
|
|
table.draw();
|
|
|
|
// for "afficher" entrées par page
|
|
$("#historiqueParcours_length select").val("10").trigger("change");
|
|
}
|
|
|
|
function downloadExcel(applyFilters) {
|
|
const table = $("#historiqueParcours").DataTable(); // Get the DataTable instance
|
|
const headers = $("#historiqueParcours th").filter(function () {
|
|
return !$(this).hasClass("no-export");}).map(function () {
|
|
return $(this).text().trim();
|
|
}).get();
|
|
|
|
const data = [];
|
|
const rowsData = applyFilters ? table.rows({ filter: "applied" }).data() : table.rows().data();
|
|
rowsData.each(function (row) {
|
|
const filteredRow = $(row).filter(function (index) {
|
|
return !$("#historiqueParcours th").eq(index).hasClass("no-export");
|
|
});
|
|
|
|
data.push(filteredRow.get());
|
|
});
|
|
|
|
const ws = XLSX.utils.aoa_to_sheet([headers, ...data]);
|
|
const wb = XLSX.utils.book_new();
|
|
XLSX.utils.book_append_sheet(wb, ws, "Historique Parcours");
|
|
|
|
const wbout = XLSX.write(wb, { bookType: "xlsx", type: "binary" });
|
|
|
|
function s2ab(s) {
|
|
const buf = new ArrayBuffer(s.length);
|
|
const view = new Uint8Array(buf);
|
|
for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xff;
|
|
|
|
return buf;
|
|
}
|
|
|
|
const now = new Date();
|
|
const pad = (num) => String(num).padStart(2, "0");
|
|
const formattedDate = `${pad(now.getDate())}${pad(now.getMonth() + 1)}${now.getFullYear()}${pad(now.getHours())}${pad(now.getMinutes())}`;
|
|
|
|
const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
|
|
const link = document.createElement("a");
|
|
link.href = URL.createObjectURL(blob);
|
|
link.download = `historique_parcours_${formattedDate}.xlsx`;
|
|
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
function downloadCSV(applyFilters) {
|
|
const table = $("#historiqueParcours").DataTable();
|
|
const headers = $("#historiqueParcours th").filter(function () {
|
|
return !$(this).hasClass("no-export");}).map(function () {
|
|
return $(this).text().trim();
|
|
}).get();
|
|
|
|
let csvContent = "data:text/csv;charset=utf-8," + headers.join(";") + "\n";
|
|
const rowsData = applyFilters ? table.rows({ filter: "applied" }).data() : table.rows().data();
|
|
|
|
rowsData.each(function (row) {
|
|
let filteredRow = row.filter((cell, index) => {
|
|
return !$(`#historiqueParcours th`).eq(index).hasClass("no-export");
|
|
});
|
|
csvContent += filteredRow.join(";") + "\n";
|
|
});
|
|
|
|
const encodedUri = encodeURI(csvContent);
|
|
const link = document.createElement("a");
|
|
link.setAttribute("href", encodedUri);
|
|
link.setAttribute("download", "historique_parcours.csv");
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
}
|
|
|
|
async function generateProject(numParcours, produit) {
|
|
try {
|
|
const response = await fetch(`/generate/${produit}/projet/${numParcours}`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json"},
|
|
});
|
|
|
|
|
|
if (!response.ok) throw new Error("Erreur réseau ou serveur");
|
|
|
|
const disposition = response.headers.get("content-disposition");
|
|
const filename = disposition.split(";")[1].trim().split("=")[1];
|
|
|
|
const blob = await response.blob();
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = document.createElement("a");
|
|
a.href = url;
|
|
a.download = filename;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
window.URL.revokeObjectURL(url);
|
|
a.remove();
|
|
} catch (error) {
|
|
console.error("Erreur lors de la génération du projet:", error);
|
|
}
|
|
}
|
|
|
|
// Fonction pour décoder le JWT
|
|
function parseJwt(token) {
|
|
try {
|
|
const base64Url = token.split(".")[1];
|
|
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
const jsonPayload = decodeURIComponent(atob(base64).split("").map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);}).join(""));
|
|
return JSON.parse(jsonPayload);
|
|
} catch (error) {
|
|
console.error("Erreur lors du décodage du token:", error);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
//generagte Project
|
|
$("#historiqueParcours").on("click", "button#btnGenerate", function() {
|
|
const numParcours = $(this).data("num-parcours");
|
|
const produit = $(this).data("produit");
|
|
|
|
generateProject(numParcours, produit);
|
|
});
|
|
|
|
//export CSV
|
|
$("#exportCSV").on("click", function () {
|
|
downloadCSV(false);
|
|
});
|
|
|
|
//export CSV with filter
|
|
$("#exportCSVFilter").on("click", function () {
|
|
downloadCSV(true);
|
|
});
|
|
|
|
//export to excel
|
|
$("#exportXlxs").on("click", function () {
|
|
downloadExcel(false);
|
|
});
|
|
|
|
// export to excel using Filter
|
|
$("#exportXlxsFilter").on("click", function () {
|
|
downloadExcel(true);
|
|
});
|
|
|
|
|
|
function displayError(message) {
|
|
const errorElement = document.getElementById("error");
|
|
|
|
errorElement.textContent = message;
|
|
errorElement.style.display = "block";
|
|
}
|