3752 lines
167 KiB
JavaScript
3752 lines
167 KiB
JavaScript
function initSubmenuForm() {
|
||
// Accéder aux informations stockées du parcours
|
||
const parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
||
}
|
||
|
||
function toNumber(x) {
|
||
if (x == null) return 0;
|
||
|
||
let value = String(x).trim();
|
||
if (!value) return 0;
|
||
|
||
value = value
|
||
.replace(/\s/g, '')
|
||
.replace(/[^\d.,-]/g, '');
|
||
|
||
if (!value) return 0;
|
||
|
||
const isNegative = value.startsWith('-');
|
||
value = value.replace(/-/g, '');
|
||
if (isNegative && value) {
|
||
value = '-' + value;
|
||
}
|
||
|
||
const hasComma = value.includes(',');
|
||
const hasDot = value.includes('.');
|
||
|
||
if (hasComma) {
|
||
value = value.replace(/\./g, '').replace(/,/g, '.');
|
||
} else if (hasDot) {
|
||
const dotMatches = value.match(/\./g);
|
||
const dotCount = dotMatches ? dotMatches.length : 0;
|
||
if (dotCount > 1) {
|
||
const parts = value.split('.');
|
||
const lastSegment = parts[parts.length - 1];
|
||
if (lastSegment.length === 3) {
|
||
value = parts.join('');
|
||
} else {
|
||
value = parts.slice(0, -1).join('') + '.' + lastSegment;
|
||
}
|
||
}
|
||
}
|
||
|
||
const parsed = Number(value);
|
||
return Number.isFinite(parsed) ? parsed : 0;
|
||
}
|
||
|
||
// Fonction pour formater un nombre avec X décimales max (sans décimales si entier)
|
||
function formatNumber(num, decimals = 2) {
|
||
if (!num || isNaN(num)) return '0.' + '0'.repeat(decimals);
|
||
const factor = Math.pow(10, decimals);
|
||
const rounded = Math.round(num * factor) / factor;
|
||
// Si c'est un nombre entier, ne pas afficher les décimales
|
||
if (Number.isInteger(rounded)) {
|
||
return rounded.toString();
|
||
}
|
||
return rounded.toFixed(decimals);
|
||
}
|
||
|
||
function getElementByIdFlexible(id) {
|
||
if (!id) return null;
|
||
const direct = document.getElementById(id);
|
||
if (direct) return direct;
|
||
try {
|
||
return document.querySelector(`[id="${id.replace(/"/g, '\\"')}"]`);
|
||
} catch (err) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Exposer initSubmenuForm globalement pour y accéder depuis l'extérieur
|
||
window.initSubmenuForm = initSubmenuForm;// Module IIFE pour éviter la pollution de l'espace global
|
||
(function () {
|
||
// Variables globales du module
|
||
let parcours, contrat, client, intermediaire, rc, projet, tarif;
|
||
|
||
//Variables modulos et liste
|
||
let modRCCA, modRCActRCC, modRCActRCE, modRCActCompl, modRCMar, modRCZone, modRCEngagCompl, modRCGarAdd, modRCSinistre, modRCFranchise, modRCPrimeMini
|
||
|
||
// ═══════════════════════════════════════════════════════════════
|
||
// FONCTIONS HELPERS
|
||
// ═══════════════════════════════════════════════════════════════
|
||
|
||
// Fonction helper : trouver la tranche la plus proche
|
||
function findClosestTranche(val, tranches) {
|
||
if (val <= tranches[0]) return tranches[0];
|
||
if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1];
|
||
|
||
for (let i = 0; i < tranches.length - 1; i++) {
|
||
if (val >= tranches[i] && val < tranches[i + 1]) {
|
||
return tranches[i];
|
||
}
|
||
}
|
||
return tranches[tranches.length - 1];
|
||
}
|
||
|
||
// Fonction pour afficher un avertissement visuel de dépassement %
|
||
function showPercentageWarning(excess) {
|
||
let warningDiv = document.getElementById('percentageWarning');
|
||
if (!warningDiv) {
|
||
warningDiv = document.createElement('div');
|
||
warningDiv.id = 'percentageWarning';
|
||
warningDiv.style.cssText = `
|
||
position: fixed;
|
||
top: 20px;
|
||
right: 20px;
|
||
background: #f44336;
|
||
color: white;
|
||
padding: 15px 25px;
|
||
border-radius: 5px;
|
||
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
|
||
z-index: 9999;
|
||
font-weight: bold;
|
||
`;
|
||
document.body.appendChild(warningDiv);
|
||
}
|
||
|
||
warningDiv.innerHTML = `Plafonnement à 100% (vous dépassiez de ${excess.toFixed(1)}%)`;
|
||
warningDiv.style.display = 'block';
|
||
|
||
setTimeout(() => {
|
||
warningDiv.style.display = 'none';
|
||
}, 3000);
|
||
}
|
||
|
||
// Fonction pour masquer toutes les primes (quand % invalide)
|
||
function hideAllPrimes() {
|
||
const primeElements = [
|
||
'primeChapActRCC', 'primeChapActRCE',
|
||
'primeChapActComplRCC', 'primeChapActComplRCE',
|
||
'primeChapMarchRCC', 'primeChapMarchRCE',
|
||
'primeChapZonesRCC', 'primeChapZonesRCE',
|
||
'primeEngValue', 'primeChapGarAddRCC', 'primeChapGarAddRCE',
|
||
'priceFr250', 'priceFr400', 'priceFr2000'
|
||
];
|
||
|
||
primeElements.forEach(id => {
|
||
const el = document.getElementById(id);
|
||
if (el) {
|
||
el.innerHTML = '<span style="color:#f44336;font-weight:bold;"> % invalide (> 100%)</span>';
|
||
}
|
||
});
|
||
}
|
||
|
||
// Fonction pour mettre à jour l'indicateur visuel du total des pourcentages
|
||
function updatePercentageIndicator(total) {
|
||
const indicator = document.getElementById('pourcentageTotal');
|
||
if (!indicator) return;
|
||
|
||
const displayTotal = total.toFixed(1);
|
||
indicator.textContent = `Total : ${displayTotal}%`;
|
||
|
||
if (total > 100) {
|
||
indicator.style.background = '#f44336';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #c62828';
|
||
} else if (total === 100 || Math.abs(total - 100) < 0.1) {
|
||
indicator.style.background = '#4caf50';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #2e7d32';
|
||
} else if (total >= 95) {
|
||
indicator.style.background = '#ff9800';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #ef6c00';
|
||
} else {
|
||
indicator.style.background = 'white';
|
||
indicator.style.color = 'darkblue';
|
||
indicator.style.border = '2px solid darkblue';
|
||
}
|
||
}
|
||
|
||
// ═══════════════════════════════════════════════════════════════
|
||
|
||
// Initialisation du formulaire et des données
|
||
function init() {
|
||
// Materialize init select
|
||
var select = document.querySelectorAll('select');
|
||
M.FormSelect.init(select);
|
||
|
||
// Materialize init Modal
|
||
var modals = document.querySelectorAll('.modal');
|
||
M.Modal.init(modals);
|
||
|
||
// Initialiser les modals spécifiques
|
||
window.modalAnimauxVivants = M.Modal.getInstance(document.getElementById('modalAnimauxVivants'));
|
||
window.modalTransportBeton = M.Modal.getInstance(document.getElementById('modalTransportBeton'));
|
||
window.modalAutocaristeRCE = M.Modal.getInstance(document.getElementById('modalAutocaristeRCE'));
|
||
window.modalTarifCom = M.Modal.getInstance(document.getElementById('modalTarifCom'));
|
||
|
||
// Accéder aux informations stockées du parcours
|
||
parcours = JSON.parse(sessionStorage.getItem('parcours'));
|
||
contrat = JSON.parse(sessionStorage.getItem('contrat'));
|
||
client = contrat?.["@expand"]?.client || null;
|
||
intermediaire = contrat?.["@expand"]?.intermediaire || null;
|
||
|
||
// Récupérer les données RC depuis la nouvelle structure (EXACTEMENT comme TPPC)
|
||
rc = contrat?.["@expand"]?.enCours || null; // RC principal
|
||
projet = rc?.["@expand"]?.projetRC || null; // Données projetRC
|
||
tarif = rc?.["@expand"]?.tarifRC || null; // Données tarifRC
|
||
|
||
console.log("Initialisation pour formulaire tarif :", parcours);
|
||
|
||
constantsJSON().then(() => {
|
||
//TODO à virer après les tests
|
||
console.log("--- Initialisation modulateur RC ---"
|
||
, "\nCA : ", modRCCA
|
||
, "\nactRCC : ", modRCActRCC
|
||
, "\nactRCE : ", modRCActRCE
|
||
, "\nactCompl : ", modRCActCompl
|
||
, "\nmar : ", modRCMar
|
||
, "\nengagComple : ", modRCEngagCompl
|
||
, "\nfranchise : ", modRCFranchise
|
||
, "\ngarAdd : ", modRCGarAdd
|
||
, "\nprimeMini : ", modRCPrimeMini
|
||
, "\nzone : ", modRCZone
|
||
, "\nantecedantSinistre: ", modRCSinistre
|
||
);
|
||
|
||
// Appel des différentes fonctions d'initialisation
|
||
setupEventListeners();
|
||
setupTarifetteButtons();
|
||
populateFormData();
|
||
updatePercentageIndicator(100); // Initialiser à 100%
|
||
calcGlobal();
|
||
})
|
||
}
|
||
|
||
// Configuration des listeners d'événements
|
||
function setupEventListeners() {
|
||
// Empêcher la soumission du formulaire avec la touche Enter
|
||
const form = document.getElementById('projetForm');
|
||
if (form) {
|
||
form.addEventListener('keydown', function(e) {
|
||
// Si Enter est pressée et que ce n'est pas sur un bouton submit
|
||
if (e.key === 'Enter' && e.target.type !== 'submit' && e.target.tagName !== 'BUTTON') {
|
||
// Si c'est un input de pourcentage, on passe au suivant
|
||
if (e.target.classList.contains('input-pourcent')) {
|
||
e.preventDefault();
|
||
// Déclencher l'événement input pour forcer le calcul
|
||
e.target.dispatchEvent(new Event('input', { bubbles: true }));
|
||
// Passer au champ suivant
|
||
const inputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(inp => inp.offsetParent !== null);
|
||
const currentIndex = inputs.indexOf(e.target);
|
||
if (currentIndex >= 0 && currentIndex < inputs.length - 1) {
|
||
inputs[currentIndex + 1].focus();
|
||
inputs[currentIndex + 1].select();
|
||
}
|
||
} else {
|
||
// Pour les autres inputs, empêcher le submit mais permettre la navigation
|
||
e.preventDefault();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
document.getElementById('loadHistoriqueBtn').addEventListener('click', function () {
|
||
handleLoadHistoriqueBtn();
|
||
});
|
||
|
||
resetInputs();
|
||
|
||
var radioButtonsCot = document.getElementsByName('cotisation');
|
||
for (var i = 0; i < radioButtonsCot.length; i++) {
|
||
radioButtonsCot[i].addEventListener('change', function () {
|
||
if (this.value == "forfaitaire") {
|
||
document.getElementById("rowNbrVehicule").style.display = "block";
|
||
document.getElementById("labelVoiturier").style.display = "block";
|
||
document.getElementById("labelCommissionnaire").style.display = "none";
|
||
document.getElementById("labelDemenageur").style.display = "block";
|
||
document.getElementById("labelLogistique").style.display = "none";
|
||
document.getElementById("labelAutocariste").style.display = "block";
|
||
document.getElementById("labelAutres").style.display = "none";
|
||
|
||
document.getElementById("nbrVehicule").value = null;
|
||
|
||
// Lancement du calcul forfaitaire
|
||
calcForfaitaire();
|
||
} else if (this.value == "revisable") {
|
||
document.getElementById("rowNbrVehicule").style.display = "none";
|
||
document.getElementById("labelVoiturier").style.display = "block";
|
||
document.getElementById("labelCommissionnaire").style.display = "block";
|
||
document.getElementById("labelDemenageur").style.display = "block";
|
||
document.getElementById("labelLogistique").style.display = "block";
|
||
document.getElementById("labelAutocariste").style.display = "none";
|
||
document.getElementById("labelAutres").style.display = "block";
|
||
|
||
// Lancement du calcul revisable
|
||
calcRevisable();
|
||
}
|
||
});
|
||
};
|
||
|
||
document.getElementById('chiffreAffaire').addEventListener('input', function () {
|
||
const cot = document.querySelector('input[name="cotisation"]:checked')?.value;
|
||
|
||
if (document.getElementById('chiffreAffaire').value.trim() == '') {
|
||
document.getElementById("modCA").style.display = "none";
|
||
} else {
|
||
// Masquer modCA en forfaitaire car il n'est pas utilisé
|
||
if (cot === 'forfaitaire') {
|
||
document.getElementById("modCA").style.display = "none";
|
||
} else {
|
||
document.getElementById("modCA").style.display = "block";
|
||
}
|
||
}
|
||
|
||
calcGlobal();
|
||
// Validation conditionnelle : CA obligatoire seulement en revisable
|
||
if (typeof validateField === 'function') {
|
||
if (cot === 'revisable') {
|
||
validateField('chiffreAffaire', true);
|
||
} else {
|
||
// En forfaitaire, CA optionnel
|
||
validateField('chiffreAffaire', false);
|
||
}
|
||
}
|
||
if (document.getElementById('projetForm')) {
|
||
updateSubmitButtonState('projetForm');
|
||
}
|
||
});
|
||
|
||
document.getElementById('nbrVehicule').addEventListener('input', function () {
|
||
// Validation : forcer entre 1 et 2 véhicules (comme ancienne plateforme)
|
||
let nbVeh = parseInt(this.value);
|
||
if (nbVeh < 1) {
|
||
this.value = 1;
|
||
} else if (nbVeh > 2) {
|
||
this.value = 2;
|
||
} else if (isNaN(nbVeh)) {
|
||
this.value = 1;
|
||
}
|
||
|
||
calcGlobal();
|
||
validateField('nbrVehicule', true);
|
||
if (document.getElementById('projetForm')) {
|
||
updateSubmitButtonState('projetForm');
|
||
}
|
||
});
|
||
|
||
document.getElementById('sinistre').addEventListener('input', function () {
|
||
if (document.getElementById('sinistre').value.trim() == '') {
|
||
document.getElementById("modSinistre").style.display = "none";
|
||
} else {
|
||
document.getElementById("modSinistre").style.display = "block";
|
||
}
|
||
});
|
||
|
||
document.getElementById('checkRCE').addEventListener('click', function () {
|
||
var RCE = document.querySelectorAll('[name="RCE"]');
|
||
|
||
if (document.getElementById('checkRCE').checked == true) {
|
||
for (var i = 0; i < RCE.length; i++) {
|
||
RCE[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < RCE.length; i++) {
|
||
RCE[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
calcGlobal();
|
||
});
|
||
|
||
// Ajouter des styles dynamiques pour améliorer le feedback visuel
|
||
const style = document.createElement('style');
|
||
style.textContent = `
|
||
.input-pourcent:focus {
|
||
border-color: #1976d2 !important;
|
||
box-shadow: 0 0 8px rgba(25, 118, 210, 0.5) !important;
|
||
outline: none;
|
||
transform: scale(1.05);
|
||
transition: all 0.2s ease;
|
||
}
|
||
.input-pourcent:hover {
|
||
border-color: #5c6bc0 !important;
|
||
transition: all 0.2s ease;
|
||
}
|
||
.input-pourcent.set {
|
||
background-color: #e8f5e9 !important;
|
||
border-color: #4caf50 !important;
|
||
}
|
||
`;
|
||
document.head.appendChild(style);
|
||
|
||
// Ajout d'un écouteur d'événement à chaque champ pourcentage
|
||
document.querySelectorAll('.input-pourcent').forEach(input => {
|
||
// Sélectionner automatiquement le contenu au focus pour faciliter la saisie
|
||
input.addEventListener('focus', function() {
|
||
this.select();
|
||
});
|
||
|
||
// Validation automatique lors de la perte de focus (clic ailleurs)
|
||
input.addEventListener('blur', function() {
|
||
// Déclencher le recalcul si la valeur a changé
|
||
if (this.value !== this.defaultValue) {
|
||
this.dispatchEvent(new Event('input', { bubbles: true }));
|
||
}
|
||
});
|
||
|
||
input.addEventListener('input', function() {
|
||
// Récupérer l'ID de l'input modifié pour accéder à son isSet
|
||
const isSetInputId = 'isSet' + input.id.replace('pourcent', '');
|
||
const isSetInput = document.getElementById(isSetInputId);
|
||
|
||
// Mettre à jour isSet correspondant à true si l'input a une valeur
|
||
if (input.value != '') {
|
||
isSetInput.value = 'true';
|
||
input.classList.add('set'); // Changer le fond
|
||
} else {
|
||
isSetInput.value = 'false'; // Réinitialiser isSet si l'input est vide
|
||
input.classList.remove('set'); // Remettre le fond d'origine
|
||
}
|
||
|
||
// Réinitialiser les inputs non set à vide avant de recalculer
|
||
document.querySelectorAll('.input-pourcent').forEach(p => {
|
||
const correspondingIsSetInput = document.getElementById('isSet' + p.id.replace('pourcent', ''));
|
||
if (correspondingIsSetInput.value == 'false') {
|
||
p.value = ''; // Réinitialiser la valeur
|
||
}
|
||
});
|
||
|
||
// Calcul de la somme des pourcentages des champs actuellement modifiés
|
||
let totalPourcent = 0;
|
||
document.querySelectorAll('.input-pourcent').forEach(pourcentInput => {
|
||
if (pourcentInput.value != '' && pourcentInput.offsetParent != null) {
|
||
totalPourcent += toNumber(pourcentInput.value);
|
||
}
|
||
});
|
||
|
||
// PLAFONNEMENT STRICT À 100%
|
||
if (totalPourcent > 100) {
|
||
const excess = totalPourcent - 100;
|
||
|
||
// Plafonnement : empêcher de dépasser
|
||
// Réduire la valeur qui vient d'être modifiée
|
||
const currentInputVal = toNumber(input.value);
|
||
const maxPossible = currentInputVal - excess;
|
||
|
||
if (maxPossible >= 0) {
|
||
// Plafonner la valeur actuelle
|
||
input.value = maxPossible.toFixed(2);
|
||
totalPourcent = 100;
|
||
} else {
|
||
// La valeur est trop grande, la limiter au restant
|
||
const otherTotal = totalPourcent - currentInputVal;
|
||
input.value = (100 - otherTotal).toFixed(2);
|
||
totalPourcent = 100;
|
||
}
|
||
|
||
// Afficher message d'avertissement visuel
|
||
showPercentageWarning(excess);
|
||
|
||
// Masquer les primes pour montrer que c'est invalide
|
||
const allInputs = document.querySelectorAll('.input-pourcent');
|
||
let finalTotal = 0;
|
||
allInputs.forEach(p => {
|
||
if (p.offsetParent != null) {
|
||
finalTotal += toNumber(p.value);
|
||
}
|
||
});
|
||
|
||
if (finalTotal > 100.01) { // Tolérance de 0.01 pour les arrondis
|
||
// BLOQUER les calculs - afficher erreur
|
||
hideAllPrimes();
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Calcul de la différence à répartir
|
||
const remainingPourcent = 100 - totalPourcent;
|
||
|
||
// Répartition de la différence sur les champs restants non marqués isSet
|
||
const nonModifiedInputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(p => {
|
||
const correspondingIsSetInput = document.getElementById('isSet' + p.id.replace('pourcent', ''));
|
||
return p.value == '' && correspondingIsSetInput.value == 'false' && p.offsetParent != null;
|
||
});
|
||
|
||
// Vérifier si nous avons des inputs non modifiés pour répartir le pourcentage restant
|
||
if (remainingPourcent > 0 && nonModifiedInputs.length > 0) {
|
||
const pourcentToAdd = remainingPourcent / nonModifiedInputs.length;
|
||
|
||
nonModifiedInputs.forEach(p => {
|
||
p.value = pourcentToAdd.toFixed(2);
|
||
});
|
||
} else if (remainingPourcent > 0 && nonModifiedInputs.length === 0) {
|
||
// Tous les champs sont remplis mais total < 100
|
||
// Trouver le dernier champ non-set et lui ajouter le restant
|
||
const allInputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(p => p.offsetParent != null);
|
||
const lastNonSet = allInputs.filter(p => {
|
||
const correspondingIsSetInput = document.getElementById('isSet' + p.id.replace('pourcent', ''));
|
||
return correspondingIsSetInput.value == 'false';
|
||
}).pop();
|
||
|
||
if (lastNonSet) {
|
||
const currentVal = toNumber(lastNonSet.value);
|
||
lastNonSet.value = (currentVal + remainingPourcent).toFixed(2);
|
||
}
|
||
}
|
||
|
||
// Mettre à jour l'indicateur visuel du total
|
||
updatePercentageIndicator(totalPourcent);
|
||
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
// Bouton reset de l'équilibrage pourcentage
|
||
document.getElementById('resetPourcent').addEventListener('click', function() {
|
||
resetInputs();
|
||
updatePercentageIndicator(100); // Après reset = 100%
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkVoiturier').addEventListener('click', function () {
|
||
var actVoiturier = document.querySelectorAll('[name="actVoiturier/Loueur"]');
|
||
var actComplVoiturier = document.querySelectorAll('[name="actComplVoiturier/Loueur"]');
|
||
var marVoiturier = document.querySelectorAll('[name="marVoiturier/Loueur"]');
|
||
|
||
if (document.getElementById('checkVoiturier').checked == true) {
|
||
for (var i = 0; i < actVoiturier.length; i++) {
|
||
actVoiturier[i].style.display = "block";
|
||
actComplVoiturier[i].style.display = "block";
|
||
marVoiturier[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actVoiturier.length; i++) {
|
||
actVoiturier[i].style.display = "none";
|
||
actComplVoiturier[i].style.display = "none";
|
||
marVoiturier[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkCommissionnaire').addEventListener('click', function () {
|
||
var actCommissionnaire = document.querySelectorAll('[name="actCommissionnaire de Transport"]');
|
||
var actComplCommissionnaire = document.querySelectorAll('[name="actComplCommissionnaire de Transport"]');
|
||
var marCommissionnaire = document.querySelectorAll('[name="marCommissionnaire de Transport"]');
|
||
|
||
if (document.getElementById('checkCommissionnaire').checked == true) {
|
||
for (var i = 0; i < actCommissionnaire.length; i++) {
|
||
actCommissionnaire[i].style.display = "block";
|
||
actComplCommissionnaire[i].style.display = "block";
|
||
marCommissionnaire[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actCommissionnaire.length; i++) {
|
||
actCommissionnaire[i].style.display = "none";
|
||
actComplCommissionnaire[i].style.display = "none";
|
||
marCommissionnaire[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkDemenageur').addEventListener('click', function () {
|
||
var actDemenageur = document.querySelectorAll('[name="actDéménageur"]');
|
||
var actComplDemenageur = document.querySelectorAll('[name="actComplDéménageur"]');
|
||
var marDemenageur = document.querySelectorAll('[name="marDéménageur"]');
|
||
|
||
if (document.getElementById('checkDemenageur').checked == true) {
|
||
for (var i = 0; i < actDemenageur.length; i++) {
|
||
actDemenageur[i].style.display = "block";
|
||
actComplDemenageur[i].style.display = "block";
|
||
marDemenageur[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actDemenageur.length; i++) {
|
||
actDemenageur[i].style.display = "none";
|
||
actComplDemenageur[i].style.display = "none";
|
||
marDemenageur[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkLogistique').addEventListener('click', function () {
|
||
var actLogistique = document.querySelectorAll('[name="actLogistique"]');
|
||
var actComplLogistique = document.querySelectorAll('[name="actComplLogistique"]');
|
||
var marLogistique = document.querySelectorAll('[name="marLogistique"]');
|
||
|
||
if (document.getElementById('checkLogistique').checked == true) {
|
||
for (var i = 0; i < actLogistique.length; i++) {
|
||
actLogistique[i].style.display = "block";
|
||
actComplLogistique[i].style.display = "block";
|
||
marLogistique[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actLogistique.length; i++) {
|
||
actLogistique[i].style.display = "none";
|
||
actComplLogistique[i].style.display = "none";
|
||
marLogistique[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkAutocariste').addEventListener('click', function () {
|
||
var actAutocariste = document.querySelectorAll('[name="actAutocariste"]');
|
||
var marAutocariste = document.querySelectorAll('[name="marAutocariste"]');
|
||
|
||
if (document.getElementById('checkAutocariste').checked == true) {
|
||
for (var i = 0; i < actAutocariste.length; i++) {
|
||
actAutocariste[i].style.display = "block";
|
||
marAutocariste[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actAutocariste.length; i++) {
|
||
actAutocariste[i].style.display = "none";
|
||
marAutocariste[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
document.getElementById('checkAutres').addEventListener('click', function () {
|
||
var actAutres = document.querySelectorAll('[name="actAutres activites"]');
|
||
var marAutres = document.querySelectorAll('[name="marAutres activites"]');
|
||
|
||
if (document.getElementById('checkAutres').checked == true) {
|
||
for (var i = 0; i < actAutres.length; i++) {
|
||
actAutres[i].style.display = "block";
|
||
marAutres[i].style.display = "block";
|
||
}
|
||
} else {
|
||
for (var i = 0; i < actAutres.length; i++) {
|
||
actAutres[i].style.display = "none";
|
||
marAutres[i].style.display = "none";
|
||
}
|
||
}
|
||
|
||
// Reset de l'équilibrage pourcentage
|
||
resetInputs();
|
||
updatePercentageIndicator(100);
|
||
calcGlobal();
|
||
});
|
||
|
||
// Event listeners pour les inputs capital (au lieu de selects)
|
||
const capitalInputs = [
|
||
'selectActVoiturier/Loueur',
|
||
'selectActCommissionnaire de Transport',
|
||
'selectActDéménageur',
|
||
'selectActLogistique',
|
||
'selectActAutocariste',
|
||
'selectActAutres activites'
|
||
];
|
||
|
||
capitalInputs.forEach(name => {
|
||
const el = document.getElementsByName(name)[0];
|
||
if (el) {
|
||
el.addEventListener('input', function() {
|
||
calcGlobal();
|
||
});
|
||
}
|
||
});
|
||
|
||
const checkboxesActComplVoiturier = document.querySelectorAll('div[name="actComplVoiturier/Loueur"] input[type="checkbox"]');
|
||
checkboxesActComplVoiturier.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesActCompltComDeTransport = document.querySelectorAll('div[name="actComplCommissionnaire de Transport"] input[type="checkbox"]');
|
||
checkboxesActCompltComDeTransport.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesActComplDem = document.querySelectorAll('div[name="actComplDéménageur"] input[type="checkbox"]');
|
||
checkboxesActComplDem.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesActComplLogistique = document.querySelectorAll('div[name="actComplLogistique"] input[type="checkbox"]');
|
||
checkboxesActComplLogistique.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesMarVoiturier = document.querySelectorAll('div[name="marVoiturier/Loueur"] input[type="checkbox"]');
|
||
checkboxesMarVoiturier.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesMarComDeTransport = document.querySelectorAll('div[name="marCommissionnaire de Transport"] input[type="checkbox"]');
|
||
checkboxesMarComDeTransport.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesMarDem = document.querySelectorAll('div[name="marDéménageur"] input[type="checkbox"]');
|
||
checkboxesMarDem.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesMarLogistique = document.querySelectorAll('div[name="marLogistique"] input[type="checkbox"]');
|
||
checkboxesMarLogistique.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
const checkboxesMarAutres = document.querySelectorAll('div[name="marAutres activites"] input[type="checkbox"]');
|
||
checkboxesMarAutres.forEach(checkbox => {
|
||
checkbox.addEventListener('change', function () {
|
||
calcGlobal();
|
||
});
|
||
});
|
||
|
||
document.getElementById('btnMondeEntier').addEventListener('click', function () {
|
||
document.getElementById('zone1').checked = true;
|
||
document.getElementById('zone1').disabled = true;
|
||
document.getElementById('zone2').checked = true;
|
||
document.getElementById('zone2').disabled = true;
|
||
document.getElementById('zone3').checked = true;
|
||
document.getElementById('zone4').checked = true;
|
||
document.getElementById('zone5').checked = true;
|
||
document.getElementById('zone6').checked = true;
|
||
});
|
||
|
||
document.getElementById('btnReset').addEventListener('click', function () {
|
||
document.getElementById('zone1').checked = false;
|
||
document.getElementById('zone1').disabled = false;
|
||
document.getElementById('zone2').checked = false;
|
||
document.getElementById('zone2').disabled = false;
|
||
document.getElementById('zone3').checked = false;
|
||
document.getElementById('zone4').checked = false;
|
||
document.getElementById('zone5').checked = false;
|
||
document.getElementById('zone6').checked = false;
|
||
});
|
||
|
||
document.getElementById('btnZone1').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone1');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone2').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone2');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone3').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone3');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone4').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone4');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone5').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone5');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone6').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZone6');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('btnZone7').addEventListener('click', function () {
|
||
const elem = document.getElementById('modalZoneExclus');
|
||
const instance = M.Modal.getInstance(elem);
|
||
instance.open();
|
||
});
|
||
|
||
document.getElementById('zone2').addEventListener('click', function () {
|
||
if (document.getElementById('zone2').checked == true) {
|
||
document.getElementById('zone1').checked = true;
|
||
document.getElementById('zone1').disabled = true;
|
||
} else if (document.getElementById('zone2').checked == false) {
|
||
document.getElementById('zone1').checked = true;
|
||
document.getElementById('zone1').disabled = false;
|
||
}
|
||
});
|
||
|
||
document.getElementById('zone3').addEventListener('click', function () {
|
||
if (document.getElementById('zone3').checked == true) {
|
||
document.getElementById('zone2').checked = true;
|
||
document.getElementById('zone1').checked = true;
|
||
document.getElementById('zone2').disabled = true;
|
||
document.getElementById('zone1').disabled = true;
|
||
} else if (document.getElementById('zone3').checked == false) {
|
||
document.getElementById('zone1').checked = true;
|
||
document.getElementById('zone1').disabled = true;
|
||
document.getElementById('zone2').checked = true;
|
||
document.getElementById('zone2').disabled = false;
|
||
}
|
||
});
|
||
|
||
// === Brancher toutes les cases zones sur calcGlobal ===
|
||
document.querySelectorAll('input[id^="zone"]').forEach(cb => {
|
||
cb.addEventListener('change', calcGlobal);
|
||
});
|
||
|
||
// Dommages immatériels
|
||
document.getElementById('checkDomImmat').addEventListener('click', function () {
|
||
document.getElementById('selectDomImmat').style.display = this.checked ? "block" : "none";
|
||
calcGlobal();
|
||
});
|
||
const inputDomImmat = document.getElementById('inputDomImmat');
|
||
if (inputDomImmat) inputDomImmat.addEventListener('input', calcGlobal);
|
||
|
||
// Contenants confiés
|
||
document.getElementById('checkContConf').addEventListener('click', function () {
|
||
document.getElementById('selectContConf').style.display = this.checked ? "block" : "none";
|
||
calcGlobal();
|
||
});
|
||
const inputContConf = document.getElementById('inputContConf');
|
||
if (inputContConf) inputContConf.addEventListener('input', calcGlobal);
|
||
|
||
// Différence inventaire
|
||
document.getElementById('checkDiffInv').addEventListener('click', function () {
|
||
document.getElementById('selectDiffInv').style.display = this.checked ? "block" : "none";
|
||
calcGlobal();
|
||
});
|
||
const inputDiffInv = document.getElementById('inputDiffInv');
|
||
if (inputDiffInv) inputDiffInv.addEventListener('input', calcGlobal);
|
||
|
||
// TPPC show/hide + recalc
|
||
const checkTPPC = document.getElementById('checkTPPC');
|
||
const selectTPPC = document.getElementById('selectTPPC');
|
||
|
||
|
||
|
||
if (checkTPPC && selectTPPC) {
|
||
checkTPPC.addEventListener('click', function () {
|
||
console.log('TPPC checkbox clicked:', this.checked);
|
||
selectTPPC.style.display = this.checked ? "block" : "none";
|
||
|
||
if (!this.checked) {
|
||
// reset des valeurs si décoché
|
||
const cap = document.getElementById('selTPPCcapital');
|
||
const veh = document.getElementById('selTPPCveh');
|
||
if (cap) cap.value = "";
|
||
if (veh) veh.value = "";
|
||
}
|
||
|
||
calcGlobal();
|
||
});
|
||
} else {
|
||
console.error('TPPC elements not found!', { checkTPPC, selectTPPC });
|
||
}
|
||
|
||
const inputTPPCcap = document.getElementById('selTPPCcapital');
|
||
const inputTPPCveh = document.getElementById('selTPPCveh');
|
||
if (inputTPPCcap) {
|
||
inputTPPCcap.addEventListener('input', calcGlobal);
|
||
console.log('TPPC capital input listener attached');
|
||
}
|
||
if (inputTPPCveh) {
|
||
inputTPPCveh.addEventListener('input', calcGlobal);
|
||
console.log('TPPC véhicules input listener attached');
|
||
}
|
||
|
||
// Protection juridique
|
||
document.getElementById('checkPJ').addEventListener('click', calcGlobal);
|
||
|
||
// RCE
|
||
document.getElementById('checkStationLavage').addEventListener('click', calcGlobal);
|
||
document.getElementById('checkGarageInterne').addEventListener('click', calcGlobal);
|
||
document.getElementById('checkCSE').addEventListener('click', calcGlobal);
|
||
// Dès que l’utilisateur tape ou modifie le champ sinistre, on recalcule
|
||
const elSin = document.getElementById('sinistre');
|
||
if (elSin) {
|
||
elSin.addEventListener('input', () => {
|
||
console.log('[event] valeur sinistre modifiée =', elSin.value);
|
||
calcGlobal();
|
||
});
|
||
elSin.addEventListener('change', () => {
|
||
console.log('[event] valeur sinistre validée =', elSin.value);
|
||
calcGlobal();
|
||
});
|
||
}
|
||
|
||
document.querySelectorAll('.franchise-card .btn').forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
const selectedFr = btn.getAttribute('name'); // "250", "400", "mini300"
|
||
window.franchiseChoisie = selectedFr;
|
||
console.log('[tarifette] franchise choisie =', selectedFr);
|
||
document.querySelectorAll('.franchise-card').forEach(c => c.classList.remove('selected'));
|
||
btn.closest('.franchise-card').classList.add('selected');
|
||
});
|
||
});
|
||
|
||
// Event listeners pour les modals d'alerte
|
||
setupMarchandiseAlerts();
|
||
setupActiviteAlerts();
|
||
|
||
// Event listener pour le bouton Valider du modal tarif commercial
|
||
document.getElementById('comm-OK').addEventListener('click', handleValidateTarifCom);
|
||
|
||
// Le bouton Annuler ferme automatiquement le modal grâce à la classe "modal-close"
|
||
}
|
||
|
||
function parsePrefillArray(value) {
|
||
if (Array.isArray(value)) return value;
|
||
if (typeof value === 'string') {
|
||
try {
|
||
const parsed = JSON.parse(value);
|
||
return Array.isArray(parsed) ? parsed : [];
|
||
} catch (error) {
|
||
return [];
|
||
}
|
||
}
|
||
return [];
|
||
}
|
||
|
||
function normalizePrefillValue(value) {
|
||
if (Array.isArray(value)) {
|
||
return value
|
||
.map((item) => normalizePrefillValue(item))
|
||
.sort((a, b) => String(a).localeCompare(String(b), 'fr'));
|
||
}
|
||
|
||
if (value && typeof value === 'object') {
|
||
const normalized = {};
|
||
Object.keys(value).sort().forEach((key) => {
|
||
normalized[key] = normalizePrefillValue(value[key]);
|
||
});
|
||
return normalized;
|
||
}
|
||
|
||
if (typeof value === 'string') {
|
||
const trimmed = value.trim();
|
||
if (!trimmed) return '';
|
||
const numeric = toNumber(trimmed);
|
||
if (!Number.isNaN(numeric) && trimmed.match(/^-?[\d\s,\.]+$/)) {
|
||
return numeric;
|
||
}
|
||
return trimmed.toLowerCase();
|
||
}
|
||
|
||
if (value == null) return null;
|
||
return value;
|
||
}
|
||
|
||
function buildProjetPrefillDelta(snapshot, baseline) {
|
||
if (!snapshot || typeof snapshot !== 'object') return null;
|
||
if (!baseline || typeof baseline !== 'object') return snapshot;
|
||
|
||
const delta = {};
|
||
Object.keys(snapshot).forEach((key) => {
|
||
const currentValue = normalizePrefillValue(snapshot[key]);
|
||
const baselineValue = normalizePrefillValue(baseline[key]);
|
||
|
||
if (JSON.stringify(currentValue) !== JSON.stringify(baselineValue)) {
|
||
delta[key] = snapshot[key];
|
||
}
|
||
});
|
||
|
||
return Object.keys(delta).length > 0 ? delta : null;
|
||
}
|
||
|
||
function applyProjetDataToTarif(projetSource) {
|
||
if (!projetSource || typeof projetSource !== 'object') return;
|
||
|
||
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(projetSource, key);
|
||
const hasAny = (keys) => keys.some(hasOwn);
|
||
const normalize = (value) => String(value || '')
|
||
.normalize('NFD')
|
||
.replace(/[\u0300-\u036f]/g, '')
|
||
.toLowerCase()
|
||
.trim();
|
||
|
||
const toProjetNumber = (value) => {
|
||
if (value == null) return null;
|
||
const raw = String(value).trim();
|
||
if (!raw || raw.toLowerCase() === 'nous consulter') return null;
|
||
const parsed = toNumber(raw);
|
||
return Number.isFinite(parsed) ? parsed : null;
|
||
};
|
||
|
||
const pickNumber = (...keys) => {
|
||
for (const key of keys) {
|
||
const parsed = toProjetNumber(projetSource[key]);
|
||
if (parsed != null) return parsed;
|
||
}
|
||
return null;
|
||
};
|
||
|
||
const setCheckboxState = (id, checked, dispatchClick) => {
|
||
const element = document.getElementById(id);
|
||
if (!element) return;
|
||
element.checked = Boolean(checked);
|
||
if (dispatchClick) {
|
||
element.dispatchEvent(new Event('click'));
|
||
}
|
||
};
|
||
|
||
const setFirstValue = (elements, value) => {
|
||
if (value == null) return;
|
||
for (const element of elements) {
|
||
if (element) {
|
||
element.value = value;
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
|
||
const typeCotisation = projetSource.typeCot || projetSource.typeCotisation;
|
||
if (typeCotisation) {
|
||
const radio = document.getElementById(typeCotisation) || document.querySelector(`input[name="cotisation"][value="${typeCotisation}"]`);
|
||
if (radio) {
|
||
radio.checked = true;
|
||
radio.dispatchEvent(new Event('change'));
|
||
}
|
||
}
|
||
|
||
if (hasOwn('ca')) {
|
||
const caField = getElementByIdFlexible('CA') || getElementByIdFlexible('chiffreAffaire');
|
||
if (caField) {
|
||
const rawCA = String(projetSource.ca || '').trim();
|
||
caField.value = (!rawCA || rawCA.toLowerCase() === 'nous consulter') ? '' : rawCA;
|
||
}
|
||
}
|
||
|
||
const nbVehiculeField = getElementByIdFlexible('nbVehicules') || getElementByIdFlexible('nbrVehicule');
|
||
const nbVehFromProjet = toProjetNumber(projetSource.nombreVehicules ?? projetSource.nbVehicules);
|
||
const nbVehFromTable = Array.isArray(projetSource.designationVehicule) ? projetSource.designationVehicule.length : null;
|
||
if (nbVehiculeField) {
|
||
if (nbVehFromProjet != null) {
|
||
nbVehiculeField.value = Math.max(0, Math.round(nbVehFromProjet));
|
||
} else if (nbVehFromTable != null && nbVehFromTable > 0) {
|
||
nbVehiculeField.value = nbVehFromTable;
|
||
}
|
||
}
|
||
|
||
const activityMappings = [
|
||
{
|
||
keys: ['actVoiturier', 'actLoueur'],
|
||
checkboxId: 'checkVoiturier',
|
||
capitalKeys: ['valueActVoiturier', 'valueActLoueur'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalVoiturier'),
|
||
document.querySelector('input[name="selectActVoiturier/Loueur"]')
|
||
]
|
||
},
|
||
{
|
||
keys: ['actMultimodal'],
|
||
checkboxId: 'checkCommissionnaire',
|
||
capitalKeys: ['valueActMultimodal'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalCommissionnaire'),
|
||
document.querySelector('input[name="selectActCommissionnaire de Transport"]'),
|
||
document.querySelector('input[name="selectActCommissionnaireDeTransport"]')
|
||
]
|
||
},
|
||
{
|
||
keys: ['actDemEntr', 'actDemInterne', 'actDemPar', 'actDemParDom', 'actDemParAdv', 'actGardeMeuble'],
|
||
checkboxId: 'checkDemenageur',
|
||
capitalKeys: ['valueActDemEntr', 'valueActDemInterne', 'valueActDemPar', 'valueActDemParDom', 'valueActDemParAdv'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalDemenageur'),
|
||
document.querySelector('input[name="selectActDéménageur"]'),
|
||
document.querySelector('input[name="selectActDemenageur"]')
|
||
]
|
||
},
|
||
{
|
||
keys: ['actPrestaLog', 'actEntDep'],
|
||
checkboxId: 'checkLogistique',
|
||
capitalKeys: ['valueActPrestaLog', 'valueActEntDep'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalLogistique'),
|
||
document.querySelector('input[name="selectActLogistique"]')
|
||
]
|
||
},
|
||
{
|
||
keys: ['actAutocariste'],
|
||
checkboxId: 'checkAutocariste',
|
||
capitalKeys: ['valueActAutocariste'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalAutocariste'),
|
||
document.querySelector('input[name="selectActAutocariste"]')
|
||
]
|
||
},
|
||
{
|
||
keys: ['actAutres'],
|
||
checkboxId: 'checkAutres',
|
||
capitalKeys: ['valueActAutres'],
|
||
capitalFields: [
|
||
getElementByIdFlexible('capitalAutres'),
|
||
document.querySelector('input[name="selectActAutres activites"]'),
|
||
document.querySelector('input[name="selectActAutresActivites"]')
|
||
]
|
||
}
|
||
];
|
||
|
||
activityMappings.forEach((mapping) => {
|
||
if (!hasAny(mapping.keys)) return;
|
||
const selected = mapping.keys.some((key) => Boolean(projetSource[key]));
|
||
setCheckboxState(mapping.checkboxId, selected, true);
|
||
if (selected) {
|
||
const capitalValue = pickNumber(...mapping.capitalKeys);
|
||
setFirstValue(mapping.capitalFields, capitalValue);
|
||
}
|
||
});
|
||
|
||
if (hasAny(['zone1', 'zone2', 'zone3', 'zone4', 'zone5', 'zone6'])) {
|
||
const zone1 = Boolean(projetSource.zone1);
|
||
const zone2 = Boolean(projetSource.zone2);
|
||
const zone3 = Boolean(projetSource.zone3);
|
||
const zone4 = Boolean(projetSource.zone4);
|
||
const zone5 = Boolean(projetSource.zone5);
|
||
const zone6 = Boolean(projetSource.zone6);
|
||
|
||
const zone1El = document.getElementById('zone1');
|
||
const zone2El = document.getElementById('zone2');
|
||
const zone3El = document.getElementById('zone3');
|
||
const zone4El = document.getElementById('zone4');
|
||
const zone5El = document.getElementById('zone5');
|
||
const zone6El = document.getElementById('zone6');
|
||
|
||
if (zone1El) {
|
||
zone1El.checked = zone1 || zone2 || zone3;
|
||
zone1El.disabled = zone2 || zone3;
|
||
}
|
||
if (zone2El) {
|
||
zone2El.checked = zone2 || zone3;
|
||
zone2El.disabled = zone3;
|
||
}
|
||
if (zone3El) zone3El.checked = zone3;
|
||
if (zone4El) zone4El.checked = zone4;
|
||
if (zone5El) zone5El.checked = zone5;
|
||
if (zone6El) zone6El.checked = zone6;
|
||
}
|
||
|
||
if (hasOwn('autresRC')) {
|
||
setCheckboxState('checkRCE', Boolean(projetSource.autresRC), true);
|
||
}
|
||
|
||
if (hasOwn('pj')) {
|
||
setCheckboxState('checkPJ', Boolean(projetSource.pj), false);
|
||
}
|
||
|
||
const activitesComplementairesMap = [
|
||
{ field: 'activitesVoiturier', container: 'actComplVoiturier/Loueur' },
|
||
{ field: 'activitesCommissionnaire', container: 'actComplCommissionnaire de Transport' },
|
||
{ field: 'activitesDemenageur', container: 'actComplDéménageur' },
|
||
{ field: 'activitesLogistique', container: 'actComplLogistique' }
|
||
];
|
||
|
||
activitesComplementairesMap.forEach(({ field, container }) => {
|
||
if (!hasOwn(field)) return;
|
||
const wanted = parsePrefillArray(projetSource[field]);
|
||
const wantedSet = new Set(wanted.map((item) => String(item).trim()));
|
||
const checkboxes = document.querySelectorAll(`[name="${container}"] input[type="checkbox"]`);
|
||
checkboxes.forEach((checkbox) => {
|
||
const label = checkbox.nextElementSibling ? checkbox.nextElementSibling.textContent.trim() : checkbox.value;
|
||
checkbox.checked = wantedSet.has(label);
|
||
});
|
||
});
|
||
|
||
const marchandiseKeys = [
|
||
'marOrdinaire',
|
||
'marRoulant',
|
||
'marEngins',
|
||
'marRoulantDem',
|
||
'marMobilerUsag',
|
||
'marPerissable',
|
||
'marAnimaux',
|
||
'marCiterne',
|
||
'marBeton',
|
||
'marExceptionnels',
|
||
'marVrac'
|
||
];
|
||
|
||
if (hasAny(marchandiseKeys)) {
|
||
const flags = {
|
||
marOrdinaire: Boolean(projetSource.marOrdinaire),
|
||
marRoulant: Boolean(projetSource.marRoulant),
|
||
marEngins: Boolean(projetSource.marEngins),
|
||
marRoulantDem: Boolean(projetSource.marRoulantDem),
|
||
marMobilerUsag: Boolean(projetSource.marMobilerUsag),
|
||
marPerissable: Boolean(projetSource.marPerissable),
|
||
marAnimaux: Boolean(projetSource.marAnimaux),
|
||
marCiterne: Boolean(projetSource.marCiterne),
|
||
marBeton: Boolean(projetSource.marBeton),
|
||
marExceptionnels: Boolean(projetSource.marExceptionnels),
|
||
marVrac: Boolean(projetSource.marVrac)
|
||
};
|
||
|
||
const shouldSelectMarchandise = (label) => {
|
||
const text = normalize(label);
|
||
if (!text) return false;
|
||
if (flags.marRoulantDem && text.includes('vehicules roulants') && text.includes('demenagement')) return true;
|
||
if (flags.marRoulant && text.includes('vehicules roulants') && !text.includes('demenagement')) return true;
|
||
if (flags.marOrdinaire && text.includes('ordinaires')) return true;
|
||
if (flags.marEngins && text.includes('engins de chantier')) return true;
|
||
if (flags.marMobilerUsag && text.includes('mobiliers')) return true;
|
||
if (flags.marPerissable && text.includes('perissables')) return true;
|
||
if (flags.marAnimaux && text.includes('animaux vivants')) return true;
|
||
if (flags.marCiterne && text.includes('citerne')) return true;
|
||
if (flags.marBeton && text.includes('beton')) return true;
|
||
if (flags.marExceptionnels && text.includes('exceptionnels')) return true;
|
||
if (flags.marVrac && (text.includes('benne') || text.includes('vrac'))) return true;
|
||
return false;
|
||
};
|
||
|
||
[
|
||
'marVoiturier/Loueur',
|
||
'marCommissionnaire de Transport',
|
||
'marDéménageur',
|
||
'marLogistique',
|
||
'marAutocariste',
|
||
'marAutres activites'
|
||
].forEach((container) => {
|
||
const checkboxes = document.querySelectorAll(`[name="${container}"] input[type="checkbox"]`);
|
||
checkboxes.forEach((checkbox) => {
|
||
const label = checkbox.nextElementSibling ? checkbox.nextElementSibling.textContent : checkbox.value;
|
||
checkbox.checked = shouldSelectMarchandise(label);
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
// Peupler le formulaire avec les données
|
||
function populateFormData() {
|
||
//Poupulate select historique
|
||
if (!contrat.historique) {
|
||
document.getElementById('historiqueDiv').style.display = "none";
|
||
} else {
|
||
document.getElementById('historiqueDiv').style.display = "block";
|
||
|
||
const idSelect = document.getElementById('idSelect');
|
||
|
||
contrat.historique.forEach(function (item) {
|
||
var option = document.createElement('option');
|
||
option.value = item.id;
|
||
option.textContent = item.type + " " + item.produit + " - " + item.date + " - " + item.heure;
|
||
|
||
if (item.nom != undefined && item.prenom != undefined) {
|
||
option.textContent += " - " + item.nom + " " + item.prenom;
|
||
}
|
||
|
||
idSelect.appendChild(option);
|
||
});
|
||
|
||
M.FormSelect.init(idSelect);
|
||
}
|
||
|
||
// Helpers défauts (au cas où aucune donnée côté RC)
|
||
const ensureDefaultActComplVoiturier = () => {
|
||
const container = document.querySelector('[name="actComplVoiturier/Loueur"]');
|
||
if (!container) return;
|
||
const checkboxes = Array.from(container.querySelectorAll('input[type="checkbox"]'));
|
||
const anyChecked = checkboxes.some(cb => cb.checked);
|
||
if (!anyChecked) {
|
||
checkboxes.forEach((cb, idx) => {
|
||
if (idx <= 1) cb.checked = true; // Voiturier + Loueur
|
||
});
|
||
}
|
||
};
|
||
const ensureDefaultMarchandisesVoiturier = () => {
|
||
const container = document.querySelector('[name="marVoiturier/Loueur"]');
|
||
if (!container) return;
|
||
const checkboxes = Array.from(container.querySelectorAll('input[type="checkbox"]'));
|
||
const anyChecked = checkboxes.some(cb => cb.checked);
|
||
if (!anyChecked && checkboxes.length > 0) {
|
||
checkboxes[0].checked = true; // Marchandises ordinaires par défaut
|
||
}
|
||
};
|
||
|
||
// ===== PRÉ-REMPLIR LE FORMULAIRE AVEC LES DONNÉES RC DE LA BASE =====
|
||
if (!rc) {
|
||
console.log('Aucune donnée RC à pré-remplir');
|
||
ensureDefaultActComplVoiturier();
|
||
ensureDefaultMarchandisesVoiturier();
|
||
return;
|
||
}
|
||
|
||
console.log('Pre-remplissage du formulaire tarif avec les donnees RC:', rc);
|
||
|
||
// Type de cotisation
|
||
if (rc.typeCotisation) {
|
||
const radioBtn = document.getElementById(rc.typeCotisation);
|
||
if (radioBtn) {
|
||
radioBtn.checked = true;
|
||
radioBtn.dispatchEvent(new Event('change'));
|
||
}
|
||
}
|
||
|
||
// Chiffre d'affaires et nombre de véhicules
|
||
const caField = getElementByIdFlexible('CA') || getElementByIdFlexible('chiffreAffaire');
|
||
if (rc.chiffreAffaires && caField) caField.value = rc.chiffreAffaires;
|
||
|
||
const nbVehiculeField = getElementByIdFlexible('nbVehicules') || getElementByIdFlexible('nbrVehicule');
|
||
if (rc.nombreVehicules && nbVehiculeField) nbVehiculeField.value = rc.nombreVehicules;
|
||
|
||
// Sinistralité (depuis tarifRC)
|
||
if (tarif && tarif.sinistre) {
|
||
document.getElementById('sinistre').value = tarif.sinistre;
|
||
}
|
||
|
||
// Checkbox RCE
|
||
if (rc.checkRCE !== undefined) {
|
||
document.getElementById('checkRCE').checked = rc.checkRCE;
|
||
document.getElementById('checkRCE').dispatchEvent(new Event('click'));
|
||
}
|
||
|
||
// Activité Voiturier/Loueur
|
||
if (rc.checkVoiturier !== undefined) {
|
||
const checkVoiturierEl = getElementByIdFlexible('checkVoiturier');
|
||
if (checkVoiturierEl) {
|
||
checkVoiturierEl.checked = rc.checkVoiturier;
|
||
const capitalVoiturierEl = getElementByIdFlexible('capitalVoiturier') || document.querySelector('input[name="selectActVoiturier/Loueur"]');
|
||
if (rc.capitalVoiturier && capitalVoiturierEl) capitalVoiturierEl.value = rc.capitalVoiturier;
|
||
checkVoiturierEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Activité Commissionnaire
|
||
if (rc.checkCommissionnaire !== undefined) {
|
||
const checkCommissionnaireEl = getElementByIdFlexible('checkCommissionnaire');
|
||
if (checkCommissionnaireEl) {
|
||
checkCommissionnaireEl.checked = rc.checkCommissionnaire;
|
||
const capitalCommissionnaireEl = getElementByIdFlexible('capitalCommissionnaire') || document.querySelector('input[name="selectActCommissionnaire de Transport"]') || document.querySelector('input[name="selectActCommissionnaireDeTransport"]');
|
||
if (rc.capitalCommissionnaire && capitalCommissionnaireEl) capitalCommissionnaireEl.value = rc.capitalCommissionnaire;
|
||
checkCommissionnaireEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Activité Déménageur
|
||
if (rc.checkDemenageur !== undefined) {
|
||
const checkDemenageurEl = getElementByIdFlexible('checkDemenageur');
|
||
if (checkDemenageurEl) {
|
||
checkDemenageurEl.checked = rc.checkDemenageur;
|
||
const capitalDemenageurEl = getElementByIdFlexible('capitalDemenageur') || document.querySelector('input[name="selectActDéménageur"]') || document.querySelector('input[name="selectActDemenageur"]');
|
||
if (rc.capitalDemenageur && capitalDemenageurEl) capitalDemenageurEl.value = rc.capitalDemenageur;
|
||
checkDemenageurEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Activité Logistique
|
||
if (rc.checkLogistique !== undefined) {
|
||
const checkLogistiqueEl = getElementByIdFlexible('checkLogistique');
|
||
if (checkLogistiqueEl) {
|
||
checkLogistiqueEl.checked = rc.checkLogistique;
|
||
const capitalLogistiqueEl = getElementByIdFlexible('capitalLogistique') || document.querySelector('input[name="selectActLogistique"]');
|
||
if (rc.capitalLogistique && capitalLogistiqueEl) capitalLogistiqueEl.value = rc.capitalLogistique;
|
||
checkLogistiqueEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Activité Autocariste
|
||
if (rc.checkAutocariste !== undefined) {
|
||
const checkAutocaristeEl = getElementByIdFlexible('checkAutocariste');
|
||
if (checkAutocaristeEl) {
|
||
checkAutocaristeEl.checked = rc.checkAutocariste;
|
||
const capitalAutocaristeEl = getElementByIdFlexible('capitalAutocariste') || document.querySelector('input[name="selectActAutocariste"]');
|
||
if (rc.capitalAutocariste && capitalAutocaristeEl) capitalAutocaristeEl.value = rc.capitalAutocariste;
|
||
checkAutocaristeEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Activité Autres
|
||
if (rc.checkAutres !== undefined) {
|
||
const checkAutresEl = getElementByIdFlexible('checkAutres');
|
||
if (checkAutresEl) {
|
||
checkAutresEl.checked = rc.checkAutres;
|
||
const capitalAutresEl = getElementByIdFlexible('capitalAutres') || document.querySelector('input[name="selectActAutres activites"]') || document.querySelector('input[name="selectActAutresActivites"]');
|
||
if (rc.capitalAutres && capitalAutresEl) capitalAutresEl.value = rc.capitalAutres;
|
||
checkAutresEl.dispatchEvent(new Event('click'));
|
||
}
|
||
}
|
||
|
||
// Zones géographiques
|
||
if (rc.zone1) document.getElementById('zone1').checked = rc.zone1;
|
||
if (rc.zone2) document.getElementById('zone2').checked = rc.zone2;
|
||
if (rc.zone3) document.getElementById('zone3').checked = rc.zone3;
|
||
if (rc.zone4) document.getElementById('zone4').checked = rc.zone4;
|
||
if (rc.zone5) document.getElementById('zone5').checked = rc.zone5;
|
||
if (rc.zone6) document.getElementById('zone6').checked = rc.zone6;
|
||
|
||
// Pré-remplir les activités complémentaires (JSON) pour TOUTES les activités
|
||
const activitiesTypes = [
|
||
{ field: 'actComplVoiturier', name: 'actComplVoiturier/Loueur' },
|
||
{ field: 'actComplCommissionnaire', name: 'actComplCommissionnaire de Transport' },
|
||
{ field: 'actComplDemenageur', name: 'actComplDéménageur' },
|
||
{ field: 'actComplLogistique', name: 'actComplLogistique' }
|
||
];
|
||
|
||
console.log('Pre-remplissage des activites complementaires...');
|
||
activitiesTypes.forEach(({ field, name }) => {
|
||
// D'abord DÉCOCHER toutes les checkboxes de cette activité
|
||
const allCheckboxes = document.querySelectorAll(`[name="${name}"] input[type="checkbox"]`);
|
||
allCheckboxes.forEach(cb => cb.checked = false);
|
||
|
||
if (rc[field]) {
|
||
try {
|
||
// PocketBase parse automatiquement les champs JSON, donc rc[field] est déjà un array
|
||
const activites = Array.isArray(rc[field]) ? rc[field] : JSON.parse(rc[field]);
|
||
console.log(` ${field}:`, activites);
|
||
activites.forEach(actText => {
|
||
// Chercher la checkbox dont le span adjacent contient ce texte
|
||
allCheckboxes.forEach(cb => {
|
||
const label = cb.nextElementSibling?.textContent.trim();
|
||
if (label === actText) {
|
||
cb.checked = true;
|
||
console.log(` Coche: ${actText}`);
|
||
}
|
||
});
|
||
});
|
||
} catch (e) { console.error(`Erreur parsing ${field}:`, e); }
|
||
}
|
||
});
|
||
|
||
// Pré-remplir les marchandises (JSON) pour TOUTES les activités
|
||
const marchandisesTypes = [
|
||
{ field: 'marchandisesVoiturier', name: 'marVoiturier/Loueur' },
|
||
{ field: 'marchandisesCommissionnaire', name: 'marCommissionnaire de Transport' },
|
||
{ field: 'marchandisesDemenageur', name: 'marDéménageur' },
|
||
{ field: 'marchandisesLogistique', name: 'marLogistique' },
|
||
{ field: 'marchandisesAutocariste', name: 'marAutocariste' },
|
||
{ field: 'marchandisesAutres', name: 'marAutres activites' }
|
||
];
|
||
|
||
console.log('Pre-remplissage des marchandises...');
|
||
marchandisesTypes.forEach(({ field, name }) => {
|
||
// D'abord DÉCOCHER toutes les checkboxes de cette marchandise
|
||
const allCheckboxes = document.querySelectorAll(`[name="${name}"] input[type="checkbox"]`);
|
||
allCheckboxes.forEach(cb => cb.checked = false);
|
||
|
||
if (rc[field]) {
|
||
try {
|
||
// PocketBase parse automatiquement les champs JSON, donc rc[field] est déjà un array
|
||
const marchandises = Array.isArray(rc[field]) ? rc[field] : JSON.parse(rc[field]);
|
||
console.log(` ${field}:`, marchandises);
|
||
marchandises.forEach(marText => {
|
||
// Chercher la checkbox dont le span adjacent contient ce texte
|
||
allCheckboxes.forEach(cb => {
|
||
const label = cb.nextElementSibling?.textContent.trim();
|
||
if (label === marText) {
|
||
cb.checked = true;
|
||
console.log(` Coche: ${marText}`);
|
||
}
|
||
});
|
||
});
|
||
} catch (e) { console.error(`Erreur parsing ${field}:`, e); }
|
||
}
|
||
});
|
||
|
||
// Valeurs par défaut si aucune marchandise/activité compl. remontée
|
||
ensureDefaultActComplVoiturier();
|
||
ensureDefaultMarchandisesVoiturier();
|
||
|
||
// Pré-remplir les pourcentages (depuis tarifRC)
|
||
// Priorité au tarif persistant; ne pas retomber sur rc pour ces champs.
|
||
const tarifSource = tarif || rc?.["@expand"]?.tarifRC || rc?.tarifRC || null;
|
||
// Fallback ultime : données de session (hook RC orchestrator) si tout est vide
|
||
let sessionTarifData = null;
|
||
try {
|
||
const stored = sessionStorage.getItem('rc_tarif_validated_data');
|
||
sessionTarifData = stored ? JSON.parse(stored) : null;
|
||
} catch (e) {
|
||
sessionTarifData = null;
|
||
}
|
||
if (tarifSource || sessionTarifData) {
|
||
const pctVoiturierEl = getElementByIdFlexible('pourcent_voiturier') || getElementByIdFlexible('pourcentVoiturier/Loueur');
|
||
if (tarifSource?.pourcentageVoiturier && pctVoiturierEl) pctVoiturierEl.value = tarifSource.pourcentageVoiturier;
|
||
|
||
const pctCommissionnaireEl = getElementByIdFlexible('pourcent_commissionnaire') || getElementByIdFlexible('pourcentCommissionnaire de Transport') || getElementByIdFlexible('pourcentCommissionnaireDeTransport');
|
||
if (tarifSource?.pourcentageCommissionnaire && pctCommissionnaireEl) pctCommissionnaireEl.value = tarifSource.pourcentageCommissionnaire;
|
||
|
||
const pctDemenageurEl = getElementByIdFlexible('pourcent_demenageur') || getElementByIdFlexible('pourcentDéménageur') || getElementByIdFlexible('pourcentDemenageur');
|
||
if (tarifSource?.pourcentageDemenageur && pctDemenageurEl) pctDemenageurEl.value = tarifSource.pourcentageDemenageur;
|
||
|
||
const pctLogistiqueEl = getElementByIdFlexible('pourcent_logistique') || getElementByIdFlexible('pourcentLogistique');
|
||
if (tarifSource?.pourcentageLogistique && pctLogistiqueEl) pctLogistiqueEl.value = tarifSource.pourcentageLogistique;
|
||
|
||
const pctAutocaristeEl = getElementByIdFlexible('pourcent_autocariste') || getElementByIdFlexible('pourcentAutocariste');
|
||
if (tarifSource?.pourcentageAutocariste && pctAutocaristeEl) pctAutocaristeEl.value = tarifSource.pourcentageAutocariste;
|
||
|
||
const pctAutresEl = getElementByIdFlexible('pourcent_autres') || getElementByIdFlexible('pourcentAutres activites') || getElementByIdFlexible('pourcentAutresActivites');
|
||
if (tarifSource?.pourcentageAutres && pctAutresEl) pctAutresEl.value = tarifSource.pourcentageAutres;
|
||
|
||
// ===== ENGAGEMENTS COMPLÉMENTAIRES (depuis tarifRC) =====
|
||
// Dommages immatériels
|
||
const engagementSrc = tarifSource || sessionTarifData?.engagementsComplementaires;
|
||
if (tarifSource?.checkDomImmat || engagementSrc?.domicileImmatriculation?.checked) {
|
||
document.getElementById('checkDomImmat').checked = true;
|
||
document.getElementById('selectDomImmat').style.display = 'block';
|
||
const cap = tarifSource?.capitalDomImmat ?? engagementSrc?.domicileImmatriculation?.capital;
|
||
if (cap) {
|
||
document.getElementById('inputDomImmat').value = cap;
|
||
}
|
||
}
|
||
|
||
// Contenants confiés
|
||
if (tarifSource?.checkContConf || engagementSrc?.contenantConfie?.checked) {
|
||
document.getElementById('checkContConf').checked = true;
|
||
document.getElementById('selectContConf').style.display = 'block';
|
||
const cap = tarifSource?.capitalContConf ?? engagementSrc?.contenantConfie?.capital;
|
||
if (cap) {
|
||
document.getElementById('inputContConf').value = cap;
|
||
}
|
||
}
|
||
|
||
// Différence inventaire
|
||
if (tarifSource?.checkDiffInv || engagementSrc?.differenceInventaire?.checked) {
|
||
document.getElementById('checkDiffInv').checked = true;
|
||
document.getElementById('selectDiffInv').style.display = 'block';
|
||
const cap = tarifSource?.capitalDiffInv ?? engagementSrc?.differenceInventaire?.capital;
|
||
if (cap) {
|
||
document.getElementById('inputDiffInv').value = cap;
|
||
}
|
||
}
|
||
|
||
// ===== GARANTIES ADDITIONNELLES (depuis tarifRC) =====
|
||
// TPPC
|
||
const garantiesSrc = tarifSource || sessionTarifData?.garantiesAdditionnelles;
|
||
if (tarifSource?.checkTPPC || garantiesSrc?.tppc?.checked) {
|
||
document.getElementById('checkTPPC').checked = true;
|
||
document.getElementById('selectTPPC').style.display = 'block';
|
||
const cap = tarifSource?.capitalTPPC ?? garantiesSrc?.tppc?.capital;
|
||
if (cap) {
|
||
document.getElementById('selTPPCcapital').value = cap;
|
||
}
|
||
const veh = tarifSource?.vehiculesTPPC ?? garantiesSrc?.tppc?.vehicules;
|
||
if (veh) {
|
||
document.getElementById('selTPPCveh').value = veh;
|
||
}
|
||
}
|
||
|
||
// Protection juridique
|
||
if (tarifSource?.checkPJ || garantiesSrc?.pj) {
|
||
document.getElementById('checkPJ').checked = true;
|
||
}
|
||
|
||
// RCE - Station lavage
|
||
if (tarifSource?.checkStationLavage || garantiesSrc?.stationLavage) {
|
||
document.getElementById('checkStationLavage').checked = true;
|
||
}
|
||
|
||
// RCE - Garage interne
|
||
if (tarifSource?.checkGarageInterne || garantiesSrc?.garageInterne) {
|
||
document.getElementById('checkGarageInterne').checked = true;
|
||
}
|
||
|
||
// RCE - CSE
|
||
if (tarifSource?.checkCSE || garantiesSrc?.cse) {
|
||
document.getElementById('checkCSE').checked = true;
|
||
}
|
||
|
||
// ===== FRANCHISE CHOISIE =====
|
||
if (tarifSource?.franchiseChoisie) {
|
||
window.franchiseChoisie = tarifSource.franchiseChoisie;
|
||
// Mettre en surbrillance la carte sélectionnée
|
||
const selectedButton = document.querySelector(`.franchise-card button[name="${tarifSource.franchiseChoisie}"]`);
|
||
if (selectedButton) {
|
||
selectedButton.closest('.franchise-card').classList.add('selected');
|
||
}
|
||
}
|
||
}
|
||
|
||
// Pré-remplissage Projet -> Tarif
|
||
// - si snapshot session: appliquer seulement les champs modifies sur Projet
|
||
// - sinon: utiliser Projet uniquement si on n'a pas de tarif persistant
|
||
let sessionProjetData = null;
|
||
try {
|
||
const storedProjetData = sessionStorage.getItem('rc_projet_data');
|
||
sessionProjetData = storedProjetData ? JSON.parse(storedProjetData) : null;
|
||
} catch (error) {
|
||
sessionProjetData = null;
|
||
}
|
||
|
||
let projetPrefillSource = null;
|
||
if (sessionProjetData) {
|
||
projetPrefillSource = buildProjetPrefillDelta(sessionProjetData, projet);
|
||
} else if (!tarifSource && !sessionTarifData && projet) {
|
||
projetPrefillSource = projet;
|
||
}
|
||
|
||
if (projetPrefillSource) {
|
||
applyProjetDataToTarif(projetPrefillSource);
|
||
}
|
||
|
||
if (sessionProjetData) {
|
||
sessionStorage.removeItem('rc_projet_data');
|
||
}
|
||
|
||
console.log('Formulaire tarif pre-rempli avec succes');
|
||
|
||
// Recalculer après pré-remplissage
|
||
setTimeout(() => {
|
||
calcGlobal();
|
||
}, 500);
|
||
}
|
||
|
||
function calcModCA(caRaw){
|
||
const ca = Number(String(caRaw || '').replace(/\s/g,'').replace(',','.')) || 0;
|
||
const thresholds = Object.keys(modRCCA).map(n => Number(n)).sort((a,b)=>a-b);
|
||
for (const t of thresholds) if (ca < t) return modRCCA[t];
|
||
return modRCCA[thresholds.at(-1)] ?? 1;
|
||
}
|
||
|
||
function calcModMarchandises(data, activityName, type, cot) {
|
||
let m = 1;
|
||
|
||
// On cible le bloc correspondant à l'activité
|
||
const container = document.querySelector(`[name="mar${activityName}"]`);
|
||
if (!container) return 1;
|
||
|
||
// On récupère toutes les cases à cocher de ce bloc
|
||
const checkboxes = container.querySelectorAll('input[type="checkbox"]');
|
||
|
||
checkboxes.forEach(cb => {
|
||
if (cb.checked) {
|
||
// Le libellé affiché est dans le <span> juste après l'input
|
||
const label = cb.nextElementSibling?.innerText.trim();
|
||
|
||
// On simplifie le libellé pour matcher les clés du JSON
|
||
let key = null;
|
||
if (label.includes("ordinaires")) key = "Marchandises ordinaires";
|
||
else if (label.includes("Véhicules roulants")) key = "Véhicules roulants";
|
||
else if (label.includes("Engins de chantier")) key = "Engins de chantier";
|
||
else if (label.includes("Mobiliers")) key = "Mobiliers en déménagement";
|
||
else if (label.includes("périssables")) key = "Marchandises périssables";
|
||
else if (label.includes("citerne")) key = "Marchandises en citerne";
|
||
else if (label.includes("Animaux")) key = "Animaux vivants";
|
||
else if (label.includes("benne")) key = "Marchandises en benne";
|
||
else if (label.includes("béton")) key = "Transport de béton";
|
||
|
||
if (key) {
|
||
const v = data?.[cot]?.[activityName]?.[key]?.[`mod${type}`];
|
||
if (typeof v === "number") {
|
||
m *= v;
|
||
} else {
|
||
console.warn(`Pas de mod trouvé pour activité=${activityName}, clé=${key}, type=${type}, cot=${cot}`);
|
||
}
|
||
} else {
|
||
console.warn(`Libellé non reconnu: "${label}"`);
|
||
}
|
||
}
|
||
});
|
||
|
||
return m;
|
||
}
|
||
|
||
function getZoneMods(data) {
|
||
let mRCC = 1;
|
||
let mRCE = 1;
|
||
|
||
// On parcourt toutes les cases à cocher de zones
|
||
for (let i = 1; i <= 6; i++) {
|
||
const cb = document.getElementById(`zone${i}`);
|
||
if (cb && cb.checked) {
|
||
// Récupérer le libellé affiché
|
||
const label = document.getElementById(`zone${i}-text`).innerText.trim();
|
||
|
||
// Trouver la clé correspondante dans le JSON
|
||
let key = null;
|
||
if (label.includes("France Métropolitaine")) key = "France Métropolitaine et pays limitrophes";
|
||
else if (label.includes("Union Européenne")) key = "Union Européenne";
|
||
else if (label.includes("Autres pays européens")) key = "Autres pays européens sauf Russie et Ukraine (y compris UK et Norvège)";
|
||
else if (label.includes("Maghreb") || label.includes("Amérique du Nord")) key = "Pays du Maghreb et Amérique du Nord ( USA / Canada / Mexique )";
|
||
else if (label.includes("Amérique Centrale") || label.includes("Asie") || label.includes("Océanie")) key = "Amérique Centrale et Sud / Caraïbes, Asie et Océanie";
|
||
else if (label.includes("Afrique") || label.includes("Moyen Orient")) key = "Afrique Hors Maghreb / Proche Orient / Moyen Orient";
|
||
|
||
if (key && data[key]) {
|
||
const zone = data[key];
|
||
if (typeof zone.modRCC === "number") mRCC = Math.max(mRCC, zone.modRCC);
|
||
if (typeof zone.modRCE === "number") mRCE = Math.max(mRCE, zone.modRCE);
|
||
}
|
||
}
|
||
}
|
||
|
||
return { mRCC, mRCE };
|
||
}
|
||
|
||
function calcModActCompl(data, activityName, type, cot) {
|
||
let m = 1;
|
||
const current = getSelectedActivities().find(a => a.typeActivite === activityName);
|
||
if (!current) return 1;
|
||
const table = data?.[cot]?.[activityName] || {};
|
||
(current.listActComplChecked||[]).forEach(name => {
|
||
const v = table[name]?.[`mod${type}`];
|
||
if (typeof v === "number") m *= v;
|
||
});
|
||
return m;
|
||
}
|
||
|
||
function calcEngagCompl(data, primeRCC) {
|
||
let prime = primeRCC;
|
||
let surPrime = 0;
|
||
let modDommImmat = 1;
|
||
let infos = [];
|
||
|
||
function writeToCard(inputId, message) {
|
||
const inputEl = document.getElementById(inputId);
|
||
if (!inputEl) return;
|
||
|
||
const cardContent = inputEl.closest('.card-content');
|
||
if (!cardContent) return;
|
||
|
||
// Supprime l’ancien wrapper pour cet input
|
||
cardContent.querySelectorAll(`div.chip[data-for="${inputId}"]`).forEach(el => el.remove());
|
||
|
||
if (!message) return;
|
||
|
||
// Wrapper
|
||
const wrapper = document.createElement("div");
|
||
wrapper.classList.add("chip"); // uniquement "chip"
|
||
wrapper.dataset.for = inputId;
|
||
|
||
// Message
|
||
const p = document.createElement("p");
|
||
p.dataset.for = inputId;
|
||
p.classList.add("helper-text", "red-text");
|
||
p.style.display = "block"; // override helper-text { display: none; }
|
||
p.textContent = message;
|
||
|
||
wrapper.appendChild(p);
|
||
cardContent.appendChild(wrapper);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// === Contenants confiés ===
|
||
const checkContConf = document.getElementById('checkContConf');
|
||
const inputContConf = document.getElementById('inputContConf');
|
||
if (checkContConf?.checked) {
|
||
const val = toNumber(inputContConf?.value);
|
||
if (val > 0) {
|
||
const tranches = Object.keys(data.modRCC["Contenants confiés"]).map(Number).sort((a,b)=>a-b);
|
||
const tranche = findClosestTranche(val, tranches);
|
||
const add = data.modRCC["Contenants confiés"][tranche];
|
||
if (typeof add === "number") {
|
||
surPrime += add;
|
||
const msg = `Prime RCC : +${add.toLocaleString('fr-FR',{style:'currency',currency:'EUR'})}`;
|
||
//infos.push(msg); pour ajouter le message dans la div "Prime RCC"
|
||
writeToCard('inputContConf', msg);
|
||
}
|
||
}
|
||
} else {
|
||
writeToCard('inputContConf', null); // supprime si décoché
|
||
}
|
||
|
||
// === Différence inventaire ===
|
||
const checkDiffInv = document.getElementById('checkDiffInv');
|
||
const inputDiffInv = document.getElementById('inputDiffInv');
|
||
if (checkDiffInv?.checked) {
|
||
const val = toNumber(inputDiffInv?.value);
|
||
if (val > 0) {
|
||
const tranches = Object.keys(data.modRCC["Différence inventaire"]).map(Number).sort((a,b)=>a-b);
|
||
const tranche = findClosestTranche(val, tranches);
|
||
const add = data.modRCC["Différence inventaire"][tranche];
|
||
if (typeof add === "number") {
|
||
surPrime += add;
|
||
const msg = `Prime RCC : +${add.toLocaleString('fr-FR',{style:'currency',currency:'EUR'})}`;
|
||
//infos.push(msg); pour ajouter le message dans la div "Prime RCC"
|
||
writeToCard('inputDiffInv', msg);
|
||
}
|
||
}
|
||
} else {
|
||
writeToCard('inputDiffInv', null);
|
||
}
|
||
|
||
// === Dommages immatériels ===
|
||
const checkDomImmat = document.getElementById('checkDomImmat');
|
||
const inputDomImmat = document.getElementById('inputDomImmat');
|
||
if (checkDomImmat?.checked) {
|
||
const val = toNumber(inputDomImmat?.value);
|
||
if (val > 0) {
|
||
const tranches = Object.keys(data.modRCC["Dommages immatériels"]).map(Number).sort((a,b)=>a-b);
|
||
const tranche = findClosestTranche(val, tranches);
|
||
const mod = data.modRCC["Dommages immatériels"][tranche];
|
||
if (typeof mod === "number") {
|
||
modDommImmat = mod;
|
||
const msg = `Mod Taux RCC : ×${mod}`;
|
||
//infos.push(msg); pour ajouter le message dans la div "Prime RCC"
|
||
writeToCard('inputDomImmat', msg);
|
||
}
|
||
}
|
||
} else {
|
||
writeToCard('inputDomImmat', null);
|
||
}
|
||
|
||
// === Totaux ===
|
||
prime += surPrime;
|
||
prime *= modDommImmat;
|
||
|
||
return { prime, surPrime, infos };
|
||
}
|
||
|
||
// Fonction helper : trouver la tranche la plus proche
|
||
function findClosestTranche(val, tranches) {
|
||
if (val <= tranches[0]) return tranches[0];
|
||
if (val >= tranches[tranches.length - 1]) return tranches[tranches.length - 1];
|
||
|
||
for (let i = 0; i < tranches.length - 1; i++) {
|
||
if (val >= tranches[i] && val < tranches[i + 1]) {
|
||
// Prendre la tranche inférieure ou égale
|
||
return tranches[i];
|
||
}
|
||
}
|
||
return tranches[tranches.length - 1];
|
||
}
|
||
|
||
// Fonction pour afficher un avertissement visuel de dépassement %
|
||
function showPercentageWarning(excess) {
|
||
// Créer ou récupérer le div d'avertissement
|
||
let warningDiv = document.getElementById('percentageWarning');
|
||
if (!warningDiv) {
|
||
warningDiv = document.createElement('div');
|
||
warningDiv.id = 'percentageWarning';
|
||
warningDiv.style.cssText = `
|
||
position: fixed;
|
||
top: 20px;
|
||
right: 20px;
|
||
background: #f44336;
|
||
color: white;
|
||
padding: 15px 25px;
|
||
border-radius: 5px;
|
||
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
|
||
z-index: 9999;
|
||
font-weight: bold;
|
||
animation: slideIn 0.3s ease;
|
||
`;
|
||
document.body.appendChild(warningDiv);
|
||
}
|
||
|
||
warningDiv.innerHTML = `Vous dépassez 100% (vous dépassiez de ${excess.toFixed(1)}%)`;
|
||
warningDiv.style.display = 'block';
|
||
|
||
// Masquer après 3 secondes
|
||
setTimeout(() => {
|
||
warningDiv.style.display = 'none';
|
||
}, 3000);
|
||
}
|
||
|
||
// Fonction pour masquer toutes les primes (quand % invalide)
|
||
function hideAllPrimes() {
|
||
const primeElements = [
|
||
'primeChapActRCC', 'primeChapActRCE',
|
||
'primeChapActComplRCC', 'primeChapActComplRCE',
|
||
'primeChapMarchRCC', 'primeChapMarchRCE',
|
||
'primeChapZonesRCC', 'primeChapZonesRCE',
|
||
'primeEngValue', 'primeChapGarAddRCC', 'primeChapGarAddRCE',
|
||
'priceFr250', 'priceFr400', 'priceFr2000'
|
||
];
|
||
|
||
primeElements.forEach(id => {
|
||
const el = document.getElementById(id);
|
||
if (el) {
|
||
el.innerHTML = '<span style="color:#f44336;font-weight:bold;"> % invalide (> 100%)</span>';
|
||
}
|
||
});
|
||
}
|
||
|
||
// Fonction pour afficher toutes les primes (quand % valide)
|
||
function showAllPrimes() {
|
||
}
|
||
|
||
// Fonction pour mettre à jour l'indicateur visuel du total des pourcentages
|
||
function updatePercentageIndicator(total) {
|
||
const indicator = document.getElementById('pourcentageTotal');
|
||
if (!indicator) return;
|
||
|
||
const displayTotal = total.toFixed(1);
|
||
indicator.textContent = `Total : ${displayTotal}%`;
|
||
|
||
// Changer la couleur selon le total
|
||
if (total > 100) {
|
||
// ROUGE : Dépassement - INVALIDE
|
||
indicator.style.background = '#f44336';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #c62828';
|
||
indicator.style.animation = 'pulse 1s infinite';
|
||
} else if (total === 100 || Math.abs(total - 100) < 0.1) {
|
||
// VERT : Parfait - 100%
|
||
indicator.style.background = '#4caf50';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #2e7d32';
|
||
indicator.style.animation = 'none';
|
||
} else if (total >= 95) {
|
||
// ORANGE : Proche de 100%
|
||
indicator.style.background = '#ff9800';
|
||
indicator.style.color = 'white';
|
||
indicator.style.border = '3px solid #ef6c00';
|
||
indicator.style.animation = 'none';
|
||
} else {
|
||
// BLEU : En cours de saisie
|
||
indicator.style.background = 'white';
|
||
indicator.style.color = 'darkblue';
|
||
indicator.style.border = '2px solid darkblue';
|
||
indicator.style.animation = 'none';
|
||
}
|
||
}
|
||
|
||
function calcGarAdd(data, primeRCC, primeRCE) {
|
||
let primeRCCres = Number(primeRCC) || 0;
|
||
let primeRCEres = Number(primeRCE) || 0;
|
||
let surPrimeRCE = 0;
|
||
const infosRCC = [];
|
||
const infosRCE = [];
|
||
|
||
function writeToCard(inputId, message) {
|
||
const inputEl = document.getElementById(inputId);
|
||
if (!inputEl) return;
|
||
|
||
const cardContent = inputEl.closest('.card-content');
|
||
if (!cardContent) return;
|
||
|
||
// Supprime l’ancien wrapper pour cet input
|
||
cardContent.querySelectorAll(`div.chip[data-for="${inputId}"]`).forEach(el => el.remove());
|
||
|
||
if (!message) return;
|
||
|
||
// Wrapper
|
||
const wrapper = document.createElement("div");
|
||
wrapper.classList.add("chip");
|
||
wrapper.dataset.for = inputId;
|
||
|
||
// Style : occupe sa propre ligne mais largeur adaptée au contenu
|
||
wrapper.style.display = "table"; // se comporte comme un bloc centré sur son contenu
|
||
wrapper.style.margin = "8px auto"; // centre horizontalement
|
||
|
||
// Message
|
||
const p = document.createElement("p");
|
||
p.dataset.for = inputId;
|
||
p.classList.add("helper-text", "red-text");
|
||
p.style.display = "block"; // override helper-text { display: none; }
|
||
p.textContent = message;
|
||
|
||
wrapper.appendChild(p);
|
||
cardContent.appendChild(wrapper);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// === Station de lavage (RCE forfait) ===
|
||
const checkStation = document.getElementById('checkStationLavage');
|
||
if (checkStation?.checked) {
|
||
const add = data.modRCE["Station de lavage"];
|
||
if (typeof add === "number") {
|
||
surPrimeRCE += add;
|
||
const msg = `Prime RCE : +${add.toLocaleString('fr-FR', { style:'currency', currency:'EUR' })}`;
|
||
//infosRCE.push(msg);
|
||
writeToCard('checkStationLavage', msg);
|
||
}
|
||
} else {
|
||
writeToCard('checkStationLavage', null);
|
||
}
|
||
|
||
// === Garage interne (RCE forfait) ===
|
||
const checkGarage = document.getElementById('checkGarageInterne');
|
||
if (checkGarage?.checked) {
|
||
const add = data.modRCE["Garage interne"];
|
||
if (typeof add === "number") {
|
||
surPrimeRCE += add;
|
||
const msg = `Prime RCE : +${add.toLocaleString('fr-FR', { style:'currency', currency:'EUR' })}`;
|
||
//infosRCE.push(msg);
|
||
writeToCard('checkGarageInterne', msg);
|
||
}
|
||
} else {
|
||
writeToCard('checkGarageInterne', null);
|
||
}
|
||
|
||
// === Comité Social et Economique (RCE forfait) ===
|
||
const checkCSE = document.getElementById('checkCSE');
|
||
if (checkCSE?.checked) {
|
||
const add = data.modRCE["Comité Social et Economique"];
|
||
if (typeof add === "number") {
|
||
surPrimeRCE += add;
|
||
const msg = `Prime RCE : +${add.toLocaleString('fr-FR', { style:'currency', currency:'EUR' })}`;
|
||
//infosRCE.push(msg);
|
||
writeToCard('checkCSE', msg);
|
||
}
|
||
} else {
|
||
writeToCard('checkCSE', null);
|
||
}
|
||
|
||
// === Addition des garanties RCE ===
|
||
primeRCEres += surPrimeRCE;
|
||
|
||
return { primeRCC: primeRCCres, primeRCE: primeRCEres, surPrimeRCE, infosRCC, infosRCE };
|
||
}
|
||
|
||
|
||
|
||
function calcSinistre(data, primeRCC, primeRCE) {
|
||
console.log('[calcSinistre] start', { primeRCC, primeRCE });
|
||
|
||
let primeRCCres = Number(primeRCC) || 0;
|
||
let primeRCEres = Number(primeRCE) || 0;
|
||
let mod = 1;
|
||
|
||
const elSin = document.getElementById('sinistre');
|
||
const elCA = document.getElementById('chiffreAffaire');
|
||
const chip = document.getElementById('modSinistre');
|
||
|
||
if (!elSin || !elCA) {
|
||
console.warn('[calcSinistre] Missing #sinistre or #chiffreAffaire');
|
||
} else {
|
||
const sinistreVal = toNumber(elSin.value);
|
||
const CA = toNumber(elCA.value);
|
||
|
||
console.log('[calcSinistre] inputs', { sinistreVal, CA });
|
||
|
||
if (CA > 0 && sinistreVal >= 0) {
|
||
const ratio = sinistreVal / CA;
|
||
let key = 0.4;
|
||
if (ratio <= 0.4) key = 0.4;
|
||
else if (ratio <= 0.7) key = 0.7;
|
||
else key = 1;
|
||
|
||
mod = data[key];
|
||
console.log('[calcSinistre] ratio=', ratio.toFixed(3), 'key=', key, 'mod=', mod);
|
||
} else {
|
||
console.log('[calcSinistre] CA <= 0 or sinistre < 0 -> mod=1');
|
||
}
|
||
}
|
||
|
||
// Apply modulation to both RCC and RCE
|
||
primeRCCres *= mod;
|
||
primeRCEres *= mod;
|
||
|
||
if (chip) {
|
||
chip.style.display = 'block';
|
||
chip.innerHTML = 'Modulation sinistre :<br>x ' + mod.toLocaleString('fr-FR', { minimumFractionDigits: 2 });
|
||
} else {
|
||
console.warn('[calcSinistre] #modSinistre not found');
|
||
}
|
||
|
||
console.log('[calcSinistre] result', { primeRCC: primeRCCres, primeRCE: primeRCEres, mod });
|
||
return { primeRCC: primeRCCres, primeRCE: primeRCEres, mod };
|
||
}
|
||
|
||
|
||
// --- Fonctions utilitaires ---
|
||
|
||
function getMaxMiniRCC(activites, cot) {
|
||
let maxMini = 0;
|
||
activites.forEach(act => {
|
||
// Récupérer l'input/select pour cette activité
|
||
const inputEl = document.querySelector(`input[name="selectAct${act}"], select[name="selectAct${act}"]`);
|
||
if (!inputEl) return;
|
||
|
||
const capitalSaisi = toNumber(inputEl.value);
|
||
if (capitalSaisi <= 0) return;
|
||
|
||
// Déterminer le type de cotisation
|
||
const cotType = cot === 'revisable' ? 'revisable' : 'forfaitaire';
|
||
|
||
// Trouver la tranche la plus proche
|
||
const grilleAct = modRCPrimeMini?.[cotType]?.[act];
|
||
if (grilleAct) {
|
||
const tranches = Object.keys(grilleAct).map(Number).sort((a,b)=>a-b);
|
||
const tranche = findClosestTranche(capitalSaisi, tranches);
|
||
const miniData = grilleAct[tranche];
|
||
|
||
if (miniData && typeof miniData.miniRCC === 'number') {
|
||
maxMini = Math.max(maxMini, miniData.miniRCC);
|
||
}
|
||
}
|
||
});
|
||
return maxMini;
|
||
}
|
||
|
||
function getMaxMiniRCE(activites, cot) {
|
||
let maxMini = 0;
|
||
activites.forEach(act => {
|
||
// Récupérer l'input/select pour cette activité
|
||
const inputEl = document.querySelector(`input[name="selectAct${act}"], select[name="selectAct${act}"]`);
|
||
if (!inputEl) return;
|
||
|
||
const capitalSaisi = toNumber(inputEl.value);
|
||
if (capitalSaisi <= 0) return;
|
||
|
||
// Déterminer le type de cotisation
|
||
const cotType = cot === 'revisable' ? 'revisable' : 'forfaitaire';
|
||
|
||
// Trouver la tranche la plus proche
|
||
const grilleAct = modRCPrimeMini?.[cotType]?.[act];
|
||
if (grilleAct) {
|
||
const tranches = Object.keys(grilleAct).map(Number).sort((a,b)=>a-b);
|
||
const tranche = findClosestTranche(capitalSaisi, tranches);
|
||
const miniData = grilleAct[tranche];
|
||
|
||
if (miniData && typeof miniData.miniRCE === 'number') {
|
||
maxMini = Math.max(maxMini, miniData.miniRCE);
|
||
}
|
||
}
|
||
});
|
||
return maxMini;
|
||
}
|
||
|
||
|
||
function calcTarifRCC({
|
||
CA,
|
||
primeRCCbase,
|
||
primeRCEbase,
|
||
capitalTPPC,
|
||
nbVehicules,
|
||
coefTPPC,
|
||
franchiseCoef,
|
||
primeMini
|
||
}) {
|
||
// --- Prime RCC avec franchise ---
|
||
let primeFranchiseRCC = Number(primeRCCbase) * Number(franchiseCoef.modRCC || 1);
|
||
let primeFranchiseRCE = Number(primeRCEbase) * Number(franchiseCoef.modRCE || 1);
|
||
|
||
// --- Ajout TPPC APRÈS franchise ---
|
||
const primeTPPC = capitalTPPC * nbVehicules * coefTPPC;
|
||
primeFranchiseRCC = primeFranchiseRCC + primeTPPC;
|
||
|
||
// --- Calcul taux AVANT minima ---
|
||
let tauxRCC = CA > 0 ? (primeFranchiseRCC * 100 / CA).toFixed(2) : "0.00";
|
||
let tauxRCE = CA > 0 ? (primeFranchiseRCE * 100 / CA).toFixed(2) : "0.00";
|
||
|
||
// --- Application des minima ---
|
||
let isMiniRCC = false;
|
||
let isMiniRCE = false;
|
||
|
||
if (primeFranchiseRCC < primeMini[0]) {
|
||
tauxRCC = (primeFranchiseRCC * 100 / CA).toFixed(2); // Garder le taux avant mini
|
||
primeFranchiseRCC = primeMini[0];
|
||
isMiniRCC = true;
|
||
}
|
||
|
||
if (primeFranchiseRCE < primeMini[1]) {
|
||
tauxRCE = (primeFranchiseRCE * 100 / CA).toFixed(2); // Garder le taux avant mini
|
||
primeFranchiseRCE = primeMini[1];
|
||
isMiniRCE = true;
|
||
}
|
||
|
||
// --- Recalculer taux si PAS mini ---
|
||
if (!isMiniRCC && CA > 0) {
|
||
tauxRCC = (primeFranchiseRCC * 100 / CA).toFixed(2);
|
||
}
|
||
if (!isMiniRCE && CA > 0) {
|
||
tauxRCE = (primeFranchiseRCE * 100 / CA).toFixed(2);
|
||
}
|
||
|
||
// --- Prime totale ---
|
||
const primeTotale = primeFranchiseRCC + primeFranchiseRCE;
|
||
|
||
// --- Taux global ---
|
||
const tauxGlobal = CA > 0 ? ((primeTotale * 100 / CA).toFixed(2)) : "0.00";
|
||
|
||
return {
|
||
primeRCC: primeFranchiseRCC.toString(),
|
||
tauxRCC,
|
||
primeRCE: primeFranchiseRCE.toString(),
|
||
tauxRCE,
|
||
primeTotale: primeTotale.toString(),
|
||
tauxGlobal,
|
||
isMiniRCC,
|
||
isMiniRCE
|
||
};
|
||
}
|
||
|
||
|
||
function calcTarifettes(primePJ, CA, activites, capitalTPPC, nbVehicules, coefTPPC, primeRCCbase, primeRCEbase) {
|
||
const cards = [
|
||
{ key: "250", priceId: "priceFr250", rccId: "rccFr250", rceId: "rceFr250", pjId: "pjFr250", txRccId: "tauxRccFr250", txRceId: "tauxRceFr250", txGlobId: "tauxGlobalFr250" },
|
||
{ key: "400", priceId: "priceFr400", rccId: "rccFr400", rceId: "rceFr400", pjId: "pjFr400", txRccId: "tauxRccFr400", txRceId: "tauxRceFr400", txGlobId: "tauxGlobalFr400" },
|
||
{ key: "10% avec mini 300 € et maxi 2000", priceId: "priceFr2000", rccId: "rccFr2000", rceId: "rceFr2000", pjId: "pjFr2000", txRccId: "tauxRccFr2000", txRceId: "tauxRceFr2000", txGlobId: "tauxGlobalFr2000" },
|
||
];
|
||
|
||
// Déterminer le type de cotisation
|
||
const cot = document.querySelector('input[name="cotisation"]:checked')?.value || 'revisable';
|
||
const checkRCE = document.getElementById('checkRCE')?.checked || false;
|
||
const checkPJ = document.getElementById('checkPJ')?.checked || false;
|
||
|
||
const primeMini = [
|
||
getMaxMiniRCC(activites, cot),
|
||
getMaxMiniRCE(activites, cot)
|
||
];
|
||
|
||
cards.forEach(card => {
|
||
const mods = modRCFranchise[card.key] || { modRCC: 1, modRCE: 1 };
|
||
|
||
const result = calcTarifRCC({
|
||
CA,
|
||
primeRCCbase,
|
||
primeRCEbase,
|
||
capitalTPPC,
|
||
nbVehicules,
|
||
coefTPPC,
|
||
franchiseCoef: mods,
|
||
primeMini
|
||
});
|
||
|
||
// Calculer la PJ en fonction de la prime totale RCC+RCE
|
||
let primePJcalc = 0;
|
||
if (checkPJ) {
|
||
const primeTotaleAvantPJ = Number(result.primeRCC) + (checkRCE ? Number(result.primeRCE) : 0);
|
||
primePJcalc = calcPJ(primeTotaleAvantPJ);
|
||
}
|
||
|
||
// Prime totale finale avec PJ
|
||
const primeTotaleFinale = Number(result.primeRCC) + (checkRCE ? Number(result.primeRCE) : 0) + primePJcalc;
|
||
const tauxGlobalFinal = CA > 0 ? formatNumber((Number(result.primeRCC) + (checkRCE ? Number(result.primeRCE) : 0)) * 100 / CA, 2) : "0.000";
|
||
|
||
// Récupérer les éléments du DOM
|
||
const elPrice = document.getElementById(card.priceId);
|
||
const elRCC = document.getElementById(card.rccId);
|
||
const elRCE = document.getElementById(card.rceId);
|
||
const elPJ = document.getElementById(card.pjId);
|
||
const elTxRCC = document.getElementById(card.txRccId);
|
||
const elTxRCE = document.getElementById(card.txRceId);
|
||
const elTxGlob = document.getElementById(card.txGlobId);
|
||
|
||
// Récupérer les lignes parent pour masquer/afficher
|
||
const rowRCE = elRCE?.closest('p');
|
||
const rowTxRCE = elTxRCE?.closest('p');
|
||
const rowPJ = elPJ?.closest('p');
|
||
const rowTxGlob = elTxGlob?.closest('p');
|
||
|
||
// Afficher le prix total
|
||
if (elPrice) elPrice.innerText = formatNumber(primeTotaleFinale, 2) + ' €';
|
||
|
||
// Afficher Prime RCC (toujours visible)
|
||
if (elRCC) {
|
||
elRCC.innerText = formatNumber(result.primeRCC, 2) + " €" + (result.isMiniRCC ? " (Mini)" : "");
|
||
}
|
||
|
||
// Afficher Prime RCE uniquement si cochée ET > 0
|
||
if (rowRCE) {
|
||
if (checkRCE && result.primeRCE > 0) {
|
||
rowRCE.style.display = 'block';
|
||
if (elRCE) {
|
||
elRCE.innerText = formatNumber(result.primeRCE, 2) + " €" + (result.isMiniRCE ? " (Mini)" : "");
|
||
}
|
||
} else {
|
||
rowRCE.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// Afficher Prime PJ uniquement si cochée ET > 0
|
||
if (rowPJ) {
|
||
if (checkPJ && primePJcalc > 0) {
|
||
rowPJ.style.display = 'block';
|
||
if (elPJ) {
|
||
elPJ.innerText = formatNumber(primePJcalc, 2) + " €";
|
||
}
|
||
} else {
|
||
rowPJ.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// En forfaitaire, ne pas afficher les taux (uniquement des primes fixes)
|
||
if (cot === 'forfaitaire') {
|
||
// Masquer tous les taux en forfaitaire
|
||
if (elTxRCC?.closest('p')) elTxRCC.closest('p').style.display = 'none';
|
||
if (rowTxRCE) rowTxRCE.style.display = 'none';
|
||
if (rowTxGlob) rowTxGlob.style.display = 'none';
|
||
} else {
|
||
// En revisable, afficher les taux
|
||
if (elTxRCC?.closest('p')) {
|
||
elTxRCC.closest('p').style.display = 'block';
|
||
elTxRCC.innerText = formatNumber(result.tauxRCC, 2) + " %";
|
||
}
|
||
|
||
if (rowTxRCE) {
|
||
if (checkRCE && result.primeRCE > 0) {
|
||
rowTxRCE.style.display = 'block';
|
||
if (elTxRCE) {
|
||
elTxRCE.innerText = formatNumber(result.tauxRCE, 2) + " %";
|
||
}
|
||
} else {
|
||
rowTxRCE.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
if (rowTxGlob && CA > 0) {
|
||
rowTxGlob.style.display = 'block';
|
||
if (elTxGlob) {
|
||
elTxGlob.innerText = tauxGlobalFinal + " %";
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// Fonction pour calculer la PJ selon la prime totale
|
||
function calcPJ(primeTotale) {
|
||
let primePJ = 0;
|
||
const tablePJ = modRCGarAdd?.modRCC?.["Protection juridique"];
|
||
if (!tablePJ) return 0;
|
||
|
||
// Parcourir les tranches de PJ et prendre la plus grande tranche inférieure à la prime totale
|
||
const tranches = Object.keys(tablePJ).map(Number).sort((a, b) => a - b);
|
||
for (const tranche of tranches) {
|
||
if (primeTotale >= tranche) {
|
||
primePJ = tablePJ[tranche];
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
return primePJ;
|
||
}
|
||
|
||
|
||
|
||
function calcGlobal() {
|
||
// Vérification des pourcentages AVANT calcul
|
||
const allPourcentInputs = Array.from(document.querySelectorAll('.input-pourcent')).filter(p => p.offsetParent != null);
|
||
let totalPourcentCheck = 0;
|
||
allPourcentInputs.forEach(p => {
|
||
totalPourcentCheck += toNumber(p.value);
|
||
});
|
||
|
||
if (totalPourcentCheck > 100.01) {
|
||
// Total > 100% : BLOQUER tous les calculs
|
||
hideAllPrimes();
|
||
return;
|
||
}
|
||
|
||
const cot = document.querySelector('input[name="cotisation"]:checked')?.value;
|
||
let result = (cot === 'revisable') ? calcRevisable() : calcForfaitaire();
|
||
|
||
if (result) {
|
||
const capitalTPPCsaisi = toNumber(document.getElementById("selTPPCcapital")?.value);
|
||
const nbVehicules = toNumber(document.getElementById("selTPPCveh")?.value);
|
||
|
||
// Trouver la tranche TPPC la plus proche
|
||
let capitalTPPC = 0;
|
||
let coefTPPC = 0;
|
||
if (capitalTPPCsaisi > 0 && modRCGarAdd?.modRCC?.["TPPC"]) {
|
||
const tranches = Object.keys(modRCGarAdd.modRCC.TPPC).map(Number).sort((a,b)=>a-b);
|
||
capitalTPPC = findClosestTranche(capitalTPPCsaisi, tranches);
|
||
coefTPPC = modRCGarAdd.modRCC.TPPC[capitalTPPC] || 0;
|
||
}
|
||
|
||
calcTarifettes(result.primePJ, result.CA, result.activites, capitalTPPC, nbVehicules, coefTPPC, result.primeRCCbase, result.primeRCEbase);
|
||
}
|
||
}
|
||
|
||
function calcRevisable() {
|
||
// ========= Variables centrales (déclarées au début) =========
|
||
const capitalTPPCEl = document.getElementById("capital_TPPC");
|
||
const vehiculeTPPCEl = document.getElementById("vehicule_TPPC");
|
||
const coefTPPCEl = document.getElementById("garantie_prime_TPPC");
|
||
|
||
const capitalTPPC = toNumber(capitalTPPCEl?.value);
|
||
const nbVehicules = toNumber(vehiculeTPPCEl?.value);
|
||
const coefTPPC = toNumber(coefTPPCEl?.value) || 0.01;
|
||
let primeBaseRCC = 0;
|
||
let tauxBaseRCC = 0.000;
|
||
let primeRCC = 0;
|
||
let tauxRCC = 0.000;
|
||
let primeBaseRCE = 0;
|
||
let tauxBaseRCE = 0.000;
|
||
let primeRCE = 0;
|
||
let tauxRCE = 0.000;
|
||
let primePJ = 0;
|
||
let primeGlobal = 0;
|
||
let tauxGlobal = 0;
|
||
|
||
// Tableaux de travail par activité
|
||
let primeBaseRCCparAct = [];
|
||
let primeBaseRCEparAct = [];
|
||
|
||
// ========= Étape CA =========
|
||
const modCA = calcModCA(document.getElementById('chiffreAffaire').value);
|
||
document.getElementById('modCA').innerHTML =
|
||
'Mod. CA test :<br>x ' + modCA.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||
|
||
// ========= Étape Activités (taux base) =========
|
||
tauxBaseRCC = get_taux_base_RCC(modRCActRCC, "revisable");
|
||
if (document.getElementById('checkRCE').checked === true) {
|
||
tauxBaseRCE = get_taux_base_RCE(modRCActRCE, "revisable");
|
||
}
|
||
|
||
const CA = toNumber(document.getElementById("chiffreAffaire").value);
|
||
|
||
// ========= Calcul primes de base RCC =========
|
||
for (let i = 0; i < tauxBaseRCC.length; i++) {
|
||
const pourcentInput = toNumber(document.getElementById("pourcent" + tauxBaseRCC[i].typeActivite)?.value);
|
||
const primeBase = (tauxBaseRCC[i].tauxBase / 100 * pourcentInput / 100 * CA);
|
||
primeBaseRCCparAct.push({
|
||
typeActivite: tauxBaseRCC[i].typeActivite,
|
||
primeBase: primeBase
|
||
});
|
||
}
|
||
|
||
// ========= Calcul primes de base RCE si coché =========
|
||
if (document.getElementById('checkRCE').checked) {
|
||
for (let i = 0; i < tauxBaseRCE.length; i++) {
|
||
const pourcentInput = toNumber(document.getElementById("pourcent" + tauxBaseRCE[i].typeActivite)?.value);
|
||
const primeBase = (tauxBaseRCE[i].tauxBase / 100 * pourcentInput / 100 * CA);
|
||
primeBaseRCEparAct.push({
|
||
typeActivite: tauxBaseRCE[i].typeActivite,
|
||
primeBase: primeBase
|
||
});
|
||
}
|
||
}
|
||
|
||
// Sommes des primes de base (SANS mod CA)
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
// UI (affichage sans mod CA)
|
||
document.getElementById('primeChapActRCC').innerHTML =
|
||
'<span>Prime de base RCC : ' + primeBaseRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
|
||
document.getElementById('primeChapActRCE').innerHTML =
|
||
'<span>Prime de base RCE : ' + primeBaseRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
|
||
// ========= Étape Activités complémentaires =========
|
||
for (let i = 0; i < primeBaseRCCparAct.length; i++) {
|
||
primeBaseRCCparAct[i].primeBase *= calcModActCompl(modRCActCompl, primeBaseRCCparAct[i].typeActivite, "RCC", "revisable");
|
||
}
|
||
|
||
if (document.getElementById('checkRCE').checked) {
|
||
for (let i = 0; i < primeBaseRCEparAct.length; i++) {
|
||
primeBaseRCEparAct[i].primeBase *= calcModActCompl(
|
||
modRCActCompl,
|
||
primeBaseRCEparAct[i].typeActivite,
|
||
"RCE",
|
||
"revisable"
|
||
);
|
||
}
|
||
}
|
||
|
||
// Re-sommes (toujours sans mod CA)
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
document.getElementById('primeChapActComplRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeBaseRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapActComplRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeBaseRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Marchandises (× par activité) + Mod CA =========
|
||
const selections = getSelectedActivities();
|
||
|
||
for (let i = 0; i < primeBaseRCCparAct.length; i++) {
|
||
const actName = primeBaseRCCparAct[i].typeActivite;
|
||
const modMar = calcModMarchandises(modRCMar, actName, "RCC", "revisable");
|
||
// Appliquer marchandises ET CA ensemble
|
||
primeBaseRCCparAct[i].primeBase = primeBaseRCCparAct[i].primeBase * modMar * modCA;
|
||
}
|
||
|
||
if (document.getElementById('checkRCE').checked) {
|
||
for (let i = 0; i < primeBaseRCEparAct.length; i++) {
|
||
const actName = primeBaseRCEparAct[i].typeActivite;
|
||
const modMar = calcModMarchandises(modRCMar, actName, "RCE", "revisable");
|
||
// Appliquer marchandises ET CA ensemble
|
||
primeBaseRCEparAct[i].primeBase = primeBaseRCEparAct[i].primeBase * modMar * modCA;
|
||
}
|
||
}
|
||
|
||
// Recalcule totaux apres mods marchandises + CA
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
// Maintenant primeRCC et primeRCE incluent déjà le mod CA
|
||
primeRCC = primeBaseRCC;
|
||
primeRCE = primeBaseRCE;
|
||
|
||
// UI marchandises
|
||
document.getElementById('primeChapMarchRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapMarchRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Zones (× max RCC / × max RCE) =========
|
||
const { mRCC, mRCE } = getZoneMods(modRCZone);
|
||
primeRCC *= mRCC;
|
||
primeRCE *= mRCE;
|
||
|
||
// UI zones
|
||
document.getElementById('primeChapZonesRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapZonesRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Engagements complémentaires (×) =========
|
||
const result = calcEngagCompl(modRCEngagCompl, primeRCC);
|
||
primeRCC = result.prime;
|
||
|
||
// UI engagements
|
||
document.getElementById('primeEngValue').innerText =
|
||
'Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
const infoContainer = document.getElementById('primeEngInfos');
|
||
infoContainer.innerHTML = "";
|
||
result.infos.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
infoContainer.appendChild(p);
|
||
}); // non necessaire, mais garder si utile, car fonctionne a 100%
|
||
|
||
// ========= Étape Garanties additionnelles (RCE uniquement) =========
|
||
const garAdd = calcGarAdd(modRCGarAdd, primeRCC, primeRCE);
|
||
// primeRCC reste inchangée (TPPC appliquée plus tard)
|
||
primeRCE = garAdd.primeRCE; // RCE avec Station lavage, Garage, CSE
|
||
|
||
// UI RCC
|
||
const blocRCC = document.getElementById('primeChapGarAddRCC');
|
||
blocRCC.innerHTML = '<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
garAdd.infosRCC.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
blocRCC.appendChild(p);
|
||
});// toujours inutile, pas necessaire
|
||
|
||
// UI RCE
|
||
const blocRCE = document.getElementById('primeChapGarAddRCE');
|
||
blocRCE.innerHTML = '<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
garAdd.infosRCE.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
blocRCE.appendChild(p);
|
||
}); // toujours inutile, pas necessaire
|
||
|
||
// ========= Étape Sinistres =========
|
||
const sin = calcSinistre(modRCSinistre, primeRCC, primeRCE);
|
||
primeRCC = sin.primeRCC;
|
||
primeRCE = sin.primeRCE;
|
||
|
||
// ========= Sauvegarder les primes BASE pour les tarifettes (après sinistre, avant franchise) =========
|
||
const primeRCCavantFranchise = primeRCC;
|
||
const primeRCEavantFranchise = primeRCE;
|
||
|
||
// Les totaux RCC et RCE sont maintenant prêts pour les franchises
|
||
const totalRCC = primeRCC;
|
||
const totalRCE = primeRCE;
|
||
|
||
// PJ (calculée dans calcTarifettes selon prime totale)
|
||
primePJ = 0;
|
||
|
||
primeGlobal = totalRCC + totalRCE + primePJ;
|
||
|
||
// UI
|
||
document.getElementById('modCA').innerHTML =
|
||
'Modulation CA :<br>x ' + modCA.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||
|
||
const activiteMap = {
|
||
"Voiturier / Loueur": "Voiturier/Loueur",
|
||
"Commissionnaire de Transport": "Commissionnaire de Transport",
|
||
"Déménageur": "Déménageur",
|
||
"Logistique": "Logistique",
|
||
"Autocariste": "Autocariste",
|
||
"Autres activites": "Autres activites"
|
||
};
|
||
|
||
function getSelectedActivites() {
|
||
const activites = [];
|
||
document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => {
|
||
const span = cb.parentElement.querySelector('span');
|
||
if (span) {
|
||
const labelText = span.textContent.trim();
|
||
if (activiteMap[labelText]) {
|
||
activites.push(activiteMap[labelText]);
|
||
}
|
||
}
|
||
});
|
||
return activites;
|
||
}
|
||
|
||
|
||
const activites = getSelectedActivites();
|
||
|
||
return {
|
||
CA,
|
||
activites,
|
||
primeRCC: totalRCC,
|
||
primeRCE: totalRCE,
|
||
primeRCCbase: primeRCCavantFranchise,
|
||
primeRCEbase: primeRCEavantFranchise,
|
||
primePJ,
|
||
primeGlobal
|
||
};
|
||
}
|
||
|
||
function calcForfaitaire() {
|
||
// ========= Variables centrales =========
|
||
let primeBaseRCC = 0;
|
||
let primeBaseRCE = 0;
|
||
let primeRCC = 0;
|
||
let primeRCE = 0;
|
||
let primePJ = 0;
|
||
let primeGlobal = 0;
|
||
|
||
// Tableaux de travail par activité
|
||
let primeBaseRCCparAct = [];
|
||
let primeBaseRCEparAct = [];
|
||
|
||
// ========= Récupération du nombre de véhicules =========
|
||
const nbrVehicule = toNumber(document.getElementById('nbrVehicule')?.value);
|
||
// Déterminer si c'est 1 ou 2 véhicules (par défaut 1)
|
||
const nbVehiculeKey = (nbrVehicule === 2) ? "deuxVehicules" : "unVehicule";
|
||
|
||
// ========= Étape Activités (primes forfaitaires de base) =========
|
||
const selections = getSelectedActivities();
|
||
|
||
selections.forEach(activity => {
|
||
const typeActivite = activity.typeActivite;
|
||
const inputElement = document.querySelector(
|
||
`input[name="selectAct${typeActivite}"], select[name="selectAct${typeActivite}"]`
|
||
);
|
||
|
||
if (inputElement) {
|
||
const capitalSaisi = toNumber(inputElement.value);
|
||
|
||
if (capitalSaisi <= 0) {
|
||
return; // Skip cette activité
|
||
}
|
||
|
||
// Récupération de la prime forfaitaire RCC
|
||
const grilleActRCC = modRCActRCC.forfaitaire[typeActivite];
|
||
if (grilleActRCC) {
|
||
const tranches = Object.keys(grilleActRCC).map(Number).sort((a, b) => a - b);
|
||
const tranche = findClosestTranche(capitalSaisi, tranches);
|
||
const primeData = grilleActRCC[tranche];
|
||
|
||
if (primeData && typeof primeData[nbVehiculeKey] === 'number') {
|
||
const primeBase = primeData[nbVehiculeKey];
|
||
primeBaseRCCparAct.push({
|
||
typeActivite: typeActivite,
|
||
primeBase: primeBase
|
||
});
|
||
|
||
// Affichage du taux (ici c'est une prime fixe)
|
||
const rccDiv = document.getElementById("tauxBaseRCCact" + typeActivite);
|
||
if (rccDiv) {
|
||
rccDiv.innerText = "RCC : " + primeBase.toFixed(2) + " €";
|
||
}
|
||
|
||
// Info tranche si différente
|
||
if (capitalSaisi !== tranche) {
|
||
const rowDiv = inputElement.closest('.row');
|
||
if (rowDiv) {
|
||
const oldInfo = rowDiv.querySelector('.info-tranche');
|
||
if (oldInfo) oldInfo.remove();
|
||
|
||
const infoSpan = document.createElement('span');
|
||
infoSpan.className = 'info-tranche';
|
||
infoSpan.style.color = '#e53935';
|
||
infoSpan.style.fontSize = '0.8em';
|
||
infoSpan.style.fontStyle = 'italic';
|
||
infoSpan.innerText = `(tranche ${tranche.toLocaleString('fr-FR')} €)`;
|
||
|
||
rowDiv.appendChild(infoSpan);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Récupération de la prime forfaitaire RCE si coché
|
||
if (document.getElementById('checkRCE')?.checked) {
|
||
const grilleActRCE = modRCActRCE.forfaitaire[typeActivite];
|
||
if (grilleActRCE && grilleActRCE[nbVehiculeKey]) {
|
||
const primeBaseRCE_val = grilleActRCE[nbVehiculeKey].optimale || 0;
|
||
primeBaseRCEparAct.push({
|
||
typeActivite: typeActivite,
|
||
primeBase: primeBaseRCE_val
|
||
});
|
||
|
||
// Affichage
|
||
const rceDiv = document.getElementById("tauxBaseRCEact" + typeActivite);
|
||
if (rceDiv) {
|
||
rceDiv.innerText = "RCE : " + primeBaseRCE_val.toFixed(2) + " €";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Sommes des primes de base
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
// UI (affichage)
|
||
document.getElementById('primeChapActRCC').innerHTML =
|
||
'<span>Prime de base RCC : ' + primeBaseRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
|
||
document.getElementById('primeChapActRCE').innerHTML =
|
||
'<span>Prime de base RCE : ' + primeBaseRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
|
||
// ========= Étape Activités complémentaires =========
|
||
for (let i = 0; i < primeBaseRCCparAct.length; i++) {
|
||
primeBaseRCCparAct[i].primeBase *= calcModActCompl(modRCActCompl, primeBaseRCCparAct[i].typeActivite, "RCC", "forfaitaire");
|
||
}
|
||
|
||
if (document.getElementById('checkRCE')?.checked) {
|
||
for (let i = 0; i < primeBaseRCEparAct.length; i++) {
|
||
primeBaseRCEparAct[i].primeBase *= calcModActCompl(
|
||
modRCActCompl,
|
||
primeBaseRCEparAct[i].typeActivite,
|
||
"RCE",
|
||
"forfaitaire"
|
||
);
|
||
}
|
||
}
|
||
|
||
// Re-sommes
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
document.getElementById('primeChapActComplRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeBaseRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapActComplRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeBaseRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Marchandises (× par activité) =========
|
||
for (let i = 0; i < primeBaseRCCparAct.length; i++) {
|
||
const actName = primeBaseRCCparAct[i].typeActivite;
|
||
const modMar = calcModMarchandises(modRCMar, actName, "RCC", "forfaitaire");
|
||
primeBaseRCCparAct[i].primeBase = primeBaseRCCparAct[i].primeBase * modMar;
|
||
}
|
||
|
||
if (document.getElementById('checkRCE')?.checked) {
|
||
for (let i = 0; i < primeBaseRCEparAct.length; i++) {
|
||
const actName = primeBaseRCEparAct[i].typeActivite;
|
||
const modMar = calcModMarchandises(modRCMar, actName, "RCE", "forfaitaire");
|
||
primeBaseRCEparAct[i].primeBase = primeBaseRCEparAct[i].primeBase * modMar;
|
||
}
|
||
}
|
||
|
||
// Recalcule totaux après mods marchandises
|
||
primeBaseRCC = primeBaseRCCparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
primeBaseRCE = primeBaseRCEparAct.reduce((total, item) => total + item.primeBase, 0);
|
||
|
||
primeRCC = primeBaseRCC;
|
||
primeRCE = primeBaseRCE;
|
||
|
||
// UI marchandises
|
||
document.getElementById('primeChapMarchRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapMarchRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Zones (× max RCC / × max RCE) =========
|
||
const { mRCC, mRCE } = getZoneMods(modRCZone);
|
||
primeRCC *= mRCC;
|
||
primeRCE *= mRCE;
|
||
|
||
// UI zones
|
||
document.getElementById('primeChapZonesRCC').innerHTML =
|
||
'<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
document.getElementById('primeChapZonesRCE').innerHTML =
|
||
'<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
// ========= Étape Engagements complémentaires (×) =========
|
||
const result = calcEngagCompl(modRCEngagCompl, primeRCC);
|
||
primeRCC = result.prime;
|
||
|
||
// UI engagements
|
||
document.getElementById('primeEngValue').innerText =
|
||
'Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' });
|
||
|
||
const infoContainer = document.getElementById('primeEngInfos');
|
||
infoContainer.innerHTML = "";
|
||
result.infos.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
infoContainer.appendChild(p);
|
||
});
|
||
|
||
// ========= Étape Garanties additionnelles (RCE uniquement) =========
|
||
const garAdd = calcGarAdd(modRCGarAdd, primeRCC, primeRCE);
|
||
primeRCE = garAdd.primeRCE;
|
||
|
||
// UI RCC
|
||
const blocRCC = document.getElementById('primeChapGarAddRCC');
|
||
blocRCC.innerHTML = '<span>Prime RCC : ' + primeRCC.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
garAdd.infosRCC.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
blocRCC.appendChild(p);
|
||
});
|
||
|
||
// UI RCE
|
||
const blocRCE = document.getElementById('primeChapGarAddRCE');
|
||
blocRCE.innerHTML = '<span>Prime RCE : ' + primeRCE.toLocaleString('fr-FR', { style: 'currency', currency: 'EUR' }) + '</span>';
|
||
garAdd.infosRCE.forEach(msg => {
|
||
const p = document.createElement("p");
|
||
p.style.color = "#e53935";
|
||
p.style.fontWeight = "300";
|
||
p.style.fontSize = "0.85em";
|
||
p.style.marginTop = "5px";
|
||
p.style.fontStyle = "italic";
|
||
p.innerText = msg;
|
||
blocRCE.appendChild(p);
|
||
});
|
||
|
||
// ========= Étape Sinistres (OPTIONNEL en forfaitaire - basé sur CA) =========
|
||
// Note: En forfaitaire, normalement pas de sinistre car pas de CA
|
||
// Mais on garde la logique au cas où il y aurait un CA saisi
|
||
const CA = toNumber(document.getElementById("chiffreAffaire")?.value);
|
||
if (CA > 0) {
|
||
const sin = calcSinistre(modRCSinistre, primeRCC, primeRCE);
|
||
primeRCC = sin.primeRCC;
|
||
primeRCE = sin.primeRCE;
|
||
}
|
||
|
||
// ========= Sauvegarder les primes BASE pour les tarifettes =========
|
||
const primeRCCavantFranchise = primeRCC;
|
||
const primeRCEavantFranchise = primeRCE;
|
||
|
||
// Les totaux RCC et RCE sont maintenant prêts
|
||
const totalRCC = primeRCC;
|
||
const totalRCE = primeRCE;
|
||
|
||
// PJ (calculée dans calcTarifettes selon prime totale)
|
||
primePJ = 0;
|
||
|
||
primeGlobal = totalRCC + totalRCE + primePJ;
|
||
|
||
const activiteMap = {
|
||
"Voiturier / Loueur": "Voiturier/Loueur",
|
||
"Commissionnaire de Transport": "Commissionnaire de Transport",
|
||
"Déménageur": "Déménageur",
|
||
"Logistique": "Logistique",
|
||
"Autocariste": "Autocariste",
|
||
"Autres activites": "Autres activites"
|
||
};
|
||
|
||
function getSelectedActivites() {
|
||
const activites = [];
|
||
document.querySelectorAll('label input[type="checkbox"]:checked').forEach(cb => {
|
||
const span = cb.parentElement.querySelector('span');
|
||
if (span) {
|
||
const labelText = span.textContent.trim();
|
||
if (activiteMap[labelText]) {
|
||
activites.push(activiteMap[labelText]);
|
||
}
|
||
}
|
||
});
|
||
return activites;
|
||
}
|
||
|
||
const activites = getSelectedActivites();
|
||
|
||
return {
|
||
CA: CA || 0,
|
||
activites,
|
||
primeRCC: totalRCC,
|
||
primeRCE: totalRCE,
|
||
primeRCCbase: primeRCCavantFranchise,
|
||
primeRCEbase: primeRCEavantFranchise,
|
||
primePJ,
|
||
primeGlobal
|
||
};
|
||
}
|
||
|
||
function getZoneMods(modRCZone) {
|
||
const zones = [
|
||
{ id: 'zone1', label: 'France Métropolitaine et pays limitrophes' },
|
||
{ id: 'zone2', label: 'Union Européenne' },
|
||
{ id: 'zone3', label: 'Autres pays européens sauf Russie et Ukraine (y compris UK et Norvège)' },
|
||
{ id: 'zone4', label: 'Pays du Maghreb et Amérique du Nord ( USA / Canada / Mexique )' },
|
||
{ id: 'zone5', label: 'Amérique Centrale et Sud / Caraïbes, Asie et Océanie' },
|
||
{ id: 'zone6', label: 'Afrique Hors Maghreb / Proche Orient / Moyen Orient' }
|
||
];
|
||
let mRCC = 1, mRCE = 1;
|
||
zones.forEach(z => {
|
||
const cb = document.getElementById(z.id);
|
||
if (cb && cb.checked) {
|
||
const m = modRCZone[z.label];
|
||
if (m) {
|
||
if (typeof m.modRCC === 'number') mRCC = Math.max(mRCC, m.modRCC);
|
||
if (typeof m.modRCE === 'number') mRCE = Math.max(mRCE, m.modRCE);
|
||
}
|
||
}
|
||
});
|
||
return { mRCC, mRCE };
|
||
}
|
||
|
||
|
||
function handleLoadHistoriqueBtn() {
|
||
var selectedId = document.getElementById('idSelect').value;
|
||
|
||
if (selectedId != "") {
|
||
fetch(`/contrat/update/${contrat.produit}/${contrat.id}/${selectedId}`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.valid) {
|
||
window.location.href = `/navParcours?numParcours=${getNumParcoursFromURL()}&submenu=projet`;
|
||
} else {
|
||
console.log('Echec lors de la mise à jour de la relation id contrat - id client :', data);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
//Appel pour recevoir les constantes
|
||
async function constantsJSON() {
|
||
try {
|
||
const responsesJSON = await Promise.all([
|
||
fetch('/rc/modulo/CARC'),
|
||
fetch('/rc/modulo/activiteRCC'),
|
||
fetch('/rc/modulo/activiteRCE'),
|
||
fetch('/rc/modulo/activiteComplRC'),
|
||
fetch('/rc/modulo/marchandiseRC'),
|
||
fetch('/rc/modulo/zoneRC'),
|
||
fetch('/rc/modulo/engagComplRC'),
|
||
fetch('/rc/modulo/garAdditionelRC'),
|
||
fetch('/rc/modulo/sinistreRC'),
|
||
fetch('/rc/modulo/franchiseRC'),
|
||
fetch('/rc/modulo/primeMiniRC')
|
||
]);
|
||
const jsonResponses = await Promise.all(responsesJSON.map(r => r.json())); // Récupérer toutes les réponses JSON
|
||
|
||
// Extraire la valeur objRetourne de chaque réponse
|
||
[
|
||
modRCCA,
|
||
modRCActRCC,
|
||
modRCActRCE,
|
||
modRCActCompl,
|
||
modRCMar,
|
||
modRCZone,
|
||
modRCEngagCompl,
|
||
modRCGarAdd,
|
||
modRCSinistre,
|
||
modRCFranchise,
|
||
modRCPrimeMini
|
||
] = jsonResponses.map(response => response.objRetourne); // Adapter pour extraire objRetourne
|
||
} catch (err) {
|
||
throw err;
|
||
}
|
||
}
|
||
|
||
function resetInputs() {
|
||
// Sélection des éléments input pourcentage
|
||
const pourcentInputs = document.querySelectorAll('.input-pourcent');
|
||
// Calculer le nombre d'inputs visibles
|
||
const visibleInputs = Array.from(pourcentInputs).filter(input => input.offsetParent != null);
|
||
|
||
// Vérifier s'il y a des inputs visibles
|
||
if (visibleInputs.length > 0) {
|
||
// Réinitialiser les valeurs
|
||
visibleInputs.forEach(p => {
|
||
p.value = ''; // Réinitialiser la valeur
|
||
const correspondingIsSetInput = document.getElementById('isSet' + p.id.replace('pourcent', ''));
|
||
correspondingIsSetInput.value = 'false'; // Réinitialiser isSet
|
||
p.classList.remove('set'); // Remettre le fond d'origine
|
||
});
|
||
|
||
// Calculer le pourcentage à répartir
|
||
const pourcentToAdd = (100 / visibleInputs.length).toFixed(2);
|
||
|
||
// Répartir le pourcentage entre les inputs visibles
|
||
visibleInputs.forEach(p => {
|
||
p.value = pourcentToAdd; // Assigner la valeur calculée
|
||
// Ne pas changer isSet à true ici
|
||
// correspondingIsSetInput.value reste 'false'
|
||
});
|
||
|
||
// Mettre à jour l'indicateur
|
||
updatePercentageIndicator(100);
|
||
}
|
||
}
|
||
|
||
function get_taux_base_RCC(grille_mod_RCC, cot) {
|
||
const tauxOptimaux = [];
|
||
const selections = getSelectedActivities();
|
||
|
||
selections.forEach(activity => {
|
||
const typeActivite = activity.typeActivite;
|
||
const inputElement = document.querySelector(
|
||
`input[name="selectAct${typeActivite}"], select[name="selectAct${typeActivite}"]`
|
||
);
|
||
|
||
if (inputElement) {
|
||
const capitalSaisi = toNumber(inputElement.value);
|
||
|
||
if (capitalSaisi <= 0) {
|
||
return;
|
||
}
|
||
|
||
if (cot === 'revisable') {
|
||
const grilleAct = grille_mod_RCC.revisable[typeActivite];
|
||
if (grilleAct) {
|
||
const tranches = Object.keys(grilleAct).map(Number).sort((a, b) => a - b);
|
||
const tranche = findClosestTranche(capitalSaisi, tranches);
|
||
const tauxBase = grilleAct[tranche];
|
||
|
||
if (typeof tauxBase === 'number') {
|
||
// 1. Mettre à jour la div RCC avec uniquement le texte principal
|
||
const rccDiv = document.getElementById("tauxBaseRCCact" + typeActivite);
|
||
if (rccDiv) {
|
||
rccDiv.innerText = "RCC : " + tauxBase.toFixed(3) + " %";
|
||
}
|
||
if (capitalSaisi !== tranche) {
|
||
const rowDiv = inputElement.closest('.row');
|
||
if (rowDiv) {
|
||
const oldInfo = rowDiv.querySelector('.info-tranche');
|
||
if (oldInfo) oldInfo.remove();
|
||
|
||
const infoSpan = document.createElement('span');
|
||
infoSpan.className = 'info-tranche';
|
||
infoSpan.style.color = '#e53935';
|
||
infoSpan.style.fontSize = '0.8em';
|
||
infoSpan.style.fontStyle = 'italic';
|
||
infoSpan.innerText = `(tranche ${tranche.toLocaleString('fr-FR')} €)`;
|
||
|
||
rowDiv.appendChild(infoSpan);
|
||
}
|
||
}
|
||
|
||
tauxOptimaux.push({ typeActivite, capital: tranche, tauxBase });
|
||
}
|
||
}
|
||
} else if (cot === 'forfaitaire') {
|
||
console.log("TODO FORFAITAIRE");
|
||
}
|
||
}
|
||
});
|
||
|
||
return tauxOptimaux;
|
||
}
|
||
|
||
|
||
function get_taux_base_RCE(grille_mod_RCE, cot) {
|
||
const tauxOptimaux = [];
|
||
const selections = getSelectedActivities();
|
||
|
||
selections.forEach(activity => {
|
||
const typeActivite = activity.typeActivite;
|
||
const inputElement = document.querySelector(`input[name="selectAct${typeActivite}"], select[name="selectAct${typeActivite}"]`);
|
||
|
||
if (inputElement) {
|
||
const capitalSaisi = toNumber(inputElement.value);
|
||
|
||
// Si rien n'est saisi ou invalide, ignorer
|
||
if (capitalSaisi <= 0) {
|
||
return;
|
||
}
|
||
|
||
// Traitement selon le type de cotisation
|
||
if (cot == 'revisable') {
|
||
if (grille_mod_RCE.revisable[typeActivite]) {
|
||
const tauxBase = grille_mod_RCE.revisable[typeActivite]["optimale"];
|
||
document.getElementById("tauxBaseRCEact" + typeActivite).innerHTML = "RCE : " + tauxBase.toFixed(3) + " %"
|
||
tauxOptimaux.push({ typeActivite, tauxBase });
|
||
}
|
||
} else if (cot == 'forfaitaire') {
|
||
console.log("TODO FORFAITAIRE"); // ehhh
|
||
}
|
||
}
|
||
});
|
||
|
||
return tauxOptimaux;
|
||
}
|
||
|
||
function getSelectedActivities() {
|
||
const selections = [];
|
||
|
||
// Récupérer le nombre de véhicules depuis l'input
|
||
const nombreVehicules = document.getElementById('nbrVehicule').value || null; // Valeur par défaut à null si vide
|
||
|
||
if (document.getElementById('checkVoiturier').checked) {
|
||
const listActComplChecked = [];
|
||
const listMarChecked = [];
|
||
|
||
// Récupérer les activités complémentaires
|
||
const actComplCheckboxes = document.querySelectorAll('[name="actComplVoiturier/Loueur"] input[type="checkbox"]:checked');
|
||
actComplCheckboxes.forEach(checkbox => {
|
||
listActComplChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
// Récupérer les marchandises
|
||
const marComplCheckboxes = document.querySelectorAll('[name="marVoiturier/Loueur"] input[type="checkbox"]:checked');
|
||
marComplCheckboxes.forEach(checkbox => {
|
||
listMarChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
selections.push({
|
||
typeActivite: "Voiturier/Loueur",
|
||
nombreVehicules: nombreVehicules,
|
||
listActComplChecked: listActComplChecked,
|
||
listMarChecked: listMarChecked
|
||
});
|
||
}
|
||
|
||
if (document.getElementById('checkCommissionnaire').checked) {
|
||
const listActComplChecked = [];
|
||
const listMarChecked = [];
|
||
|
||
// Récupérer les activités complémentaires
|
||
const actComplCheckboxes = document.querySelectorAll('[name="actComplCommissionnaire de Transport"] input[type="checkbox"]:checked');
|
||
actComplCheckboxes.forEach(checkbox => {
|
||
listActComplChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
// Récupérer les marchandises
|
||
const marComplCheckboxes = document.querySelectorAll('[name="marCommissionnaire de Transport"] input[type="checkbox"]:checked');
|
||
marComplCheckboxes.forEach(checkbox => {
|
||
listMarChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
selections.push({
|
||
typeActivite: "Commissionnaire de Transport",
|
||
nombreVehicules: null,
|
||
listActComplChecked: listActComplChecked,
|
||
listMarChecked: listMarChecked
|
||
});
|
||
}
|
||
|
||
if (document.getElementById('checkDemenageur').checked) {
|
||
const listActComplChecked = [];
|
||
const listMarChecked = [];
|
||
|
||
// Récupérer les activités complémentaires
|
||
const actComplCheckboxes = document.querySelectorAll('[name="actComplDéménageur"] input[type="checkbox"]:checked');
|
||
actComplCheckboxes.forEach(checkbox => {
|
||
listActComplChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
// Récupérer les marchandises
|
||
const marComplCheckboxes = document.querySelectorAll('[name="marDéménageur"] input[type="checkbox"]:checked');
|
||
marComplCheckboxes.forEach(checkbox => {
|
||
listMarChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
selections.push({
|
||
typeActivite: "Déménageur",
|
||
nombreVehicules: nombreVehicules,
|
||
listActComplChecked: listActComplChecked,
|
||
listMarChecked: listMarChecked
|
||
});
|
||
}
|
||
|
||
if (document.getElementById('checkLogistique').checked) {
|
||
const listActComplChecked = [];
|
||
const listMarChecked = [];
|
||
|
||
// Récupérer les activités complémentaires
|
||
const actComplCheckboxes = document.querySelectorAll('[name="actComplLogistique"] input[type="checkbox"]:checked');
|
||
actComplCheckboxes.forEach(checkbox => {
|
||
listActComplChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
// Récupérer les marchandises
|
||
const marComplCheckboxes = document.querySelectorAll('[name="marLogistique"] input[type="checkbox"]:checked');
|
||
marComplCheckboxes.forEach(checkbox => {
|
||
listMarChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
selections.push({
|
||
typeActivite: "Logistique",
|
||
nombreVehicules: null,
|
||
listActComplChecked: listActComplChecked,
|
||
listMarChecked: listMarChecked
|
||
});
|
||
}
|
||
|
||
if (document.getElementById('checkAutres').checked) {
|
||
const listActComplChecked = [];
|
||
const listMarChecked = [];
|
||
|
||
// Récupérer les activités complémentaires
|
||
const actComplCheckboxes = document.querySelectorAll('[name="actComplAutres activites"] input[type="checkbox"]:checked');
|
||
actComplCheckboxes.forEach(checkbox => {
|
||
listActComplChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
// Récupérer les marchandises
|
||
const marComplCheckboxes = document.querySelectorAll('[name="marAutres activites"] input[type="checkbox"]:checked');
|
||
marComplCheckboxes.forEach(checkbox => {
|
||
listMarChecked.push(checkbox.nextElementSibling.textContent.trim());
|
||
});
|
||
|
||
selections.push({
|
||
typeActivite: "Autres activites",
|
||
nombreVehicules: nombreVehicules,
|
||
listActComplChecked: listActComplChecked,
|
||
listMarChecked: listMarChecked
|
||
});
|
||
}
|
||
// Ajoutez d'autres cas si nécessaire
|
||
|
||
return selections;
|
||
}
|
||
|
||
// Fonction pour sauvegarder les données tarifRC dans la base
|
||
async function saveTarifRC() {
|
||
if (!rc || !contrat) {
|
||
console.error('Données manquantes pour sauvegarder le tarif RC');
|
||
return { valid: false, message: 'Données manquantes' };
|
||
}
|
||
|
||
// Préparer les références aux champs selon les différents templates possibles
|
||
const caInput = getElementByIdFlexible('CA') || getElementByIdFlexible('chiffreAffaire');
|
||
const nbVehInput = getElementByIdFlexible('nbVehicules') || getElementByIdFlexible('nbrVehicule');
|
||
|
||
const capitalVoiturierInput = getElementByIdFlexible('capitalVoiturier') || document.querySelector('input[name="selectActVoiturier/Loueur"]');
|
||
const capitalCommissionnaireInput = getElementByIdFlexible('capitalCommissionnaire') || document.querySelector('input[name="selectActCommissionnaire de Transport"]') || document.querySelector('input[name="selectActCommissionnaireDeTransport"]');
|
||
const capitalDemenageurInput = getElementByIdFlexible('capitalDemenageur') || document.querySelector('input[name="selectActDéménageur"]') || document.querySelector('input[name="selectActDemenageur"]');
|
||
const capitalLogistiqueInput = getElementByIdFlexible('capitalLogistique') || document.querySelector('input[name="selectActLogistique"]');
|
||
const capitalAutocaristeInput = getElementByIdFlexible('capitalAutocariste') || document.querySelector('input[name="selectActAutocariste"]');
|
||
const capitalAutresInput = getElementByIdFlexible('capitalAutres') || document.querySelector('input[name="selectActAutres activites"]') || document.querySelector('input[name="selectActAutresActivites"]');
|
||
|
||
const pctVoiturierInput = getElementByIdFlexible('pourcent_voiturier') || getElementByIdFlexible('pourcentVoiturier/Loueur');
|
||
const pctCommissionnaireInput = getElementByIdFlexible('pourcent_commissionnaire') || getElementByIdFlexible('pourcentCommissionnaire de Transport') || getElementByIdFlexible('pourcentCommissionnaireDeTransport');
|
||
const pctDemenageurInput = getElementByIdFlexible('pourcent_demenageur') || getElementByIdFlexible('pourcentDéménageur') || getElementByIdFlexible('pourcentDemenageur');
|
||
const pctLogistiqueInput = getElementByIdFlexible('pourcent_logistique') || getElementByIdFlexible('pourcentLogistique');
|
||
const pctAutocaristeInput = getElementByIdFlexible('pourcent_autocariste') || getElementByIdFlexible('pourcentAutocariste');
|
||
const pctAutresInput = getElementByIdFlexible('pourcent_autres') || getElementByIdFlexible('pourcentAutres activites') || getElementByIdFlexible('pourcentAutresActivites');
|
||
|
||
// ===== ÉTAPE 1: Collecter les données communes à sauvegarder dans RC principal =====
|
||
const rcMainData = {
|
||
typeCotisation: document.querySelector('input[name="cotisation"]:checked')?.value,
|
||
chiffreAffaires: toNumber(caInput?.value ?? caInput?.textContent),
|
||
nombreVehicules: Math.max(0, Math.round(toNumber(nbVehInput?.value ?? nbVehInput?.textContent))),
|
||
checkRCE: document.getElementById('checkRCE')?.checked || false,
|
||
checkVoiturier: document.getElementById('checkVoiturier')?.checked || false,
|
||
capitalVoiturier: toNumber(capitalVoiturierInput?.value ?? capitalVoiturierInput?.textContent),
|
||
checkCommissionnaire: document.getElementById('checkCommissionnaire')?.checked || false,
|
||
capitalCommissionnaire: toNumber(capitalCommissionnaireInput?.value ?? capitalCommissionnaireInput?.textContent),
|
||
checkDemenageur: document.getElementById('checkDemenageur')?.checked || false,
|
||
capitalDemenageur: toNumber(capitalDemenageurInput?.value ?? capitalDemenageurInput?.textContent),
|
||
checkLogistique: document.getElementById('checkLogistique')?.checked || false,
|
||
capitalLogistique: toNumber(capitalLogistiqueInput?.value ?? capitalLogistiqueInput?.textContent),
|
||
checkAutocariste: document.getElementById('checkAutocariste')?.checked || false,
|
||
capitalAutocariste: toNumber(capitalAutocaristeInput?.value ?? capitalAutocaristeInput?.textContent),
|
||
checkAutres: document.getElementById('checkAutres')?.checked || false,
|
||
capitalAutres: toNumber(capitalAutresInput?.value ?? capitalAutresInput?.textContent),
|
||
|
||
// Activités complémentaires (JSON) - collectées avec les bons noms
|
||
actComplVoiturier: collectActivitesComplJSON('voiturier'),
|
||
actComplCommissionnaire: collectActivitesComplJSON('commissionnaire'),
|
||
actComplDemenageur: collectActivitesComplJSON('demenageur'),
|
||
actComplLogistique: collectActivitesComplJSON('logistique'),
|
||
|
||
// Marchandises (JSON) - collectées avec les bons noms
|
||
marchandisesVoiturier: collectMarchandisesJSON('voiturier'),
|
||
marchandisesCommissionnaire: collectMarchandisesJSON('commissionnaire'),
|
||
marchandisesDemenageur: collectMarchandisesJSON('demenageur'),
|
||
marchandisesLogistique: collectMarchandisesJSON('logistique'),
|
||
marchandisesAutocariste: collectMarchandisesJSON('autocariste'),
|
||
marchandisesAutres: collectMarchandisesJSON('autres'),
|
||
|
||
// Zones
|
||
zone1: document.getElementById('zone1')?.checked || false,
|
||
zone2: document.getElementById('zone2')?.checked || false,
|
||
zone3: document.getElementById('zone3')?.checked || false,
|
||
zone4: document.getElementById('zone4')?.checked || false,
|
||
zone5: document.getElementById('zone5')?.checked || false,
|
||
zone6: document.getElementById('zone6')?.checked || false,
|
||
|
||
//commentaire
|
||
commentaire: document.getElementById('commentaire')?.value,
|
||
};
|
||
|
||
// ===== LOGS DE DÉBOGAGE =====
|
||
console.log('=== DEBUT SAUVEGARDE TARIF RC ===');
|
||
console.log('rcMainData:', rcMainData);
|
||
|
||
// ===== ÉTAPE 2: Collecter les résultats de calculs pour tarifRC =====
|
||
const tarifRCData = {
|
||
sinistre: toNumber(document.getElementById('sinistre')?.value),
|
||
pourcentageVoiturier: toNumber(pctVoiturierInput?.value ?? pctVoiturierInput?.textContent),
|
||
isSetVoiturier: Boolean(pctVoiturierInput?.value?.trim()),
|
||
pourcentageCommissionnaire: toNumber(pctCommissionnaireInput?.value ?? pctCommissionnaireInput?.textContent),
|
||
isSetCommissionnaire: Boolean(pctCommissionnaireInput?.value?.trim()),
|
||
pourcentageDemenageur: toNumber(pctDemenageurInput?.value ?? pctDemenageurInput?.textContent),
|
||
isSetDemenageur: Boolean(pctDemenageurInput?.value?.trim()),
|
||
pourcentageLogistique: toNumber(pctLogistiqueInput?.value ?? pctLogistiqueInput?.textContent),
|
||
isSetLogistique: Boolean(pctLogistiqueInput?.value?.trim()),
|
||
pourcentageAutocariste: toNumber(pctAutocaristeInput?.value ?? pctAutocaristeInput?.textContent),
|
||
isSetAutocariste: Boolean(pctAutocaristeInput?.value?.trim()),
|
||
pourcentageAutres: toNumber(pctAutresInput?.value ?? pctAutresInput?.textContent),
|
||
isSetAutres: Boolean(pctAutresInput?.value?.trim()),
|
||
|
||
// Tarifs pour franchise 250
|
||
primeRCC_250: toNumber(document.getElementById('rccFr250')?.textContent),
|
||
primeRCE_250: toNumber(document.getElementById('rceFr250')?.textContent),
|
||
primePJ_250: toNumber(document.getElementById('pjFr250')?.textContent),
|
||
primeTotal_250: toNumber(document.getElementById('priceFr250')?.textContent),
|
||
tauxRCC_250: toNumber(document.getElementById('tauxRccFr250')?.textContent),
|
||
tauxRCE_250: toNumber(document.getElementById('tauxRceFr250')?.textContent),
|
||
tauxGlobal_250: toNumber(document.getElementById('tauxGlobalFr250')?.textContent),
|
||
|
||
// Tarifs pour franchise 400
|
||
primeRCC_400: toNumber(document.getElementById('rccFr400')?.textContent),
|
||
primeRCE_400: toNumber(document.getElementById('rceFr400')?.textContent),
|
||
primePJ_400: toNumber(document.getElementById('pjFr400')?.textContent),
|
||
primeTotal_400: toNumber(document.getElementById('priceFr400')?.textContent),
|
||
tauxRCC_400: toNumber(document.getElementById('tauxRccFr400')?.textContent),
|
||
tauxRCE_400: toNumber(document.getElementById('tauxRceFr400')?.textContent),
|
||
tauxGlobal_400: toNumber(document.getElementById('tauxGlobalFr400')?.textContent),
|
||
|
||
// Tarifs pour franchise 2000
|
||
primeRCC_2000: toNumber(document.getElementById('rccFr2000')?.textContent),
|
||
primeRCE_2000: toNumber(document.getElementById('rceFr2000')?.textContent),
|
||
primePJ_2000: toNumber(document.getElementById('pjFr2000')?.textContent),
|
||
primeTotal_2000: toNumber(document.getElementById('priceFr2000')?.textContent),
|
||
tauxRCC_2000: toNumber(document.getElementById('tauxRccFr2000')?.textContent),
|
||
tauxRCE_2000: toNumber(document.getElementById('tauxRceFr2000')?.textContent),
|
||
tauxGlobal_2000: toNumber(document.getElementById('tauxGlobalFr2000')?.textContent),
|
||
|
||
// Franchise choisie
|
||
franchiseChoisie: window.franchiseChoisie || null,
|
||
|
||
// Engagements complémentaires (dans tarifRC, pas dans rc!)
|
||
checkDomImmat: document.getElementById('checkDomImmat')?.checked || false,
|
||
capitalDomImmat: toNumber(document.getElementById('inputDomImmat')?.value),
|
||
checkContConf: document.getElementById('checkContConf')?.checked || false,
|
||
capitalContConf: toNumber(document.getElementById('inputContConf')?.value),
|
||
checkDiffInv: document.getElementById('checkDiffInv')?.checked || false,
|
||
capitalDiffInv: toNumber(document.getElementById('inputDiffInv')?.value),
|
||
|
||
// Garanties additionnelles (dans tarifRC, pas dans rc!)
|
||
checkStationLavage: document.getElementById('checkStationLavage')?.checked || false,
|
||
checkGarageInterne: document.getElementById('checkGarageInterne')?.checked || false,
|
||
checkCSE: document.getElementById('checkCSE')?.checked || false,
|
||
checkTPPC: document.getElementById('checkTPPC')?.checked || false,
|
||
capitalTPPC: toNumber(document.getElementById('selTPPCcapital')?.value),
|
||
vehiculesTPPC: Math.max(0, Math.round(toNumber(document.getElementById('selTPPCveh')?.value))),
|
||
checkPJ: document.getElementById('checkPJ')?.checked || false,
|
||
|
||
tarifcommercial: toNumber(document.getElementById('tarifCom')?.value),
|
||
};
|
||
|
||
console.log('tarifRCData:', tarifRCData);
|
||
|
||
try {
|
||
let idTarifRC;
|
||
let rcId = rc?.id;
|
||
|
||
// ===== VÉRIFIER SI RC EXISTE, SINON LE CRÉER =====
|
||
if (!rcId) {
|
||
console.log('RC n\'existe pas encore, création en cours...');
|
||
const createRCResponse = await fetch(`/rc/create`, {
|
||
method: 'POST',
|
||
body: JSON.stringify({ typeCotisation: rcMainData.typeCotisation }),
|
||
headers: { 'Content-Type': 'application/json' },
|
||
});
|
||
const createRCData = await createRCResponse.json();
|
||
|
||
if (createRCData.valid) {
|
||
rcId = createRCData.rc.id;
|
||
// Mettre à jour le contrat avec le nouvel ID RC
|
||
await fetch(`/contrat/update/${contrat.produit}/${contrat.id}/${rcId}`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
});
|
||
} else {
|
||
console.error('Échec de la création de RC:', createRCData.message);
|
||
return { valid: false, message: 'Échec création RC' };
|
||
}
|
||
}
|
||
|
||
// ===== ÉTAPE 3: Sauvegarder/Mettre à jour tarifRC =====
|
||
if (tarif && tarif.id) {
|
||
// Mettre à jour un enregistrement tarifRC existant
|
||
console.log(`Mise a jour tarifRC existant (ID: ${tarif.id})`);
|
||
const response = await fetch(`/rc/tarif/update/${tarif.id}`, {
|
||
method: 'POST',
|
||
body: JSON.stringify(tarifRCData),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
const data = await response.json();
|
||
console.log('Reponse serveur tarifRC update:', data);
|
||
if (data.valid) {
|
||
idTarifRC = data.tarifRc.id;
|
||
} else {
|
||
console.error('Echec de la mise a jour de tarifRC:', data.message);
|
||
return { valid: false, message: data.message };
|
||
}
|
||
} else {
|
||
// Créer un nouvel enregistrement tarifRC
|
||
console.log('Creation nouveau tarifRC');
|
||
const response = await fetch(`/rc/tarif/create`, {
|
||
method: 'POST',
|
||
body: JSON.stringify(tarifRCData),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
const data = await response.json();
|
||
console.log('Reponse serveur tarifRC create:', data);
|
||
if (data.valid) {
|
||
idTarifRC = data.tarifRc.id;
|
||
} else {
|
||
console.error('Echec de la creation de tarifRC:', data.message);
|
||
return { valid: false, message: data.message };
|
||
}
|
||
}
|
||
|
||
// ===== ÉTAPE 4: Mettre à jour RC principal avec les données communes ET la référence tarifRC =====
|
||
rcMainData.tarifRC = idTarifRC; // Ajouter la référence à tarifRC
|
||
|
||
console.log(`Mise a jour RC principal (ID: ${rcId}) avec reference tarifRC: ${idTarifRC}`);
|
||
console.log('Donnees envoyees pour RC:', rcMainData);
|
||
|
||
const updateRCResponse = await fetch(`/rc/update/${rcId}`, {
|
||
method: 'POST',
|
||
body: JSON.stringify(rcMainData),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
const updateRCData = await updateRCResponse.json();
|
||
console.log('Reponse serveur RC update:', updateRCData);
|
||
|
||
if (!updateRCData.valid) {
|
||
console.error('Echec de la mise a jour de RC principal:', updateRCData.message);
|
||
return { valid: false, message: 'Échec mise à jour RC principal' };
|
||
}
|
||
|
||
console.log('=== TARIF RC SAUVEGARDE AVEC SUCCES ===');
|
||
console.log('RC ID:', rcId, '| TarifRC ID:', idTarifRC);
|
||
return { valid: true, idTarifRC, idRC: rcId };
|
||
} catch (error) {
|
||
console.error('Erreur lors de la sauvegarde de tarifRC:', error);
|
||
return { valid: false, message: error.message };
|
||
}
|
||
}
|
||
|
||
// Fonction helper pour collecter les activités complémentaires
|
||
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
|
||
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);
|
||
}
|
||
|
||
// Fonction pour gérer les clics sur les boutons de tariffettes
|
||
function setupTarifetteButtons() {
|
||
const tarifetteButtons = document.querySelectorAll('.franchise-card button[name]');
|
||
tarifetteButtons.forEach(button => {
|
||
button.addEventListener('click', async function(e) {
|
||
e.preventDefault();
|
||
const franchiseValue = this.getAttribute('name');
|
||
|
||
// Mettre à jour la variable globale et l'UI
|
||
window.franchiseChoisie = franchiseValue;
|
||
console.log(`Tariffette sélectionnée: ${franchiseValue}€`);
|
||
|
||
// Mettre en surbrillance la carte sélectionnée
|
||
document.querySelectorAll('.franchise-card').forEach(c => c.classList.remove('selected'));
|
||
this.closest('.franchise-card').classList.add('selected');
|
||
|
||
// Ouvrir le modal de tarif commercial
|
||
openModalTarifCom(franchiseValue);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Fonction pour configurer les alertes de marchandises
|
||
function setupMarchandiseAlerts() {
|
||
// Alerte pour Animaux Vivants
|
||
document.querySelectorAll('[name^="mar"] input[type="checkbox"]').forEach(cb => {
|
||
cb.addEventListener('change', function() {
|
||
const label = this.nextElementSibling?.textContent.trim();
|
||
if (label && label.includes('Animaux vivants') && this.checked) {
|
||
window.modalAnimauxVivants.open();
|
||
}
|
||
if (label && label.includes('Transport de béton') && this.checked) {
|
||
window.modalTransportBeton.open();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// Fonction pour configurer les alertes d'activités
|
||
function setupActiviteAlerts() {
|
||
// Alerte pour Autocariste + RCE
|
||
const checkAutocariste = document.getElementById('checkAutocariste');
|
||
const checkRCE = document.getElementById('checkRCE');
|
||
|
||
const checkBothAutocariste = () => {
|
||
if (checkAutocariste?.checked && checkRCE?.checked) {
|
||
window.modalAutocaristeRCE.open();
|
||
}
|
||
};
|
||
|
||
if (checkAutocariste) checkAutocariste.addEventListener('change', checkBothAutocariste);
|
||
if (checkRCE) checkRCE.addEventListener('change', checkBothAutocariste);
|
||
}
|
||
|
||
// Seuil de différence acceptable (5%)
|
||
const seuil = 5;
|
||
|
||
// Fonction pour ouvrir le modal de tarif commercial
|
||
function openModalTarifCom(franchiseValue) {
|
||
// Récupérer le tarif de référence selon la franchise
|
||
let tarifRef = 0;
|
||
if (franchiseValue === '250') {
|
||
tarifRef = toNumber(document.getElementById('priceFr250')?.textContent);
|
||
} else if (franchiseValue === '400') {
|
||
tarifRef = toNumber(document.getElementById('priceFr400')?.textContent);
|
||
} else if (franchiseValue === 'mini300') {
|
||
tarifRef = toNumber(document.getElementById('priceFr2000')?.textContent);
|
||
}
|
||
|
||
// Réinitialiser le modal
|
||
document.getElementById('tarifRefText').innerText = `Tarif de Référence : ${formatNumber(tarifRef, 2)} €`;
|
||
document.getElementById('tarifCom').value = '';
|
||
document.getElementById('commentaire').value = '';
|
||
document.getElementById('comm-OK').disabled = false;
|
||
document.getElementById('tarifCom-error').style.display = 'none';
|
||
document.getElementById('col-commentaire').style.display = 'none';
|
||
document.getElementById('qualiteDiv').style.display = 'none';
|
||
document.getElementById('comm-OK').setAttribute('data-franchise', franchiseValue);
|
||
document.getElementById('comm-OK').setAttribute('data-tarif-ref', tarifRef);
|
||
|
||
// Event listener pour le champ tarif commercial
|
||
const tarifComInput = document.getElementById('tarifCom');
|
||
tarifComInput.removeEventListener('input', handleTarifComInput);
|
||
tarifComInput.addEventListener('input', handleTarifComInput);
|
||
|
||
// Event listener pour le commentaire
|
||
const commentaireInput = document.getElementById('commentaire');
|
||
commentaireInput.removeEventListener('input', handleCommentaireInput);
|
||
commentaireInput.addEventListener('input', handleCommentaireInput);
|
||
|
||
// Ouvrir le modal
|
||
window.modalTarifCom.open();
|
||
}
|
||
|
||
// Fonction pour gérer l'input du tarif commercial
|
||
function handleTarifComInput(e) {
|
||
const tarifCom = parseFloat(e.target.value);
|
||
const tarifRef = parseFloat(document.getElementById('comm-OK').getAttribute('data-tarif-ref'));
|
||
|
||
if (!tarifCom || tarifCom <= 0) {
|
||
document.getElementById('qualiteDiv').style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
const diff = 100 * (tarifCom / tarifRef);
|
||
let qualitePrime = '';
|
||
let emoji = '';
|
||
let showComment = false;
|
||
|
||
if (diff < (100 + seuil) && diff > (100 - seuil)) {
|
||
emoji = 'mood';
|
||
showComment = false;
|
||
|
||
if (diff > 100) {
|
||
qualitePrime = `Tarif correct (+${(diff - 100).toFixed(2)}%)`;
|
||
} else if (diff < 100) {
|
||
qualitePrime = `Tarif correct (-${(100 - diff).toFixed(2)}%)`;
|
||
} else {
|
||
qualitePrime = 'Le juste prix';
|
||
emoji = 'thumb_up_alt';
|
||
}
|
||
} else {
|
||
emoji = 'mood_bad';
|
||
showComment = true;
|
||
|
||
if (diff > (100 + seuil)) {
|
||
qualitePrime = `Tarif trop élevé (+${(diff - 100).toFixed(2)}%)`;
|
||
} else if (diff < (100 - seuil)) {
|
||
qualitePrime = `Tarif trop bas (-${(100 - diff).toFixed(2)}%)`;
|
||
}
|
||
}
|
||
|
||
document.getElementById('qualiteDiv').style.display = 'block';
|
||
document.getElementById('qualitePrime').innerText = qualitePrime;
|
||
document.getElementById('modalTarifCom-icon').innerText = emoji;
|
||
document.getElementById('modalTarifCom-icon').style.color = (emoji === 'mood_bad') ? 'red' : 'green';
|
||
|
||
if (showComment) {
|
||
document.getElementById('tarifCom-error').style.display = 'flex';
|
||
document.getElementById('col-commentaire').style.display = 'flex';
|
||
if (!document.getElementById('commentaire').value.trim()) {
|
||
document.getElementById('comm-OK').disabled = true;
|
||
}
|
||
} else {
|
||
document.getElementById('comm-OK').disabled = false;
|
||
document.getElementById('tarifCom-error').style.display = 'none';
|
||
document.getElementById('col-commentaire').style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// Fonction pour gérer l'input du commentaire
|
||
function handleCommentaireInput(e) {
|
||
const commentaire = e.target.value.trim();
|
||
const tarifComError = document.getElementById('tarifCom-error').style.display !== 'none';
|
||
|
||
if (tarifComError) {
|
||
document.getElementById('comm-OK').disabled = !commentaire;
|
||
}
|
||
}
|
||
|
||
// Fonction pour gérer la validation du tarif commercial
|
||
async function handleValidateTarifCom() {
|
||
const tarifCom = parseFloat(document.getElementById('tarifCom').value);
|
||
const commentaire = document.getElementById('commentaire').value.trim();
|
||
const franchiseValue = document.getElementById('comm-OK').getAttribute('data-franchise');
|
||
|
||
if (!tarifCom || tarifCom <= 0) {
|
||
M.toast({html: 'Veuillez saisir un tarif commercial valide', classes: 'red'});
|
||
return;
|
||
}
|
||
|
||
|
||
// Fermer le modal
|
||
window.modalTarifCom.close();
|
||
|
||
// Afficher un loader
|
||
M.toast({html: 'Sauvegarde en cours...', classes: 'blue'});
|
||
|
||
// Sauvegarder le tarif
|
||
const saveResult = await saveTarifRC();
|
||
|
||
if (saveResult && saveResult.valid) {
|
||
M.toast({html: `Tarif sauvegardé avec succès !`, classes: 'green'});
|
||
|
||
// Rediriger vers la page projet après un court délai
|
||
setTimeout(() => {
|
||
console.log('Redirection vers projet...');
|
||
// Construire l'URL de redirection vers projet
|
||
const numParcours = parcours?.numParcours;
|
||
if (numParcours) {
|
||
window.location.href = `navParcours?numParcours=${numParcours}&submenu=projet`;
|
||
} else {
|
||
M.toast({html: 'Erreur: impossible de rediriger', classes: 'red'});
|
||
}
|
||
}, 1000);
|
||
} else {
|
||
M.toast({html: 'Erreur lors de la sauvegarde du tarif', classes: 'red'});
|
||
}
|
||
}
|
||
|
||
// Exposer les fonctions globalement pour y accéder depuis l'extérieur
|
||
window.initSubmenuForm = init;
|
||
window.saveTarifRC = saveTarifRC;
|
||
})();
|