554 lines
19 KiB
JavaScript
Executable File
554 lines
19 KiB
JavaScript
Executable File
/**
|
|
* INITIALISATION GÉNÉRALE
|
|
*/
|
|
/**
|
|
* Gère la pré-connexion via cookie (chargement du formulaire et focus intelligent).
|
|
* Récupère le login mémorisé et place le curseur dans le champ approprié.
|
|
*/
|
|
|
|
function connexion_cookie() {
|
|
const racine = $("#racineWeb").val() || "";
|
|
const msgErreur = $("#msgErreur").val();
|
|
|
|
$.ajax({
|
|
url: racine + "Ajaxconnexioncookie/",
|
|
type: 'POST',
|
|
cache: false,
|
|
// Utilisation d'un objet pour un encodage automatique sécurisé
|
|
data: { msgErreur: msgErreur },
|
|
success: function(data) {
|
|
// Injection du formulaire de connexion
|
|
$("#div_ajaxconnexion").html(data);
|
|
|
|
// Initialisation des composants stylisés
|
|
if ($.isFunction($.fn.selectpicker)) {
|
|
$(".selectpicker").selectpicker('refresh');
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error("Erreur lors du chargement des cookies de connexion:", error);
|
|
},
|
|
complete: function() {
|
|
// Gestion intelligente du focus
|
|
const $loginField = $("#login");
|
|
const $mdpField = $("#mdp");
|
|
const $codeSocieteField = $("#codeSociete");
|
|
|
|
// Si un login est déjà présent (issu du cookie)
|
|
if ($loginField.val() && $loginField.val().trim() !== "") {
|
|
// On place le curseur sur le mot de passe
|
|
$mdpField.focus();
|
|
} else {
|
|
// Sinon, on commence par le début (Code Société ou Login)
|
|
if ($codeSocieteField.length > 0) {
|
|
$codeSocieteField.focus();
|
|
} else {
|
|
$loginField.focus();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
$(function() {
|
|
// 1. Initialisation des composants au chargement de la page
|
|
appliquerDataTable('.tabliste');
|
|
|
|
|
|
// 2. Lancement du cycle de rafraîchissement automatique
|
|
const vueActuelle = $("#vue").val();
|
|
|
|
// On ne lance le timer que si l'utilisateur est connecté (pas sur la vue Connexion)
|
|
if (vueActuelle !== "Connexion") {
|
|
setInterval(function() {
|
|
// On vérifie si l'onglet est actif pour éviter des requêtes inutiles
|
|
if (!document.hidden) {
|
|
raffraichier_gabarit();
|
|
}
|
|
}, 60000); // 60 secondes
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Fonction principale de rafraîchissement du gabarit (UI et Session)
|
|
* Gère la mise à jour des données et la redirection forcée en cas de déconnexion.
|
|
*/
|
|
function raffraichier_gabarit() {
|
|
const racine = $("#racineWeb").val() || "/";
|
|
const vueActuelle = $("#vue").val();
|
|
const codeLangue = $("#codeLangue").val() || "fr_FR";
|
|
|
|
$.ajax({
|
|
url: racine + "Ajaxgabarit/",
|
|
type: 'GET',
|
|
cache: false,
|
|
success: function(data) {
|
|
// 1. On transforme la chaîne 'data' en objet jQuery pour manipulation
|
|
const $dataFrag = $(data);
|
|
|
|
// 2. Injection dans le DOM
|
|
$("#div_ajaxgabarit").html($dataFrag);
|
|
|
|
// 3. RECUPERATION SECURISEE DU CODE SOCIETE
|
|
// On essaie d'abord dans le DOM, puis dans le fragment reçu si le DOM est lent
|
|
let codeSociete = $("#div_ajaxgabarit").find("#codeSociete").val()
|
|
|| $dataFrag.filter("#codeSociete").val()
|
|
|| $("#codeSociete").val();
|
|
|
|
// Debug en console pour vérifier la capture
|
|
console.log("Check Session - codeSociete trouvé :", codeSociete);
|
|
|
|
// 4. VERIFICATION DE LA SESSION
|
|
if ((!codeSociete || codeSociete.trim() === "") && vueActuelle !== "Connexion") {
|
|
|
|
const msg = "Votre session a expiré. Veuillez vous reconnecter.";
|
|
const msgEng = "Your session has expired. Please log in again.";
|
|
|
|
// On bloque l'écran avec confirm_ebene
|
|
confirm_ebene(msg, msgEng).then(() => {
|
|
window.location.assign(racine + "Connexion/deconnecter/");
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
// Si on arrive ici, la session est valide
|
|
},
|
|
error: function(xhr) {
|
|
// Si le serveur renvoie une erreur HTTP (401, 403, 500)
|
|
if (xhr.status === 401 && vueActuelle !== "Connexion") {
|
|
window.location.assign(racine + "Connexion/deconnecter/");
|
|
}
|
|
},
|
|
complete: function() {
|
|
// Ré-initialisation des composants sur le nouveau HTML
|
|
if ($.isFunction($.fn.datepicker)) {
|
|
$(".datepicker").datepicker();
|
|
}
|
|
|
|
/*
|
|
if (typeof raffraichier_messagerie === "function") {
|
|
raffraichier_messagerie();
|
|
}
|
|
*/
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* GESTION DU MENU BURGER
|
|
* Gère l'affichage mobile et la fermeture lors d'un clic extérieur.
|
|
*/
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const burgerToggle = document.getElementById('burgerMenuToggle');
|
|
const burgerDropdown = document.getElementById('burgerDropdown');
|
|
|
|
if (burgerToggle && burgerDropdown) {
|
|
// Alterne la classe 'show' au clic sur le bouton
|
|
burgerToggle.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
burgerDropdown.classList.toggle('show');
|
|
});
|
|
|
|
// Ferme le menu si on clique n'importe où ailleurs sur le document
|
|
document.addEventListener('click', (e) => {
|
|
if (!e.target.closest('.burger-menu-container')) {
|
|
burgerDropdown.classList.remove('show');
|
|
}
|
|
});
|
|
|
|
// Empêche la fermeture si on clique à l'intérieur du menu lui-même
|
|
burgerDropdown.addEventListener('click', (e) => e.stopPropagation());
|
|
}
|
|
});
|
|
|
|
/**
|
|
* FORMATAGE DES MESSAGES (Responsive)
|
|
* Ajoute des balises <br> pour forcer le retour à la ligne selon la taille d'écran.
|
|
*/
|
|
function formatMessageForSwal(message) {
|
|
if (!message) return '';
|
|
|
|
const screenWidth = window.innerWidth;
|
|
// Détermine la limite de caractères avant le saut de ligne
|
|
const maxLineLength = screenWidth < 576 ? 40 : (screenWidth < 768 ? 60 : 80);
|
|
|
|
if (message.length <= maxLineLength && !message.includes('\n')) return message;
|
|
|
|
const words = message.split(' ');
|
|
let lines = [];
|
|
let currentLine = '';
|
|
|
|
words.forEach(word => {
|
|
if ((currentLine + ' ' + word).length > maxLineLength && currentLine !== '') {
|
|
lines.push(currentLine);
|
|
currentLine = word;
|
|
} else {
|
|
currentLine = currentLine ? currentLine + ' ' + word : word;
|
|
}
|
|
});
|
|
|
|
if (currentLine) lines.push(currentLine);
|
|
return lines.join('<br>');
|
|
}
|
|
|
|
/**
|
|
* AJUSTEMENT DYNAMIQUE SWEETALERT
|
|
* Redimensionne la popup et gère le scroll interne pour les longs textes.
|
|
*/
|
|
function adjustSwalContent() {
|
|
const popup = Swal.getPopup();
|
|
const title = Swal.getTitle();
|
|
const htmlContainer = Swal.getHtmlContainer();
|
|
|
|
if (popup && title) {
|
|
const screenWidth = window.innerWidth;
|
|
// Application de styles responsives directs
|
|
if (screenWidth < 576) {
|
|
Object.assign(popup.style, { maxWidth: '95vw', width: '95vw', margin: '10px' });
|
|
} else {
|
|
Object.assign(popup.style, { maxWidth: screenWidth < 768 ? '85vw' : '500px', width: '100%' });
|
|
}
|
|
|
|
// Gestion du scroll si le titre est trop grand
|
|
const maxTitleHeight = Math.min(window.innerHeight * 0.6, 400);
|
|
if (title.scrollHeight > maxTitleHeight) {
|
|
Object.assign(title.style, { overflowY: 'auto', maxHeight: maxTitleHeight + 'px', paddingRight: '10px' });
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* WRAPPER GÉNÉRIQUE SWEETALERT
|
|
* Centralise les paramètres communs pour alert_ebene, confirm_ebene, etc.
|
|
*/
|
|
function baseSwal(options) {
|
|
return Swal.fire({
|
|
...options,
|
|
customClass: {
|
|
popup: 'responsive-swal-popup',
|
|
title: 'responsive-swal-title',
|
|
htmlContainer: 'responsive-swal-html'
|
|
},
|
|
didOpen: adjustSwalContent,
|
|
willOpen: () => { document.body.style.overflow = 'hidden'; },
|
|
willClose: () => { document.body.style.overflow = 'auto'; }
|
|
});
|
|
}
|
|
|
|
/**
|
|
* ALERTE SIMPLE
|
|
* Affiche une information bilingue.
|
|
*/
|
|
function alert_ebene(p_msg, p_msg_eng) {
|
|
const codeLangue = $("#codeLangue").val();
|
|
const message = (codeLangue === "en_US") ? p_msg_eng : p_msg;
|
|
|
|
baseSwal({
|
|
title: formatMessageForSwal(message),
|
|
icon: 'info',
|
|
confirmButtonText: codeLangue === "en_US" ? 'OK' : 'D\'accord'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* CONFIRMATION
|
|
* Affiche une boîte de dialogue Oui/Non et retourne une promesse.
|
|
*/
|
|
function confirm_ebene(p_msg, p_msg_eng) {
|
|
const codeLangue = $("#codeLangue").val();
|
|
const message = (codeLangue === "en_US") ? p_msg_eng : p_msg;
|
|
|
|
return baseSwal({
|
|
title: formatMessageForSwal(message),
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonText: codeLangue === "en_US" ? 'Yes' : 'Oui',
|
|
cancelButtonText: codeLangue === "en_US" ? 'No' : 'Non'
|
|
}).then(result => result.isConfirmed);
|
|
}
|
|
|
|
/**
|
|
* SAISIE TEXTE (PROMPT)
|
|
* Ouvre une modale avec champ de saisie et exécute un callback avec la valeur.
|
|
*/
|
|
function prompt_ebene(p_msg, p_msg_eng, p_retour, callback) {
|
|
const codeLangue = $("#codeLangue").val();
|
|
const message = (codeLangue === "en_US") ? p_msg_eng : p_msg;
|
|
|
|
baseSwal({
|
|
title: formatMessageForSwal(message),
|
|
input: 'text',
|
|
inputValue: p_retour,
|
|
showCancelButton: true,
|
|
confirmButtonText: 'OK',
|
|
cancelButtonText: codeLangue === "en_US" ? 'Cancel' : 'Annuler'
|
|
}).then(result => {
|
|
callback(result.isConfirmed ? result.value : null);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* CHANGEMENT DE MOT DE PASSE
|
|
* Demande confirmation avant redirection.
|
|
*/
|
|
function change_password() {
|
|
const v_msg = "Attention, vous serez déconnecté par la suite! Voulez-vous changer votre mot de passe?";
|
|
const v_msgEng = "Attention, you will be logged out afterwards! Do you want to change your password?";
|
|
|
|
confirm_ebene(v_msg, v_msgEng).then(isConfirmed => {
|
|
if (isConfirmed) {
|
|
window.location.assign($("#racineWeb").val() + "Changermotpass/");
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* AFFICHAGE BÉNÉFICIAIRE
|
|
* Prépare le contexte serveur avant de charger la fiche bénéficiaire.
|
|
*/
|
|
function ajax_context_beneficiaire_afficher(idBeneficiaire, okId) {
|
|
// Affiche un loader pendant le chargement
|
|
$("#contenu").html('<div class="spinner-responsive"><span><i class="fa fa-spinner fa-spin"></i></span></div>');
|
|
|
|
$.ajax({
|
|
url: $("#racineWeb").val() + "Ajaxcontextbeneficiaire/",
|
|
type: 'post',
|
|
data: { idBeneficiaire, okId },
|
|
complete: () => {
|
|
window.location.assign($("#racineWeb").val() + "Fichebeneficiaire/" + idBeneficiaire);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* GESTION DE LA LANGUE À LA CONNEXION
|
|
* Met à jour le bloc de connexion via AJAX lors du changement de langue.
|
|
*/
|
|
function changer_langue_connexion() {
|
|
const codeLangue = $("#langue").val();
|
|
$.ajax({
|
|
url: $("#racineWeb").val() + "Ajaxconnexioncookie/changerlangue/",
|
|
type: 'post',
|
|
data: { codeLangue },
|
|
success: (data) => $("#div_detail_connexion").html(data),
|
|
complete: () => $(".selectpicker").selectpicker('refresh')
|
|
});
|
|
}
|
|
|
|
/**
|
|
* CONFIGURATION DATATABLES
|
|
* Initialise un tableau DataTable avec options génériques.
|
|
*
|
|
* @param {string|jQuery} selector - Sélecteur du tableau (ex: '.tabliste' ou '#myTable')
|
|
* @param {object} options - Options personnalisées (langue, boutons, ordre, etc.)
|
|
*/
|
|
function appliquerDataTable(selector = '.tabliste', options = {}) {
|
|
const codeLangue = $("#codeLangue").val() || 'fr_FR';
|
|
|
|
const translations = {
|
|
fr_FR: {
|
|
lengthMenu: "Affiche _MENU_ par page",
|
|
zeroRecords: "Aucune donnée trouvée",
|
|
info: "_PAGE_ sur _PAGES_",
|
|
search: "Recherche:",
|
|
paginate: { next: "►", previous: "◄" }
|
|
},
|
|
en_US: {
|
|
lengthMenu: "Display _MENU_ records",
|
|
zeroRecords: "Nothing found",
|
|
info: "Showing page _PAGE_ of _PAGES_",
|
|
search: "Search:",
|
|
paginate: { next: "►", previous: "◄" }
|
|
}
|
|
};
|
|
|
|
$(selector).each(function() {
|
|
const $table = $(this);
|
|
|
|
// Colonnes marquées comme 'data-hidden'
|
|
const hiddenTargets = [];
|
|
$table.find('thead th').each((idx, th) => {
|
|
if ($(th).data('hidden')) hiddenTargets.push(idx);
|
|
});
|
|
|
|
const instance = $table.DataTable($.extend(true, {
|
|
destroy: true,
|
|
responsive: true,
|
|
order: [[0, "desc"]],
|
|
language: translations[codeLangue] || translations.fr_FR,
|
|
columnDefs: [{ targets: hiddenTargets, visible: false }],
|
|
dom: 'Bfrtip',
|
|
buttons: ['copy', 'csv', 'excel', 'pdf', 'print']
|
|
}, options));
|
|
|
|
// Ajustement après rendu
|
|
$table.on('init.dt', function () {
|
|
if (instance && instance.responsive) {
|
|
instance.columns.adjust();
|
|
instance.responsive.recalc();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* MESSAGERIE ET NOTIFICATIONS
|
|
* Récupère le nombre de messages et déconnecte si session expirée.
|
|
*/
|
|
function raffraichier_messagerie() {
|
|
if (!navigator.onLine) {
|
|
$("#test_connexion").css('background-color', 'red');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: $("#racineWeb").val() + "Ajaxmessagerie/",
|
|
success: (data) => {
|
|
$("#nbMessagesNonLus").html(data);
|
|
$("#span_notification").text($("#msgNonLus").val());
|
|
|
|
// Sécurité : redirection forcée si le serveur indique une déconnexion nécessaire
|
|
if ($("#deconnexion").val() === '1') {
|
|
window.location.assign($("#racineWeb").val() + "Connexion/deconnecter/");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Réajuster les popups SweetAlert lors du redimensionnement de la fenêtre
|
|
window.addEventListener('resize', () => {
|
|
if (Swal.isVisible()) setTimeout(adjustSwalContent, 100);
|
|
});
|
|
|
|
/**
|
|
* Sélectionne une police d'assurance et met à jour les champs cachés globaux.
|
|
* Cette fonction est généralement appelée lors d'un clic sur une ligne de tableau
|
|
* ou un bouton de sélection dans une liste de polices.
|
|
*/
|
|
function selectionner_police(id, no) {
|
|
debugger;
|
|
// Mise à jour de l'ID de la police dans le champ caché prévu pour le traitement serveur
|
|
$("#idPolice_C").val(id);
|
|
|
|
// Mise à jour du numéro de police pour l'affichage ou les recherches secondaires
|
|
$("#numeroPolice_C").val(no);
|
|
|
|
// Note : On pourrait ajouter ici un retour visuel (ex: surbrillance de la ligne sélectionnée)
|
|
console.log(`Police sélectionnée : ID ${id} / N° ${no}`);
|
|
|
|
afficher_police_id(id);
|
|
}
|
|
|
|
/**
|
|
* Vérifie la sélection d'une police et lance la mise à jour du contexte.
|
|
* Utilisée généralement avant d'afficher le détail d'un contrat.
|
|
*/
|
|
function afficher_police_id(idPolice) {
|
|
debugger;
|
|
|
|
// Récupération de l'ID depuis le champ caché
|
|
//const idPolice = $("#idPolice_C").val();
|
|
|
|
// Vérifie si l'ID est présent et non composé uniquement d'espaces
|
|
if (idPolice > "0") {
|
|
ajax_context_police_afficher(idPolice);
|
|
} else {
|
|
// Optionnel : Alerte si aucune police n'est sélectionnée
|
|
console.warn("Aucun identifiant de police trouvé pour l'affichage.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Définit le contexte de la police côté serveur via AJAX avant redirection.
|
|
* @param {string|number} idPolice - L'identifiant de la police à mettre en session.
|
|
*/
|
|
function ajax_context_police_afficher(idPolice) {
|
|
debugger;
|
|
|
|
const racine = $("#racineWeb").val() || "/";
|
|
|
|
$.ajax({
|
|
url: racine + "Ajaxcontextpolice/",
|
|
type: 'POST',
|
|
// On envoie un objet pour que jQuery gère proprement l'encodage
|
|
data: { idPolice: idPolice },
|
|
beforeSend: function() {
|
|
// Optionnel : On pourrait afficher un petit loader ici
|
|
},
|
|
success: function() {
|
|
// Le contexte est mis à jour avec succès
|
|
console.log("Contexte police mis à jour.");
|
|
},
|
|
error: function(xhr, status, error) {
|
|
// Alerte l'utilisateur en cas de problème technique
|
|
const msg = "Erreur lors de la préparation du dossier police.";
|
|
const msgEng = "Error while preparing the policy file.";
|
|
|
|
if (typeof alert_ebene === "function") {
|
|
alert_ebene(msg, msgEng);
|
|
} else {
|
|
alert(msg);
|
|
}
|
|
},
|
|
complete: function() {
|
|
// Redirection vers la fiche de la police après le traitement AJAX
|
|
window.location.assign(racine + "Fichepolice/");
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Charge la liste des quittances pour une police sur une période donnée.
|
|
*/
|
|
function afficher_quittances_police_periode() {
|
|
debugger;
|
|
|
|
// 1. Récupération des paramètres
|
|
const racine = $("#racineWeb").val() || "/";
|
|
const idPolice = $("#idPolice_C").val();
|
|
const debut = $("#debut").val();
|
|
const fin = $("#fin").val();
|
|
const $conteneur = $("#div_quittancepolice");
|
|
|
|
// 2. Vérification de l'ID Police (Correction du bug numeroPolice)
|
|
if (!idPolice || idPolice.trim() === "") {
|
|
console.warn("Affichage quittances impossible : ID Police manquant.");
|
|
return;
|
|
}
|
|
|
|
// 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>
|
|
`);
|
|
|
|
// 4. Appel AJAX
|
|
$.ajax({
|
|
url: racine + "Ajaxfichepolice/",
|
|
type: 'POST',
|
|
data: {
|
|
idPolice: idPolice,
|
|
debut: debut,
|
|
fin: fin
|
|
},
|
|
success: function(data) {
|
|
// Injection du résultat
|
|
$conteneur.hide().html(data).fadeIn();
|
|
},
|
|
error: function(xhr, status, error) {
|
|
$conteneur.html(`
|
|
<div class="alert alert-danger shadow-sm m-3">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
|
${_("Erreur lors du chargement des quittances.")}
|
|
</div>
|
|
`);
|
|
console.error("Erreur AJAX Quittances:", status, error);
|
|
}
|
|
});
|
|
} |