diff --git a/app/customers/backend/router.py b/app/customers/backend/router.py index 53d4390..1c2c8c9 100644 --- a/app/customers/backend/router.py +++ b/app/customers/backend/router.py @@ -288,6 +288,120 @@ async def update_customer(customer_id: int, update: CustomerUpdate): raise HTTPException(status_code=500, detail=str(e)) +@router.post("/customers/sync-economic-from-simplycrm") +async def sync_economic_numbers_from_simplycrm(): + """ + šŸ”— Sync e-conomic customer numbers fra Simply-CRM til Hub customers. + + Henter cf_854 (economic_customer_number) fra Simply-CRM accounts og + opdaterer matching Hub customers baseret pĆ„ navn. + """ + try: + from app.services.simplycrm_service import SimplyCRMService + + logger.info("šŸš€ Starting e-conomic number sync from Simply-CRM...") + + stats = { + "simplycrm_accounts": 0, + "accounts_with_economic_number": 0, + "hub_customers_updated": 0, + "hub_customers_not_found": 0, + "errors": 0 + } + + async with SimplyCRMService() as simplycrm: + # Hent alle accounts fra Simply-CRM + logger.info("šŸ“„ Fetching accounts from Simply-CRM...") + query = "SELECT accountname, cf_854 FROM Accounts LIMIT 5000;" + accounts = await simplycrm.query(query) + + stats["simplycrm_accounts"] = len(accounts) + logger.info(f"āœ… Found {len(accounts)} accounts in Simply-CRM") + + if not accounts: + return { + "status": "success", + "message": "No accounts found in Simply-CRM", + "stats": stats + } + + # Filter accounts med economic customer number + accounts_with_economic = [ + acc for acc in accounts + if acc.get('cf_854') and str(acc.get('cf_854')).strip() not in ['', '0', 'null', 'NULL'] + ] + + stats["accounts_with_economic_number"] = len(accounts_with_economic) + logger.info(f"āœ… {len(accounts_with_economic)} accounts have e-conomic customer numbers") + + # Map company name → economic_customer_number + name_to_economic = {} + for acc in accounts_with_economic: + company_name = acc.get('accountname', '').strip() + economic_number = str(acc.get('cf_854', '')).strip() + + if company_name and economic_number: + # Normalize navn til lowercase for matching + name_key = company_name.lower() + name_to_economic[name_key] = { + 'original_name': company_name, + 'economic_customer_number': economic_number + } + + logger.info(f"šŸ“Š Mapped {len(name_to_economic)} unique company names") + + # Hent alle Hub customers + hub_customers = execute_query("SELECT id, name FROM customers") + logger.info(f"šŸ“Š Found {len(hub_customers)} customers in Hub") + + # Match og opdater + for customer in hub_customers: + customer_name_key = customer['name'].strip().lower() + + if customer_name_key in name_to_economic: + economic_data = name_to_economic[customer_name_key] + economic_number = economic_data['economic_customer_number'] + + try: + execute_query( + """UPDATE customers + SET economic_customer_number = %s, + last_synced_at = NOW() + WHERE id = %s""", + (economic_number, customer['id']) + ) + + logger.info(f"āœ… Updated {customer['name']} → e-conomic #{economic_number}") + stats["hub_customers_updated"] += 1 + + except Exception as update_error: + logger.error(f"āŒ Failed to update customer {customer['id']}: {update_error}") + stats["errors"] += 1 + else: + stats["hub_customers_not_found"] += 1 + + logger.info(f"āœ… Sync complete: {stats}") + + # Auto-link tmodule_customers after sync + try: + logger.info("šŸ”— Running auto-link for timetracking customers...") + link_results = execute_query("SELECT * FROM link_tmodule_customers_to_hub()") + logger.info(f"āœ… Linked {len(link_results)} timetracking customers") + stats["tmodule_customers_linked"] = len(link_results) + except Exception as link_error: + logger.warning(f"āš ļø Auto-linking failed (non-critical): {link_error}") + + return { + "status": "success", + "message": f"Synced {stats['hub_customers_updated']} customers with e-conomic numbers from Simply-CRM", + "stats": stats + } + + except Exception as e: + logger.error(f"āŒ Simply-CRM sync failed: {e}") + raise HTTPException(status_code=500, detail=str(e)) + + @router.post("/customers/{customer_id}/link-economic") async def link_economic_customer(customer_id: int, link_request: dict): """Manually link customer to e-conomic customer number"""