export function leaseVsBuyCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Lease vs Buy Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Vehicle Details Section
const vehicleSection = form.addSubform('vehicle', { title: '🚗 Vehicle Details' });
vehicleSection.addRow(row => {
row.addMoney('vehiclePrice', {
label: 'Vehicle Price (MSRP)',
min: 0,
max: 500000,
defaultValue: 35000,
isRequired: true,
tooltip: 'The full purchase price of the vehicle'
}, '1fr');
row.addInteger('comparisonYears', {
label: 'Comparison Period (Years)',
min: 1,
max: 10,
defaultValue: 5,
isRequired: true,
tooltip: 'How many years to compare costs'
}, '1fr');
});
// Lease Details Section
const leaseSection = form.addSubform('lease', { title: '📋 Lease Option' });
leaseSection.addRow(row => {
row.addMoney('leaseDownPayment', {
label: 'Down Payment',
min: 0,
max: 100000,
defaultValue: 2000,
tooltip: 'Initial payment at lease signing'
}, '1fr');
row.addMoney('leaseMonthlyPayment', {
label: 'Monthly Payment',
min: 0,
max: 5000,
defaultValue: 350,
isRequired: true
}, '1fr');
});
leaseSection.addRow(row => {
row.addInteger('leaseTerm', {
label: 'Lease Term (Months)',
min: 12,
max: 60,
defaultValue: 36,
isRequired: true
}, '1fr');
row.addMoney('leaseAcquisitionFee', {
label: 'Acquisition Fee',
min: 0,
max: 2000,
defaultValue: 650,
tooltip: 'One-time fee charged by the leasing company'
}, '1fr');
});
leaseSection.addRow(row => {
row.addMoney('leaseDispositionFee', {
label: 'Disposition Fee',
min: 0,
max: 1000,
defaultValue: 350,
tooltip: 'Fee charged when returning the vehicle'
}, '1fr');
row.addInteger('mileageAllowance', {
label: 'Annual Mileage Allowance',
min: 5000,
max: 30000,
defaultValue: 12000,
tooltip: 'Miles allowed per year in the lease'
}, '1fr');
});
// Buy Details Section
const buySection = form.addSubform('buy', { title: '🔑 Buy Option' });
buySection.addRow(row => {
row.addMoney('buyDownPayment', {
label: 'Down Payment',
min: 0,
max: 200000,
defaultValue: 5000,
tooltip: 'Initial payment when purchasing'
}, '1fr');
row.addDecimal('loanInterestRate', {
label: 'Loan Interest Rate (APR)',
min: 0,
max: 30,
defaultValue: 6.5,
suffix: '%',
isRequired: true
}, '1fr');
});
buySection.addRow(row => {
row.addInteger('loanTerm', {
label: 'Loan Term (Months)',
min: 12,
max: 84,
defaultValue: 60,
isRequired: true
}, '1fr');
row.addDecimal('estimatedResalePercent', {
label: 'Estimated Resale Value',
min: 0,
max: 100,
defaultValue: 50,
suffix: '% of MSRP',
tooltip: 'Expected value at end of comparison period'
}, '1fr');
});
// Additional Costs Section
const costsSection = form.addSubform('costs', { title: '💵 Additional Costs (Annual)' });
costsSection.addRow(row => {
row.addMoney('leaseInsurance', {
label: 'Lease Insurance (Annual)',
min: 0,
max: 10000,
defaultValue: 1800,
tooltip: 'Lease often requires higher coverage'
}, '1fr');
row.addMoney('buyInsurance', {
label: 'Buy Insurance (Annual)',
min: 0,
max: 10000,
defaultValue: 1500
}, '1fr');
});
costsSection.addRow(row => {
row.addMoney('leaseMaintenance', {
label: 'Lease Maintenance (Annual)',
min: 0,
max: 5000,
defaultValue: 300,
tooltip: 'Often lower due to warranty coverage'
}, '1fr');
row.addMoney('buyMaintenance', {
label: 'Buy Maintenance (Annual)',
min: 0,
max: 5000,
defaultValue: 800,
tooltip: 'Increases as vehicle ages'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Lease Cost Breakdown
const leaseResultsSection = form.addSubform('leaseResults', { title: '📊 Lease Cost Breakdown', isCollapsible: true });
leaseResultsSection.addRow(row => {
row.addPriceDisplay('leasePaymentsTotal', {
label: 'Total Lease Payments',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const months = years * 12;
const leaseTerm = leaseSection.integer('leaseTerm')?.value() || 36;
const monthlyPayment = leaseSection.decimal('leaseMonthlyPayment')?.value() || 350;
// Calculate number of lease terms needed
const leaseTerms = Math.ceil(months / leaseTerm);
return Math.round(monthlyPayment * leaseTerm * leaseTerms * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('leaseFeesTotal', {
label: 'Total Fees',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const leaseTerm = leaseSection.integer('leaseTerm')?.value() || 36;
const downPayment = leaseSection.decimal('leaseDownPayment')?.value() || 2000;
const acquisitionFee = leaseSection.decimal('leaseAcquisitionFee')?.value() || 650;
const dispositionFee = leaseSection.decimal('leaseDispositionFee')?.value() || 350;
const leaseTerms = Math.ceil((years * 12) / leaseTerm);
return Math.round((downPayment + acquisitionFee + dispositionFee) * leaseTerms * 100) / 100;
},
variant: 'default'
}, '1fr');
});
leaseResultsSection.addRow(row => {
row.addPriceDisplay('leaseInsuranceTotal', {
label: 'Total Insurance',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const annualInsurance = costsSection.decimal('leaseInsurance')?.value() || 1800;
return Math.round(annualInsurance * years * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('leaseMaintenanceTotal', {
label: 'Total Maintenance',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const annualMaintenance = costsSection.decimal('leaseMaintenance')?.value() || 300;
return Math.round(annualMaintenance * years * 100) / 100;
},
variant: 'default'
}, '1fr');
});
// Buy Cost Breakdown
const buyResultsSection = form.addSubform('buyResults', { title: '📊 Buy Cost Breakdown', isCollapsible: true });
buyResultsSection.addRow(row => {
row.addPriceDisplay('buyLoanPaymentsTotal', {
label: 'Total Loan Payments',
computedValue: () => {
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
const downPayment = buySection.decimal('buyDownPayment')?.value() || 5000;
const interestRate = (buySection.decimal('loanInterestRate')?.value() || 6.5) / 100 / 12;
const loanTerm = buySection.integer('loanTerm')?.value() || 60;
const loanAmount = vehiclePrice - downPayment;
if (interestRate === 0) {
return Math.round(loanAmount * 100) / 100;
}
const monthlyPayment = loanAmount * (interestRate * Math.pow(1 + interestRate, loanTerm)) / (Math.pow(1 + interestRate, loanTerm) - 1);
return Math.round(monthlyPayment * loanTerm * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('buyDownPaymentDisplay', {
label: 'Down Payment',
computedValue: () => {
return buySection.decimal('buyDownPayment')?.value() || 5000;
},
variant: 'default'
}, '1fr');
});
buyResultsSection.addRow(row => {
row.addPriceDisplay('buyInsuranceTotal', {
label: 'Total Insurance',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const annualInsurance = costsSection.decimal('buyInsurance')?.value() || 1500;
return Math.round(annualInsurance * years * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('buyMaintenanceTotal', {
label: 'Total Maintenance',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const annualMaintenance = costsSection.decimal('buyMaintenance')?.value() || 800;
return Math.round(annualMaintenance * years * 100) / 100;
},
variant: 'default'
}, '1fr');
});
buyResultsSection.addRow(row => {
row.addPriceDisplay('estimatedResaleValue', {
label: 'Estimated Resale Value',
computedValue: () => {
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
const resalePercent = (buySection.decimal('estimatedResalePercent')?.value() || 50) / 100;
return Math.round(vehiclePrice * resalePercent * 100) / 100;
},
variant: 'success'
});
});
// Comparison Results
const comparisonSection = form.addSubform('comparison', { title: '⚖️ Cost Comparison', isCollapsible: false });
comparisonSection.addRow(row => {
row.addPriceDisplay('totalLeaseCost', {
label: 'Total Lease Cost',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const months = years * 12;
const leaseTerm = leaseSection.integer('leaseTerm')?.value() || 36;
const monthlyPayment = leaseSection.decimal('leaseMonthlyPayment')?.value() || 350;
const downPayment = leaseSection.decimal('leaseDownPayment')?.value() || 2000;
const acquisitionFee = leaseSection.decimal('leaseAcquisitionFee')?.value() || 650;
const dispositionFee = leaseSection.decimal('leaseDispositionFee')?.value() || 350;
const annualInsurance = costsSection.decimal('leaseInsurance')?.value() || 1800;
const annualMaintenance = costsSection.decimal('leaseMaintenance')?.value() || 300;
const leaseTerms = Math.ceil(months / leaseTerm);
const payments = monthlyPayment * leaseTerm * leaseTerms;
const fees = (downPayment + acquisitionFee + dispositionFee) * leaseTerms;
const insurance = annualInsurance * years;
const maintenance = annualMaintenance * years;
return Math.round((payments + fees + insurance + maintenance) * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('totalBuyCost', {
label: 'Total Buy Cost',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
const downPayment = buySection.decimal('buyDownPayment')?.value() || 5000;
const interestRate = (buySection.decimal('loanInterestRate')?.value() || 6.5) / 100 / 12;
const loanTerm = buySection.integer('loanTerm')?.value() || 60;
const resalePercent = (buySection.decimal('estimatedResalePercent')?.value() || 50) / 100;
const annualInsurance = costsSection.decimal('buyInsurance')?.value() || 1500;
const annualMaintenance = costsSection.decimal('buyMaintenance')?.value() || 800;
const loanAmount = vehiclePrice - downPayment;
let totalLoanPayments;
if (interestRate === 0) {
totalLoanPayments = loanAmount;
} else {
const monthlyPayment = loanAmount * (interestRate * Math.pow(1 + interestRate, loanTerm)) / (Math.pow(1 + interestRate, loanTerm) - 1);
totalLoanPayments = monthlyPayment * loanTerm;
}
const insurance = annualInsurance * years;
const maintenance = annualMaintenance * years;
const resaleValue = vehiclePrice * resalePercent;
return Math.round((downPayment + totalLoanPayments + insurance + maintenance - resaleValue) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
comparisonSection.addRow(row => {
row.addPriceDisplay('savings', {
label: 'You Save By',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const months = years * 12;
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
// Lease calculation
const leaseTerm = leaseSection.integer('leaseTerm')?.value() || 36;
const leaseMonthlyPayment = leaseSection.decimal('leaseMonthlyPayment')?.value() || 350;
const leaseDownPayment = leaseSection.decimal('leaseDownPayment')?.value() || 2000;
const acquisitionFee = leaseSection.decimal('leaseAcquisitionFee')?.value() || 650;
const dispositionFee = leaseSection.decimal('leaseDispositionFee')?.value() || 350;
const leaseInsurance = costsSection.decimal('leaseInsurance')?.value() || 1800;
const leaseMaintenance = costsSection.decimal('leaseMaintenance')?.value() || 300;
const leaseTerms = Math.ceil(months / leaseTerm);
const totalLease = (leaseMonthlyPayment * leaseTerm * leaseTerms) +
((leaseDownPayment + acquisitionFee + dispositionFee) * leaseTerms) +
(leaseInsurance * years) + (leaseMaintenance * years);
// Buy calculation
const buyDownPayment = buySection.decimal('buyDownPayment')?.value() || 5000;
const interestRate = (buySection.decimal('loanInterestRate')?.value() || 6.5) / 100 / 12;
const loanTerm = buySection.integer('loanTerm')?.value() || 60;
const resalePercent = (buySection.decimal('estimatedResalePercent')?.value() || 50) / 100;
const buyInsurance = costsSection.decimal('buyInsurance')?.value() || 1500;
const buyMaintenance = costsSection.decimal('buyMaintenance')?.value() || 800;
const loanAmount = vehiclePrice - buyDownPayment;
let totalLoanPayments;
if (interestRate === 0) {
totalLoanPayments = loanAmount;
} else {
const monthlyPayment = loanAmount * (interestRate * Math.pow(1 + interestRate, loanTerm)) / (Math.pow(1 + interestRate, loanTerm) - 1);
totalLoanPayments = monthlyPayment * loanTerm;
}
const totalBuy = buyDownPayment + totalLoanPayments + (buyInsurance * years) +
(buyMaintenance * years) - (vehiclePrice * resalePercent);
return Math.abs(Math.round((totalLease - totalBuy) * 100) / 100);
},
variant: 'success'
}, '1fr');
row.addTextPanel('recommendation', {
label: 'Better Option',
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const months = years * 12;
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
// Lease calculation
const leaseTerm = leaseSection.integer('leaseTerm')?.value() || 36;
const leaseMonthlyPayment = leaseSection.decimal('leaseMonthlyPayment')?.value() || 350;
const leaseDownPayment = leaseSection.decimal('leaseDownPayment')?.value() || 2000;
const acquisitionFee = leaseSection.decimal('leaseAcquisitionFee')?.value() || 650;
const dispositionFee = leaseSection.decimal('leaseDispositionFee')?.value() || 350;
const leaseInsurance = costsSection.decimal('leaseInsurance')?.value() || 1800;
const leaseMaintenance = costsSection.decimal('leaseMaintenance')?.value() || 300;
const leaseTerms = Math.ceil(months / leaseTerm);
const totalLease = (leaseMonthlyPayment * leaseTerm * leaseTerms) +
((leaseDownPayment + acquisitionFee + dispositionFee) * leaseTerms) +
(leaseInsurance * years) + (leaseMaintenance * years);
// Buy calculation
const buyDownPayment = buySection.decimal('buyDownPayment')?.value() || 5000;
const interestRate = (buySection.decimal('loanInterestRate')?.value() || 6.5) / 100 / 12;
const loanTerm = buySection.integer('loanTerm')?.value() || 60;
const resalePercent = (buySection.decimal('estimatedResalePercent')?.value() || 50) / 100;
const buyInsurance = costsSection.decimal('buyInsurance')?.value() || 1500;
const buyMaintenance = costsSection.decimal('buyMaintenance')?.value() || 800;
const loanAmount = vehiclePrice - buyDownPayment;
let totalLoanPayments;
if (interestRate === 0) {
totalLoanPayments = loanAmount;
} else {
const monthlyPayment = loanAmount * (interestRate * Math.pow(1 + interestRate, loanTerm)) / (Math.pow(1 + interestRate, loanTerm) - 1);
totalLoanPayments = monthlyPayment * loanTerm;
}
const totalBuy = buyDownPayment + totalLoanPayments + (buyInsurance * years) +
(buyMaintenance * years) - (vehiclePrice * resalePercent);
if (totalLease < totalBuy) {
return 'LEASING';
} else if (totalBuy < totalLease) {
return 'BUYING';
} else {
return 'EQUAL';
}
},
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'text-align': 'center', 'color': '#059669' }
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const years = vehicleSection.integer('comparisonYears')?.value() || 5;
const vehiclePrice = vehicleSection.decimal('vehiclePrice')?.value() || 35000;
return `Comparing lease vs buy for a $${vehiclePrice.toLocaleString()} vehicle over ${years} years`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'This calculator provides estimates only. Actual costs may vary based on taxes, fees, and market conditions. Consult with a financial advisor for personalized advice.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Get Detailed Analysis'
});
}