Agrega skill y funcionalidad para vender kits completos
- Nueva skill armar_kits.md con lógica completa de kits - Nueva tool confirmar_venta_kit para vender múltiples productos - Función db_confirmar_venta_kit() para procesar ventas en batch - Procesa ventas de kits y actualiza stock de todos los productos - Maneja errores parciales (si falta stock de algún producto) - Presenta resumen completo de venta del kit
This commit is contained in:
@@ -244,6 +244,91 @@ def db_confirmar_venta(producto_nombre: str, cantidad: int) -> dict:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def db_confirmar_venta_kit(items: list) -> dict:
|
||||||
|
"""Registra la venta de múltiples productos (un kit completo)"""
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
resultados = []
|
||||||
|
total_venta = 0
|
||||||
|
errores = []
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
producto_nombre = item.get("producto_nombre", "")
|
||||||
|
cantidad = item.get("cantidad", 1)
|
||||||
|
|
||||||
|
query_normalized = normalize_text(producto_nombre.lower())
|
||||||
|
search_term = f"%{query_normalized}%"
|
||||||
|
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT * 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:
|
||||||
|
errores.append(f"Producto no encontrado: {producto_nombre}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if producto["stock"] < cantidad:
|
||||||
|
errores.append(
|
||||||
|
f"Stock insuficiente para {producto['nombre']}: tenemos {producto['stock']}, pidió {cantidad}"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Registrar venta
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO ventas (producto_id, cantidad, precio_vendido, vendedor)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
""",
|
||||||
|
(producto["id"], cantidad, producto["precio"], "AI Bot"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Actualizar stock
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
UPDATE productos SET stock = stock - ?, updated_at = datetime('now')
|
||||||
|
WHERE id = ?
|
||||||
|
""",
|
||||||
|
(cantidad, producto["id"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
subtotal = cantidad * producto["precio"]
|
||||||
|
total_venta += subtotal
|
||||||
|
|
||||||
|
resultados.append(
|
||||||
|
{
|
||||||
|
"producto": producto["nombre"],
|
||||||
|
"cantidad": cantidad,
|
||||||
|
"precio_unitario": producto["precio"],
|
||||||
|
"subtotal": subtotal,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if errores and not resultados:
|
||||||
|
return {"error": "No se pudo completar la venta", "detalles": errores}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"items_vendidos": len(resultados),
|
||||||
|
"total": total_venta,
|
||||||
|
"productos": resultados,
|
||||||
|
"errores": errores if errores else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[str]:
|
async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[str]:
|
||||||
"""Send message to Anthropic API with tools"""
|
"""Send message to Anthropic API with tools"""
|
||||||
|
|
||||||
@@ -273,7 +358,7 @@ async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[s
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "confirmar_venta",
|
"name": "confirmar_venta",
|
||||||
"description": "Registra una venta y descuenta el stock del inventario. Usar SOLO cuando el usuario confirme explícitamente que se vendió algo.",
|
"description": "Registra la venta de UN solo producto. Usar cuando el usuario confirme que vendió un producto específico.",
|
||||||
"input_schema": {
|
"input_schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -289,6 +374,34 @@ async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[s
|
|||||||
"required": ["producto_nombre", "cantidad"],
|
"required": ["producto_nombre", "cantidad"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "confirmar_venta_kit",
|
||||||
|
"description": "Registra la venta de MÚLTIPLES productos a la vez (un kit completo). Usar cuando el usuario confirme que vendió un kit o varios productos juntos.",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Lista de productos vendidos con sus cantidades",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"producto_nombre": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del producto",
|
||||||
|
},
|
||||||
|
"cantidad": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Cantidad vendida",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["producto_nombre", "cantidad"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["items"],
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
messages = [{"role": "user", "content": message}]
|
messages = [{"role": "user", "content": message}]
|
||||||
@@ -374,6 +487,16 @@ async def chat_with_ai(message: str, session_id: str = "pymesbot") -> Optional[s
|
|||||||
"content": json.dumps(resultado),
|
"content": json.dumps(resultado),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
elif tool_name == "confirmar_venta_kit":
|
||||||
|
items = tool_input.get("items", [])
|
||||||
|
resultado = db_confirmar_venta_kit(items)
|
||||||
|
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
|
# Agregar el tool use y los resultados a los mensajes
|
||||||
messages.append({"role": "assistant", "content": json.dumps(content)})
|
messages.append({"role": "assistant", "content": json.dumps(content)})
|
||||||
|
|||||||
Reference in New Issue
Block a user