diff --git a/tax-old.html b/tax-old.html new file mode 100644 index 0000000..82d039a --- /dev/null +++ b/tax-old.html @@ -0,0 +1,1922 @@ + + + + + + Company Car Tax Calculator | Belgium + + + +
+
+
+ + + +
+

Company Car Tax Calculator

+

Calculate pension impact for company cars in Belgium

+ +
+ ⚠️ Important Notice: + This calculator provides estimates based on current regulations and market data. Vehicle prices and specifications may vary. Always consult with a tax professional or HR department for official calculations. Last updated: August 2025. +
+
+ +
+
+ +
+
📝 Required Information
+ +
+
+ + + Your current gross monthly salary in EUR +
+ +
+ + + Your age today +
+ +
+ + + Expected retirement age +
+
+ +
+
+ + + Affects pension calculation rate +
+ +
+ + + Your marginal tax rate percentage +
+
+
+ + +
+
🚗 Select Your Company Cars
+
+
+
+ + +
+
⚙️ Calculated Parameters (Adjustable)
+ +
+
+ + + Auto-calculated from age difference +
+ +
+ + + How long you'll have the company car +
+ +
+ + + Expected years receiving pension +
+ +
+ + + Updates retirement years automatically +
+
+ + +
+ +
+ + +
+ + ⚙️ Advanced Options + +
+
+
+ + + Expected annual salary increase percentage +
+ +
+ + + Expected annual inflation rate percentage +
+ +
+ + + For present value calculations percentage +
+
+ +
Display Options
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+
+
+ +
+
+

How This Calculation Works

+

Company vehicles in Belgium are taxed as "Benefit in Kind" (BIK). While you pay income tax on this benefit, no social security contributions (RSZ) are paid, meaning it doesn't count toward your pension calculation.

+

Result: You'll receive less monthly pension during retirement. See below for the exact impact per vehicle type.

+
+ +

Monthly Pension Impact by Vehicle Type

+ +
+ +
+ + + +
+ +
+ + + +
+

Calculation Assumptions

+

• Pension calculation: 60% (single) or 75% (married) of average career salary
+ • Employee RSZ contribution: 13.07% (7.5% for pension)
+ • CO2 coefficients for 2025: Diesel 67g/km, Petrol 82g/km
+ • Minimum BIK: €1,650/year
+ • Electric vehicles: 4% coefficient (minimum)
+ • Solidarity contribution factor 2025: 2.75x
+ • Calculations based on current regulations

+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/tax.html b/tax.html index 57e7fba..7ab3184 100644 --- a/tax.html +++ b/tax.html @@ -663,142 +663,234 @@
- -
-
📝 Required Information
+ + +
+
🎯 Essential Information - Fill These First
- + Your current gross monthly salary in EUR
- + Your age today
- - - Expected retirement age + + + Affects pension calculation rate
- - - Affects pension calculation rate + + + Your marginal tax rate percentage
- - - Your marginal tax rate percentage + + + How long you'll have the company car
-
-
🚗 Select Your Company Cars
+
+
🚗 Select Your Company Car
- -
-
⚙️ Calculated Parameters (Adjustable)
- -
-
- - - Auto-calculated from age difference -
- -
- - - Expected years receiving pension -
- -
- - - Updates retirement years automatically -
-
- - -
- -
- - -
- - ⚙️ Advanced Options - -
-
-
- - - Expected annual salary increase percentage -
+ +
+ + +
+
+ Calculated Parameters (Adjustable) + +
+ +
+ +
-
+ + +
+ +
+
@@ -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 += '
'; - 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 += '
'; carComparisonHTML += '
'; @@ -1684,6 +2065,7 @@ average: "Average
Typical monthly loss", worstCase: "Worst Case
Largest monthly loss", duration: "Duration
Monthly loss period", + leaseDuration: "Lease Period
Company car duration", minimumTotal: "Minimum Total
Best scenario", averageTotal: "Average Total
All analyzed vehicles", maximumTotal: "Maximum Total
Worst scenario", @@ -1694,7 +2076,7 @@ lessPerMonth: "less per month", inPensionIncome: "in pension income because the company vehicle benefit doesn't contribute to your pension calculation.", overEntireRetirement: "Over your entire retirement, this adds up to", - figuresIncludeInflation: "These figures include inflation adjustments." + figuresIncludeInflation: "These figures include inflation adjustments. You can modify all parameters in the Advanced Options section." }, fr: { monthlyImpact: "Impact Mensuel sur la Pension Pendant la Retraite", @@ -1703,6 +2085,7 @@ average: "Moyenne
Perte mensuelle typique", worstCase: "Pire Cas
Perte mensuelle maximale", duration: "Durée
Période de perte mensuelle", + leaseDuration: "Période de Contrat
Durée voiture de société", minimumTotal: "Total Minimum
Meilleur scénario", averageTotal: "Total Moyen
Tous véhicules analysés", maximumTotal: "Total Maximum
Pire scénario", @@ -1713,7 +2096,7 @@ lessPerMonth: "de moins par mois", inPensionIncome: "en revenu de pension car l'avantage véhicule de société ne contribue pas à votre calcul de pension.", overEntireRetirement: "Sur toute votre retraite, cela représente", - figuresIncludeInflation: "Ces chiffres incluent les ajustements d'inflation." + figuresIncludeInflation: "Ces chiffres incluent les ajustements d'inflation. Vous pouvez modifier tous les paramètres dans la section Options Avancées." }, nl: { monthlyImpact: "Maandelijkse Pensioenimpact Tijdens Pensioen", @@ -1722,6 +2105,7 @@ average: "Gemiddeld
Typisch maandelijks verlies", worstCase: "Slechtste Geval
Grootste maandelijkse verlies", duration: "Duur
Maandelijkse verliesperiode", + leaseDuration: "Leaseperiode
Bedrijfswagen duur", minimumTotal: "Minimum Totaal
Beste scenario", averageTotal: "Gemiddeld Totaal
Alle geanalyseerde voertuigen", maximumTotal: "Maximum Totaal
Slechtste scenario", @@ -1732,30 +2116,73 @@ lessPerMonth: "minder per maand", inPensionIncome: "aan pensioeninkomen omdat het bedrijfswagen voordeel niet bijdraagt aan uw pensioenberekening.", overEntireRetirement: "Over uw gehele pensioen komt dit neer op", - figuresIncludeInflation: "Deze cijfers bevatten inflatie-aanpassingen." + figuresIncludeInflation: "Deze cijfers bevatten inflatie-aanpassingen. U kunt alle parameters aanpassen in de sectie Geavanceerde Opties." } }; + // Check if single or multiple cars + const isSingleCar = carsToAnalyze.length === 1; + let summaryHTML = '

' + summaryLabels[currentLanguage].monthlyImpact + '

'; summaryHTML += '
'; - summaryHTML += '
-€' + Math.round(minMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].bestCase + '
'; - summaryHTML += '
-€' + Math.round(avgMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].average + '
'; - summaryHTML += '
-€' + Math.round(maxMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].worstCase + '
'; - summaryHTML += '
' + retirementYears + ' ' + labels[currentLanguage].years + '
' + summaryLabels[currentLanguage].duration + '
'; + + // Determine what to show for duration + const displayDuration = leaseDuration === 0 ? retirementYears + ' ' + labels[currentLanguage].years : leaseDuration + ' ' + labels[currentLanguage].years; + const durationLabel = leaseDuration === 0 ? summaryLabels[currentLanguage].duration : summaryLabels[currentLanguage].leaseDuration; + + if (isSingleCar) { + // Single car - show only the actual value without ranges + summaryHTML += '
-€' + Math.round(minMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].monthlyImpact + '
'; + summaryHTML += '
' + displayDuration + '
' + durationLabel + '
'; + } else { + // Multiple cars - show best/average/worst + summaryHTML += '
-€' + Math.round(minMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].bestCase + '
'; + summaryHTML += '
-€' + Math.round(avgMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].average + '
'; + summaryHTML += '
-€' + Math.round(maxMonthlyLoss) + translations[currentLanguage]['units.perMo'] + '
' + summaryLabels[currentLanguage].worstCase + '
'; + summaryHTML += '
' + displayDuration + '
' + durationLabel + '
'; + } summaryHTML += '
'; summaryHTML += '

' + summaryLabels[currentLanguage].totalLifetime + '

'; summaryHTML += '
'; - summaryHTML += '
€' + Math.round(minLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].minimumTotal + '
'; - summaryHTML += '
€' + Math.round(avgLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].averageTotal + '
'; - summaryHTML += '
€' + Math.round(maxLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].maximumTotal + '
'; - summaryHTML += '
' + yearsWork + ' / ' + retirementYears + '
' + summaryLabels[currentLanguage].workRetirement + '
'; + + if (isSingleCar) { + // Single car - show only the actual total + summaryHTML += '
€' + Math.round(minLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].totalLifetime + '
'; + summaryHTML += '
' + yearsWork + ' / ' + retirementYears + '
' + summaryLabels[currentLanguage].workRetirement + '
'; + } else { + // Multiple cars - show min/avg/max totals + summaryHTML += '
€' + Math.round(minLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].minimumTotal + '
'; + summaryHTML += '
€' + Math.round(avgLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].averageTotal + '
'; + summaryHTML += '
€' + Math.round(maxLoss).toLocaleString() + '
' + summaryLabels[currentLanguage].maximumTotal + '
'; + summaryHTML += '
' + yearsWork + ' / ' + retirementYears + '
' + summaryLabels[currentLanguage].workRetirement + '
'; + } summaryHTML += '
'; summaryHTML += '
'; + + // Add lease duration context if applicable + if (leaseDuration > 0) { + const leaseContext = { + en: `

📅 Analysis Period: Based on ${leaseDuration}-year company car lease. Pension impacts shown reflect this limited period, but actual pension effects are PERMANENT once incurred.

`, + fr: `

📅 Période d'Analyse: Basé sur un contrat de ${leaseDuration} ans. Les impacts pension montrés reflètent cette période limitée, mais les effets réels sur la pension sont PERMANENTS une fois encourus.

`, + nl: `

📅 Analyseperiode: Gebaseerd op ${leaseDuration}-jarig bedrijfswagen contract. Getoonde pensioenimpacten reflecteren deze beperkte periode, maar echte pensioeneffecten zijn PERMANENT eenmaal opgelopen.

` + }; + summaryHTML += leaseContext[currentLanguage]; + } + summaryHTML += '

' + summaryLabels[currentLanguage].summary + ' ' + summaryLabels[currentLanguage].during + ' ' + retirementYears + ' ' + summaryLabels[currentLanguage].yearsText + ' '; - summaryHTML += '€' + Math.round(minMonthlyLoss) + ' - €' + Math.round(maxMonthlyLoss) + ' ' + summaryLabels[currentLanguage].lessPerMonth + ' ' + summaryLabels[currentLanguage].inPensionIncome + ' '; - summaryHTML += summaryLabels[currentLanguage].overEntireRetirement + ' €' + Math.round(minLoss).toLocaleString() + ' - €' + Math.round(maxLoss).toLocaleString() + '.'; + + if (isSingleCar) { + // Single car - show single value + summaryHTML += '€' + Math.round(minMonthlyLoss) + ' ' + summaryLabels[currentLanguage].lessPerMonth + ' ' + summaryLabels[currentLanguage].inPensionIncome + ' '; + summaryHTML += summaryLabels[currentLanguage].overEntireRetirement + ' €' + Math.round(minLoss).toLocaleString() + '.'; + } else { + // Multiple cars - show range + summaryHTML += '€' + Math.round(minMonthlyLoss) + ' - €' + Math.round(maxMonthlyLoss) + ' ' + summaryLabels[currentLanguage].lessPerMonth + ' ' + summaryLabels[currentLanguage].inPensionIncome + ' '; + summaryHTML += summaryLabels[currentLanguage].overEntireRetirement + ' €' + Math.round(minLoss).toLocaleString() + ' - €' + Math.round(maxLoss).toLocaleString() + '.'; + } + if (includeInflation) summaryHTML += ' ' + summaryLabels[currentLanguage].figuresIncludeInflation; summaryHTML += '

'; @@ -1804,6 +2231,23 @@ vehicleAutocomplete = new VehicleSearchAutocomplete('vehicle-autocomplete-container', function(vehicleData) { console.log('Vehicle selected:', vehicleData); }); + + // Add event listeners for essential field monitoring + const essentialFields = ['gross-salary', 'current-age', 'tax-rate', 'marital-status', 'lease-duration']; + essentialFields.forEach(fieldId => { + const element = document.getElementById(fieldId); + if (element) { + element.addEventListener('input', checkEssentialFields); + element.addEventListener('change', checkEssentialFields); + } + }); + + // Initial check on page load - start with vehicle section disabled + setTimeout(() => { + disableVehicleSelection(); // Start with vehicle section disabled + checkEssentialFields(); // Check if essential fields are filled + checkVehicleSelected(); // Check vehicle status + }, 200); // Increased timeout to ensure vehicleAutocomplete is initialized }); diff --git a/vehicle-search.js b/vehicle-search.js index fe89fd5..3223b1c 100644 --- a/vehicle-search.js +++ b/vehicle-search.js @@ -390,6 +390,128 @@ class VehicleSearchAutocomplete { this.hideSelectedInfo(); } + disable() { + // Store disabled state + this.isDisabled = true; + + // Disable all filter dropdowns + const filters = ['year-filter', 'fuel-filter', 'price-filter']; + filters.forEach(filterId => { + const filter = document.getElementById(filterId); + if (filter) { + filter.disabled = true; + filter.style.opacity = '0.5'; + filter.style.cursor = 'not-allowed'; + filter.style.pointerEvents = 'none'; + } + }); + + // Disable search input + const searchInput = document.getElementById('vehicle-search-input'); + if (searchInput) { + searchInput.disabled = true; + searchInput.readonly = true; + searchInput.placeholder = 'Complete Step 1 to search vehicles...'; + searchInput.style.opacity = '0.5'; + searchInput.style.cursor = 'not-allowed'; + searchInput.style.pointerEvents = 'none'; + } + + // Disable manual mode toggle + const manualCheckbox = document.getElementById('manual-override-checkbox'); + if (manualCheckbox) { + manualCheckbox.disabled = true; + manualCheckbox.style.opacity = '0.5'; + manualCheckbox.style.cursor = 'not-allowed'; + manualCheckbox.style.pointerEvents = 'none'; + } + + // Disable manual form inputs + const manualInputs = ['manual-name', 'manual-price', 'manual-co2', 'manual-fuel']; + manualInputs.forEach(inputId => { + const input = document.getElementById(inputId); + if (input) { + input.disabled = true; + input.readonly = true; + input.style.opacity = '0.5'; + input.style.cursor = 'not-allowed'; + input.style.pointerEvents = 'none'; + } + }); + + // Disable any buttons + const addButton = document.getElementById('add-vehicle-btn'); + if (addButton) { + addButton.disabled = true; + addButton.style.opacity = '0.5'; + addButton.style.cursor = 'not-allowed'; + addButton.style.pointerEvents = 'none'; + } + + // Hide results if shown + this.hideResults(); + this.hideSelectedInfo(); + } + + enable() { + // Clear disabled state + this.isDisabled = false; + + // Enable all filter dropdowns + const filters = ['year-filter', 'fuel-filter', 'price-filter']; + filters.forEach(filterId => { + const filter = document.getElementById(filterId); + if (filter) { + filter.disabled = false; + filter.style.opacity = '1'; + filter.style.cursor = 'pointer'; + filter.style.pointerEvents = 'auto'; + } + }); + + // Enable search input + const searchInput = document.getElementById('vehicle-search-input'); + if (searchInput) { + searchInput.disabled = false; + searchInput.readonly = false; + searchInput.placeholder = 'Type to search vehicles (e.g., Tesla Model 3, BMW X3, Audi A4)...'; + searchInput.style.opacity = '1'; + searchInput.style.cursor = 'text'; + searchInput.style.pointerEvents = 'auto'; + } + + // Enable manual mode toggle + const manualCheckbox = document.getElementById('manual-override-checkbox'); + if (manualCheckbox) { + manualCheckbox.disabled = false; + manualCheckbox.style.opacity = '1'; + manualCheckbox.style.cursor = 'pointer'; + manualCheckbox.style.pointerEvents = 'auto'; + } + + // Enable manual form inputs + const manualInputs = ['manual-name', 'manual-price', 'manual-co2', 'manual-fuel']; + manualInputs.forEach(inputId => { + const input = document.getElementById(inputId); + if (input) { + input.disabled = false; + input.readonly = false; + input.style.opacity = '1'; + input.style.cursor = input.tagName === 'INPUT' ? 'text' : 'pointer'; + input.style.pointerEvents = 'auto'; + } + }); + + // Enable any buttons + const addButton = document.getElementById('add-vehicle-btn'); + if (addButton) { + addButton.disabled = false; + addButton.style.opacity = '1'; + addButton.style.cursor = 'pointer'; + addButton.style.pointerEvents = 'auto'; + } + } + setVehicleData(vehicleData) { if (vehicleData.manual) { document.getElementById('manual-override-checkbox').checked = true;