personnal/ecole/public/js/rc/rc-orchestrator.js

378 lines
16 KiB
JavaScript

/**
* Orchestrateur de synchro RC entre les écrans Tarif et Projet.
*/
(function(window) {
'use strict';
// Attendre que les dépendances soient chargées
if (!window.RCSync || !window.RCDataManager) {
console.error('Dependances RC Sync manquantes');
return;
}
const { isFieldImpactingTarif, showReturnToTarifModal } = window.RCSync;
const { collectAllTarifData, prefillTarifFromProjet } = window.RCDataManager;
// ═══════════════════════════════════════════════════════════════════════
// CONFIGURATION
// ═══════════════════════════════════════════════════════════════════════
const SESSION_STORAGE_KEYS = {
TARIF_DATA: 'rc_tarif_validated_data',
PROJET_DATA: 'rc_projet_data',
TARIF_ORIGINAL: 'rc_tarif_original_for_comparison'
};
// ═══════════════════════════════════════════════════════════════════════
// DÉTECTION DE LA PAGE ACTIVE
// ═══════════════════════════════════════════════════════════════════════
/**
* Détecte si on est sur la page tarif ou projet.
*/
function detectActivePage() {
const params = new URLSearchParams(window.location.search);
const submenu = params.get('submenu');
if (submenu === 'tarif' || submenu === 'tarifrc') {
return 'tarif';
} else if (submenu === 'projet' || submenu === 'projetrc') {
return 'projet';
}
return null;
}
/**
* Détecte le produit courant à partir de la session.
*
* @returns {string|null} Code produit en minuscule
*/
function detectCurrentProduct() {
try {
const contrat = JSON.parse(sessionStorage.getItem('contrat') || 'null');
const fromContrat = contrat?.produit;
if (fromContrat) return String(fromContrat).toLowerCase();
const parcours = JSON.parse(sessionStorage.getItem('parcours') || 'null');
const fromParcours = parcours?.["@expand"]?.contrat?.produit;
return fromParcours ? String(fromParcours).toLowerCase() : null;
} catch (error) {
console.warn('Impossible de lire le produit courant:', error);
return null;
}
}
// ═══════════════════════════════════════════════════════════════════════
// GESTION SESSIONSTORAGE
// ═══════════════════════════════════════════════════════════════════════
/**
* Sauvegarde le snapshot du tarif validé en sessionStorage.
*/
function saveTarifDataToSession(tarifData) {
try {
sessionStorage.setItem(SESSION_STORAGE_KEYS.TARIF_DATA, JSON.stringify(tarifData));
sessionStorage.setItem(SESSION_STORAGE_KEYS.TARIF_ORIGINAL, JSON.stringify(tarifData));
console.log('Donnees tarif sauvegardees en session');
} catch (error) {
console.error('Erreur sauvegarde session:', error);
}
}
/**
* Lit les données tarif sauvegardées en sessionStorage.
*/
function getTarifDataFromSession() {
try {
const data = sessionStorage.getItem(SESSION_STORAGE_KEYS.TARIF_DATA);
return data ? JSON.parse(data) : null;
} catch (error) {
console.error('Erreur lecture session:', error);
return null;
}
}
// ═══════════════════════════════════════════════════════════════════════
// HOOK: APRÈS VALIDATION TARIF
// ═══════════════════════════════════════════════════════════════════════
/**
* Hook appelé après validation tarif pour garder l'état en session.
*/
function onTarifValidated() {
console.log('Hook tarif valide: collecte des donnees');
try {
// Collecter toutes les données du tarif
const tarifData = collectAllTarifData();
// Sauvegarder en session pour le pré-remplissage projet
saveTarifDataToSession(tarifData);
console.log('Donnees tarif pretes pour le projet');
} catch (error) {
console.error('Erreur hook tarif valide:', error);
}
}
// ═══════════════════════════════════════════════════════════════════════
// INITIALISATION PAGE PROJET
// ═══════════════════════════════════════════════════════════════════════
/**
* Initialisation côté projet.
* Le pré-remplissage reste géré dans projet-form-rc.js.
*/
function initProjetPage() {
console.log('Initialisation RC Orchestrator pour la page Projet');
const currentProduct = detectCurrentProduct();
if (currentProduct === 'rc') {
console.log('Projet RC detecte: la gestion modal est deja faite dans projet-form-rc.js');
return;
}
// Les données rc/tarif/projet sont DÉJÀ chargées depuis la base
// par le code existant dans projet-form-RC.js
// On configure juste la détection des changements
setTimeout(() => {
setupProjetChangeDetection();
}, 1000); // Attendre que prefillFromTarif() ait fini
}
/**
* Fallback générique de détection d'impact sur la page projet.
*/
function setupProjetChangeDetection() {
// Les données originales sont dans les variables globales window.tarif et window.rc
// définies par projet-form-RC.js
const tarifOriginal = window.tarif;
const rcOriginal = window.rc;
if (!tarifOriginal && !rcOriginal) {
console.log('Pas de tarif/rc, pas de detection');
return;
}
console.log('Configuration de la detection des changements');
console.log('Donnees originales:', { tarif: tarifOriginal, rc: rcOriginal });
// Liste COMPLÈTE des éléments à surveiller (tous les champs impactants)
const elementsToWatch = [
// CA et infos générales
'CA', 'chiffreAffaire', 'nombreVehicules', 'nbrVehicule',
// Zones géographiques
'zone1', 'zone2', 'zone3', 'zone4', 'zone5', 'zone6',
// Protection Juridique
'switchPJ', 'checkPJ',
// RCE
'choixRCE', 'checkRCE',
// TPPC
'checkTPPC', 'capitalTPPC', 'vehiculesTPPC',
// Engagements complémentaires
'checkDomImmat', 'checkContConf', 'checkDiffInv',
// Garanties additionnelles
'checkStationLavage', 'checkGarageInterne', 'checkCSE',
// Sinistralité
'nbSinistres3ans', 'montantSinistres3ans',
// Autres
'programmeInternationale', 'participationResultat'
];
// Ajouter des listeners sur tous les éléments surveillés
elementsToWatch.forEach(elementId => {
const element = document.getElementById(elementId);
if (!element) return;
const eventType = element.type === 'checkbox' ? 'change' : 'blur';
element.addEventListener(eventType, function(e) {
const fieldName = this.id;
const newValue = this.type === 'checkbox' ? this.checked : this.value;
console.log(`Changement detecte: ${fieldName} = ${newValue}`);
// Vérifier si c'est un champ impactant
if (isFieldImpactingTarif(fieldName)) {
console.warn(`"${fieldName}" impacte le tarif`);
showReturnToTarifModal(fieldName);
} else {
console.log(`"${fieldName}" n'impacte pas le tarif`);
}
});
});
// Surveiller les radio buttons (type de cotisation)
const radioTypeCot = document.querySelectorAll('input[name="typeCot"]');
radioTypeCot.forEach(radio => {
radio.addEventListener('change', function() {
console.log(`Changement type cotisation: ${this.value}`);
console.warn('Type de cotisation impacte le tarif');
showReturnToTarifModal('Type de cotisation');
});
});
// Surveiller le select activités
const activitySelector = document.getElementById('activity-selector');
if (activitySelector) {
activitySelector.addEventListener('change', function() {
const selectedValues = Array.from(this.selectedOptions).map(opt => opt.value);
console.log('Changement activites:', selectedValues);
console.warn('Activites impactent le tarif');
showReturnToTarifModal('Activités');
});
}
// Surveiller le select marchandises
const marchandiseSelector = document.getElementById('marchandise-selector');
if (marchandiseSelector) {
marchandiseSelector.addEventListener('change', function() {
const selectedValues = Array.from(this.selectedOptions).map(opt => opt.value);
console.log('Changement marchandises:', selectedValues);
console.warn('Marchandises impactent le tarif');
showReturnToTarifModal('Marchandises');
});
}
// Surveiller les boutons d'action sur les zones (Monde entier / Reset)
['btnMondeEntier', 'btnReset'].forEach(btnId => {
const btn = document.getElementById(btnId);
if (!btn) return;
btn.addEventListener('click', () => {
console.log(`Changement zones via ${btnId}`);
console.warn('Zones geographiques impactent le tarif');
showReturnToTarifModal('Zones géographiques');
});
});
console.log('Detection des changements configuree');
}
// ═══════════════════════════════════════════════════════════════════════
// INITIALISATION PAGE TARIF
// ═══════════════════════════════════════════════════════════════════════
/**
* Initialise le formulaire tarif au chargement.
* Pré-remplit depuis le projet si l'utilisateur vient du projet.
*/
function initTarifPage() {
console.log('Initialisation page Tarif');
// Vérifier si on vient du projet
const projetData = JSON.parse(sessionStorage.getItem(SESSION_STORAGE_KEYS.PROJET_DATA) || 'null');
if (projetData && !getTarifDataFromSession()) {
// On a des données projet mais pas de tarif validé
// = L'utilisateur a commencé par le projet
console.log('Pre-remplissage depuis projet');
setTimeout(() => {
prefillTarifFromProjet(projetData);
}, 500);
}
}
// ═══════════════════════════════════════════════════════════════════════
// INTERCEPTION DES FONCTIONS EXISTANTES
// ═══════════════════════════════════════════════════════════════════════
/**
* Intercepte la fonction de validation du tarif commercial existante.
* Ajoute notre hook avant la redirection.
*/
function interceptTarifValidation() {
// Attendre que la fonction window.saveTarifRC soit disponible
const checkInterval = setInterval(() => {
if (window.saveTarifRC) {
clearInterval(checkInterval);
// Sauvegarder la fonction originale
const originalSaveTarifRC = window.saveTarifRC;
// Remplacer par notre version wrappée
window.saveTarifRC = async function(...args) {
console.log('Interception de saveTarifRC');
// Appeler la fonction originale
const result = await originalSaveTarifRC.apply(this, args);
// Si succès, appeler notre hook
if (result && result.valid) {
onTarifValidated();
}
return result;
};
console.log('saveTarifRC intercepte');
}
}, 100);
// Timeout après 5 secondes
setTimeout(() => clearInterval(checkInterval), 5000);
}
// ═══════════════════════════════════════════════════════════════════════
// DÉMARRAGE AUTOMATIQUE
// ═══════════════════════════════════════════════════════════════════════
/**
* Initialise l'orchestrateur au chargement de la page.
*/
function init() {
console.log('RC Sync Orchestrator: demarrage');
const activePage = detectActivePage();
console.log(`Page active detectee: ${activePage || 'aucune'}`);
if (activePage === 'tarif') {
interceptTarifValidation();
// Attendre que le formulaire soit initialisé
setTimeout(() => {
initTarifPage();
}, 1000);
} else if (activePage === 'projet') {
// Attendre que le formulaire soit initialisé
setTimeout(() => {
initProjetPage();
}, 1000);
}
}
// Démarrage au chargement du DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// ═══════════════════════════════════════════════════════════════════════
// EXPORT PUBLIC
// ═══════════════════════════════════════════════════════════════════════
window.RCOrchestrator = {
onTarifValidated,
initProjetPage,
initTarifPage,
saveTarifDataToSession,
getTarifDataFromSession
};
console.log('RC Sync Orchestrator loaded');
})(window);