3 Commits

12 changed files with 2933 additions and 2580 deletions
Unified View
  1. +2404
    -2283
      package-lock.json
  2. +55
    -56
      package.json
  3. +6
    -1
      pom.xml
  4. BIN
      src/main/bundles/dev.bundle
  5. BIN
      src/main/bundles/prod.bundle
  6. +1
    -4
      src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java
  7. +56
    -7
      src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java
  8. +1
    -1
      src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java
  9. +2
    -2
      src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
  10. +207
    -162
      src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
  11. +201
    -64
      src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
  12. BIN
      src/main/resources/META-INF/resources/reportes/mantenimientoFechas.jasper

+ 2404
- 2283
package-lock.json
File diff suppressed because it is too large
View File


+ 55
- 56
package.json View File

@ -3,97 +3,96 @@
"license": "UNLICENSED", "license": "UNLICENSED",
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@polymer/polymer": "3.5.1",
"@vaadin/bundles": "24.4.5",
"@polymer/polymer": "3.5.2",
"@vaadin/bundles": "24.5.5",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
"@vaadin/polymer-legacy-adapter": "24.4.5",
"@vaadin/react-components": "24.4.5",
"@vaadin/react-components-pro": "24.4.5",
"@vaadin/router": "1.7.5",
"@vaadin/polymer-legacy-adapter": "24.5.5",
"@vaadin/react-components": "24.5.5",
"@vaadin/react-components-pro": "24.5.5",
"@vaadin/vaadin-development-mode-detector": "2.0.7", "@vaadin/vaadin-development-mode-detector": "2.0.7",
"@vaadin/vaadin-lumo-styles": "24.4.5",
"@vaadin/vaadin-material-styles": "24.4.5",
"@vaadin/vaadin-themable-mixin": "24.4.5",
"@vaadin/vaadin-usage-statistics": "2.1.2",
"@vaadin/vaadin-lumo-styles": "24.5.5",
"@vaadin/vaadin-material-styles": "24.5.5",
"@vaadin/vaadin-themable-mixin": "24.5.5",
"@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4",
"proj4": "2.11.0",
"lit": "3.2.1",
"proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1",
"react-router-dom": "6.28.0",
"signature_pad": "4.1.5" "signature_pad": "4.1.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7",
"@rollup/plugin-replace": "5.0.7",
"@rollup/pluginutils": "5.1.0",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@vitejs/plugin-react": "4.3.1",
"async": "3.2.5",
"glob": "10.4.1",
"@babel/preset-react": "7.26.3",
"@preact/signals-react-transform": "0.4.0",
"@rollup/plugin-replace": "6.0.1",
"@rollup/pluginutils": "5.1.3",
"@types/react": "18.3.13",
"@types/react-dom": "18.3.1",
"@vitejs/plugin-react": "4.3.3",
"async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5",
"vite": "5.3.3",
"vite-plugin-checker": "0.6.4",
"workbox-build": "7.1.1",
"workbox-core": "7.1.0",
"workbox-precaching": "7.1.0"
"typescript": "5.6.3",
"vite": "5.4.11",
"vite-plugin-checker": "0.8.0",
"workbox-build": "7.3.0",
"workbox-core": "7.3.0",
"workbox-precaching": "7.3.0"
}, },
"vaadin": { "vaadin": {
"dependencies": { "dependencies": {
"@polymer/polymer": "3.5.1",
"@vaadin/bundles": "24.4.5",
"@polymer/polymer": "3.5.2",
"@vaadin/bundles": "24.5.5",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
"@vaadin/polymer-legacy-adapter": "24.4.5",
"@vaadin/react-components": "24.4.5",
"@vaadin/react-components-pro": "24.4.5",
"@vaadin/router": "1.7.5",
"@vaadin/polymer-legacy-adapter": "24.5.5",
"@vaadin/react-components": "24.5.5",
"@vaadin/react-components-pro": "24.5.5",
"@vaadin/vaadin-development-mode-detector": "2.0.7", "@vaadin/vaadin-development-mode-detector": "2.0.7",
"@vaadin/vaadin-lumo-styles": "24.4.5",
"@vaadin/vaadin-material-styles": "24.4.5",
"@vaadin/vaadin-themable-mixin": "24.4.5",
"@vaadin/vaadin-usage-statistics": "2.1.2",
"@vaadin/vaadin-lumo-styles": "24.5.5",
"@vaadin/vaadin-material-styles": "24.5.5",
"@vaadin/vaadin-themable-mixin": "24.5.5",
"@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4",
"proj4": "2.11.0",
"lit": "3.2.1",
"proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1",
"react-router-dom": "6.28.0",
"signature_pad": "4.1.5" "signature_pad": "4.1.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7",
"@rollup/plugin-replace": "5.0.7",
"@rollup/pluginutils": "5.1.0",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@vitejs/plugin-react": "4.3.1",
"async": "3.2.5",
"glob": "10.4.1",
"@babel/preset-react": "7.26.3",
"@preact/signals-react-transform": "0.4.0",
"@rollup/plugin-replace": "6.0.1",
"@rollup/pluginutils": "5.1.3",
"@types/react": "18.3.13",
"@types/react-dom": "18.3.1",
"@vitejs/plugin-react": "4.3.3",
"async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5",
"vite": "5.3.3",
"vite-plugin-checker": "0.6.4",
"workbox-build": "7.1.1",
"workbox-core": "7.1.0",
"workbox-precaching": "7.1.0"
"typescript": "5.6.3",
"vite": "5.4.11",
"vite-plugin-checker": "0.8.0",
"workbox-build": "7.3.0",
"workbox-core": "7.3.0",
"workbox-precaching": "7.3.0"
}, },
"hash": "cecfde44fdf74f05a518ad5c890570bd04aa35ca261dade379aac8545a81171b"
"hash": "6126bd412c2a8696938f50edd1abae217c30c0119a0496af47b9d6ba1762921f"
}, },
"overrides": { "overrides": {
"@vaadin/bundles": "$@vaadin/bundles", "@vaadin/bundles": "$@vaadin/bundles",
"@vaadin/polymer-legacy-adapter": "$@vaadin/polymer-legacy-adapter", "@vaadin/polymer-legacy-adapter": "$@vaadin/polymer-legacy-adapter",
"@vaadin/vaadin-development-mode-detector": "$@vaadin/vaadin-development-mode-detector", "@vaadin/vaadin-development-mode-detector": "$@vaadin/vaadin-development-mode-detector",
"@vaadin/router": "$@vaadin/router",
"@vaadin/vaadin-usage-statistics": "$@vaadin/vaadin-usage-statistics", "@vaadin/vaadin-usage-statistics": "$@vaadin/vaadin-usage-statistics",
"@vaadin/react-components": "$@vaadin/react-components", "@vaadin/react-components": "$@vaadin/react-components",
"@vaadin/react-components-pro": "$@vaadin/react-components-pro", "@vaadin/react-components-pro": "$@vaadin/react-components-pro",


+ 6
- 1
pom.xml View File

@ -11,7 +11,7 @@
<properties> <properties>
<java.version>17</java.version> <java.version>17</java.version>
<vaadin.version>24.4.8</vaadin.version>
<vaadin.version>24.5.8</vaadin.version>
</properties> </properties>
<parent> <parent>
@ -178,6 +178,11 @@
<version>7.0.3</version> <version>7.0.3</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies> </dependencies>


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


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


+ 1
- 4
src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java View File

@ -1,9 +1,6 @@
package mx.gob.jumapacelaya.api; package mx.gob.jumapacelaya.api;
import com.nimbusds.jose.shaded.gson.*;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.google.gson.*;
import mx.gob.jumapacelaya.models.RedmineUser; import mx.gob.jumapacelaya.models.RedmineUser;
import mx.gob.jumapacelaya.models.Ticket; import mx.gob.jumapacelaya.models.Ticket;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;


+ 56
- 7
src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java View File

@ -168,11 +168,11 @@ public class DatabaseService {
" p.fechaprog, m.fecha AS fechaMantenimiento,\n" + " p.fechaprog, m.fecha AS fechaMantenimiento,\n" +
" me.NOMBRE AS MESPLANEADO, p.tecnicosmt, p.estado,\n" + " me.NOMBRE AS MESPLANEADO, p.tecnicosmt, p.estado,\n" +
" COALESCE(v.SITUACION, 'NO REALIZADO') AS SITUACION\n" + " COALESCE(v.SITUACION, 'NO REALIZADO') AS SITUACION\n" +
"FROM PLANANUAL p\n" +
"LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\n" +
"LEFT JOIN MESES me ON p.MESID = me.MESID\n" +
"LEFT JOIN VW_SITUACION_MANTENIMIENTO v ON v.PLANANUALID = p.PLANANUALID\n" +
"ORDER BY p.plananualid ASC";
" FROM PLANANUAL p\n" +
" LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\n" +
" LEFT JOIN MESES me ON p.MESID = me.MESID\n" +
" LEFT JOIN VW_SITUACION_MANTENIMIENTO v ON v.PLANANUALID = p.PLANANUALID\n" +
" ORDER BY p.FECHAPROG ASC";
try (Connection connection = getMysqlConnection(); try (Connection connection = getMysqlConnection();
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
@ -209,6 +209,54 @@ public class DatabaseService {
} }
/* ----------------Obtener el Plan Anual de Mantenimiento por ID ---------------- */
public PlanAnual getPlanAnualPorId(int id) {
String query = "SELECT p.plananualid, p.nomEquipo, p.area,\n" +
" p.monitor, p.teclado, p.mouse, p.regulador,\n" +
" p.cpu, p.impresora, p.miniPrint, p.laptop, p.escaner,\n" +
" p.fechaprog, m.fecha AS fechaMantenimiento,\n" +
" me.NOMBRE AS MESPLANEADO, p.tecnicosmt, p.estado,\n" +
" COALESCE(v.SITUACION, 'NO REALIZADO') AS SITUACION\n" +
" FROM PLANANUAL p\n" +
" LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\n" +
" LEFT JOIN MESES me ON p.MESID = me.MESID\n" +
" LEFT JOIN VW_SITUACION_MANTENIMIENTO v ON v.PLANANUALID = p.PLANANUALID\n" +
" where p.plananualid = ?";
try (Connection connection = getMysqlConnection();
PreparedStatement statement = connection.prepareStatement(query)) {
statement.setInt(1, id);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
return new PlanAnual(
resultSet.getInt("plananualid"),
resultSet.getString("nomEquipo"),
resultSet.getString("area"),
resultSet.getBoolean("monitor"),
resultSet.getBoolean("teclado"),
resultSet.getBoolean("mouse"),
resultSet.getBoolean("regulador"),
resultSet.getBoolean("cpu"),
resultSet.getBoolean("impresora"),
resultSet.getBoolean("miniPrint"),
resultSet.getBoolean("laptop"),
resultSet.getBoolean("escaner"),
resultSet.getDate("fechaprog").toLocalDate(), // Cambiado a LocalDate
resultSet.getDate("fechaMantenimiento") != null ? resultSet.getDate("fechaMantenimiento").toLocalDate() : null, // Cambiado a LocalDate
resultSet.getString("mesplaneado"),
resultSet.getString("tecnicosmt"),
resultSet.getString("estado"),
resultSet.getString("SITUACION")
);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/* ----------------Obtener detalles del mantenimiento ---------------- */ /* ----------------Obtener detalles del mantenimiento ---------------- */
public DetalleMantenimientoModel getDetalleMantenimientoPorPlanAnualId(int planAnualId) { public DetalleMantenimientoModel getDetalleMantenimientoPorPlanAnualId(int planAnualId) {
@ -339,10 +387,10 @@ public class DatabaseService {
// INSERTAR EN TABLA: MANTENIMINETOS // INSERTAR EN TABLA: MANTENIMINETOS
public int insertarMantenimiento(LocalDate fecha, String tipoMantId, String departamentoId, String empleadoId, public int insertarMantenimiento(LocalDate fecha, String tipoMantId, String departamentoId, String empleadoId,
String formaMant, String equipoId, String userSignatureBase64, String formaMant, String equipoId, String userSignatureBase64,
String smtSignatureBase64, String planAnualId) {
String smtSignatureBase64, String planAnualId, String justificacion) {
String query = "INSERT INTO MANTENIMIENTOS (fecha, tipoMantId, departamentoId, empleadoId, formaMant, nombreequipo," + String query = "INSERT INTO MANTENIMIENTOS (fecha, tipoMantId, departamentoId, empleadoId, formaMant, nombreequipo," +
" firmaUsuario, firmaSmt, planAnualId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
" firmaUsuario, firmaSmt, planAnualId, justificacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String updateStatusQuery = "UPDATE PLANANUAL SET estado = 'REALIZADO' WHERE planAnualId = ?"; String updateStatusQuery = "UPDATE PLANANUAL SET estado = 'REALIZADO' WHERE planAnualId = ?";
@ -382,6 +430,7 @@ public class DatabaseService {
} }
preparedStatement.setLong(9, Long.parseLong(planAnualId)); preparedStatement.setLong(9, Long.parseLong(planAnualId));
preparedStatement.setString(10, justificacion);
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();


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

@ -283,7 +283,7 @@ 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.getElement().setAttribute("download", true);
downloadLink.setTarget("_blank");
downloadLink.setId("descargar-reporte-link"); downloadLink.setId("descargar-reporte-link");
add(downloadLink); add(downloadLink);


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

@ -44,7 +44,7 @@ public class MainLayout extends AppLayout {
String u = securityService.getAuthenticatedUser(); String u = securityService.getAuthenticatedUser();
Span usrNameLabel = new Span("Hola " + u);
Span usrNameLabel = new Span(u);
usrNameLabel.getStyle().set("color", "#691b31"); usrNameLabel.getStyle().set("color", "#691b31");
usrNameLabel.getStyle().set("font-weight", "bold"); usrNameLabel.getStyle().set("font-weight", "bold");
usrNameLabel.getStyle().set("font-size", "20px"); usrNameLabel.getStyle().set("font-size", "20px");
@ -88,7 +88,7 @@ public class MainLayout extends AppLayout {
nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create())); nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create()));
nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create())); nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create()));
nav.addItem(new SideNavItem("Mantenimiento", MantenimientoView.class, VaadinIcon.WRENCH.create()));
//nav.addItem(new SideNavItem("Mantenimiento", MantenimientoView.class, VaadinIcon.WRENCH.create()));
nav.getStyle().set("background-color", "white"); nav.getStyle().set("background-color", "white");
nav.getStyle().set("border-radius", "5px"); nav.getStyle().set("border-radius", "5px");
nav.getStyle().set("opacity", "0.9"); nav.getStyle().set("opacity", "0.9");


+ 207
- 162
src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java View File

@ -7,6 +7,7 @@ import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.combobox.ComboBox;
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.html.H1; import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H2; import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Image; import com.vaadin.flow.component.html.Image;
@ -29,10 +30,7 @@ import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import de.f0rce.signaturepad.SignaturePad; import de.f0rce.signaturepad.SignaturePad;
import jakarta.annotation.security.PermitAll; import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.DepartamentosModel;
import mx.gob.jumapacelaya.models.TiposHardware;
import mx.gob.jumapacelaya.models.TiposMantenimiento;
import mx.gob.jumapacelaya.models.Usuario;
import mx.gob.jumapacelaya.models.*;
import mx.gob.jumapacelaya.services.DatabaseService; import mx.gob.jumapacelaya.services.DatabaseService;
import mx.gob.jumapacelaya.services.EmailService; import mx.gob.jumapacelaya.services.EmailService;
import mx.gob.jumapacelaya.services.SecurityService; import mx.gob.jumapacelaya.services.SecurityService;
@ -74,6 +72,10 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
private SignaturePad userSignPad; private SignaturePad userSignPad;
private SignaturePad smtSignPad; private SignaturePad smtSignPad;
//private SignaturePad gciatiSignPad; //private SignaturePad gciatiSignPad;
private PlanAnual planAnualActual;
private LocalDate fechaProgramada;
private LocalDate fechaSeleccionada;
private TextArea jsutificacion;
Span userSignSpan = new Span("Nombre Usuario"); Span userSignSpan = new Span("Nombre Usuario");
@ -496,209 +498,244 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
btnGuardar.addClickListener(event -> { btnGuardar.addClickListener(event -> {
LocalDate fechaSeleccionada = fecha.getValue();
TiposMantenimiento tiposMantenimiento = tipoMantt.getValue();
String tipoMantId = tiposMantenimiento != null ? tiposMantenimiento.getTipomantId() : null;
String planAnualValue = txtPlananualID.getValue();
if (planAnualActual == null) {
Notification.show("No se pudo cargar el Plan Anual. Verifica el ID.", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
DepartamentosModel departamentoSeleccionado = area.getValue();
String departamentoId = departamentoSeleccionado != null ? departamentoSeleccionado.getDepartamentoId().toString() : null;
if (planAnualActual != null) {
fechaProgramada = planAnualActual.getFechaProgramada();
fechaSeleccionada = fecha.getValue();
boolean mismoMes = fechaSeleccionada != null &&
fechaSeleccionada.getMonthValue() == fechaProgramada.getMonthValue() &&
fechaSeleccionada.getYear() == fechaProgramada.getYear();
if (!mismoMes) {
Dialog confirmDialog = new Dialog();
Span aviso = new Span("El mantenimiento esta fuera de tiempo, justifique el motivo");
jsutificacion = new TextArea();
jsutificacion.setSizeFull();
Button btnSi = new Button("Guardar",LineAwesomeIcon.SAVE_SOLID.create(), e -> {
confirmDialog.close();
guardarMantenimiento();
});
btnSi.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
VerticalLayout layout = new VerticalLayout(aviso, jsutificacion, btnSi);
layout.setSizeFull();
layout.setAlignItems(Alignment.CENTER);
confirmDialog.add(layout);
confirmDialog.open();
} else {
guardarMantenimiento();
}
}
});
Usuario usuarioSeleccionado = usuario.getValue();
String empleadoId = usuarioSeleccionado != null ? usuarioSeleccionado.getEmpleadoId().toString() : null;
String equipoId = txtNombreEquipo.getValue();
buttonsLayout.setSizeFull();
buttonsLayout.add(btnGuardar);
buttonsLayout.setAlignItems(Alignment.CENTER);
botonesLayout.add(buttonsLayout);
botonesLayout.setSizeFull();
//botonesLayout.setAlignItems(Alignment.CENTER);
}
String formaSeleccionada = formaGroup.getValue();
String formaMantt = null;
if ("Remota".equals(formaSeleccionada)) {
formaMantt = "R";
} else if ("Manual".equals(formaSeleccionada)) {
formaMantt = "M";
}
// Validación de campos obligatorios
if (fechaSeleccionada == null || tipoMantId == null || departamentoId == null || empleadoId == null ||
equipoId == null || equipoId.trim().isEmpty() || formaMantt == null || planAnualValue == null || planAnualValue.trim().isEmpty()) {
Notification.show("Por favor, completa todos los campos requeridos", 4000, Notification.Position.MIDDLE);
return;
}
// METODO PARA ENVIAR CORREOS ELECTRONICOS
private void enviarCorreo() {
Usuario usuarioSeleccionado = usuario.getValue();
if (usuarioSeleccionado != null && usuarioSeleccionado.getEmail() != null) {
String destinatario = usuarioSeleccionado.getEmail();
String asunto = "MANTENIMIENTO DE EQUIPO DE COMPUTO REALIZADO";
String cuerpo = "<html>" +
"<body>" +
"<img src='cid:image_id'/>"+
"</body>" +
"</html>";
String imagePath = "META-INF/resources/images/imgCorreo/correoMantt.png";
byte[] userSignatureBytes = userSignPad.getImageBase64();
byte[] smtSignatureBytes = smtSignPad.getImageBase64();
//byte[] gciaSignatureBytes = gciatiSignPad.getImageBase64();
emailService.enviarCorreo(destinatario, asunto, cuerpo, imagePath);
String userSignatureBase64 = Base64.getEncoder().encodeToString(userSignatureBytes);
String smtSignatureBase64 = Base64.getEncoder().encodeToString(smtSignatureBytes);
//String gciaSignatureBase64 = Base64.getEncoder().encodeToString(gciaSignatureBytes);
} else {
Notification.show("Por favor selecciona un usuario", 4000, Notification.Position.MIDDLE);
}
}
if (esFirmaVacia(userSignatureBase64)) userSignatureBase64 = null;
if (esFirmaVacia(smtSignatureBase64)) smtSignatureBase64 = null;
//if (esFirmaVacia(gciaSignatureBase64)) gciaSignatureBase64 = null;
private void guardarMantenimiento() {
TiposMantenimiento tiposMantenimiento = tipoMantt.getValue();
String tipoMantId = tiposMantenimiento != null ? tiposMantenimiento.getTipomantId() : null;
String planAnualValue = txtPlananualID.getValue();
String justificacionValue = jsutificacion != null ? jsutificacion.getValue() : null;
// Validación de campos de hardware
List<Map<String, String>> detallesHardware = new ArrayList<>();
for (HorizontalLayout layout : hardwareLayouts) {
ComboBox<TiposHardware> tipoHardware = (ComboBox<TiposHardware>) layout.getComponentAt(0);
TextField noSerie = (TextField) layout.getComponentAt(1);
TextField modelo = (TextField) layout.getComponentAt(2);
TextField placa = (TextField) layout.getComponentAt(3);
TiposHardware tipoSeleccionado = tipoHardware.getValue();
if (tipoSeleccionado == null) {
Notification.show("Por favor, selecciona un tipo de hardware", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
DepartamentosModel departamentoSeleccionado = area.getValue();
String departamentoId = departamentoSeleccionado != null ? departamentoSeleccionado.getDepartamentoId().toString() : null;
Usuario usuarioSeleccionado = usuario.getValue();
String empleadoId = usuarioSeleccionado != null ? usuarioSeleccionado.getEmpleadoId().toString() : null;
String equipoId = txtNombreEquipo.getValue();
String formaSeleccionada = formaGroup.getValue();
String formaMantt = null;
if ("Remota".equals(formaSeleccionada)) {
formaMantt = "R";
} else if ("Manual".equals(formaSeleccionada)) {
formaMantt = "M";
}
// Validación de campos obligatorios
if (fechaSeleccionada == null || tipoMantId == null || departamentoId == null || empleadoId == null ||
equipoId == null || equipoId.trim().isEmpty() || formaMantt == null || planAnualValue == null || planAnualValue.trim().isEmpty()) {
Notification.show("Por favor, completa todos los campos requeridos", 4000, Notification.Position.MIDDLE);
return;
}
boolean esOpcional = Arrays.asList("TECLADO", "MOUSE").contains(tipoSeleccionado.getNombreHardware());
String numSerie = noSerie.getValue();
String modeloVal = modelo.getValue();
String placaVal = placa.getValue();
byte[] userSignatureBytes = userSignPad.getImageBase64();
byte[] smtSignatureBytes = smtSignPad.getImageBase64();
//byte[] gciaSignatureBytes = gciatiSignPad.getImageBase64();
if (!esOpcional && (modeloVal == null || modeloVal.isEmpty() || numSerie == null || numSerie.isEmpty() || placaVal == null || placaVal.isEmpty())) {
Notification.show("Por favor, completa todos los campos de hardware.", 4000, Notification.Position.MIDDLE)
String userSignatureBase64 = Base64.getEncoder().encodeToString(userSignatureBytes);
String smtSignatureBase64 = Base64.getEncoder().encodeToString(smtSignatureBytes);
//String gciaSignatureBase64 = Base64.getEncoder().encodeToString(gciaSignatureBytes);
if (esFirmaVacia(userSignatureBase64)) userSignatureBase64 = null;
if (esFirmaVacia(smtSignatureBase64)) smtSignatureBase64 = null;
//if (esFirmaVacia(gciaSignatureBase64)) gciaSignatureBase64 = null;
// Validación de campos de hardware
List<Map<String, String>> detallesHardware = new ArrayList<>();
for (HorizontalLayout layout : hardwareLayouts) {
ComboBox<TiposHardware> tipoHardware = (ComboBox<TiposHardware>) layout.getComponentAt(0);
TextField noSerie = (TextField) layout.getComponentAt(1);
TextField modelo = (TextField) layout.getComponentAt(2);
TextField placa = (TextField) layout.getComponentAt(3);
TiposHardware tipoSeleccionado = tipoHardware.getValue();
if (tipoSeleccionado == null) {
Notification.show("Por favor, selecciona un tipo de hardware", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING); .addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
return;
}
boolean esOpcional = Arrays.asList("TECLADO", "MOUSE").contains(tipoSeleccionado.getNombreHardware());
Map<String, String> hw = new HashMap<>();
hw.put("tipoHardwareId", tipoSeleccionado.getTipoHardwareId());
hw.put("numSerie", numSerie);
hw.put("modelo", modeloVal);
hw.put("placa", placaVal);
detallesHardware.add(hw);
String numSerie = noSerie.getValue();
String modeloVal = modelo.getValue();
String placaVal = placa.getValue();
if (!esOpcional && (modeloVal == null || modeloVal.isEmpty() || numSerie == null || numSerie.isEmpty() || placaVal == null || placaVal.isEmpty())) {
Notification.show("Por favor, completa todos los campos de hardware.", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
} }
Set<String> actualizacionesSeleccionadas = actualizaciones.getSelectedItems();
String otrasActualizaciones = null;
if ("Si".equals(masActualizacionesGroup.getValue())) {
otrasActualizaciones = txtCuales.getValue();
if (otrasActualizaciones == null || otrasActualizaciones.trim().isEmpty()) {
Notification.show("Especifica las otras actualizaciones", 4000, Notification.Position.MIDDLE)
Map<String, String> hw = new HashMap<>();
hw.put("tipoHardwareId", tipoSeleccionado.getTipoHardwareId());
hw.put("numSerie", numSerie);
hw.put("modelo", modeloVal);
hw.put("placa", placaVal);
detallesHardware.add(hw);
}
Set<String> actualizacionesSeleccionadas = actualizaciones.getSelectedItems();
String otrasActualizaciones = null;
if ("Si".equals(masActualizacionesGroup.getValue())) {
otrasActualizaciones = txtCuales.getValue();
if (otrasActualizaciones == null || otrasActualizaciones.trim().isEmpty()) {
Notification.show("Especifica las otras actualizaciones", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING); .addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
return;
} }
}
// Una vez que validamos todos los campos del formulario, procedemos a insertar en BD
try {
int isInserted = databaseService.insertarMantenimiento(fechaSeleccionada, tipoMantId, departamentoId, empleadoId, formaMantt, equipoId, userSignatureBase64, smtSignatureBase64, planAnualValue);
// Una vez que validamos todos los campos del formulario, procedemos a insertar en BD
try {
int isInserted = databaseService.insertarMantenimiento(fechaSeleccionada, tipoMantId, departamentoId, empleadoId, formaMantt, equipoId, userSignatureBase64, smtSignatureBase64, planAnualValue, justificacionValue);
if (isInserted <= 0) {
Notification.show("Error al guardar el mantenimiento", 4000, Notification.Position.MIDDLE)
if (isInserted <= 0) {
Notification.show("Error al guardar el mantenimiento", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR); .addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
return;
}
int mantenimientoId = databaseService.getUltimoMantenimientoId();
int mantenimientoId = databaseService.getUltimoMantenimientoId();
for (Map<String, String> hw : detallesHardware) {
boolean ok = databaseService.insertarHardware(
for (Map<String, String> hw : detallesHardware) {
boolean ok = databaseService.insertarHardware(
hw.get("tipoHardwareId"), hw.get("tipoHardwareId"),
hw.get("numSerie"), hw.get("numSerie"),
hw.get("modelo"), hw.get("modelo"),
hw.get("placa"), hw.get("placa"),
mantenimientoId mantenimientoId
);
);
if (!ok) {
Notification.show("Error al insertar detalles del hardware: ", 4000, Notification.Position.MIDDLE)
if (!ok) {
Notification.show("Error al insertar detalles del hardware: ", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR); .addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
return;
} }
}
for (String act : actualizacionesSeleccionadas) {
boolean ok = databaseService.insertActualizacionSeg(act, null, mantenimientoId);
if (!ok) {
Notification.show("Error al insertar actualización de seguridad", 4000, Notification.Position.MIDDLE)
for (String act : actualizacionesSeleccionadas) {
boolean ok = databaseService.insertActualizacionSeg(act, null, mantenimientoId);
if (!ok) {
Notification.show("Error al insertar actualización de seguridad", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR); .addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
return;
} }
}
if (otrasActualizaciones != null) {
boolean ok = databaseService.insertActualizacionSeg("Otras", otrasActualizaciones, mantenimientoId);
if (!ok) {
Notification.show("Error al insertar otras actualizaciones", 4000, Notification.Position.MIDDLE)
if (otrasActualizaciones != null) {
boolean ok = databaseService.insertActualizacionSeg("Otras", otrasActualizaciones, mantenimientoId);
if (!ok) {
Notification.show("Error al insertar otras actualizaciones", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR); .addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
return;
} }
}
// === EXITO ===
Notification.show("¡Mantenimiento guardado exitosamente!", 4000, Notification.Position.MIDDLE)
// === EXITO ===
Notification.show("¡Mantenimiento guardado exitosamente!", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_SUCCESS); .addThemeVariants(NotificationVariant.LUMO_SUCCESS);
try {
enviarCorreo();
} catch (Exception e) {
Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE)
try {
enviarCorreo();
} catch (Exception e) {
Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR); .addThemeVariants(NotificationVariant.LUMO_ERROR);
e.printStackTrace();
}
// Limpiar campos
fecha.clear();
txtPlananualID.clear();
tipoMantt.clear();
area.clear();
usuario.clear();
txtNombreEquipo.clear();
formaGroup.clear();
actualizaciones.clear();
masActualizacionesGroup.clear();
txtCuales.clear();
userSignPad.clear();
smtSignPad.clear();
//gciatiSignPad.clear();
for (HorizontalLayout layout : hardwareLayouts) {
((ComboBox<?>) layout.getComponentAt(0)).clear();
((TextField) layout.getComponentAt(1)).clear();
((TextField) layout.getComponentAt(2)).clear();
((TextField) layout.getComponentAt(3)).clear();
}
UI.getCurrent().navigate("/");
} catch (Exception ex) {
Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
ex.printStackTrace();
e.printStackTrace();
} }
});
buttonsLayout.setSizeFull();
buttonsLayout.add(btnGuardar);
buttonsLayout.setAlignItems(Alignment.CENTER);
botonesLayout.add(buttonsLayout);
botonesLayout.setSizeFull();
//botonesLayout.setAlignItems(Alignment.CENTER);
}
// METODO PARA ENVIAR CORREOS ELECTRONICOS
private void enviarCorreo() {
Usuario usuarioSeleccionado = usuario.getValue();
if (usuarioSeleccionado != null && usuarioSeleccionado.getEmail() != null) {
String destinatario = usuarioSeleccionado.getEmail();
String asunto = "MANTENIMIENTO DE EQUIPO DE COMPUTO REALIZADO";
String cuerpo = "<html>" +
"<body>" +
"<img src='cid:image_id'/>"+
"</body>" +
"</html>";
// Limpiar campos
fecha.clear();
txtPlananualID.clear();
tipoMantt.clear();
area.clear();
usuario.clear();
txtNombreEquipo.clear();
formaGroup.clear();
actualizaciones.clear();
masActualizacionesGroup.clear();
txtCuales.clear();
userSignPad.clear();
smtSignPad.clear();
//gciatiSignPad.clear();
String imagePath = "META-INF/resources/images/imgCorreo/correoMantt.png";
for (HorizontalLayout layout : hardwareLayouts) {
((ComboBox<?>) layout.getComponentAt(0)).clear();
((TextField) layout.getComponentAt(1)).clear();
((TextField) layout.getComponentAt(2)).clear();
((TextField) layout.getComponentAt(3)).clear();
}
emailService.enviarCorreo(destinatario, asunto, cuerpo, imagePath);
UI.getCurrent().navigate("/");
} else {
Notification.show("Por favor selecciona un usuario", 4000, Notification.Position.MIDDLE);
} catch (Exception ex) {
Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
ex.printStackTrace();
} }
} }
@ -716,6 +753,14 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
String idParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id") != null String idParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id") != null
? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id").stream().findFirst().orElse(null) ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id").stream().findFirst().orElse(null)
: null; : null;
if (idParam != null) {
try {
int id = Integer.parseInt(idParam);
planAnualActual = databaseService.getPlanAnualPorId(id);
} catch (NumberFormatException e) {
planAnualActual = null;
}
}
String equipoParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo") != null String equipoParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo") != null
? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo").stream().findFirst().orElse(null) ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo").stream().findFirst().orElse(null)


+ 201
- 64
src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java View File

@ -4,20 +4,24 @@ import com.vaadin.flow.component.Component;
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.CheckboxGroupVariant;
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.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.dataview.GridListDataView; import com.vaadin.flow.component.grid.dataview.GridListDataView;
import com.vaadin.flow.component.html.H4;
import com.vaadin.flow.component.html.H5;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.html.*;
import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.NotificationVariant; import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.popover.Popover;
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.TextField; import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.Upload;
@ -26,29 +30,27 @@ 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.StreamResource;
import jakarta.annotation.security.PermitAll; import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.PlanAnual; import mx.gob.jumapacelaya.models.PlanAnual;
import mx.gob.jumapacelaya.services.DatabaseService; import mx.gob.jumapacelaya.services.DatabaseService;
import mx.gob.jumapacelaya.services.ReportService;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
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.vaadin.lineawesome.LineAwesomeIcon;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.sql.Date;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.Year; import java.time.Year;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.xml.crypto.Data;
import static java.util.regex.Pattern.matches;
@PermitAll @PermitAll
@PageTitle("Plan Anual de Mantenimiento") @PageTitle("Plan Anual de Mantenimiento")
@Route(value = "/", layout = MainLayout.class) @Route(value = "/", layout = MainLayout.class)
@ -56,20 +58,26 @@ import static java.util.regex.Pattern.matches;
public class PlanAnualView extends VerticalLayout { public class PlanAnualView extends VerticalLayout {
private final Environment env; private final Environment env;
private final ReportService reportService;
HorizontalLayout header = new HorizontalLayout();
H4 titulo = new H4(); H4 titulo = new H4();
H5 titulo1 = new H5(); H5 titulo1 = new H5();
Button btnInsertar; Button btnInsertar;
private byte[] fileContent; private byte[] fileContent;
VerticalLayout gridLayout = new VerticalLayout(); VerticalLayout gridLayout = new VerticalLayout();
HorizontalLayout uploadLayout = new HorizontalLayout(); HorizontalLayout uploadLayout = new HorizontalLayout();
HorizontalLayout checkLayout = new HorizontalLayout();
HorizontalLayout filtrosLayout = new HorizontalLayout();
private final DatabaseService databaseService; private final DatabaseService databaseService;
Grid<PlanAnual> planAnualGrid;
Button btnColumns;
Button btnImprimirRpt;
HorizontalLayout btnImprimirLayout;
public PlanAnualView(DatabaseService databaseService, Environment env) {
public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) {
this.databaseService = databaseService; this.databaseService = databaseService;
this.env = env; this.env = env;
this.reportService = reportService;
setupHeader(); setupHeader();
Grid<PlanAnual> planAnualGrid = setupGrid(); Grid<PlanAnual> planAnualGrid = setupGrid();
@ -93,17 +101,17 @@ public class PlanAnualView extends VerticalLayout {
/*headerRow.getCell(planAnualGrid.getColumnByKey("smtColumnKey")) /*headerRow.getCell(planAnualGrid.getColumnByKey("smtColumnKey"))
.setComponent(createFilterHeader("S.M.T", planAnualFilter::setSmt));*/ .setComponent(createFilterHeader("S.M.T", planAnualFilter::setSmt));*/
headerRow.getCell(planAnualGrid.getColumnByKey("equipoColumnKey"))
headerRow.getCell(planAnualGrid.getColumnByKey("equipo"))
.setComponent(createFilterHeader("Equipo", planAnualFilter::setEquipo)); .setComponent(createFilterHeader("Equipo", planAnualFilter::setEquipo));
headerRow.getCell(planAnualGrid.getColumnByKey("departamentoColumnKey"))
headerRow.getCell(planAnualGrid.getColumnByKey("departamento"))
.setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento)); .setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento));
// Componente UPLOAD para subir archivos // Componente UPLOAD para subir archivos
MemoryBuffer buffer = new MemoryBuffer(); MemoryBuffer buffer = new MemoryBuffer();
Upload upload = new Upload(buffer);
Upload upload = new Upload();
upload.setAcceptedFileTypes(".xls", ".xlsx"); upload.setAcceptedFileTypes(".xls", ".xlsx");
upload.setMaxFiles(1); upload.setMaxFiles(1);
upload.setDropLabel(new com.vaadin.flow.component.html.Span("Arrastra un archivo Excel aquí o selecciona uno")); upload.setDropLabel(new com.vaadin.flow.component.html.Span("Arrastra un archivo Excel aquí o selecciona uno"));
@ -112,7 +120,7 @@ public class PlanAnualView extends VerticalLayout {
try { try {
// Almacena el contenido del archivo en un arreglo de bytes // Almacena el contenido del archivo en un arreglo de bytes
try (InputStream inputStream = buffer.getInputStream(); try (InputStream inputStream = buffer.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
inputStream.transferTo(byteArrayOutputStream); inputStream.transferTo(byteArrayOutputStream);
fileContent = byteArrayOutputStream.toByteArray(); fileContent = byteArrayOutputStream.toByteArray();
@ -141,7 +149,6 @@ public class PlanAnualView extends VerticalLayout {
ntfError.add(notificationLayout); ntfError.add(notificationLayout);
ntfError.open(); // Abrir la notificación en pantalla ntfError.open(); // Abrir la notificación en pantalla
// Ocultar el botón de insertar si hay errores // Ocultar el botón de insertar si hay errores
btnInsertar.setVisible(false); btnInsertar.setVisible(false);
} else { } else {
@ -156,36 +163,41 @@ public class PlanAnualView extends VerticalLayout {
btnInsertar = new Button("Insertar archivo", event -> insertarDatos()); btnInsertar = new Button("Insertar archivo", event -> insertarDatos());
btnInsertar.setVisible(false); btnInsertar.setVisible(false);
gridLayout.add(planAnualGrid);
gridLayout.add(btnImprimirLayout,planAnualGrid);
gridLayout.setSizeFull(); gridLayout.setSizeFull();
uploadLayout.add(upload, btnInsertar); uploadLayout.add(upload, btnInsertar);
toggleLayouts(dataView); toggleLayouts(dataView);
RadioButtonGroup<String> radioFiltro = new RadioButtonGroup<>();
radioFiltro.setItems("Ver realizados", "Ver pendientes");
radioFiltro.setValue("Ver pendientes");
radioFiltro.addValueChangeListener(event -> {
String value = event.getValue();
if ("Ver pendientes".equals(value)) {
planAnualFilter.setExcludeRealizado(true);
} else if ("Ver realizados".equals(value)) {
planAnualFilter.setExcludeRealizado(false);
}
filtrosLayout.addClassNames("lumo-justify-content-center", "lumo-gap-m", "lumo-padding-s");
filtrosLayout.setWidthFull();
filtrosLayout.setJustifyContentMode(JustifyContentMode.CENTER);
Button btnPendientes = new Button("Pendientes", VaadinIcon.CLOCK.create());
Button btnRealizados = new Button("Realizados", VaadinIcon.CHECK_CIRCLE.create());
btnPendientes.addClassName("selected-tab");
btnPendientes.addClickListener(e -> {
planAnualFilter.setExcludeRealizado(true);
btnPendientes.addClassName("selected-tab");
btnRealizados.removeClassName("selected-tab");
});
btnRealizados.addClickListener(e -> {
planAnualFilter.setExcludeRealizado(false);
btnRealizados.addClassName("selected-tab");
btnPendientes.removeClassName("selected-tab");
}); });
checkLayout = new HorizontalLayout(radioFiltro);
checkLayout.setWidthFull();
checkLayout.setMargin(false);
checkLayout.setSpacing(true);
checkLayout.setJustifyContentMode(JustifyContentMode.CENTER);
filtrosLayout.add(btnPendientes, btnRealizados);
this.setPadding(false); this.setPadding(false);
this.setMargin(false); this.setMargin(false);
this.setSpacing(false); this.setSpacing(false);
this.setSizeFull(); this.setSizeFull();
add(header, checkLayout, gridLayout, uploadLayout);
add(filtrosLayout, gridLayout, uploadLayout);
} }
private void setupHeader() { private void setupHeader() {
@ -202,17 +214,17 @@ public class PlanAnualView extends VerticalLayout {
nomenclaturaTxt.setReadOnly(true); nomenclaturaTxt.setReadOnly(true);
nomenclaturaTxt.addClassName("nomenclatura-txt"); nomenclaturaTxt.addClassName("nomenclatura-txt");
header.setAlignSelf(Alignment.CENTER, titulo, titulo1);
headerLayout.add(titulo, titulo1); headerLayout.add(titulo, titulo1);
headerLayout.setAlignItems(Alignment.CENTER);
add(headerLayout); add(headerLayout);
} }
private Grid<PlanAnual> setupGrid() {
Grid<PlanAnual> planAnualGrid = new Grid<>(PlanAnual.class, false);
private Grid<PlanAnual> setupGrid() {
planAnualGrid = new Grid<>(PlanAnual.class, false);
planAnualGrid.addColumn((ValueProvider<PlanAnual, Integer>) PlanAnual::getNumero) planAnualGrid.addColumn((ValueProvider<PlanAnual, Integer>) PlanAnual::getNumero)
.setHeader("No.").setSortable(true);
.setHeader("No.").setSortable(true).setAutoWidth(true).setFrozen(true);
// Botón condicional // Botón condicional
planAnualGrid.addComponentColumn(planAnual -> { planAnualGrid.addComponentColumn(planAnual -> {
@ -254,55 +266,106 @@ public class PlanAnualView extends VerticalLayout {
} }
return btn; return btn;
});
}).setAutoWidth(true).setFrozen(true);
planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getNomEquipo) planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getNomEquipo)
.setHeader("Equipo").setAutoWidth(true).setKey("equipoColumnKey");
.setHeader("Equipo").setAutoWidth(true).setKey("equipo");
planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getDepartamento) planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getDepartamento)
.setHeader("Departamento").setAutoWidth(true).setKey("departamentoColumnKey");
planAnualGrid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT);
planAnualGrid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES);
.setHeader("Departamento").setAutoWidth(true).setKey("departamento");
planAnualGrid.addColumn(planAnual -> { planAnualGrid.addColumn(planAnual -> {
String mesPlaneado = planAnual.getMesplaneado(); String mesPlaneado = planAnual.getMesplaneado();
return mesPlaneado != null ? mesPlaneado.toUpperCase() : "N/A"; return mesPlaneado != null ? mesPlaneado.toUpperCase() : "N/A";
}).setHeader("Mes Planeado").setAutoWidth(true);
}).setHeader("Mes Planeado").setAutoWidth(true).setKey("mesplaneado");
// Fechas formateadas // Fechas formateadas
planAnualGrid.addColumn(planAnual -> { planAnualGrid.addColumn(planAnual -> {
LocalDate fecha = planAnual.getFechaProgramada(); LocalDate fecha = planAnual.getFechaProgramada();
return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "No programada"; return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "No programada";
}).setHeader("Fecha Programada").setAutoWidth(true).setSortable(true);
}).setHeader("Fecha Programada").setAutoWidth(true).setSortable(true).setKey("fechaProgramada");
planAnualGrid.addColumn(planAnual -> { planAnualGrid.addColumn(planAnual -> {
LocalDate fecha = planAnual.getFechaMantenimiento(); LocalDate fecha = planAnual.getFechaMantenimiento();
return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : ""; return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "";
}).setHeader("Fecha Realización").setAutoWidth(true).setSortable(true);
}).setHeader("Fecha Realización").setAutoWidth(true).setSortable(true).setKey("fechaMantenimiento");
planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getEstado) planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getEstado)
.setHeader("Estado").setAutoWidth(true);
.setHeader("Estado").setAutoWidth(true).setKey("estado");
planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSituacion) planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSituacion)
.setHeader("Situación").setAutoWidth(true);
.setHeader("Situación").setAutoWidth(true).setKey("situacion");
/*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");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMouse())).setHeader("Mouse");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isRegulador())).setHeader("Regulador");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isCpu())).setHeader("CPU");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isImpresora())).setHeader("Impresora");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMiniPrint())).setHeader("MiniPrint");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isLaptop())).setHeader("Laptop");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isEscaner())).setHeader("Escáner");*/
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.isMouse())).setHeader("Mouse").setKey("mouse");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isRegulador())).setHeader("Regulador").setKey("regulador");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isCpu())).setHeader("CPU").setKey("cpu");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isImpresora())).setHeader("Impresora").setKey("impresora");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMiniPrint())).setHeader("MiniPrint").setKey("miniprint");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isLaptop())).setHeader("Laptop").setKey("laptop");
planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isEscaner())).setHeader("Escáner").setKey("escaner");
planAnualGrid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT);
planAnualGrid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES);
btnColumns = new Button(VaadinIcon.GRID_H.create());
btnColumns.addThemeVariants(ButtonVariant.LUMO_ICON);
btnColumns.setAriaLabel("Show/Hide Columns");
btnColumns.setTooltipText("Show/Hide Columns");
btnImprimirRpt = new Button(VaadinIcon.PRINT.create());
btnImprimirRpt.addClickListener(event -> sacarReporte());
btnImprimirRpt.setTooltipText("Imprimir reporte");
btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt);
HorizontalLayout columnSelectorLayout = new HorizontalLayout();
columnSelectorLayout.setAlignItems(Alignment.END);
Popover popover = new Popover();
popover.setModal(true);
popover.setBackdropVisible(true);
popover.setPosition(PopoverPosition.BOTTOM_END);
popover.setTarget(btnColumns);
Div heading = new Div("Ver/Ocultar columnas");
heading.getStyle().set("font-weight", "600");
heading.getStyle().set("padding", "var(--lumo-space-xs)");
List<String> columns = List.of("equipo", "departamento", "mesplaneado", "fechaProgramada",
"fechaMantenimiento", "estado", "situacion", "monitor", "teclado", "mouse", "regulador",
"cpu", "impresora", "miniprint", "laptop", "escaner");
CheckboxGroup<String> chkColumns = new CheckboxGroup<>();
chkColumns.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL);
chkColumns.setItems(columns);
chkColumns.setItemLabelGenerator((item) -> {
String label = StringUtils
.join(StringUtils.splitByCharacterTypeCamelCase(item), " ");
return StringUtils.capitalize(label.toLowerCase());
});
chkColumns.addValueChangeListener((e) -> {
columns.forEach((key) -> {
Grid.Column<?> col = planAnualGrid.getColumnByKey(key);
if (col != null) {
col.setVisible(e.getValue().contains(key));
} else {
System.out.println("Columna no encontrada para key: " + key);
}
});
});
Set<String> defaultColumns = Set.of("equipo", "departamento", "mesplaneado",
"fechaProgramada", "fechaMantenimiento", "estado", "situacion");
chkColumns.setValue(defaultColumns);
popover.add(heading, chkColumns);
// Cargar datos // Cargar datos
planAnualGrid.setItems(databaseService.getPlanAnual()); planAnualGrid.setItems(databaseService.getPlanAnual());
return planAnualGrid; return planAnualGrid;
@ -471,4 +534,78 @@ public class PlanAnualView extends VerticalLayout {
gridLayout.setVisible(hasItems); gridLayout.setVisible(hasItems);
uploadLayout.setVisible(!hasItems); uploadLayout.setVisible(!hasItems);
} }
private void sacarReporte() {
Dialog dialog = new Dialog();
dialog.setHeaderTitle("Seleccione la fecha de inicio y fin");
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 fechaInicio = new DatePicker("Fecha de inicio:");
fechaInicio.setRequired(true);
fechaInicio.setI18n(i18n);
DatePicker fechaFin = new DatePicker("Fecha de fin:");
fechaFin.setRequired(true);
fechaFin.setI18n(i18n);
Button btnGenerar = new Button("Generar", VaadinIcon.PRINT.create());
btnGenerar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
btnGenerar.addClickListener(e -> {
if (fechaInicio.getValue() == null || fechaFin.getValue() == null) {
Notification.show("Por favor, seleccione ambas fechas.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
LocalDate inicio = fechaInicio.getValue();
LocalDate fin = fechaFin.getValue();
try {
// Prepara los parámetros para el reporte
Map<String, Object> parametros = new HashMap<>();
parametros.put("FECHAINICIO", java.sql.Date.valueOf(inicio));
parametros.put("FECHAFIN", java.sql.Date.valueOf(fin));
// Genera el PDF
byte[] pdf = reportService.generarReporte("mantenimientoFechas", parametros);
// Creando el recurso de descarga
StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf));
Anchor downloadLink = new Anchor(resource, "Descargar Reporte");
downloadLink.setTarget("_blank");
downloadLink.setId("descargar-reporte-link");
add(downloadLink);
getUI().ifPresent(ui ->
ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();")
);
} catch (Exception ex) {
Notification.show("Error al genrar 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);
dialog.getFooter().add(btnGenerar);
HorizontalLayout fechasLayout = new HorizontalLayout(fechaInicio, fechaFin);
dialog.add(fechasLayout);
dialog.open();
}
} }

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


Loading…
Cancel
Save