From a4c8aac92d965b51438e6c920cfa906a1cf19a23 Mon Sep 17 00:00:00 2001
From: Jon \n`;
+ summary += `\n
\n\n`;
+
+ // Add financial notes
+ if (analysisData.financialSummary.qualityOfEarnings) {
+ summary += `**Quality of Earnings:** ${analysisData.financialSummary.qualityOfEarnings}\n\n`;
+ }
+ if (analysisData.financialSummary.revenueGrowthDrivers) {
+ summary += `**Revenue Growth Drivers:** ${analysisData.financialSummary.revenueGrowthDrivers}\n\n`;
+ }
+ if (analysisData.financialSummary.marginStabilityAnalysis) {
+ summary += `**Margin Stability:** ${analysisData.financialSummary.marginStabilityAnalysis}\n\n`;
+ }
+ if (analysisData.financialSummary.capitalExpenditures) {
+ summary += `**Capital Expenditures:** ${analysisData.financialSummary.capitalExpenditures}\n\n`;
+ }
+ if (analysisData.financialSummary.workingCapitalIntensity) {
+ summary += `**Working Capital Intensity:** ${analysisData.financialSummary.workingCapitalIntensity}\n\n`;
+ }
+ if (analysisData.financialSummary.freeCashFlowQuality) {
+ summary += `**Free Cash Flow Quality:** ${analysisData.financialSummary.freeCashFlowQuality}\n\n`;
}
}
@@ -562,15 +676,11 @@ export class OptimizedAgenticRAGProcessor {
if (analysisData.managementTeamOverview.managementQualityAssessment) {
summary += `**Quality Assessment:** ${analysisData.managementTeamOverview.managementQualityAssessment}\n\n`;
}
- }
-
- // Add market analysis
- if (analysisData.marketIndustryAnalysis?.estimatedMarketSize) {
- summary += `## Market & Industry Analysis\n\n`;
- summary += `**Market Size:** ${analysisData.marketIndustryAnalysis.estimatedMarketSize}\n\n`;
-
- if (analysisData.marketIndustryAnalysis.keyIndustryTrends) {
- summary += `**Industry Trends:** ${analysisData.marketIndustryAnalysis.keyIndustryTrends}\n\n`;
+ if (analysisData.managementTeamOverview.postTransactionIntentions) {
+ summary += `**Post-Transaction Intentions:** ${analysisData.managementTeamOverview.postTransactionIntentions}\n\n`;
+ }
+ if (analysisData.managementTeamOverview.organizationalStructure) {
+ summary += `**Organizational Structure:** ${analysisData.managementTeamOverview.organizationalStructure}\n\n`;
}
}
@@ -582,6 +692,31 @@ export class OptimizedAgenticRAGProcessor {
if (analysisData.preliminaryInvestmentThesis.potentialRisks) {
summary += `**Potential Risks:** ${analysisData.preliminaryInvestmentThesis.potentialRisks}\n\n`;
}
+ if (analysisData.preliminaryInvestmentThesis.valueCreationLevers) {
+ summary += `**Value Creation Levers:** ${analysisData.preliminaryInvestmentThesis.valueCreationLevers}\n\n`;
+ }
+ if (analysisData.preliminaryInvestmentThesis.alignmentWithFundStrategy) {
+ summary += `**Alignment with Fund Strategy:** ${analysisData.preliminaryInvestmentThesis.alignmentWithFundStrategy}\n\n`;
+ }
+ }
+
+ // Add key questions and next steps
+ if (analysisData.keyQuestionsNextSteps?.criticalQuestions) {
+ summary += `## Key Questions & Next Steps\n\n`;
+ summary += `**Critical Questions:** ${analysisData.keyQuestionsNextSteps.criticalQuestions}\n\n`;
+
+ if (analysisData.keyQuestionsNextSteps.missingInformation) {
+ summary += `**Missing Information:** ${analysisData.keyQuestionsNextSteps.missingInformation}\n\n`;
+ }
+ if (analysisData.keyQuestionsNextSteps.preliminaryRecommendation) {
+ summary += `**Preliminary Recommendation:** ${analysisData.keyQuestionsNextSteps.preliminaryRecommendation}\n\n`;
+ }
+ if (analysisData.keyQuestionsNextSteps.rationaleForRecommendation) {
+ summary += `**Rationale for Recommendation:** ${analysisData.keyQuestionsNextSteps.rationaleForRecommendation}\n\n`;
+ }
+ if (analysisData.keyQuestionsNextSteps.proposedNextSteps) {
+ summary += `**Proposed Next Steps:** ${analysisData.keyQuestionsNextSteps.proposedNextSteps}\n\n`;
+ }
}
return summary;
diff --git a/backend/src/services/pdfGenerationService.ts b/backend/src/services/pdfGenerationService.ts
index 986e243..8c59041 100644
--- a/backend/src/services/pdfGenerationService.ts
+++ b/backend/src/services/pdfGenerationService.ts
@@ -74,8 +74,7 @@ class PDFGenerationService {
* Convert markdown to HTML
*/
private markdownToHTML(markdown: string): string {
- // Simple markdown to HTML conversion
- // In a production environment, you might want to use a proper markdown parser
+ // Enhanced markdown to HTML conversion with table support
let html = markdown
// Headers
.replace(/^### (.*$)/gim, '\n \n\n\n`;
+
+ // Revenue row
+ if (financials.fy1?.revenue || financials.fy2?.revenue || financials.fy3?.revenue || financials.ltm?.revenue) {
+ summary += `Metric \n`;
+
+ const periods = [];
+ if (financials.fy1) periods.push('FY1');
+ if (financials.fy2) periods.push('FY2');
+ if (financials.fy3) periods.push('FY3');
+ if (financials.ltm) periods.push('LTM');
+
+ periods.forEach(period => {
+ summary += `${period} \n`;
+ });
+ summary += `\n \n`;
+ }
+
+ // EBITDA row
+ if (financials.fy1?.ebitda || financials.fy2?.ebitda || financials.fy3?.ebitda || financials.ltm?.ebitda) {
+ summary += `Revenue \n`;
+ periods.forEach(period => {
+ let value = '-';
+ if (period === 'FY1' && financials.fy1?.revenue) value = financials.fy1.revenue;
+ else if (period === 'FY2' && financials.fy2?.revenue) value = financials.fy2.revenue;
+ else if (period === 'FY3' && financials.fy3?.revenue) value = financials.fy3.revenue;
+ else if (period === 'LTM' && financials.ltm?.revenue) value = financials.ltm.revenue;
+ summary += `${value} \n`;
+ });
+ summary += `\n \n`;
+ }
+
+ // EBITDA Margin row
+ if (financials.fy1?.ebitdaMargin || financials.fy2?.ebitdaMargin || financials.fy3?.ebitdaMargin || financials.ltm?.ebitdaMargin) {
+ summary += `EBITDA \n`;
+ periods.forEach(period => {
+ let value = '-';
+ if (period === 'FY1' && financials.fy1?.ebitda) value = financials.fy1.ebitda;
+ else if (period === 'FY2' && financials.fy2?.ebitda) value = financials.fy2.ebitda;
+ else if (period === 'FY3' && financials.fy3?.ebitda) value = financials.fy3.ebitda;
+ else if (period === 'LTM' && financials.ltm?.ebitda) value = financials.ltm.ebitda;
+ summary += `${value} \n`;
+ });
+ summary += `\n \n`;
+ }
+
+ // Revenue Growth row
+ if (financials.fy1?.revenueGrowth || financials.fy2?.revenueGrowth || financials.fy3?.revenueGrowth || financials.ltm?.revenueGrowth) {
+ summary += `EBITDA Margin \n`;
+ periods.forEach(period => {
+ let value = '-';
+ if (period === 'FY1' && financials.fy1?.ebitdaMargin) value = financials.fy1.ebitdaMargin;
+ else if (period === 'FY2' && financials.fy2?.ebitdaMargin) value = financials.fy2.ebitdaMargin;
+ else if (period === 'FY3' && financials.fy3?.ebitdaMargin) value = financials.fy3.ebitdaMargin;
+ else if (period === 'LTM' && financials.ltm?.ebitdaMargin) value = financials.ltm.ebitdaMargin;
+ summary += `${value} \n`;
+ });
+ summary += `\n \n`;
+ }
+
+ summary += `\nRevenue Growth \n`;
+ periods.forEach(period => {
+ let value = '-';
+ if (period === 'FY1' && financials.fy1?.revenueGrowth) value = financials.fy1.revenueGrowth;
+ else if (period === 'FY2' && financials.fy2?.revenueGrowth) value = financials.fy2.revenueGrowth;
+ else if (period === 'FY3' && financials.fy3?.revenueGrowth) value = financials.fy3.revenueGrowth;
+ else if (period === 'LTM' && financials.ltm?.revenueGrowth) value = financials.ltm.revenueGrowth;
+ summary += `${value} \n`;
+ });
+ summary += `$1
')
@@ -87,13 +86,19 @@ class PDFGenerationService {
.replace(/\*(.*?)\*/g, '$1')
// Lists
.replace(/^- (.*$)/gim, '
') .replace(/^(.+)$/gm, '
$1
'); // Wrap lists properly html = html.replace(/<\/table>/g, ''); + html = html.replace(/