@@ -858,9 +950,10 @@
"tab.basic": "Setup",
"tab.advanced": "Options",
"tab.custom": "Cars",
- "section.required": "📝 Required Information",
- "section.vehicles": "🚗 Select Your Company Cars",
- "section.calculated": "⚙️ Calculated Parameters (Adjustable)",
+ "section.essential": "🎯 Essential Information - Fill These First",
+ "section.vehicles": "🚗 Select Your Company Car",
+ "section.additional": "📊 Additional Information",
+ "section.calculated": "Calculated Parameters (Adjustable)",
"section.advancedOptions": "Advanced Options",
"section.options": "Display Options",
"section.personal": "Personal Information",
@@ -875,6 +968,7 @@
"label.currentAge": "Current Age",
"label.retirementAge": "Retirement Age",
"label.yearsWork": "Years to Work",
+ "label.leaseDuration": "Company Car Duration",
"label.retirementYears": "Years in Retirement",
"label.lifeExpectancy": "Life Expectancy",
"label.salaryGrowth": "Annual Salary Growth",
@@ -892,6 +986,7 @@
"help.currentAge": "Your age today",
"help.retirementAge": "Expected retirement age",
"help.yearsWork": "Automatically calculated",
+ "help.leaseDuration": "How long you'll have the company car",
"help.retirementYears": "Expected years receiving pension",
"help.lifeExpectancy": "Updates retirement years automatically",
"help.salaryGrowth": "Expected annual salary increase percentage",
@@ -899,10 +994,16 @@
"help.discountRate": "For present value calculations percentage",
"help.employerPension": "Additional employer pension percentage",
"help.mobilityBudget": "38.07% contribution for pension rights",
- "option.single": "Single / Double Income",
- "option.married": "Married (single income)",
+ "option.single": "Single",
+ "option.married": "Married (spouse no income)",
+ "option.cohabiting": "Legal Cohabitation",
+ "option.divorced": "Divorced",
+ "option.marriedDual": "Married (both working)",
"option.no": "No",
"option.yes": "Yes - Show comparison",
+ "option.untilRetirement": "Until Retirement",
+ "placeholder.maritalStatus": "Choose your status...",
+ "placeholder.leaseDuration": "How long will you have it?",
"option.includeInflation": "Adjust for inflation in calculations",
"option.includePresentValue": "Show present value of losses",
"option.includeElectric": "Include electric vehicle comparison",
@@ -960,9 +1061,10 @@
"tab.basic": "Config",
"tab.advanced": "Options",
"tab.custom": "Véhicules",
- "section.required": "📝 Informations Obligatoires",
- "section.vehicles": "🚗 Sélectionnez vos Voitures de Société",
- "section.calculated": "⚙️ Paramètres Calculés (Ajustables)",
+ "section.essential": "🎯 Informations Essentielles - Remplir en Premier",
+ "section.vehicles": "🚗 Sélectionnez votre Voiture de Société",
+ "section.additional": "📊 Informations Supplémentaires",
+ "section.calculated": "Paramètres Calculés (Ajustables)",
"section.advancedOptions": "Options Avancées",
"section.options": "Options d'Affichage",
"section.personal": "Informations Personnelles",
@@ -977,6 +1079,7 @@
"label.currentAge": "Âge Actuel",
"label.retirementAge": "Âge de Retraite",
"label.yearsWork": "Années de Travail",
+ "label.leaseDuration": "Durée Voiture de Société",
"label.retirementYears": "Années de Retraite",
"label.lifeExpectancy": "Espérance de Vie",
"label.salaryGrowth": "Croissance Salariale Annuelle",
@@ -994,6 +1097,7 @@
"help.currentAge": "Votre âge aujourd'hui",
"help.retirementAge": "Âge de retraite prévu",
"help.yearsWork": "Calculé automatiquement",
+ "help.leaseDuration": "Durée prévue de la voiture de société",
"help.retirementYears": "Années prévues de perception de pension",
"help.lifeExpectancy": "Met à jour automatiquement les années de retraite",
"help.salaryGrowth": "Pourcentage d'augmentation salariale annuelle prévue",
@@ -1001,10 +1105,16 @@
"help.discountRate": "Pour les calculs de valeur actuelle en pourcentage",
"help.employerPension": "Pourcentage de pension employeur supplémentaire",
"help.mobilityBudget": "38,07% de contribution pour les droits à la pension",
- "option.single": "Célibataire / Double Revenu",
- "option.married": "Marié (revenu unique)",
+ "option.single": "Célibataire",
+ "option.married": "Marié (conjoint sans revenu)",
+ "option.cohabiting": "Cohabitation Légale",
+ "option.divorced": "Divorcé(e)",
+ "option.marriedDual": "Marié (les deux travaillent)",
"option.no": "Non",
"option.yes": "Oui - Afficher la comparaison",
+ "option.untilRetirement": "Jusqu'à la Retraite",
+ "placeholder.maritalStatus": "Choisissez votre statut...",
+ "placeholder.leaseDuration": "Combien de temps l'aurez-vous?",
"option.includeInflation": "Ajuster pour l'inflation dans les calculs",
"option.includePresentValue": "Afficher la valeur actuelle des pertes",
"option.includeElectric": "Inclure la comparaison de véhicules électriques",
@@ -1062,9 +1172,10 @@
"tab.basic": "Basis",
"tab.advanced": "Opties",
"tab.custom": "Auto's",
- "section.required": "📝 Verplichte Informatie",
- "section.vehicles": "🚗 Selecteer uw Bedrijfswagens",
- "section.calculated": "⚙️ Berekende Parameters (Aanpasbaar)",
+ "section.essential": "🎯 Essentiële Informatie - Vul Deze Eerst In",
+ "section.vehicles": "🚗 Selecteer uw Bedrijfswagen",
+ "section.additional": "📊 Aanvullende Informatie",
+ "section.calculated": "Berekende Parameters (Aanpasbaar)",
"section.advancedOptions": "Geavanceerde Opties",
"section.options": "Weergaveopties",
"section.personal": "Persoonlijke Informatie",
@@ -1079,6 +1190,7 @@
"label.currentAge": "Huidige Leeftijd",
"label.retirementAge": "Pensioenleeftijd",
"label.yearsWork": "Jaren Werken",
+ "label.leaseDuration": "Bedrijfswagen Duur",
"label.retirementYears": "Jaren Pensioen",
"label.lifeExpectancy": "Levensverwachting",
"label.salaryGrowth": "Jaarlijkse Salarisgroei",
@@ -1096,6 +1208,7 @@
"help.currentAge": "Uw leeftijd vandaag",
"help.retirementAge": "Verwachte pensioenleeftijd",
"help.yearsWork": "Automatisch berekend",
+ "help.leaseDuration": "Hoe lang u de bedrijfswagen zult hebben",
"help.retirementYears": "Verwachte jaren pensioenuitkering",
"help.lifeExpectancy": "Werkt pensioenjaren automatisch bij",
"help.salaryGrowth": "Verwacht jaarlijks salarissverhoging percentage",
@@ -1103,10 +1216,16 @@
"help.discountRate": "Voor huidige waarde berekeningen percentage",
"help.employerPension": "Extra werkgever pensioenpercentage",
"help.mobilityBudget": "38,07% bijdrage voor pensioenrechten",
- "option.single": "Alleenstaand / Dubbel Inkomen",
- "option.married": "Getrouwd (enkel inkomen)",
+ "option.single": "Alleenstaand",
+ "option.married": "Getrouwd (partner geen inkomen)",
+ "option.cohabiting": "Wettelijk Samenwonend",
+ "option.divorced": "Gescheiden",
+ "option.marriedDual": "Getrouwd (beiden werkend)",
"option.no": "Nee",
"option.yes": "Ja - Toon vergelijking",
+ "option.untilRetirement": "Tot Pensioen",
+ "placeholder.maritalStatus": "Kies uw status...",
+ "placeholder.leaseDuration": "Hoe lang zult u het hebben?",
"option.includeInflation": "Aanpassen voor inflatie in berekeningen",
"option.includePresentValue": "Toon huidige waarde van verliezen",
"option.includeElectric": "Elektrische voertuig vergelijking opnemen",
@@ -1259,12 +1378,19 @@
}
function updateSelectOptions() {
- // Update marital status options
+ // Update marital status options - skip placeholder and map correctly
const maritalSelect = document.getElementById('marital-status');
if (maritalSelect) {
const maritalOptions = maritalSelect.querySelectorAll('option');
- maritalOptions[0].textContent = translations[currentLanguage]['option.single'];
- maritalOptions[1].textContent = translations[currentLanguage]['option.married'];
+ // Skip the placeholder option [0] and update the actual options
+ if (maritalOptions.length >= 6) {
+ maritalOptions[0].textContent = translations[currentLanguage]['placeholder.maritalStatus']; // placeholder
+ maritalOptions[1].textContent = translations[currentLanguage]['option.single']; // single
+ maritalOptions[2].textContent = translations[currentLanguage]['option.married']; // married
+ maritalOptions[3].textContent = translations[currentLanguage]['option.cohabiting']; // cohabiting
+ maritalOptions[4].textContent = translations[currentLanguage]['option.divorced']; // divorced
+ maritalOptions[5].textContent = translations[currentLanguage]['option.marriedDual']; // married-dual
+ }
}
// Mobility budget is now a checkbox, no options to update
@@ -1320,13 +1446,202 @@
// Removed switchTab function - no longer using tabs
+ // Progress monitoring functions
+ function checkEssentialFields() {
+ const requiredFields = ['gross-salary', 'current-age', 'tax-rate', 'marital-status', 'lease-duration'];
+ let allFilled = true;
+
+ for (const fieldId of requiredFields) {
+ const element = document.getElementById(fieldId);
+ if (!element.value || element.value.trim() === '') {
+ allFilled = false;
+ break;
+ }
+ }
+
+ // Step indicators removed - no need to update status
+ if (allFilled) {
+ enableVehicleSelection();
+ } else {
+ disableVehicleSelection();
+ disableCalculateButton();
+ hideCalculatedSection(); // Hide calculated parameters when Step 1 incomplete
+ }
+
+ return allFilled;
+ }
+
+ // Step status function removed - no longer needed without step indicators
+
+ function enableVehicleSelection() {
+ const vehicleSection = document.getElementById('vehicle-section');
+ if (vehicleSection) {
+ // Show the Step 2 section
+ vehicleSection.style.display = 'block';
+ vehicleSection.style.opacity = '1';
+ vehicleSection.style.border = '1px solid #d97706';
+ vehicleSection.style.background = 'linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%)';
+
+ // Style the section title
+ const sectionTitle = vehicleSection.querySelector('.section-title');
+ if (sectionTitle) {
+ sectionTitle.style.color = '#d97706';
+ }
+
+ // Enable the vehicle search system
+ if (vehicleAutocomplete && typeof vehicleAutocomplete.enable === 'function') {
+ try {
+ vehicleAutocomplete.enable();
+ } catch (error) {
+ console.error('Error enabling vehicle search:', error);
+ }
+ } else {
+ console.warn('vehicleAutocomplete not available for enabling');
+ }
+ }
+ }
+
+ function disableVehicleSelection() {
+ const vehicleSection = document.getElementById('vehicle-section');
+ if (vehicleSection) {
+ // Completely hide Step 2 section instead of just disabling
+ vehicleSection.style.display = 'none';
+
+ // Reset the styling when hiding
+ vehicleSection.style.opacity = '0.6';
+ vehicleSection.style.border = '1px solid #e5e7eb';
+ vehicleSection.style.background = '#f9fafb';
+
+ // Reset section title styling
+ const sectionTitle = vehicleSection.querySelector('.section-title');
+ if (sectionTitle) {
+ sectionTitle.style.color = '#6b7280';
+ }
+
+ // Disable the vehicle search system
+ if (vehicleAutocomplete && typeof vehicleAutocomplete.disable === 'function') {
+ try {
+ vehicleAutocomplete.disable();
+ } catch (error) {
+ console.error('Error disabling vehicle search:', error);
+ }
+ } else {
+ console.warn('vehicleAutocomplete not available for disabling');
+ }
+ }
+ }
+
+ function checkVehicleSelected() {
+ const customCarsList = document.getElementById('custom-cars-list');
+ const hasVehicle = customCarsList && customCarsList.children.length > 0;
+
+ // Check vehicle status without updating step indicators
+ if (hasVehicle) {
+ enableCalculateButton();
+ showCalculatedSection(); // Show calculated parameters when vehicle is selected
+ } else {
+ disableCalculateButton();
+ hideCalculatedSection(); // Hide calculated parameters when no vehicle
+ }
+
+ return hasVehicle;
+ }
+
+ function enableCalculateButton() {
+ const calculateSection = document.getElementById('calculate-section');
+ const calculateBtn = document.getElementById('calculate-btn');
+
+ if (calculateSection && calculateBtn) {
+ calculateSection.style.opacity = '1';
+ calculateBtn.disabled = false;
+ calculateBtn.style.background = '#059669';
+ calculateBtn.style.color = 'white';
+ calculateBtn.style.cursor = 'pointer';
+ calculateBtn.onmouseover = function() {
+ this.style.background = '#047857';
+ this.style.transform = 'translateY(-2px)';
+ };
+ calculateBtn.onmouseout = function() {
+ this.style.background = '#059669';
+ this.style.transform = 'translateY(0)';
+ };
+
+ // Button is now enabled and styled
+ }
+ }
+
+ function disableCalculateButton() {
+ const calculateSection = document.getElementById('calculate-section');
+ const calculateBtn = document.getElementById('calculate-btn');
+
+ if (calculateSection && calculateBtn) {
+ calculateSection.style.opacity = '0.3';
+ calculateBtn.disabled = true;
+ calculateBtn.style.background = '#d1d5db';
+ calculateBtn.style.color = '#9ca3af';
+ calculateBtn.style.cursor = 'not-allowed';
+ calculateBtn.onmouseover = null;
+ calculateBtn.onmouseout = null;
+ }
+ }
+
+ function toggleCalculatedParams() {
+ const content = document.getElementById('calculated-content');
+ const toggle = document.getElementById('calculated-toggle');
+
+ if (content.style.display === 'none') {
+ content.style.display = 'block';
+ toggle.style.transform = 'rotate(180deg)';
+ } else {
+ content.style.display = 'none';
+ toggle.style.transform = 'rotate(0deg)';
+ }
+ }
+
+ function toggleAdvancedOptions() {
+ const content = document.getElementById('advanced-content');
+ const toggle = document.getElementById('advanced-toggle');
+
+ if (content.style.display === 'none') {
+ content.style.display = 'block';
+ toggle.style.transform = 'rotate(180deg)';
+ } else {
+ content.style.display = 'none';
+ toggle.style.transform = 'rotate(0deg)';
+ }
+ }
+
+ function showCalculatedSection() {
+ const advancedCalculatedContainer = document.getElementById('advanced-calculated-container');
+ if (advancedCalculatedContainer) {
+ advancedCalculatedContainer.style.display = 'block';
+ }
+ }
+
+ function hideCalculatedSection() {
+ const advancedCalculatedContainer = document.getElementById('advanced-calculated-container');
+ if (advancedCalculatedContainer) {
+ advancedCalculatedContainer.style.display = 'none';
+ // Also close both sections if they were open
+ const calculatedContent = document.getElementById('calculated-content');
+ const calculatedToggle = document.getElementById('calculated-toggle');
+ const advancedContent = document.getElementById('advanced-content');
+ const advancedToggle = document.getElementById('advanced-toggle');
+
+ if (calculatedContent) calculatedContent.style.display = 'none';
+ if (calculatedToggle) calculatedToggle.style.transform = 'rotate(0deg)';
+ if (advancedContent) advancedContent.style.display = 'none';
+ if (advancedToggle) advancedToggle.style.transform = 'rotate(0deg)';
+ }
+ }
+
function validateRequiredFields() {
const requiredFields = [
{id: 'gross-salary', name: 'Gross Monthly Salary'},
- {id: 'current-age', name: 'Current Age'},
- {id: 'retirement-age', name: 'Retirement Age'},
+ {id: 'current-age', name: 'Current Age'},
{id: 'tax-rate', name: 'Income Tax Rate'},
- {id: 'marital-status', name: 'Marital Status'}
+ {id: 'marital-status', name: 'Marital Status'},
+ {id: 'lease-duration', name: 'Company Car Duration'}
];
const emptyFields = [];
@@ -1375,6 +1690,7 @@
const customCar = VehicleAutocompleteUtils.convertToCustomCar(vehicleData);
customCars.push(customCar);
updateCustomCarsList();
+ checkVehicleSelected(); // Check if vehicle is selected for progress
// Reset the autocomplete form
vehicleAutocomplete.reset();
@@ -1417,6 +1733,7 @@
function removeCustomCar(index) {
customCars.splice(index, 1);
updateCustomCarsList();
+ checkVehicleSelected(); // Check if vehicle is still selected for progress
}
function calculateBIK(carPrice, co2, fuel) {
@@ -1464,6 +1781,8 @@
const inflation = parseFloat(document.getElementById('inflation').value) / 100;
const discountRate = parseFloat(document.getElementById('discount-rate').value) / 100;
const currentAge = parseInt(document.getElementById('current-age').value);
+ const leaseDuration = parseInt(document.getElementById('lease-duration').value);
+ const yearsWithCar = leaseDuration === 0 ? yearsWork : Math.min(leaseDuration, yearsWork);
// Get options
const includeInflation = document.getElementById('include-inflation').checked;
@@ -1473,7 +1792,27 @@
const mobilityBudget = document.getElementById('mobility-budget').checked;
const annualSalary = grossSalary * 12;
- const pensionMultiplier = maritalStatus === "married" ? 0.75 : 0.60;
+
+ // Belgian pension calculation rates based on marital status
+ let pensionMultiplier;
+ switch(maritalStatus) {
+ case "married":
+ pensionMultiplier = 0.75; // 75% for married with non-working spouse
+ break;
+ case "married-dual":
+ pensionMultiplier = 0.60; // 60% for married with both working
+ break;
+ case "cohabiting":
+ pensionMultiplier = 0.60; // 60% for legal cohabitation
+ break;
+ case "divorced":
+ pensionMultiplier = 0.60; // 60% for divorced individuals
+ break;
+ case "single":
+ default:
+ pensionMultiplier = 0.60; // 60% for single individuals
+ break;
+ }
// Build cars array from selected vehicles only
let carsToAnalyze = [];
@@ -1574,21 +1913,45 @@
}
const averageCareerSalary = totalCareerSalary / yearsWork;
- // Pension calculation
- const annualPensionLoss = (averageCareerSalary * pensionMultiplier * yearsWork) / 45;
- const monthlyPensionLoss = annualPensionLoss / 12;
+ // Dual calculation: lease period and lifetime impact
+ // Lease period impact (only the years with the car)
+ const annualPensionLossLease = (averageCareerSalary * pensionMultiplier * yearsWithCar) / 45;
+ const monthlyPensionLossLease = annualPensionLossLease / 12;
+
+ // Full career impact (if continued until retirement)
+ const annualPensionLossFull = (averageCareerSalary * pensionMultiplier * yearsWork) / 45;
+ const monthlyPensionLossFull = annualPensionLossFull / 12;
+
+ // Use lease period for main calculations if specified
+ const annualPensionLoss = leaseDuration === 0 ? annualPensionLossFull : annualPensionLossLease;
+ const monthlyPensionLoss = leaseDuration === 0 ? monthlyPensionLossFull : monthlyPensionLossLease;
// Track min/max monthly losses
minMonthlyLoss = Math.min(minMonthlyLoss, monthlyPensionLoss);
maxMonthlyLoss = Math.max(maxMonthlyLoss, monthlyPensionLoss);
- // Total loss calculation
+ // Total loss calculation (for display period)
let totalPensionLoss = 0;
for (let year = 0; year < retirementYears; year++) {
const yearlyLoss = annualPensionLoss * (includeInflation ? Math.pow(1 + inflation, year) : 1);
totalPensionLoss += yearlyLoss;
}
+ // Calculate full lifetime impact for comparison
+ let totalPensionLossFull = 0;
+ if (leaseDuration > 0) {
+ for (let year = 0; year < retirementYears; year++) {
+ const yearlyLoss = annualPensionLossFull * (includeInflation ? Math.pow(1 + inflation, year) : 1);
+ totalPensionLossFull += yearlyLoss;
+ }
+ }
+
+ // Store both values for display
+ car.monthlyLossLease = monthlyPensionLossLease;
+ car.monthlyLossFull = monthlyPensionLossFull;
+ car.totalLossLease = totalPensionLoss;
+ car.totalLossFull = leaseDuration > 0 ? totalPensionLossFull : totalPensionLoss;
+
// Present value calculation
let presentValueLoss = totalPensionLoss;
if (includePresentValue) {
@@ -1627,10 +1990,28 @@
carComparisonHTML += '
' + labels[currentLanguage].co2TaxYear + '€' + Math.round(solidarityContribution).toLocaleString() + '
';
carComparisonHTML += '
';
- carComparisonHTML += '
' + labels[currentLanguage].monthlyPensionLoss + '-€' + Math.round(monthlyPensionLoss) + translations[currentLanguage]['units.perMonth'] + '
';
- carComparisonHTML += '
' + labels[currentLanguage].duringRetirement + '' + labels[currentLanguage].everyMonthFor + ' ' + retirementYears + ' ' + labels[currentLanguage].years + '
';
- carComparisonHTML += '
' + labels[currentLanguage].totalLifetimeLoss + '€' + Math.round(totalPensionLoss).toLocaleString() + '
';
- carComparisonHTML += presentValueRow;
+
+ // Show lease period impact if specified
+ if (leaseDuration > 0) {
+ carComparisonHTML += '
';
+ carComparisonHTML += '
📅 ' + leaseDuration + '-Year Lease Impact:
';
+ carComparisonHTML += '
' + labels[currentLanguage].monthlyPensionLoss + '-€' + Math.round(car.monthlyLossLease) + translations[currentLanguage]['units.perMonth'] + '
';
+ carComparisonHTML += '
' + labels[currentLanguage].totalLifetimeLoss + '€' + Math.round(car.totalLossLease).toLocaleString() + '
';
+ carComparisonHTML += '
';
+
+ carComparisonHTML += '
';
+ carComparisonHTML += '
⚠️ If Continued Until Retirement:
';
+ carComparisonHTML += '
' + labels[currentLanguage].monthlyPensionLoss + '-€' + Math.round(car.monthlyLossFull) + translations[currentLanguage]['units.perMonth'] + '
';
+ carComparisonHTML += '
' + labels[currentLanguage].totalLifetimeLoss + '€' + Math.round(car.totalLossFull).toLocaleString() + '
';
+ carComparisonHTML += '
';
+ } else {
+ // Original display for full career
+ carComparisonHTML += '
' + labels[currentLanguage].monthlyPensionLoss + '-€' + Math.round(monthlyPensionLoss) + translations[currentLanguage]['units.perMonth'] + '
';
+ carComparisonHTML += '
' + labels[currentLanguage].duringRetirement + '' + labels[currentLanguage].everyMonthFor + ' ' + retirementYears + ' ' + labels[currentLanguage].years + '
';
+ carComparisonHTML += '
' + labels[currentLanguage].totalLifetimeLoss + '€' + Math.round(totalPensionLoss).toLocaleString() + '
';
+ carComparisonHTML += presentValueRow;
+ }
+
carComparisonHTML += '