Acta
This commit is contained in:
parent
ea2242f79a
commit
503d141996
426
Js/fonctions.js
426
Js/fonctions.js
|
|
@ -61,8 +61,9 @@ $(function() {
|
|||
// On ne lance le timer que si l'utilisateur est connecté (pas sur la vue Connexion)
|
||||
if (vueActuelle !== "Connexion") {
|
||||
setInterval(function() {
|
||||
|
||||
console.log("Actualisation gabarit");
|
||||
raffraichier_gabarit();
|
||||
|
||||
/* On vérifie si l'onglet est actif pour éviter des requêtes inutiles
|
||||
|
||||
if (!document.hidden) {
|
||||
|
|
@ -523,15 +524,8 @@ function afficher_quittances_police_periode() {
|
|||
}
|
||||
|
||||
// 3. Préparation de l'interface (Loader)
|
||||
$conteneur.html(`
|
||||
<div class="text-center my-5 py-5">
|
||||
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
|
||||
<span class="visually-hidden">Chargement...</span>
|
||||
</div>
|
||||
<p class="mt-2 text-primary fw-bold">Chargement des quittances...</p>
|
||||
</div>
|
||||
`);
|
||||
|
||||
showLoader("#div_quittancepolice", { size: 3 });
|
||||
|
||||
// 4. Appel AJAX
|
||||
$.ajax({
|
||||
url: racine + "Ajaxfichepolice/",
|
||||
|
|
@ -617,15 +611,9 @@ function imprimer_quittance_client(idQuittance) {
|
|||
/* ===================================================
|
||||
* 3. Préparation visuelle (Spinner)
|
||||
* =================================================== */
|
||||
divExport.innerHTML = `
|
||||
<div class="text-center my-5 py-5">
|
||||
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
|
||||
<span class="visually-hidden">Chargement...</span>
|
||||
</div>
|
||||
<p class="mt-3 text-muted fw-bold">Génération du document client en cours...</p>
|
||||
</div>
|
||||
`;
|
||||
showLoader("#div_export_quittance", { size: 3 });
|
||||
|
||||
|
||||
/* ===================================================
|
||||
* 4. Initialisation de l'instance Bootstrap
|
||||
* =================================================== */
|
||||
|
|
@ -794,8 +782,8 @@ function adherents_police()
|
|||
|
||||
function afficher_adherents_police()
|
||||
{
|
||||
$("#div_liste_adherent").html('<div style="padding-top:80px;"><img src="Bootstrap/images/loading.gif"/> <span style="font-size:15pt;">' + 'Veuillez patienter... / Please wait...' + '</span></div>');
|
||||
|
||||
showLoader("#div_liste_adherent", { size: 3 });
|
||||
|
||||
$.ajax({
|
||||
url: $("#racineWeb").val()+"Ajaxlisteadherent/",
|
||||
type : 'post',
|
||||
|
|
@ -809,150 +797,274 @@ function afficher_adherents_police()
|
|||
}
|
||||
|
||||
|
||||
// --- I18n dictionary ---
|
||||
const I18N = {
|
||||
fr_FR: {
|
||||
loading: "Affichage en cours...",
|
||||
exportPdf: "Exporter les graphiques en PDF",
|
||||
dashboardTitle: "Graphiques des sinistres",
|
||||
charts: {
|
||||
claimsTitle: "Répartition des sinistres",
|
||||
claimsCount: "Nombre de sinistres",
|
||||
monthlyTitle: "Évolution mensuelle",
|
||||
monthlyCumulative: "Sinistres cumulés",
|
||||
monthlySingle: "Sinistres uniques",
|
||||
lossRatioTitle: "Ratio de sinistralité",
|
||||
lossRatioLabel: "Ratio de sinistralité"
|
||||
},
|
||||
months: ["Jan", "Fév", "Mar", "Avr", "Mai", "Juin", "Juil", "Août", "Sep", "Oct", "Nov", "Déc"],
|
||||
errors: {
|
||||
ajax: "Impossible de charger les graphiques.",
|
||||
pdfLib: "Erreur : jsPDF n'est pas chargé."
|
||||
}
|
||||
},
|
||||
en_US: {
|
||||
loading: "Loading in progress...",
|
||||
exportPdf: "Export charts to PDF",
|
||||
dashboardTitle: "Claims Charts",
|
||||
charts: {
|
||||
claimsTitle: "Claims distribution",
|
||||
claimsCount: "Number of claims",
|
||||
monthlyTitle: "Monthly trend",
|
||||
monthlyCumulative: "Claims cumulative",
|
||||
monthlySingle: "Claims single",
|
||||
lossRatioTitle: "Loss ratio",
|
||||
lossRatioLabel: "Loss ratio"
|
||||
},
|
||||
months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
errors: {
|
||||
ajax: "Unable to load charts.",
|
||||
pdfLib: "Error: jsPDF is not loaded."
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// --- Helpers ---
|
||||
function getLang() {
|
||||
const codeLangue = $("#codeLangue").val() || "fr_FR";
|
||||
return I18N[codeLangue] ? codeLangue : "fr_FR";
|
||||
}
|
||||
|
||||
function t(path) {
|
||||
const lang = getLang();
|
||||
return path.split(".").reduce((acc, key) => (acc && acc[key] != null ? acc[key] : null), I18N[lang]);
|
||||
}
|
||||
|
||||
// Optional: normalize backend month keys to localized labels
|
||||
function localizeMonths(months) {
|
||||
const map = {
|
||||
Jan: "Jan", Feb: "Feb", Mar: "Mar", Apr: "Apr", May: "May", Jun: "Jun",
|
||||
Jul: "Jul", Aug: "Aug", Sep: "Sep", Oct: "Oct", Nov: "Nov", Dec: "Dec"
|
||||
};
|
||||
const langMonths = t("months");
|
||||
// If backend already provides localized months, keep them; else map to language months by index
|
||||
if (!Array.isArray(months) || months.length !== 12) return months;
|
||||
const canonical = months.map(m => map[m] || m);
|
||||
// Use the language month names but preserve array length and order
|
||||
return langMonths && langMonths.length === 12 ? langMonths : canonical;
|
||||
}
|
||||
|
||||
function showLoader(selector, options = {}) {
|
||||
const { message = null, size = 3 } = options;
|
||||
const text = message || t("loading");
|
||||
|
||||
const loaderHtml = `
|
||||
<div class="text-center my-5 py-5 js-generic-loader">
|
||||
<div class="spinner-border text-primary" role="status" style="width: ${size}rem; height: ${size}rem;">
|
||||
<span class="visually-hidden">${text}</span>
|
||||
</div>
|
||||
<p class="mt-3 text-muted fw-bold">${text}</p>
|
||||
</div>
|
||||
`;
|
||||
$(selector).html(loaderHtml);
|
||||
}
|
||||
|
||||
function hideLoader(selector, contentHtml = "") {
|
||||
$(selector).html(contentHtml);
|
||||
}
|
||||
|
||||
function graphique_sinistre() {
|
||||
// Spinner pendant le chargement
|
||||
$("#div_graphique").html(`
|
||||
<div class="text-center my-5 py-5">
|
||||
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
|
||||
<span class="visually-hidden">Chargement...</span>
|
||||
</div>
|
||||
<p class="mt-3 text-muted fw-bold">Affichage des graphiques en cours...</p>
|
||||
showLoader("#div_graphique", { size: 3 });
|
||||
|
||||
$.ajax({
|
||||
url: $("#racineWeb").val() + "Ajaxgraphiquesinistres/api/",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
const exportLabel = t("exportPdf");
|
||||
|
||||
const html = `
|
||||
<div class="text-end my-3">
|
||||
<button id="exportPdfBtn" class="btn btn-danger">
|
||||
<i class="fas fa-file-pdf"></i> ${exportLabel}
|
||||
</button>
|
||||
</div>
|
||||
`);
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-primary">${t("charts.claimsTitle")}</h5>
|
||||
<canvas id="claimsChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-success">${t("charts.monthlyTitle")}</h5>
|
||||
<canvas id="claimsMonthChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-danger">${t("charts.lossRatioTitle")}</h5>
|
||||
<canvas id="lossRatioChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
hideLoader("#div_graphique", html);
|
||||
|
||||
$.ajax({
|
||||
url: $("#racineWeb").val() + "Ajaxgraphiquesinistres/api/",
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
console.log("Réponse JSON reçue:", data);
|
||||
// Render charts with localized labels
|
||||
renderClaimsChart(data.claims);
|
||||
renderClaimsMonthChart(data.claimsMonth);
|
||||
renderLossRatioChart(data.lossRatio);
|
||||
|
||||
// Layout HTML
|
||||
$("#div_graphique").html(`
|
||||
<div class="text-end my-3">
|
||||
<button id="exportPdfBtn" class="btn btn-danger">
|
||||
<i class="fas fa-file-pdf"></i> Exporter le tableau de bord en PDF
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-primary">Répartition des sinistres</h5>
|
||||
<canvas id="claimsChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-success">Évolution mensuelle</h5>
|
||||
<canvas id="claimsMonthChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-danger">Ratio de sinistralité</h5>
|
||||
<canvas id="lossRatioChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
setupExportPdf();
|
||||
},
|
||||
error: function (err) {
|
||||
console.error("Erreur AJAX:", err);
|
||||
hideLoader("#div_graphique", `
|
||||
<div class="alert alert-danger">${t("errors.ajax")}</div>
|
||||
`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Graphiques Chart.js ---
|
||||
// --- Charts ---
|
||||
|
||||
// 1. Répartition
|
||||
new Chart(document.getElementById('claimsChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: data.claims.claimsLabels,
|
||||
datasets: [{
|
||||
label: 'Nombre de sinistres',
|
||||
data: data.claims.claimsValues,
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.6)'
|
||||
}]
|
||||
}
|
||||
});
|
||||
function renderClaimsChart(claims) {
|
||||
new Chart(document.getElementById("claimsChart"), {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: claims.claimsLabels,
|
||||
datasets: [{
|
||||
label: t("charts.claimsCount"),
|
||||
data: claims.claimsValues,
|
||||
backgroundColor: "rgba(54, 162, 235, 0.6)"
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: { display: true }
|
||||
},
|
||||
scales: {
|
||||
x: { title: { display: false } },
|
||||
y: { title: { display: false }, beginAtZero: true }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Évolution mensuelle
|
||||
new Chart(document.getElementById('claimsMonthChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.claimsMonth.months,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Sinistres mensuels',
|
||||
data: data.claimsMonth.monthlyClaims,
|
||||
borderColor: 'rgba(255, 99, 132, 0.8)',
|
||||
fill: false
|
||||
},
|
||||
{
|
||||
label: 'Sinistres uniques',
|
||||
data: data.claimsMonth.singleClaims,
|
||||
borderColor: 'rgba(75, 192, 192, 0.8)',
|
||||
fill: false
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
function renderClaimsMonthChart(claimsMonth) {
|
||||
const labels = localizeMonths(claimsMonth.months);
|
||||
|
||||
// 3. Ratio de sinistralité
|
||||
new Chart(document.getElementById('lossRatioChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.lossRatio.lossRatioLabels,
|
||||
datasets: [{
|
||||
label: 'Ratio de sinistralité',
|
||||
data: data.lossRatio.lossRatioValues,
|
||||
borderColor: 'rgba(255, 206, 86, 0.8)',
|
||||
fill: false
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
// --- Export PDF ---
|
||||
$("#exportPdfBtn").on("click", function() {
|
||||
if (!window.jspdf) {
|
||||
alert("Erreur : jsPDF n'est pas chargé.");
|
||||
return;
|
||||
}
|
||||
|
||||
const { jsPDF } = window.jspdf;
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
|
||||
pdf.setFontSize(18);
|
||||
pdf.text("Tableau de bord - Synthèse", 10, 20);
|
||||
|
||||
// Ajout des graphiques
|
||||
addChartToPdf(pdf, 'claimsChart', 'Répartition des sinistres', 40);
|
||||
addChartToPdf(pdf, 'claimsMonthChart', 'Évolution mensuelle', 120);
|
||||
|
||||
pdf.addPage();
|
||||
addChartToPdf(pdf, 'lossRatioChart', 'Ratio de sinistralité', 40);
|
||||
|
||||
pdf.save('Tableau_de_bord.pdf');
|
||||
});
|
||||
|
||||
function addChartToPdf(pdf, canvasId, title, startY) {
|
||||
const canvas = document.getElementById(canvasId);
|
||||
if (canvas) {
|
||||
const imgData = canvas.toDataURL('image/png', 1.0);
|
||||
pdf.setFontSize(14);
|
||||
pdf.text(title, 10, startY);
|
||||
pdf.addImage(imgData, 'PNG', 10, startY + 5, 180, 60);
|
||||
}
|
||||
}
|
||||
new Chart(document.getElementById("claimsMonthChart"), {
|
||||
type: "line",
|
||||
data: {
|
||||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: t("charts.monthlyCumulative"),
|
||||
data: claimsMonth.monthlyClaims,
|
||||
borderColor: "rgba(255, 99, 132, 0.8)",
|
||||
backgroundColor: "rgba(255, 99, 132, 0.2)",
|
||||
tension: 0.25,
|
||||
fill: false
|
||||
},
|
||||
error: function(err) {
|
||||
console.error("Erreur AJAX:", err);
|
||||
$("#div_graphique").html(`
|
||||
<div class="alert alert-danger">
|
||||
Impossible de charger les graphiques.
|
||||
</div>
|
||||
`);
|
||||
{
|
||||
label: t("charts.monthlySingle"),
|
||||
data: claimsMonth.singleClaims,
|
||||
borderColor: "rgba(75, 192, 192, 0.8)",
|
||||
backgroundColor: "rgba(75, 192, 192, 0.2)",
|
||||
tension: 0.25,
|
||||
fill: false
|
||||
}
|
||||
});
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: { display: true }
|
||||
},
|
||||
scales: {
|
||||
x: { title: { display: false } },
|
||||
y: { title: { display: false }, beginAtZero: true }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderLossRatioChart(lossRatio) {
|
||||
const labels = localizeMonths(lossRatio.lossRatioLabels);
|
||||
|
||||
new Chart(document.getElementById("lossRatioChart"), {
|
||||
type: "line",
|
||||
data: {
|
||||
labels,
|
||||
datasets: [{
|
||||
label: t("charts.lossRatioLabel"),
|
||||
data: lossRatio.lossRatioValues,
|
||||
borderColor: "rgba(255, 206, 86, 0.8)",
|
||||
backgroundColor: "rgba(255, 206, 86, 0.2)",
|
||||
tension: 0.25,
|
||||
fill: false
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: { display: true }
|
||||
},
|
||||
scales: {
|
||||
x: { title: { display: false } },
|
||||
y: { title: { display: false }, beginAtZero: true }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Export PDF ---
|
||||
|
||||
function setupExportPdf() {
|
||||
$("#exportPdfBtn").on("click", function () {
|
||||
if (!window.jspdf) {
|
||||
alert(t("errors.pdfLib"));
|
||||
return;
|
||||
}
|
||||
const { jsPDF } = window.jspdf;
|
||||
const pdf = new jsPDF("p", "mm", "a4");
|
||||
|
||||
pdf.setFontSize(18);
|
||||
pdf.text(t("dashboardTitle"), 10, 20);
|
||||
|
||||
addChartToPdf(pdf, "claimsChart", t("charts.claimsTitle"), 40);
|
||||
addChartToPdf(pdf, "claimsMonthChart", t("charts.monthlyTitle"), 120);
|
||||
|
||||
pdf.addPage();
|
||||
addChartToPdf(pdf, "lossRatioChart", t("charts.lossRatioTitle"), 40);
|
||||
|
||||
pdf.save("Tableau_de_bord.pdf"); // you can also localize the filename if needed
|
||||
});
|
||||
}
|
||||
|
||||
function addChartToPdf(pdf, canvasId, title, startY) {
|
||||
const canvas = document.getElementById(canvasId);
|
||||
if (canvas) {
|
||||
const imgData = canvas.toDataURL("image/png", 1.0);
|
||||
pdf.setFontSize(14);
|
||||
pdf.text(title, 10, startY);
|
||||
pdf.addImage(imgData, "PNG", 10, startY + 5, 180, 60);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ $activeChildId = $menuData['child'];
|
|||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<!-- Application Scripts -->
|
||||
<script src="/Js/fonctions.js?ver=2025.12.31.03"></script>
|
||||
<script src="/Js/fonctions.js?ver=2025.12.31.04"></script>
|
||||
|
||||
<?php if (est_anglophone()): ?>
|
||||
<script src="/Js/datepicker-eng.js"></script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user