Agrega verificación de stock para ventas de kits múltiples

- Nueva tool verificar_stock_kit() para calcular cuántos kits se pueden armar
- Nueva función db_verificar_stock_kit() que verifica stock de todos los productos
- Calcula kits_posibles basado en el producto con menor stock relativo
- Actualiza skill armar_kits.md con proceso de verificación obligatoria
- Ahora advierte antes de vender: 'Solo podés armar X kits, pediste Y'
- Prevents ventas parciales no deseadas de kits
This commit is contained in:
Renato
2026-02-15 22:48:48 +01:00
parent bd355d39fa
commit 53b632c07c
2 changed files with 154 additions and 0 deletions

View File

@@ -329,6 +329,89 @@ def db_confirmar_venta_kit(items: list) -> dict:
}
def db_verificar_stock_kit(items: list, cantidad_kits: int) -> dict:
"""Verifica si hay stock suficiente para armar N kits completos"""
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
productos_info = []
kits_posibles = float("inf")
faltantes = []
for item in items:
producto_nombre = item.get("producto_nombre", "")
cantidad_por_kit = item.get("cantidad", 1)
query_normalized = normalize_text(producto_nombre.lower())
search_term = f"%{query_normalized}%"
cursor.execute(
"""
SELECT nombre, stock FROM productos
WHERE activo = 1 AND (
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(LOWER(nombre), 'á', 'a'), 'é', 'e'), 'í', 'i'), 'ó', 'o'), 'ú', 'u') LIKE ?
)
LIMIT 1
""",
(search_term,),
)
producto = cursor.fetchone()
if not producto:
faltantes.append(f"Producto no encontrado: {producto_nombre}")
continue
stock_disponible = producto["stock"]
kits_con_este_producto = stock_disponible // cantidad_por_kit
productos_info.append(
{
"nombre": producto["nombre"],
"stock": stock_disponible,
"cantidad_por_kit": cantidad_por_kit,
"kits_posibles": kits_con_este_producto,
}
)
# El límite es el producto con menos kits posibles
if kits_con_este_producto < kits_posibles:
kits_posibles = kits_con_este_producto
conn.close()
# Si no hay productos válidos
if not productos_info:
return {
"puede_vender": False,
"kits_solicitados": cantidad_kits,
"kits_posibles": 0,
"mensaje": "No se encontraron los productos del kit",
"detalles": faltantes,
}
# Si puede vender todos los kits solicitados
if kits_posibles >= cantidad_kits:
return {
"puede_vender": True,
"kits_solicitados": cantidad_kits,
"kits_posibles": cantidad_kits,
"mensaje": f"✅ Stock suficiente para {cantidad_kits} kits",
"productos": productos_info,
}
# Si no alcanza el stock
return {
"puede_vender": False,
"kits_solicitados": cantidad_kits,
"kits_posibles": kits_posibles,
"mensaje": f"⚠️ Solo podés armar {kits_posibles} kits completos (pediste {cantidad_kits})",
"productos": productos_info,
"sugerencia": f"Con el stock actual solo alcanza para {kits_posibles} kits. ¿Vendés {kits_posibles} o preferís ver otros productos?",
}
async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[str]:
"""Send message to Anthropic API with tools"""
@@ -402,6 +485,38 @@ async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[s
"required": ["items"],
},
},
{
"name": "verificar_stock_kit",
"description": "Verifica si hay stock suficiente para armar N kits completos ANTES de vender. Usar SIEMPRE cuando el usuario quiera vender múltiples kits para calcular cuántos se pueden armar con el stock actual.",
"input_schema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Lista de productos que componen un kit",
"items": {
"type": "object",
"properties": {
"producto_nombre": {
"type": "string",
"description": "Nombre del producto",
},
"cantidad": {
"type": "integer",
"description": "Cantidad que lleva el kit de este producto",
},
},
"required": ["producto_nombre", "cantidad"],
},
},
"cantidad_kits": {
"type": "integer",
"description": "Cantidad de kits que quiere vender",
},
},
"required": ["items", "cantidad_kits"],
},
},
]
messages = [{"role": "user", "content": message}]
@@ -497,6 +612,17 @@ async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[s
"content": json.dumps(resultado),
}
)
elif tool_name == "verificar_stock_kit":
items = tool_input.get("items", [])
cantidad_kits = tool_input.get("cantidad_kits", 1)
resultado = db_verificar_stock_kit(items, cantidad_kits)
tool_results.append(
{
"type": "tool_result",
"tool_use_id": tool_call.get("id"),
"content": json.dumps(resultado),
}
)
# Agregar el tool use y los resultados a los mensajes
messages.append({"role": "assistant", "content": json.dumps(content)})

View File

@@ -37,11 +37,39 @@ Formato de presentación:
## Venta de Kits
### VERIFICACIÓN CRÍTICA - Antes de Vender Múltiples Kits
**SIEMPRE** verificar stock antes de confirmar venta de múltiples kits.
**Proceso:**
1. Usar `verificar_stock_kit` con:
- `items`: Lista de productos del kit
- `cantidad_kits`: Cuántos kits quiere vender
2. Si `puede_vender: true` → Proceder con `confirmar_venta_kit`
3. Si `puede_vender: false` → Informar límite y preguntar si vende esa cantidad
**Ejemplo:**
Usuario: "Se vendieron 10 kits"
Bot: [USAR verificar_stock_kit(items=[...], cantidad_kits=10)]
Si alcanza:
"✅ Tenés stock para 10 kits. ¿Confirmamos la venta?"
Si no alcanza (solo hay para 7):
"⚠️ Solo podés armar 7 kits completos con el stock actual.
¿Vendemos 7 kits o preferís ver otros productos?"
### Confirmación de Venta de Kit
Cuando el usuario diga "se vendió el kit", "concretamos", "dale, lo lleva", etc:
**Si es UN solo kit:**
**Acción:** Usar `confirmar_venta_kit` con TODOS los productos del kit.
**Si son MÚLTIPLES kits:**
**Acción:**
1. PRIMERO `verificar_stock_kit` para verificar cuántos se pueden armar
2. LUEGO `confirmar_venta_kit` SOLO si hay stock suficiente
**Ejemplo:**
Usuario: "Se vendió el kit de 15mil"
Bot: [USAR confirmar_venta_kit con items=[