{
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "consultar_inventario",
          "description": "Obtiene el inventario en tiempo real. Soporta filtros opcionales.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega": {
                "type": "INTEGER",
                "description": "ID de la bodega. Ejemplo: 1"
              },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a filtrar. Ejemplo: [1, 2]. Si se especifica, filtra por estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "codigo": {
                "type": "STRING",
                "description": "Código de producto."
              },
              "nombre": {
                "type": "STRING",
                "description": "Fragmento del nombre del producto a buscar."
              },
              "limit": {
                "type": "INTEGER",
                "description": "Limita la cantidad de registros devueltos. Útil para no saturar memoria."
              },
              "modificado_hoy": {
                "type": "INTEGER",
                "description": "Si es 1, filtra únicamente los productos con movimientos de venta o entrada en el día de hoy."
              },
              "desde_fecha": {
                "type": "STRING",
                "description": "Filtra productos con movimientos a partir de esta fecha u hora (YYYY-MM-DD HH:MM:SS)."
              }
            }
          }
        },
        {
          "name": "consultar_inventario_cambios",
          "description": "Obtiene únicamente los productos del inventario que tuvieron ventas o entradas durante el día (o desde una fecha). Altamente optimizado.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega": {
                "type": "INTEGER",
                "description": "ID de la bodega a consultar."
              },
              "modificado_hoy": {
                "type": "INTEGER",
                "description": "Si es 1, filtra productos con movimiento de hoy."
              },
              "desde_fecha": {
                "type": "STRING",
                "description": "Fecha u hora inicial YYYY-MM-DD HH:MM:SS."
              }
            }
          }
        },
        {
          "name": "consultar_ventas",
          "description": "Devuelve las métricas principales de negocio (KPIs, totales de dinero, costos, utilidad, ventas por bodega, categoría y marca) en un periodo. USA ESTA HERRAMIENTA si el usuario quiere ver métricas monetarias.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "fi": {
                "type": "STRING",
                "description": "Fecha inicial YYYY-MM-DD."
              },
              "ff": {
                "type": "STRING",
                "description": "Fecha final YYYY-MM-DD."
              },
              "bodega": {
                "type": "INTEGER",
                "description": "Filtrar ventas por una bodega específica (ID)."
              },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a filtrar. Ejemplo: [1, 2]. Si se especifica, filtra por estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "categoria": {
                "type": "STRING",
                "description": "Filtrar por nombre de categoría exacta (ej. 'Analgesicos')."
              },
              "marca": {
                "type": "STRING",
                "description": "Filtrar por nombre de marca exacta (ej. 'Mk')."
              },
              "producto": {
                "type": "STRING",
                "description": "Filtrar por nombre específico de un producto."
              }
            }
          }
        },
        {
          "name": "consultar_rotacion",
          "description": "Obtiene los productos con más movimiento en UNIDADES FÍSICAS (calculando ventas netas). Devuelve la rotación global y desglose por bodega. REGLA: Usa limit=60 y page para paginar. IMPORTANTE: En tu respuesta usa SIEMPRE el 'nombre_bodega' y no el ID o 'Bodega 1'.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega": {
                "type": "INTEGER",
                "description": "Filtrar por una bodega específica."
              },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a filtrar. Ejemplo: [1, 2]. Si se especifica, filtra por estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "codigo": {
                "type": "STRING",
                "description": "Filtrar por un código de producto específico."
              },
              "nombre": {
                "type": "STRING",
                "description": "Filtrar por nombre, marca o categoría del producto."
              },
              "fecha_inicio": {
                "type": "STRING",
                "description": "Fecha de inicio YYYY-MM-DD."
              },
              "fecha_fin": {
                "type": "STRING",
                "description": "Fecha de fin YYYY-MM-DD."
              },
              "limit": {
                "type": "INTEGER",
                "description": "Limita la cantidad de registros. Por defecto 60."
              },
              "page": {
                "type": "INTEGER",
                "description": "Número de página a consultar. Por defecto 1."
              }
            }
          }
        },
        {
          "name": "analizar_y_sugerir_traslados",
          "description": "HERRAMIENTA OBLIGATORIA Y ÚNICA para sugerir traslados de bodega. Si el usuario pregunta 'qué puedo trasladar' o 'sugiere traslados', DEBES llamar a esta herramienta inmediatamente sin escribir texto antes. NO uses consultar_rotacion para esto.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega_origen": { "type": "INTEGER", "description": "Filtro opcional. ID de la bodega desde donde va a salir la mercancía (donante)." },
              "bodega_destino": { "type": "INTEGER", "description": "Filtro opcional. ID de la bodega hacia donde debe entrar la mercancía (receptor)." },
              "bodegas_destino": {
                "type": "ARRAY",
                "description": "IDs opcionales de bodegas destino (receptores). Ejemplo: [5, 7]. Si se especifica, calcula traslados solo hacia estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "codigo": { "type": "STRING", "description": "Filtro opcional por código de producto." },
              "nombre": { "type": "STRING", "description": "Filtro opcional por nombre, marca o categoría." },
              "fecha_inicio": { "type": "STRING", "description": "Fecha de inicio YYYY-MM-DD." },
              "fecha_fin": { "type": "STRING", "description": "Fecha de fin YYYY-MM-DD." },
              "dias_provision": { "type": "INTEGER", "description": "Días de provisión (cobertura) para el cálculo de stock mínimo. Por defecto 7. NO confundir con el periodo de rotación (ventas pasadas)." },
              "conservar_minimo": { "type": "BOOLEAN", "description": "Si es true, garantiza que la bodega de origen conserve al menos 1 caja/unidad de cada producto (evitando dejar la bodega en cero si el producto no tiene ventas)." }
            }
          }
        },
        {
          "name": "crear_traslado",
          "description": "Mueve productos de UNA bodega_salida a UNA bodega_entrada (una sola ruta). ÚSALA solo si hay UNA ruta. Si hay más de una ruta, usa crear_traslados_lote. REGLAS: 1) Agrupa TODOS los productos de esa ruta en UN SOLO llamado. 2) INMEDIATAMENTE después, ejecuta finalizar_traslado con la misma bodega_salida.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega_salida": {
                "type": "INTEGER",
                "description": "ID de la bodega origen"
              },
              "bodega_entrada": {
                "type": "INTEGER",
                "description": "ID de la bodega destino"
              },
              "productos": {
                "type": "ARRAY",
                "description": "Lista de productos a trasladar",
                "items": {
                  "type": "OBJECT",
                  "properties": {
                    "codigo": { "type": "STRING", "description": "Código de producto" },
                    "caja": { "type": "NUMBER", "description": "Cantidad de cajas enteras a trasladar" },
                    "frcc": { "type": "NUMBER", "description": "Cantidad de fracciones (unidades sueltas) a trasladar. IMPORTANTE: Si el producto no maneja fracciones (campo 'factor' es 0 o no tiene), este valor DEBE ser 0 estrictamente." }
                  },
                  "required": ["codigo", "caja", "frcc"]
                }
              }
            },
            "required": ["bodega_salida", "bodega_entrada", "productos"]
          }
        },
        {
          "name": "finalizar_traslado",
          "description": "OBLIGATORIO: Cierra y guarda permanentemente el traslado en la base de datos. DEBES ejecutar esta herramienta INMEDIATAMENTE después de CADA llamado exitoso a crear_traslado. NUNCA dejes un traslado abierto sin cerrar.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega_salida": {
                "type": "INTEGER",
                "description": "ID de la bodega origen desde donde se estaba trasladando"
              }
            },
            "required": ["bodega_salida"]
          }
        },
        {
          "name": "crear_traslados_lote",
          "description": "Crea MÚLTIPLES traslados en un SOLO llamado. ÚSALA cuando hay más de una ruta origen→destino. Incluye TODAS las rutas en el array 'traslados'. Internamente crea y cierra cada traslado automáticamente. NO uses crear_traslado+finalizar_traslado repetidamente si hay más de una ruta.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "traslados": {
                "type": "ARRAY",
                "description": "Lista de rutas de traslado a ejecutar",
                "items": {
                  "type": "OBJECT",
                  "properties": {
                    "bodega_salida":  { "type": "INTEGER", "description": "ID de la bodega origen" },
                    "bodega_entrada": { "type": "INTEGER", "description": "ID de la bodega destino" },
                    "productos": {
                      "type": "ARRAY",
                      "description": "Productos a trasladar en esta ruta",
                      "items": {
                        "type": "OBJECT",
                        "properties": {
                          "codigo": { "type": "STRING", "description": "Código de producto" },
                          "caja":   { "type": "NUMBER", "description": "Cantidad de cajas enteras a trasladar" },
                          "frcc":   { "type": "NUMBER", "description": "Cantidad de fracciones (unidades sueltas) a trasladar. IMPORTANTE: Si el producto no maneja fracciones (campo 'factor' es 0 o no tiene), este valor DEBE ser 0 estrictamente." }
                        },
                        "required": ["codigo", "caja", "frcc"]
                      }
                    }
                  },
                  "required": ["bodega_salida", "bodega_entrada", "productos"]
                }
              }
            },
            "required": ["traslados"]
          }
        },
        {
          "name": "ejecutar_sugeridos_lote",
          "description": "Calcula y ejecuta TODOS los traslados sugeridos automáticamente desde el backend en un solo paso. ÚSALO SIEMPRE cuando el usuario te pida ejecutar o confirmar los traslados sugeridos. Esto evita tener que construir un JSON gigante de productos en el chat, ahorrando tokens y previniendo errores de límite. Soporta omisiones automáticas.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega_origen": { "type": "INTEGER", "description": "Filtro. ID de la bodega de salida (donante)." },
              "bodega_destino": { "type": "INTEGER", "description": "Filtro. ID de la bodega de entrada (destino)." },
              "bodegas_destino": {
                "type": "ARRAY",
                "description": "IDs opcionales de bodegas destino (receptores). Ejemplo: [5, 7]. Si se especifica, ejecuta traslados solo hacia estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "dias_provision": { "type": "INTEGER", "description": "Días de provisión (cobertura) a considerar en las sugerencias (por defecto 7). NO confundir con el periodo de rotación (ventas pasadas)." },
              "fecha_inicio": { "type": "STRING", "description": "Fecha de inicio YYYY-MM-DD. Opcional (por defecto hace 30 días)." },
              "fecha_fin": { "type": "STRING", "description": "Fecha de fin YYYY-MM-DD. Opcional (por defecto hoy)." },
              "omitir_productos": {
                "type": "ARRAY",
                "description": "Lista de marcas, nombres o categorías a omitir de los traslados (ej. ['helados', 'gaseosas', 'Mk']).",
                "items": { "type": "STRING" }
              },
              "conservar_minimo": {
                "type": "BOOLEAN",
                "description": "Si es true, garantiza que la bodega de origen conserve al menos 1 caja/unidad de cada producto (evitando dejar la bodega en cero si el producto no tiene ventas)."
              }
            }
          }
        },
        {
          "name": "analizar_y_sugerir_compras",
          "description": "Calcula y sugiere la compra de productos a proveedores externos basándose en las ventas (rotación) de un período e inventario actual. Muestra las cantidades sugeridas y el último proveedor de cada producto.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega": { "type": "INTEGER", "description": "Filtro opcional. ID de la bodega a analizar. Si se omite, analiza todas las bodegas." },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a analizar. Ejemplo: [1, 3]. Si se especifica, se analizan solo estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "dias_provision": { "type": "INTEGER", "description": "Días de provisión (cobertura) a considerar en las sugerencias (por defecto 15)." },
              "fecha_inicio": { "type": "STRING", "description": "Fecha de inicio YYYY-MM-DD. Opcional (por defecto hace 30 días)." },
              "fecha_fin": { "type": "STRING", "description": "Fecha de fin YYYY-MM-DD. Opcional (por defecto hoy)." },
              "nombre": { "type": "STRING", "description": "Filtro opcional por nombre, marca o categoría del producto." },
              "codigo": { "type": "STRING", "description": "Filtro opcional por código de producto." },
              "omitir_productos": {
                "type": "ARRAY",
                "description": "Lista de marcas, nombres o categorías a omitir de las sugerencias (ej. ['helados', 'gaseosas', 'Mk']).",
                "items": { "type": "STRING" }
              }
            }
          }
        },
        {
          "name": "exportar_compras_excel",
          "description": "Exporta las últimas sugerencias de compra a proveedores generadas en la sesión a un archivo Excel descargable. Úsalo cuando el usuario pida descargar o exportar las sugerencias de compra a Excel.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "alertar_stock_critico",
          "description": "Obtiene los productos activos sin existencias (inventario menor o igual a 0) que registran ventas en un período (rotación), agrupados por bodega.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "bodega": {
                "type": "INTEGER",
                "description": "ID de la bodega a filtrar."
              },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a filtrar. Ejemplo: [1, 2]. Si se especifica, filtra por estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "dias_rotacion": {
                "type": "INTEGER",
                "description": "Número de días de rotación a evaluar. Solo se reportan productos agotados que registraron ventas en este período. Por defecto 60."
              },
              "omitir_productos": {
                "type": "ARRAY",
                "description": "Lista de marcas, nombres o categorías a omitir de las alertas (ej. ['helados', 'Mk']).",
                "items": { "type": "STRING" }
              }
            }
          }
        },
        {
          "name": "exportar_stock_critico_excel",
          "description": "Exporta las últimas alertas de stock crítico (sin existencias) a un archivo Excel descargable. Úsalo cuando el usuario pida descargar o exportar el reporte de stock crítico a Excel.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "obtener_productos_sin_rotacion",
          "description": "Busca productos activos con inventario disponible que no se han vendido en un rango de días determinado (por defecto últimos 60 días).",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "dias_sin_venta": {
                "type": "INTEGER",
                "description": "Número de días sin registrar ventas. Por defecto 60."
              },
              "bodega": {
                "type": "INTEGER",
                "description": "ID de la bodega a filtrar."
              },
              "bodegas": {
                "type": "ARRAY",
                "description": "IDs de bodegas a filtrar. Ejemplo: [1, 2]. Si se especifica, filtra por estas bodegas.",
                "items": { "type": "INTEGER" }
              },
              "omitir_productos": {
                "type": "ARRAY",
                "description": "Lista de marcas, nombres o categorías a omitir del listado.",
                "items": { "type": "STRING" }
              }
            }
          }
        },
        {
          "name": "exportar_sin_rotacion_excel",
          "description": "Exporta el último listado de productos sin rotación ('hueso') a un archivo Excel descargable. Úsalo cuando el usuario pida descargar o exportar el reporte de productos sin rotación a Excel.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "auditar_margenes_ganancia",
          "description": "Audita y detecta productos activos cuyos márgenes de utilidad (basados en CostoCajaP y VentaCajaP) sean negativos (pérdidas) o inferiores a un umbral (por defecto < 10%). Permite auditar una bodega específica y opcionalmente filtrar solo productos que cuenten con inventario disponible.",
          "parameters": {
            "type": "OBJECT",
            "properties": {
              "margen_critico": {
                "type": "NUMBER",
                "description": "Umbral del porcentaje de margen por debajo del cual alertar. Por defecto 10.0."
              },
              "bodega": {
                "type": "INTEGER",
                "description": "ID de la bodega específica para auditar sus costos y precios de inventario particulares."
              },
              "con_inventario": {
                "type": "BOOLEAN",
                "description": "Si es true, sólo audita los productos que tienen inventario disponible (mayor a 0) en la bodega analizada."
              }
            }
          }
        },
        {
          "name": "exportar_margenes_excel",
          "description": "Exporta la última auditoría de márgenes inconsistentes o bajos a un archivo Excel descargable. Úsalo cuando el usuario pida descargar o exportar la auditoría de márgenes a Excel.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "consultar_cartera_y_deudas",
          "description": "Obtiene el consolidado de las cuentas por cobrar a clientes (cartera) y cuentas por pagar a proveedores con saldos vencidos pendientes.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "exportar_cartera_deudas_excel",
          "description": "Exporta el reporte consolidado de cuentas por cobrar (cartera) y por pagar a proveedores a un archivo Excel descargable. Úsalo cuando el usuario pida descargar o exportar las cuentas pendientes a Excel.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        },
        {
          "name": "exportar_compras_txt",
          "description": "Exporta las últimas sugerencias de compra a proveedores generadas en la sesión a un archivo de texto plano (.txt) con la estructura definida (1234 \\t código \\t nombre \\t cantidad). Úsalo cuando el usuario pida descargar o exportar las sugerencias de compra a plano o TXT.",
          "parameters": {
            "type": "OBJECT",
            "properties": {}
          }
        }
      ]
    }
  ]
}
