Implement e-conomic customer sync and CVR search (get_customers + search_customer_by_cvr)
This commit is contained in:
parent
55478c20d3
commit
c9af509e1c
@ -126,6 +126,77 @@ class EconomicService:
|
|||||||
logger.error(f"❌ e-conomic connection error: {e}")
|
logger.error(f"❌ e-conomic connection error: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# ========== CUSTOMER MANAGEMENT ==========
|
||||||
|
|
||||||
|
async def get_customers(self, page: int = 0, page_size: int = 1000) -> List[Dict]:
|
||||||
|
"""
|
||||||
|
Get customers from e-conomic
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Page number (0-indexed)
|
||||||
|
page_size: Number of records per page
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of customer records with customerNumber, corporateIdentificationNumber, name
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(
|
||||||
|
f"{self.api_url}/customers",
|
||||||
|
params={"skippages": page, "pagesize": page_size},
|
||||||
|
headers=self._get_headers()
|
||||||
|
) as response:
|
||||||
|
if response.status == 200:
|
||||||
|
data = await response.json()
|
||||||
|
customers = data.get('collection', [])
|
||||||
|
logger.info(f"📥 Fetched {len(customers)} customers from e-conomic (page {page})")
|
||||||
|
return customers
|
||||||
|
else:
|
||||||
|
error = await response.text()
|
||||||
|
logger.error(f"❌ Failed to fetch customers: {response.status} - {error}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Error fetching customers from e-conomic: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
async def search_customer_by_cvr(self, cvr: str) -> Optional[Dict]:
|
||||||
|
"""
|
||||||
|
Search for customer by CVR number
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cvr: CVR number (8 digits)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Customer record if found, None otherwise
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Clean CVR
|
||||||
|
import re
|
||||||
|
cvr_clean = re.sub(r'\D', '', str(cvr))[:8]
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(
|
||||||
|
f"{self.api_url}/customers",
|
||||||
|
params={"filter": f"corporateIdentificationNumber$eq:{cvr_clean}"},
|
||||||
|
headers=self._get_headers()
|
||||||
|
) as response:
|
||||||
|
if response.status == 200:
|
||||||
|
data = await response.json()
|
||||||
|
customers = data.get('collection', [])
|
||||||
|
if customers:
|
||||||
|
logger.info(f"✅ Found customer with CVR {cvr_clean}: {customers[0].get('name')}")
|
||||||
|
return customers[0]
|
||||||
|
else:
|
||||||
|
logger.debug(f"❌ No customer found with CVR {cvr_clean}")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
error = await response.text()
|
||||||
|
logger.error(f"❌ CVR search failed: {response.status} - {error}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Error searching customer by CVR: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
# ========== SUPPLIER/VENDOR MANAGEMENT ==========
|
# ========== SUPPLIER/VENDOR MANAGEMENT ==========
|
||||||
|
|
||||||
async def search_supplier_by_name(self, supplier_name: str) -> Optional[Dict]:
|
async def search_supplier_by_name(self, supplier_name: str) -> Optional[Dict]:
|
||||||
|
|||||||
@ -307,15 +307,65 @@ async def sync_from_economic() -> Dict[str, Any]:
|
|||||||
try:
|
try:
|
||||||
logger.info("🔄 Starting e-conomic sync...")
|
logger.info("🔄 Starting e-conomic sync...")
|
||||||
|
|
||||||
# Note: This requires adding get_customers() method to economic_service.py
|
from app.services.economic_service import EconomicService
|
||||||
# For now, return a placeholder response
|
economic = EconomicService()
|
||||||
|
|
||||||
logger.warning("⚠️ e-conomic sync not fully implemented yet")
|
# Get all customers from e-conomic
|
||||||
|
economic_customers = await economic.get_customers(page=0, page_size=10000)
|
||||||
|
logger.info(f"📥 Fetched {len(economic_customers)} customers from e-conomic")
|
||||||
|
|
||||||
|
matched_count = 0
|
||||||
|
not_matched_count = 0
|
||||||
|
|
||||||
|
for eco_customer in economic_customers:
|
||||||
|
customer_number = eco_customer.get('customerNumber')
|
||||||
|
cvr = eco_customer.get('corporateIdentificationNumber')
|
||||||
|
name = eco_customer.get('name', '')
|
||||||
|
|
||||||
|
if not customer_number:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Clean CVR
|
||||||
|
if cvr:
|
||||||
|
cvr = re.sub(r'\D', '', str(cvr))[:8]
|
||||||
|
if len(cvr) != 8:
|
||||||
|
cvr = None
|
||||||
|
|
||||||
|
# Try to match by CVR first
|
||||||
|
matched = None
|
||||||
|
if cvr:
|
||||||
|
matched = execute_query(
|
||||||
|
"SELECT id, name FROM customers WHERE cvr_number = %s",
|
||||||
|
(cvr,)
|
||||||
|
)
|
||||||
|
|
||||||
|
# If no CVR match, try normalized name
|
||||||
|
if not matched and name:
|
||||||
|
normalized = normalize_name(name)
|
||||||
|
all_customers = execute_query("SELECT id, name FROM customers WHERE economic_customer_number IS NULL")
|
||||||
|
for hub_customer in all_customers:
|
||||||
|
if normalize_name(hub_customer['name']) == normalized:
|
||||||
|
matched = [hub_customer]
|
||||||
|
break
|
||||||
|
|
||||||
|
if matched:
|
||||||
|
# Update Hub customer with e-conomic number
|
||||||
|
execute_query(
|
||||||
|
"UPDATE customers SET economic_customer_number = %s, last_synced_at = NOW() WHERE id = %s",
|
||||||
|
(customer_number, matched[0]['id'])
|
||||||
|
)
|
||||||
|
matched_count += 1
|
||||||
|
logger.info(f"🔗 Matchet: {matched[0]['name']} → e-conomic kunde #{customer_number} (CVR: {cvr or 'navn-match'})")
|
||||||
|
else:
|
||||||
|
not_matched_count += 1
|
||||||
|
|
||||||
|
logger.info(f"✅ e-conomic sync fuldført: {matched_count} matchet, {not_matched_count} ikke matchet af {len(economic_customers)} totalt")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "not_implemented",
|
"status": "success",
|
||||||
"message": "e-conomic customer sync requires get_customers() method in economic_service.py",
|
"matched": matched_count,
|
||||||
"matched": 0
|
"not_matched": not_matched_count,
|
||||||
|
"total_processed": len(economic_customers)
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -332,6 +382,9 @@ async def sync_cvr_to_economic() -> Dict[str, Any]:
|
|||||||
try:
|
try:
|
||||||
logger.info("🔄 Starting CVR to e-conomic sync...")
|
logger.info("🔄 Starting CVR to e-conomic sync...")
|
||||||
|
|
||||||
|
from app.services.economic_service import EconomicService
|
||||||
|
economic = EconomicService()
|
||||||
|
|
||||||
# Find customers with CVR but no economic_customer_number
|
# Find customers with CVR but no economic_customer_number
|
||||||
customers = execute_query("""
|
customers = execute_query("""
|
||||||
SELECT id, name, cvr_number
|
SELECT id, name, cvr_number
|
||||||
@ -344,10 +397,31 @@ async def sync_cvr_to_economic() -> Dict[str, Any]:
|
|||||||
|
|
||||||
logger.info(f"📥 Found {len(customers)} customers with CVR but no e-conomic number")
|
logger.info(f"📥 Found {len(customers)} customers with CVR but no e-conomic number")
|
||||||
|
|
||||||
# Note: This requires e-conomic API search functionality
|
found_count = 0
|
||||||
# For now, return placeholder
|
linked_count = 0
|
||||||
|
|
||||||
logger.warning("⚠️ CVR to e-conomic sync not fully implemented yet")
|
for customer in customers:
|
||||||
|
cvr = customer['cvr_number']
|
||||||
|
|
||||||
|
# Search e-conomic for this CVR
|
||||||
|
eco_customer = await economic.search_customer_by_cvr(cvr)
|
||||||
|
|
||||||
|
if eco_customer:
|
||||||
|
customer_number = eco_customer.get('customerNumber')
|
||||||
|
if customer_number:
|
||||||
|
# Update Hub customer
|
||||||
|
execute_query(
|
||||||
|
"UPDATE customers SET economic_customer_number = %s, last_synced_at = NOW() WHERE id = %s",
|
||||||
|
(customer_number, customer['id'])
|
||||||
|
)
|
||||||
|
found_count += 1
|
||||||
|
linked_count += 1
|
||||||
|
logger.info(f"✅ Fundet og linket: {customer['name']} (CVR: {cvr}) → e-conomic kunde #{customer_number}")
|
||||||
|
else:
|
||||||
|
found_count += 1
|
||||||
|
logger.warning(f"⚠️ Fundet men mangler kundenummer: {customer['name']} (CVR: {cvr})")
|
||||||
|
|
||||||
|
logger.info(f"✅ CVR søgning fuldført: {found_count} fundet, {linked_count} linket af {len(customers)} kontrolleret")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "not_implemented",
|
"status": "not_implemented",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user