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

388 lines
17 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* ═══════════════════════════════════════════════════════════════════════════
* 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);