from typing import Optional, Dict, Any, List from datetime import datetime import os import logging logger = logging.getLogger(__name__) try: from weasyprint import HTML HAS_WEASYPRINT = True except ImportError: HAS_WEASYPRINT = False logger.warning("weasyprint not installed, PDF generation disabled") QUOTATION_TEMPLATE = """

QUOTATION

#{quotation_number}

Bill To

{customer_name}

{customer_company}

{customer_country}

Quote Details

Date: {date}

Valid Until: {valid_until}

Currency: {currency}

{items_rows}
Item Description Qty Unit Unit Price Total
Subtotal:{subtotal}
Discount:-{discount}
Shipping:{shipping}
TOTAL:{total}

Terms & Conditions

Payment Terms: {payment_terms}

Delivery Terms: {delivery_terms}

Lead Time: {lead_time}

{notes_html}
""" class PDFGenerator: @staticmethod def generate_quotation(data: Dict[str, Any]) -> Optional[bytes]: if not HAS_WEASYPRINT: return None items = data.get("items", []) items_rows = "" for i, item in enumerate(items, 1): items_rows += ( f"" f"{item.get('product_name', '')}" f"{item.get('description', '') or ''}" f"{item.get('quantity', 0)}" f"{item.get('unit', 'pcs')}" f"{item.get('unit_price', 0):.2f}" f"{item.get('total_price', 0):.2f}" f"" ) cur = data.get("currency", "USD") subtotal = f"{cur} {data.get('subtotal', 0):.2f}" discount = f"{cur} {data.get('discount', 0):.2f}" if data.get("discount") else f"{cur} 0.00" shipping = f"{cur} {data.get('shipping', 0):.2f}" if data.get("shipping") else f"{cur} 0.00" total = f"{cur} {data.get('total', 0):.2f}" notes_html = "" if data.get("notes"): notes_html = f"

Notes: {data['notes']}

" html = QUOTATION_TEMPLATE.format( quotation_number=data.get("quotation_number", "N/A"), customer_name=data.get("customer_name", ""), customer_company=data.get("customer_company", "") or "", customer_country=data.get("customer_country", "") or "", date=data.get("date", datetime.utcnow().strftime("%Y-%m-%d")), valid_until=data.get("valid_until", "N/A"), currency=cur, items_rows=items_rows, subtotal=subtotal, discount=discount, shipping=shipping, total=total, payment_terms=data.get("payment_terms", "N/A"), delivery_terms=data.get("delivery_terms", "N/A"), lead_time=data.get("lead_time", "N/A"), notes_html=notes_html, generated_at=datetime.utcnow().strftime("%Y-%m-%d %H:%M UTC"), ) pdf = HTML(string=html).write_pdf() return pdf pdf_generator = PDFGenerator()