AI-Powered Lease & Tenant Risk Analysis Tool (Conceptual Simulator)
Property & Lease Context
$
Tenant Profile Simulation
Input hypothetical data for the prospective tenant.
Financial Stability
$
$
Calculated Rent-to-Income: -
Calculated Debt-to-Income (excl. rent): -
Rental & Employment History (Conceptual Scores 1-10)
1 = Very Poor/High Risk, 10 = Excellent/Low Risk for these scores.Other Factors
Lease Clause Analysis (Landlord Perspective)
Indicate presence and nature of key lease clauses. Risk points are conceptual: Negative means higher risk for landlord, Positive means lower risk.
Risk Factor Weighting (Importance 1-10)
Risk Assessment & Report
Assessment results will appear here after processing data.
No assessment data. Please input data and click "Analyze Risk".
'; return; } const assessment = ailtra_model.assessment; let detailsHTML = 'Risk Score Contributions (Higher score = Higher Risk):
'; assessment.contributions.forEach(c => { detailsHTML += `
${c.name} (Factor Score: ${c.score}/100, Weight: ${c.weight})
${c.weightedEffect} pts to Overall
`;
});
resultsSection.innerHTML = `
Risk Assessment for ${ailtra_model.inputsSnapshot.context.propertyType}
${assessment.overallScore.toFixed(1)} / 100
${assessment.qualitativeLevel}
This is a conceptual risk score based on your inputs and weights. 0-33 suggests Low Risk, 34-66 Moderate Risk, and 67-100 High Risk from the landlord's perspective.
`; } // --- PDF Generation --- function ailtra_downloadPDF() { if (!ailtra_model.assessment) { alert("Please assess risk first."); return; } if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Core PDF library (jsPDF) is not loaded.'); console.error('jsPDF library not found.'); return; } const { jsPDF: JSPDF } = window.jspdf; const doc = new JSPDF(); if (typeof doc.autoTable !== 'function') { alert('PDF Table plugin (jsPDF-AutoTable) is not loaded correctly. Tables in PDF might be missing or PDF generation may fail.\nPlease ensure your internet connection is active and no browser extensions are blocking scripts from cdnjs.cloudflare.com.'); console.error('doc.autoTable is not a function. jsPDF-AutoTable plugin error.'); // Optionally provide a text-only fallback if tables are critical } let y = 15; const m = 15; const cw = doc.internal.pageSize.getWidth() - (2 * m); const assessment = ailtra_model.assessment; const inputs = assessment.inputsSnapshot; // Use the snapshot function addLine(text, size, style = 'normal', indent = 0, spacing = 2.5) { if (y > 275) { doc.addPage(); y = m; } doc.setFontSize(size); doc.setFont(undefined, style); const lines = doc.splitTextToSize(text, cw - indent); doc.text(lines, m + indent, y); y += (lines.length * (size * 0.35)) + spacing; } addLine(`Lease & Tenant Risk Analysis Report`, 18, 'bold', 0, 5); addLine(`Property Type: ${inputs.context.propertyType}`, 10); addLine(`Monthly Rent: ${ailtra_formatCurrency(inputs.context.monthlyRent)} | Lease Term: ${inputs.context.leaseTerm} months`, 10, 'normal', 0, 5); addLine(`Overall Risk Score: ${assessment.overallScore.toFixed(1)} / 100 - ${assessment.qualitativeLevel}`, 14, 'bold', 0, 6); addLine("Tenant Profile Summary:", 12, 'bold', 0, 3); const rti = inputs.tenant.income > 0 ? (inputs.context.monthlyRent / inputs.tenant.income)*100 : Infinity; const dti = inputs.tenant.income > 0 ? (inputs.tenant.debt / inputs.tenant.income)*100 : Infinity; addLine(`- Income: ${ailtra_formatCurrency(inputs.tenant.income)}/month | Debt: ${ailtra_formatCurrency(inputs.tenant.debt)}/month`, 9, 'normal', 5, 1.5); addLine(`- Rent-to-Income: ${isFinite(rti) ? ailtra_formatPercent(rti) : 'N/A'} | Debt-to-Income (excl. rent): ${isFinite(dti) ? ailtra_formatPercent(dti) : 'N/A'}`, 9, 'normal', 5, 1.5); addLine(`- Rental History Score: ${inputs.tenant.rentalHistoryScore}/10 | Employment Stability: ${inputs.tenant.employmentStabilityScore}/10 | Occupancy Fit: ${inputs.tenant.occupantsFitScore}/5`, 9, 'normal', 5, 3); addLine("Lease Clause Configuration:", 12, 'bold', 0, 3); const clauseHead = [['Clause', 'Selected Option', 'Conceptual Risk Pts', 'Weight']]; const clauseBody = inputs.leaseClauses.map(c => [ c.name, c.options[c.selectedOption].text, c.options[c.selectedOption].points.toString(), c.weight.toString() ]); if (typeof doc.autoTable === 'function') { doc.autoTable({ startY: y, head: clauseHead, body: clauseBody, theme: 'grid', headStyles: {fillColor: [45,55,72]}, styles: {fontSize:8, cellPadding:1.5}}); y = doc.lastAutoTable.finalY + 5; } else { addLine("Lease clause table could not be generated (plugin issue).", 8, 'italic'); y +=5; } addLine("Risk Weighting & Score Contribution:", 12, 'bold', 0, 3); const contribHead = [['Risk Category', 'Category Risk Score (0-100)', 'Assigned Weight (1-10)', 'Weighted Contribution to Overall']]; const contribBody = assessment.contributions.map(c => [ c.name, `${parseFloat(c.score).toFixed(0)} / 100`, c.weight.toString(), `${parseFloat(c.weightedEffect).toFixed(0)} pts` ]); if (typeof doc.autoTable === 'function') { doc.autoTable({ startY: y, head: contribHead, body: contribBody, theme: 'grid', headStyles: {fillColor: [45,55,72]}, styles: {fontSize:8, cellPadding:1.5}}); y = doc.lastAutoTable.finalY + 7; } else { addLine("Contributions table could not be generated (plugin issue).", 8, 'italic'); y +=5; } addLine("Disclaimer: This is a conceptual simulation based on user-defined parameters and subjective scoring. It does not constitute professional financial, legal, or investment advice.", 7, 'italic'); doc.save(`LeaseTenantRisk_Analysis_${inputs.context.propertyType.replace(/\s+/g, '_')}.pdf`); }