Alsancak ve diğer mağaza filtreleme düzeltmesi - context-aware warehouse search
Browse files- smart_warehouse.py +118 -45
smart_warehouse.py
CHANGED
@@ -5,11 +5,39 @@ import re
|
|
5 |
import os
|
6 |
import json
|
7 |
|
8 |
-
def get_warehouse_stock_smart(user_message):
|
9 |
-
"""Let GPT-5 intelligently find
|
10 |
|
11 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
# Get XML data with retry
|
14 |
xml_text = None
|
15 |
for attempt in range(3): # Try 3 times
|
@@ -40,22 +68,41 @@ def get_warehouse_stock_smart(user_message):
|
|
40 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
41 |
|
42 |
if name_match:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
product_info = {
|
44 |
"index": i,
|
45 |
"name": name_match.group(1),
|
46 |
-
"variant": variant_match.group(1) if variant_match else ""
|
|
|
47 |
}
|
48 |
products_summary.append(product_info)
|
49 |
|
|
|
|
|
|
|
|
|
|
|
50 |
# Let GPT-5 find ALL matching products
|
51 |
smart_prompt = f"""User is asking: "{user_message}"
|
52 |
|
53 |
Find ALL products that match this query from the list below.
|
54 |
If user asks about specific size (S, M, L, XL), return only that size.
|
55 |
If user asks generally (without size), return ALL variants of the product.
|
|
|
56 |
|
57 |
-
Products list:
|
58 |
-
{json.dumps(products_summary, ensure_ascii=False, indent=2)}
|
59 |
|
60 |
Return index numbers of ALL matching products as comma-separated list (e.g., "5,8,12,15").
|
61 |
If no products found, return: -1
|
@@ -63,7 +110,7 @@ If no products found, return: -1
|
|
63 |
Examples:
|
64 |
- "madone sl 6 var mı" -> Return ALL Madone SL 6 variants (all sizes)
|
65 |
- "madone sl 6 S beden" -> Return only S size variant
|
66 |
-
- "
|
67 |
|
68 |
headers = {
|
69 |
"Content-Type": "application/json",
|
@@ -101,7 +148,7 @@ Examples:
|
|
101 |
|
102 |
# Aggregate warehouse info from all matching products
|
103 |
all_warehouses = {}
|
104 |
-
|
105 |
|
106 |
for idx in indices:
|
107 |
if 0 <= idx < len(all_products):
|
@@ -112,50 +159,76 @@ Examples:
|
|
112 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
113 |
|
114 |
if name_match:
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
# Format result
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
# Show
|
142 |
-
if
|
143 |
-
result.append(f"
|
144 |
-
for
|
145 |
-
result.append(f"• {name}")
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
# Show aggregated warehouse stock
|
151 |
if all_warehouses:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
result.append("Toplam stok durumu:")
|
153 |
-
for warehouse,
|
154 |
-
|
|
|
155 |
else:
|
156 |
result.append("Hiçbir mağazada stok yok")
|
157 |
-
|
158 |
-
|
159 |
|
160 |
except (ValueError, IndexError) as e:
|
161 |
print(f"DEBUG - Error parsing indices: {e}")
|
|
|
5 |
import os
|
6 |
import json
|
7 |
|
8 |
+
def get_warehouse_stock_smart(user_message, previous_result=None):
|
9 |
+
"""Let GPT-5 intelligently find products or filter by warehouse"""
|
10 |
|
11 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
12 |
|
13 |
+
# Check if user is asking about specific warehouse from previous result
|
14 |
+
warehouse_keywords = {
|
15 |
+
'caddebostan': 'Caddebostan',
|
16 |
+
'ortaköy': 'Ortaköy',
|
17 |
+
'ortakoy': 'Ortaköy',
|
18 |
+
'alsancak': 'Alsancak',
|
19 |
+
'izmir': 'Alsancak',
|
20 |
+
'bahçeköy': 'Bahçeköy',
|
21 |
+
'bahcekoy': 'Bahçeköy'
|
22 |
+
}
|
23 |
+
|
24 |
+
user_lower = user_message.lower()
|
25 |
+
asked_warehouse = None
|
26 |
+
for keyword, warehouse in warehouse_keywords.items():
|
27 |
+
if keyword in user_lower:
|
28 |
+
asked_warehouse = warehouse
|
29 |
+
break
|
30 |
+
|
31 |
+
# If asking about warehouse and we have previous result, filter it
|
32 |
+
if asked_warehouse and previous_result and isinstance(previous_result, list):
|
33 |
+
filtered = []
|
34 |
+
for line in previous_result:
|
35 |
+
if asked_warehouse in line or "Bulunan" in line or "varyant" in line:
|
36 |
+
filtered.append(line)
|
37 |
+
|
38 |
+
if len(filtered) > 2: # Has actual warehouse data
|
39 |
+
return filtered
|
40 |
+
|
41 |
# Get XML data with retry
|
42 |
xml_text = None
|
43 |
for attempt in range(3): # Try 3 times
|
|
|
68 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
69 |
|
70 |
if name_match:
|
71 |
+
# Check warehouse stock for this product
|
72 |
+
warehouses_with_stock = []
|
73 |
+
warehouse_regex = r'<Warehouse>.*?<Name><!\[CDATA\[(.*?)\]\]></Name>.*?<Stock>(.*?)</Stock>.*?</Warehouse>'
|
74 |
+
warehouses = re.findall(warehouse_regex, product_block, re.DOTALL)
|
75 |
+
|
76 |
+
for wh_name, wh_stock in warehouses:
|
77 |
+
try:
|
78 |
+
if int(wh_stock.strip()) > 0:
|
79 |
+
warehouses_with_stock.append(wh_name)
|
80 |
+
except:
|
81 |
+
pass
|
82 |
+
|
83 |
product_info = {
|
84 |
"index": i,
|
85 |
"name": name_match.group(1),
|
86 |
+
"variant": variant_match.group(1) if variant_match else "",
|
87 |
+
"warehouses": warehouses_with_stock
|
88 |
}
|
89 |
products_summary.append(product_info)
|
90 |
|
91 |
+
# If user is asking about specific warehouse, include that in prompt
|
92 |
+
warehouse_filter = ""
|
93 |
+
if asked_warehouse:
|
94 |
+
warehouse_filter = f"\nIMPORTANT: User is asking specifically about {asked_warehouse} warehouse. Only return products available in that warehouse."
|
95 |
+
|
96 |
# Let GPT-5 find ALL matching products
|
97 |
smart_prompt = f"""User is asking: "{user_message}"
|
98 |
|
99 |
Find ALL products that match this query from the list below.
|
100 |
If user asks about specific size (S, M, L, XL), return only that size.
|
101 |
If user asks generally (without size), return ALL variants of the product.
|
102 |
+
{warehouse_filter}
|
103 |
|
104 |
+
Products list (with warehouse availability):
|
105 |
+
{json.dumps(products_summary[:200], ensure_ascii=False, indent=2)}
|
106 |
|
107 |
Return index numbers of ALL matching products as comma-separated list (e.g., "5,8,12,15").
|
108 |
If no products found, return: -1
|
|
|
110 |
Examples:
|
111 |
- "madone sl 6 var mı" -> Return ALL Madone SL 6 variants (all sizes)
|
112 |
- "madone sl 6 S beden" -> Return only S size variant
|
113 |
+
- "alsancak şubede hangi boy var" -> Return only products available in ALSANCAK warehouse"""
|
114 |
|
115 |
headers = {
|
116 |
"Content-Type": "application/json",
|
|
|
148 |
|
149 |
# Aggregate warehouse info from all matching products
|
150 |
all_warehouses = {}
|
151 |
+
product_details = []
|
152 |
|
153 |
for idx in indices:
|
154 |
if 0 <= idx < len(all_products):
|
|
|
159 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
160 |
|
161 |
if name_match:
|
162 |
+
product_name = name_match.group(1)
|
163 |
+
variant = variant_match.group(1) if variant_match else ""
|
164 |
+
|
165 |
+
# Get warehouse stock
|
166 |
+
warehouse_regex = r'<Warehouse>.*?<Name><!\[CDATA\[(.*?)\]\]></Name>.*?<Stock>(.*?)</Stock>.*?</Warehouse>'
|
167 |
+
warehouses = re.findall(warehouse_regex, product_block, re.DOTALL)
|
168 |
+
|
169 |
+
for wh_name, wh_stock in warehouses:
|
170 |
+
try:
|
171 |
+
stock = int(wh_stock.strip())
|
172 |
+
if stock > 0:
|
173 |
+
# Format warehouse name
|
174 |
+
display_name = format_warehouse_name(wh_name)
|
175 |
+
|
176 |
+
# If filtering by warehouse, only include that warehouse
|
177 |
+
if asked_warehouse:
|
178 |
+
if asked_warehouse in display_name:
|
179 |
+
product_details.append({
|
180 |
+
'name': product_name,
|
181 |
+
'variant': variant,
|
182 |
+
'warehouse': display_name,
|
183 |
+
'stock': stock
|
184 |
+
})
|
185 |
+
else:
|
186 |
+
if display_name not in all_warehouses:
|
187 |
+
all_warehouses[display_name] = []
|
188 |
+
all_warehouses[display_name].append({
|
189 |
+
'variant': variant,
|
190 |
+
'stock': stock
|
191 |
+
})
|
192 |
+
except:
|
193 |
+
pass
|
194 |
|
195 |
# Format result
|
196 |
+
result = []
|
197 |
+
|
198 |
+
if asked_warehouse:
|
199 |
+
# Show products in specific warehouse
|
200 |
+
if product_details:
|
201 |
+
result.append(f"{asked_warehouse} mağazasında mevcut:")
|
202 |
+
for detail in product_details:
|
203 |
+
result.append(f"• {detail['name']} ({detail['variant']}): {detail['stock']} adet")
|
204 |
+
else:
|
205 |
+
result.append(f"{asked_warehouse} mağazasında bu ürün mevcut değil")
|
206 |
+
else:
|
207 |
+
# Show all warehouses
|
|
|
208 |
if all_warehouses:
|
209 |
+
result.append(f"Bulunan {sum(len(v) for v in all_warehouses.values())} varyant:")
|
210 |
+
|
211 |
+
# Show a sample of variants
|
212 |
+
shown = 0
|
213 |
+
for warehouse, variants in all_warehouses.items():
|
214 |
+
for v in variants[:2]: # Show max 2 per warehouse
|
215 |
+
if shown < 5:
|
216 |
+
variant_text = f" ({v['variant']})" if v['variant'] else ""
|
217 |
+
result.append(f"• {product_name}{variant_text}")
|
218 |
+
shown += 1
|
219 |
+
|
220 |
+
if sum(len(v) for v in all_warehouses.values()) > 5:
|
221 |
+
result.append(f"... ve {sum(len(v) for v in all_warehouses.values()) - 5} varyant daha")
|
222 |
+
|
223 |
+
result.append("")
|
224 |
result.append("Toplam stok durumu:")
|
225 |
+
for warehouse, variants in sorted(all_warehouses.items()):
|
226 |
+
total = sum(v['stock'] for v in variants)
|
227 |
+
result.append(f"{warehouse}: {total} adet")
|
228 |
else:
|
229 |
result.append("Hiçbir mağazada stok yok")
|
230 |
+
|
231 |
+
return result
|
232 |
|
233 |
except (ValueError, IndexError) as e:
|
234 |
print(f"DEBUG - Error parsing indices: {e}")
|