SamiKoen commited on
Commit
4fa4ebe
·
verified ·
1 Parent(s): 6379eb1

Upload 7 files

Browse files
Files changed (7) hide show
  1. app.py +126 -75
  2. search_marlin_products.py +157 -0
  3. test_final.py +31 -0
  4. test_m_turuncu.py +160 -0
  5. test_updated_warehouse.py +166 -0
  6. test_variant.py +110 -0
  7. test_warehouse.py +136 -0
app.py CHANGED
@@ -60,7 +60,7 @@ else:
60
 
61
  # Mağaza stok bilgilerini çekme fonksiyonu
62
  def get_warehouse_stock(product_name):
63
- """B2B API'den mağaza stok bilgilerini çek"""
64
  try:
65
  import re
66
  warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
@@ -71,71 +71,134 @@ def get_warehouse_stock(product_name):
71
 
72
  root = ET.fromstring(response.content)
73
 
74
- # Ürünü ara
75
- for product in root.findall('Product'):
76
- product_name_elem = product.find('ProductName')
77
- if product_name_elem is not None and product_name_elem.text:
78
- xml_product_name = product_name_elem.text.lower().strip()
79
- search_name = product_name.lower().strip()
80
-
81
- # Fuzzy matching - normalize both names
82
- # Turkish character normalization
83
- turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- def normalize_turkish(text):
86
- # First normalize Unicode (İ → i̇ → i)
87
- import unicodedata
88
- text = unicodedata.normalize('NFD', text)
89
- text = ''.join(char for char in text if unicodedata.category(char) != 'Mn') # Remove diacritics
90
 
91
- # Then Turkish character mapping
92
- for tr_char, en_char in turkish_map.items():
93
- text = text.replace(tr_char, en_char)
94
- return text
95
-
96
- # Remove common variations for better matching
97
- normalized_search = normalize_turkish(search_name.replace('(2026)', '').replace('(2025)', '').replace(' - ', ' ').strip())
98
- normalized_xml = normalize_turkish(xml_product_name.replace('(2026)', '').replace('(2025)', '').replace(' - ', ' ').strip())
99
-
100
- # Extract key product identifiers (first 2-3 meaningful words)
101
- search_words = normalized_search.split()
102
- xml_words = normalized_xml.split()
103
-
104
- # Calculate similarity score based on common words
105
- common_words = set(search_words) & set(xml_words)
106
-
107
- # Check if we have enough common words (at least 2 key words match)
108
- # OR if the first two words match (brand + model number usually)
109
- search_key = ' '.join(search_words[:2]) if len(search_words) >= 2 else normalized_search
110
- xml_key = ' '.join(xml_words[:2]) if len(xml_words) >= 2 else normalized_xml
111
-
112
- # Match if:
113
- # 1. First two words are the same (e.g., "marlin 6", "checkpoint sl")
114
- # 2. OR we have at least 2 common words
115
- # 3. OR one contains the other (for partial matches)
116
- if (search_key == xml_key or
117
- len(common_words) >= 2 or
118
- search_key in normalized_xml or
119
- xml_key in normalized_search):
120
- warehouses = product.find('Warehouses')
121
- if warehouses is not None:
122
- warehouse_info = []
123
- for warehouse in warehouses.findall('Warehouse'):
124
- name_elem = warehouse.find('Name')
125
- stock_elem = warehouse.find('Stock')
126
-
127
- if name_elem is not None and stock_elem is not None:
128
- warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
129
- try:
130
- stock_count = int(stock_elem.text) if stock_elem.text else 0
131
- if stock_count > 0:
132
- warehouse_info.append(f"{warehouse_name}: {stock_count} adet")
133
- except (ValueError, TypeError):
134
- pass
135
 
136
- return warehouse_info if warehouse_info else ["Hiçbir mağazada stokta bulunmuyor"]
137
-
138
- return ["Ürün bulunamadı"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  except Exception as e:
141
  print(f"Mağaza stok bilgisi çekme hatası: {e}")
@@ -752,8 +815,6 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
752
  if product_result['is_product_query'] and product_result['response']:
753
  # Check if user is asking about specific warehouse/store location
754
  if any(keyword in user_message.lower() for keyword in ['mağaza', 'mağazada', 'nerede', 'hangi mağaza', 'şube']):
755
- print(f"DEBUG: Mağaza sorusu algılandı: {user_message}")
756
-
757
  # First, always search for products using improved search
758
  # This will find products even with partial/typo names
759
  warehouse_info_parts = []
@@ -766,7 +827,6 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
766
  product_names = re.findall(r'\*([^*]+)\*', product_result['response'])
767
 
768
  if product_names:
769
- print(f"DEBUG: Response'tan {len(product_names)} ürün adı çıkarıldı")
770
  for product_name in product_names[:3]: # Max 3 products
771
  # Clean up the product name
772
  product_name = product_name.strip()
@@ -779,9 +839,7 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
779
  if product_name in ['Stokta mevcut', 'Stokta yok', 'Fiyat:', 'Kampanya:', 'İndirim:', 'Birden fazla ürün buldum:']:
780
  continue
781
 
782
- print(f"DEBUG: Mağaza stogu kontrol ediliyor: {product_name}")
783
  warehouse_stock = get_warehouse_stock(product_name)
784
- print(f"DEBUG: Mağaza stok sonucu: {warehouse_stock}")
785
 
786
  if warehouse_stock and warehouse_stock != ['Ürün bulunamadı'] and warehouse_stock != ['Hiçbir mağazada stokta bulunmuyor']:
787
  warehouse_info_parts.append(f"{product_name} mağaza stogu:")
@@ -791,12 +849,9 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
791
 
792
  # If still no warehouse info, use products_found as backup
793
  if not warehouse_info_parts and product_result['products_found']:
794
- print(f"DEBUG: Response'tan bulunamadı, products_found kullanılıyor")
795
  for product in product_result['products_found'][:2]:
796
  product_name = product[2] # Full product name
797
- print(f"DEBUG: Mağaza stogu kontrol ediliyor: {product_name}")
798
  warehouse_stock = get_warehouse_stock(product_name)
799
- print(f"DEBUG: Mağaza stok sonucu: {warehouse_stock}")
800
 
801
  if warehouse_stock and warehouse_stock != ['Ürün bulunamadı'] and warehouse_stock != ['Hiçbir mağazada stokta bulunmuyor']:
802
  warehouse_info_parts.append(f"{product_name} mağaza stogu:")
@@ -806,15 +861,12 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
806
 
807
  if warehouse_info_parts:
808
  warehouse_response = "\n".join(warehouse_info_parts)
809
- print(f"DEBUG: ChatGPT'ye gönderilecek mağaza bilgisi: {warehouse_response}")
810
  messages.append({
811
  "role": "system",
812
  "content": f"MAĞAZA STOK BİLGİSİ (BF Space):\n{warehouse_response}\n\nSADECE bu bilgileri kullanarak kullanıcıya yardımcı ol."
813
  })
814
  product_found_improved = True
815
  logger.info("✅ BF Space: Warehouse stock info used")
816
- else:
817
- print("DEBUG: Hiç mağaza bilgisi bulunamadı")
818
 
819
  if not product_found_improved:
820
  # Use improved search response directly
@@ -824,7 +876,6 @@ def process_whatsapp_message_with_memory(user_message, phone_number):
824
  })
825
  product_found_improved = True
826
  logger.info("✅ BF Space: Improved product search used")
827
- print(f"DEBUG: Improved search found response: {product_result['response'][:100]}...")
828
  except Exception as e:
829
  logger.error(f"❌ BF Space: Improved search error: {e}")
830
 
 
60
 
61
  # Mağaza stok bilgilerini çekme fonksiyonu
62
  def get_warehouse_stock(product_name):
63
+ """B2B API'den mağaza stok bilgilerini çek - İyileştirilmiş versiyon"""
64
  try:
65
  import re
66
  warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
 
71
 
72
  root = ET.fromstring(response.content)
73
 
74
+ # Turkish character normalization function
75
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
76
+
77
+ def normalize_turkish(text):
78
+ import unicodedata
79
+ text = unicodedata.normalize('NFD', text)
80
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
81
+ for tr_char, en_char in turkish_map.items():
82
+ text = text.replace(tr_char, en_char)
83
+ return text
84
+
85
+ # Normalize search product name
86
+ search_name = normalize_turkish(product_name.lower().strip())
87
+ search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
88
+ search_words = search_name.split()
89
+
90
+ best_matches = []
91
+ exact_matches = []
92
+ variant_matches = []
93
+ candidates = []
94
+
95
+ # Check if this is a size/color specific query (like "M Turuncu")
96
+ is_size_color_query = (len(search_words) <= 3 and
97
+ any(word in ['s', 'm', 'l', 'xl', 'xs', 'small', 'medium', 'large',
98
+ 'turuncu', 'siyah', 'beyaz', 'mavi', 'kirmizi', 'yesil',
99
+ 'orange', 'black', 'white', 'blue', 'red', 'green']
100
+ for word in search_words))
101
+
102
+ # İlk geçiş: Variant alanında beden/renk araması
103
+ if is_size_color_query:
104
+ for product in root.findall('Product'):
105
+ product_name_elem = product.find('ProductName')
106
+ variant_elem = product.find('Variant')
107
 
108
+ if product_name_elem is not None and product_name_elem.text:
109
+ xml_product_name = product_name_elem.text.strip()
 
 
 
110
 
111
+ # Variant field check
112
+ if variant_elem is not None and variant_elem.text:
113
+ variant_text = normalize_turkish(variant_elem.text.lower().replace('-', ' '))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
+ # Check if all search words are in variant field
116
+ if all(word in variant_text for word in search_words):
117
+ variant_matches.append((product, xml_product_name, variant_text))
118
+
119
+ if variant_matches:
120
+ candidates = variant_matches
121
+ else:
122
+ # Fallback to normal product name search
123
+ is_size_color_query = False
124
+
125
+ # İkinci geçiş: Normal ürün adı tam eşleşmeleri (variant match yoksa)
126
+ if not is_size_color_query or not candidates:
127
+ for product in root.findall('Product'):
128
+ product_name_elem = product.find('ProductName')
129
+ if product_name_elem is not None and product_name_elem.text:
130
+ xml_product_name = product_name_elem.text.strip()
131
+ normalized_xml = normalize_turkish(xml_product_name.lower())
132
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
133
+ xml_words = normalized_xml.split()
134
+
135
+ # Tam eşleşme kontrolü - ilk iki kelime tam aynı olmalı
136
+ if len(search_words) >= 2 and len(xml_words) >= 2:
137
+ search_key = f"{search_words[0]} {search_words[1]}"
138
+ xml_key = f"{xml_words[0]} {xml_words[1]}"
139
+
140
+ if search_key == xml_key:
141
+ exact_matches.append((product, xml_product_name, normalized_xml))
142
+
143
+ # Eğer variant match varsa onu kullan, yoksa exact matches kullan
144
+ if not candidates:
145
+ candidates = exact_matches if exact_matches else []
146
+
147
+ # Eğer hala bir match yoksa, fuzzy matching yap
148
+ if not candidates:
149
+ for product in root.findall('Product'):
150
+ product_name_elem = product.find('ProductName')
151
+ if product_name_elem is not None and product_name_elem.text:
152
+ xml_product_name = product_name_elem.text.strip()
153
+ normalized_xml = normalize_turkish(xml_product_name.lower())
154
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
155
+ xml_words = normalized_xml.split()
156
+
157
+ # Ortak kelime sayısını hesapla
158
+ common_words = set(search_words) & set(xml_words)
159
+
160
+ # En az 2 ortak kelime olmalı VE ilk kelime aynı olmalı (marka kontrolü)
161
+ if (len(common_words) >= 2 and
162
+ len(search_words) > 0 and len(xml_words) > 0 and
163
+ search_words[0] == xml_words[0]):
164
+ best_matches.append((product, xml_product_name, normalized_xml, len(common_words)))
165
+
166
+ # En çok ortak kelimeye sahip olanları seç
167
+ if best_matches:
168
+ max_common = max(match[3] for match in best_matches)
169
+ candidates = [(match[0], match[1], match[2]) for match in best_matches if match[3] == max_common]
170
+
171
+ # Stok bilgilerini topla ve tekrarları önle
172
+ warehouse_stock_map = {} # warehouse_name -> total_stock
173
+
174
+ for product, xml_name, _ in candidates:
175
+ warehouses = product.find('Warehouses')
176
+ if warehouses is not None:
177
+ for warehouse in warehouses.findall('Warehouse'):
178
+ name_elem = warehouse.find('Name')
179
+ stock_elem = warehouse.find('Stock')
180
+
181
+ if name_elem is not None and stock_elem is not None:
182
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
183
+ try:
184
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
185
+ if stock_count > 0:
186
+ # Aynı mağaza için stokları topla
187
+ if warehouse_name in warehouse_stock_map:
188
+ warehouse_stock_map[warehouse_name] += stock_count
189
+ else:
190
+ warehouse_stock_map[warehouse_name] = stock_count
191
+ except (ValueError, TypeError):
192
+ pass
193
+
194
+ if warehouse_stock_map:
195
+ # Mağaza stoklarını liste halinde döndür
196
+ all_warehouse_info = []
197
+ for warehouse_name, total_stock in warehouse_stock_map.items():
198
+ all_warehouse_info.append(f"{warehouse_name}: {total_stock} adet")
199
+ return all_warehouse_info
200
+ else:
201
+ return ["Hiçbir mağazada stokta bulunmuyor"]
202
 
203
  except Exception as e:
204
  print(f"Mağaza stok bilgisi çekme hatası: {e}")
 
815
  if product_result['is_product_query'] and product_result['response']:
816
  # Check if user is asking about specific warehouse/store location
817
  if any(keyword in user_message.lower() for keyword in ['mağaza', 'mağazada', 'nerede', 'hangi mağaza', 'şube']):
 
 
818
  # First, always search for products using improved search
819
  # This will find products even with partial/typo names
820
  warehouse_info_parts = []
 
827
  product_names = re.findall(r'\*([^*]+)\*', product_result['response'])
828
 
829
  if product_names:
 
830
  for product_name in product_names[:3]: # Max 3 products
831
  # Clean up the product name
832
  product_name = product_name.strip()
 
839
  if product_name in ['Stokta mevcut', 'Stokta yok', 'Fiyat:', 'Kampanya:', 'İndirim:', 'Birden fazla ürün buldum:']:
840
  continue
841
 
 
842
  warehouse_stock = get_warehouse_stock(product_name)
 
843
 
844
  if warehouse_stock and warehouse_stock != ['Ürün bulunamadı'] and warehouse_stock != ['Hiçbir mağazada stokta bulunmuyor']:
845
  warehouse_info_parts.append(f"{product_name} mağaza stogu:")
 
849
 
850
  # If still no warehouse info, use products_found as backup
851
  if not warehouse_info_parts and product_result['products_found']:
 
852
  for product in product_result['products_found'][:2]:
853
  product_name = product[2] # Full product name
 
854
  warehouse_stock = get_warehouse_stock(product_name)
 
855
 
856
  if warehouse_stock and warehouse_stock != ['Ürün bulunamadı'] and warehouse_stock != ['Hiçbir mağazada stokta bulunmuyor']:
857
  warehouse_info_parts.append(f"{product_name} mağaza stogu:")
 
861
 
862
  if warehouse_info_parts:
863
  warehouse_response = "\n".join(warehouse_info_parts)
 
864
  messages.append({
865
  "role": "system",
866
  "content": f"MAĞAZA STOK BİLGİSİ (BF Space):\n{warehouse_response}\n\nSADECE bu bilgileri kullanarak kullanıcıya yardımcı ol."
867
  })
868
  product_found_improved = True
869
  logger.info("✅ BF Space: Warehouse stock info used")
 
 
870
 
871
  if not product_found_improved:
872
  # Use improved search response directly
 
876
  })
877
  product_found_improved = True
878
  logger.info("✅ BF Space: Improved product search used")
 
879
  except Exception as e:
880
  logger.error(f"❌ BF Space: Improved search error: {e}")
881
 
search_marlin_products.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import requests
3
+ import xml.etree.ElementTree as ET
4
+
5
+ def search_marlin_products():
6
+ """B2B API'den MARLIN ürünlerini listele"""
7
+ try:
8
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
9
+ response = requests.get(warehouse_url, verify=False, timeout=15)
10
+
11
+ if response.status_code != 200:
12
+ return None
13
+
14
+ root = ET.fromstring(response.content)
15
+
16
+ # Turkish character normalization function
17
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
18
+
19
+ def normalize_turkish(text):
20
+ import unicodedata
21
+ text = unicodedata.normalize('NFD', text)
22
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
23
+ for tr_char, en_char in turkish_map.items():
24
+ text = text.replace(tr_char, en_char)
25
+ return text
26
+
27
+ marlin_products = []
28
+
29
+ # MARLIN içeren tüm ürünleri bul
30
+ for product in root.findall('Product'):
31
+ product_name_elem = product.find('ProductName')
32
+ if product_name_elem is not None and product_name_elem.text:
33
+ xml_product_name = product_name_elem.text.strip()
34
+ normalized_xml = normalize_turkish(xml_product_name.lower())
35
+
36
+ if 'marlin' in normalized_xml:
37
+ # Stok durumunu kontrol et
38
+ has_stock = False
39
+ stock_info = []
40
+
41
+ warehouses = product.find('Warehouses')
42
+ if warehouses is not None:
43
+ for warehouse in warehouses.findall('Warehouse'):
44
+ name_elem = warehouse.find('Name')
45
+ stock_elem = warehouse.find('Stock')
46
+
47
+ if name_elem is not None and stock_elem is not None:
48
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
49
+ try:
50
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
51
+ if stock_count > 0:
52
+ stock_info.append(f"{warehouse_name}: {stock_count}")
53
+ has_stock = True
54
+ except (ValueError, TypeError):
55
+ pass
56
+
57
+ marlin_products.append({
58
+ 'name': xml_product_name,
59
+ 'has_stock': has_stock,
60
+ 'stock_info': stock_info
61
+ })
62
+
63
+ return marlin_products
64
+
65
+ except Exception as e:
66
+ print(f"Arama hatası: {e}")
67
+ return None
68
+
69
+ def search_turuncu_products():
70
+ """B2B API'den TURUNCU içeren ürünleri listele"""
71
+ try:
72
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
73
+ response = requests.get(warehouse_url, verify=False, timeout=15)
74
+
75
+ if response.status_code != 200:
76
+ return None
77
+
78
+ root = ET.fromstring(response.content)
79
+
80
+ # Turkish character normalization function
81
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
82
+
83
+ def normalize_turkish(text):
84
+ import unicodedata
85
+ text = unicodedata.normalize('NFD', text)
86
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
87
+ for tr_char, en_char in turkish_map.items():
88
+ text = text.replace(tr_char, en_char)
89
+ return text
90
+
91
+ turuncu_products = []
92
+
93
+ # TURUNCU içeren tüm ürünleri bul
94
+ for product in root.findall('Product'):
95
+ product_name_elem = product.find('ProductName')
96
+ if product_name_elem is not None and product_name_elem.text:
97
+ xml_product_name = product_name_elem.text.strip()
98
+ normalized_xml = normalize_turkish(xml_product_name.lower())
99
+
100
+ if 'turuncu' in normalized_xml:
101
+ # Stok durumunu kontrol et
102
+ has_stock = False
103
+ stock_info = []
104
+
105
+ warehouses = product.find('Warehouses')
106
+ if warehouses is not None:
107
+ for warehouse in warehouses.findall('Warehouse'):
108
+ name_elem = warehouse.find('Name')
109
+ stock_elem = warehouse.find('Stock')
110
+
111
+ if name_elem is not None and stock_elem is not None:
112
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
113
+ try:
114
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
115
+ if stock_count > 0:
116
+ stock_info.append(f"{warehouse_name}: {stock_count}")
117
+ has_stock = True
118
+ except (ValueError, TypeError):
119
+ pass
120
+
121
+ turuncu_products.append({
122
+ 'name': xml_product_name,
123
+ 'has_stock': has_stock,
124
+ 'stock_info': stock_info
125
+ })
126
+
127
+ return turuncu_products
128
+
129
+ except Exception as e:
130
+ print(f"Arama hatası: {e}")
131
+ return None
132
+
133
+ if __name__ == "__main__":
134
+ print("=== MARLIN ÜRÜNLERİ ===")
135
+ marlin_products = search_marlin_products()
136
+ if marlin_products:
137
+ print(f"Toplam {len(marlin_products)} MARLIN ürünü bulundu:")
138
+ for i, product in enumerate(marlin_products, 1):
139
+ print(f"{i:2}. {product['name']}")
140
+ if product['has_stock']:
141
+ print(f" STOKTA: {', '.join(product['stock_info'])}")
142
+ else:
143
+ print(f" STOKTA DEĞİL")
144
+ print()
145
+
146
+ print("\n" + "="*50)
147
+ print("=== TURUNCU ÜRÜNLERİ ===")
148
+ turuncu_products = search_turuncu_products()
149
+ if turuncu_products:
150
+ print(f"Toplam {len(turuncu_products)} TURUNCU ürünü bulundu:")
151
+ for i, product in enumerate(turuncu_products, 1):
152
+ print(f"{i:2}. {product['name']}")
153
+ if product['has_stock']:
154
+ print(f" STOKTA: {', '.join(product['stock_info'])}")
155
+ else:
156
+ print(f" STOKTA DEĞİL")
157
+ print()
test_final.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # Final test with updated get_warehouse_stock function from app.py
3
+
4
+ import sys
5
+ import os
6
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
7
+
8
+ # Import the updated function from app.py
9
+ from app import get_warehouse_stock
10
+
11
+ if __name__ == "__main__":
12
+ test_cases = [
13
+ "M Turuncu",
14
+ "Marlin 6 M Turuncu",
15
+ "L Siyah",
16
+ "S Beyaz"
17
+ ]
18
+
19
+ for test_case in test_cases:
20
+ print(f"\n=== Testing: {test_case} ===")
21
+ try:
22
+ result = get_warehouse_stock(test_case)
23
+ if result:
24
+ print("Sonuç:")
25
+ for item in result:
26
+ print(f" • {item}")
27
+ else:
28
+ print("Sonuç bulunamadı")
29
+ except Exception as e:
30
+ print(f"Hata: {e}")
31
+ print("-" * 50)
test_m_turuncu.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import requests
3
+ import xml.etree.ElementTree as ET
4
+
5
+ def get_warehouse_stock(product_name):
6
+ """B2B API'den mağaza stok bilgilerini çek - İyileştirilmiş versiyon"""
7
+ try:
8
+ import re
9
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
10
+ response = requests.get(warehouse_url, verify=False, timeout=15)
11
+
12
+ if response.status_code != 200:
13
+ return None
14
+
15
+ root = ET.fromstring(response.content)
16
+
17
+ # Turkish character normalization function
18
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
19
+
20
+ def normalize_turkish(text):
21
+ import unicodedata
22
+ text = unicodedata.normalize('NFD', text)
23
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
24
+ for tr_char, en_char in turkish_map.items():
25
+ text = text.replace(tr_char, en_char)
26
+ return text
27
+
28
+ # Normalize search product name
29
+ search_name = normalize_turkish(product_name.lower().strip())
30
+ search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
31
+ search_words = search_name.split()
32
+
33
+ print(f"DEBUG: Aranan ürün: '{product_name}' -> normalize: '{search_name}' -> kelimeler: {search_words}")
34
+
35
+ best_matches = []
36
+ exact_matches = []
37
+ color_size_matches = [] # For size/color specific searches
38
+
39
+ # Check if this is a size/color query (like "M Turuncu")
40
+ is_size_color_query = len(search_words) <= 2 and any(word in ['s', 'm', 'l', 'xl', 'xs', 'small', 'medium', 'large', 'turuncu', 'siyah', 'beyaz', 'mavi', 'kirmizi', 'yesil'] for word in search_words)
41
+
42
+ if is_size_color_query:
43
+ print(f"DEBUG: Beden/renk araması algılandı: {search_words}")
44
+ # For size/color queries, look for products containing these terms
45
+ for product in root.findall('Product'):
46
+ product_name_elem = product.find('ProductName')
47
+ if product_name_elem is not None and product_name_elem.text:
48
+ xml_product_name = product_name_elem.text.strip()
49
+ normalized_xml = normalize_turkish(xml_product_name.lower())
50
+
51
+ # Check if all search words appear in the product name
52
+ if all(word in normalized_xml for word in search_words):
53
+ color_size_matches.append((product, xml_product_name, normalized_xml))
54
+ print(f"DEBUG: BEDEN/RENK EŞLEŞME: '{xml_product_name}'")
55
+
56
+ candidates = color_size_matches
57
+ else:
58
+ # Normal product search logic
59
+ # İlk geçiş: Tam eşleşmeleri bul
60
+ for product in root.findall('Product'):
61
+ product_name_elem = product.find('ProductName')
62
+ if product_name_elem is not None and product_name_elem.text:
63
+ xml_product_name = product_name_elem.text.strip()
64
+ normalized_xml = normalize_turkish(xml_product_name.lower())
65
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
66
+ xml_words = normalized_xml.split()
67
+
68
+ # Tam eşleşme kontrolü - ilk iki kelime tam aynı olmalı
69
+ if len(search_words) >= 2 and len(xml_words) >= 2:
70
+ search_key = f"{search_words[0]} {search_words[1]}"
71
+ xml_key = f"{xml_words[0]} {xml_words[1]}"
72
+
73
+ if search_key == xml_key:
74
+ exact_matches.append((product, xml_product_name, normalized_xml))
75
+ print(f"DEBUG: TAM EŞLEŞME: '{xml_product_name}'")
76
+
77
+ # Eğer tam eşleşme varsa, sadece onları kullan
78
+ candidates = exact_matches if exact_matches else []
79
+
80
+ # Eğer tam eşleşme yoksa, fuzzy matching yap
81
+ if not candidates:
82
+ print("DEBUG: Tam eşleşme yok, fuzzy matching yapılıyor...")
83
+ for product in root.findall('Product'):
84
+ product_name_elem = product.find('ProductName')
85
+ if product_name_elem is not None and product_name_elem.text:
86
+ xml_product_name = product_name_elem.text.strip()
87
+ normalized_xml = normalize_turkish(xml_product_name.lower())
88
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
89
+ xml_words = normalized_xml.split()
90
+
91
+ # Ortak kelime sayısını hesapla
92
+ common_words = set(search_words) & set(xml_words)
93
+
94
+ # En az 2 ortak kelime olmalı VE ilk kelime aynı olmalı (marka kontrolü)
95
+ if (len(common_words) >= 2 and
96
+ len(search_words) > 0 and len(xml_words) > 0 and
97
+ search_words[0] == xml_words[0]):
98
+ best_matches.append((product, xml_product_name, normalized_xml, len(common_words)))
99
+ print(f"DEBUG: FUZZY EŞLEŞME: '{xml_product_name}' (ortak: {len(common_words)})")
100
+
101
+ # En çok ortak kelimeye sahip olanları seç
102
+ if best_matches:
103
+ max_common = max(match[3] for match in best_matches)
104
+ candidates = [(match[0], match[1], match[2]) for match in best_matches if match[3] == max_common]
105
+
106
+ print(f"DEBUG: Toplam {len(candidates)} aday ürün bulundu")
107
+
108
+ # Stok bilgilerini topla ve tekrarları önle
109
+ warehouse_stock_map = {} # warehouse_name -> total_stock
110
+
111
+ for product, xml_name, _ in candidates:
112
+ warehouses = product.find('Warehouses')
113
+ if warehouses is not None:
114
+ for warehouse in warehouses.findall('Warehouse'):
115
+ name_elem = warehouse.find('Name')
116
+ stock_elem = warehouse.find('Stock')
117
+
118
+ if name_elem is not None and stock_elem is not None:
119
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
120
+ try:
121
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
122
+ if stock_count > 0:
123
+ # Aynı mağaza için stokları topla
124
+ if warehouse_name in warehouse_stock_map:
125
+ warehouse_stock_map[warehouse_name] += stock_count
126
+ else:
127
+ warehouse_stock_map[warehouse_name] = stock_count
128
+ print(f"DEBUG: STOK BULUNDU - {warehouse_name}: {stock_count} adet ({xml_name})")
129
+ except (ValueError, TypeError):
130
+ pass
131
+
132
+ if warehouse_stock_map:
133
+ # Mağaza stoklarını liste halinde döndür
134
+ all_warehouse_info = []
135
+ for warehouse_name, total_stock in warehouse_stock_map.items():
136
+ all_warehouse_info.append(f"{warehouse_name}: {total_stock} adet")
137
+ return all_warehouse_info
138
+ else:
139
+ print("DEBUG: Hiçbir mağazada stok bulunamadı")
140
+ return ["Hiçbir mağazada stokta bulunmuyor"]
141
+
142
+ except Exception as e:
143
+ print(f"Mağaza stok bilgisi çekme hatası: {e}")
144
+ return None
145
+
146
+ if __name__ == "__main__":
147
+ # Test the function with different M Turuncu variations
148
+ test_cases = [
149
+ "M Turuncu",
150
+ "m turuncu",
151
+ "M TURUNCU",
152
+ "Medium Turuncu",
153
+ "Marlin 6 M Turuncu"
154
+ ]
155
+
156
+ for test_case in test_cases:
157
+ print(f"=== Testing: {test_case} ===")
158
+ result = get_warehouse_stock(test_case)
159
+ print(f"Result: {result}")
160
+ print()
test_updated_warehouse.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import requests
3
+ import xml.etree.ElementTree as ET
4
+
5
+ def get_warehouse_stock(product_name):
6
+ """B2B API'den mağaza stok bilgilerini çek - Final Updated Version"""
7
+ try:
8
+ import re
9
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
10
+ response = requests.get(warehouse_url, verify=False, timeout=15)
11
+
12
+ if response.status_code != 200:
13
+ return None
14
+
15
+ root = ET.fromstring(response.content)
16
+
17
+ # Turkish character normalization function
18
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
19
+
20
+ def normalize_turkish(text):
21
+ import unicodedata
22
+ text = unicodedata.normalize('NFD', text)
23
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
24
+ for tr_char, en_char in turkish_map.items():
25
+ text = text.replace(tr_char, en_char)
26
+ return text
27
+
28
+ # Normalize search product name
29
+ search_name = normalize_turkish(product_name.lower().strip())
30
+ search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
31
+ search_words = search_name.split()
32
+
33
+ best_matches = []
34
+ exact_matches = []
35
+ variant_matches = []
36
+ candidates = []
37
+
38
+ # Check if this is a size/color specific query (like "M Turuncu")
39
+ is_size_color_query = (len(search_words) <= 3 and
40
+ any(word in ['s', 'm', 'l', 'xl', 'xs', 'small', 'medium', 'large',
41
+ 'turuncu', 'siyah', 'beyaz', 'mavi', 'kirmizi', 'yesil',
42
+ 'orange', 'black', 'white', 'blue', 'red', 'green']
43
+ for word in search_words))
44
+
45
+ # İlk geçiş: Variant alanında beden/renk araması
46
+ if is_size_color_query:
47
+ for product in root.findall('Product'):
48
+ product_name_elem = product.find('ProductName')
49
+ variant_elem = product.find('Variant')
50
+
51
+ if product_name_elem is not None and product_name_elem.text:
52
+ xml_product_name = product_name_elem.text.strip()
53
+
54
+ # Variant field check
55
+ if variant_elem is not None and variant_elem.text:
56
+ variant_text = normalize_turkish(variant_elem.text.lower().replace('-', ' '))
57
+
58
+ # Check if all search words are in variant field
59
+ if all(word in variant_text for word in search_words):
60
+ variant_matches.append((product, xml_product_name, variant_text))
61
+
62
+ if variant_matches:
63
+ candidates = variant_matches
64
+ else:
65
+ # Fallback to normal product name search
66
+ is_size_color_query = False
67
+
68
+ # İkinci geçiş: Normal ürün adı tam eşleşmeleri (variant match yoksa)
69
+ if not is_size_color_query or not candidates:
70
+ for product in root.findall('Product'):
71
+ product_name_elem = product.find('ProductName')
72
+ if product_name_elem is not None and product_name_elem.text:
73
+ xml_product_name = product_name_elem.text.strip()
74
+ normalized_xml = normalize_turkish(xml_product_name.lower())
75
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
76
+ xml_words = normalized_xml.split()
77
+
78
+ # Tam eşleşme kontrolü - ilk iki kelime tam aynı olmalı
79
+ if len(search_words) >= 2 and len(xml_words) >= 2:
80
+ search_key = f"{search_words[0]} {search_words[1]}"
81
+ xml_key = f"{xml_words[0]} {xml_words[1]}"
82
+
83
+ if search_key == xml_key:
84
+ exact_matches.append((product, xml_product_name, normalized_xml))
85
+
86
+ # Eğer variant match varsa onu kullan, yoksa exact matches kullan
87
+ if not candidates:
88
+ candidates = exact_matches if exact_matches else []
89
+
90
+ # Eğer hala bir match yoksa, fuzzy matching yap
91
+ if not candidates:
92
+ for product in root.findall('Product'):
93
+ product_name_elem = product.find('ProductName')
94
+ if product_name_elem is not None and product_name_elem.text:
95
+ xml_product_name = product_name_elem.text.strip()
96
+ normalized_xml = normalize_turkish(xml_product_name.lower())
97
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
98
+ xml_words = normalized_xml.split()
99
+
100
+ # Ortak kelime sayısını hesapla
101
+ common_words = set(search_words) & set(xml_words)
102
+
103
+ # En az 2 ortak kelime olmalı VE ilk kelime aynı olmalı (marka kontrolü)
104
+ if (len(common_words) >= 2 and
105
+ len(search_words) > 0 and len(xml_words) > 0 and
106
+ search_words[0] == xml_words[0]):
107
+ best_matches.append((product, xml_product_name, normalized_xml, len(common_words)))
108
+
109
+ # En çok ortak kelimeye sahip olanları seç
110
+ if best_matches:
111
+ max_common = max(match[3] for match in best_matches)
112
+ candidates = [(match[0], match[1], match[2]) for match in best_matches if match[3] == max_common]
113
+
114
+ # Stok bilgilerini topla ve tekrarları önle
115
+ warehouse_stock_map = {} # warehouse_name -> total_stock
116
+
117
+ for product, xml_name, _ in candidates:
118
+ warehouses = product.find('Warehouses')
119
+ if warehouses is not None:
120
+ for warehouse in warehouses.findall('Warehouse'):
121
+ name_elem = warehouse.find('Name')
122
+ stock_elem = warehouse.find('Stock')
123
+
124
+ if name_elem is not None and stock_elem is not None:
125
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
126
+ try:
127
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
128
+ if stock_count > 0:
129
+ # Aynı mağaza için stokları topla
130
+ if warehouse_name in warehouse_stock_map:
131
+ warehouse_stock_map[warehouse_name] += stock_count
132
+ else:
133
+ warehouse_stock_map[warehouse_name] = stock_count
134
+ except (ValueError, TypeError):
135
+ pass
136
+
137
+ if warehouse_stock_map:
138
+ # Mağaza stoklarını liste halinde döndür
139
+ all_warehouse_info = []
140
+ for warehouse_name, total_stock in warehouse_stock_map.items():
141
+ all_warehouse_info.append(f"{warehouse_name}: {total_stock} adet")
142
+ return all_warehouse_info
143
+ else:
144
+ return ["Hiçbir mağazada stokta bulunmuyor"]
145
+
146
+ except Exception as e:
147
+ print(f"Mağaza stok bilgisi çekme hatası: {e}")
148
+ return None
149
+
150
+ if __name__ == "__main__":
151
+ test_cases = [
152
+ "M Turuncu",
153
+ "Marlin 6 M Turuncu",
154
+ "L Siyah"
155
+ ]
156
+
157
+ for test_case in test_cases:
158
+ print(f"\n=== Testing: {test_case} ===")
159
+ result = get_warehouse_stock(test_case)
160
+ if result:
161
+ print("Sonuç:")
162
+ for item in result:
163
+ print(f" • {item}")
164
+ else:
165
+ print("Sonuç bulunamadı")
166
+ print("-" * 50)
test_variant.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import requests
3
+ import xml.etree.ElementTree as ET
4
+
5
+ def test_variant_search(product_name):
6
+ """B2B API'den variant field'ı kontrol et"""
7
+ try:
8
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
9
+ response = requests.get(warehouse_url, verify=False, timeout=15)
10
+
11
+ if response.status_code != 200:
12
+ return None
13
+
14
+ root = ET.fromstring(response.content)
15
+
16
+ # Turkish character normalization function
17
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
18
+
19
+ def normalize_turkish(text):
20
+ import unicodedata
21
+ text = unicodedata.normalize('NFD', text)
22
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
23
+ for tr_char, en_char in turkish_map.items():
24
+ text = text.replace(tr_char, en_char)
25
+ return text
26
+
27
+ # Normalize search product name
28
+ search_name = normalize_turkish(product_name.lower().strip())
29
+ search_words = search_name.split()
30
+
31
+ print(f"DEBUG: Aranan: '{product_name}' -> normalize: '{search_name}' -> kelimeler: {search_words}")
32
+
33
+ variant_matches = []
34
+
35
+ # Check variant field for M-TURUNCU like patterns
36
+ for product in root.findall('Product'):
37
+ product_name_elem = product.find('ProductName')
38
+ variant_elem = product.find('Variant')
39
+
40
+ if product_name_elem is not None and product_name_elem.text:
41
+ xml_product_name = product_name_elem.text.strip()
42
+
43
+ # Check variant field
44
+ if variant_elem is not None and variant_elem.text:
45
+ variant_text = variant_elem.text.strip()
46
+ variant_normalized = normalize_turkish(variant_text.lower().replace('-', ' '))
47
+
48
+ # Check if all search words are in variant field
49
+ if all(word in variant_normalized for word in search_words):
50
+ # Check for stock
51
+ warehouses = product.find('Warehouses')
52
+ stock_info = []
53
+ if warehouses is not None:
54
+ for warehouse in warehouses.findall('Warehouse'):
55
+ name_elem = warehouse.find('Name')
56
+ stock_elem = warehouse.find('Stock')
57
+
58
+ if name_elem is not None and stock_elem is not None:
59
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
60
+ try:
61
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
62
+ if stock_count > 0:
63
+ stock_info.append(f"{warehouse_name}: {stock_count}")
64
+ except (ValueError, TypeError):
65
+ pass
66
+
67
+ variant_matches.append({
68
+ 'product_name': xml_product_name,
69
+ 'variant': variant_text,
70
+ 'variant_normalized': variant_normalized,
71
+ 'stock_info': stock_info
72
+ })
73
+
74
+ print(f"DEBUG: VARIANT MATCH - {xml_product_name}")
75
+ print(f" Variant: {variant_text} -> {variant_normalized}")
76
+ if stock_info:
77
+ print(f" Stok: {', '.join(stock_info)}")
78
+ else:
79
+ print(f" Stokta yok")
80
+
81
+ return variant_matches
82
+
83
+ except Exception as e:
84
+ print(f"Hata: {e}")
85
+ return None
86
+
87
+ if __name__ == "__main__":
88
+ # Test different cases
89
+ test_cases = [
90
+ "M Turuncu",
91
+ "m turuncu",
92
+ "L Siyah",
93
+ "S Beyaz"
94
+ ]
95
+
96
+ for test_case in test_cases:
97
+ print(f"\n=== Testing: {test_case} ===")
98
+ result = test_variant_search(test_case)
99
+
100
+ if result:
101
+ print(f"Toplam {len(result)} variant match bulundu:")
102
+ for i, match in enumerate(result, 1):
103
+ print(f"{i}. {match['product_name']} - {match['variant']}")
104
+ if match['stock_info']:
105
+ print(f" Stokta: {', '.join(match['stock_info'])}")
106
+ else:
107
+ print(f" Stokta değil")
108
+ else:
109
+ print("Variant match bulunamadı")
110
+ print("-" * 50)
test_warehouse.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import requests
3
+ import xml.etree.ElementTree as ET
4
+
5
+ def get_warehouse_stock(product_name):
6
+ """B2B API'den mağaza stok bilgilerini çek - İyileştirilmiş versiyon"""
7
+ try:
8
+ import re
9
+ warehouse_url = 'https://video.trek-turkey.com/bizimhesap-warehouse-xml.php'
10
+ response = requests.get(warehouse_url, verify=False, timeout=15)
11
+
12
+ if response.status_code != 200:
13
+ return None
14
+
15
+ root = ET.fromstring(response.content)
16
+
17
+ # Turkish character normalization function
18
+ turkish_map = {'ı': 'i', 'ğ': 'g', 'ü': 'u', 'ş': 's', 'ö': 'o', 'ç': 'c', 'İ': 'i', 'I': 'i'}
19
+
20
+ def normalize_turkish(text):
21
+ import unicodedata
22
+ text = unicodedata.normalize('NFD', text)
23
+ text = ''.join(char for char in text if unicodedata.category(char) != 'Mn')
24
+ for tr_char, en_char in turkish_map.items():
25
+ text = text.replace(tr_char, en_char)
26
+ return text
27
+
28
+ # Normalize search product name
29
+ search_name = normalize_turkish(product_name.lower().strip())
30
+ search_name = search_name.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
31
+ search_words = search_name.split()
32
+
33
+ print(f"DEBUG: Aranan ürün: '{product_name}' -> normalize: '{search_name}' -> kelimeler: {search_words}")
34
+
35
+ best_matches = []
36
+ exact_matches = []
37
+
38
+ # İlk geçiş: Tam eşleşmeleri bul
39
+ for product in root.findall('Product'):
40
+ product_name_elem = product.find('ProductName')
41
+ if product_name_elem is not None and product_name_elem.text:
42
+ xml_product_name = product_name_elem.text.strip()
43
+ normalized_xml = normalize_turkish(xml_product_name.lower())
44
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
45
+ xml_words = normalized_xml.split()
46
+
47
+ # Tam eşleşme kontrolü - ilk iki kelime tam aynı olmalı
48
+ if len(search_words) >= 2 and len(xml_words) >= 2:
49
+ search_key = f"{search_words[0]} {search_words[1]}"
50
+ xml_key = f"{xml_words[0]} {xml_words[1]}"
51
+
52
+ if search_key == xml_key:
53
+ exact_matches.append((product, xml_product_name, normalized_xml))
54
+ print(f"DEBUG: TAM EŞLEŞME bulundu: '{xml_product_name}'")
55
+
56
+ # Eğer tam eşleşme varsa, sadece onları kullan
57
+ candidates = exact_matches if exact_matches else []
58
+
59
+ # Eğer tam eşleşme yoksa, fuzzy matching yap
60
+ if not candidates:
61
+ print("DEBUG: Tam eşleşme yok, fuzzy matching yapılıyor...")
62
+ for product in root.findall('Product'):
63
+ product_name_elem = product.find('ProductName')
64
+ if product_name_elem is not None and product_name_elem.text:
65
+ xml_product_name = product_name_elem.text.strip()
66
+ normalized_xml = normalize_turkish(xml_product_name.lower())
67
+ normalized_xml = normalized_xml.replace('(2026)', '').replace('(2025)', '').replace(' gen 3', '').replace(' gen', '').strip()
68
+ xml_words = normalized_xml.split()
69
+
70
+ # Ortak kelime sayısını hesapla
71
+ common_words = set(search_words) & set(xml_words)
72
+
73
+ # En az 2 ortak kelime olmalı VE ilk kelime aynı olmalı (marka kontrolü)
74
+ if (len(common_words) >= 2 and
75
+ len(search_words) > 0 and len(xml_words) > 0 and
76
+ search_words[0] == xml_words[0]):
77
+ best_matches.append((product, xml_product_name, normalized_xml, len(common_words)))
78
+ print(f"DEBUG: FUZZY EŞLEŞME: '{xml_product_name}' (ortak: {len(common_words)})")
79
+
80
+ # En çok ortak kelimeye sahip olanları seç
81
+ if best_matches:
82
+ max_common = max(match[3] for match in best_matches)
83
+ candidates = [(match[0], match[1], match[2]) for match in best_matches if match[3] == max_common]
84
+
85
+ print(f"DEBUG: Toplam {len(candidates)} aday ürün bulundu")
86
+
87
+ # Stok bilgilerini topla ve tekrarları önle
88
+ warehouse_stock_map = {} # warehouse_name -> total_stock
89
+
90
+ for product, xml_name, _ in candidates:
91
+ warehouses = product.find('Warehouses')
92
+ if warehouses is not None:
93
+ for warehouse in warehouses.findall('Warehouse'):
94
+ name_elem = warehouse.find('Name')
95
+ stock_elem = warehouse.find('Stock')
96
+
97
+ if name_elem is not None and stock_elem is not None:
98
+ warehouse_name = name_elem.text if name_elem.text else "Bilinmeyen"
99
+ try:
100
+ stock_count = int(stock_elem.text) if stock_elem.text else 0
101
+ if stock_count > 0:
102
+ # Aynı mağaza için stokları topla
103
+ if warehouse_name in warehouse_stock_map:
104
+ warehouse_stock_map[warehouse_name] += stock_count
105
+ else:
106
+ warehouse_stock_map[warehouse_name] = stock_count
107
+ print(f"DEBUG: STOK BULUNDU - {warehouse_name}: {stock_count} adet ({xml_name})")
108
+ except (ValueError, TypeError):
109
+ pass
110
+
111
+ if warehouse_stock_map:
112
+ # Mağaza stoklarını liste halinde döndür
113
+ all_warehouse_info = []
114
+ for warehouse_name, total_stock in warehouse_stock_map.items():
115
+ all_warehouse_info.append(f"{warehouse_name}: {total_stock} adet")
116
+ return all_warehouse_info
117
+ else:
118
+ print("DEBUG: Hiçbir mağazada stok bulunamadı")
119
+ return ["Hiçbir mağazada stokta bulunmuyor"]
120
+
121
+ except Exception as e:
122
+ print(f"Mağaza stok bilgisi çekme hatası: {e}")
123
+ return None
124
+
125
+ if __name__ == "__main__":
126
+ # Test the function with different inputs
127
+ test_cases = [
128
+ "MARLIN 6 (2026)",
129
+ "Marlin 6"
130
+ ]
131
+
132
+ for test_case in test_cases:
133
+ print(f"=== Testing: {test_case} ===")
134
+ result = get_warehouse_stock(test_case)
135
+ print(f"Result: {result}")
136
+ print()