diff --git a/src/main/bundles/dev.bundle b/src/main/bundles/dev.bundle index 76e0c9c..4815a84 100644 Binary files a/src/main/bundles/dev.bundle and b/src/main/bundles/dev.bundle differ diff --git a/src/main/frontend/themes/sistema-mantenimiento/styles.css b/src/main/frontend/themes/sistema-mantenimiento/styles.css index 972bbb6..d5b28db 100644 --- a/src/main/frontend/themes/sistema-mantenimiento/styles.css +++ b/src/main/frontend/themes/sistema-mantenimiento/styles.css @@ -212,8 +212,9 @@ vaadin-button:not([theme]) { 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' */ @@ -270,6 +271,7 @@ vaadin-login-form-wrapper::part(error-message) { 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); +} diff --git a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java index 76cd613..b07cc9b 100644 --- a/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java +++ b/src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java @@ -539,6 +539,7 @@ public class DatabaseService { } + // INSERTAR ARCHIVO EXCEL EN LA TABLA: PLANANUAL public void insertarDesdeExcel(InputStream inputStream) { String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO, MOUSE, " + "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 private Date getDateCellValue(Cell cell) { if (cell != null) { diff --git a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java index 3150b8a..128c570 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java @@ -72,7 +72,7 @@ public class MainLayout extends AppLayout { headerLayout.setAlignItems(FlexComponent.Alignment.CENTER); 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(); headerLayout.add(imgLogo); diff --git a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java index fec2ed8..11dc8a8 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java @@ -6,9 +6,11 @@ import com.vaadin.flow.component.button.ButtonVariant; 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.datepicker.DatePicker; import com.vaadin.flow.component.dependency.CssImport; 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.GridVariant; import com.vaadin.flow.component.grid.HeaderRow; @@ -23,6 +25,7 @@ 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.textfield.NumberField; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.receivers.MemoryBuffer; @@ -71,7 +74,9 @@ public class PlanAnualView extends VerticalLayout { Grid planAnualGrid; Button btnColumns; Button btnImprimirRpt; + Button btnAddEquipo; HorizontalLayout btnImprimirLayout; + private Popover reportePopover; public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) { this.databaseService = databaseService; @@ -191,6 +196,7 @@ public class PlanAnualView extends VerticalLayout { }); filtrosLayout.add(btnPendientes, btnRealizados); + mostrarPopoverReportes(); this.setPadding(false); @@ -299,7 +305,7 @@ public class PlanAnualView extends VerticalLayout { /*planAnualGrid.addColumn((ValueProvider) PlanAnual::getSmt) .setHeader("S.M.T").setKey("smtColumnKey");*/ - + // Iconos en columnas booleanas planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor").setKey("monitor"); planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado").setKey("teclado"); @@ -321,9 +327,14 @@ public class PlanAnualView extends VerticalLayout { btnColumns.setTooltipText("Show/Hide Columns"); btnImprimirRpt = new Button(VaadinIcon.PRINT.create()); - btnImprimirRpt.addClickListener(event -> sacarReporte()); + btnImprimirRpt.addClickListener(event -> reportePopover.open()); 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(); columnSelectorLayout.setAlignItems(Alignment.END); @@ -608,4 +619,212 @@ public class PlanAnualView extends VerticalLayout { 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 items = List.of("ENERO", "FEBRERO", "MARZO", "ABRIL", "MAYO", "JUNIO", + "JULIO", "AGOSTO", "SEPTIEMBRE", "OCTUBRE", "NOVIEMBRE", "DICIEMBRE"); + ComboBox cmbMes = new ComboBox<>("Mes Planeado:"); + cmbMes.setItems(items); + + CheckboxGroup group1 = new CheckboxGroup<>(); + group1.setLabel("Seleccione los componentes del equipo"); + group1.setItems("MONITOR","TECLADO","MOUSE","REGULADOR"); + + CheckboxGroup 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 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 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 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();") + ); + + } 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(); + } } diff --git a/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java b/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java index c73e3b3..13bb9ad 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java @@ -44,7 +44,7 @@ public class LoginView extends VerticalLayout implements BeforeEnterObserver { // Configuración de i18n para el formulario de login LoginI18n i18n = LoginI18n.createDefault(); LoginI18n.Form i18nFormulario = i18n.getForm(); - i18nFormulario.setTitle("Mantenimiento Preventivo y Correctivo (BETA)"); + i18nFormulario.setTitle("Mantenimiento Preventivo y Correctivo"); i18nFormulario.setUsername("Usuario"); i18nFormulario.setPassword("Contraseña"); 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"); 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 login.setAction("login"); diff --git a/src/main/resources/META-INF/resources/reportes/listadoMantenimientos.jasper b/src/main/resources/META-INF/resources/reportes/listadoMantenimientos.jasper new file mode 100644 index 0000000..7238b84 Binary files /dev/null and b/src/main/resources/META-INF/resources/reportes/listadoMantenimientos.jasper differ