BF / smart_warehouse.py
SamiKoen's picture
Alsancak ve diğer mağaza filtreleme düzeltmesi - context-aware warehouse search
75f5dad
raw
history blame
11.4 kB
"""Smart warehouse stock finder using GPT-5's intelligence"""
import requests
import re
import os
import json
def get_warehouse_stock_smart(user_message, previous_result=None):
"""Let GPT-5 intelligently find products or filter by warehouse"""
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Check if user is asking about specific warehouse from previous result
warehouse_keywords = {
'caddebostan': 'Caddebostan',
'ortaköy': 'Ortaköy',
'ortakoy': 'Ortaköy',
'alsancak': 'Alsancak',
'izmir': 'Alsancak',
'bahçeköy': 'Bahçeköy',
'bahcekoy': 'Bahçeköy'
}
user_lower = user_message.lower()
asked_warehouse = None
for keyword, warehouse in warehouse_keywords.items():
if keyword in user_lower:
asked_warehouse = warehouse
break
# If asking about warehouse and we have previous result, filter it
if asked_warehouse and previous_result and isinstance(previous_result, list):
filtered = []
for line in previous_result:
if asked_warehouse in line or "Bulunan" in line or "varyant" in line:
filtered.append(line)
if len(filtered) > 2: # Has actual warehouse data
return filtered
# Get XML data with retry
xml_text = None
for attempt in range(3): # Try 3 times
try:
url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml-b2b-api-v2.php'
timeout_val = 10 + (attempt * 5) # Increase timeout on each retry: 10, 15, 20
response = requests.get(url, verify=False, timeout=timeout_val)
xml_text = response.text
print(f"DEBUG - XML fetched: {len(xml_text)} characters (attempt {attempt+1})")
break
except requests.exceptions.Timeout:
print(f"XML fetch timeout (attempt {attempt+1}/3, timeout={timeout_val}s)")
if attempt == 2:
print("All attempts failed - timeout")
return None
except Exception as e:
print(f"XML fetch error: {e}")
return None
# Extract just product blocks to reduce token usage
product_pattern = r'<Product>(.*?)</Product>'
all_products = re.findall(product_pattern, xml_text, re.DOTALL)
# Create a simplified product list for GPT
products_summary = []
for i, product_block in enumerate(all_products):
name_match = re.search(r'<ProductName><!\[CDATA\[(.*?)\]\]></ProductName>', product_block)
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
if name_match:
# Check warehouse stock for this product
warehouses_with_stock = []
warehouse_regex = r'<Warehouse>.*?<Name><!\[CDATA\[(.*?)\]\]></Name>.*?<Stock>(.*?)</Stock>.*?</Warehouse>'
warehouses = re.findall(warehouse_regex, product_block, re.DOTALL)
for wh_name, wh_stock in warehouses:
try:
if int(wh_stock.strip()) > 0:
warehouses_with_stock.append(wh_name)
except:
pass
product_info = {
"index": i,
"name": name_match.group(1),
"variant": variant_match.group(1) if variant_match else "",
"warehouses": warehouses_with_stock
}
products_summary.append(product_info)
# If user is asking about specific warehouse, include that in prompt
warehouse_filter = ""
if asked_warehouse:
warehouse_filter = f"\nIMPORTANT: User is asking specifically about {asked_warehouse} warehouse. Only return products available in that warehouse."
# Let GPT-5 find ALL matching products
smart_prompt = f"""User is asking: "{user_message}"
Find ALL products that match this query from the list below.
If user asks about specific size (S, M, L, XL), return only that size.
If user asks generally (without size), return ALL variants of the product.
{warehouse_filter}
Products list (with warehouse availability):
{json.dumps(products_summary[:200], ensure_ascii=False, indent=2)}
Return index numbers of ALL matching products as comma-separated list (e.g., "5,8,12,15").
If no products found, return: -1
Examples:
- "madone sl 6 var mı" -> Return ALL Madone SL 6 variants (all sizes)
- "madone sl 6 S beden" -> Return only S size variant
- "alsancak şubede hangi boy var" -> Return only products available in ALSANCAK warehouse"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
payload = {
"model": "gpt-5-chat-latest",
"messages": [
{"role": "system", "content": "You are a product matcher. Find ALL matching products. Return only index numbers."},
{"role": "user", "content": smart_prompt}
],
"temperature": 0,
"max_tokens": 100
}
try:
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers=headers,
json=payload,
timeout=10
)
if response.status_code == 200:
result = response.json()
indices_str = result['choices'][0]['message']['content'].strip()
if indices_str == "-1":
return ["Ürün bulunamadı"]
try:
# Parse multiple indices
indices = [int(idx.strip()) for idx in indices_str.split(',')]
# Aggregate warehouse info from all matching products
all_warehouses = {}
product_details = []
for idx in indices:
if 0 <= idx < len(all_products):
product_block = all_products[idx]
# Get product name and variant
name_match = re.search(r'<ProductName><!\[CDATA\[(.*?)\]\]></ProductName>', product_block)
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
if name_match:
product_name = name_match.group(1)
variant = variant_match.group(1) if variant_match else ""
# Get warehouse stock
warehouse_regex = r'<Warehouse>.*?<Name><!\[CDATA\[(.*?)\]\]></Name>.*?<Stock>(.*?)</Stock>.*?</Warehouse>'
warehouses = re.findall(warehouse_regex, product_block, re.DOTALL)
for wh_name, wh_stock in warehouses:
try:
stock = int(wh_stock.strip())
if stock > 0:
# Format warehouse name
display_name = format_warehouse_name(wh_name)
# If filtering by warehouse, only include that warehouse
if asked_warehouse:
if asked_warehouse in display_name:
product_details.append({
'name': product_name,
'variant': variant,
'warehouse': display_name,
'stock': stock
})
else:
if display_name not in all_warehouses:
all_warehouses[display_name] = []
all_warehouses[display_name].append({
'variant': variant,
'stock': stock
})
except:
pass
# Format result
result = []
if asked_warehouse:
# Show products in specific warehouse
if product_details:
result.append(f"{asked_warehouse} mağazasında mevcut:")
for detail in product_details:
result.append(f"• {detail['name']} ({detail['variant']}): {detail['stock']} adet")
else:
result.append(f"{asked_warehouse} mağazasında bu ürün mevcut değil")
else:
# Show all warehouses
if all_warehouses:
result.append(f"Bulunan {sum(len(v) for v in all_warehouses.values())} varyant:")
# Show a sample of variants
shown = 0
for warehouse, variants in all_warehouses.items():
for v in variants[:2]: # Show max 2 per warehouse
if shown < 5:
variant_text = f" ({v['variant']})" if v['variant'] else ""
result.append(f"• {product_name}{variant_text}")
shown += 1
if sum(len(v) for v in all_warehouses.values()) > 5:
result.append(f"... ve {sum(len(v) for v in all_warehouses.values()) - 5} varyant daha")
result.append("")
result.append("Toplam stok durumu:")
for warehouse, variants in sorted(all_warehouses.items()):
total = sum(v['stock'] for v in variants)
result.append(f"{warehouse}: {total} adet")
else:
result.append("Hiçbir mağazada stok yok")
return result
except (ValueError, IndexError) as e:
print(f"DEBUG - Error parsing indices: {e}")
return None
else:
print(f"GPT API error: {response.status_code}")
return None
except Exception as e:
print(f"Error calling GPT: {e}")
return None
def format_warehouse_name(wh_name):
"""Format warehouse name nicely"""
if "CADDEBOSTAN" in wh_name:
return "Caddebostan mağazası"
elif "ORTAKÖY" in wh_name:
return "Ortaköy mağazası"
elif "ALSANCAK" in wh_name:
return "İzmir Alsancak mağazası"
elif "BAHCEKOY" in wh_name or "BAHÇEKÖY" in wh_name:
return "Bahçeköy mağazası"
else:
return wh_name.replace("MAGAZA DEPO", "").strip()