1438 lines
56 KiB
JavaScript
1438 lines
56 KiB
JavaScript
jQuery(function($) {
|
|
jQuery('form.load_simulator').each(function() {
|
|
jQuery(this).attr('action', window.location.origin + '/credit-step1')
|
|
})
|
|
|
|
/**
|
|
* Système de sauvegarde localStorage
|
|
*/
|
|
const FORM_STORAGE_KEY = 'credit_direct_form_data';
|
|
const FORM_STORAGE_TIMESTAMP = 'credit_direct_form_timestamp';
|
|
const STORAGE_EXPIRY_HOURS = 24; // Les données expirent après 24h
|
|
|
|
/**
|
|
* Affiche l'indicateur de sauvegarde
|
|
*/
|
|
function showSaveIndicator(message, type = 'success') {
|
|
let indicator = jQuery('.auto-save-indicator');
|
|
|
|
if (indicator.length === 0) {
|
|
indicator = jQuery('<div class="auto-save-indicator"></div>');
|
|
jQuery('body').append(indicator);
|
|
}
|
|
|
|
indicator.removeClass('show saving error').addClass('show ' + type);
|
|
indicator.text(message);
|
|
|
|
// Masquer après 3 secondes
|
|
setTimeout(() => {
|
|
indicator.removeClass('show');
|
|
}, 3000);
|
|
}
|
|
|
|
/**
|
|
* Sauvegarde les données du formulaire dans localStorage
|
|
*/
|
|
function saveFormData() {
|
|
// Afficher l'indicateur de sauvegarde
|
|
showSaveIndicator('Sauvegarde en cours...', 'saving');
|
|
|
|
const formData = {};
|
|
const currentStep = getCurrentStep();
|
|
|
|
// Récupérer tous les champs du formulaire
|
|
jQuery('form.form-submit').find('input, select, textarea').each(function() {
|
|
const $field = jQuery(this);
|
|
const name = $field.attr('name');
|
|
const type = $field.attr('type');
|
|
|
|
if (!name) return;
|
|
|
|
let value = '';
|
|
|
|
switch (type) {
|
|
case 'checkbox':
|
|
value = $field.is(':checked') ? $field.val() : '';
|
|
break;
|
|
case 'radio':
|
|
if ($field.is(':checked')) {
|
|
value = $field.val();
|
|
}
|
|
break;
|
|
case 'file':
|
|
// Ne pas sauvegarder les fichiers
|
|
return;
|
|
default:
|
|
value = $field.val() || '';
|
|
break;
|
|
}
|
|
|
|
// Ne sauvegarder que si la valeur n'est pas vide
|
|
if (value !== '') {
|
|
formData[name] = value;
|
|
}
|
|
});
|
|
|
|
// Sauvegarder avec l'étape actuelle et le timestamp
|
|
const dataToSave = {
|
|
step: currentStep,
|
|
data: formData,
|
|
timestamp: Date.now()
|
|
};
|
|
|
|
try {
|
|
localStorage.setItem(FORM_STORAGE_KEY, JSON.stringify(dataToSave));
|
|
localStorage.setItem(FORM_STORAGE_TIMESTAMP, Date.now().toString());
|
|
console.log('Données sauvegardées dans localStorage:', dataToSave);
|
|
|
|
// Afficher le succès
|
|
setTimeout(() => {
|
|
showSaveIndicator('Données sauvegardées', 'success');
|
|
}, 500);
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de la sauvegarde localStorage:', e);
|
|
showSaveIndicator('Erreur de sauvegarde', 'error');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Restaure les données du formulaire depuis localStorage
|
|
*/
|
|
function restoreFormData() {
|
|
try {
|
|
const savedData = localStorage.getItem(FORM_STORAGE_KEY);
|
|
if (!savedData) return false;
|
|
|
|
const parsedData = JSON.parse(savedData);
|
|
const now = Date.now();
|
|
const savedTime = parsedData.timestamp || 0;
|
|
|
|
// Vérifier si les données ne sont pas expirées
|
|
if (now - savedTime > STORAGE_EXPIRY_HOURS * 60 * 60 * 1000) {
|
|
console.log('Données localStorage expirées, suppression...');
|
|
clearFormData();
|
|
return false;
|
|
}
|
|
|
|
const formData = parsedData.data || {};
|
|
let restoredCount = 0;
|
|
|
|
// Restaurer les valeurs
|
|
Object.keys(formData).forEach(name => {
|
|
const $field = jQuery('form.form-submit').find(`[name="${name}"]`);
|
|
if ($field.length === 0) return;
|
|
|
|
const value = formData[name];
|
|
const type = $field.attr('type');
|
|
|
|
switch (type) {
|
|
case 'checkbox':
|
|
if (value) {
|
|
$field.prop('checked', true);
|
|
}
|
|
break;
|
|
case 'radio':
|
|
$field.filter(`[value="${value}"]`).prop('checked', true);
|
|
break;
|
|
default:
|
|
$field.val(value);
|
|
break;
|
|
}
|
|
|
|
// Ajouter un effet visuel temporaire
|
|
$field.addClass('field-restored');
|
|
setTimeout(() => {
|
|
$field.removeClass('field-restored');
|
|
}, 2000);
|
|
|
|
restoredCount++;
|
|
});
|
|
|
|
console.log(`${restoredCount} champs restaurés depuis localStorage`);
|
|
|
|
if (restoredCount > 0) {
|
|
showSaveIndicator(`${restoredCount} champs restaurés`, 'success');
|
|
}
|
|
|
|
return restoredCount > 0;
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de la restauration localStorage:', e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Efface les données du formulaire du localStorage
|
|
*/
|
|
function clearFormData() {
|
|
try {
|
|
localStorage.removeItem(FORM_STORAGE_KEY);
|
|
localStorage.removeItem(FORM_STORAGE_TIMESTAMP);
|
|
console.log('Données localStorage effacées');
|
|
|
|
// Masquer le message d'information
|
|
jQuery('.localstorage-info').fadeOut();
|
|
|
|
// Afficher un message de confirmation
|
|
showSaveIndicator('Données effacées', 'success');
|
|
|
|
} catch (e) {
|
|
console.error('Erreur lors de l\'effacement localStorage:', e);
|
|
showSaveIndicator('Erreur lors de l\'effacement', 'error');
|
|
}
|
|
}
|
|
|
|
// Rendre la fonction accessible globalement
|
|
window.clearFormData = clearFormData;
|
|
|
|
/**
|
|
* Détermine l'étape actuelle basée sur l'URL
|
|
*/
|
|
function getCurrentStep() {
|
|
const path = window.location.pathname;
|
|
if (path.includes('credit-step1')) return 'step1';
|
|
if (path.includes('credit-step2')) return 'step2';
|
|
if (path.includes('credit-step3')) return 'step3';
|
|
if (path.includes('credit-step4')) return 'step4';
|
|
if (path.includes('credit-step5')) return 'step5';
|
|
return 'unknown';
|
|
}
|
|
|
|
/**
|
|
* Sauvegarde automatique lors de la modification des champs
|
|
*/
|
|
function setupAutoSave() {
|
|
// Sauvegarde sur clic du lien "previous-step"
|
|
jQuery('a.previous-step').on('click', function(e) {
|
|
/* e.preventDefault(); */
|
|
saveFormData();
|
|
});
|
|
|
|
// Sauvegarde sur changement de valeur (désactivé)
|
|
// jQuery('form.form-submit').on('change input', 'input, select, textarea', function() {
|
|
// // Debounce pour éviter trop de sauvegardes
|
|
// clearTimeout(window.autoSaveTimeout);
|
|
// window.autoSaveTimeout = setTimeout(saveFormData, 1000);
|
|
// });
|
|
|
|
// Sauvegarde sur clic des boutons radio/checkbox (désactivé)
|
|
// jQuery('form.form-submit').on('click', 'input[type="radio"], input[type="checkbox"]', function() {
|
|
// setTimeout(saveFormData, 100);
|
|
// });
|
|
|
|
// Sauvegarde avant soumission du formulaire (désactivé)
|
|
// jQuery('form.form-submit').on('submit', function() {
|
|
// saveFormData();
|
|
// });
|
|
|
|
// Sauvegarde avant navigation (bouton étape précédente) (désactivé)
|
|
// jQuery('a[href*="credit-step"]').on('click', function() {
|
|
// saveFormData();
|
|
// });
|
|
|
|
// Sauvegarde lors de l'ajout/suppression de crédits en cours (désactivé)
|
|
// $(document).on('currentLoanAdded currentLoanRemoved', function() {
|
|
// setTimeout(saveFormData, 500);
|
|
// });
|
|
}
|
|
|
|
/**
|
|
* Affiche le message d'information localStorage
|
|
*/
|
|
function showLocalStorageInfo() {
|
|
const savedData = localStorage.getItem(FORM_STORAGE_KEY);
|
|
if (!savedData) return;
|
|
|
|
// Vérifier si le message existe déjà
|
|
if (jQuery('.localstorage-info').length > 0) return;
|
|
|
|
const infoHtml = `
|
|
<div class="localstorage-info">
|
|
<span class="icon">💾</span>
|
|
Vos données sont sauvegardées automatiquement.
|
|
<button class="clear-storage-btn" onclick="clearFormData()">Effacer</button>
|
|
</div>
|
|
`;
|
|
|
|
// Insérer au début du formulaire
|
|
jQuery('form.form-submit').prepend(infoHtml);
|
|
}
|
|
|
|
/**
|
|
* Initialise le système de sauvegarde
|
|
*/
|
|
function initFormStorage() {
|
|
|
|
if(hasCreditDirectToken())
|
|
return;
|
|
|
|
//check if localStorage is empty
|
|
if(localStorage.getItem(FORM_STORAGE_KEY) === null)
|
|
return;
|
|
|
|
// Restaurer les données au chargement
|
|
const restored = restoreFormData();
|
|
|
|
// Configurer la sauvegarde automatique
|
|
setupAutoSave();
|
|
|
|
// Effacer les données après soumission réussie (optionnel)
|
|
jQuery(document).on('formSubmitted', function() {
|
|
clearFormData();
|
|
});
|
|
|
|
// Si des données ont été restaurées, initialiser l'affichage des zones conditionnelles
|
|
if (restored) {
|
|
setTimeout(function() {
|
|
initializePreFilledValues();
|
|
}, 200);
|
|
}
|
|
|
|
// Afficher le message d'information
|
|
showLocalStorageInfo();
|
|
|
|
console.log('Système de sauvegarde localStorage initialisé');
|
|
}
|
|
|
|
function hasCreditDirectToken() {
|
|
return window.location.search.includes('credit-direct-token');
|
|
}
|
|
|
|
// Initialiser le système de sauvegarde UNIQUEMENT si le paramètre est présent dans l'URL
|
|
initFormStorage();
|
|
if (hasCreditDirectToken()) {
|
|
}
|
|
|
|
/**
|
|
* General
|
|
*/
|
|
function empty(value) { return value == undefined || value == null || value == [] || value == ''; }
|
|
|
|
function makeLabelRequired(containerSelector = 'body') {
|
|
if (jQuery(containerSelector).length > 0) {
|
|
jQuery(containerSelector).find('input:required, select:required, textarea:required').each(function() {
|
|
var labelId = jQuery(this).attr('id');
|
|
var label = jQuery('label[for="' + labelId + '"]')
|
|
|
|
if (label.length > 0 && label.html().charAt(label.html().length - 1) !== '*') {
|
|
label.html(label.html() + '*')
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
if (jQuery('.wpcf-borrower').length > 0) {
|
|
makeLabelRequired('.wpcf-borrower')
|
|
} else {
|
|
makeLabelRequired('.form-submit')
|
|
}
|
|
|
|
/**
|
|
* Step 2
|
|
*/
|
|
function changeJobLabels(value, container) {
|
|
var jobLabels = {
|
|
independent: {
|
|
factory: 'de l\'entreprise',
|
|
salary: 'Revenu imposable annuel',
|
|
startDate: 'de début d\'activité'
|
|
},
|
|
withoutEmployer: {
|
|
employer: 'de l\'employeur/organisme de paiement',
|
|
salary: 'Indemnités mensuelles',
|
|
startDate: 'd\'engagement'
|
|
},
|
|
withEmployer: {
|
|
employer: 'de l\'employeur/organisme de paiement',
|
|
salary: 'Salaire net mensuel',
|
|
startDate: 'd\'engagement'
|
|
}
|
|
}, job = {
|
|
independent: 5,
|
|
withoutEmployer: ['1','6','9','12']
|
|
};
|
|
|
|
console.log('job', value, job.independent);
|
|
|
|
var prefix = container.find('#IDcofirstname').length > 0 ? 'co' : ''
|
|
var fields = ['emname', 'emaddress', 'emzip', 'emcity', 'emcountry', 'commitmentdate', 'salary']
|
|
|
|
fields.forEach(id => {
|
|
var labelText = null
|
|
|
|
switch (id) {
|
|
case 'commitmentdate':
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.startDate
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.startDate
|
|
} else {
|
|
labelText = jobLabels.withEmployer.startDate
|
|
}
|
|
break;
|
|
|
|
case 'salary':
|
|
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.salary
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.salary
|
|
} else {
|
|
labelText = jobLabels.withEmployer.salary
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if(value === job.independent) {
|
|
labelText = jobLabels.independent.factory
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
labelText = jobLabels.withoutEmployer.employer
|
|
} else {
|
|
labelText = jobLabels.withEmployer.employer
|
|
}
|
|
break;
|
|
}
|
|
|
|
container.find('label[for="ID' + prefix + id + '"] > span').text(labelText);
|
|
|
|
console.log('labelText', labelText);
|
|
});
|
|
|
|
/* console.log('container', container);
|
|
console.log('prefix', container.find('.'+prefix+'independent_section')); */
|
|
console.log('value', value);
|
|
|
|
if(value == job.independent) {
|
|
container.find('.'+prefix+'independent_section').fadeIn().removeClass('hidden');
|
|
//remove required attributes
|
|
container.find('.'+prefix+'employee_section').find('input, select').removeAttr('required');
|
|
container.find('.'+prefix+'employee_section').fadeOut().addClass('hidden');
|
|
container.find('.'+prefix+'independent_section').find('input, select').attr('required', true);
|
|
} else if(job.withoutEmployer.includes(value)) {
|
|
container.find('.withemployer_section').fadeOut().addClass('hidden');
|
|
container.find('.withemployer_section').find('input, select').removeAttr('required');
|
|
|
|
console.log((jobLabels.withoutEmployer.salary));
|
|
/* container.find('.'+prefix+'IDsalary').prev().text(jobLabels.withoutEmployer.salary);
|
|
|
|
console.log(container.find('#'+prefix+'IDsalary').prev()); */
|
|
} else {
|
|
container.find('.'+prefix+'independent_section').fadeOut().addClass('hidden');
|
|
//not input field required
|
|
container.find('.'+prefix+'employee_section').find('input:not([type="file"]), select').attr('required', true);
|
|
container.find('.'+prefix+'employee_section').fadeIn().removeClass('hidden');
|
|
|
|
//except file inputs
|
|
container.find('.'+prefix+'independent_section').find('input:not([type="file"]), select').removeAttr('required');
|
|
|
|
if(jQuery('.withemployer_section').hasClass('hidden')) {
|
|
jQuery('.withemployer_section').fadeIn().removeClass('hidden');
|
|
jQuery('.withemployer_section').find('input, select').attr('required', true);
|
|
}
|
|
}
|
|
|
|
container
|
|
.find('#ID' + prefix + 'emnumber')
|
|
.attr('required', value === job.independent)
|
|
.parent()
|
|
.toggleClass('d-none', value !== job.independent)
|
|
|
|
makeLabelRequired()
|
|
}
|
|
|
|
function displayCoBorrower() {
|
|
var
|
|
excludedFieldsName = [
|
|
'cocontract_type',
|
|
'coemname',
|
|
'coemaddress',
|
|
'coemzip',
|
|
'coemcity',
|
|
'coemcountry',
|
|
'cocommitmentdate',
|
|
'cooiamouthmealvoucher',
|
|
'cooiamouthrentalincome',
|
|
'cooiamouthunemployment',
|
|
'cooiamouthother',
|
|
'cooiothertext',
|
|
'co_secteur_activite',
|
|
'co_num_tva',
|
|
'coMtn_loyer'
|
|
],
|
|
hasCoBorrower =
|
|
jQuery('input[name="hascoborrower"]:checked').length > 0 &&
|
|
jQuery('input[name="hascoborrower"]:checked').val() == 1,
|
|
key = '.wpcf-coborrower',
|
|
cols_key = '.credit-cols';
|
|
|
|
console.log('hasCoBorrower', hasCoBorrower);
|
|
|
|
// Gestion de l'affichage/masquage
|
|
jQuery(key).toggleClass('d-none', !hasCoBorrower);
|
|
|
|
// Gestion des colonnes
|
|
if (hasCoBorrower) {
|
|
// Mode deux colonnes
|
|
jQuery(cols_key).removeClass('col-md-12').addClass('col-md-6');
|
|
|
|
// Ajuster les colonnes internes
|
|
jQuery('.credit-cols [class*="col-md-"]').each(function() {
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
var currentSize = parseInt(className.replace('col-md-', ''));
|
|
console.log('currentSize', currentSize);
|
|
|
|
// Sauvegarder la taille originale si ce n'est pas déjà fait
|
|
if (!jQuery(this).data('original-size')) {
|
|
jQuery(this).data('original-size', className);
|
|
}
|
|
|
|
// Définir la nouvelle taille
|
|
jQuery(this).removeClass(className).addClass('col-md-12');
|
|
}
|
|
}.bind(this));
|
|
});
|
|
} else {
|
|
// Mode une colonne
|
|
jQuery('.credit-cols .wpcf-borrower').removeClass('col-md-6');
|
|
|
|
if(!jQuery(cols_key).hasClass('col-md-12'))
|
|
jQuery(cols_key).addClass('col-md-12').removeClass('col-md-6');
|
|
|
|
// Restaurer les colonnes internes à leur taille d'origine
|
|
jQuery('.credit-cols [class*="col-md-"]').each(function() {
|
|
var originalSize = jQuery(this).data('original-size');
|
|
|
|
if (originalSize) {
|
|
// Supprimer toutes les classes col-md-* actuelles
|
|
var classes = jQuery(this).attr('class').split(' ');
|
|
classes.forEach(function(className) {
|
|
if (className.startsWith('col-md-')) {
|
|
jQuery(this).removeClass(className);
|
|
}
|
|
}.bind(this));
|
|
|
|
// Restaurer la taille originale
|
|
jQuery(this).addClass(originalSize);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Gestion des champs requis
|
|
jQuery(key).find('input[type="text"], input[type="number"], input[type="date"], select, textarea').each(function() {
|
|
if (excludedFieldsName.indexOf(jQuery(this).attr('name')) < 0) {
|
|
jQuery(this).attr('required', hasCoBorrower)
|
|
}
|
|
})
|
|
|
|
if (!hasCoBorrower) {
|
|
jQuery(key).find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() {
|
|
jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio')
|
|
})
|
|
|
|
jQuery(key).find('input:not([type="checkbox"]):not([type="radio"]), select, textarea').each(function() {
|
|
jQuery(this).val('')
|
|
})
|
|
}
|
|
|
|
makeLabelRequired(key)
|
|
displayOtherIncome(
|
|
hasCoBorrower && jQuery('input[name="cohasotherincome"]:checked').length > 0 && jQuery('input[name="cohasotherincome"]:checked').val() == 1,
|
|
'.co'
|
|
)
|
|
}
|
|
|
|
function displayOtherIncome(show, key) {
|
|
var target = jQuery('.wpcf-otherincome' + key)
|
|
|
|
if (target.length > 0) {
|
|
target.toggleClass('d-none', !show);
|
|
|
|
if (!show) {
|
|
target.find('input[type="checkbox"]:checked, input[type="radio"][value="0"]').each(function() {
|
|
jQuery(this).prop('checked', jQuery(this).attr('type') === 'radio')
|
|
})
|
|
}
|
|
|
|
displayOtherIncomeSubFields(target.find('input[type="checkbox"], input[type="radio"]:checked'))
|
|
}
|
|
}
|
|
|
|
function displayOtherIncomeSubFields(el) {
|
|
el.each(function() {
|
|
var subFields = jQuery(this).closest('.form-row').find('.form-group')
|
|
|
|
if (subFields.length > 0) {
|
|
subFields.toggleClass('d-none', !jQuery(this).is(':checked'))
|
|
subFields.find('input').attr('required', jQuery(this).is(':checked'))
|
|
}
|
|
})
|
|
}
|
|
|
|
function initializePreFilledValues() {
|
|
// Gérer l'affichage des sections basé sur les valeurs pré-remplies
|
|
setTimeout(function() {
|
|
// Vérifier si hascoborrower est pré-rempli
|
|
var hasCoBorrowerChecked = jQuery('input[name="hascoborrower"]:checked');
|
|
if (hasCoBorrowerChecked.length > 0) {
|
|
displayCoBorrower();
|
|
}
|
|
|
|
// Vérifier si hasotherincome est pré-rempli (emprunteur)
|
|
var hasOtherIncomeChecked = jQuery('input[name="hasotherincome"]:checked');
|
|
if (hasOtherIncomeChecked.length > 0) {
|
|
displayOtherIncome(hasOtherIncomeChecked.val() == 1, '.em');
|
|
}
|
|
|
|
// Vérifier si cohasotherincome est pré-rempli (co-emprunteur)
|
|
var coHasOtherIncomeChecked = jQuery('input[name="cohasotherincome"]:checked');
|
|
if (coHasOtherIncomeChecked.length > 0) {
|
|
displayOtherIncome(coHasOtherIncomeChecked.val() == 1, '.co');
|
|
}
|
|
|
|
// Vérifier si hascurrentloan est pré-rempli
|
|
var hasCurrentLoanChecked = jQuery('input[name="hascurrentloan"]:checked');
|
|
if (hasCurrentLoanChecked.length > 0) {
|
|
var isChecked = hasCurrentLoanChecked.val() == '1';
|
|
jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked);
|
|
}
|
|
|
|
// Vérifier si cohascurrentloan est pré-rempli
|
|
var coHasCurrentLoanChecked = jQuery('input[name="cohascurrentloan"]:checked');
|
|
if (coHasCurrentLoanChecked.length > 0) {
|
|
var isChecked = coHasCurrentLoanChecked.val() == '1';
|
|
jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isChecked);
|
|
}
|
|
|
|
// Gérer les champs autres revenus pré-remplis
|
|
jQuery('.wpcf-otherincome input[type="checkbox"]:checked').each(function() {
|
|
displayOtherIncomeSubFields(jQuery(this));
|
|
});
|
|
|
|
// Gérer les champs indépendant pré-remplis
|
|
var jobSelect = jQuery('select[name="job"]');
|
|
if (jobSelect.length > 0 && jobSelect.val()) {
|
|
changeJobLabels(jobSelect.val(), jobSelect.closest('fieldset'));
|
|
}
|
|
|
|
var coJobSelect = jQuery('select[name="cojob"]');
|
|
if (coJobSelect.length > 0 && coJobSelect.val()) {
|
|
changeJobLabels(coJobSelect.val(), coJobSelect.closest('fieldset'));
|
|
}
|
|
}, 100); // Petit délai pour s'assurer que le DOM est chargé
|
|
}
|
|
|
|
var hasCoBorrowerField = jQuery('input[name="hascoborrower"]:checked')
|
|
|
|
if (hasCoBorrowerField.length > 0) {
|
|
displayCoBorrower()
|
|
}
|
|
|
|
if (jQuery('input[name="hasotherincome"]:checked').length > 0) {
|
|
displayOtherIncome(jQuery('input[name="hasotherincome"]:checked').val() == 1, '.em')
|
|
}
|
|
|
|
// Initialisation pour les valeurs pré-remplies
|
|
initializePreFilledValues();
|
|
|
|
jQuery('body').on('change', 'input[name="hascoborrower"]', displayCoBorrower);
|
|
|
|
jQuery('body').on('change', 'input[name="hasotherincome"]', function() {
|
|
displayOtherIncome(jQuery(this).val() == 1, '.em')
|
|
});
|
|
|
|
jQuery('body').on('change', 'input.wpcf-otherincome--oitype', function(e) {
|
|
displayOtherIncomeSubFields(jQuery(e.target))
|
|
});
|
|
|
|
jQuery('body').on('change', 'input[name="cohasotherincome"]', function() {
|
|
displayOtherIncome(jQuery(this).val() == 1, '.co')
|
|
});
|
|
|
|
jQuery('body').on('change', 'select[name="job"], select[name="cojob"]', function() {
|
|
changeJobLabels(jQuery(this).val(), jQuery(this).closest('fieldset'))
|
|
});
|
|
|
|
/**
|
|
* Step 3
|
|
*/
|
|
jQuery('body').on('change', 'select[name="hometype"], select[name="cohometype"]', function(e) {
|
|
var val = jQuery(this).val(),
|
|
c = 'd-none',
|
|
cname = 'wpcf-' + jQuery(this).attr('name') + '--complement-home' + val,
|
|
elements = jQuery('.wpcf-' + jQuery(this).attr('name') + '--complement .form-group');
|
|
|
|
elements.addClass(c);
|
|
|
|
elements.each(function() {
|
|
if (jQuery(this).hasClass(cname)) {
|
|
jQuery('.' + cname).removeClass(c);
|
|
}
|
|
|
|
jQuery(this).find('input, select').attr('required', !jQuery(this).hasClass(c))
|
|
makeLabelRequired(jQuery(this).context)
|
|
})
|
|
|
|
});
|
|
|
|
var currentLoanProto = jQuery('.wpcf-currentloan--block').length > 0 ? jQuery('.wpcf-currentloan--block') : null;
|
|
var currentLoanCount = 0;
|
|
|
|
if (currentLoanProto !== null) {
|
|
currentLoanProto.removeClass('wpcf-prototype');
|
|
currentLoanProto = currentLoanProto[0].outerHTML
|
|
jQuery('.wpcf-currentloan--block').remove()
|
|
}
|
|
|
|
var coCurrentLoanProto = jQuery('.wpcf-cocurrentloan--block').length > 0 ? jQuery('.wpcf-cocurrentloan--block') : null;
|
|
var coCurrentLoanCount = 0;
|
|
|
|
if (coCurrentLoanProto !== null) {
|
|
coCurrentLoanProto.removeClass('wpcf-prototype');
|
|
coCurrentLoanProto = coCurrentLoanProto[0].outerHTML
|
|
jQuery('.wpcf-cocurrentloan--block').remove()
|
|
}
|
|
|
|
jQuery('body').on('change', 'input[name="hascurrentloan"], input[name="cohascurrentloan"]', function(e) {
|
|
var selector = jQuery(this).attr('name') === 'hascurrentloan' ? '.wpcf-currentloan' : '.wpcf-cocurrentloan';
|
|
var elem = jQuery(selector),
|
|
c = 'd-none';
|
|
// Pour les radio, on vérifie la value sélectionnée
|
|
var isChecked = jQuery('input[name="' + jQuery(this).attr('name') + '"]:checked').val() == '1';
|
|
elem.toggleClass(c, !isChecked);
|
|
if (!isChecked) {
|
|
jQuery(this).attr('name') === 'hascurrentloan' ? jQuery('.wpcf-currentloan--block').remove() : jQuery('.wpcf-cocurrentloan--block').remove();
|
|
} else if (elem.find(selector + '--block').length < 1) {
|
|
jQuery(this).attr('name') === 'hascurrentloan' ? addCurrentLoan() : addCoCurrentLoan();
|
|
}
|
|
});
|
|
|
|
// Affichage initial au chargement de la page
|
|
function updateCurrentLoanVisibility() {
|
|
var isChecked = jQuery('input[name="hascurrentloan"]:checked').val() == '1';
|
|
jQuery('.wpcf-currentloan').toggleClass('d-none', !isChecked);
|
|
if (!isChecked) {
|
|
jQuery('.wpcf-currentloan--block').remove();
|
|
} else if (jQuery('.wpcf-currentloan--block').length < 1) {
|
|
addCurrentLoan();
|
|
}
|
|
var isCoChecked = jQuery('input[name="cohascurrentloan"]:checked').val() == '1';
|
|
jQuery('.wpcf-cocurrentloan').toggleClass('d-none', !isCoChecked);
|
|
if (!isCoChecked) {
|
|
jQuery('.wpcf-cocurrentloan--block').remove();
|
|
} else if (jQuery('.wpcf-cocurrentloan--block').length < 1) {
|
|
addCoCurrentLoan();
|
|
}
|
|
}
|
|
// Appel au chargement
|
|
updateCurrentLoanVisibility();
|
|
|
|
jQuery('body').on('click', 'button.wpcf-currentload--add, button.wpcf-cocurrentload--add', function(e) {
|
|
e.preventDefault()
|
|
jQuery(this).hasClass('wpcf-currentload--add') ? addCurrentLoan() : addCoCurrentLoan()
|
|
})
|
|
|
|
function addCurrentLoan() {
|
|
var newLoan = currentLoanProto.replaceAll('__number__', currentLoanCount)
|
|
jQuery(newLoan).insertBefore(jQuery('.wpcf-currentload--add'))
|
|
|
|
currentLoanCount++
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanAdded');
|
|
}
|
|
|
|
function addCoCurrentLoan() {
|
|
var newLoan = coCurrentLoanProto.replaceAll('__number__', coCurrentLoanCount)
|
|
jQuery(newLoan).insertBefore(jQuery('.wpcf-cocurrentload--add'))
|
|
|
|
coCurrentLoanCount++
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanAdded');
|
|
}
|
|
|
|
jQuery('body').on('click', '.wpcf-currentloan--block--remove, .wpcf-cocurrentloan--block--remove', function(e) {
|
|
e.preventDefault();
|
|
jQuery(this).parent().remove();
|
|
|
|
// Déclencher l'événement personnalisé pour la sauvegarde
|
|
$(document).trigger('currentLoanRemoved');
|
|
});
|
|
|
|
// Fonction pour afficher/cacher la zone isFichedDisplay
|
|
function displayIsFichedZone() {
|
|
var hasFiched = jQuery('input[name="isFiched"]:checked').length > 0 &&
|
|
jQuery('input[name="isFiched"]:checked').val() == 1;
|
|
|
|
jQuery('.isFichedDisplay').toggleClass('d-none', !hasFiched);
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var isFichedField = jQuery('input[name="isFiched"]:checked');
|
|
if (isFichedField.length > 0) {
|
|
displayIsFichedZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'input[name="isFiched"]', displayIsFichedZone);
|
|
|
|
// Fonction pour afficher/cacher la zone isIndependant
|
|
function displayIsIndependantZone() {
|
|
var isIndependant = jQuery('select[name="job"]').val() === '5';
|
|
jQuery('.isIndependant').toggleClass('d-none', !isIndependant);
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var jobSelect = jQuery('select[name="job"]');
|
|
if (jobSelect.length > 0) {
|
|
displayIsIndependantZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'select[name="job"]', displayIsIndependantZone);
|
|
|
|
// Fonction pour afficher/cacher la zone hasLoyer
|
|
function displayHasLoyerZone() {
|
|
var isLocataire = jQuery('select[name="housing_status"]').val() === 'locataire';
|
|
jQuery('.hasLoyer').toggleClass('d-none', !isLocataire);
|
|
}
|
|
|
|
// Vérifier l'état initial
|
|
var situationSelect = jQuery('select[name="housing_status"]');
|
|
if (situationSelect.length > 0) {
|
|
displayHasLoyerZone();
|
|
}
|
|
|
|
// Ajouter l'écouteur d'événement pour le changement
|
|
jQuery('body').on('change', 'select[name="housing_status"]', displayHasLoyerZone);
|
|
|
|
// Affichage de la taille totale des fichiers sélectionnés pour le champ IDpaycheck + vérification taille max 2 Mo
|
|
jQuery('body').on('change', '#IDpaycheck, #IDcopaycheck', function(e) {
|
|
var files = e.target.files;
|
|
var totalSize = 0;
|
|
var maxSize = 2 * 1024 * 1024; // 2 Mo en octets
|
|
var errorFiles = [];
|
|
for (var i = 0; i < files.length; i++) {
|
|
totalSize += files[i].size;
|
|
if (files[i].size > maxSize) {
|
|
errorFiles.push(files[i].name);
|
|
}
|
|
}
|
|
// Conversion en Mo, arrondi à 2 décimales
|
|
var totalSizeMo = (totalSize / (1024 * 1024)).toFixed(2);
|
|
// Création ou sélection de l'élément d'affichage
|
|
var infoId = 'paycheck-size-info';
|
|
var infoElem = jQuery('#' + infoId);
|
|
if (infoElem.length === 0) {
|
|
infoElem = jQuery('<div id="' + infoId + '" style="font-size:0.9em;color:#555;"></div>');
|
|
jQuery(this).after(infoElem);
|
|
}
|
|
// Création ou sélection de l'élément d'erreur
|
|
var errorId = 'paycheck-size-error';
|
|
var errorElem = jQuery('#' + errorId);
|
|
if (errorElem.length === 0) {
|
|
errorElem = jQuery('<div id="' + errorId + '" style="font-size:0.95em;color:#c00;"></div>');
|
|
infoElem.after(errorElem);
|
|
}
|
|
var submitBtn = jQuery('.form-submit button[type="submit"]');
|
|
if (files.length > 0) {
|
|
infoElem.text('Taille totale des fichiers sélectionnés : ' + totalSizeMo + ' Mo');
|
|
} else {
|
|
infoElem.text('');
|
|
}
|
|
if (errorFiles.length > 0) {
|
|
errorElem.html('Fichier(s) trop volumineux (> 2 Mo) :<br><b>' + errorFiles.join(', ') + '</b>');
|
|
submitBtn.prop('disabled', true);
|
|
} else {
|
|
errorElem.text('');
|
|
submitBtn.prop('disabled', false);
|
|
}
|
|
});
|
|
|
|
// Affichage conditionnel du champ "fonds propres" selon le choix Oui/Non avec effet slide
|
|
const yesRadio = document.getElementById('estateequity_yes');
|
|
const noRadio = document.getElementById('estateequity_no');
|
|
if (yesRadio && noRadio) {
|
|
$(yesRadio).on('change', function() {
|
|
if (yesRadio.checked) {
|
|
$('.fonds-propres').stop(true, true).slideDown();
|
|
$('[name="estateequity"]').prop('required', true);
|
|
}
|
|
});
|
|
$(noRadio).on('change', function() {
|
|
if (noRadio.checked) {
|
|
$('.fonds-propres').stop(true, true).slideUp();
|
|
$('[name="estateequity"]').prop('required', false);
|
|
}
|
|
});
|
|
// Initialisation à l'ouverture de la page
|
|
if (yesRadio.checked) {
|
|
$('.fonds-propres').show();
|
|
} else {
|
|
$('.fonds-propres').hide();
|
|
}
|
|
}
|
|
|
|
// Variables pour le debouncing des inputs
|
|
let capitalTimeout;
|
|
let durationTimeout;
|
|
let isCreditCalculationEnabled = true;
|
|
|
|
if(jQuery('#creditCalcManualSwitch').length > 0)
|
|
isCreditCalculationEnabled = true;
|
|
|
|
// Liste des types de crédit qui utilisent des années
|
|
const LOAN_TYPES_IN_YEARS = ['am', 'amr', 'cied', 'ph'];
|
|
|
|
// Fonction pour mettre à jour l'affichage des valeurs calculées
|
|
function updateCreditDisplay(result) {
|
|
console.log('updateCreditDisplay - result:', result);
|
|
|
|
// Calcul du TAEG
|
|
const taeg = parseFloat(result.taux_nominal_annuel.replace('%', ''));
|
|
const taux_debiteur = (taeg * 0.11 + taeg).toFixed(2);
|
|
|
|
// Mise à jour des champs cachés
|
|
jQuery('input[name="capital"]').val(result.capital);
|
|
jQuery('input[name="duree"]').val(result.duree);
|
|
jQuery('input[name="cout_total"]').val(result.cout_total);
|
|
jQuery('input[name="mensualite"]').val(result.mensualite);
|
|
jQuery('input[name="taux_nominal_annuel"]').val(result.taux_nominal_annuel);
|
|
|
|
console.log('updateCreditDisplay - Champs cachés mis à jour:', {
|
|
capital: result.capital,
|
|
duree: result.duree,
|
|
cout_total: result.cout_total,
|
|
mensualite: result.mensualite,
|
|
taux: result.taux_nominal_annuel
|
|
});
|
|
|
|
// Mise à jour de l'affichage dans .credit-info
|
|
jQuery('.credit-info .credit-item').each(function() {
|
|
var $value = jQuery(this).find('.credit-value');
|
|
var $label = jQuery(this).find('.credit-label');
|
|
|
|
if($label.text().includes('Montant:')) {
|
|
$value.text(result.capital + ' €');
|
|
}
|
|
else if($label.text().includes('Durée:')) {
|
|
$value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois'));
|
|
}
|
|
else if($label.text().includes('Mensualité:')) {
|
|
$value.text(result.mensualite + '€');
|
|
}
|
|
else if($label.text().includes('Coût total:')) {
|
|
$value.text(result.cout_total + '€');
|
|
}
|
|
else if($label.text().includes('TAEG:')) {
|
|
$value.text(taux_debiteur + '%');
|
|
}
|
|
else if($label.text().includes('Taux débiteur:')) {
|
|
$value.text(result.taux_nominal_annuel);
|
|
}
|
|
});
|
|
|
|
// Mise à jour du récapitulatif dans .info-credits-step
|
|
jQuery('.info-credits-step .row > div').each(function() {
|
|
$(this).find('p').each(function() {
|
|
var $label = $(this);
|
|
var $value = $label.next('span');
|
|
|
|
if($label.text().includes('Montant emprunté :')) {
|
|
$value.text(result.capital + ' €');
|
|
}
|
|
else if($label.text().includes('Durée :')) {
|
|
$value.text(result.duree + ($('input[name="type_credit"]').val() === 'am' ? ' ans' : ' mois'));
|
|
}
|
|
else if($label.text().includes('Mensualité :')) {
|
|
$value.text(result.mensualite + ' €');
|
|
}
|
|
else if($label.text().includes('Coût Total :')) {
|
|
$value.text(result.cout_total + ' €');
|
|
}
|
|
else if($label.text().includes('Taux débiteur :')) {
|
|
$value.text(result.taux_nominal_annuel);
|
|
}
|
|
else if($label.text().includes('Taeg :')) {
|
|
$value.text(taux_debiteur + '%');
|
|
}
|
|
});
|
|
});
|
|
|
|
console.log('updateCreditDisplay - Affichage mis à jour');
|
|
}
|
|
|
|
// Fonction pour mettre à jour les limites et valeurs des champs selon le type de crédit
|
|
function updateFieldLimits(selectedType) {
|
|
const creditType = map_values[selectedType];
|
|
if (!creditType) {
|
|
console.warn('Type de crédit non reconnu:', selectedType);
|
|
return;
|
|
}
|
|
|
|
const $capitalField = jQuery('#IDbatiment_emprunt');
|
|
const $durationField = jQuery('#IDbatiment_duree');
|
|
let currentCapital = parseFloat($capitalField.val());
|
|
|
|
// Récupérer les limites depuis form_sliders pour les durées
|
|
const sliderConfig = form_sliders[creditType];
|
|
if (!sliderConfig) {
|
|
console.warn('Configuration slider non trouvée pour:', creditType);
|
|
return;
|
|
}
|
|
|
|
// Récupérer les limites spécifiques du crédit depuis cd_js.groups
|
|
const creditConfig = cd_js.groups[selectedType];
|
|
if (creditConfig && creditConfig.capital_max) {
|
|
// Ne modifier le montant que s'il dépasse la limite du crédit choisi
|
|
if (currentCapital > creditConfig.capital_max) {
|
|
currentCapital = creditConfig.capital_selected || creditConfig.capital_max;
|
|
$capitalField.val(currentCapital);
|
|
}
|
|
}
|
|
|
|
// Mettre à jour les attributs min/max du champ capital
|
|
$capitalField.attr('min', sliderConfig.capital_min);
|
|
$capitalField.attr('max', sliderConfig.capital_max);
|
|
$capitalField.attr('step', sliderConfig.capital_step || 100);
|
|
|
|
// Ajuster la valeur du capital si nécessaire selon les limites du slider
|
|
if (currentCapital > sliderConfig.capital_max) {
|
|
currentCapital = sliderConfig.capital_max;
|
|
$capitalField.val(currentCapital);
|
|
} else if (currentCapital < sliderConfig.capital_min) {
|
|
currentCapital = sliderConfig.capital_min;
|
|
$capitalField.val(currentCapital);
|
|
}
|
|
|
|
// Déterminer la durée maximale disponible pour ce montant
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
let maxDurationForAmount = sliderConfig.durees[sliderConfig.durees.length - 1];
|
|
|
|
// Parcourir les durées disponibles dans l'ordre décroissant
|
|
for (let i = sliderConfig.durees.length - 1; i >= 0; i--) {
|
|
const duration = sliderConfig.durees[i];
|
|
// Vérifier si cette durée est valide pour le montant actuel
|
|
if (currentCapital >= sliderConfig.capital_min && currentCapital <= sliderConfig.capital_max) {
|
|
maxDurationForAmount = duration;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Convertir la durée maximale en années si nécessaire
|
|
const displayDuration = isYearlyDuration ? Math.floor(maxDurationForAmount / 12) : maxDurationForAmount;
|
|
const minDuration = isYearlyDuration ? Math.ceil(sliderConfig.duree_min / 12) : sliderConfig.duree_min;
|
|
const maxDuration = isYearlyDuration ? Math.floor(sliderConfig.duree_max / 12) : sliderConfig.duree_max;
|
|
|
|
// Mettre à jour les attributs min/max du champ durée
|
|
$durationField.attr('min', minDuration);
|
|
$durationField.attr('max', maxDuration);
|
|
|
|
// Définir la durée maximale disponible
|
|
$durationField.val(displayDuration);
|
|
|
|
// Mettre à jour l'unité dans l'input-group-text
|
|
jQuery('.input-group-text').text(isYearlyDuration ? 'Ans' : 'Mois');
|
|
|
|
// Mettre à jour l'affichage
|
|
calculateCredit();
|
|
|
|
// Mettre à jour le champ caché type_credit
|
|
jQuery('input[name="type_credit"]').val(creditType);
|
|
}
|
|
|
|
// Gestionnaire pour le changement de type de crédit
|
|
jQuery('#IDestateloantype').on('change', function() {
|
|
const creditType = jQuery(this).val();
|
|
if (creditType) {
|
|
updateFieldLimits(creditType);
|
|
calculateCredit();
|
|
}
|
|
});
|
|
|
|
// Fonction pour arrondir le capital à la valeur acceptable la plus proche
|
|
function snapCapitalValue(value, creditType) {
|
|
if (!creditType || !form_sliders[creditType]) {
|
|
return value;
|
|
}
|
|
|
|
const sliderConfig = form_sliders[creditType];
|
|
|
|
// Utiliser le step défini dans form_sliders
|
|
const step = sliderConfig.capital_step || 100;
|
|
|
|
// S'assurer que la valeur est dans les limites
|
|
value = Math.max(sliderConfig.capital_min, Math.min(value, sliderConfig.capital_max));
|
|
|
|
// Arrondir à la valeur la plus proche selon le step
|
|
return Math.round(value / step) * step;
|
|
}
|
|
|
|
// Fonction pour arrondir la durée à la valeur acceptable la plus proche
|
|
function snapDurationValue(value, creditType) {
|
|
if (!creditType || !form_sliders[creditType]) {
|
|
return value;
|
|
}
|
|
|
|
const sliderConfig = form_sliders[creditType];
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
|
|
console.log('snapDurationValue - value:', value);
|
|
console.log('snapDurationValue - creditType:', creditType);
|
|
console.log('snapDurationValue - isYearlyDuration:', isYearlyDuration);
|
|
|
|
if (isYearlyDuration) {
|
|
// Pour les crédits en années, on vérifie juste les limites min/max
|
|
// Les limites sont déjà en années pour ces types de crédit
|
|
const minYears = sliderConfig.duree_min;
|
|
const maxYears = sliderConfig.duree_max;
|
|
|
|
console.log('snapDurationValue - minYears:', minYears);
|
|
console.log('snapDurationValue - maxYears:', maxYears);
|
|
|
|
if (value > maxYears) return maxYears;
|
|
if (value < minYears) return minYears;
|
|
return value;
|
|
} else {
|
|
// Pour les autres crédits, on cherche la durée disponible la plus proche
|
|
let closestDuration = sliderConfig.durees[0];
|
|
let minDiff = Math.abs(value - sliderConfig.durees[0]);
|
|
|
|
for (let i = 1; i < sliderConfig.durees.length; i++) {
|
|
const diff = Math.abs(value - sliderConfig.durees[i]);
|
|
if (diff < minDiff) {
|
|
minDiff = diff;
|
|
closestDuration = sliderConfig.durees[i];
|
|
}
|
|
}
|
|
return closestDuration;
|
|
}
|
|
}
|
|
|
|
// Fonction pour calculer la mensualité
|
|
function calc_mens(mnt, dur, taeg) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
|
|
// Pour le crédit pont, on ne calcule que les intérêts mensuels
|
|
if (creditType === 'cdp') {
|
|
const t100 = taeg / 100;
|
|
// Calcul des intérêts mensuels uniquement : (capital * taux_annuel) / 12
|
|
const mens = (mnt * t100) / 12;
|
|
return Math.floor(mens * 100) / 100;
|
|
}
|
|
|
|
// Pour les autres types de crédit, calcul normal
|
|
const t100 = taeg / 100;
|
|
const t101 = 1 + t100;
|
|
const d12 = 1 / 12;
|
|
const dur12 = dur / 12;
|
|
const buf1 = Math.pow(t101, d12);
|
|
const buf2 = Math.pow(1 / t101, dur12);
|
|
const mens = (mnt * (buf1 - 1)) / (1 - buf2);
|
|
|
|
return Math.floor(mens * 100) / 100;
|
|
}
|
|
|
|
// Notre propre fonction de calcul qui utilise les fonctions de base de cd_main.js
|
|
function calculateCredit() {
|
|
const capital = parseFloat(jQuery('#IDbatiment_emprunt').val());
|
|
const duration = parseInt(jQuery('#IDbatiment_duree').val());
|
|
const selectedType = jQuery('#IDestateloantype').val();
|
|
const creditType = map_values[selectedType];
|
|
|
|
console.log('=== Début calcul crédit ===');
|
|
console.log('Type sélectionné:', selectedType);
|
|
console.log('Type de crédit mappé:', creditType);
|
|
console.log('Capital:', capital);
|
|
console.log('Durée:', duration);
|
|
|
|
if (isNaN(capital) || isNaN(duration) || !creditType) {
|
|
console.warn('Valeurs invalides pour le calcul:', {
|
|
capital: isNaN(capital) ? 'invalide' : capital,
|
|
duration: isNaN(duration) ? 'invalide' : duration,
|
|
selectedType,
|
|
creditType: !creditType ? 'non mappé' : creditType
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Convertir la durée en mois si nécessaire pour les calculs
|
|
const isYearlyDuration = LOAN_TYPES_IN_YEARS.includes(creditType);
|
|
const durationForCalculation = isYearlyDuration ? duration * 12 : duration;
|
|
|
|
console.log('Durée pour calcul:', durationForCalculation, isYearlyDuration ? '(en années)' : '(en mois)');
|
|
|
|
let results;
|
|
// Appeler la fonction de calcul appropriée
|
|
switch(creditType) {
|
|
case 'pat':
|
|
results = calculate_pat(capital, duration);
|
|
break;
|
|
case 'am':
|
|
results = calculate_am(capital, duration);
|
|
break;
|
|
case 'ph':
|
|
results = calculate_ph(capital, duration);
|
|
break;
|
|
case 'amr':
|
|
case 'cdp':
|
|
case 'cied':
|
|
results = calculate_mono_rate_bt_10_30(creditType, capital, duration);
|
|
break;
|
|
case 'fin_neuve':
|
|
results = calculate_fin_neuve(capital, duration);
|
|
break;
|
|
case 'fin_occ_m3a':
|
|
results = calculate_pao_m_3(capital, duration);
|
|
break;
|
|
case 'fin_occ_p3a':
|
|
results = calculate_pao_p_3(capital, duration);
|
|
break;
|
|
case 'mobil_carav':
|
|
results = calculate_mobilhome(capital, duration);
|
|
break;
|
|
case 'regroup_cred':
|
|
results = calculate_regroupement_de_credit(capital, duration);
|
|
break;
|
|
case 'frais_notaire':
|
|
results = calculate_frais_notaire(capital, duration);
|
|
break;
|
|
case 'but_immo':
|
|
results = calculate_but_immo(capital, duration);
|
|
break;
|
|
default:
|
|
console.warn('Type de crédit non reconnu:', creditType);
|
|
results = calculate_pat(capital, duration);
|
|
}
|
|
|
|
if (!results) {
|
|
console.warn('Pas de résultats retournés par la fonction de calcul');
|
|
return;
|
|
}
|
|
|
|
console.log('Résultats bruts:', results);
|
|
|
|
// Extraire les valeurs des résultats
|
|
const [min_duration, max_duration, selected_duration, duree_in_range, taux_nominal] = results;
|
|
|
|
// Convertir le taux en nombre si c'est une chaîne
|
|
const taux = parseFloat(String(taux_nominal).replace('%', ''));
|
|
|
|
if (isNaN(taux)) {
|
|
console.error('Taux nominal invalide après conversion:', {
|
|
original: taux_nominal,
|
|
converti: taux
|
|
});
|
|
return;
|
|
}
|
|
|
|
console.log('Taux nominal (débiteur):', taux + '%');
|
|
console.log('Durée sélectionnée:', selected_duration, isYearlyDuration ? 'mois (convertie)' : 'mois');
|
|
|
|
// Pour les crédits en années, la durée retournée est déjà en mois
|
|
const durationInMonths = isYearlyDuration ? durationForCalculation : selected_duration;
|
|
|
|
// Calculer la mensualité avec notre fonction locale
|
|
const mensualite = calc_mens(capital, durationInMonths, taux);
|
|
|
|
if (isNaN(mensualite)) {
|
|
console.error('Erreur dans le calcul de la mensualité:', {
|
|
capital,
|
|
durationInMonths,
|
|
taux
|
|
});
|
|
return;
|
|
}
|
|
|
|
const cout_total = (mensualite * durationInMonths).toFixed(2);
|
|
|
|
console.log('Mensualité calculée:', mensualite.toFixed(2) + '€');
|
|
console.log('Coût total calculé:', cout_total + '€');
|
|
|
|
// Créer l'objet result pour updateCreditDisplay
|
|
const displayResult = {
|
|
capital: capital,
|
|
duree: duration,
|
|
mensualite: mensualite.toFixed(2),
|
|
cout_total: cout_total,
|
|
taux_nominal_annuel: taux.toFixed(2) + ' %',
|
|
taux_debiteur: taux.toFixed(2) + ' %'
|
|
};
|
|
|
|
console.log('Résultat final pour affichage:', displayResult);
|
|
console.log('--- Fin calcul crédit ---');
|
|
|
|
// Mettre à jour l'affichage
|
|
updateCreditDisplay(displayResult);
|
|
|
|
// Mettre à jour le champ caché type_credit
|
|
jQuery('input[name="type_credit"]').val(creditType);
|
|
}
|
|
|
|
if(isCreditCalculationEnabled) {
|
|
// Remplacer tous les appels à calculate_mensualite par calculateCredit
|
|
jQuery('#IDbatiment_emprunt')
|
|
.on('input', function() {
|
|
const $this = jQuery(this);
|
|
clearTimeout(capitalTimeout);
|
|
|
|
if ($this.val() !== '') {
|
|
capitalTimeout = setTimeout(() => {
|
|
let capital = parseFloat($this.val());
|
|
if (!isNaN(capital)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
const snappedValue = snapCapitalValue(capital, creditType);
|
|
if (snappedValue !== capital) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}, 500); // Délai un peu plus long pour laisser le temps de taper
|
|
}
|
|
})
|
|
.on('change', function() {
|
|
// Validation finale quand on quitte le champ (onblur)
|
|
const $this = jQuery(this);
|
|
if ($this.val() !== '') {
|
|
let capital = parseFloat($this.val());
|
|
if (!isNaN(capital)) {
|
|
const selectedType = jQuery('#IDestateloantype').val();
|
|
const creditConfig = cd_js.groups[selectedType];
|
|
|
|
// Vérifier les limites du crédit
|
|
if (creditConfig && creditConfig.capital_max && capital > creditConfig.capital_max) {
|
|
capital = creditConfig.capital_selected || creditConfig.capital_max;
|
|
$this.val(capital);
|
|
}
|
|
|
|
// Snap à la valeur la plus proche et recalcul
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
const snappedValue = snapCapitalValue(capital, creditType);
|
|
if (snappedValue !== capital) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}
|
|
});
|
|
|
|
jQuery('#IDbatiment_duree')
|
|
.on('input', function() {
|
|
const $this = jQuery(this);
|
|
clearTimeout(durationTimeout);
|
|
durationTimeout = setTimeout(() => {
|
|
let duration = parseInt($this.val());
|
|
if (!isNaN(duration)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
console.log('Input duration:', duration);
|
|
console.log('Credit type:', creditType);
|
|
console.log('Is yearly:', LOAN_TYPES_IN_YEARS.includes(creditType));
|
|
|
|
// Ne pas snapper pendant la saisie pour les crédits en années
|
|
if (LOAN_TYPES_IN_YEARS.includes(creditType)) {
|
|
calculateCredit();
|
|
} else {
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
if (snappedValue !== duration) {
|
|
$this.val(snappedValue);
|
|
}
|
|
calculateCredit();
|
|
}
|
|
}
|
|
}, 300);
|
|
})
|
|
.on('change', function() {
|
|
let duration = parseInt($(this).val());
|
|
if (!isNaN(duration)) {
|
|
const creditType = jQuery('input[name="type_credit"]').val();
|
|
console.log('onchange - creditType:', creditType);
|
|
console.log('onchange - LOAN_TYPES_IN_YEARS:', LOAN_TYPES_IN_YEARS);
|
|
console.log('onchange - includes?', LOAN_TYPES_IN_YEARS.includes(creditType));
|
|
|
|
if (LOAN_TYPES_IN_YEARS.includes(creditType)) {
|
|
console.log('change', duration);
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
console.log('snappedValue', snappedValue);
|
|
if (snappedValue !== duration) {
|
|
$(this).val(snappedValue);
|
|
}
|
|
} else {
|
|
// Pour les autres crédits, comportement normal
|
|
const snappedValue = snapDurationValue(duration, creditType);
|
|
if (snappedValue !== duration) {
|
|
$(this).val(snappedValue);
|
|
}
|
|
}
|
|
calculateCredit();
|
|
}
|
|
});
|
|
|
|
// Calcul initial au chargement
|
|
/* $(document).ready(function() {
|
|
const creditType = $('input[name="type_credit"]').val();
|
|
if (creditType) {
|
|
updateFieldLimits(creditType);
|
|
calculateCredit();
|
|
}
|
|
}); */
|
|
|
|
// Gestionnaire pour la soumission du formulaire
|
|
jQuery('.form-submit').on('submit', function() {
|
|
// Recalculer une dernière fois avant l'envoi
|
|
calculateCredit();
|
|
});
|
|
}
|
|
|
|
function findRate(type) {
|
|
console.log('findRate - Type recherché:', type);
|
|
let rate;
|
|
|
|
switch(type) {
|
|
case 'amr':
|
|
rate = cd_js.groups.achat_maison_de_rapport.de_10_a_30_ans;
|
|
break;
|
|
case 'cdp':
|
|
rate = cd_js.groups.credit_pont.de_10_a_30_ans;
|
|
break;
|
|
case 'cied':
|
|
rate = cd_js.groups.independants_et_entreprises_en_difficultes.de_10_a_30_ans;
|
|
break;
|
|
default:
|
|
console.warn('Type de crédit non reconnu pour le taux mono:', type);
|
|
rate = null;
|
|
}
|
|
|
|
console.log('findRate - Taux trouvé:', rate);
|
|
return rate;
|
|
}
|
|
|
|
function calculate_mono_rate_bt_10_30(type, selected_capital, selected_duration) {
|
|
const annual_rate = findRate(type);
|
|
if (!annual_rate) {
|
|
console.error('Taux non trouvé pour le type:', type);
|
|
return null;
|
|
}
|
|
|
|
const min_duration = 10;
|
|
const max_duration = 30;
|
|
let duree_in_range = true;
|
|
const add_message = '';
|
|
|
|
if (min_duration <= parseInt(selected_duration) && parseInt(selected_duration) <= max_duration) {
|
|
// La durée est dans la plage
|
|
} else {
|
|
duree_in_range = false;
|
|
selected_duration = max_duration;
|
|
}
|
|
|
|
// Convertir la durée en mois pour le calcul
|
|
selected_duration = selected_duration * 12;
|
|
|
|
return [min_duration, max_duration, selected_duration, duree_in_range, annual_rate, add_message];
|
|
}
|
|
|
|
}); |