/** * ═══════════════════════════════════════════════════════════════════════════ * RC DATA MANAGER * ═══════════════════════════════════════════════════════════════════════════ * * Ce module gère la collecte, la sauvegarde et le pré-remplissage des données * RC entre les formulaires Tarif et Projet. * * @requires rc-sync-utils.js * @author AXA Transport Team * @version 2.0.0 * @since 2026-02-17 */ (function(window) { 'use strict'; const { toNumber, getValue, setValue, getElementByIdFlexible } = window.RCSync; // ═══════════════════════════════════════════════════════════════════════ // MAPPING DES CHAMPS TARIF ↔ PROJET // ═══════════════════════════════════════════════════════════════════════ /** * Mapping complet des champs entre Tarif et Projet. * Permet la synchronisation bidirectionnelle. * * Structure: { tarifFieldId: projetFieldId } */ const FIELD_MAPPING = { // Informations générales 'CA': 'CA', 'chiffreAffaire': 'CA', 'nbVehicules': 'nombreVehicules', 'nbrVehicule': 'nombreVehicules', // Type de cotisation 'cotisation': 'typeCot', // Activités RCC - Voiturier 'checkVoiturier': 'actVoiturier', 'capitalVoiturier': 'valueActVoiturier', // Activités RCC - Commissionnaire (Multimodal) 'checkCommissionnaire': 'actMultimodal', 'capitalCommissionnaire': 'valueActMultimodal', // Activités RCC - Déménageur 'checkDemenageur': 'actDemEntr', 'capitalDemenageur': 'valueActDemEntr', // Activités RCC - Logistique 'checkLogistique': 'actPrestaLog', 'capitalLogistique': 'valueActPrestaLog', // RCE 'checkRCE': 'autresRC', // Zones géographiques 'zone1': 'zone1', 'zone2': 'zone2', 'zone3': 'zone3', 'zone4': 'zone4', 'zone5': 'zone5', 'zone6': 'zone6', // Protection Juridique 'checkPJ': 'pj', // Garanties additionnelles - Engagements complémentaires 'checkDomImmat': 'extRCCConfie', // Simplifié 'checkContConf': 'extRCCConfie', 'checkTPPC': 'extRCCTPPC', // Extensions RCC 'checkStationLavage': 'extRCCModifCalArrim', // Extensions RCE // (géré séparément car structure différente) // Sinistralité 'sinistre': 'nbSinistres3ans' }; // ═══════════════════════════════════════════════════════════════════════ // COLLECTE DES DONNÉES COMPLÈTES // ═══════════════════════════════════════════════════════════════════════ /** * Collecte toutes les données du formulaire Tarif RC. * Cette fonction est exhaustive et capture TOUS les champs nécessaires. * * @returns {Object} Objet contenant toutes les données du tarif * * @example * const tarifData = collectAllTarifData(); * console.log(tarifData.ca, tarifData.zones, tarifData.marchandises); */ function collectAllTarifData() { // Références flexibles aux éléments const getEl = getElementByIdFlexible; const data = { // ═══ INFORMATIONS GÉNÉRALES ═══ typeCotisation: document.querySelector('input[name="cotisation"]:checked')?.value || null, ca: toNumber(getValue('CA') || getValue('chiffreAffaire')), nombreVehicules: Math.max(0, Math.round(toNumber(getValue('nbVehicules') || getValue('nbrVehicule')))), // ═══ ACTIVITÉS RCC ═══ activites: { voiturier: { checked: getValue('checkVoiturier') || false, capital: toNumber(getValue('capitalVoiturier')), pourcentage: toNumber(getValue('pourcent_voiturier') || getValue('pourcentVoiturier/Loueur')), isSet: Boolean(getValue('pourcent_voiturier')?.trim()) }, commissionnaire: { checked: getValue('checkCommissionnaire') || false, capital: toNumber(getValue('capitalCommissionnaire')), pourcentage: toNumber(getValue('pourcent_commissionnaire')), isSet: Boolean(getValue('pourcent_commissionnaire')?.trim()) }, demenageur: { checked: getValue('checkDemenageur') || false, capital: toNumber(getValue('capitalDemenageur')), pourcentage: toNumber(getValue('pourcent_demenageur')), isSet: Boolean(getValue('pourcent_demenageur')?.trim()) }, logistique: { checked: getValue('checkLogistique') || false, capital: toNumber(getValue('capitalLogistique')), pourcentage: toNumber(getValue('pourcent_logistique')), isSet: Boolean(getValue('pourcent_logistique')?.trim()) }, autocariste: { checked: getValue('checkAutocariste') || false, capital: toNumber(getValue('capitalAutocariste')), pourcentage: toNumber(getValue('pourcent_autocariste')), isSet: Boolean(getValue('pourcent_autocariste')?.trim()) }, autres: { checked: getValue('checkAutres') || false, capital: toNumber(getValue('capitalAutres')), pourcentage: toNumber(getValue('pourcent_autres')), isSet: Boolean(getValue('pourcent_autres')?.trim()) } }, // ═══ RCE ═══ rce: { checked: getValue('checkRCE') || false }, // ═══ ACTIVITÉS COMPLÉMENTAIRES (JSON) ═══ activitesComplementaires: { voiturier: collectActivitesComplJSON('voiturier'), commissionnaire: collectActivitesComplJSON('commissionnaire'), demenageur: collectActivitesComplJSON('demenageur'), logistique: collectActivitesComplJSON('logistique') }, // ═══ MARCHANDISES (JSON) ═══ marchandises: { voiturier: collectMarchandisesJSON('voiturier'), commissionnaire: collectMarchandisesJSON('commissionnaire'), demenageur: collectMarchandisesJSON('demenageur'), logistique: collectMarchandisesJSON('logistique'), autocariste: collectMarchandisesJSON('autocariste'), autres: collectMarchandisesJSON('autres') }, // ═══ ZONES GÉOGRAPHIQUES ═══ zones: { zone1: getValue('zone1') || false, zone2: getValue('zone2') || false, zone3: getValue('zone3') || false, zone4: getValue('zone4') || false, zone5: getValue('zone5') || false, zone6: getValue('zone6') || false }, // ═══ ENGAGEMENTS COMPLÉMENTAIRES ═══ engagementsComplementaires: { domicileImmatriculation: { checked: getValue('checkDomImmat') || false, capital: toNumber(getValue('inputDomImmat')) }, contenantConfie: { checked: getValue('checkContConf') || false, capital: toNumber(getValue('inputContConf')) }, differenceInventaire: { checked: getValue('checkDiffInv') || false, capital: toNumber(getValue('inputDiffInv')) } }, // ═══ GARANTIES ADDITIONNELLES ═══ garantiesAdditionnelles: { stationLavage: getValue('checkStationLavage') || false, garageInterne: getValue('checkGarageInterne') || false, cse: getValue('checkCSE') || false, tppc: { checked: getValue('checkTPPC') || false, capital: toNumber(getValue('selTPPCcapital')), vehicules: Math.max(0, Math.round(toNumber(getValue('selTPPCveh')))) }, pj: getValue('checkPJ') || false }, // ═══ SINISTRALITÉ ═══ sinistralite: { nombre3ans: toNumber(getValue('sinistre')), montant3ans: 0 // TODO: ajouter si champ existe }, // ═══ RÉSULTATS DE CALCUL ═══ resultats: { // Franchise 250 fr250: { primeRCC: toNumber(getEl('rccFr250')?.textContent), primeRCE: toNumber(getEl('rceFr250')?.textContent), primePJ: toNumber(getEl('pjFr250')?.textContent), primeTotal: toNumber(getEl('priceFr250')?.textContent), tauxRCC: toNumber(getEl('tauxRccFr250')?.textContent), tauxRCE: toNumber(getEl('tauxRceFr250')?.textContent), tauxGlobal: toNumber(getEl('tauxGlobalFr250')?.textContent) }, // Franchise 400 fr400: { primeRCC: toNumber(getEl('rccFr400')?.textContent), primeRCE: toNumber(getEl('rceFr400')?.textContent), primePJ: toNumber(getEl('pjFr400')?.textContent), primeTotal: toNumber(getEl('priceFr400')?.textContent), tauxRCC: toNumber(getEl('tauxRccFr400')?.textContent), tauxRCE: toNumber(getEl('tauxRceFr400')?.textContent), tauxGlobal: toNumber(getEl('tauxGlobalFr400')?.textContent) }, // Franchise 2000 fr2000: { primeRCC: toNumber(getEl('rccFr2000')?.textContent), primeRCE: toNumber(getEl('rceFr2000')?.textContent), primePJ: toNumber(getEl('pjFr2000')?.textContent), primeTotal: toNumber(getEl('priceFr2000')?.textContent), tauxRCC: toNumber(getEl('tauxRccFr2000')?.textContent), tauxRCE: toNumber(getEl('tauxRceFr2000')?.textContent), tauxGlobal: toNumber(getEl('tauxGlobalFr2000')?.textContent) }, franchiseChoisie: window.franchiseChoisie || null, tarifCommercial: toNumber(getValue('tarifCom')) }, // ═══ COMMENTAIRE ═══ commentaire: getValue('commentaire') || '' }; console.log('📊 Données Tarif collectées:', data); return data; } /** * Fonction helper pour collecter les activités complémentaires depuis le formulaire. * * @param {string} typeActivite - Type d'activité ('voiturier', 'commissionnaire', etc.) * @returns {string} JSON array des activités cochées * @private */ function collectActivitesComplJSON(typeActivite) { let name; switch(typeActivite.toLowerCase()) { case 'voiturier': name = 'actComplVoiturier/Loueur'; break; case 'commissionnaire': name = 'actComplCommissionnaire de Transport'; break; case 'demenageur': name = 'actComplDéménageur'; break; case 'logistique': name = 'actComplLogistique'; break; default: return JSON.stringify([]); } const checkboxes = document.querySelectorAll(`[name="${name}"] input[type="checkbox"]:checked`); const activites = []; checkboxes.forEach(cb => { const text = cb.nextElementSibling ? cb.nextElementSibling.textContent.trim() : cb.value; activites.push(text); }); return JSON.stringify(activites); } /** * Fonction helper pour collecter les marchandises depuis le formulaire. * * @param {string} typeActivite - Type d'activité * @returns {string} JSON array des marchandises cochées * @private */ function collectMarchandisesJSON(typeActivite) { let name; switch(typeActivite.toLowerCase()) { case 'voiturier': name = 'marVoiturier/Loueur'; break; case 'commissionnaire': name = 'marCommissionnaire de Transport'; break; case 'demenageur': name = 'marDéménageur'; break; case 'logistique': name = 'marLogistique'; break; case 'autocariste': name = 'marAutocariste'; break; case 'autres': name = 'marAutres activites'; break; default: return JSON.stringify([]); } const checkboxes = document.querySelectorAll(`[name="${name}"] input[type="checkbox"]:checked`); const marchandises = []; checkboxes.forEach(cb => { const text = cb.nextElementSibling ? cb.nextElementSibling.textContent.trim() : cb.value; marchandises.push(text); }); return JSON.stringify(marchandises); } // ═══════════════════════════════════════════════════════════════════════ // PRÉ-REMPLISSAGE TARIF → PROJET // ═══════════════════════════════════════════════════════════════════════ /** * Pré-remplit le formulaire Projet avec les données du Tarif. * Cette fonction est appelée quand l'utilisateur passe du Tarif au Projet. * * @param {Object} tarifData - Données complètes du tarif (de collectAllTarifData) * * @example * const tarifData = collectAllTarifData(); * prefillProjetFromTarif(tarifData); */ function prefillProjetFromTarif(tarifData) { if (!tarifData) { console.warn('Pas de données tarif à pré-remplir'); return; } console.log('📝 Pré-remplissage Projet depuis Tarif...'); try { // ═══ INFORMATIONS GÉNÉRALES ═══ // CA if (tarifData.ca) { setValue('CA', tarifData.ca); console.log(' ✓ CA:', tarifData.ca); } // Type de cotisation if (tarifData.typeCotisation) { const radio = document.querySelector(`input[name="typeCot"][value="${tarifData.typeCotisation}"]`); if (radio) { radio.checked = true; console.log(' ✓ Type cotisation:', tarifData.typeCotisation); } } // Nombre de véhicules if (tarifData.nombreVehicules) { setValue('nombreVehicules', tarifData.nombreVehicules); console.log(' ✓ Véhicules:', tarifData.nombreVehicules); } // ═══ ACTIVITÉS ═══ const activitySelector = document.getElementById('activity-selector'); if (activitySelector && tarifData.activites) { const activitesToAdd = []; if (tarifData.activites.voiturier?.checked) { activitesToAdd.push('Voiturier/Loueur'); } if (tarifData.activites.commissionnaire?.checked) { activitesToAdd.push('Commissionnaire de Transport'); } if (tarifData.activites.demenageur?.checked) { activitesToAdd.push('Déménageur d\'entreprises'); } if (tarifData.activites.logistique?.checked) { activitesToAdd.push('Prestataire logistique'); } if (tarifData.activites.autocariste?.checked) { activitesToAdd.push('Autocariste'); } if (tarifData.activites.autres?.checked) { activitesToAdd.push('Autres activités'); } // Sélectionner les options dans le select Array.from(activitySelector.options).forEach(option => { if (activitesToAdd.includes(option.value)) { option.selected = true; } }); // Trigger change pour créer les chips Materialize const event = new Event('change', { bubbles: true }); activitySelector.dispatchEvent(event); console.log(' ✓ Activités:', activitesToAdd.length); } // ═══ MARCHANDISES ═══ const marchandiseSelector = document.getElementById('marchandise-selector'); if (marchandiseSelector && tarifData.marchandises) { const marchandisesToSelect = []; // Parser les marchandises de chaque type ['voiturier', 'commissionnaire', 'demenageur', 'logistique', 'autocariste', 'autres'].forEach(type => { const marchArray = tarifData.marchandises[type]; if (Array.isArray(marchArray)) { marchArray.forEach(m => marchandisesToSelect.push(m)); } }); // Sélectionner dans le select Array.from(marchandiseSelector.options).forEach(option => { if (marchandisesToSelect.includes(option.text) || marchandisesToSelect.includes(option.value)) { option.selected = true; } }); const event = new Event('change', { bubbles: true }); marchandiseSelector.dispatchEvent(event); console.log(' ✓ Marchandises:', marchandisesToSelect.length); } // ═══ ZONES GÉOGRAPHIQUES ═══ if (tarifData.zones) { let zonesCount = 0; Object.keys(tarifData.zones).forEach(zoneKey => { const checkbox = document.getElementById(zoneKey); if (checkbox && tarifData.zones[zoneKey]) { checkbox.checked = true; zonesCount++; } }); console.log(' ✓ Zones:', zonesCount); } // ═══ PROTECTION JURIDIQUE ═══ if (tarifData.garantiesAdditionnelles?.pj) { const switchPJ = document.getElementById('switchPJ'); if (switchPJ) { switchPJ.checked = true; console.log(' ✓ PJ activée'); // Afficher la section PJ const pjSection = document.getElementById('pj-section'); if (pjSection) pjSection.style.display = 'block'; } } // ═══ RCE ═══ if (tarifData.rce?.checked) { const choixRCE = document.getElementById('choixRCE'); if (choixRCE) { choixRCE.checked = true; console.log(' ✓ RCE activée'); // Afficher la section RCE const rceSection = document.getElementById('section-rce'); if (rceSection) rceSection.style.display = 'block'; } } // ═══ TPPC ═══ if (tarifData.garantiesAdditionnelles?.tppc?.checked) { const checkTPPC = document.getElementById('checkTPPC'); if (checkTPPC) { checkTPPC.checked = true; if (tarifData.garantiesAdditionnelles.tppc.capital) { setValue('capitalTPPC', tarifData.garantiesAdditionnelles.tppc.capital); } if (tarifData.garantiesAdditionnelles.tppc.vehicules) { setValue('vehiculesTPPC', tarifData.garantiesAdditionnelles.tppc.vehicules); } console.log(' ✓ TPPC'); } } // ═══ ENGAGEMENTS COMPLÉMENTAIRES ═══ const engagements = tarifData.engagementsComplementaires; if (engagements) { if (engagements.domicileImmatriculation?.checked) { setValue('checkDomImmat', true); console.log(' ✓ Domicile immatriculation'); } if (engagements.contenantConfie?.checked) { setValue('checkContConf', true); console.log(' ✓ Contenant confié'); } } // ═══ SINISTRALITÉ ═══ if (tarifData.sinistralite) { if (tarifData.sinistralite.nombre3ans) { setValue('nbSinistres3ans', tarifData.sinistralite.nombre3ans); } if (tarifData.sinistralite.montant3ans) { setValue('montantSinistres3ans', tarifData.sinistralite.montant3ans); } console.log(' ✓ Sinistralité'); } // ═══ RÉSULTATS TARIFAIRES ═══ if (tarifData.resultats) { const res = tarifData.resultats; // Taux if (res.tauxRCCHT) setValue('tauxRCCHT', res.tauxRCCHT); if (res.tauxRCCTTC) setValue('tauxRCCTTC', res.tauxRCCTTC); if (res.tauxRCEHT) setValue('tauxRCEHT', res.tauxRCEHT); if (res.tauxRCETTC) setValue('tauxRCETTC', res.tauxRCETTC); if (res.tauxTotalHT) setValue('tauxTotalHT', res.tauxTotalHT); if (res.tauxTotalTTC) setValue('tauxTotalTTC', res.tauxTotalTTC); // Cotisations if (res.cotRCCHT) setValue('cotRCCHT', res.cotRCCHT); if (res.cotRCCTTC) setValue('cotRCCTTC', res.cotRCCTTC); if (res.cotRCEHT) setValue('cotRCEHT', res.cotRCEHT); if (res.cotRCETTC) setValue('cotRCETTC', res.cotRCETTC); if (res.cotPJHT) setValue('cotPJHT', res.cotPJHT); if (res.cotPJTTC) setValue('cotPJTTC', res.cotPJTTC); if (res.cotTotalHT) setValue('cotTotalHT', res.cotTotalHT); if (res.cotTotalTTC) setValue('cotTotalTTC', res.cotTotalTTC); console.log(' ✓ Résultats tarifaires'); } // Forcer la mise à jour des éléments Materialize if (window.M && window.M.FormSelect) { const selects = document.querySelectorAll('select'); window.M.FormSelect.init(selects); } if (window.M && window.M.updateTextFields) { window.M.updateTextFields(); } console.log('✅ Pré-remplissage Projet terminé'); } catch (error) { console.error('❌ Erreur lors du pré-remplissage Projet:', error); } } // ═══════════════════════════════════════════════════════════════════════ // PRÉ-REMPLISSAGE PROJET → TARIF // ═══════════════════════════════════════════════════════════════════════ /** * Pré-remplit le formulaire Tarif avec les données du Projet. * Cette fonction est appelée quand l'utilisateur passe du Projet au Tarif. * * @param {Object} projetData - Données complètes du projet * * @example * prefillTarifFromProjet(projetData); */ function prefillTarifFromProjet(projetData) { if (!projetData) { console.warn('Pas de données projet à pré-remplir'); return; } console.log('📝 Pré-remplissage Tarif depuis Projet...'); try { // CA if (projetData.ca) { setValue('CA', projetData.ca); } // Type de cotisation if (projetData.typeCot) { const radio = document.querySelector(`input[name="cotisation"][value="${projetData.typeCot}"]`); if (radio) radio.checked = true; } // Zones géographiques ['zone1', 'zone2', 'zone3', 'zone4', 'zone5', 'zone6'].forEach(zone => { if (projetData[zone]) { setValue(zone, true); } }); // PJ if (projetData.pj) { setValue('checkPJ', true); } // RCE if (projetData.autresRC) { setValue('checkRCE', true); } console.log('✅ Pré-remplissage Tarif terminé'); } catch (error) { console.error('❌ Erreur lors du pré-remplissage Tarif:', error); } } // ═══════════════════════════════════════════════════════════════════════ // EXPORT PUBLIC // ═══════════════════════════════════════════════════════════════════════ window.RCDataManager = { collectAllTarifData, prefillProjetFromTarif, prefillTarifFromProjet, FIELD_MAPPING }; console.log('✅ RC Data Manager loaded'); })(window);