388 lines
17 KiB
JavaScript
388 lines
17 KiB
JavaScript
/**
|
||
* ═══════════════════════════════════════════════════════════════════════════
|
||
* 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); |