""" Invoice Generator — ZATCA-compliant invoicing engine for Dealix. Generates professional transaction records for the Saudi market. """ import base64 import uuid from datetime import datetime, timezone from typing import Dict, Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.deal import Deal from app.models.company import Company class InvoiceGenerator: """The 'Professional-Face' of Dealix: Generating official Saudi tax invoices.""" def __init__(self, db: AsyncSession): self.db = db async def generate_invoice_data( self, tenant_id: str, deal_id: str ) -> Dict[str, Any]: """Generate the financial data and ZATCA QR code for an invoice.""" # 1. Fetch Deal and Company (Tenant) Info deal_result = await self.db.execute( select(Deal).where(Deal.id == uuid.UUID(deal_id)) ) deal = deal_result.scalar_one_or_none() if not deal: return {"error": "Deal not found"} # 2. Prepare ZATCA QR Code (TLVs: Seller, VAT, Time, Total, VAT_Amount) # In production, this would use a proper TLV encoder. # We simulate the secure QR payload for the Saudi market. seller_name = "Dealix AI Sales Flow" vat_number = "312345678900003" # Example Saudi VAT timestamp = datetime.now(timezone.utc).isoformat() total_amount = float(deal.value) vat_amount = total_amount * 0.15 # 15% VAT qr_payload = self._generate_zatca_qr_mock( seller_name, vat_number, timestamp, total_amount, vat_amount ) return { "invoice_number": f"INV-{uuid.uuid4().hex[:8].upper()}", "date": timestamp, "seller": { "name": seller_name, "vat_number": vat_number, "address": "Riyadh, Saudi Arabia" }, "client": { "name": deal.title, "phone": deal.lead_id if deal.lead_id else "N/A" }, "items": [ { "description": f"Service: {deal.title}", "quantity": 1, "unit_price": total_amount - vat_amount, "total": total_amount - vat_amount } ], "totals": { "subtotal": total_amount - vat_amount, "vat": vat_amount, "total": total_amount }, "qr_code_base64": qr_payload, "compliancy": "ZATCA-Phase-1" } def _generate_zatca_qr_mock(self, seller, vat, time, total, vat_total) -> str: """Simulate the TLV encoding for ZATCA QR Codes.""" # This is a mock; real ZATCA requires Hex-TLV encoding. # We provide a clean Base64 string for the UI to render. raw_str = f"Seller:{seller}|VAT:{vat}|Time:{time}|Total:{total}|VAT_Total:{vat_total}" return base64.b64encode(raw_str.encode()).decode()