up
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
)
|
||||
|
||||
func ClientesView(c *fiber.Ctx) error {
|
||||
return c.Render("renovaciones/clientes", fiber.Map{
|
||||
"user": c.Locals("user"),
|
||||
"modules": c.Locals("userModules"),
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
func GetClientes(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.GetAllClientes(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,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
func GetClientesSelect(c *fiber.Ctx) error {
|
||||
records, err := models.GetAllClientesSelect()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(records)
|
||||
}
|
||||
|
||||
func CreateCliente(c *fiber.Ctx) error {
|
||||
var m models.Cliente
|
||||
if err := c.BodyParser(&m); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
m.Activo = true
|
||||
if err := models.CreateCliente(m); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.Status(201).JSON(fiber.Map{"message": "Cliente creado", "ok": true})
|
||||
}
|
||||
|
||||
func UpdateCliente(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.Cliente
|
||||
if err := c.BodyParser(&m); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
m.ID = uint(id)
|
||||
if err := models.UpdateCliente(m); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Actualizado", "ok": true})
|
||||
}
|
||||
|
||||
func DeleteCliente(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.DeleteCliente(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Eliminado", "ok": true})
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
||||
)
|
||||
|
||||
func ContratosView(c *fiber.Ctx) error {
|
||||
return c.Render("renovaciones/contratos", fiber.Map{
|
||||
"user": c.Locals("user"),
|
||||
"modules": c.Locals("userModules"),
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
func GetContratos(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.GetAllContratos(limit, offset, c.Query("search"), c.Query("estado"))
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
// Enriquecer con días restantes
|
||||
type ContratoDTO struct {
|
||||
models.Contrato
|
||||
DiasRestantes int `json:"dias_restantes"`
|
||||
Urgencia string `json:"urgencia"` // verde | amarillo | rojo
|
||||
}
|
||||
dtos := make([]ContratoDTO, len(records))
|
||||
now := time.Now()
|
||||
for i, r := range records {
|
||||
dias := int(r.FechaVencimiento.Sub(now).Hours() / 24)
|
||||
urgencia := "verde"
|
||||
if dias <= 0 {
|
||||
urgencia = "rojo"
|
||||
} else if dias <= 30 {
|
||||
urgencia = "amarillo"
|
||||
}
|
||||
dtos[i] = ContratoDTO{Contrato: r, DiasRestantes: dias, Urgencia: urgencia}
|
||||
}
|
||||
return c.JSON(fiber.Map{
|
||||
"registros": dtos,
|
||||
"total": total,
|
||||
"totalPages": int(math.Ceil(float64(total) / float64(limit))),
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
func CreateContrato(c *fiber.Ctx) error {
|
||||
type Input struct {
|
||||
ClienteID uint `json:"cliente_id" form:"cliente_id"`
|
||||
ServicioID uint `json:"servicio_id" form:"servicio_id"`
|
||||
FechaInicio string `json:"fecha_inicio" form:"fecha_inicio"`
|
||||
FechaVencimiento string `json:"fecha_vencimiento" form:"fecha_vencimiento"`
|
||||
PrecioAcordado float64 `json:"precio_acordado" form:"precio_acordado"`
|
||||
AutoRenovar bool `json:"auto_renovar" form:"auto_renovar"`
|
||||
Notas string `json:"notas" form:"notas"`
|
||||
}
|
||||
var inp Input
|
||||
if err := c.BodyParser(&inp); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
fi, err := time.Parse("2006-01-02", inp.FechaInicio)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Fecha inicio inválida"})
|
||||
}
|
||||
fv, err := time.Parse("2006-01-02", inp.FechaVencimiento)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Fecha vencimiento inválida"})
|
||||
}
|
||||
m := models.Contrato{
|
||||
ClienteID: inp.ClienteID,
|
||||
ServicioID: inp.ServicioID,
|
||||
FechaInicio: fi,
|
||||
FechaVencimiento: fv,
|
||||
PrecioAcordado: inp.PrecioAcordado,
|
||||
AutoRenovar: inp.AutoRenovar,
|
||||
Notas: inp.Notas,
|
||||
Estado: "activo",
|
||||
}
|
||||
if err := models.CreateContrato(m); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.Status(201).JSON(fiber.Map{"message": "Contrato creado", "ok": true})
|
||||
}
|
||||
|
||||
func UpdateContrato(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"})
|
||||
}
|
||||
type Input struct {
|
||||
Estado string `json:"estado" form:"estado"`
|
||||
FechaVencimiento string `json:"fecha_vencimiento" form:"fecha_vencimiento"`
|
||||
PrecioAcordado float64 `json:"precio_acordado" form:"precio_acordado"`
|
||||
AutoRenovar bool `json:"auto_renovar" form:"auto_renovar"`
|
||||
Notas string `json:"notas" form:"notas"`
|
||||
}
|
||||
var inp Input
|
||||
if err := c.BodyParser(&inp); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
existing, err := models.GetContratoByID(uint(id))
|
||||
if err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "No encontrado"})
|
||||
}
|
||||
if inp.FechaVencimiento != "" {
|
||||
fv, err := time.Parse("2006-01-02", inp.FechaVencimiento)
|
||||
if err == nil {
|
||||
existing.FechaVencimiento = fv
|
||||
}
|
||||
}
|
||||
if inp.Estado != "" {
|
||||
existing.Estado = inp.Estado
|
||||
}
|
||||
existing.PrecioAcordado = inp.PrecioAcordado
|
||||
existing.AutoRenovar = inp.AutoRenovar
|
||||
existing.Notas = inp.Notas
|
||||
if err := models.UpdateContrato(*existing); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Actualizado", "ok": true})
|
||||
}
|
||||
|
||||
func RenovarContrato(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"})
|
||||
}
|
||||
existing, err := models.GetContratoByID(uint(id))
|
||||
if err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "No encontrado"})
|
||||
}
|
||||
// Calcular nueva fecha según periodicidad del servicio
|
||||
nuevaInicio := existing.FechaVencimiento.AddDate(0, 0, 1)
|
||||
nuevaVenc := calcularFechaVencimiento(nuevaInicio, existing.Servicio.Periodicidad)
|
||||
|
||||
nuevo := models.Contrato{
|
||||
ClienteID: existing.ClienteID,
|
||||
ServicioID: existing.ServicioID,
|
||||
FechaInicio: nuevaInicio,
|
||||
FechaVencimiento: nuevaVenc,
|
||||
PrecioAcordado: existing.PrecioAcordado,
|
||||
AutoRenovar: existing.AutoRenovar,
|
||||
Estado: "activo",
|
||||
Notas: "Renovación automática desde contrato #" + strconv.Itoa(int(existing.ID)),
|
||||
}
|
||||
if err := models.CreateContrato(nuevo); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
// Marcar anterior como renovado
|
||||
existing.Estado = "renovado"
|
||||
models.UpdateContrato(*existing)
|
||||
|
||||
return c.JSON(fiber.Map{"message": "Renovado", "ok": true})
|
||||
}
|
||||
|
||||
func EnviarCorreoContrato(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"})
|
||||
}
|
||||
contrato, err := models.GetContratoByID(uint(id))
|
||||
if err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "No encontrado"})
|
||||
}
|
||||
if err := services.EnviarCorreoManual(contrato); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Correo enviado", "ok": true})
|
||||
}
|
||||
|
||||
func DeleteContrato(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.DeleteContrato(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Eliminado", "ok": true})
|
||||
}
|
||||
|
||||
func calcularFechaVencimiento(desde time.Time, periodicidad string) time.Time {
|
||||
switch periodicidad {
|
||||
case "mensual":
|
||||
return desde.AddDate(0, 1, 0)
|
||||
case "trimestral":
|
||||
return desde.AddDate(0, 3, 0)
|
||||
case "semestral":
|
||||
return desde.AddDate(0, 6, 0)
|
||||
case "anual":
|
||||
return desde.AddDate(1, 0, 0)
|
||||
default:
|
||||
return desde.AddDate(1, 0, 0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
||||
)
|
||||
|
||||
// ─── 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 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 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})
|
||||
}
|
||||
|
||||
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"})
|
||||
}
|
||||
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})
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
)
|
||||
|
||||
func ServiciosView(c *fiber.Ctx) error {
|
||||
return c.Render("renovaciones/servicios", fiber.Map{
|
||||
"user": c.Locals("user"),
|
||||
"modules": c.Locals("userModules"),
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
func GetServicios(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.GetAllServicios(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,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
func GetServiciosSelect(c *fiber.Ctx) error {
|
||||
records, err := models.GetAllServiciosSelect()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(records)
|
||||
}
|
||||
|
||||
func CreateServicio(c *fiber.Ctx) error {
|
||||
var m models.Servicio
|
||||
if err := c.BodyParser(&m); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
m.Activo = true
|
||||
if err := models.CreateServicio(m); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.Status(201).JSON(fiber.Map{"message": "Servicio creado", "ok": true})
|
||||
}
|
||||
|
||||
func UpdateServicio(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.Servicio
|
||||
if err := c.BodyParser(&m); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
m.ID = uint(id)
|
||||
if err := models.UpdateServicio(m); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Actualizado", "ok": true})
|
||||
}
|
||||
|
||||
func DeleteServicio(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.DeleteServicio(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Eliminado", "ok": true})
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"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/utils"
|
||||
)
|
||||
|
||||
func SmtpConfigView(c *fiber.Ctx) error {
|
||||
cfg, _ := models.GetSmtpConfig()
|
||||
return c.Render("renovaciones/smtp", fiber.Map{
|
||||
"user": c.Locals("user"),
|
||||
"modules": c.Locals("userModules"),
|
||||
"config": cfg,
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
func GetSmtpConfig(c *fiber.Ctx) error {
|
||||
cfg, err := models.GetSmtpConfig()
|
||||
if err != nil {
|
||||
return c.JSON(fiber.Map{"ok": false, "config": nil})
|
||||
}
|
||||
// No exponer contraseña en claro
|
||||
cfg.Password = "***"
|
||||
return c.JSON(fiber.Map{"ok": true, "config": cfg})
|
||||
}
|
||||
|
||||
func SaveSmtpConfig(c *fiber.Ctx) error {
|
||||
type Input struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Encryption string `json:"encryption"`
|
||||
FromAddress string `json:"from_address"`
|
||||
FromName string `json:"from_name"`
|
||||
}
|
||||
var inp Input
|
||||
if err := c.BodyParser(&inp); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
// Cifrar contraseña solo si se provee una nueva (no es placeholder)
|
||||
passEncrypted := inp.Password
|
||||
if inp.Password != "" && inp.Password != "***" {
|
||||
passEncrypted = utils.Encrypt(inp.Password, app.Http.Server.Key)
|
||||
} else if inp.Password == "***" {
|
||||
// Mantener contraseña ya guardada
|
||||
if existing, err := models.GetSmtpConfig(); err == nil {
|
||||
passEncrypted = existing.Password
|
||||
}
|
||||
}
|
||||
|
||||
cfg := models.SmtpConfig{
|
||||
Host: inp.Host,
|
||||
Port: inp.Port,
|
||||
Username: inp.Username,
|
||||
Password: passEncrypted,
|
||||
Encryption: inp.Encryption,
|
||||
FromAddress: inp.FromAddress,
|
||||
FromName: inp.FromName,
|
||||
}
|
||||
|
||||
if err := models.SaveSmtpConfig(cfg); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
// Recargar el mailer en memoria con la nueva config
|
||||
app.Http.Mail.Host = cfg.Host
|
||||
app.Http.Mail.Port = cfg.Port
|
||||
app.Http.Mail.Username = cfg.Username
|
||||
app.Http.Mail.Password = utils.Decrypt(passEncrypted, 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()
|
||||
|
||||
return c.JSON(fiber.Map{"message": "Configuración guardada", "ok": true})
|
||||
}
|
||||
|
||||
func TestSmtpConfig(c *fiber.Ctx) error {
|
||||
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 de destino requerido"})
|
||||
}
|
||||
htmlBody := "<h2>Test SMTP</h2><p>La configuración SMTP funciona correctamente.</p>"
|
||||
if err := app.Http.Mail.Send(body.Email, "Test SMTP - U-site", htmlBody); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Correo de prueba enviado", "ok": true})
|
||||
}
|
||||
Reference in New Issue
Block a user