From 5c81939bbf743d2d509d467fb33625c938d55776 Mon Sep 17 00:00:00 2001 From: Lizandro GD Date: Mon, 13 Jul 2026 18:31:15 +0000 Subject: [PATCH] feat: agente - agregar listar_facturas + campos agente en AI Config create/update Co-Authored-By: Claude Sonnet 4.6 --- pkg/services/telegram_agent_service.go | 31 +++++++++++ rest/controllers/ai_config_controller.go | 70 +++++++++++++----------- 2 files changed, 70 insertions(+), 31 deletions(-) diff --git a/pkg/services/telegram_agent_service.go b/pkg/services/telegram_agent_service.go index ce2acd2..56171a1 100644 --- a/pkg/services/telegram_agent_service.go +++ b/pkg/services/telegram_agent_service.go @@ -130,6 +130,14 @@ func agentTools() []agentTool { "uuid": str("UUID de la aplicación"), }, []string{"config_id", "uuid"})), + // ── Facturas ───────────────────────────────────────────────────────── + tool("listar_facturas", "Lista facturas. Puede filtrar por estado: pendiente, pagada, vencida, cancelada.", + obj(map[string]agentToolParam{ + "page": num("Página (default 1)"), + "search": str("Búsqueda por número, cliente o descripción"), + "estado": agentToolParam{Type: "string", Description: "pendiente | pagada | vencida | cancelada", Enum: []string{"pendiente", "pagada", "vencida", "cancelada", ""}}, + }, nil)), + // ── Clientes ───────────────────────────────────────────────────────── tool("listar_clientes", "Lista clientes con paginación y búsqueda.", obj(map[string]agentToolParam{ @@ -360,6 +368,29 @@ func runTool(name string, a map[string]interface{}) (interface{}, error) { return coolifyAppAction(getInt("config_id", 0), getStr("uuid"), "start") // ── Clientes ─────────────────────────────────────────────────────────── + case "listar_facturas": + page := getInt("page", 1) + search := getStr("search") + estado := getStr("estado") + limit := 10 + offset := (page - 1) * limit + all, total, err := models.GetAllFacturas(limit, offset, search) + if err != nil { + return nil, err + } + // Filtrar por estado si se especificó + items := all + if estado != "" { + items = nil + for _, f := range all { + if f.Estado == estado { + items = append(items, f) + } + } + total = int64(len(items)) + } + return map[string]interface{}{"items": items, "total": total, "page": page}, nil + case "listar_clientes": page := getInt("page", 1) search := getStr("search") diff --git a/rest/controllers/ai_config_controller.go b/rest/controllers/ai_config_controller.go index 19f4f7a..c192681 100644 --- a/rest/controllers/ai_config_controller.go +++ b/rest/controllers/ai_config_controller.go @@ -78,14 +78,16 @@ func GetAiConfigs(c *fiber.Ctx) error { // CreateAiConfigHandler crea una nueva configuración de IA. func CreateAiConfigHandler(c *fiber.Ctx) error { type Req struct { - Nombre string `json:"nombre"` - Provider string `json:"provider"` - ApiKey string `json:"api_key"` - BaseURL string `json:"base_url"` - ModelName string `json:"model_name"` - IsActive bool `json:"is_active"` - Notes string `json:"notes"` - Modulo string `json:"modulo"` + Nombre string `json:"nombre"` + Provider string `json:"provider"` + ApiKey string `json:"api_key"` + BaseURL string `json:"base_url"` + ModelName string `json:"model_name"` + IsActive bool `json:"is_active"` + Notes string `json:"notes"` + Modulo string `json:"modulo"` + EsAgenteBot bool `json:"es_agente_bot"` + TelegramConfigID *uint `json:"telegram_config_id"` } var req Req if err := c.BodyParser(&req); err != nil { @@ -102,14 +104,16 @@ func CreateAiConfigHandler(c *fiber.Ctx) error { } item := models.AiConfig{ - Nombre: strings.TrimSpace(req.Nombre), - Provider: strings.ToLower(strings.TrimSpace(req.Provider)), - ApiKey: strings.TrimSpace(req.ApiKey), - BaseURL: strings.TrimSpace(req.BaseURL), - ModelName: strings.TrimSpace(req.ModelName), - IsActive: req.IsActive, - Notes: req.Notes, - Modulo: models.JoinModulos(strings.Split(req.Modulo, ",")), + Nombre: strings.TrimSpace(req.Nombre), + Provider: strings.ToLower(strings.TrimSpace(req.Provider)), + ApiKey: strings.TrimSpace(req.ApiKey), + BaseURL: strings.TrimSpace(req.BaseURL), + ModelName: strings.TrimSpace(req.ModelName), + IsActive: req.IsActive, + Notes: req.Notes, + Modulo: models.JoinModulos(strings.Split(req.Modulo, ",")), + EsAgenteBot: req.EsAgenteBot, + TelegramConfigID: req.TelegramConfigID, } if err := models.CreateAiConfig(&item); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) @@ -125,14 +129,16 @@ func UpdateAiConfigHandler(c *fiber.Ctx) error { } type Req struct { - Nombre string `json:"nombre"` - Provider string `json:"provider"` - ApiKey string `json:"api_key"` // vacío = no cambiar - BaseURL string `json:"base_url"` - ModelName string `json:"model_name"` - IsActive bool `json:"is_active"` - Notes string `json:"notes"` - Modulo string `json:"modulo"` + Nombre string `json:"nombre"` + Provider string `json:"provider"` + ApiKey string `json:"api_key"` // vacío = no cambiar + BaseURL string `json:"base_url"` + ModelName string `json:"model_name"` + IsActive bool `json:"is_active"` + Notes string `json:"notes"` + Modulo string `json:"modulo"` + EsAgenteBot bool `json:"es_agente_bot"` + TelegramConfigID *uint `json:"telegram_config_id"` } var req Req if err := c.BodyParser(&req); err != nil { @@ -140,13 +146,15 @@ func UpdateAiConfigHandler(c *fiber.Ctx) error { } updates := map[string]interface{}{ - "nombre": strings.TrimSpace(req.Nombre), - "provider": strings.ToLower(strings.TrimSpace(req.Provider)), - "base_url": strings.TrimSpace(req.BaseURL), - "model_name": strings.TrimSpace(req.ModelName), - "is_active": req.IsActive, - "notes": req.Notes, - "modulo": models.JoinModulos(strings.Split(req.Modulo, ",")), + "nombre": strings.TrimSpace(req.Nombre), + "provider": strings.ToLower(strings.TrimSpace(req.Provider)), + "base_url": strings.TrimSpace(req.BaseURL), + "model_name": strings.TrimSpace(req.ModelName), + "is_active": req.IsActive, + "notes": req.Notes, + "modulo": models.JoinModulos(strings.Split(req.Modulo, ",")), + "es_agente_bot": req.EsAgenteBot, + "telegram_config_id": req.TelegramConfigID, } if strings.TrimSpace(req.ApiKey) != "" { updates["api_key"] = strings.TrimSpace(req.ApiKey)