/** * ═══════════════════════════════════════════════════════════════════════════ * RC SYNC ORCHESTRATOR * ═══════════════════════════════════════════════════════════════════════════ * * Ce module orchestre la synchronisation entre Tarif RC et Projet RC. * Il s'intègre avec les formulaires existants sans les modifier. * * @requires rc-sync-utils.js * @requires rc-data-manager.js * @author AXA Transport Team * @version 2.0.0 * @since 2026-02-17 */ (function(window) { 'use strict'; // Attendre que les dépendances soient chargées if (!window.RCSync || !window.RCDataManager) { console.error('❌ Dépendances RC Sync manquantes'); return; } const { isChangeImpactingTarif, showReturnToTarifModal } = window.RCSync; const { collectAllTarifData, prefillProjetFromTarif, 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 la page active (tarif ou projet) depuis l'URL. * * @returns {'tarif'|'projet'|null} Page active ou null */ 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; } // ═══════════════════════════════════════════════════════════════════════ // GESTION SESSIONSTORAGE // ═══════════════════════════════════════════════════════════════════════ /** * Sauvegarde les données du tarif validé dans sessionStorage. * * @param {Object} tarifData - Données complètes du tarif */ 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('✅ Données tarif sauvegardées en session'); } catch (error) { console.error('❌ Erreur sauvegarde session:', error); } } /** * Récupère les données du tarif depuis sessionStorage. * * @returns {Object|null} Données du tarif ou null */ 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; } } /** * Récupère les données originales du tarif pour comparaison. * * @returns {Object|null} Données originales du tarif */ function getTarifOriginalDataFromSession() { try { const data = sessionStorage.getItem(SESSION_STORAGE_KEYS.TARIF_ORIGINAL); return data ? JSON.parse(data) : null; } catch (error) { return null; } } // ═══════════════════════════════════════════════════════════════════════ // HOOK: APRÈS VALIDATION TARIF // ═══════════════════════════════════════════════════════════════════════ /** * Hook appelé après la validation du tarif commercial. * Collecte toutes les données et les sauvegarde en session. * * Cette fonction doit être appelée juste avant la redirection vers le projet. */ function onTarifValidated() { console.log('🎯 Hook: Tarif validé, collecte des données...'); try { // Collecter toutes les données du tarif const tarifData = collectAllTarifData(); // Sauvegarder en session pour le pré-remplissage projet saveTarifDataToSession(tarifData); console.log('✅ Données tarif prêtes pour le projet'); } catch (error) { console.error('❌ Erreur hook tarif validé:', error); } } // ═══════════════════════════════════════════════════════════════════════ // INITIALISATION PAGE PROJET // ═══════════════════════════════════════════════════════════════════════ /** * Initialise le formulaire projet au chargement. * Configure UNIQUEMENT la détection des changements impactants. * Le pré-remplissage est géré par prefillFromTarif() existant dans projet-form-RC.js */ function initProjetPage() { console.log('🚀 Initialisation RC Orchestrator pour page Projet...'); // 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 } /** * Configure la détection des changements impactants dans le projet. * Affiche un modal si l'utilisateur modifie un champ qui impacte le tarif. * Utilise les variables globales rc/tarif depuis projet-form-RC.js */ 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 détection'); return; } console.log('👁️ Configuration détection changements...'); console.log('📋 Données 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 détecté: ${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 activités:`, selectedValues); console.warn(`⚠️ Activités 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 géographiques impactent le tarif !'); showReturnToTarifModal('Zones géographiques'); }); }); console.log('✅ Détection changements configurée sur tous les champs impactants'); } // ═══════════════════════════════════════════════════════════════════════ // 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('📥 Pré-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 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 intercepté'); } }, 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: Démarrage...'); const activePage = detectActivePage(); console.log(`📄 Page active détectée: ${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);