feat: search e-conomic for customers by name (v1.3.59)

- Added EconomicService.search_customer_by_name() method
- Added GET /api/v1/customers/{id}/search-economic endpoint
- Returns matching e-conomic customers by name (partial match)
- Helps find economic customer number for customers without CVR
- Shows customerNumber, name, CVR, email, city in results
This commit is contained in:
Christian 2025-12-23 15:39:35 +01:00
parent 1b0217ef7b
commit 4c2593b99c
3 changed files with 77 additions and 1 deletions

View File

@ -1 +1 @@
1.3.58 1.3.59

View File

@ -327,6 +327,52 @@ async def link_economic_customer(customer_id: int, link_request: dict):
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
@router.get("/customers/{customer_id}/search-economic")
async def search_economic_for_customer(customer_id: int, query: Optional[str] = None):
"""Search e-conomic for matching customers by name"""
try:
from app.services.economic_service import EconomicService
# Get customer
customer = execute_query_single(
"SELECT id, name FROM customers WHERE id = %s",
(customer_id,))
if not customer:
raise HTTPException(status_code=404, detail="Customer not found")
# Use provided query or customer name
search_query = query or customer['name']
# Search in e-conomic
economic = EconomicService()
results = await economic.search_customer_by_name(search_query)
return {
"status": "success",
"customer_id": customer_id,
"customer_name": customer['name'],
"search_query": search_query,
"results": [
{
"customerNumber": r.get('customerNumber'),
"name": r.get('name'),
"corporateIdentificationNumber": r.get('corporateIdentificationNumber'),
"email": r.get('email'),
"city": r.get('city')
}
for r in results
],
"count": len(results)
}
except HTTPException:
raise
except Exception as e:
logger.error(f"❌ Failed to search e-conomic for customer {customer_id}: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/customers/{customer_id}/subscriptions/lock") @router.post("/customers/{customer_id}/subscriptions/lock")
async def lock_customer_subscriptions(customer_id: int, lock_request: dict): async def lock_customer_subscriptions(customer_id: int, lock_request: dict):
"""Lock/unlock subscriptions for customer in local DB - BMC Låst status controlled in vTiger""" """Lock/unlock subscriptions for customer in local DB - BMC Låst status controlled in vTiger"""

View File

@ -197,6 +197,36 @@ class EconomicService:
logger.error(f"❌ Error searching customer by CVR: {e}") logger.error(f"❌ Error searching customer by CVR: {e}")
return None return None
async def search_customer_by_name(self, name: str) -> List[Dict]:
"""
Search for customers by name (partial match)
Args:
name: Customer name to search for
Returns:
List of matching customer records
"""
try:
async with aiohttp.ClientSession() as session:
async with session.get(
f"{self.api_url}/customers",
params={"filter": f"name$like:*{name}*"},
headers=self._get_headers()
) as response:
if response.status == 200:
data = await response.json()
customers = data.get('collection', [])
logger.info(f"✅ Found {len(customers)} customers matching '{name}'")
return customers
else:
error = await response.text()
logger.error(f"❌ Name search failed: {response.status} - {error}")
return []
except Exception as e:
logger.error(f"❌ Error searching customer by name: {e}")
return []
# ========== 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]: