Qualitative Risk Assessment
Overall Risk Score: ${totalRiskScore.toFixed(1)} / 100
Risk Level: ${riskLevel}
Key Risk Factors Considered:
${riskFactors.map(f => `- ${f.text.split('(')[0].trim()} (Sponsor Track Record, Market, etc.) - Impact: ${f.risk}/10
`).join('')}
${sponsorPromoteText ? `
Sponsor Promote Structure: ${sponsorPromoteText}
` : ''}
`;
navigateToTab('tabAnalysis');
}
function generatePdf() {
if (!currentAnalysisData) {
alert("Please analyze the investment first to generate a PDF.");
return;
}
const data = currentAnalysisData;
const pdf = new jsPDF();
const today = new Date().toLocaleDateString();
pdf.setFontSize(18);
pdf.setTextColor(59, 130, 246); // Tailwind blue-600
pdf.text("Crowdfunded Real Estate Investment Analysis", 105, 20, null, null, "center");
pdf.setFontSize(10);
pdf.setTextColor(100);
pdf.text(`Deal: ${data.dealName}`, 14, 30);
pdf.text(`Generated on: ${today}`, 105, 30, null, null, "center");
let yPos = 40;
const addSection = (title, sectionData) => {
pdf.setFontSize(12);
pdf.setTextColor(31, 41, 55); // gray-800
pdf.text(title, 14, yPos);
yPos += 6;
pdf.autoTable({
startY: yPos,
body: sectionData,
theme: 'grid',
styles: { fontSize: 9, cellPadding: 2 },
columnStyles: { 0: { fontStyle: 'bold' } },
margin: { left: 14, right: 14 }
});
yPos = pdf.lastAutoTable.finalY + 8;
};
const investmentDetailsData = [
["Your Investment Amount:", formatCurrency(data.investmentAmount)],
["Property Type:", data.propertyType],
["Deal Structure:", data.dealStructure],
["Projected Holding Period:", `${data.holdingPeriod} Years`],
["Location Context:", data.locationContext]
];
addSection("Investment & Deal Specifics", investmentDetailsData);
const returnsFeesData = [
["Upfront Platform/Sponsor Fees:", `${formatCurrency(data.upfrontFeeAmount)} (${data.platformFeesInput})`],
["Net Investment Amount:", formatCurrency(data.netInvestmentAmount)],
["Projected Annual Cash Flow/Distributions:", formatCurrency(data.projectedAnnualCashFlow)],
["Total Projected Cash Flow (during hold):", formatCurrency(data.totalProjectedCashFlow)],
["Projected Profit Share from Sale:", formatCurrency(data.projectedSaleProfit)],
["Ongoing Asset Management Fees (Annual Rate Est.):", formatPercentage(data.ongoingFeeRate) + (data.ongoingFeesInput.includes('$') ? ` (from ${data.ongoingFeesInput})` : ` (from ${data.ongoingFeesInput})`)],
["Total Estimated Ongoing Fees (over hold):", formatCurrency(data.totalEstimatedOngoingFees)],
["Sponsor Promote Structure:", data.sponsorPromoteText || "N/A"],
];
addSection("Projected Returns & Fees", returnsFeesData);
const financialProjectionsData = [
["Total Net Profit (Est.):", formatCurrency(data.netProfit)],
["Total Return on Net Investment (ROI):", formatPercentage(data.totalReturnOnInvestment)],
["Annualized ROI (Est.):", formatPercentage(data.annualizedROI)],
["Average Annual Cash on Cash Return (Est.):", formatPercentage(data.cashOnCashReturn)],
];
addSection("Key Financial Projections", financialProjectionsData);
pdf.setFontSize(12);
pdf.setTextColor(31, 41, 55);
pdf.text("Qualitative Risk Assessment", 14, yPos);
yPos +=6;
const riskSummaryData = [
["Overall Risk Score:", `${data.totalRiskScore.toFixed(1)} / 100`],
["Risk Level:", data.riskLevel],
];
pdf.autoTable({ startY: yPos, body: riskSummaryData, theme: 'plain', styles: { fontSize: 9, cellPadding: 1.5 }, columnStyles: { 0: { fontStyle: 'bold' } }});
yPos = pdf.lastAutoTable.finalY + 3;
const riskFactorsTable = data.riskFactors.map(f => [f.text.split('(')[0].trim(), `${f.risk}/10`]);
pdf.autoTable({
startY: yPos,
head: [['Factor Category', 'Assigned Risk Impact']],
body: riskFactorsTable,
theme: 'grid',
headStyles: { fillColor: [229, 231, 235], textColor: [55, 65, 81] },
styles: { fontSize: 9, cellPadding: 2 },
margin: { left: 14, right: 14 }
});
pdf.save(`Crowdfunded_Investment_Analysis_${data.dealName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf`);
}
// Event Listeners & Initialization
document.addEventListener('DOMContentLoaded', () => {
// Assign elements
dealNameElem = document.getElementById('dealName');
investmentAmountElem = document.getElementById('investmentAmount');
propertyTypeElem = document.getElementById('propertyType');
dealStructureElem = document.getElementById('dealStructure');
holdingPeriodElem = document.getElementById('holdingPeriod');
locationContextElem = document.getElementById('locationContext');
projectedAnnualCashFlowElem = document.getElementById('projectedAnnualCashFlow');
projectedSaleProfitElem = document.getElementById('projectedSaleProfit');
platformFeesElem = document.getElementById('platformFees');
ongoingAssetManagementFeesElem = document.getElementById('ongoingAssetManagementFees');
sponsorPromoteElem = document.getElementById('sponsorPromote');
sponsorTrackRecordElem = document.getElementById('sponsorTrackRecord');
marketConditionsElem = document.getElementById('marketConditions');
liquidityOptionsElem = document.getElementById('liquidityOptions');
leverageLevelElem = document.getElementById('leverageLevel');
communicationTransparencyElem = document.getElementById('communicationTransparency');
analysisOutputElem = document.getElementById('analysisOutput');
analyzeButtonElem = document.getElementById('analyzeButton');
downloadPdfButtonElem = document.getElementById('downloadPdfButton');
if (!analyzeButtonElem || !downloadPdfButtonElem) {
console.error("Critical button elements not found!");
return;
}
analyzeButtonElem.addEventListener('click', analyzeInvestment);
downloadPdfButtonElem.addEventListener('click', generatePdf);
const firstTabButton = document.querySelector('.tab-button');
if (firstTabButton) {
changeTab({ currentTarget: firstTabButton }, 'tabInvestment');
}
});