package models import ( "fmt" "time" "github.com/sujit-baniya/fiber-boilerplate/app" "gorm.io/gorm" ) type NotificacionLog struct { gorm.Model ClienteID uint `json:"cliente_id" gorm:"column:cliente_id"` Cliente Cliente `json:"cliente" gorm:"foreignKey:ClienteID"` ReglaID uint `json:"regla_id" gorm:"column:regla_id"` Regla NotificacionRegla `json:"regla" gorm:"foreignKey:ReglaID"` ContratosIDs string `json:"contratos_ids" gorm:"column:contratos_ids;type:text"` // JSON array FechaEnvio time.Time `json:"fecha_envio" gorm:"column:fecha_envio"` Estado string `json:"estado" gorm:"column:estado;default:'pendiente'"` // enviado | fallido | pendiente ErrorMsg string `json:"error_msg" gorm:"column:error_msg;type:text"` Asunto string `json:"asunto" gorm:"column:asunto"` PreviewHTML string `json:"preview_html" gorm:"column:preview_html;type:text"` Pasarela string `json:"pasarela" gorm:"column:pasarela;type:varchar(20)"` // bold | dlocal | (vacío para correos de aviso) EnlacePago string `json:"enlace_pago" gorm:"column:enlace_pago;type:text"` // URL del link de pago generado en este envío } func (NotificacionLog) TableName() string { return "notificaciones_log" } func GetAllNotificacionLogs(limit, offset int, clienteID uint, estado string) ([]NotificacionLog, int64, error) { var items []NotificacionLog var total int64 db := app.Http.Database.DB.Model(&NotificacionLog{}). Preload("Cliente").Preload("Regla") if clienteID > 0 { db = db.Where("cliente_id = ?", clienteID) } if estado != "" { db = db.Where("estado = ?", estado) } if err := db.Count(&total).Error; err != nil { return nil, 0, err } if err := db.Order("created_at DESC").Limit(limit).Offset(offset).Find(&items).Error; err != nil { return nil, 0, err } return items, total, nil } func GetNotificacionLogByID(id uint) (*NotificacionLog, error) { var item NotificacionLog if err := app.Http.Database.DB.Preload("Cliente").Preload("Regla").First(&item, id).Error; err != nil { return nil, err } return &item, nil } // YaEnviadoHoy comprueba si ya se envió notificación de esta regla a este cliente hoy func YaEnviadoHoy(clienteID, reglaID uint) bool { var count int64 today := time.Now().UTC().Truncate(24 * time.Hour) tomorrow := today.Add(24 * time.Hour) app.Http.Database.DB.Model(&NotificacionLog{}). Where("cliente_id = ? AND regla_id = ? AND estado = 'enviado' AND created_at >= ? AND created_at < ?", clienteID, reglaID, today, tomorrow). Count(&count) return count > 0 } func CreateNotificacionLog(n NotificacionLog) (*NotificacionLog, error) { if err := app.Http.Database.DB.Create(&n).Error; err != nil { return nil, err } return &n, nil } func UpdateNotificacionLog(n NotificacionLog) error { return app.Http.Database.DB.Model(&n).Updates(map[string]interface{}{ "estado": n.Estado, "error_msg": n.ErrorMsg, "pasarela": n.Pasarela, "enlace_pago": n.EnlacePago, }).Error } // Aliases simples para los controllers func GetAllLogs(limit, offset int) ([]NotificacionLog, int64, error) { return GetAllNotificacionLogs(limit, offset, 0, "") } func GetLogByID(id uint) (*NotificacionLog, error) { return GetNotificacionLogByID(id) } // GetLogsByContratoID devuelve los logs de notificaciones que incluyen un contrato específico func GetLogsByContratoID(contratoID uint) ([]NotificacionLog, error) { var items []NotificacionLog // contratos_ids es un JSON array, buscamos que contenga el ID pattern := fmt.Sprintf(`%%[%d]%%`, contratoID) if err := app.Http.Database.DB. Preload("Regla"). Where("contratos_ids LIKE ?", pattern). Order("created_at DESC"). Limit(50). Find(&items).Error; err != nil { return nil, err } return items, nil }