feat: automatización de cotizaciones, contratos, actas y cuentas de cobro con IA
Implementa las 4 fases de la especificación de automatización: módulo de plantillas/tarifas editable por el equipo, generación de PDF (HTML+JS vía Chrome headless) para cotizaciones/contratos/arquitecturas/cuentas de cobro, chat propio en el dashboard reutilizando el mismo motor y tools del bot de Telegram, y nuevas tools del agente para crear estos documentos end-to-end. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
772a4a5656
commit
516220a8a1
@@ -104,6 +104,11 @@ func Migrate() {
|
||||
// Tablero de tareas
|
||||
&models.Tarea{},
|
||||
&models.TareaComentario{},
|
||||
// Automatización de cotizaciones, contratos, actas y cuentas de cobro con IA
|
||||
&models.PlantillaDocumento{},
|
||||
&models.Tarifa{},
|
||||
&models.DocumentoGenerado{},
|
||||
&models.Arquitectura{},
|
||||
); err != nil {
|
||||
log.Fatalf("Error during main migration: %v", err)
|
||||
}
|
||||
@@ -150,6 +155,9 @@ func Migrate() {
|
||||
// Agregar submódulo "Partner Recursos" al módulo Portal de Clientes
|
||||
SeedPartnerRecursos()
|
||||
|
||||
// Crear módulo y submódulos de Automatización IA (cotizaciones, contratos, asistente)
|
||||
SeedAutomatizacionIA()
|
||||
|
||||
log.Println("Migration Completed...")
|
||||
}
|
||||
|
||||
@@ -404,6 +412,79 @@ func SeedRenovaciones() {
|
||||
log.Println("[SEED] Seed de Renovaciones completado.")
|
||||
}
|
||||
|
||||
// SeedAutomatizacionIA inserta el módulo "Automatización IA" y sus submódulos
|
||||
// (Asistente, Plantillas de Documento, Tarifas) si no existen, y los asigna al
|
||||
// rol Administrador. Es idempotente.
|
||||
func SeedAutomatizacionIA() {
|
||||
db := app.Http.Database.DB
|
||||
|
||||
// 1. Crear/obtener módulo
|
||||
var modulo models.Modules
|
||||
result := db.Where("title = ?", "Automatización IA").First(&modulo)
|
||||
if result.Error != nil {
|
||||
modulo = models.Modules{
|
||||
Title: "Automatización IA",
|
||||
Description: "Cotizaciones, contratos, actas y cuentas de cobro generados por IA",
|
||||
ModifiedAt: time.Now(),
|
||||
}
|
||||
if err := db.Create(&modulo).Error; err != nil {
|
||||
log.Printf("[SEED] Error creando módulo Automatización IA: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("[SEED] Módulo 'Automatización IA' creado con ID %d", modulo.ID)
|
||||
} else {
|
||||
log.Printf("[SEED] Módulo 'Automatización IA' ya existe (ID %d)", modulo.ID)
|
||||
}
|
||||
|
||||
// 2. Definir submódulos
|
||||
entries := []struct{ title, desc, url string }{
|
||||
{"Asistente", "Chat propio: mismo motor y tools que el bot de Telegram", "/app/asistente"},
|
||||
{"Plantillas de Documento", "Fuente de verdad de cotización, contrato, acta y cuenta de cobro", "/app/automatizacion/plantillas"},
|
||||
{"Tarifas", "Valor por hora, licencias, VMs y márgenes usados al cotizar", "/app/automatizacion/tarifas"},
|
||||
}
|
||||
|
||||
var insertados []models.Submodules
|
||||
for _, e := range entries {
|
||||
var sub models.Submodules
|
||||
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
||||
sub = models.Submodules{
|
||||
Title: e.title,
|
||||
Description: e.desc,
|
||||
Url: e.url,
|
||||
ModuleId: modulo.ID,
|
||||
ModifiedAt: time.Now(),
|
||||
}
|
||||
if err := db.Create(&sub).Error; err != nil {
|
||||
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
||||
continue
|
||||
}
|
||||
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
||||
} else {
|
||||
if sub.ModuleId != modulo.ID {
|
||||
if err := db.Model(&sub).Update("module_id", modulo.ID).Error; err != nil {
|
||||
log.Printf("[SEED] Error actualizando module_id de '%s': %v", sub.Title, err)
|
||||
} else {
|
||||
log.Printf("[SEED] Submódulo '%s' reasignado a módulo Automatización IA", sub.Title)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
||||
}
|
||||
}
|
||||
insertados = append(insertados, sub)
|
||||
}
|
||||
|
||||
// 3. Asignar solo al rol Administrador
|
||||
var rolAdmin models.Roles
|
||||
if err := db.Where("name = ?", "Administrador").First(&rolAdmin).Error; err != nil {
|
||||
log.Printf("[SEED] Rol 'Administrador' no encontrado, se omite asignación: %v", err)
|
||||
} else {
|
||||
db.Model(&rolAdmin).Association("Submodules").Append(&insertados)
|
||||
log.Printf("[SEED] Submódulos de Automatización IA asignados al rol 'Administrador'")
|
||||
}
|
||||
|
||||
log.Println("[SEED] Seed de Automatización IA completado.")
|
||||
}
|
||||
|
||||
// SeedIntegraciones crea el módulo "Integraciones" con los submódulos
|
||||
// de Hostinger y Cloudflare, y los asigna a todos los roles existentes.
|
||||
// Es idempotente: si el registro ya existe (por URL) lo reutiliza sin duplicar.
|
||||
|
||||
Reference in New Issue
Block a user