diff --git a/pos/blueprints/chat_bp.py b/pos/blueprints/chat_bp.py index 393ad25..0272bae 100644 --- a/pos/blueprints/chat_bp.py +++ b/pos/blueprints/chat_bp.py @@ -60,29 +60,39 @@ def chat(): effective_query = part_words if effective_query and tenant: - # First: search local inventory - try: - local_results = _search_local_inventory(tenant, effective_query, search_query or '', branch_id) - if local_results: - search_results.extend(local_results) - except Exception: - pass + # Support multiple search queries separated by | (for quotes/cotizaciones) + query_terms = [q.strip() for q in effective_query.split('|') if q.strip()] + seen_part_numbers = set() - # Then: search TecDoc catalog - if master: + for qt in query_terms: + # First: search local inventory try: - catalog_results = catalog_service.smart_search( - master, effective_query, tenant, branch_id, limit=10 - ) - if catalog_results: - # Mark as catalog results and avoid duplicates - local_parts = {r.get('part_number', '') for r in search_results} - for cr in catalog_results: - if cr.get('oem_part_number', '') not in local_parts: - cr['source'] = 'catalog' - search_results.append(cr) + local_results = _search_local_inventory(tenant, qt, qt, branch_id) + if local_results: + for lr in local_results: + pn = lr.get('part_number', '') + if pn not in seen_part_numbers: + seen_part_numbers.add(pn) + search_results.append(lr) except Exception: - pass # search failure is non-fatal + pass + + # Then: search TecDoc catalog + if master: + try: + per_query_limit = max(3, 10 // len(query_terms)) + catalog_results = catalog_service.smart_search( + master, qt, tenant, branch_id, limit=per_query_limit + ) + if catalog_results: + for cr in catalog_results: + pn = cr.get('oem_part_number', '') + if pn not in seen_part_numbers: + seen_part_numbers.add(pn) + cr['source'] = 'catalog' + search_results.append(cr) + except Exception: + pass # search failure is non-fatal except Exception: pass # DB failure is non-fatal for chat diff --git a/pos/services/ai_chat.py b/pos/services/ai_chat.py index c8914c4..2e1bd88 100644 --- a/pos/services/ai_chat.py +++ b/pos/services/ai_chat.py @@ -49,6 +49,43 @@ Reglas OBLIGATORIAS: 4. Nombres mexicanos: Tsuru = TSURU, Aveo = AVEO, Jetta = JETTA, Pointer = POINTER, Chevy = CORSA, Vocho = BEETLE. 5. No preguntes mas info si ya puedes buscar. Si el usuario dice "balatas para Tsuru 2015", busca directo. 6. "message" es breve y directo: "Buscando balatas para Nissan Tsuru 2015..." + +Cuando el usuario describe un SINTOMA del vehiculo (no una parte especifica), diagnostica el problema y sugiere las partes que podrian necesitar reemplazo. + +Ejemplos de sintomas: +- "el carro vibra al frenar" → Discos de freno y/o balatas desgastadas. search_query: "Brake Disc" +- "se calienta el motor" → Termostato, bomba de agua, radiador. search_query: "Thermostat" +- "hace ruido al dar vuelta" → Juntas homocineticas. search_query: "CV Joint" +- "no arranca" → Bateria, alternador, motor de arranque. search_query: "Starter Motor" +- "gasta mucha gasolina" → Filtro de aire, bujias, inyectores. search_query: "Air Filter" +- "huele a gasolina" → Inyectores, bomba de gasolina, mangueras. search_query: "Fuel Pump" +- "se jala a un lado" → Terminales de direccion, rotulas, alineacion. search_query: "Tie Rod End" +- "hace ruido al arrancar" → Banda serpentina, tensor, marcha. search_query: "Serpentine Belt" +- "pierde aceite" → Junta de tapa de valvulas, empaques. search_query: "Gasket" +- "el aire no enfria" → Compresor de AC, gas refrigerante. search_query: "A/C Compressor" + +Si detectas un sintoma, responde con: +1. Diagnostico probable +2. Lista de partes que podrian necesitar reemplazo (en orden de probabilidad) +3. search_query con la parte mas probable + +Cuando el usuario pida una COTIZACION o diga "cotizame", "cuanto cuesta", "precio de": +1. Identifica TODAS las partes necesarias para el trabajo completo +2. Devuelve multiples search_queries separadas por | + +Ejemplo: "cotizame frenos completos para Corolla 2020" +search_query: "Brake Pad|Brake Disc|Brake Fluid|Brake Hose" + +Ejemplo: "servicio completo para Tsuru 2015" +search_query: "Oil Filter|Air Filter|Spark Plug|Coolant|Brake Fluid" + +Ejemplo: "kit de distribucion para Jetta 2018" +search_query: "Timing Belt|Tensioner|Idler Pulley|Water Pump" + +Detecta el idioma del usuario y responde en el mismo idioma. +Si escribe en ingles, responde en ingles. +Si escribe en espanol, responde en espanol. +El search_query SIEMPRE debe ser en ingles (el catalogo TecDoc esta en ingles). """ diff --git a/pos/static/css/chat.css b/pos/static/css/chat.css index a0ced4f..ec6a47e 100644 --- a/pos/static/css/chat.css +++ b/pos/static/css/chat.css @@ -268,6 +268,35 @@ .chat-send-btn:hover { background: var(--color-primary-hover, #e5952f); } .chat-send-btn:disabled { opacity: 0.5; cursor: not-allowed; } +/* ─── Camera Button (Photo identification) ─── */ + +.chat-cam-btn { + width: 38px; + height: 38px; + border-radius: var(--radius-md); + border: 1px solid var(--color-border); + background: var(--color-bg-base); + color: var(--color-text-secondary); + font-size: 1.1rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + transition: background var(--duration-fast) var(--ease-in-out), + color var(--duration-fast) var(--ease-in-out), + border-color var(--duration-fast) var(--ease-in-out); +} + +.chat-cam-btn:hover { + border-color: var(--color-accent); + color: var(--color-accent); +} + +.chat-msg-image img { + border: 1px solid var(--color-border); +} + /* ─── Mic Button (Voice Input) ─── */ .chat-mic-btn { diff --git a/pos/static/js/chat.js b/pos/static/js/chat.js index de3f72c..bb6463c 100644 --- a/pos/static/js/chat.js +++ b/pos/static/js/chat.js @@ -39,6 +39,8 @@