heating-monitor/internal/web/handlers.go
2024-11-28 13:52:58 +01:00

180 lines
5.5 KiB
Go

package web
import (
"log"
"math"
"net/http"
"strconv"
"time"
"heating-monitor/internal/bot"
"heating-monitor/internal/config"
"heating-monitor/internal/repository"
"github.com/labstack/echo/v4"
"gorm.io/gorm"
)
func GetEventsHandler(c echo.Context, db *gorm.DB) error {
// Verificar que la base de datos esté correctamente inicializada
if db == nil {
log.Printf("Error: base de datos no inicializada")
return c.JSON(http.StatusInternalServerError, "Error al conectar con la base de datos")
}
// Obtener los parámetros de entrada
pageNum, sizeNum := getPaginationParams(c, 10)
filter := c.QueryParam("filter")
search := c.QueryParam("search")
startDateStr := c.QueryParam("startDate")
endDateStr := c.QueryParam("endDate")
// Construir y aplicar filtros dinámicos
query := applyFilters(db.Model(&bot.HeatingEvent{}), filter, search, startDateStr, endDateStr)
// Crear una consulta separada para todos los eventos (sin paginación)
var allEvents []bot.HeatingEvent
err := query.Find(&allEvents).Error
if err != nil {
log.Printf("Error al obtener todos los eventos filtrados: %v", err)
return c.JSON(http.StatusInternalServerError, "Error al obtener eventos completos")
}
// Calcular el tiempo total de encendido para todos los eventos filtrados
totalHours, totalMinutes := calculateTotalOnHours(allEvents)
// Obtener el total de resultados antes de la paginación
var count int64
err = query.Count(&count).Error
if err != nil {
log.Printf("Error al contar eventos: %v", err)
return c.JSON(http.StatusInternalServerError, "Error al contar eventos")
}
// Calcular offset y limitar resultados
offset := (pageNum - 1) * sizeNum
var events []bot.HeatingEvent
//err = query.Offset(offset).Limit(sizeNum).Find(&events).Error
err = query.Order("timestamp DESC").Offset(offset).Limit(sizeNum).Find(&events).Error
if err != nil {
log.Printf("Error al obtener eventos: %v", err)
return c.JSON(http.StatusInternalServerError, "Error al obtener eventos")
}
// Calcular la gráfica de consumos
consumptionData, isGroupedByMonth := calculateConsumptionData(allEvents)
// Separar las etiquetas y los totales
labels := make([]string, 0, len(consumptionData))
totals := make([]float64, 0, len(consumptionData))
for label, total := range consumptionData {
labels = append(labels, label)
totals = append(totals, total)
}
// Calcular paginación
totalPages := int(math.Ceil(float64(count) / float64(sizeNum)))
prevPage := pageNum - 1
if prevPage < 1 {
prevPage = 1
}
nextPage := pageNum + 1
if nextPage > totalPages {
nextPage = totalPages
}
// Renderizar en la plantilla
return LoadTemplate(c, "view.html", map[string]interface{}{
"events": events,
"page": pageNum,
"totalPages": totalPages,
"size": sizeNum,
"prevPage": prevPage,
"nextPage": nextPage,
"count": count,
"filter": filter,
"search": search,
"startDate": startDateStr,
"endDate": endDateStr,
"totalHours": totalHours,
"totalMinutes": totalMinutes,
"labels": labels,
"totals": totals,
"isGroupedByMonth": isGroupedByMonth,
})
}
// GetEventHandler obtiene un evento por ID y muestra la página de edición
func GetEventHandler(c echo.Context, db *gorm.DB) error {
// Obtener el ID del evento
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Printf("Error al convertir ID: %v", err)
return c.JSON(http.StatusBadRequest, "ID inválido")
}
// Buscar el evento usando el repositorio
event, err := repository.GetEventByID(db, id)
if err != nil {
log.Printf("Error al obtener evento con ID %d: %v", id, err)
return c.JSON(http.StatusNotFound, "Evento no encontrado")
}
// Renderizar los eventos en la plantilla
return LoadTemplate(c, "edit.html", event)
}
// UpdateEventHandler actualiza un evento en la base de datos
func UpdateEventHandler(c echo.Context, db *gorm.DB) error {
// Obtener el ID del evento
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Printf("Error al convertir ID: %v", err)
return c.JSON(http.StatusBadRequest, "ID inválido")
}
// Obtener los datos del evento desde el formulario
event := new(bot.HeatingEvent)
// Convertir el timestamp manualmente desde la cadena
timestampStr := c.FormValue("timestamp")
timestamp, err := time.Parse("2006-01-02T15:04", timestampStr)
if err != nil {
log.Printf("Error al convertir el timestamp: %v", err)
return c.JSON(http.StatusBadRequest, "Formato de fecha inválido")
}
// Asignar el timestamp convertido
event.Timestamp = timestamp
event.EventType = c.FormValue("event_type")
// Actualizar el evento usando el repositorio
_, err = repository.UpdateEventByID(db, id, event)
if err != nil {
log.Printf("Error al actualizar evento con ID %d: %v", id, err)
return c.JSON(http.StatusInternalServerError, "Error al actualizar evento")
}
return c.Redirect(http.StatusFound, "/")
}
func AboutHandler(c echo.Context, db *gorm.DB) error {
// Cargar configuración desde .env
cfg, err := config.LoadConfig()
if err != nil {
log.Fatalf("Error al cargar la configuración: %v", err)
}
// Pasar los datos de configuración a la plantilla
data := map[string]interface{}{
"ProgramAuthor": cfg.ProgramAuthor,
"ProgramLink": cfg.ProgramLink,
"ProgramAvatar": cfg.ProgramAvatar,
"ProgramName": cfg.ProgramName,
"ProgramVersion": cfg.ProgramVersion,
"ProgramYear": cfg.ProgramYear,
"ProgramTechnologies": cfg.ProgramTechnologies,
}
return LoadTemplate(c, "about.html", data)
}