Multi-Family vs. Single-Family Investment Analyzer

Multi-Family vs. Single-Family Investment Analyzer

Applied to some expenses and for real value calculations.
Your required rate of return for Net Present Value of cash flows.

Single-Family Property Acquisition

Single-Family Income & Operating Expenses

Multi-Family Property Acquisition

Multi-Family Income & Operating Expenses

Investment Comparison Results

Est. Net Financial Position Change (Nominal): ${formatCurrency(mfResults.netFinancialPositionChange)}

Est. Net Financial Position Change (Real): ${formatCurrency(mfResults.netFinancialPositionChangeReal)}

`; renderYearByYearTable(mfResults.yearByYearData, mfYearByYearTableContainerEl, "Multi-Family"); } else { mfResultsEl.innerHTML = "

Multi-Family Property

Not analyzed (no purchase price entered).

"; mfYearByYearTableContainerEl.innerHTML = ""; } yearByYearTitleEl.style.display = (sfResults || mfResults) ? 'block' : 'none'; let conclusionHTML = ""; if (sfResults && mfResults) { if (sfResults.netFinancialPositionChangeReal > mfResults.netFinancialPositionChangeReal) { conclusionHTML = `Based on these assumptions, the Single-Family property appears to result in a better estimated real net financial position by approximately ${formatCurrency(sfResults.netFinancialPositionChangeReal - mfResults.netFinancialPositionChangeReal)} after ${general.analysisPeriod} years.`; } else if (mfResults.netFinancialPositionChangeReal > sfResults.netFinancialPositionChangeReal) { conclusionHTML = `Based on these assumptions, the Multi-Family property appears to result in a better estimated real net financial position by approximately ${formatCurrency(mfResults.netFinancialPositionChangeReal - sfResults.netFinancialPositionChangeReal)} after ${general.analysisPeriod} years.`; } else { conclusionHTML = `Based on these assumptions, both scenarios result in a similar estimated real financial position after ${general.analysisPeriod} years.`; } } else if (sfResults) { conclusionHTML = `Only Single-Family property analyzed. Estimated real net financial position change: ${formatCurrency(sfResults.netFinancialPositionChangeReal)}.`; } else if (mfResults) { conclusionHTML = `Only Multi-Family property analyzed. Estimated real net financial position change: ${formatCurrency(mfResults.netFinancialPositionChangeReal)}.`; } else { conclusionHTML = "Please enter details for at least one property type to see a conclusion."; } overallConclusionEl.innerHTML = conclusionHTML; notesContainerEl.style.display = 'block'; downloadPdfBtn.style.display = 'block'; } function renderYearByYearTable(data, container, title) { if (!data || data.length === 0) { container.innerHTML = `

${title} - Year-by-Year Data

No data to display.

`; container.style.display = 'block'; return; } let tableHTML = `

${title} - Year-by-Year Projections (Nominal $)

`; data.forEach(yearData => { tableHTML += ``; }); tableHTML += `
YearProp. ValueEff. Gross Inc.Op. Expenses NOIDebt ServiceCash Flow BTLoan Bal.Equity
${yearData.year} ${formatCurrency(yearData.currentPropertyValue)} ${formatCurrency(yearData.effectiveGrossIncome)} ${formatCurrency(yearData.totalOperatingExpenses)} ${formatCurrency(yearData.noi)} ${formatCurrency(yearData.debtServiceYear)} ${formatCurrency(yearData.cashFlowBeforeTaxNominal)} ${formatCurrency(yearData.loanBalanceEndOfYear)} ${formatCurrency(yearData.equityNominal)}
`; container.innerHTML = tableHTML; container.style.display = 'block'; } function formatCurrency(value) { return `$${(value || 0).toLocaleString(undefined, {minimumFractionDigits:0, maximumFractionDigits:0})}`; } downloadPdfBtn?.addEventListener('click', function () { const { jsPDF } = window.jspdf; const pdfOutputArea = document.getElementById('mfsfPdfOutputArea'); if (!pdfOutputArea || overallConclusionEl.innerHTML === "" || overallConclusionEl.innerHTML.includes("Please run the comparison")) { alert('Please run the comparison first before downloading PDF.'); return; } document.getElementById('mfsfNotesContainer').style.display = 'block'; document.getElementById('mfsfInputSummaryForPdf').style.display = 'block'; document.getElementById('mfsfYearByYearTitle').style.display = 'block'; document.getElementById('mfsfSfYearByYearTableContainer').style.display = document.getElementById('sfPurchasePrice').value > 0 ? 'block' : 'none'; document.getElementById('mfsfMfYearByYearTableContainer').style.display = document.getElementById('mfPurchasePrice').value > 0 ? 'block' : 'none'; html2canvas(pdfOutputArea, { scale: 1.0, useCORS: true, backgroundColor: '#ffffff', windowWidth: pdfOutputArea.scrollWidth, windowHeight: pdfOutputArea.scrollHeight }) .then(canvas => { const imgData = canvas.toDataURL('image/jpeg', 0.8); // Lower quality for potentially large canvas const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a3' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const margin = 20; let contentWidth = pdfWidth - 2 * margin; let contentHeight = pdfHeight - 2 * margin; const canvasWidth = canvas.width; const canvasHeight = canvas.height; let imgWidth = canvasWidth; let imgHeight = canvasHeight; let ratio = imgWidth / imgHeight; if (imgWidth > contentWidth) { imgWidth = contentWidth; imgHeight = imgWidth / ratio; } if (imgHeight > contentHeight) { imgHeight = contentHeight; imgWidth = imgHeight * ratio; } const x = (pdfWidth - imgWidth) / 2; const y = (pdfHeight - imgHeight) / 2; pdf.addImage(imgData, 'JPEG', x, y, imgWidth, imgHeight, undefined, 'FAST'); pdf.save('SF_vs_MF_RealEstate_Comparison.pdf'); }) .catch(err => { console.error("Error generating PDF:", err); alert("Error generating PDF. See console for details."); }); }); function escapeHtml(unsafe) { if (typeof unsafe !== 'string') return unsafe === undefined || unsafe === null ? '' : String(unsafe); return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); } switchTab('generalTab'); });
Scroll to Top