Land Subdivision Profit Calculator

Land Subdivision Profit Calculator

Estimate the potential profit from your land subdivision project.

$0.00

Return on Investment (ROI):

0.00%

`; } else { let formHtml = `

${category}

`; for (const key in appData[category]) { formHtml += createFormGroup(key, appData[category][key], category); } formHtml += '
'; content.innerHTML = formHtml; } tabContentsContainer.appendChild(content); tabContents.push(content); }); updateTabs(); calculateAll(); setupEventListeners(); } function calculateAll() { const acq = appData['Land Acquisition Costs']; const dev = appData['Development & Soft Costs']; const sales = appData['Projected Sales']; // Calculate Costs const acquisitionCost = (parseFloat(acq.purchase_price.value) || 0) + (parseFloat(acq.closing_costs.value) || 0); const baseDevCost = (parseFloat(dev.surveying_platting.value) || 0) + (parseFloat(dev.infrastructure.value) || 0) + (parseFloat(dev.permits_fees.value) || 0); const contingency = baseDevCost * 0.15; dev.contingency.value = contingency.toFixed(2); document.getElementById('input-Development & Soft Costs-contingency').value = contingency.toFixed(2); const totalDevCost = baseDevCost + contingency; const totalProjectCost = acquisitionCost + totalDevCost; // Calculate Revenue const totalRevenue = (parseFloat(sales.number_of_lots.value) || 0) * (parseFloat(sales.price_per_lot.value) || 0); const sellingCosts = totalRevenue * 0.06; sales.selling_costs.value = sellingCosts.toFixed(2); document.getElementById('input-Projected Sales-selling_costs').value = sellingCosts.toFixed(2); const netRevenue = totalRevenue - sellingCosts; // Calculate Profit & ROI const grossProfit = netRevenue - totalProjectCost; const roi = totalProjectCost > 0 ? (grossProfit / totalProjectCost) * 100 : 0; updateDashboard(totalProjectCost, totalRevenue, grossProfit, roi); updateChart({ 'Acquisition': acquisitionCost, 'Development': totalDevCost, 'Selling Costs': sellingCosts, 'Gross Profit': grossProfit > 0 ? grossProfit : 0 }); } function updateDashboard(totalCost, totalRevenue, profit, roi) { const summaryContainer = document.getElementById('summary-container'); summaryContainer.innerHTML = `
Total Projected Revenue:$${totalRevenue.toLocaleString('en-US', {maximumFractionDigits: 2})}
Total Estimated Cost:$${totalCost.toLocaleString('en-US', {maximumFractionDigits: 2})}
`; document.getElementById('gross-profit').textContent = `$${profit.toLocaleString('en-US', {maximumFractionDigits: 2})}`; document.getElementById('roi').textContent = `${roi.toFixed(2)}%`; } function updateChart(data) { const ctx = document.getElementById('profit-chart').getContext('2d'); const labels = Object.keys(data); const values = Object.values(data); const isProfit = data['Gross Profit'] > 0; if (profitChart) { profitChart.data.labels = labels; profitChart.data.datasets[0].data = values; profitChart.update(); } else { profitChart = new Chart(ctx, { type: 'doughnut', data: { labels: labels, datasets: [{ label: 'Financial Breakdown', data: values, backgroundColor: ['#fca5a5', '#fdba74', '#fde68a', '#86efac'], borderColor: 'white', borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom', labels: { boxWidth: 12, padding: 15 } }, tooltip: { callbacks: { label: (c) => `${c.label}: $${parseFloat(c.raw).toLocaleString('en-US', {maximumFractionDigits: 0})}` } } } } }); } } function updateTabs() { tabs.forEach((tab, i) => tab.classList.toggle('active', i === currentTabIndex)); tabContents.forEach((c, i) => c.classList.toggle('active', i === currentTabIndex)); prevBtn.disabled = currentTabIndex === 0; nextBtn.disabled = currentTabIndex === tabs.length - 1; prevBtn.classList.toggle('opacity-50', currentTabIndex === 0); nextBtn.classList.toggle('opacity-50', currentTabIndex === tabs.length - 1); } function setupEventListeners() { tabsContainer.addEventListener('click', (e) => { if (e.target.classList.contains('tab')) { currentTabIndex = parseInt(e.target.dataset.index); updateTabs(); } }); prevBtn.addEventListener('click', () => { if (currentTabIndex > 0) { currentTabIndex--; updateTabs(); } }); nextBtn.addEventListener('click', () => { if (currentTabIndex < tabs.length - 1) { currentTabIndex++; updateTabs(); } }); tabContentsContainer.addEventListener('input', (e) => { if (e.target.tagName === 'INPUT') { const category = e.target.dataset.category; const key = e.target.dataset.key; if (appData[category] && appData[category][key]) { appData[category][key].value = e.target.value; calculateAll(); } } }); document.getElementById('pdf-download-btn').addEventListener('click', generatePdf); } function generatePdf() { const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfContainer = document.createElement('div'); pdfContainer.style.cssText = 'position:absolute; left:-9999px; width:800px; padding:20px; font-family:Inter,sans-serif; color:#1f2937;'; let html = `

Land Subdivision Profit Analysis

Gross Profit

${document.getElementById('gross-profit').textContent}

Return on Investment

${document.getElementById('roi').textContent}

`; for (const category in appData) { if (category === 'Dashboard') continue; html += `

${category}

`; for (const key in appData[category]) { const item = appData[category][key]; const value = parseFloat(item.value).toLocaleString('en-US', {maximumFractionDigits: 2}); html += ``; } html += '
${item.label} ${item.prefix || ''}${value}
'; } pdfContainer.innerHTML = html; document.body.appendChild(pdfContainer); html2canvas(pdfContainer, { scale: 2 }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const { width, height } = pdf.internal.pageSize; const imgHeight = canvas.height * width / canvas.width; let heightLeft = imgHeight, position = 0; pdf.addImage(imgData, 'PNG', 0, 0, width, imgHeight); heightLeft -= height; while (heightLeft > 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, width, imgHeight); heightLeft -= height; } pdf.save('land-subdivision-profit-analysis.pdf'); document.body.removeChild(pdfContainer); }); } initialize(); });
Scroll to Top