diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index ddefb70..9cf5704 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java index b07cc9b..ae212a0 100644 --- a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java +++ b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java @@ -806,4 +806,41 @@ public class DatabaseService { return false; } } + + + /* ---------------- Insertar en bitacora de eliminacion de equipos ---------------- */ + public boolean insertarBitacoraEliminacion(int plananualid, String usuarioid, LocalDate fechora, String motivo) { + String query = "INSERT INTO BITACORAELIMINACIONES (PLANANUALID, USUARIOID, FECHAHORA, MOTIVO) VALUES (?, ?, ?, ?)"; + try (Connection conn = getMysqlConnection(); + PreparedStatement stmt = conn.prepareStatement(query)) { + stmt.setInt(1, plananualid); + stmt.setString(2, usuarioid); + stmt.setDate(3, fechora != null ? Date.valueOf(fechora) : null); + stmt.setString(4, motivo); + return stmt.executeUpdate() > 0; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + + /* ---------------- Eliminar equipo de PLAN ANUAL ---------------- */ + public void eliminarEquipoPlanAnual(int planAnualId) { + String sql = "DELETE FROM PLANANUAL WHERE PLANANUALID = ?"; + try (Connection conn = getMysqlConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + stmt.setInt(1, planAnualId); + int rowsAffected = stmt.executeUpdate(); + if (rowsAffected > 0) { + System.out.println(planAnualId + " eliminado correctamente."); + } else { + System.out.println("No se encontró el equipo con ID: " + planAnualId); + } + } catch (SQLException e) { + System.err.println("Error al eliminar el equipo de PLANANUAL: " + e.getMessage()); + e.printStackTrace(); + } + } } diff --git a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java index 69fbe5e..b27b695 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java @@ -8,6 +8,7 @@ import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.checkbox.CheckboxGroup; import com.vaadin.flow.component.checkbox.CheckboxGroupVariant; import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.confirmdialog.ConfirmDialog; import com.vaadin.flow.component.datepicker.DatePicker; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.dialog.Dialog; @@ -15,6 +16,8 @@ import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.GridVariant; import com.vaadin.flow.component.grid.HeaderRow; +import com.vaadin.flow.component.grid.contextmenu.GridContextMenu; +import com.vaadin.flow.component.grid.contextmenu.GridMenuItem; import com.vaadin.flow.component.grid.dataview.GridListDataView; import com.vaadin.flow.component.html.*; import com.vaadin.flow.component.icon.Icon; @@ -45,6 +48,8 @@ import net.sf.jasperreports.engine.JasperPrint; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.*; import org.springframework.core.env.Environment; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.vaadin.lineawesome.LineAwesomeIcon; import java.io.*; @@ -114,6 +119,14 @@ public class PlanAnualView extends VerticalLayout { headerRow.getCell(planAnualGrid.getColumnByKey("departamento")) .setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento)); + headerRow.getCell(planAnualGrid.getColumnByKey("mesplaneado")) + .setComponent(createFilterHeader("Mes Planeado", planAnualFilter::setMesPlaneado)); + + + + // MENU CONTEXTUAL DEL GRID + PersonContextMenu contextMenu = new PersonContextMenu(planAnualGrid); + // Componente UPLOAD para subir archivos @@ -486,6 +499,7 @@ public class PlanAnualView extends VerticalLayout { private String smt; private String equipo; private String departamento; + private String mesPlaneado; private boolean excludeRealizado = true; public PlanAnualFilter(GridListDataView dataView) { @@ -508,6 +522,11 @@ public class PlanAnualView extends VerticalLayout { this.dataView.refreshAll(); } + public void setMesPlaneado(String mesPlaneado) { + this.mesPlaneado = mesPlaneado; + this.dataView.refreshAll(); + } + public void setExcludeRealizado(boolean excludeRealizado) { this.excludeRealizado = excludeRealizado; this.dataView.refreshAll(); @@ -521,14 +540,15 @@ public class PlanAnualView extends VerticalLayout { boolean matchesSmt = matches(planAnual.getSmt(), smt); boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo); boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento); + boolean matchesMesPlaneado = matches(planAnual.getMesplaneado(), mesPlaneado); if (excludeRealizado) { // Mostrar solo los pendientes - return matchesSmt && matchesEquipo && matchesDepartamento + return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado && (planAnual.getEstado() == null || !"REALIZADO".equalsIgnoreCase(planAnual.getEstado())); } else { // Mostrar solo realizados - return matchesSmt && matchesEquipo && matchesDepartamento + return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado && "REALIZADO".equalsIgnoreCase(planAnual.getEstado()); } } @@ -835,4 +855,96 @@ public class PlanAnualView extends VerticalLayout { dialog.add(layout); dialog.open(); } + + + private class PersonContextMenu extends GridContextMenu { + public PersonContextMenu(Grid target) { + super(target); + + addItem("Realizar", e -> e.getItem().ifPresent(planAnual -> { + int idPlananual = planAnual.getNumero(); + LocalDate fechaSistema = LocalDate.now(); + String nomEquipo = planAnual.getNomEquipo(); + String departamento = planAnual.getDepartamento(); + + getUI().ifPresent(ui -> ui.navigate( + "mantenimiento?id=" + idPlananual + + "&fecha=" + fechaSistema + + "&tipo=1" + + "&nomEquipo=" + nomEquipo + + "&departamento=" + departamento)); + })); + + addItem("Borrar", e -> e.getItem().ifPresent(planAnual -> { + eliminarPlanAnual(planAnual); + })); + + add(new Hr()); + + GridMenuItem nomEquipo = addItem("Equipo", + e -> e.getItem().ifPresent(planAnual -> { + planAnual.getNomEquipo(); + })); + + GridMenuItem depto = addItem("Departamento", + e -> e.getItem().ifPresent(planAnual -> { + planAnual.getDepartamento(); + })); + + setDynamicContentHandler(planAnual -> { + if (planAnual == null) + return false; + nomEquipo.setText(String.format("Equipo: %s", planAnual.getNomEquipo())); + depto.setText(String.format("Area: %s", planAnual.getDepartamento())); + + return true; + }); + } + } + + private void eliminarPlanAnual(PlanAnual planAnual) { + Dialog dialog = new Dialog(); + dialog.setHeaderTitle("Eliminar Mantenimiento"); + + TextField txtMotivo = new TextField("Justifica el motivo de la eliminación"); + txtMotivo.setWidthFull(); + txtMotivo.setRequired(true); + + dialog.add( + new VerticalLayout( + new Span("¿Estás seguro de que deseas eliminar el mantenimiento del equipo: " + planAnual.getNomEquipo()), + txtMotivo + ) + ); + + Button btnEliminar = new Button("Eliminar", VaadinIcon.TRASH.create(), event -> { + String motivo = txtMotivo.getValue(); + if (motivo.isEmpty()) { + txtMotivo.setErrorMessage("El motivo es requerido."); + txtMotivo.setInvalid(true); + return; + } + txtMotivo.setInvalid(false); + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String usuarioId = authentication != null ? authentication.getName().toUpperCase() : "DESCONOCIDO"; + LocalDate fecha = LocalDate.now(); + + // Llamar al servicio para insertar la bitácora de eliminación + databaseService.insertarBitacoraEliminacion(planAnual.getNumero(), usuarioId, fecha, motivo); + + // Llamar al servicio para eliminar el plan anual + databaseService.eliminarEquipoPlanAnual(planAnual.getNumero()); + Notification.show("Equipo eliminado correctamente", 3000, Notification.Position.MIDDLE) + .addThemeVariants(NotificationVariant.LUMO_SUCCESS); + dialog.close(); + UI.getCurrent().getPage().executeJs("setTimeout(() => { location.reload(); }, 2000);"); + }); + + Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); + + HorizontalLayout dialogFooter = new HorizontalLayout(btnEliminar, btnCancelar); + dialog.getFooter().add(dialogFooter); + dialog.open(); + } }