diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index cf0e708..f1fc546 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/java/com/primefactorsolutions/views/MainLayout.java b/src/main/java/com/primefactorsolutions/views/MainLayout.java index 58b1afd..076a92b 100644 --- a/src/main/java/com/primefactorsolutions/views/MainLayout.java +++ b/src/main/java/com/primefactorsolutions/views/MainLayout.java @@ -1,7 +1,8 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.Employee; -import com.primefactorsolutions.views.admin.EmployeesListView; +import com.primefactorsolutions.views.employee.DocumentsListView; +import com.primefactorsolutions.views.employee.EmployeesListView; import com.primefactorsolutions.views.admin.TimeOffListView; import com.primefactorsolutions.views.assessment.AssessmentsListView; import com.primefactorsolutions.views.assessment.CandidatesListView; diff --git a/src/main/java/com/primefactorsolutions/views/ProfileView.java b/src/main/java/com/primefactorsolutions/views/ProfileView.java deleted file mode 100644 index b5a6988..0000000 --- a/src/main/java/com/primefactorsolutions/views/ProfileView.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.primefactorsolutions.views; - -import com.vaadin.flow.component.html.Main; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import jakarta.annotation.security.PermitAll; -import org.springframework.context.annotation.Scope; - -@SpringComponent -@PermitAll -@Scope("prototype") -@PageTitle("Profile") -@Route(value = "/profiles", layout = MainLayout.class) -public class ProfileView extends Main { -} - diff --git a/src/main/java/com/primefactorsolutions/views/DocumentView.java b/src/main/java/com/primefactorsolutions/views/employee/DocumentView.java similarity index 98% rename from src/main/java/com/primefactorsolutions/views/DocumentView.java rename to src/main/java/com/primefactorsolutions/views/employee/DocumentView.java index 8ffca8a..cbfaca7 100644 --- a/src/main/java/com/primefactorsolutions/views/DocumentView.java +++ b/src/main/java/com/primefactorsolutions/views/employee/DocumentView.java @@ -1,10 +1,12 @@ -package com.primefactorsolutions.views; +package com.primefactorsolutions.views.employee; import com.primefactorsolutions.model.Document; import com.primefactorsolutions.model.DocumentType; import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.service.DocumentService; import com.primefactorsolutions.service.EmployeeService; +import com.primefactorsolutions.views.BaseEntityForm; +import com.primefactorsolutions.views.MainLayout; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; diff --git a/src/main/java/com/primefactorsolutions/views/DocumentsListView.java b/src/main/java/com/primefactorsolutions/views/employee/DocumentsListView.java similarity index 96% rename from src/main/java/com/primefactorsolutions/views/DocumentsListView.java rename to src/main/java/com/primefactorsolutions/views/employee/DocumentsListView.java index 790a4ff..543b09e 100644 --- a/src/main/java/com/primefactorsolutions/views/DocumentsListView.java +++ b/src/main/java/com/primefactorsolutions/views/employee/DocumentsListView.java @@ -1,4 +1,4 @@ -package com.primefactorsolutions.views; +package com.primefactorsolutions.views.employee; import com.google.common.collect.Lists; import com.primefactorsolutions.model.Document; @@ -6,6 +6,8 @@ import com.primefactorsolutions.model.DocumentType; import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.service.DocumentService; import com.primefactorsolutions.service.EmployeeService; +import com.primefactorsolutions.views.BaseView; +import com.primefactorsolutions.views.MainLayout; import com.primefactorsolutions.views.util.MenuBarUtils; import com.vaadin.flow.component.ClickEvent; import com.vaadin.flow.component.Component; diff --git a/src/main/java/com/primefactorsolutions/views/admin/EmployeeReportView.java b/src/main/java/com/primefactorsolutions/views/employee/EmployeeReportView.java similarity index 98% rename from src/main/java/com/primefactorsolutions/views/admin/EmployeeReportView.java rename to src/main/java/com/primefactorsolutions/views/employee/EmployeeReportView.java index 3c3269c..225cf49 100644 --- a/src/main/java/com/primefactorsolutions/views/admin/EmployeeReportView.java +++ b/src/main/java/com/primefactorsolutions/views/employee/EmployeeReportView.java @@ -1,4 +1,4 @@ -package com.primefactorsolutions.views.admin; +package com.primefactorsolutions.views.employee; import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.service.EmployeeService; diff --git a/src/main/java/com/primefactorsolutions/views/EmployeeView.java b/src/main/java/com/primefactorsolutions/views/employee/EmployeeView.java similarity index 99% rename from src/main/java/com/primefactorsolutions/views/EmployeeView.java rename to src/main/java/com/primefactorsolutions/views/employee/EmployeeView.java index 89274ac..a6a8c3a 100644 --- a/src/main/java/com/primefactorsolutions/views/EmployeeView.java +++ b/src/main/java/com/primefactorsolutions/views/employee/EmployeeView.java @@ -1,4 +1,4 @@ -package com.primefactorsolutions.views; +package com.primefactorsolutions.views.employee; import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.model.Team; @@ -7,8 +7,8 @@ import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.service.ReportService; import com.primefactorsolutions.service.TeamService; import com.primefactorsolutions.service.TimeOffRequestService; -import com.primefactorsolutions.views.admin.EmployeeReportView; -import com.primefactorsolutions.views.admin.EmployeesListView; +import com.primefactorsolutions.views.BaseEntityForm; +import com.primefactorsolutions.views.MainLayout; import com.vaadin.componentfactory.pdfviewer.PdfViewer; import com.vaadin.flow.component.ClickEvent; import com.vaadin.flow.component.Component; diff --git a/src/main/java/com/primefactorsolutions/views/admin/EmployeesListView.java b/src/main/java/com/primefactorsolutions/views/employee/EmployeesListView.java similarity index 99% rename from src/main/java/com/primefactorsolutions/views/admin/EmployeesListView.java rename to src/main/java/com/primefactorsolutions/views/employee/EmployeesListView.java index 607564b..84240b4 100644 --- a/src/main/java/com/primefactorsolutions/views/admin/EmployeesListView.java +++ b/src/main/java/com/primefactorsolutions/views/employee/EmployeesListView.java @@ -1,10 +1,9 @@ -package com.primefactorsolutions.views.admin; +package com.primefactorsolutions.views.employee; import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.views.BaseView; import com.primefactorsolutions.views.Constants; -import com.primefactorsolutions.views.EmployeeView; import com.primefactorsolutions.views.MainLayout; import com.primefactorsolutions.views.util.MenuBarUtils; import com.vaadin.flow.component.button.Button; diff --git a/src/main/java/com/primefactorsolutions/views/timeoff/TimeOffSummaryListView.java b/src/main/java/com/primefactorsolutions/views/timeoff/TimeOffSummaryListView.java index 517b82a..9dbdd31 100644 --- a/src/main/java/com/primefactorsolutions/views/timeoff/TimeOffSummaryListView.java +++ b/src/main/java/com/primefactorsolutions/views/timeoff/TimeOffSummaryListView.java @@ -7,10 +7,10 @@ import com.primefactorsolutions.service.TimeOffRequestService; import com.primefactorsolutions.service.TimeOffService; import com.primefactorsolutions.views.BaseView; import com.primefactorsolutions.views.MainLayout; +import com.primefactorsolutions.views.util.MenuBarUtils; import com.vaadin.flow.component.UI; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.html.Span; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; @@ -19,6 +19,7 @@ import com.vaadin.flow.server.StreamResource; import com.vaadin.flow.spring.annotation.SpringComponent; import com.vaadin.flow.spring.security.AuthenticationContext; import jakarta.annotation.security.PermitAll; +import org.apache.commons.lang3.tuple.Pair; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; @@ -36,6 +37,7 @@ import java.time.LocalDate; import java.time.Period; import java.time.Year; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import static com.primefactorsolutions.views.Constants.PAGE_SIZE; @@ -47,6 +49,7 @@ import static com.primefactorsolutions.views.Constants.PAGE_SIZE; @PermitAll public class TimeOffSummaryListView extends BaseView { + private static final Map SUMMARY_MAP = new ConcurrentHashMap<>(); private final TimeOffRequestService requestService; private final EmployeeService employeeService; private final TeamService teamService; @@ -93,12 +96,44 @@ public class TimeOffSummaryListView extends BaseView { private void setupRequestGrid() { requestGrid.addColumn(this::getEmployeeFullName).setHeader("Empleado"); requestGrid.addColumn(this::getTeamName).setHeader("Equipo"); - requestGrid.addColumn(this::getGeneralTotal).setHeader("Total general"); + requestGrid.addColumn(this::getRemainingHolidays).setHeader("Remaining holiday"); + requestGrid.addColumn(this::getRemainingPersonal).setHeader("Remaining personal"); + requestGrid.addColumn(this::getRemainingVacation).setHeader("Remaining vacation"); + requestGrid.addColumn(this::getRemainingTotal).setHeader("Remaining total"); + + if (isRoleAdmin()) { + requestGrid.addComponentColumn(employee -> MenuBarUtils.menuBar( + Pair.of("Download", __ -> downloadEmployeeReport(employee.getId())))); + } requestGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM); requestGrid.setPageSize(PAGE_SIZE); } + private Double getRemainingHolidays(final Employee employee) { + final TimeOffSummary summary = SUMMARY_MAP.computeIfAbsent(employee.getId(), __ -> getTimeOffSummary(employee)); + + return summary.remainingHolidayDays; + } + + private Double getRemainingPersonal(final Employee employee) { + final TimeOffSummary summary = SUMMARY_MAP.computeIfAbsent(employee.getId(), __ -> getTimeOffSummary(employee)); + + return summary.remainingPersonalDays; + } + + private Double getRemainingVacation(final Employee employee) { + final TimeOffSummary summary = SUMMARY_MAP.computeIfAbsent(employee.getId(), __ -> getTimeOffSummary(employee)); + + return summary.remainingVacationDays; + } + + private Double getRemainingTotal(final Employee employee) { + final TimeOffSummary summary = SUMMARY_MAP.computeIfAbsent(employee.getId(), __ -> getTimeOffSummary(employee)); + + return summary.getTotalRemaining(); + } + private void refreshGeneralRequestGrid(final Employee employee, final Team team) { requestGrid.setPagingDataProvider((page, pageSize) -> { @@ -150,32 +185,34 @@ public class TimeOffSummaryListView extends BaseView { } private String getGeneralTotal(final Employee employee) { - List employeeRequests = requestService.findRequestsByEmployeeId(employee.getId()); - List timeOffs = timeOffService.findVacations(); - - List vacationDays = calculateVacationDays(employee); - + final List employeeRequests = requestService.findRequestsByEmployeeId(employee.getId()); + final List timeOffs = timeOffService.findVacations(); + final List vacationDays = calculateVacationDays(employee); double utilizedVacationCurrentDays = vacationDays.get(1); - List vacationCurrentRequests = requestService + + final List vacationCurrentRequests = requestService .findByEmployeeAndCategory(employee.getId(), TimeOffRequestType.VACACION_GESTION_ACTUAL); + if (vacationCurrentRequests != null && !vacationCurrentRequests.isEmpty()) { utilizedVacationCurrentDays = vacationCurrentRequests.getLast().getDaysBalance(); } double totalVacationCurrentDays = vacationDays.get(1) - (vacationDays.get(1) - utilizedVacationCurrentDays); double utilizedVacationPreviousDays = vacationDays.get(0); - List vacationPreviousRequests = requestService + final List vacationPreviousRequests = requestService .findByEmployeeAndCategory(employee.getId(), TimeOffRequestType.VACACION_GESTION_ANTERIOR); + if (vacationPreviousRequests != null && !vacationPreviousRequests.isEmpty()) { utilizedVacationPreviousDays = vacationPreviousRequests.getLast().getDaysBalance(); } - double totalVacationPreviousDays = vacationDays.getFirst() + + final double totalVacationPreviousDays = vacationDays.getFirst() - (vacationDays.getFirst() - utilizedVacationPreviousDays); - double totalUtilized = calculateTotalUtilized(employeeRequests); - double totalVacations = totalVacationCurrentDays + totalVacationPreviousDays; - double totalAvailable = calculateTotalAvailable(timeOffs, employeeRequests, employee); + final double totalUtilized = calculateTotalUtilized(employeeRequests); + final double totalVacations = totalVacationCurrentDays + totalVacationPreviousDays; + final double totalAvailable = calculateTotalAvailable(timeOffs, employeeRequests, employee); double generalTotal = totalAvailable + totalVacations - totalUtilized; @@ -269,6 +306,7 @@ public class TimeOffSummaryListView extends BaseView { vacationDays.add(0.0); vacationDays.add(0.0); } + return vacationDays; } @@ -419,20 +457,7 @@ public class TimeOffSummaryListView extends BaseView { ui.getPage().open(registration.getResourceUri().toString()); } - private HorizontalLayout createSummaryLayout(final Employee employee) { - ResultEmp result = extracted(employee); - double totalAvailableDays = result.remainingHolidayDays() + result.remainingPersonalDays() - + result.remainingVacationDays(); - - return new HorizontalLayout( - new Span("Total feriados fijos y movibles: " + result.remainingHolidayDays()), - new Span("Total días libres personales: " + result.remainingPersonalDays()), - new Span("Total vacaciones pendientes de uso: " + result.remainingVacationDays()), - new Span("TOTAL GENERAL DE DÍAS DISPONIBLES: " + totalAvailableDays) - ); - } - - private ResultEmp extracted(final Employee employee) { + private TimeOffSummary getTimeOffSummary(final Employee employee) { final boolean isMale = employee.getGender() == Employee.Gender.MALE; final int currentYear = LocalDate.now().getYear(); final LocalDate currentDate = LocalDate.now(); @@ -478,10 +503,14 @@ public class TimeOffSummaryListView extends BaseView { currentDate ); - return new ResultEmp(remainingHolidayDays, remainingPersonalDays, remainingVacationDays); + return new TimeOffSummary(remainingHolidayDays, remainingPersonalDays, remainingVacationDays); } - private record ResultEmp(double remainingHolidayDays, double remainingPersonalDays, double remainingVacationDays) { + private record TimeOffSummary(double remainingHolidayDays, double remainingPersonalDays, + double remainingVacationDays) { + public double getTotalRemaining() { + return remainingHolidayDays + remainingPersonalDays + remainingVacationDays; + } } private double getHealthLicence(final UUID employeeId) { @@ -612,7 +641,7 @@ public class TimeOffSummaryListView extends BaseView { private ByteArrayInputStream generatePdfReport(final UUID employeeId) { final List requests = requestService.findRequestsByEmployeeId(employeeId); final Employee employee = employeeService.getEmployee(employeeId); - final ResultEmp result = extracted(employee); + final TimeOffSummary result = getTimeOffSummary(employee); try (PDDocument document = new PDDocument(); ByteArrayOutputStream out = new ByteArrayOutputStream()) { PDPage page = new PDPage(); diff --git a/src/main/java/com/primefactorsolutions/views/util/MenuBarUtils.java b/src/main/java/com/primefactorsolutions/views/util/MenuBarUtils.java index 601b4da..9485172 100644 --- a/src/main/java/com/primefactorsolutions/views/util/MenuBarUtils.java +++ b/src/main/java/com/primefactorsolutions/views/util/MenuBarUtils.java @@ -18,7 +18,8 @@ public class MenuBarUtils { "View", VaadinIcon.EYE, "Edit", VaadinIcon.PENCIL, "Copy", VaadinIcon.COPY, - "Email", VaadinIcon.ENVELOPE + "Email", VaadinIcon.ENVELOPE, + "Download", VaadinIcon.DOWNLOAD ); public static MenuItem createIconItem(final MenuBar menu, final VaadinIcon iconName, final String ariaLabel) {