fello-iq / backend /utils.py
umar-100's picture
app V1.0
da90d9b
import os
from fpdf import FPDF
from googleapiclient.discovery import build
from google.oauth2 import service_account
from typing import List
from dotenv import load_dotenv
import json
load_dotenv()
class FelloUtils:
@staticmethod
def generate_pdf_report(data: dict) -> bytes:
"""Generates a professional PDF report with heavy debugging."""
try:
pdf = FPDF()
pdf.add_page()
# Helper function to sanitize text for Latin-1 (FPDF default)
def s(text):
if text is None: return ""
# Replace common problematic unicode characters that crash FPDF
return str(text).encode('latin-1', 'replace').decode('latin-1')
# 1. Title
pdf.set_font("Arial", 'B', 20)
pdf.set_text_color(37, 99, 235)
pdf.cell(200, 15, txt="Fello IQ Account Intelligence", ln=True, align='C')
pdf.ln(10)
# 2. Company Identity
pdf.set_font("Arial", 'B', 14)
pdf.set_text_color(15, 23, 42)
company = s(data.get('company_name', 'N/A'))
domain = s(data.get('domain', 'N/A'))
pdf.cell(0, 10, txt=f"Account: {company} ({domain})", ln=True)
pdf.set_font("Arial", size=10)
industry = s(data.get('industry', 'N/A'))
revenue = s(data.get('annual_revenue', 'N/A'))
pdf.cell(0, 7, txt=f"Industry: {industry} | Revenue: {revenue}", ln=True)
pdf.ln(5)
# 3. Strategic Intelligence
pdf.set_font("Arial", 'B', 12)
score = data.get('intent_score', 0)
stage = s(data.get('intent_stage', 'Unknown'))
pdf.cell(0, 10, txt=f"Intent Score: {score}/10 - {stage}", ln=True)
pdf.set_font("Arial", 'I', 10)
summary = s(data.get('ai_summary', 'No summary available.'))
pdf.multi_cell(0, 7, txt=f"AI Summary: {summary}")
pdf.ln(5)
# 4. Recommended Actions
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, txt="Recommended Sales Actions:", ln=True)
pdf.set_font("Arial", size=10)
actions = data.get('recommended_sales_actions', [])
if not actions:
pdf.cell(0, 7, txt="- No specific actions recommended.", ln=True)
else:
for action in actions:
pdf.multi_cell(0, 7, txt=s(f"- {action}"))
pdf_output = pdf.output(dest='S')
return pdf_output.encode('latin-1', 'replace')
except Exception as e:
print("!!! PDF GENERATION CRASHED !!!")
print(traceback.format_exc())
raise e
@staticmethod
def sync_to_google_sheets(data: dict):
"""Appends research data to Google Sheets using your reference logic."""
SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
SPREADSHEET_ID = os.getenv("SPREADSHEET_ID")
try:
creds_json = os.getenv("GOOGLE_CREDENTIALS_JSON")
creds_info = json.loads(creds_json)
creds = service_account.Credentials.from_service_account_info(
creds_info, scopes=SCOPES
)
service = build("sheets", "v4", credentials=creds)
# Formatting the row based on the Pydantic model
values = [
data['company_name'],
data['domain'],
data['intent_score'],
data['intent_stage'],
data['industry'],
data['annual_revenue'],
", ".join(data['recommended_sales_actions'][:2])
]
body = {"values": [values]}
service.spreadsheets().values().append(
spreadsheetId=SPREADSHEET_ID,
range="Sheet1",
valueInputOption="USER_ENTERED",
insertDataOption="INSERT_ROWS",
body=body
).execute()
return True
except Exception as e:
print(f"Google Sheets Sync Error: {e}")
return False