Files
soft_usite/rest/controllers/notificacion_controller.go

268 lines
8.7 KiB
Go

package controllers
import (
"math"
"strconv"
"strings"
"text/template"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/app"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
"github.com/sujit-baniya/fiber-boilerplate/utils"
)
// ─── Plantillas ─────────────────────────────────────────────────────────────
func PlantillasView(c *fiber.Ctx) error {
return c.Render("renovaciones/plantillas", fiber.Map{
"user": c.Locals("user"),
"modules": c.Locals("userModules"),
}, "layouts/main")
}
func GetPlantillas(c *fiber.Ctx) error {
page, _ := strconv.Atoi(c.Query("page", "1"))
limit, _ := strconv.Atoi(c.Query("limit", "10"))
if page < 1 {
page = 1
}
offset := (page - 1) * limit
records, total, err := models.GetAllPlantillas(limit, offset, c.Query("search"))
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{
"registros": records,
"total": total,
"totalPages": int(math.Ceil(float64(total) / float64(limit))),
"page": page,
})
}
func CreatePlantilla(c *fiber.Ctx) error {
var m models.PlantillaCorreo
if err := c.BodyParser(&m); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
if m.CuerpoHTML != "" {
if _, err := template.New("validate").Parse(m.CuerpoHTML); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Sintaxis inválida en el HTML: " + err.Error()})
}
}
if err := models.CreatePlantilla(m); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.Status(201).JSON(fiber.Map{"message": "Plantilla creada", "ok": true})
}
func UpdatePlantilla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
var updates map[string]interface{}
if err := c.BodyParser(&updates); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
if html, ok := updates["cuerpo_html"].(string); ok && html != "" {
if _, err := template.New("validate").Parse(html); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Sintaxis inválida en el HTML: " + err.Error()})
}
}
if err := models.UpdatePlantilla(uint(id), updates); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Actualizado", "ok": true})
}
func DeletePlantilla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
if err := models.DeletePlantilla(uint(id)); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Eliminado", "ok": true})
}
func PreviewPlantilla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
p, err := models.GetPlantillaByID(uint(id))
if err != nil {
return c.Status(404).JSON(fiber.Map{"error": "No encontrada"})
}
html, err := services.RenderPlantilla(p, services.DatosEjemplo())
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"html": html, "ok": true})
}
// ValidarPlantilla comprueba si el CuerpoHTML es un Go template válido
func ValidarPlantilla(c *fiber.Ctx) error {
var body struct {
HTML string `json:"html"`
}
if err := c.BodyParser(&body); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
html := strings.TrimSpace(body.HTML)
if html == "" {
return c.JSON(fiber.Map{"ok": true})
}
if _, err := template.New("validate").Parse(html); err != nil {
return c.Status(400).JSON(fiber.Map{"ok": false, "error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true})
}
func TestEnvioPlantilla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
var body struct {
Email string `json:"email"`
}
if err := c.BodyParser(&body); err != nil || body.Email == "" {
return c.Status(400).JSON(fiber.Map{"error": "Email requerido"})
}
p, err := models.GetPlantillaByID(uint(id))
if err != nil {
return c.Status(404).JSON(fiber.Map{"error": "No encontrada"})
}
// Recargar siempre la config activa desde BD antes de enviar
if cfg, err2 := models.GetSmtpConfig(); err2 == nil {
app.Http.Mail.Host = cfg.Host
app.Http.Mail.Port = cfg.Port
app.Http.Mail.Username = cfg.Username
app.Http.Mail.Password = utils.Decrypt(cfg.Password, app.Http.Server.Key)
app.Http.Mail.Encryption = cfg.Encryption
app.Http.Mail.FromAddress = cfg.FromAddress
app.Http.Mail.FromName = cfg.FromName
app.Http.Mail.SetupMailer()
}
if err := services.EnviarCorreoPrueba(body.Email, p); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Correo enviado", "ok": true})
}
// ─── Reglas ──────────────────────────────────────────────────────────────────
func ReglasView(c *fiber.Ctx) error {
return c.Render("renovaciones/reglas", fiber.Map{
"user": c.Locals("user"),
"modules": c.Locals("userModules"),
}, "layouts/main")
}
func GetReglas(c *fiber.Ctx) error {
records, err := models.GetAllReglas()
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"registros": records, "total": len(records)})
}
func CreateRegla(c *fiber.Ctx) error {
var m models.NotificacionRegla
if err := c.BodyParser(&m); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
if err := models.CreateRegla(m); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.Status(201).JSON(fiber.Map{"message": "Regla creada", "ok": true})
}
func UpdateRegla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
var m models.NotificacionRegla
if err := c.BodyParser(&m); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
m.ID = uint(id)
if err := models.UpdateRegla(m); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Actualizado", "ok": true})
}
func DeleteRegla(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
if err := models.DeleteRegla(uint(id)); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Eliminado", "ok": true})
}
// ─── Historial ───────────────────────────────────────────────────────────────
func HistorialView(c *fiber.Ctx) error {
return c.Render("renovaciones/historial", fiber.Map{
"user": c.Locals("user"),
"modules": c.Locals("userModules"),
}, "layouts/main")
}
func GetHistorial(c *fiber.Ctx) error {
page, _ := strconv.Atoi(c.Query("page", "1"))
limit, _ := strconv.Atoi(c.Query("limit", "20"))
if page < 1 {
page = 1
}
offset := (page - 1) * limit
records, total, err := models.GetAllLogs(limit, offset)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{
"registros": records,
"total": total,
"totalPages": int(math.Ceil(float64(total) / float64(limit))),
"page": page,
})
}
func ReenviarNotificacion(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
log, err := models.GetLogByID(uint(id))
if err != nil {
return c.Status(404).JSON(fiber.Map{"error": "No encontrado"})
}
if err := services.ReenviarLog(log); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Reenviado", "ok": true})
}
func VerPreviewLog(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "ID inválido"})
}
log, err := models.GetLogByID(uint(id))
if err != nil {
return c.Status(404).JSON(fiber.Map{"error": "No encontrado"})
}
return c.JSON(fiber.Map{"html": log.PreviewHTML, "asunto": log.Asunto, "ok": true})
}