3 Commits

10 changed files with 481 additions and 20 deletions
Unified View
  1. BIN
      src/main/bundles/dev.bundle
  2. BIN
      src/main/bundles/prod.bundle
  3. +24
    -5
      src/main/frontend/themes/sistema-mantenimiento/styles.css
  4. +86
    -0
      src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java
  5. +7
    -2
      src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java
  6. +1
    -1
      src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
  7. +15
    -3
      src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
  8. +346
    -7
      src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
  9. +2
    -2
      src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java
  10. BIN
      src/main/resources/META-INF/resources/reportes/listadoMantenimientos.jasper

BIN
src/main/bundles/dev.bundle View File


BIN
src/main/bundles/prod.bundle View File


+ 24
- 5
src/main/frontend/themes/sistema-mantenimiento/styles.css View File

@ -212,8 +212,9 @@ vaadin-button:not([theme]) {
color: #a02142; color: #a02142;
} }
vaadin-button:hover::before {
color: blue;
vaadin-button[theme~="tertiary-inline"], vaadin-button[theme~="icon"] {
color: #a02142;
} }
/* Estilos para el theme personalizado 'subir-archivo' */ /* Estilos para el theme personalizado 'subir-archivo' */
@ -270,6 +271,24 @@ vaadin-login-form-wrapper::part(error-message) {
color: #a02142; color: #a02142;
} }
/* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */
/* (*)(*) ESTILOS PARA EL TAMAÑO DEL GRID (*)(*) */
/* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */
vaadin-popover-overlay::part(overlay) {
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
@media (max-width: 900px) {
.v-horizontallayout {
flex-direction: column !important;
align-items: stretch !important;
}
.mantenimiento-text-field,
.mantenimiento-combo,
vaadin-text-field,
vaadin-combo-box {
min-width: 0;
width: 100% !important;
box-sizing: border-box;
}
}

+ 86
- 0
src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java View File

@ -539,6 +539,7 @@ public class DatabaseService {
} }
// INSERTAR ARCHIVO EXCEL EN LA TABLA: PLANANUAL
public void insertarDesdeExcel(InputStream inputStream) { public void insertarDesdeExcel(InputStream inputStream) {
String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO, MOUSE, " + String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO, MOUSE, " +
"REGULADOR, CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG, TECNICOSMT, ESTADO) " + "REGULADOR, CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG, TECNICOSMT, ESTADO) " +
@ -612,6 +613,54 @@ public class DatabaseService {
} }
} }
// INSERTAR NUEVO EQUIPO INDIVIDUAL EN PLANANUAL
public void insertarNuevoEquipo(String nomequipo, String area, boolean monitor, boolean teclado,
boolean mouse, boolean regulador, boolean cpu, boolean impresora,
boolean miniprint, boolean laptop, boolean escaner, Date fechaprog,
String tecnicosmt, String estado, Integer mesId) {
String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO,MOUSE, REGULADOR,\n" +
"CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG,\n" +
"TECNICOSMT, ESTADO, MESID)\n" +
"VALUES (?, ?,\n" +
"?, ?, ?, ?, ?, ?, ?, ?, ?,\n" +
"?, ?, ?, ?)";
try (Connection conn = getMysqlConnection();
PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setString(1, nomequipo);
stmt.setString(2, area);
stmt.setBoolean(3, monitor);
stmt.setBoolean(4, teclado);
stmt.setBoolean(5, mouse);
stmt.setBoolean(6, regulador);
stmt.setBoolean(7, cpu);
stmt.setBoolean(8, impresora);
stmt.setBoolean(9, miniprint);
stmt.setBoolean(10, laptop);
stmt.setBoolean(11, escaner);
// Manejo de fechas
if (fechaprog != null) {
stmt.setDate(12, new java.sql.Date(fechaprog.getTime()));
} else {
stmt.setNull(12, java.sql.Types.DATE); // Manejo de valor nulo
}
stmt.setString(13, tecnicosmt);
stmt.setString(14, estado);
stmt.setInt(15, mesId);
stmt.executeUpdate();
} catch (SQLException e) {
System.err.println("Error al insertar nuevo equipo en PLANANUAL: " + e.getMessage());
}
}
// Método auxiliar para obtener un valor de tipo Date de una celda // Método auxiliar para obtener un valor de tipo Date de una celda
private Date getDateCellValue(Cell cell) { private Date getDateCellValue(Cell cell) {
if (cell != null) { if (cell != null) {
@ -757,4 +806,41 @@ public class DatabaseService {
return false; 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();
}
}
} }

+ 7
- 2
src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java View File

@ -8,7 +8,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.html.Anchor; import com.vaadin.flow.component.html.Anchor;
import com.vaadin.flow.server.StreamRegistration;
import com.vaadin.flow.server.StreamResource; import com.vaadin.flow.server.StreamResource;
import mx.gob.jumapacelaya.services.ReportService; import mx.gob.jumapacelaya.services.ReportService;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -282,14 +284,17 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
// Se crea el recurso para descarga // Se crea el recurso para descarga
StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf)); StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf));
Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
/*Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
downloadLink.setTarget("_blank"); downloadLink.setTarget("_blank");
downloadLink.setId("descargar-reporte-link"); downloadLink.setId("descargar-reporte-link");
add(downloadLink); add(downloadLink);
getUI().ifPresent(ui -> getUI().ifPresent(ui ->
ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();") ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();")
);
);*/
StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource);
UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')");
} catch (Exception ex) { } catch (Exception ex) {
Notification.show("Error al generar el reporte: " + ex.getMessage(), 4000, Notification.Position.MIDDLE) Notification.show("Error al generar el reporte: " + ex.getMessage(), 4000, Notification.Position.MIDDLE)


+ 1
- 1
src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java View File

@ -72,7 +72,7 @@ public class MainLayout extends AppLayout {
headerLayout.setAlignItems(FlexComponent.Alignment.CENTER); headerLayout.setAlignItems(FlexComponent.Alignment.CENTER);
headerLayout.getStyle().set("background-color", "#DDC9A3"); headerLayout.getStyle().set("background-color", "#DDC9A3");
Image imgLogo = new Image("images/900X160.png", "Logo");
Image imgLogo = new Image("images/LOGO_900X160.png", "Logo");
imgLogo.setWidthFull(); imgLogo.setWidthFull();
headerLayout.add(imgLogo); headerLayout.add(imgLogo);


+ 15
- 3
src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java View File

@ -76,6 +76,7 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
private LocalDate fechaProgramada; private LocalDate fechaProgramada;
private LocalDate fechaSeleccionada; private LocalDate fechaSeleccionada;
private TextArea jsutificacion; private TextArea jsutificacion;
private VerticalLayout mainLayout;
Span userSignSpan = new Span("Nombre Usuario"); Span userSignSpan = new Span("Nombre Usuario");
@ -92,6 +93,15 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
this.userService = userService; this.userService = userService;
this.emailService = emailService; this.emailService = emailService;
mainLayout = new VerticalLayout();
mainLayout.setHeightFull();
mainLayout.getStyle()
.set("box-shadow","0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "12px")
.set("background-color", "white")
.set("padding", "1rem")
.set("margin", "1rem auto");
HorizontalLayout fechaLayout = new HorizontalLayout(); HorizontalLayout fechaLayout = new HorizontalLayout();
//Componentes de texto //Componentes de texto
TextField nomenclatura = new TextField("Nomenclatura"); TextField nomenclatura = new TextField("Nomenclatura");
@ -211,7 +221,8 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
buttons(); buttons();
add(fechaLayout, departamentoLayout, controlsLayout, actualizacionesLayout, etiquetaLayout, firmasLayout, botonesLayout);
mainLayout.add(fechaLayout, departamentoLayout, controlsLayout, actualizacionesLayout, etiquetaLayout, firmasLayout, botonesLayout);
add(mainLayout);
} }
@ -451,7 +462,7 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
smtSignPad.setHeight("200px"); smtSignPad.setHeight("200px");
smtSignPad.setBackgroundColor("#FFFFFF"); smtSignPad.setBackgroundColor("#FFFFFF");
smtSignPad.setPenColor("#000000"); smtSignPad.setPenColor("#000000");
smtSignPad.getElement().getStyle().set("border", "2px solid black");
smtSignPad.getElement().getStyle().set("border", "1px solid black");
String u = securityService.getAuthenticatedUser(); String u = securityService.getAuthenticatedUser();
Span smtSignSpan = new Span(u); Span smtSignSpan = new Span(u);
Span tituloSMT = new Span("Responsable de Soporte"); Span tituloSMT = new Span("Responsable de Soporte");
@ -475,8 +486,9 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
firmasLayout.add(userSignLayout, smtSignLayout, gcialSignLayout); firmasLayout.add(userSignLayout, smtSignLayout, gcialSignLayout);
firmasLayout.setSizeFull();
firmasLayout.setWidthFull();
firmasLayout.setSpacing(false); firmasLayout.setSpacing(false);
firmasLayout.setJustifyContentMode(JustifyContentMode.CENTER);
} }


+ 346
- 7
src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java View File

@ -1,17 +1,23 @@
package mx.gob.jumapacelaya.ui; package mx.gob.jumapacelaya.ui;
import com.vaadin.flow.component.Component; import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.checkbox.CheckboxGroup; import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.checkbox.CheckboxGroupVariant; 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.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dialog.Dialog; import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant; import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.grid.HeaderRow; 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.grid.dataview.GridListDataView;
import com.vaadin.flow.component.html.*; import com.vaadin.flow.component.html.*;
import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.icon.Icon;
@ -23,6 +29,7 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.popover.Popover; import com.vaadin.flow.component.popover.Popover;
import com.vaadin.flow.component.popover.PopoverPosition; import com.vaadin.flow.component.popover.PopoverPosition;
import com.vaadin.flow.component.radiobutton.RadioButtonGroup; import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer; import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
@ -30,6 +37,7 @@ import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.function.ValueProvider; import com.vaadin.flow.function.ValueProvider;
import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.StreamRegistration;
import com.vaadin.flow.server.StreamResource; import com.vaadin.flow.server.StreamResource;
import jakarta.annotation.security.PermitAll; import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.PlanAnual; import mx.gob.jumapacelaya.models.PlanAnual;
@ -40,6 +48,8 @@ import net.sf.jasperreports.engine.JasperPrint;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.springframework.core.env.Environment; 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 org.vaadin.lineawesome.LineAwesomeIcon;
import java.io.*; import java.io.*;
@ -71,7 +81,9 @@ public class PlanAnualView extends VerticalLayout {
Grid<PlanAnual> planAnualGrid; Grid<PlanAnual> planAnualGrid;
Button btnColumns; Button btnColumns;
Button btnImprimirRpt; Button btnImprimirRpt;
Button btnAddEquipo;
HorizontalLayout btnImprimirLayout; HorizontalLayout btnImprimirLayout;
private Popover reportePopover;
public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) { public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) {
this.databaseService = databaseService; this.databaseService = databaseService;
@ -107,6 +119,14 @@ public class PlanAnualView extends VerticalLayout {
headerRow.getCell(planAnualGrid.getColumnByKey("departamento")) headerRow.getCell(planAnualGrid.getColumnByKey("departamento"))
.setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento)); .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 // Componente UPLOAD para subir archivos
@ -191,6 +211,7 @@ public class PlanAnualView extends VerticalLayout {
}); });
filtrosLayout.add(btnPendientes, btnRealizados); filtrosLayout.add(btnPendientes, btnRealizados);
mostrarPopoverReportes();
this.setPadding(false); this.setPadding(false);
@ -299,7 +320,7 @@ public class PlanAnualView extends VerticalLayout {
/*planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSmt) /*planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSmt)
.setHeader("S.M.T").setKey("smtColumnKey");*/ .setHeader("S.M.T").setKey("smtColumnKey");*/
// Iconos en columnas booleanas // Iconos en columnas booleanas
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor").setKey("monitor"); planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor").setKey("monitor");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado").setKey("teclado"); planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado").setKey("teclado");
@ -321,9 +342,14 @@ public class PlanAnualView extends VerticalLayout {
btnColumns.setTooltipText("Show/Hide Columns"); btnColumns.setTooltipText("Show/Hide Columns");
btnImprimirRpt = new Button(VaadinIcon.PRINT.create()); btnImprimirRpt = new Button(VaadinIcon.PRINT.create());
btnImprimirRpt.addClickListener(event -> sacarReporte());
btnImprimirRpt.addClickListener(event -> reportePopover.open());
btnImprimirRpt.setTooltipText("Imprimir reporte"); btnImprimirRpt.setTooltipText("Imprimir reporte");
btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt);
btnAddEquipo = new Button(VaadinIcon.PLUS.create());
btnAddEquipo.addClickListener(event -> addNuevoEquipo());
btnAddEquipo.setTooltipText("Agregar nuevo equipo");
btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo);
HorizontalLayout columnSelectorLayout = new HorizontalLayout(); HorizontalLayout columnSelectorLayout = new HorizontalLayout();
columnSelectorLayout.setAlignItems(Alignment.END); columnSelectorLayout.setAlignItems(Alignment.END);
@ -473,6 +499,7 @@ public class PlanAnualView extends VerticalLayout {
private String smt; private String smt;
private String equipo; private String equipo;
private String departamento; private String departamento;
private String mesPlaneado;
private boolean excludeRealizado = true; private boolean excludeRealizado = true;
public PlanAnualFilter(GridListDataView<PlanAnual> dataView) { public PlanAnualFilter(GridListDataView<PlanAnual> dataView) {
@ -495,6 +522,11 @@ public class PlanAnualView extends VerticalLayout {
this.dataView.refreshAll(); this.dataView.refreshAll();
} }
public void setMesPlaneado(String mesPlaneado) {
this.mesPlaneado = mesPlaneado;
this.dataView.refreshAll();
}
public void setExcludeRealizado(boolean excludeRealizado) { public void setExcludeRealizado(boolean excludeRealizado) {
this.excludeRealizado = excludeRealizado; this.excludeRealizado = excludeRealizado;
this.dataView.refreshAll(); this.dataView.refreshAll();
@ -508,14 +540,15 @@ public class PlanAnualView extends VerticalLayout {
boolean matchesSmt = matches(planAnual.getSmt(), smt); boolean matchesSmt = matches(planAnual.getSmt(), smt);
boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo); boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo);
boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento); boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento);
boolean matchesMesPlaneado = matches(planAnual.getMesplaneado(), mesPlaneado);
if (excludeRealizado) { if (excludeRealizado) {
// Mostrar solo los pendientes // Mostrar solo los pendientes
return matchesSmt && matchesEquipo && matchesDepartamento
return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado
&& (planAnual.getEstado() == null || !"REALIZADO".equalsIgnoreCase(planAnual.getEstado())); && (planAnual.getEstado() == null || !"REALIZADO".equalsIgnoreCase(planAnual.getEstado()));
} else { } else {
// Mostrar solo realizados // Mostrar solo realizados
return matchesSmt && matchesEquipo && matchesDepartamento
return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado
&& "REALIZADO".equalsIgnoreCase(planAnual.getEstado()); && "REALIZADO".equalsIgnoreCase(planAnual.getEstado());
} }
} }
@ -582,14 +615,17 @@ public class PlanAnualView extends VerticalLayout {
// Creando el recurso de descarga // Creando el recurso de descarga
StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf)); StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf));
Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
/*Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
downloadLink.setTarget("_blank"); downloadLink.setTarget("_blank");
downloadLink.setId("descargar-reporte-link"); downloadLink.setId("descargar-reporte-link");
add(downloadLink); add(downloadLink);
getUI().ifPresent(ui -> getUI().ifPresent(ui ->
ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();") ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();")
);
);*/
StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource);
UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')");
} catch (Exception ex) { } catch (Exception ex) {
@ -608,4 +644,307 @@ public class PlanAnualView extends VerticalLayout {
dialog.open(); dialog.open();
} }
private void addNuevoEquipo() {
Dialog dialog = new Dialog();
dialog.setHeaderTitle("Agregar nuevo equipo");
TextField nombreEquipo = new TextField("Nombre equipo:");
TextField area = new TextField("Área:");
DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n()
.setWeekdays(List.of("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sabado"))
.setWeekdaysShort(List.of("Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"))
.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");
DatePicker fechaProgramada = new DatePicker("Fecha programada:");
fechaProgramada.setI18n(i18n);
List<String> items = List.of("ENERO", "FEBRERO", "MARZO", "ABRIL", "MAYO", "JUNIO",
"JULIO", "AGOSTO", "SEPTIEMBRE", "OCTUBRE", "NOVIEMBRE", "DICIEMBRE");
ComboBox<String> cmbMes = new ComboBox<>("Mes Planeado:");
cmbMes.setItems(items);
CheckboxGroup<String> group1 = new CheckboxGroup<>();
group1.setLabel("Seleccione los componentes del equipo");
group1.setItems("MONITOR","TECLADO","MOUSE","REGULADOR");
CheckboxGroup<String> group2 = new CheckboxGroup<>();
group2.setItems("CPU","IMPRESORA","MINIPRINT","LAPTOP","ESCANER");
HorizontalLayout layout1 = new HorizontalLayout(nombreEquipo, area);
HorizontalLayout layout2 = new HorizontalLayout(fechaProgramada,cmbMes);
VerticalLayout layout3 = new VerticalLayout(group1,group2);
layout3.setSpacing(false);
Button btnGuardar = new Button("Guardar", LineAwesomeIcon.SAVE_SOLID.create());
btnGuardar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
btnGuardar.addClickListener(e -> {
if (nombreEquipo.getValue().isEmpty() || area.getValue().isEmpty() ||
fechaProgramada.getValue() == null || cmbMes.getValue() == null) {
Notification.show("Por favor, complete todos los campos.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
final Map<String, Integer> MES_ID_MAP = new HashMap<>();
MES_ID_MAP.put("ENERO", 1);
MES_ID_MAP.put("FEBRERO", 2);
MES_ID_MAP.put("MARZO", 3);
MES_ID_MAP.put("ABRIL", 4);
MES_ID_MAP.put("MAYO", 5);
MES_ID_MAP.put("JUNIO", 6);
MES_ID_MAP.put("JULIO", 7);
MES_ID_MAP.put("AGOSTO", 8);
MES_ID_MAP.put("SEPTIEMBRE", 9);
MES_ID_MAP.put("OCTUBRE", 10);
MES_ID_MAP.put("NOVIEMBRE", 11);
MES_ID_MAP.put("DICIEMBRE", 12);
String mesSeleccionado = cmbMes.getValue();
Integer mesId = MES_ID_MAP.get(mesSeleccionado);
if (group1.getValue().isEmpty() && group2.getValue().isEmpty()) {
Notification.show("Debe seleccionar al menos un componente del equipo.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
Set<String> seleccionados = new HashSet<>();
seleccionados.addAll(group1.getValue());
seleccionados.addAll(group2.getValue());
boolean monitor = seleccionados.contains("MONITOR");
boolean teclado = seleccionados.contains("TECLADO");
boolean mouse = seleccionados.contains("MOUSE");
boolean regulador = seleccionados.contains("REGULADOR");
boolean cpu = seleccionados.contains("CPU");
boolean impresora = seleccionados.contains("IMPRESORA");
boolean miniprint = seleccionados.contains("MINIPRINT");
boolean laptop = seleccionados.contains("LAPTOP");
boolean escaner = seleccionados.contains("ESCANER");
databaseService.insertarNuevoEquipo(
nombreEquipo.getValue().toUpperCase(),
area.getValue().toUpperCase(),
monitor,
teclado,
mouse,
regulador,
cpu,
impresora,
miniprint,
laptop,
escaner,
java.sql.Date.valueOf(fechaProgramada.getValue()),
"",
"PENDIENTE",
mesId
);
Notification.show("Equipo agregado correctamente", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
dialog.close();
// Recargar el grid para mostrar el nuevo equipo
planAnualGrid.setItems(databaseService.getPlanAnual());
});
Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close());
dialog.getFooter().add(btnGuardar);
dialog.getFooter().add(btnCancelar);
dialog.add(layout1,layout2,layout3);
dialog.open();
}
private void mostrarPopoverReportes() {
reportePopover = new Popover();
reportePopover.setModal(true);
reportePopover.setBackdropVisible(true);
reportePopover.setPosition(PopoverPosition.BOTTOM_END);
reportePopover.setTarget(btnImprimirRpt);
Div headding = new Div("Reportes disponibles");
headding.getStyle().set("font-weight", "600");
headding.getStyle().set("padding", "var(--lumo-space-xs)");
VerticalLayout listaRrportes = new VerticalLayout();
//listaRrportes.setSpacing(false);
listaRrportes.setPadding(false);
Button btnReporteFechas = new Button("Mantenimiento por fechas", VaadinIcon.STAR.create(), e -> {
reportePopover.close();
sacarReporte();
});
btnReporteFechas.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE);
Button btnListadoMant = new Button("Listado de mantenimientos", VaadinIcon.STAR.create(), e -> {
reportePopover.close();
obtenerListadoRpt();
});
btnListadoMant.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE);
listaRrportes.add(btnReporteFechas, btnListadoMant);
reportePopover.add(headding, listaRrportes);
}
private void obtenerListadoRpt() {
Dialog dialog = new Dialog();
dialog.setHeaderTitle("Ingresa el peridodo a consultar");
TextField txtMes = new TextField("Mes:");
txtMes.setRequired(true);
NumberField txtAnio = new NumberField("Año:");
txtAnio.setRequired(true);
HorizontalLayout layout = new HorizontalLayout(txtMes, txtAnio);
Button btnGenerar = new Button("Generar", VaadinIcon.PRINT.create());
btnGenerar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
btnGenerar.addClickListener(e -> {
String mes = txtMes.getValue().toUpperCase();
Integer anio = txtAnio.getValue() != null ? txtAnio.getValue().intValue() : null;
if (mes.isEmpty() || anio == null) {
Notification.show("Por favor, completa todos los campos.", 2000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
try {
// Preparando los parámetros para el reporte
Map<String, Object> parametros = new HashMap<>();
parametros.put("pMES", mes);
parametros.put("pANIO", anio);
// Generando el PDF
byte[] pdf = reportService.generarReporte("listadoMantenimientos", parametros);
// Creando el recurso de descarga
StreamResource resource = new StreamResource("listado_mantenimientos.pdf", () -> new ByteArrayInputStream(pdf));
/*Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
downloadLink.setTarget("_blank");
downloadLink.setId("descargar-listado-link");
add(downloadLink);
getUI().ifPresent(ui ->
ui.getPage().executeJs("document.getElementById('descargar-listado-link').click();")
);*/
StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource);
UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')");
} catch (Exception ex) {
Notification.show("Error al generar el reporte: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
ex.printStackTrace();
}
});
Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close());
dialog.getFooter().add(btnCancelar, btnGenerar);
dialog.add(layout);
dialog.open();
}
private class PersonContextMenu extends GridContextMenu<PlanAnual> {
public PersonContextMenu(Grid<PlanAnual> 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<PlanAnual> nomEquipo = addItem("Equipo",
e -> e.getItem().ifPresent(planAnual -> {
planAnual.getNomEquipo();
}));
GridMenuItem<PlanAnual> 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();
}
} }

+ 2
- 2
src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java View File

@ -44,7 +44,7 @@ public class LoginView extends VerticalLayout implements BeforeEnterObserver {
// Configuración de i18n para el formulario de login // Configuración de i18n para el formulario de login
LoginI18n i18n = LoginI18n.createDefault(); LoginI18n i18n = LoginI18n.createDefault();
LoginI18n.Form i18nFormulario = i18n.getForm(); LoginI18n.Form i18nFormulario = i18n.getForm();
i18nFormulario.setTitle("Mantenimiento Preventivo y Correctivo (BETA)");
i18nFormulario.setTitle("Mantenimiento Preventivo y Correctivo");
i18nFormulario.setUsername("Usuario"); i18nFormulario.setUsername("Usuario");
i18nFormulario.setPassword("Contraseña"); i18nFormulario.setPassword("Contraseña");
i18nFormulario.setSubmit("Iniciar sesión"); i18nFormulario.setSubmit("Iniciar sesión");
@ -57,7 +57,7 @@ public class LoginView extends VerticalLayout implements BeforeEnterObserver {
i18nError.setMessage("Usuario o contraseña incorrectos, verifica tus credenciales"); i18nError.setMessage("Usuario o contraseña incorrectos, verifica tus credenciales");
i18n.setErrorMessage(i18nError); i18n.setErrorMessage(i18nError);
i18n.setAdditionalInformation("Versión 1.0 Beta");
i18n.setAdditionalInformation("Versión 2.0.0 - © 2024 JUMAPACelaya");
// Configuración del formulario de login // Configuración del formulario de login
login.setAction("login"); login.setAction("login");


BIN
src/main/resources/META-INF/resources/reportes/listadoMantenimientos.jasper View File


Loading…
Cancel
Save