diff --git a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java index 62f639b..669353b 100644 --- a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java +++ b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -1042,20 +1043,24 @@ public class DatabaseService { public String crearTokenEncuesta(int mantenimientoid) { String token = UUID.randomUUID().toString(); Timestamp expira = new Timestamp(System.currentTimeMillis() + (24 * 60 * 60 * 1000)); + LocalDate fechaEnvio = LocalDate.now(ZoneId.of("America/Mexico_City")); - String query = "INSERT INTO ENCUESTATOKENS (TOKEN, MANTENIMIENTOID, FECHAEXPIRACION) VALUES (?, ?, ?)"; + String query = "INSERT INTO ENCUESTATOKENS (TOKEN, MANTENIMIENTOID, FECHAENVIO, FECHAEXPIRACION) VALUES (?, ?, ?, ?)"; try (Connection conn = getMysqlConnection(); PreparedStatement stmt = conn.prepareStatement(query)) { stmt.setString(1, token); stmt.setInt(2, mantenimientoid); - stmt.setTimestamp(3, expira); + stmt.setDate(3, Date.valueOf(fechaEnvio)); + stmt.setTimestamp(4, expira); stmt.executeUpdate(); + return token; + } catch (SQLException e) { logger.error("Error al crear el token de encuesta: ", e); + throw new RuntimeException("Ya existe una encuesta para este mantenimiento o error en DB", e); } - return token; } public Integer validarTokenYObtenerId(String token) { @@ -1075,21 +1080,34 @@ public class DatabaseService { return null; } - public List getTotalEncuestas() { + public List getTotalEncuestas(Integer mesId, Integer anio) { List totalEncuestas = new ArrayList<>(); - String query = "SELECT * FROM VW_CONTEO_ENCUESTAS"; + String query = "{call sp_reporte_encuestas(?, ?)}"; try (Connection conn = getMysqlConnection(); - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query)) { + CallableStatement cstmt = conn.prepareCall(query)) { - while (rs.next()) { - ConteoEncuestas conteo = new ConteoEncuestas( - rs.getInt("TOTAL_ENVIADAS"), - rs.getInt("TOTAL_RESPONDIDAS"), - rs.getDouble("PORCENTAJE_TOTAL") - ); - totalEncuestas.add(conteo); + if (mesId != null) { + cstmt.setInt(1, mesId); + } else { + cstmt.setNull(1, Types.INTEGER); + } + + if (anio != null) { + cstmt.setInt(2, anio); + } else { + cstmt.setNull(2, Types.INTEGER); + } + + try (ResultSet rs = cstmt.executeQuery()) { + while (rs.next()) { + ConteoEncuestas conteo = new ConteoEncuestas( + rs.getInt("TOTAL_ENVIADAS"), + rs.getInt("TOTAL_RESPONDIDAS"), + rs.getDouble("PORCENTAJE_TOTAL") + ); + totalEncuestas.add(conteo); + } } } catch (SQLException e) { logger.error("Error al obtener el total de encuestas: ", e); @@ -1097,24 +1115,37 @@ public class DatabaseService { return totalEncuestas; } - public List getTotalRespuestas() { + public List getTotalRespuestas(Integer mesId, Integer anio) { List totalRespuestas = new ArrayList<>(); - String query = "SELECT * FROM VW_CONTEO_RESPUESTAS"; + String query = "{call sp_reporte_respuestas(?, ?)}"; try (Connection conn = getMysqlConnection(); - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query)) { + CallableStatement cstmt = conn.prepareCall(query)) { - while (rs.next()) { - ConteoRespuestas conteo = new ConteoRespuestas( - rs.getInt("PREGUNTAID"), - rs.getString("PREGUNTA"), - rs.getInt("TOTALREGISTROS"), - rs.getInt("TOTALSI"), - rs.getInt("TOTALNO"), - rs.getDouble("PORCENTAJE") - ); - totalRespuestas.add(conteo); + if (mesId != null) { + cstmt.setInt(1, mesId); + } else { + cstmt.setNull(1, Types.INTEGER); + } + + if (anio != null) { + cstmt.setInt(2, anio); + } else { + cstmt.setNull(2, Types.INTEGER); + } + + try (ResultSet rs = cstmt.executeQuery()) { + while (rs.next()) { + ConteoRespuestas conteo = new ConteoRespuestas( + rs.getInt("PREGUNTAID"), + rs.getString("PREGUNTA"), + rs.getInt("TOTALREGISTROS"), + rs.getInt("TOTALSI"), + rs.getInt("TOTALNO"), + rs.getDouble("PORCENTAJE") + ); + totalRespuestas.add(conteo); + } } } catch (SQLException e) { logger.error("Error al obtener el total de respuestas: ", e); diff --git a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java index b0b7205..8a44906 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java @@ -536,25 +536,25 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser private void enviarCorreo() { Usuario usuarioDestino = cbUsuario.getValue(); if (usuarioDestino != null && usuarioDestino.getEmail() != null) { - String destinatario = usuarioDestino.getEmail(); - String asunto = "Encuesta de satisfacción -Mantenimiento #" + mantenimientoIdActual; + try { + String token = service.crearTokenEncuesta(mantenimientoIdActual); - String token = service.crearTokenEncuesta(mantenimientoIdActual); - String linkEncuesta = baseUrl + "/encuesta?token=" + token; + String destinatario = usuarioDestino.getEmail(); + String asunto = "Encuesta de satisfacción - Mantenimiento #" + mantenimientoIdActual; + String linkEncuesta = baseUrl + "/encuesta?token=" + token; + String cuerpo = ""; + String imagePath = "META-INF/resources/images/imgCorreo/imgEncuesta.png"; - String cuerpo = "" + - "" + - "" + - ""+ - "" + - "" + - ""; + emailService.enviarCorreo(destinatario, asunto, cuerpo, imagePath); - String imagePath = "META-INF/resources/images/imgCorreo/imgEncuesta.png"; + Notification.show("Encuesta enviada correctamente", 3000, Notification.Position.BOTTOM_END) + .addThemeVariants(NotificationVariant.LUMO_SUCCESS); - emailService.enviarCorreo(destinatario,asunto,cuerpo,imagePath); - Notification.show("Encuesta enviada correctamente para el mantenimiento No. " + mantenimientoIdActual, 3000, Notification.Position.BOTTOM_END) - .addThemeVariants(NotificationVariant.LUMO_SUCCESS); + } catch (Exception e) { + Notification.show("Error: No se pudo enviar. Es probable que ya exista una encuesta generada.", + 5000, Notification.Position.MIDDLE) + .addThemeVariants(NotificationVariant.LUMO_ERROR); + } } else { Notification.show("Por favor, seleccione un usuario destino", 3000, Notification.Position.MIDDLE); } diff --git a/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java b/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java index bf8e392..6eb5e6b 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java @@ -2,6 +2,7 @@ package mx.gob.jumapacelaya.ui; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.dashboard.Dashboard; import com.vaadin.flow.component.dashboard.DashboardSection; import com.vaadin.flow.component.dashboard.DashboardWidget; @@ -23,7 +24,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.lineawesome.LineAwesomeIcon; +import java.util.HashMap; import java.util.List; +import java.util.Map; @PermitAll @PageTitle("Resultados de Encuestas") @@ -41,6 +44,7 @@ public class ResultEncuestasView extends VerticalLayout { private DashboardWidget pregunta4; private DashboardWidget pregunta5; private DashboardWidget pregunta6; + private ComboBox cmbMes; public ResultEncuestasView(DatabaseService databaseService) { this.databaseService = databaseService; @@ -52,7 +56,32 @@ public class ResultEncuestasView extends VerticalLayout { Button btnExport = new Button("Exportar a PDF", LineAwesomeIcon.FILE_PDF.create()); btnExport.addThemeVariants(ButtonVariant.LUMO_SMALL); - HorizontalLayout toolbar = new HorizontalLayout(btnExport); + Map meses = new HashMap<>(); + meses.put(1, "Enero"); + meses.put(2, "Febrero"); + meses.put(3, "Marzo"); + meses.put(4, "Abril"); + meses.put(5, "Mayo"); + meses.put(6, "Junio"); + meses.put(7, "Julio"); + meses.put(8, "Agosto"); + meses.put(9, "Septiembre"); + meses.put(10, "Octubre"); + meses.put(11, "Noviembre"); + meses.put(12, "Diciembre"); + + + cmbMes = new ComboBox<>(); + cmbMes.setItems(meses.keySet()); + cmbMes.setItemLabelGenerator(meses::get); + cmbMes.setPlaceholder("Filtrar por mes"); + cmbMes.setClearButtonVisible(true); + cmbMes.addValueChangeListener(e -> { + Integer mesSeleccionado = e.getValue(); + actualizarDashboard(mesSeleccionado, 2026); + }); + + HorizontalLayout toolbar = new HorizontalLayout(btnExport, cmbMes); toolbar.setAlignItems(Alignment.BASELINE); toolbar.setWidthFull(); @@ -94,8 +123,7 @@ public class ResultEncuestasView extends VerticalLayout { preguntasSection.add(pregunta5); preguntasSection.add(pregunta6); - mostrarTotales(); - mostrarPreguntas(); + actualizarDashboard(null, null); add(dashboard); return dashboard; } @@ -160,8 +188,13 @@ public class ResultEncuestasView extends VerticalLayout { return vl; } - public void mostrarTotales() { - List datos = databaseService.getTotalEncuestas(); + private void actualizarDashboard(Integer mes, Integer anio) { + mostrarTotales(mes, anio); + mostrarPreguntas(mes, anio); + } + + public void mostrarTotales(Integer mes, Integer anio) { + List datos = databaseService.getTotalEncuestas(mes, anio); if (!datos.isEmpty()) { ConteoEncuestas totales = datos.get(0); @@ -180,15 +213,20 @@ public class ResultEncuestasView extends VerticalLayout { String.valueOf(totales.getPorcentajeRespondidas()), LineAwesomeIcon.PERCENT_SOLID, "#BC955B" )); + } else { + totalEncu.setContent(createDiv("0", LineAwesomeIcon.CLIPBOARD_LIST_SOLID, "#BC955B")); } } - public void mostrarPreguntas() { - List lista = databaseService.getTotalRespuestas(); + public void mostrarPreguntas(Integer mes, Integer anio) { + List lista = databaseService.getTotalRespuestas(mes, anio); DashboardWidget[] widgets = {pregunta1,pregunta2,pregunta3,pregunta4,pregunta5,pregunta6}; + for (DashboardWidget w : widgets) w.setContent(new Span("Sin datos")); + for (int i = 0; i < lista.size() && i < widgets.length; i++) { + ConteoRespuestas data = lista.get(i); DashboardWidget widget = widgets[i];