personnal/ecole/public/js/rc-data-manager.js

626 lines
26 KiB
JavaScript

/**
* Utilitaires de synchro RC (collecte + pré-remplissage Tarif/Projet).
*/
(function(window) {
'use strict';
const { toNumber, getValue, setValue, getElementByIdFlexible } = window.RCSync;
// ═══════════════════════════════════════════════════════════════════════
// MAPPING DES CHAMPS TARIF ↔ PROJET
// ═══════════════════════════════════════════════════════════════════════
/**
* Mapping des champs Tarif <-> Projet.
* Format: { idTarif: idProjet }.
*/
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
// ═══════════════════════════════════════════════════════════════════════
/**
* Lit l'ensemble des champs utiles depuis le formulaire tarif.
*/
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')),
// Pas de champ montant dans le formulaire actuel.
montant3ans: 0
},
// ═══ 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('Donnees tarif collectees:', data);
return data;
}
/**
* Récupère les activités complémentaires cochées pour un type d'activité.
*/
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('Pre-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(' Vehicules:', 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(' Activites:', 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 activee');
// 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 activee');
// 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 confie');
}
}
// ═══ SINISTRALITÉ ═══
if (tarifData.sinistralite) {
if (tarifData.sinistralite.nombre3ans) {
setValue('nbSinistres3ans', tarifData.sinistralite.nombre3ans);
}
if (tarifData.sinistralite.montant3ans) {
setValue('montantSinistres3ans', tarifData.sinistralite.montant3ans);
}
console.log(' Sinistralite');
}
// ═══ 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(' Resultats 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('Pre-remplissage Projet termine');
} catch (error) {
console.error('Erreur lors du pre-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('Pre-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('Pre-remplissage Tarif termine');
} catch (error) {
console.error('Erreur lors du pre-remplissage Tarif:', error);
}
}
// ═══════════════════════════════════════════════════════════════════════
// EXPORT PUBLIC
// ═══════════════════════════════════════════════════════════════════════
window.RCDataManager = {
collectAllTarifData,
prefillProjetFromTarif,
prefillTarifFromProjet,
FIELD_MAPPING
};
console.log('RC Data Manager loaded');
})(window);