|
|
|
@ -11,9 +11,7 @@ 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.GridVariant; |
|
|
|
import com.vaadin.flow.component.html.Anchor; |
|
|
|
import com.vaadin.flow.component.html.Div; |
|
|
|
import com.vaadin.flow.component.html.H3; |
|
|
|
import com.vaadin.flow.component.html.Span; |
|
|
|
import com.vaadin.flow.component.icon.Icon; |
|
|
|
import com.vaadin.flow.component.icon.VaadinIcon; |
|
|
|
@ -24,9 +22,9 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout; |
|
|
|
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.progressbar.ProgressBar; |
|
|
|
import com.vaadin.flow.component.richtexteditor.RichTextEditor; |
|
|
|
import com.vaadin.flow.data.renderer.ComponentRenderer; |
|
|
|
import com.vaadin.flow.function.SerializableBiConsumer; |
|
|
|
import com.vaadin.flow.router.PageTitle; |
|
|
|
import com.vaadin.flow.router.Route; |
|
|
|
import com.vaadin.flow.server.StreamRegistration; |
|
|
|
@ -34,31 +32,29 @@ import com.vaadin.flow.server.StreamResource; |
|
|
|
import jakarta.annotation.security.PermitAll; |
|
|
|
import mx.gob.jumapacelaya.api.RedmineClient; |
|
|
|
import mx.gob.jumapacelaya.api.ServerProperties; |
|
|
|
import mx.gob.jumapacelaya.models.ActividadDiaria; |
|
|
|
import mx.gob.jumapacelaya.models.RedmineUser; |
|
|
|
import mx.gob.jumapacelaya.models.Ticket; |
|
|
|
import mx.gob.jumapacelaya.services.LdapService; |
|
|
|
import mx.gob.jumapacelaya.services.UserService; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.apache.poi.ss.usermodel.Cell; |
|
|
|
import org.apache.poi.ss.usermodel.Row; |
|
|
|
import org.apache.poi.ss.usermodel.Sheet; |
|
|
|
import org.apache.poi.ss.usermodel.Workbook; |
|
|
|
import org.apache.poi.ss.usermodel.*; |
|
|
|
import org.apache.poi.ss.util.CellRangeAddress; |
|
|
|
import org.apache.poi.util.IOUtils; |
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.vaadin.lineawesome.LineAwesomeIcon; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.time.LocalDate; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.time.temporal.ChronoUnit; |
|
|
|
import java.util.*; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Locale; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
|
|
|
@ -91,11 +87,12 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
// Layout de opciones |
|
|
|
opcionesLyt = new HorizontalLayout(); |
|
|
|
opcionesLyt.setWidthFull(); |
|
|
|
opcionesLyt.setMargin(false); |
|
|
|
opcionesLyt.setAlignItems(Alignment.BASELINE); |
|
|
|
//opcionesLyt.setMargin(false); |
|
|
|
opcionesLyt.getStyle() |
|
|
|
.set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)") |
|
|
|
.set("border-radius", "10px") |
|
|
|
.set("background-color", "white") |
|
|
|
//.set("background-color", "white") |
|
|
|
.set("padding", "1rem") |
|
|
|
.set("margin", "1rem auto"); |
|
|
|
|
|
|
|
@ -103,18 +100,42 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
chkSoloAbiertos = new Checkbox("Ver solo abiertos"); |
|
|
|
chkSoloAbiertos.setValue(false); // inicial: mostrar cerrados |
|
|
|
|
|
|
|
fechaDesde = new DatePicker("Fecha desde:"); |
|
|
|
fechaHasta = new DatePicker("Fecha hasta:"); |
|
|
|
btnBuscar = new Button("Buscar"); |
|
|
|
fechaDesde = new DatePicker(); |
|
|
|
fechaDesde.setPlaceholder("Fecha desde:"); |
|
|
|
fechaDesde.setLocale(new Locale("es", "MX")); |
|
|
|
DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() |
|
|
|
.setWeekdays(List.of("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")) |
|
|
|
.setWeekdaysShort(List.of("Dom","Lun","Mar","Mié","Jue","Vie","Sab")) |
|
|
|
.setMonthNames(List.of("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")) |
|
|
|
.setFirstDayOfWeek(1) |
|
|
|
.setToday("Hoy") |
|
|
|
.setCancel("Cancelar") |
|
|
|
.setDateFormat("dd/MM/yyyy"); |
|
|
|
fechaDesde.setI18n(i18n); |
|
|
|
|
|
|
|
fechaHasta = new DatePicker(); |
|
|
|
fechaHasta.setPlaceholder("Fecha hasta:"); |
|
|
|
fechaHasta.setLocale(new Locale("es", "MX")); |
|
|
|
DatePicker.DatePickerI18n i18nh = new DatePicker.DatePickerI18n() |
|
|
|
.setWeekdays(List.of("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")) |
|
|
|
.setWeekdaysShort(List.of("Dom","Lun","Mar","Mié","Jue","Vie","Sab")) |
|
|
|
.setMonthNames(List.of("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")) |
|
|
|
.setFirstDayOfWeek(1) |
|
|
|
.setToday("Hoy") |
|
|
|
.setCancel("Cancelar") |
|
|
|
.setDateFormat("dd/MM/yyyy"); |
|
|
|
fechaHasta.setI18n(i18nh); |
|
|
|
|
|
|
|
btnBuscar = new Button("Buscar", VaadinIcon.SEARCH.create()); |
|
|
|
|
|
|
|
// Listener del checkbox |
|
|
|
chkSoloAbiertos.addValueChangeListener(e -> { |
|
|
|
boolean soloAbiertos = e.getValue(); // marcado = abiertos |
|
|
|
loadTickets(soloAbiertos); |
|
|
|
|
|
|
|
fechaDesde.setEnabled(!soloAbiertos); |
|
|
|
fechaHasta.setEnabled(!soloAbiertos); |
|
|
|
btnBuscar.setEnabled(!soloAbiertos); |
|
|
|
|
|
|
|
grid.getDataProvider().refreshAll(); |
|
|
|
}); |
|
|
|
|
|
|
|
// Estado inicial |
|
|
|
@ -128,6 +149,30 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
|
|
|
|
opcionesLyt.add(chkSoloAbiertos, fechaDesde, fechaHasta, btnBuscar); |
|
|
|
|
|
|
|
|
|
|
|
grid.setItems( |
|
|
|
query -> { |
|
|
|
try { |
|
|
|
return redmineClient.getTickets( |
|
|
|
userService.getRedmineUser(), |
|
|
|
chkSoloAbiertos.getValue(), |
|
|
|
query.getOffset(), |
|
|
|
query.getLimit(), |
|
|
|
fechaDesde.getValue(), |
|
|
|
fechaHasta.getValue() |
|
|
|
).stream(); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Error al cargar tickets", e); |
|
|
|
return Stream.empty(); |
|
|
|
} |
|
|
|
}, |
|
|
|
query -> redmineClient.getTotalTickets( |
|
|
|
userService.getRedmineUser(), |
|
|
|
chkSoloAbiertos.getValue(), |
|
|
|
fechaDesde.getValue(), |
|
|
|
fechaHasta.getValue() |
|
|
|
) |
|
|
|
); |
|
|
|
// Configuración de columnas del grid |
|
|
|
grid.addColumn(Ticket::getId).setHeader("No.") |
|
|
|
.setAutoWidth(true) |
|
|
|
@ -148,6 +193,7 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")) : ""; |
|
|
|
}).setHeader("Fecha creación") |
|
|
|
.setAutoWidth(true) |
|
|
|
.setSortable(true) |
|
|
|
.setKey("fechaCreacion"); |
|
|
|
|
|
|
|
grid.addColumn(ticket -> { |
|
|
|
@ -155,6 +201,7 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")) : ""; |
|
|
|
}).setHeader("Fecha cierre") |
|
|
|
.setAutoWidth(true) |
|
|
|
.setSortable(true) |
|
|
|
.setKey("fechaCierre"); |
|
|
|
|
|
|
|
grid.addColumn(ticket -> { |
|
|
|
@ -198,7 +245,7 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
} else { |
|
|
|
return ""; |
|
|
|
} |
|
|
|
}).setHeader("Duración").setAutoWidth(true).setKey("duracion"); |
|
|
|
}).setHeader("Duración").setAutoWidth(true).setSortable(true).setKey("duracion"); |
|
|
|
|
|
|
|
|
|
|
|
grid.addColumn(ticket -> |
|
|
|
@ -217,7 +264,6 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
grid.addComponentColumn(ticket -> { |
|
|
|
Button btnVer = new Button(new Icon(VaadinIcon.EYE)); |
|
|
|
btnVer.addClickListener(event -> showDescription(ticket)); |
|
|
|
btnVer.getStyle().set("color", "#A02142"); |
|
|
|
return btnVer; |
|
|
|
}); |
|
|
|
|
|
|
|
@ -229,6 +275,7 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
btnColumns = new Button(VaadinIcon.GRID_H.create()); |
|
|
|
// Botón para exportar |
|
|
|
btnExport = new Button("Exportar", LineAwesomeIcon.FILE_EXCEL.create()); |
|
|
|
btnExport.addThemeVariants(ButtonVariant.LUMO_PRIMARY); |
|
|
|
btnExport.addClickListener(e -> exportTicketsCerrados()); |
|
|
|
showColumnsLyt = new HorizontalLayout(btnExport, btnColumns); |
|
|
|
showColumnsLyt.setJustifyContentMode(JustifyContentMode.END); |
|
|
|
@ -281,30 +328,6 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
|
|
|
|
// Invertir parámetro para que coincida con RedmineClient |
|
|
|
boolean paramCliente = !soloAbiertos; |
|
|
|
|
|
|
|
grid.setItems( |
|
|
|
query -> { |
|
|
|
try { |
|
|
|
return redmineClient.getTickets( |
|
|
|
user, |
|
|
|
chkSoloAbiertos.getValue(), |
|
|
|
query.getOffset(), |
|
|
|
query.getLimit(), |
|
|
|
fechaDesde.getValue(), |
|
|
|
fechaHasta.getValue() |
|
|
|
).stream(); |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
return Stream.empty(); |
|
|
|
} |
|
|
|
}, |
|
|
|
query -> redmineClient.getTotalTickets( |
|
|
|
user, |
|
|
|
chkSoloAbiertos.getValue(), |
|
|
|
fechaDesde.getValue(), |
|
|
|
fechaHasta.getValue() |
|
|
|
) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -365,7 +388,7 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
UI.getCurrent().getPage().executeJs("setTimeout(() => { window.location.reload(); }, 3000);"); |
|
|
|
|
|
|
|
} catch (IOException | InterruptedException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
log.error("Error al cerrar el ticket " + ticket.getId(), e); |
|
|
|
Notification.show("Error al cerrar el ticket " + ticket.getId()); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -399,85 +422,210 @@ public class ActDiariaView extends VerticalLayout { |
|
|
|
|
|
|
|
// Metodo para exportar los tickets cerrados a un archivo de Excel |
|
|
|
private void exportTicketsCerrados() { |
|
|
|
try { |
|
|
|
RedmineUser user = userService.getRedmineUser(); |
|
|
|
|
|
|
|
// Traer TODOS los tickets cerrados, respetando fechas si están seleccionadas |
|
|
|
List<Ticket> ticketsCerrados = redmineClient.getAllTickets( |
|
|
|
user, |
|
|
|
false, // false = cerrados |
|
|
|
fechaDesde.getValue(), |
|
|
|
fechaHasta.getValue() |
|
|
|
); |
|
|
|
|
|
|
|
Workbook workbook = new XSSFWorkbook(); |
|
|
|
Sheet sheet = workbook.createSheet("Tickets cerrados"); |
|
|
|
|
|
|
|
String[] headers = {"ID","Tipo","Tiempo estimado","Fecha creación","Fecha cierre", |
|
|
|
"Fecha actualización","Situación","Estado","Duración","Autor","Asunto"}; |
|
|
|
Row headerRow = sheet.createRow(0); |
|
|
|
for (int i = 0; i < headers.length; i++) { |
|
|
|
Cell cell = headerRow.createCell(i); |
|
|
|
cell.setCellValue(headers[i]); |
|
|
|
} |
|
|
|
final UI ui = UI.getCurrent(); |
|
|
|
final RedmineUser user = userService.getRedmineUser(); |
|
|
|
final LocalDate desde = fechaDesde.getValue(); |
|
|
|
final LocalDate hasta = fechaHasta.getValue(); |
|
|
|
|
|
|
|
int rowNum = 1; |
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); |
|
|
|
|
|
|
|
for (Ticket ticket : ticketsCerrados) { |
|
|
|
Row row = sheet.createRow(rowNum++); |
|
|
|
row.createCell(0).setCellValue(ticket.getId()); |
|
|
|
row.createCell(1).setCellValue(ticket.getType()); |
|
|
|
row.createCell(2).setCellValue(ticket.getEstimatedHrs() + " horas"); |
|
|
|
row.createCell(3).setCellValue(ticket.getDateCreate() != null ? ticket.getDateCreate().format(formatter) : ""); |
|
|
|
row.createCell(4).setCellValue(ticket.getDateClose() != null ? ticket.getDateClose().format(formatter) : ""); |
|
|
|
row.createCell(5).setCellValue(ticket.getUpdateOn() != null ? ticket.getUpdateOn().format(formatter) : ""); |
|
|
|
row.createCell(7).setCellValue(ticket.getStatus()); |
|
|
|
row.createCell(9).setCellValue(ticket.getAuthor() != null ? ticket.getAuthor().getUsername() : ""); |
|
|
|
row.createCell(10).setCellValue(ticket.getSubject()); |
|
|
|
|
|
|
|
if (ticket.getDateCreateLocal() != null && ticket.getDateCloseLocal() != null) { |
|
|
|
long dias = ChronoUnit.DAYS.between(ticket.getDateCreateLocal(), ticket.getDateCloseLocal()); |
|
|
|
row.createCell(8).setCellValue(dias + " días"); |
|
|
|
} else { |
|
|
|
row.createCell(8).setCellValue(""); |
|
|
|
if (ui == null) return; |
|
|
|
|
|
|
|
Dialog loadingDialog = createLoadingDialog("Generando archivo por favor espere..."); |
|
|
|
loadingDialog.open(); |
|
|
|
|
|
|
|
|
|
|
|
new Thread(() -> { |
|
|
|
try { |
|
|
|
// Traer TODOS los tickets cerrados, respetando fechas si están seleccionadas |
|
|
|
List<Ticket> ticketsCerrados = redmineClient.getAllTickets( |
|
|
|
user, |
|
|
|
false, // false = cerrados |
|
|
|
desde, |
|
|
|
hasta |
|
|
|
); |
|
|
|
|
|
|
|
Workbook workbook = new XSSFWorkbook(); |
|
|
|
Sheet sheet = workbook.createSheet("Tickets cerrados"); |
|
|
|
|
|
|
|
CellStyle titleStyle = workbook.createCellStyle(); |
|
|
|
Font titleFont = workbook.createFont(); |
|
|
|
titleFont.setBold(true); |
|
|
|
titleFont.setFontHeightInPoints((short) 20); |
|
|
|
titleStyle.setFont(titleFont); |
|
|
|
titleStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
|
|
|
CellStyle subTitleStyle = workbook.createCellStyle(); |
|
|
|
Font subTitleFont = workbook.createFont(); |
|
|
|
subTitleFont.setFontHeightInPoints((short) 18); |
|
|
|
subTitleStyle.setFont(subTitleFont); |
|
|
|
subTitleStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
|
|
|
int ultimaCol = 10; |
|
|
|
|
|
|
|
Row row1 = sheet.createRow(1); |
|
|
|
Cell cell1 = row1.createCell(0); |
|
|
|
cell1.setCellValue("JUNTA MUNICIPAL DE AGUA POTABLE Y ALCANTARILLADO DE CELAYA."); |
|
|
|
cell1.setCellStyle(titleStyle); |
|
|
|
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, ultimaCol)); |
|
|
|
|
|
|
|
Row row2 = sheet.createRow(2); |
|
|
|
Cell cell2 = row2.createCell(0); |
|
|
|
cell2.setCellValue("División Del Norte #132, Col. El Vergel, Celaya, Gto. C.P: 38078"); |
|
|
|
cell2.setCellStyle(subTitleStyle); |
|
|
|
sheet.addMergedRegion(new CellRangeAddress(2, 2, 0, ultimaCol)); |
|
|
|
|
|
|
|
|
|
|
|
try ( |
|
|
|
InputStream jmpaLogo = ActDiariaView.class.getClassLoader() |
|
|
|
.getResourceAsStream("META-INF/resources/images/LOGO_24'27.png"); |
|
|
|
InputStream adminLogo = ActDiariaView.class.getClassLoader() |
|
|
|
.getResourceAsStream("META-INF/resources/images/LOGO_admon2.png") |
|
|
|
) { |
|
|
|
if (jmpaLogo != null || adminLogo != null) { |
|
|
|
byte[] bytes = IOUtils.toByteArray(jmpaLogo); |
|
|
|
byte[] bytes1 = IOUtils.toByteArray(adminLogo); |
|
|
|
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); |
|
|
|
int pictureIdx1 = workbook.addPicture(bytes1, Workbook.PICTURE_TYPE_PNG); |
|
|
|
|
|
|
|
Drawing<?> drawing = sheet.createDrawingPatriarch(); |
|
|
|
CreationHelper helper = workbook.getCreationHelper(); |
|
|
|
CreationHelper helper1 = workbook.getCreationHelper(); |
|
|
|
|
|
|
|
ClientAnchor anchor = helper.createClientAnchor(); |
|
|
|
ClientAnchor anchor1 = helper1.createClientAnchor(); |
|
|
|
|
|
|
|
// Posición en la esquina superior izquierda |
|
|
|
anchor.setCol1(1); |
|
|
|
anchor.setRow1(1); |
|
|
|
|
|
|
|
anchor1.setCol1(10); |
|
|
|
anchor1.setRow1(1); |
|
|
|
|
|
|
|
Picture pict = drawing.createPicture(anchor, pictureIdx); |
|
|
|
pict.resize(0.30, 0.60); // Ajusta según el tamaño de tu imagen original |
|
|
|
|
|
|
|
Picture pict1 = drawing.createPicture(anchor1, pictureIdx1); |
|
|
|
pict1.resize(0.30, 0.37); |
|
|
|
} else { |
|
|
|
log.error("No se encontró el archivo de imagen en la ruta especificada"); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Error al procesar el logo", e); |
|
|
|
} |
|
|
|
|
|
|
|
if (ticket.getEstimatedHrs() != null && ticket.getDateCreateLocal() != null && ticket.getDateCloseLocal() != null) { |
|
|
|
long horasReales = ChronoUnit.HOURS.between(ticket.getDateCreateLocal(), ticket.getDateCloseLocal()); |
|
|
|
row.createCell(6).setCellValue(horasReales <= ticket.getEstimatedHrs() ? "En tiempo" : "Excedido"); |
|
|
|
} else { |
|
|
|
row.createCell(6).setCellValue("Sin estimación"); |
|
|
|
|
|
|
|
CellStyle headerStyle = workbook.createCellStyle(); |
|
|
|
Font headerFont = workbook.createFont(); |
|
|
|
headerFont.setBold(true); |
|
|
|
headerFont.setColor(IndexedColors.WHITE.getIndex()); |
|
|
|
headerStyle.setFont(headerFont); |
|
|
|
headerStyle.setFillForegroundColor(IndexedColors.MAROON.getIndex()); |
|
|
|
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); |
|
|
|
headerStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
headerStyle.setBorderBottom(BorderStyle.THIN); |
|
|
|
|
|
|
|
String[] headers = {"ID","Tipo","Tiempo estimado","Fecha creación","Fecha cierre", |
|
|
|
"Fecha actualización","Situación","Estado","Duración","Autor","Asunto"}; |
|
|
|
|
|
|
|
int rowNum = 6; |
|
|
|
Row headerRow = sheet.createRow(rowNum++); |
|
|
|
for (int i = 0; i < headers.length; i++) { |
|
|
|
Cell cell = headerRow.createCell(i); |
|
|
|
cell.setCellValue(headers[i]); |
|
|
|
cell.setCellStyle(headerStyle); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < headers.length; i++) { |
|
|
|
sheet.autoSizeColumn(i); |
|
|
|
} |
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); |
|
|
|
|
|
|
|
for (Ticket ticket : ticketsCerrados) { |
|
|
|
Row row = sheet.createRow(rowNum++); |
|
|
|
row.createCell(0).setCellValue(ticket.getId()); |
|
|
|
row.createCell(1).setCellValue(ticket.getType()); |
|
|
|
row.createCell(2).setCellValue(ticket.getEstimatedHrs() + " horas"); |
|
|
|
row.createCell(3).setCellValue(ticket.getDateCreate() != null ? ticket.getDateCreate().format(formatter) : ""); |
|
|
|
row.createCell(4).setCellValue(ticket.getDateClose() != null ? ticket.getDateClose().format(formatter) : ""); |
|
|
|
row.createCell(5).setCellValue(ticket.getUpdateOn() != null ? ticket.getUpdateOn().format(formatter) : ""); |
|
|
|
row.createCell(7).setCellValue(ticket.getStatus()); |
|
|
|
row.createCell(9).setCellValue(ticket.getAuthor() != null ? ticket.getAuthor().getUsername() : ""); |
|
|
|
row.createCell(10).setCellValue(ticket.getSubject()); |
|
|
|
|
|
|
|
if (ticket.getDateCreateLocal() != null && ticket.getDateCloseLocal() != null) { |
|
|
|
long dias = ChronoUnit.DAYS.between(ticket.getDateCreateLocal(), ticket.getDateCloseLocal()); |
|
|
|
row.createCell(8).setCellValue(dias + " días"); |
|
|
|
} else { |
|
|
|
row.createCell(8).setCellValue(""); |
|
|
|
} |
|
|
|
|
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
|
|
|
workbook.write(out); |
|
|
|
workbook.close(); |
|
|
|
if (ticket.getEstimatedHrs() != null && ticket.getDateCreateLocal() != null && ticket.getDateCloseLocal() != null) { |
|
|
|
long horasReales = ChronoUnit.HOURS.between(ticket.getDateCreateLocal(), ticket.getDateCloseLocal()); |
|
|
|
row.createCell(6).setCellValue(horasReales <= ticket.getEstimatedHrs() ? "En tiempo" : "Excedido"); |
|
|
|
} else { |
|
|
|
row.createCell(6).setCellValue("Sin estimación"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
StreamResource resource = new StreamResource("tickets_cerrados.xlsx", |
|
|
|
() -> new ByteArrayInputStream(out.toByteArray())); |
|
|
|
for (int i = 0; i < headers.length; i++) { |
|
|
|
sheet.autoSizeColumn(i); |
|
|
|
} |
|
|
|
|
|
|
|
StreamRegistration registration = UI.getCurrent().getSession() |
|
|
|
.getResourceRegistry().registerResource(resource); |
|
|
|
UI.getCurrent().getPage().executeJs( |
|
|
|
"window.open('" + registration.getResourceUri().toString() + "','_blank')" |
|
|
|
); |
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
|
|
|
workbook.write(out); |
|
|
|
workbook.close(); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Error exportando tickets", e); |
|
|
|
Notification.show("Error al exportar los tickets", 5000, Notification.Position.MIDDLE) |
|
|
|
.addThemeVariants(NotificationVariant.LUMO_ERROR); |
|
|
|
} |
|
|
|
ui.access(() -> { |
|
|
|
try { |
|
|
|
StreamResource resource = new StreamResource("rptGeneralDeTicketsMsaAyda.xlsx", |
|
|
|
() -> new ByteArrayInputStream(out.toByteArray())); |
|
|
|
|
|
|
|
StreamRegistration registration = ui.getSession() |
|
|
|
.getResourceRegistry().registerResource(resource); |
|
|
|
|
|
|
|
ui.getPage().executeJs( |
|
|
|
"window.open('" + registration.getResourceUri().toString() + "','_blank')" |
|
|
|
); |
|
|
|
} catch (Exception ex) { |
|
|
|
log.error("Error al registrar recurso", ex); |
|
|
|
} finally { |
|
|
|
loadingDialog.close(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Error exportando tickets", e); |
|
|
|
ui.access(() -> { |
|
|
|
loadingDialog.close(); |
|
|
|
Notification.show("Error al generar el reporte", 5000, Notification.Position.MIDDLE) |
|
|
|
.addThemeVariants(NotificationVariant.LUMO_ERROR); |
|
|
|
}); |
|
|
|
} |
|
|
|
}).start(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void filtrarTickets() { |
|
|
|
boolean soloAbiertos = chkSoloAbiertos.getValue(); |
|
|
|
loadTickets(soloAbiertos); |
|
|
|
grid.getDataProvider().refreshAll(); |
|
|
|
} |
|
|
|
|
|
|
|
private Dialog createLoadingDialog(String mensaje) { |
|
|
|
Dialog dialog = new Dialog(); |
|
|
|
dialog.setCloseOnEsc(false); |
|
|
|
dialog.setCloseOnOutsideClick(false); |
|
|
|
|
|
|
|
VerticalLayout layout = new VerticalLayout(); |
|
|
|
layout.setAlignItems(Alignment.CENTER); |
|
|
|
layout.setPadding(true); |
|
|
|
layout.setSpacing(true); |
|
|
|
|
|
|
|
ProgressBar progressBar = new ProgressBar(); |
|
|
|
progressBar.setIndeterminate(true); |
|
|
|
progressBar.setWidth("15rem"); |
|
|
|
|
|
|
|
Span texto = new Span(mensaje); |
|
|
|
texto.getStyle().set("font-weight", "bold"); |
|
|
|
texto.getStyle().set("color", "var(--lumo-primary-text-color)"); |
|
|
|
|
|
|
|
layout.add(texto, progressBar); |
|
|
|
dialog.add(layout); |
|
|
|
|
|
|
|
return dialog; |
|
|
|
} |
|
|
|
} |