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:
@@ -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)})
|
||||
|
||||
Reference in New Issue
Block a user