Start-Up_Viability_Agent / document_templates.py
Navada25's picture
Update document_templates.py with stock analysis features
404da36 verified
# Document Template Generation System for NAVADA
"""
Business document template generation with customizable formats
for different startup stages and investor needs.
"""
import io
import json
import datetime
from typing import Dict, Any, List, Optional
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, PageBreak,
Table, TableStyle, Image, KeepTogether, ListFlowable, ListItem
)
from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
import pandas as pd
class DocumentTemplateGenerator:
"""Generate professional business documents for startups."""
def __init__(self):
self.styles = self._create_custom_styles()
self.templates = {
'business_case': self.generate_business_case,
'pitch_deck': self.generate_pitch_deck_outline,
'financial_model': self.generate_financial_model_template,
'investor_memo': self.generate_investor_memo,
'executive_summary': self.generate_executive_summary,
'market_analysis': self.generate_market_analysis,
'competitive_analysis': self.generate_competitive_analysis,
'go_to_market': self.generate_go_to_market_strategy,
'risk_assessment': self.generate_risk_assessment,
'term_sheet': self.generate_term_sheet_template
}
def _create_custom_styles(self):
"""Create custom paragraph styles for professional documents."""
styles = getSampleStyleSheet()
# Title style
styles.add(ParagraphStyle(
name='CustomTitle',
parent=styles['Title'],
fontSize=24,
textColor=colors.HexColor('#1a1a1a'),
spaceAfter=30,
alignment=TA_CENTER
))
# Heading styles
styles.add(ParagraphStyle(
name='CustomHeading1',
parent=styles['Heading1'],
fontSize=18,
textColor=colors.HexColor('#2c3e50'),
spaceAfter=16,
spaceBefore=12,
leftIndent=0,
fontName='Helvetica-Bold'
))
styles.add(ParagraphStyle(
name='CustomHeading2',
parent=styles['Heading2'],
fontSize=14,
textColor=colors.HexColor('#34495e'),
spaceAfter=12,
spaceBefore=8,
leftIndent=10,
fontName='Helvetica-Bold'
))
# Body text
styles.add(ParagraphStyle(
name='CustomBodyText',
parent=styles['BodyText'],
fontSize=11,
textColor=colors.HexColor('#2c3e50'),
alignment=TA_JUSTIFY,
spaceAfter=12,
leading=16
))
# Bullet points
styles.add(ParagraphStyle(
name='CustomBullet',
parent=styles['BodyText'],
fontSize=11,
leftIndent=20,
bulletIndent=10,
spaceAfter=8
))
return styles
def generate_business_case(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a comprehensive business case document."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(
buffer,
pagesize=A4,
rightMargin=72,
leftMargin=72,
topMargin=72,
bottomMargin=72
)
story = []
# Cover Page
story.append(Paragraph(
f"<b>BUSINESS CASE</b><br/><br/>{startup_data.get('company_name', 'Your Startup')}",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.5*inch))
# Date
story.append(Paragraph(
f"Prepared: {datetime.datetime.now().strftime('%B %d, %Y')}",
self.styles['Normal']
))
story.append(PageBreak())
# Executive Summary
story.append(Paragraph("EXECUTIVE SUMMARY", self.styles['CustomHeading1']))
story.append(Paragraph(
startup_data.get('executive_summary',
'This business case outlines the strategic rationale, market opportunity, '
'and financial projections for our venture. We address a significant market '
'gap with an innovative solution that delivers measurable value to our target customers.'),
self.styles['CustomBodyText']
))
story.append(Spacer(1, 0.3*inch))
# Problem Statement
story.append(Paragraph("1. PROBLEM STATEMENT", self.styles['CustomHeading1']))
story.append(Paragraph(
startup_data.get('problem_statement',
'The market currently faces significant challenges that create opportunities '
'for innovative solutions. Our research indicates substantial unmet needs '
'in our target segment.'),
self.styles['CustomBodyText']
))
# Market Pain Points
pain_points = startup_data.get('pain_points', [
'Inefficient current solutions',
'High costs for existing alternatives',
'Poor user experience',
'Lack of integration capabilities'
])
story.append(Paragraph("Key Pain Points:", self.styles['CustomHeading2']))
for point in pain_points:
story.append(Paragraph(f"• {point}", self.styles['CustomBullet']))
story.append(Spacer(1, 0.3*inch))
# Proposed Solution
story.append(Paragraph("2. PROPOSED SOLUTION", self.styles['CustomHeading1']))
story.append(Paragraph(
startup_data.get('solution',
'Our solution leverages cutting-edge technology and deep market insights '
'to deliver a superior alternative that addresses all identified pain points.'),
self.styles['CustomBodyText']
))
# Value Proposition
story.append(Paragraph("Value Proposition:", self.styles['CustomHeading2']))
value_props = startup_data.get('value_proposition', [
'10x improvement in efficiency',
'50% cost reduction',
'Seamless user experience',
'Full integration with existing systems'
])
for prop in value_props:
story.append(Paragraph(f"• {prop}", self.styles['CustomBullet']))
story.append(Spacer(1, 0.3*inch))
# Market Analysis
story.append(Paragraph("3. MARKET ANALYSIS", self.styles['CustomHeading1']))
# Market Size Table
market_data = [
['Market Segment', 'TAM', 'SAM', 'SOM (Year 3)'],
['Primary Market',
startup_data.get('tam', '$50B'),
startup_data.get('sam', '$5B'),
startup_data.get('som', '$100M')],
['Growth Rate', '15% CAGR', '20% CAGR', '50% YoY'],
]
market_table = Table(market_data, colWidths=[2.5*inch, 1.5*inch, 1.5*inch, 1.5*inch])
market_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#34495e')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.HexColor('#ecf0f1')),
('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#bdc3c7'))
]))
story.append(market_table)
story.append(Spacer(1, 0.3*inch))
# Financial Projections
story.append(Paragraph("4. FINANCIAL PROJECTIONS", self.styles['CustomHeading1']))
financial_data = [
['Metric', 'Year 1', 'Year 2', 'Year 3', 'Year 5'],
['Revenue', '$500K', '$2.5M', '$10M', '$50M'],
['Gross Margin', '60%', '65%', '70%', '75%'],
['EBITDA', '-$1M', '-$500K', '$2M', '$15M'],
['Cash Flow', '-$1.5M', '-$200K', '$1.5M', '$12M'],
]
financial_table = Table(financial_data, colWidths=[1.8*inch, 1.2*inch, 1.2*inch, 1.2*inch, 1.2*inch])
financial_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#27ae60')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.HexColor('#e8f8f5')),
('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#27ae60'))
]))
story.append(financial_table)
story.append(Spacer(1, 0.3*inch))
# Implementation Timeline
story.append(Paragraph("5. IMPLEMENTATION TIMELINE", self.styles['CustomHeading1']))
phases = startup_data.get('timeline', [
{'phase': 'Phase 1: MVP Development', 'duration': '3 months',
'deliverables': 'Core product features, initial user testing'},
{'phase': 'Phase 2: Market Launch', 'duration': '2 months',
'deliverables': 'Go-to-market execution, first customers'},
{'phase': 'Phase 3: Scale', 'duration': '6 months',
'deliverables': 'Product refinement, team expansion, Series A'},
])
for phase in phases:
story.append(Paragraph(f"<b>{phase['phase']}</b> ({phase['duration']})",
self.styles['CustomHeading2']))
story.append(Paragraph(f"Deliverables: {phase['deliverables']}",
self.styles['CustomBodyText']))
story.append(Spacer(1, 0.3*inch))
# Risk Assessment
story.append(Paragraph("6. RISK ASSESSMENT", self.styles['CustomHeading1']))
risks = startup_data.get('risks', [
{'risk': 'Market Risk', 'impact': 'High', 'mitigation': 'Extensive customer validation and pivoting capability'},
{'risk': 'Technical Risk', 'impact': 'Medium', 'mitigation': 'Experienced team and proven technology stack'},
{'risk': 'Competitive Risk', 'impact': 'Medium', 'mitigation': 'First-mover advantage and strong IP protection'},
{'risk': 'Financial Risk', 'impact': 'High', 'mitigation': 'Conservative burn rate and multiple funding sources'},
])
risk_data = [['Risk Type', 'Impact', 'Mitigation Strategy']]
for risk in risks:
risk_data.append([risk['risk'], risk['impact'], risk['mitigation']])
risk_table = Table(risk_data, colWidths=[1.5*inch, 1*inch, 3.5*inch])
risk_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#e74c3c')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.HexColor('#fadbd8')),
('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#e74c3c'))
]))
story.append(risk_table)
story.append(PageBreak())
# Investment Requirements
story.append(Paragraph("7. INVESTMENT REQUIREMENTS", self.styles['CustomHeading1']))
funding_need = startup_data.get('funding_need', '$2M')
use_of_funds = startup_data.get('use_of_funds', [
{'category': 'Product Development', 'allocation': '40%', 'amount': '$800K'},
{'category': 'Sales & Marketing', 'allocation': '30%', 'amount': '$600K'},
{'category': 'Operations', 'allocation': '20%', 'amount': '$400K'},
{'category': 'Reserve', 'allocation': '10%', 'amount': '$200K'},
])
story.append(Paragraph(
f"<b>Total Funding Required:</b> {funding_need}",
self.styles['CustomBodyText']
))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph("Use of Funds:", self.styles['CustomHeading2']))
funds_data = [['Category', 'Allocation', 'Amount']]
for fund in use_of_funds:
funds_data.append([fund['category'], fund['allocation'], fund['amount']])
funds_table = Table(funds_data, colWidths=[2.5*inch, 1.5*inch, 1.5*inch])
funds_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3498db')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.HexColor('#ebf5fb')),
('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#3498db'))
]))
story.append(funds_table)
story.append(Spacer(1, 0.3*inch))
# Expected Returns
story.append(Paragraph("Expected Returns:", self.styles['CustomHeading2']))
story.append(Paragraph(
f"• Target IRR: {startup_data.get('target_irr', '35%')}<br/>"
f"• Exit Timeline: {startup_data.get('exit_timeline', '5-7 years')}<br/>"
f"• Exit Multiple: {startup_data.get('exit_multiple', '10x')}<br/>",
self.styles['CustomBodyText']
))
# Conclusion
story.append(Paragraph("8. CONCLUSION", self.styles['CustomHeading1']))
story.append(Paragraph(
startup_data.get('conclusion',
'This business case demonstrates a compelling opportunity with strong '
'fundamentals, clear market demand, and a capable team. The financial '
'projections show a path to profitability and significant returns for investors. '
'We are positioned to capture a meaningful share of a large and growing market.'),
self.styles['CustomBodyText']
))
# Next Steps
story.append(Paragraph("Next Steps:", self.styles['CustomHeading2']))
next_steps = startup_data.get('next_steps', [
'Finalize investment terms',
'Complete due diligence process',
'Execute growth strategy',
'Achieve key milestones'
])
for step in next_steps:
story.append(Paragraph(f"• {step}", self.styles['CustomBullet']))
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def generate_pitch_deck_outline(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a pitch deck outline document."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=letter)
story = []
# Title
story.append(Paragraph(
f"<b>PITCH DECK OUTLINE</b><br/><br/>{startup_data.get('company_name', 'Your Startup')}",
self.styles['CustomTitle']
))
story.append(PageBreak())
# Slide structure
slides = [
{
'number': '1',
'title': 'Title Slide',
'content': [
'Company name and logo',
'Tagline/Value proposition',
'Contact information'
],
'tips': 'Keep it clean and professional. First impressions matter.'
},
{
'number': '2',
'title': 'Problem',
'content': [
'Clear problem statement',
'Who experiences this problem',
'Current solutions and their shortcomings',
'Market pain points'
],
'tips': 'Make it relatable. Use real examples and stories.'
},
{
'number': '3',
'title': 'Solution',
'content': [
'Your unique solution',
'Key features and benefits',
'Product demo or screenshots',
'Technology advantage'
],
'tips': 'Show, don\'t just tell. Use visuals and demos when possible.'
},
{
'number': '4',
'title': 'Market Opportunity',
'content': [
'TAM, SAM, SOM analysis',
'Market growth trends',
'Target customer segments',
'Geographic expansion potential'
],
'tips': 'Use credible sources. Show bottom-up market sizing.'
},
{
'number': '5',
'title': 'Business Model',
'content': [
'Revenue streams',
'Pricing strategy',
'Customer acquisition cost (CAC)',
'Lifetime value (LTV)',
'Unit economics'
],
'tips': 'Be specific about how you make money. Show proven metrics if available.'
},
{
'number': '6',
'title': 'Traction',
'content': [
'Key metrics and KPIs',
'Customer testimonials',
'Revenue growth',
'User growth',
'Partnerships'
],
'tips': 'Use charts and graphs. Show month-over-month growth.'
},
{
'number': '7',
'title': 'Competition',
'content': [
'Competitive landscape',
'Your unique advantages',
'Barriers to entry',
'Positioning matrix'
],
'tips': 'Be honest about competition. Show why you\'ll win.'
},
{
'number': '8',
'title': 'Go-to-Market Strategy',
'content': [
'Customer acquisition channels',
'Sales strategy',
'Marketing plan',
'Partnership strategy'
],
'tips': 'Show you understand your customers and how to reach them.'
},
{
'number': '9',
'title': 'Team',
'content': [
'Founder backgrounds',
'Key team members',
'Advisory board',
'Key investors'
],
'tips': 'Highlight relevant experience and past successes.'
},
{
'number': '10',
'title': 'Financial Projections',
'content': [
'3-5 year revenue projections',
'Path to profitability',
'Key assumptions',
'Burn rate and runway'
],
'tips': 'Be realistic but ambitious. Show key drivers of growth.'
},
{
'number': '11',
'title': 'The Ask',
'content': [
'Funding amount',
'Use of funds',
'Milestones to be achieved',
'Expected timeline'
],
'tips': 'Be specific about what you need and what you\'ll accomplish.'
},
{
'number': '12',
'title': 'Contact/Q&A',
'content': [
'Contact details',
'Website and social media',
'Next steps',
'Q&A prompt'
],
'tips': 'End with a clear call to action.'
}
]
for slide in slides:
story.append(Paragraph(
f"<b>Slide {slide['number']}: {slide['title']}</b>",
self.styles['CustomHeading1']
))
story.append(Paragraph("Content:", self.styles['CustomHeading2']))
for item in slide['content']:
story.append(Paragraph(f"• {item}", self.styles['CustomBullet']))
story.append(Paragraph("💡 Tips:", self.styles['CustomHeading2']))
story.append(Paragraph(slide['tips'], self.styles['CustomBodyText']))
story.append(Spacer(1, 0.3*inch))
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def generate_financial_model_template(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a financial model template document."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=A4)
story = []
# Title
story.append(Paragraph(
f"<b>FINANCIAL MODEL TEMPLATE</b><br/><br/>{startup_data.get('company_name', 'Your Startup')}",
self.styles['CustomTitle']
))
story.append(PageBreak())
# Revenue Model
story.append(Paragraph("REVENUE MODEL", self.styles['CustomHeading1']))
# Add revenue assumptions table
revenue_assumptions = [
['Parameter', 'Year 1', 'Year 2', 'Year 3', 'Notes'],
['Customer Acquisition', '100', '500', '2000', 'Based on marketing spend'],
['Avg. Revenue/Customer', '$500', '$600', '$750', 'Price increases with value'],
['Churn Rate', '10%', '8%', '5%', 'Improving retention'],
['Upsell Rate', '20%', '30%', '40%', 'Product expansion']
]
revenue_table = Table(revenue_assumptions)
revenue_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2ecc71')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('GRID', (0, 0), (-1, -1), 1, colors.grey)
]))
story.append(revenue_table)
story.append(Spacer(1, 0.3*inch))
# Cost Structure
story.append(Paragraph("COST STRUCTURE", self.styles['CustomHeading1']))
cost_structure = [
['Cost Category', 'Year 1', 'Year 2', 'Year 3', '% of Revenue'],
['Personnel', '$500K', '$1.5M', '$3M', '30-40%'],
['Marketing', '$200K', '$750K', '$2M', '20-25%'],
['Technology', '$150K', '$300K', '$500K', '5-10%'],
['Operations', '$100K', '$250K', '$500K', '5-10%'],
['G&A', '$50K', '$200K', '$500K', '5%']
]
cost_table = Table(cost_structure)
cost_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#e74c3c')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 10),
('GRID', (0, 0), (-1, -1), 1, colors.grey)
]))
story.append(cost_table)
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def generate_investor_memo(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate an investor memorandum."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=letter)
story = []
# Title Page
story.append(Paragraph(
"<b>INVESTMENT MEMORANDUM</b>",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.3*inch))
story.append(Paragraph(
f"{startup_data.get('company_name', 'Your Startup')}",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.5*inch))
story.append(Paragraph(
"CONFIDENTIAL - NOT FOR DISTRIBUTION",
self.styles['Normal']
))
story.append(Paragraph(
f"Prepared: {datetime.datetime.now().strftime('%B %Y')}",
self.styles['Normal']
))
story.append(PageBreak())
# Investment Highlights
story.append(Paragraph("INVESTMENT HIGHLIGHTS", self.styles['CustomHeading1']))
highlights = startup_data.get('highlights', [
'Large and growing addressable market ($50B+ TAM)',
'Proven business model with strong unit economics',
'Experienced team with relevant domain expertise',
'Clear path to profitability within 24 months',
'Strategic partnerships with industry leaders',
'Proprietary technology with defensible moat'
])
for highlight in highlights:
story.append(Paragraph(f"✓ {highlight}", self.styles['CustomBullet']))
story.append(Spacer(1, 0.3*inch))
# Investment Terms
story.append(Paragraph("INVESTMENT TERMS", self.styles['CustomHeading1']))
terms_data = [
['Parameter', 'Terms'],
['Round Type', startup_data.get('round_type', 'Series A')],
['Target Raise', startup_data.get('target_raise', '$10M')],
['Pre-Money Valuation', startup_data.get('pre_money', '$40M')],
['Minimum Investment', startup_data.get('minimum', '$250K')],
['Use of Funds', 'Product (40%), Sales (30%), Ops (20%), Reserve (10%)'],
['Expected Close', startup_data.get('close_date', 'Q2 2024')]
]
terms_table = Table(terms_data, colWidths=[2*inch, 4*inch])
terms_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3498db')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('GRID', (0, 0), (-1, -1), 1, colors.grey)
]))
story.append(terms_table)
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def generate_executive_summary(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate an executive summary document."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=letter)
story = []
# Header
story.append(Paragraph(
f"<b>EXECUTIVE SUMMARY</b><br/><br/>{startup_data.get('company_name', 'Your Startup')}",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.5*inch))
# Company Overview
story.append(Paragraph("Company Overview", self.styles['CustomHeading1']))
story.append(Paragraph(
startup_data.get('overview',
'We are building the next generation platform that transforms how businesses '
'operate in the digital economy. Our solution addresses critical pain points '
'with innovative technology and a customer-centric approach.'),
self.styles['CustomBodyText']
))
story.append(Spacer(1, 0.2*inch))
# Mission & Vision
story.append(Paragraph("Mission & Vision", self.styles['CustomHeading1']))
story.append(Paragraph(
f"<b>Mission:</b> {startup_data.get('mission', 'To democratize access to advanced technology solutions')}",
self.styles['CustomBodyText']
))
story.append(Paragraph(
f"<b>Vision:</b> {startup_data.get('vision', 'To become the global leader in our category by 2030')}",
self.styles['CustomBodyText']
))
story.append(Spacer(1, 0.2*inch))
# Key Metrics
story.append(Paragraph("Key Metrics", self.styles['CustomHeading1']))
metrics = [
['Metric', 'Current', 'Target (12mo)'],
['ARR', '$2M', '$10M'],
['Customers', '50', '200'],
['NPS Score', '72', '80+'],
['Gross Margin', '65%', '75%']
]
metrics_table = Table(metrics)
metrics_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#27ae60')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('GRID', (0, 0), (-1, -1), 1, colors.grey)
]))
story.append(metrics_table)
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def generate_market_analysis(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a market analysis report."""
# Implementation similar to above templates
pass
def generate_competitive_analysis(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a competitive analysis document."""
# Implementation similar to above templates
pass
def generate_go_to_market_strategy(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a go-to-market strategy document."""
# Implementation similar to above templates
pass
def generate_risk_assessment(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a risk assessment document."""
# Implementation similar to above templates
pass
def generate_term_sheet_template(self, startup_data: Dict[str, Any]) -> bytes:
"""Generate a term sheet template."""
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=letter)
story = []
# Title
story.append(Paragraph(
"<b>TERM SHEET</b>",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph(
f"{startup_data.get('company_name', 'Your Startup, Inc.')}",
self.styles['CustomTitle']
))
story.append(Spacer(1, 0.3*inch))
story.append(Paragraph(
f"Series {startup_data.get('series', 'A')} Preferred Stock Financing",
self.styles['Normal']
))
story.append(Spacer(1, 0.5*inch))
# Terms
terms = [
('Issuer', startup_data.get('company_name', 'Company, Inc.')),
('Investors', startup_data.get('lead_investor', 'Lead Investor') + ' and other investors'),
('Amount Raised', startup_data.get('amount', '$10,000,000')),
('Pre-Money Valuation', startup_data.get('pre_money', '$40,000,000')),
('Post-Money Valuation', startup_data.get('post_money', '$50,000,000')),
('Price Per Share', startup_data.get('price_per_share', '$1.00')),
('Liquidation Preference', '1x non-participating'),
('Dividend', '8% cumulative dividend'),
('Anti-Dilution', 'Weighted average broad-based'),
('Voting Rights', '1 vote per share, vote together with common'),
('Board Composition', '5 members: 2 founders, 2 investors, 1 independent'),
('Protective Provisions', 'Standard Series A provisions'),
('Registration Rights', 'Standard demand and piggyback rights'),
('Right of First Refusal', 'Company and investors'),
('Drag Along', 'Standard drag along provisions'),
('Vesting', 'Founders: 4 years with 1-year cliff'),
('Employee Pool', '15% post-financing'),
('Closing', startup_data.get('closing', '30 days from signing'))
]
for term, value in terms:
story.append(Paragraph(
f"<b>{term}:</b> {value}",
self.styles['CustomBodyText']
))
story.append(Spacer(1, 0.1*inch))
# Legal Notice
story.append(Spacer(1, 0.5*inch))
story.append(Paragraph(
"This term sheet is non-binding except for confidentiality, exclusivity, and governing law provisions.",
self.styles['Italic']
))
# Build PDF
doc.build(story)
buffer.seek(0)
return buffer.getvalue()
def list_available_templates(self) -> List[str]:
"""Return list of available document templates."""
return list(self.templates.keys())
def generate_document(self, template_type: str, startup_data: Dict[str, Any]) -> bytes:
"""Generate a document based on the specified template type."""
if template_type not in self.templates:
raise ValueError(f"Unknown template type: {template_type}")
return self.templates[template_type](startup_data)
# Export the class
__all__ = ['DocumentTemplateGenerator']