2024-11-28 13:52:58 +01:00
|
|
|
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, "/")
|
|
|
|
}
|
|
|
|
|
2024-11-28 22:51:32 +01:00
|
|
|
// DeleteEventHandler elimina un evento de la base de datos
|
|
|
|
func DeleteEventHandler(c echo.Context, db *gorm.DB) error {
|
|
|
|
// Obtener el ID del evento desde los parámetros
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Eliminar el evento usando el repositorio
|
|
|
|
err = repository.DeleteEventByID(db, id)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error al eliminar evento con ID %d: %v", id, err)
|
|
|
|
return c.JSON(http.StatusInternalServerError, "Error al eliminar evento")
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Redirect(http.StatusFound, "/")
|
|
|
|
}
|
|
|
|
|
2024-11-28 13:52:58 +01:00
|
|
|
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)
|
|
|
|
}
|