Update to new B2B API with improved structure
Browse files- Updated URL to bizimhesap-warehouse-xml-b2b-api.php
- Changed XML parsing for new structure (ProductVariant instead of Variant)
- Updated warehouse parsing (direct Warehouse children instead of nested)
- Improved context-aware search for better variant matching
- New API has actual stock data with proper structure
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- app.py +53 -26
- test_new_api.py +29 -0
app.py
CHANGED
|
@@ -69,10 +69,18 @@ def get_warehouse_stock(product_name):
|
|
| 69 |
search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
|
| 70 |
search_words = search_name.split()
|
| 71 |
|
| 72 |
-
#
|
| 73 |
candidates = []
|
| 74 |
product_count = 0
|
| 75 |
-
max_products =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
for product in root.findall('Product'):
|
| 78 |
if product_count >= max_products:
|
|
@@ -80,37 +88,56 @@ def get_warehouse_stock(product_name):
|
|
| 80 |
product_count += 1
|
| 81 |
|
| 82 |
product_name_elem = product.find('ProductName')
|
|
|
|
|
|
|
| 83 |
if product_name_elem is not None and product_name_elem.text:
|
| 84 |
xml_product_name = product_name_elem.text.strip()
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
-
#
|
| 88 |
-
if
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
break
|
| 92 |
|
| 93 |
-
# Collect stock info
|
| 94 |
warehouse_stock_map = {}
|
| 95 |
|
| 96 |
-
for product, xml_name in candidates:
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
if
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
pass
|
| 114 |
|
| 115 |
# Cancel alarm
|
| 116 |
signal.alarm(0)
|
|
|
|
| 69 |
search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
|
| 70 |
search_words = search_name.split()
|
| 71 |
|
| 72 |
+
# Search using new B2B API structure
|
| 73 |
candidates = []
|
| 74 |
product_count = 0
|
| 75 |
+
max_products = 100 # Increase limit for new API
|
| 76 |
+
|
| 77 |
+
# Separate size/color words from product words for context-aware search
|
| 78 |
+
size_color_words = ['s', 'm', 'l', 'xl', 'xs', 'small', 'medium', 'large',
|
| 79 |
+
'turuncu', 'siyah', 'beyaz', 'mavi', 'kirmizi', 'yesil',
|
| 80 |
+
'orange', 'black', 'white', 'blue', 'red', 'green']
|
| 81 |
+
|
| 82 |
+
variant_words = [word for word in search_words if word in size_color_words]
|
| 83 |
+
product_words = [word for word in search_words if word not in size_color_words]
|
| 84 |
|
| 85 |
for product in root.findall('Product'):
|
| 86 |
if product_count >= max_products:
|
|
|
|
| 88 |
product_count += 1
|
| 89 |
|
| 90 |
product_name_elem = product.find('ProductName')
|
| 91 |
+
variant_elem = product.find('ProductVariant')
|
| 92 |
+
|
| 93 |
if product_name_elem is not None and product_name_elem.text:
|
| 94 |
xml_product_name = product_name_elem.text.strip()
|
| 95 |
+
normalized_name = normalize_turkish(xml_product_name.lower())
|
| 96 |
+
|
| 97 |
+
variant_text = ""
|
| 98 |
+
if variant_elem is not None and variant_elem.text:
|
| 99 |
+
variant_text = normalize_turkish(variant_elem.text.strip().lower())
|
| 100 |
+
|
| 101 |
+
# Context-aware matching
|
| 102 |
+
name_match = False
|
| 103 |
+
variant_match = False
|
| 104 |
+
|
| 105 |
+
# Check product name match
|
| 106 |
+
if product_words:
|
| 107 |
+
name_match = all(word in normalized_name for word in product_words)
|
| 108 |
+
else:
|
| 109 |
+
name_match = any(word in normalized_name for word in search_words if len(word) > 2)
|
| 110 |
|
| 111 |
+
# Check variant match
|
| 112 |
+
if variant_words and variant_text:
|
| 113 |
+
variant_match = all(word in variant_text for word in variant_words)
|
| 114 |
+
|
| 115 |
+
# Include if name matches and (no variant search OR variant matches)
|
| 116 |
+
if name_match and (not variant_words or variant_match):
|
| 117 |
+
candidates.append((product, xml_product_name, variant_text))
|
| 118 |
+
if len(candidates) >= 10: # Limit candidates
|
| 119 |
break
|
| 120 |
|
| 121 |
+
# Collect stock info from new structure
|
| 122 |
warehouse_stock_map = {}
|
| 123 |
|
| 124 |
+
for product, xml_name, variant in candidates:
|
| 125 |
+
# New structure: Warehouse elements are direct children of Product
|
| 126 |
+
for warehouse in product.findall('Warehouse'):
|
| 127 |
+
name_elem = warehouse.find('Name')
|
| 128 |
+
stock_elem = warehouse.find('Stock')
|
| 129 |
+
|
| 130 |
+
if name_elem is not None and stock_elem is not None:
|
| 131 |
+
warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
|
| 132 |
+
try:
|
| 133 |
+
stock_count = int(stock_elem.text) if stock_elem.text else 0
|
| 134 |
+
if stock_count > 0:
|
| 135 |
+
if warehouse_name in warehouse_stock_map:
|
| 136 |
+
warehouse_stock_map[warehouse_name] += stock_count
|
| 137 |
+
else:
|
| 138 |
+
warehouse_stock_map[warehouse_name] = stock_count
|
| 139 |
+
except (ValueError, TypeError):
|
| 140 |
+
pass
|
|
|
|
| 141 |
|
| 142 |
# Cancel alarm
|
| 143 |
signal.alarm(0)
|
test_new_api.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Test new B2B API with updated function
|
| 3 |
+
|
| 4 |
+
import sys
|
| 5 |
+
import os
|
| 6 |
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
| 7 |
+
|
| 8 |
+
from app import get_warehouse_stock
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
test_cases = [
|
| 12 |
+
"M Turuncu", # Should find M Turuncu variants
|
| 13 |
+
"Marlin M Turuncu", # Should find Marlin M Turuncu variants
|
| 14 |
+
"L Turuncu", # Should find L Turuncu variants
|
| 15 |
+
]
|
| 16 |
+
|
| 17 |
+
for test_case in test_cases:
|
| 18 |
+
print(f"\n=== Testing: {test_case} ===")
|
| 19 |
+
try:
|
| 20 |
+
result = get_warehouse_stock(test_case)
|
| 21 |
+
if result:
|
| 22 |
+
print("Sonuç:")
|
| 23 |
+
for item in result:
|
| 24 |
+
print(f" • {item}")
|
| 25 |
+
else:
|
| 26 |
+
print("Sonuç bulunamadı")
|
| 27 |
+
except Exception as e:
|
| 28 |
+
print(f"Hata: {e}")
|
| 29 |
+
print("-" * 50)
|