diff --git a/src/main/java/mx/gob/jumapacelaya/models/encuestas/MantenimientosSinEncuesta.java b/src/main/java/mx/gob/jumapacelaya/models/encuestas/MantenimientosSinEncuesta.java new file mode 100644 index 0000000..e6158bc --- /dev/null +++ b/src/main/java/mx/gob/jumapacelaya/models/encuestas/MantenimientosSinEncuesta.java @@ -0,0 +1,102 @@ +package mx.gob.jumapacelaya.models.encuestas; + +import java.time.LocalDate; + +public class MantenimientosSinEncuesta { + private int mantenimientoId; + private int planId; + private LocalDate fecha; + private String periodo; + private String tipomant; + private String departamento; + private String nomUsuario; + private String email; + private String encuesta; + + public MantenimientosSinEncuesta(int mantenimientoId, int planId, LocalDate fecha, + String periodo, String tipomant, String departamento, + String nomUsuario, String email, String encuesta) { + + this.mantenimientoId = mantenimientoId; + this.planId = planId; + this.fecha = fecha; + this.periodo = periodo; + this.tipomant = tipomant; + this.departamento = departamento; + this.nomUsuario = nomUsuario; + this.email = email; + this.encuesta = encuesta; + } + + public int getMantenimientoId() { + return mantenimientoId; + } + + public void setMantenimientoId(int mantenimientoId) { + this.mantenimientoId = mantenimientoId; + } + + public int getPlanId() { + return planId; + } + + public void setPlanId(int planId) { + this.planId = planId; + } + + public LocalDate getFecha() { + return fecha; + } + + public void setFecha(LocalDate fecha) { + this.fecha = fecha; + } + + public String getPeriodo() { + return periodo; + } + + public void setPeriodo(String periodo) { + this.periodo = periodo; + } + + public String getTipomant() { + return tipomant; + } + + public void setTipomant(String tipomant) { + this.tipomant = tipomant; + } + + public String getDepartamento() { + return departamento; + } + + public void setDepartamento(String departamento) { + this.departamento = departamento; + } + + public String getNomUsuario() { + return nomUsuario; + } + + public void setNomUsuario(String nomUsuario) { + this.nomUsuario = nomUsuario; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEncuesta() { + return encuesta; + } + + public void setEncuesta(String encuesta) { + this.encuesta = encuesta; + } +} diff --git a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java index b4d4ea5..9e5ce3b 100644 --- a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java +++ b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java @@ -1,6 +1,7 @@ package mx.gob.jumapacelaya.services; import mx.gob.jumapacelaya.models.*; +import mx.gob.jumapacelaya.models.encuestas.MantenimientosSinEncuesta; import mx.gob.jumapacelaya.models.encuestas.Pregunta; import mx.gob.jumapacelaya.models.encuestas.Respuesta; import oracle.jdbc.OracleConnection; @@ -326,6 +327,68 @@ public class DatabaseService { } + + /* ----------------Obtener mantenimientos sin encuesta respondida por periodo ---------------- */ + public List getEncuestPendientes(String mes, int anio) { + List lista = new ArrayList<>(); + String query = """ + SELECT + m.MANTENIMIENTOID MANTID, + m.PLANANUALID PLANID, + m.FECHA, + ms.NOMBRE PERIODO, + t.NOMBRE TIPOMANT, + d.DESCRIPCION DEPTO, + u.NOMBRE NOMUSUARIO, + u.EMAIL, + m.ENCUESTA + FROM MANTENIMIENTOS m + JOIN TIPOMANT t + ON t.TIPOMANTID = m.TIPOMANTID + JOIN DEPARTAMENTOS d + on d.DEPARTAMENTOID = m.DEPARTAMENTOID + JOIN USUARIOS u + on u.EMPLEADOID = m.EMPLEADOID + JOIN PLANANUAL p + ON p.PLANANUALID = m.PLANANUALID + JOIN MESES ms + ON ms.MESID = p.MESID + WHERE m.ENCUESTA = 'N' + AND m.TIPOMANTID = 1 + AND m.PLANANUALID IS NOT NULL + AND UPPER(ms.NOMBRE) = UPPER(?) + AND EXTRACT(YEAR FROM m.FECHA) = ? + """; + + try(Connection connection = getMysqlConnection(); + PreparedStatement stmt = connection.prepareStatement(query)) { + + stmt.setString(1, mes.toUpperCase()); + stmt.setInt(2, anio); + + ResultSet rs = stmt.executeQuery(); + + while (rs.next()) { + lista.add(new MantenimientosSinEncuesta( + rs.getInt("MANTID"), + rs.getInt("PLANID"), + rs.getDate("FECHA").toLocalDate(), + rs.getString("PERIODO"), + rs.getString("TIPOMANT"), + rs.getString("DEPTO"), + rs.getString("NOMUSUARIO"), + rs.getString("EMAIL"), + rs.getString("ENCUESTA") + )); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return lista; + } + + /* ----------------Obtener detalles del hardaware por ID ---------------- */ public List getHardwaredetallePorMantId(int mantenimientoId) { List detalles = new ArrayList<>(); diff --git a/src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java b/src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java index 1447d2d..1654781 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java @@ -108,8 +108,30 @@ public class ActDiariaView extends VerticalLayout { fechaDesde = new DatePicker(); fechaDesde.setPlaceholder("Fecha desde:"); + fechaDesde.setLocale(new Locale("es", "MX")); + DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() + .setWeekdays(List.of("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")) + .setWeekdaysShort(List.of("Dom","Lun","Mar","Mié","Jue","Vie","Sab")) + .setMonthNames(List.of("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")) + .setFirstDayOfWeek(1) + .setToday("Hoy") + .setCancel("Cancelar") + .setDateFormat("dd/MM/yyyy"); + fechaDesde.setI18n(i18n); + fechaHasta = new DatePicker(); fechaHasta.setPlaceholder("Fecha hasta:"); + fechaHasta.setLocale(new Locale("es", "MX")); + DatePicker.DatePickerI18n i18nh = new DatePicker.DatePickerI18n() + .setWeekdays(List.of("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")) + .setWeekdaysShort(List.of("Dom","Lun","Mar","Mié","Jue","Vie","Sab")) + .setMonthNames(List.of("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")) + .setFirstDayOfWeek(1) + .setToday("Hoy") + .setCancel("Cancelar") + .setDateFormat("dd/MM/yyyy"); + fechaHasta.setI18n(i18nh); + btnBuscar = new Button("Buscar", VaadinIcon.SEARCH.create()); // Listener del checkbox diff --git a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java index 752039d..151955e 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java @@ -1,5 +1,6 @@ package mx.gob.jumapacelaya.ui; +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.UI; import com.vaadin.flow.component.button.Button; @@ -34,6 +35,7 @@ import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.receivers.MemoryBuffer; import com.vaadin.flow.data.provider.ListDataProvider; +import com.vaadin.flow.data.renderer.ComponentRenderer; import com.vaadin.flow.data.value.ValueChangeMode; import com.vaadin.flow.function.ValueProvider; import com.vaadin.flow.router.PageTitle; @@ -42,6 +44,7 @@ import com.vaadin.flow.server.StreamRegistration; import com.vaadin.flow.server.StreamResource; import jakarta.annotation.security.PermitAll; import mx.gob.jumapacelaya.models.PlanAnual; +import mx.gob.jumapacelaya.models.encuestas.MantenimientosSinEncuesta; import mx.gob.jumapacelaya.services.DatabaseService; import mx.gob.jumapacelaya.services.ReportService; import net.sf.jasperreports.engine.JasperFillManager; @@ -130,6 +133,9 @@ public class PlanAnualView extends VerticalLayout { headerRow.getCell(planAnualGrid.getColumnByKey("mesplaneado")) .setComponent(createFilterHeader("Mes Planeado", planAnualFilter::setMesPlaneado)); + headerRow.getCell(planAnualGrid.getColumnByKey("encuesta")) + .setComponent(createFilterHeader("Encuesta", planAnualFilter::setEncuesta)); + // MENU CONTEXTUAL DEL GRID @@ -369,14 +375,8 @@ public class PlanAnualView extends VerticalLayout { btnAddEquipo.setTooltipText("Agregar nuevo equipo"); btnEnviarEncuestas = new Button(VaadinIcon.ENVELOPE.create()); - ConfirmDialog enviarEncConfirm = new ConfirmDialog(); - enviarEncConfirm.setHeader("Enviar encuestas"); - enviarEncConfirm.setText("¿Deseas enviar las encuestas de satisfacción?, Esto enviara la encuesta solo a los mantenimientos realizados"); - enviarEncConfirm.setCancelable(true); - enviarEncConfirm.addCancelListener(e -> enviarEncConfirm.close()); - enviarEncConfirm.setConfirmText("Enviar"); - enviarEncConfirm.addConfirmListener(e -> {}); - btnEnviarEncuestas.addClickListener(e -> enviarEncConfirm.open()); + btnEnviarEncuestas.addClickListener(e -> showParametrosDialog()); + btnEnviarEncuestas.setTooltipText("Enviar encuestas masivamente"); yearFilter = new ComboBox<>(); int currentYear = Year.now().getValue(); @@ -389,7 +389,7 @@ public class PlanAnualView extends VerticalLayout { List todosLosPlanes = databaseService.getPlanAnual(); - btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo/*, btnEnviarEncuestas*/, yearFilter); + btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo, btnEnviarEncuestas, yearFilter); btnImprimirLayout.setAlignItems(Alignment.BASELINE); HorizontalLayout columnSelectorLayout = new HorizontalLayout(); columnSelectorLayout.setAlignItems(Alignment.END); @@ -541,6 +541,11 @@ public class PlanAnualView extends VerticalLayout { private String equipo; private String departamento; private String mesPlaneado; + private LocalDate fechaProgramada; + private LocalDate fechaRealizacion; + private String encuesta; + private String estado; + private String situacion; private Integer year; private boolean excludeRealizado = true; @@ -569,6 +574,11 @@ public class PlanAnualView extends VerticalLayout { this.dataView.refreshAll(); } + public void setEncuesta(String encuesta) { + this.encuesta = encuesta; + this.dataView.refreshAll(); + } + public void setYear(Integer year) { this.year = year; dataView.refreshAll(); @@ -586,6 +596,7 @@ public class PlanAnualView extends VerticalLayout { boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo); boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento); boolean matchesMesPlaneado = matches(planAnual.getMesplaneado(), mesPlaneado); + boolean matchesEncuesta = matches(planAnual.getEncuesta(), encuesta); boolean matchesYear = true; if (year != null) { @@ -608,7 +619,8 @@ public class PlanAnualView extends VerticalLayout { && matchesDepartamento && matchesMesPlaneado && matchesYear - && matchesEstado; + && matchesEstado + && matchesEncuesta; } private boolean matches(String value, String serachTerm) { @@ -1005,4 +1017,114 @@ public class PlanAnualView extends VerticalLayout { dialog.getFooter().add(dialogFooter); dialog.open(); } + + + + private void showParametrosDialog() { + Dialog dialog = new Dialog(); + dialog.setHeaderTitle("Ingresar periodo"); + + TextField txtMes = new TextField("Mes:"); + txtMes.setPlaceholder("ENERO, FEBRERO, MARZO..."); + txtMes.setClearButtonVisible(true); + + TextField txtAnio = new TextField("Año"); + txtAnio.setPlaceholder("Ej. 2025"); + + Button btnBuscar = new Button("Buscar", VaadinIcon.SEARCH.create(), e -> { + String mes = txtMes.getValue(); + String anioTexto = txtAnio.getValue(); + + if (mes.isEmpty() || anioTexto.isEmpty()) { + Notification.show("Mes y año son requeridos.", 3000, Notification.Position.MIDDLE); + return; + } + + int anio; + try { + anio = Integer.parseInt(anioTexto); + } catch (NumberFormatException ex) { + Notification.show("El año debe ser numérico.", 3000, Notification.Position.MIDDLE); + return; + } + + dialog.close(); + showEncuestasDialog(mes, anio); + }); + btnBuscar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + + Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); + + HorizontalLayout actions = new HorizontalLayout(btnBuscar, btnCancelar); + + VerticalLayout layout = new VerticalLayout(txtMes, txtAnio, actions); + layout.setPadding(false); + layout.setSpacing(true); + + dialog.add(layout); + dialog.open(); + } + + private void showEncuestasDialog(String mes, int anio) { + Dialog dialog = new Dialog(); + dialog.setWidth("80%"); + dialog.setHeight("90%"); + dialog.setHeaderTitle("Encuestas pendientes por enviar..."); + + Grid grid = new Grid<>(MantenimientosSinEncuesta.class, false); + grid.addColumn(MantenimientosSinEncuesta::getMantenimientoId) + .setHeader("ID") + .setAutoWidth(true); + + grid.addColumn(item -> item.getFecha().format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))) + .setHeader("Fecha"); + + grid.addColumn(MantenimientosSinEncuesta::getPeriodo) + .setHeader("Periodo"); + + grid.addColumn(createStatusRender()) + .setHeader("Encuesta"); + + grid.addColumn(MantenimientosSinEncuesta::getDepartamento) + .setHeader("Departamento") + .setAutoWidth(true); + + grid.addColumn(MantenimientosSinEncuesta::getNomUsuario) + .setHeader("Usuario") + .setAutoWidth(true); + + grid.addColumn(MantenimientosSinEncuesta::getEmail) + .setHeader("Correo") + .setAutoWidth(true); + + List lista = databaseService.getEncuestPendientes(mes, anio); + + grid.setItems(lista); + dialog.add(grid); + dialog.getFooter().add(new Button("Cerrar", e -> dialog.close())); + + dialog.open(); + } + + private ComponentRenderer createStatusRender() { + return new ComponentRenderer<>(encuesta -> { + Span span = new Span(encuesta.getEncuesta()); + + switch (encuesta.getEncuesta().toUpperCase()) { + case "N": + String theme1 = String.format("badge %s", "error"); + span.getElement().setAttribute("theme", theme1); + break; + case "S": + String theme2 = String.format("badge %s", "success"); + span.getElement().setAttribute("theme", theme2); + break; + default: + String theme3 = String.format("badge %s", ""); + span.getElement().setAttribute("theme", theme3); + } + + return span; + }); + } }