import os import logging from sqlalchemy.orm import Session from ..database import Company from ..interfaces import LeadData, TaskData, CRMRepository from ..repositories.mock import MockRepository from ..repositories.superoffice import SuperOfficeRepository from ..config import settings logger = logging.getLogger(__name__) class CRMFactory: _instance: CRMRepository = None @classmethod def get_repository(cls) -> CRMRepository: if cls._instance: return cls._instance crm_type = os.getenv("CRM_TYPE", "MOCK").upper() if crm_type == "SUPEROFFICE": # Load credentials securely from settings/env tenant = os.getenv("SO_TENANT_ID", "") token = os.getenv("SO_API_TOKEN", "") logger.info("Initializing SuperOffice Repository...") cls._instance = SuperOfficeRepository(tenant, token) else: logger.info("Initializing Mock Repository (Default)...") cls._instance = MockRepository() return cls._instance class SyncService: def __init__(self, db: Session): self.db = db self.repo = CRMFactory.get_repository() def sync_company(self, company_id: int) -> dict: """ Pushes a local company to the external CRM. """ local_company = self.db.query(Company).filter(Company.id == company_id).first() if not local_company: return {"error": "Company not found"} # 1. Map Data # Extract highest robotics potential score max_score = 0 reason = "" for sig in local_company.signals: if sig.confidence > max_score: max_score = int(sig.confidence) reason = f"{sig.signal_type} ({sig.value})" lead_data = LeadData( name=local_company.name, website=local_company.website, city=local_company.city, country=local_company.country, industry=local_company.industry_ai, # We suggest our AI industry robotics_potential_score=max_score, robotics_potential_reason=reason ) # 2. Check if already linked external_id = local_company.crm_id # 3. Check if exists in CRM (by name) if not linked yet if not external_id: external_id = self.repo.find_company(local_company.name) action = "none" if external_id: # Update success = self.repo.update_lead(external_id, lead_data) if success: action = "updated" # If we found it by search, link it locally if not local_company.crm_id: local_company.crm_id = external_id self.db.commit() else: # Create new_id = self.repo.create_lead(lead_data) if new_id: action = "created" local_company.crm_id = new_id self.db.commit() # Create a task for the sales rep if high potential if max_score > 70: self.repo.create_task(new_id, TaskData( subject="🔥 Hot Robotics Lead", description=f"AI detected high potential ({max_score}%). Reason: {reason}. Please check website." )) return { "status": "success", "action": action, "crm": self.repo.get_name(), "external_id": local_company.crm_id }