diff --git a/package.json b/package.json index 3395e11..209a580 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "module", "dependencies": { "@f0rce/ace-widget": "1.0.2", - "@polymer/polymer": "3.5.1", + "@polymer/polymer": "3.5.2", "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1", "@vaadin/bundles": "24.5.1", "@vaadin/common-frontend": "0.0.19", @@ -19,29 +19,30 @@ "@vaadin/vaadin-usage-statistics": "2.1.3", "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", - "lit": "3.1.4", + "lit": "3.2.1", "print-js": "1.6.0", "proj4": "2.12.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.23.1" + "react-router-dom": "6.26.2" }, "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.25.7", + "@preact/signals-react-transform": "0.4.0", + "@rollup/plugin-replace": "6.0.1", + "@rollup/pluginutils": "5.1.2", + "@types/react": "18.3.11", + "@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-visualizer": "5.12.0", "strip-css-comments": "5.0.0", "transform-ast": "2.4.4", - "typescript": "5.4.5", - "vite": "5.3.3", - "vite-plugin-checker": "0.6.4", + "typescript": "5.6.3", + "vite": "5.4.9", + "vite-plugin-checker": "0.8.0", "workbox-build": "7.1.1", "workbox-core": "7.1.0", "workbox-precaching": "7.1.0" @@ -49,7 +50,7 @@ "vaadin": { "dependencies": { "@f0rce/ace-widget": "1.0.2", - "@polymer/polymer": "3.5.1", + "@polymer/polymer": "3.5.2", "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1", "@vaadin/bundles": "24.5.1", "@vaadin/common-frontend": "0.0.19", @@ -64,34 +65,35 @@ "@vaadin/vaadin-usage-statistics": "2.1.3", "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", - "lit": "3.1.4", + "lit": "3.2.1", "print-js": "1.6.0", "proj4": "2.12.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.23.1" + "react-router-dom": "6.26.2" }, "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.25.7", + "@preact/signals-react-transform": "0.4.0", + "@rollup/plugin-replace": "6.0.1", + "@rollup/pluginutils": "5.1.2", + "@types/react": "18.3.11", + "@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-visualizer": "5.12.0", "strip-css-comments": "5.0.0", "transform-ast": "2.4.4", - "typescript": "5.4.5", - "vite": "5.3.3", - "vite-plugin-checker": "0.6.4", + "typescript": "5.6.3", + "vite": "5.4.9", + "vite-plugin-checker": "0.8.0", "workbox-build": "7.1.1", "workbox-core": "7.1.0", "workbox-precaching": "7.1.0" }, - "hash": "1a0f17d48b329307b5862bc57499307d1b89f7d89260121c2b7189f76957c436" + "hash": "2dc40a4f634ae025081ca2239cba00b14a35fe94ab78ac0a4dd3023d882081d5" }, "overrides": { "@vaadin/bundles": "$@vaadin/bundles", diff --git a/src/main/java/com/primefactorsolutions/model/HoursWorked.java b/src/main/java/com/primefactorsolutions/model/HoursWorked.java index 560a6eb..32f465b 100644 --- a/src/main/java/com/primefactorsolutions/model/HoursWorked.java +++ b/src/main/java/com/primefactorsolutions/model/HoursWorked.java @@ -102,5 +102,31 @@ public class HoursWorked extends BaseEntity { public void setHorasTareasEspecificas(final double horasTareasEspecificas) { this.tareasEspecificas = tareasEspecificas; } + public double getHoraspendientes() { + double horasTrabajadas = this.getTotalHours() + this.getHorasTareasEspecificas(); + return 40 - horasTrabajadas; + } + + public void setHoraspendientes(final double horaspendientes) { + this.horaspendientes = horaspendientes; + } + + public double getHoursWorked() { + return hours; + } + + public void setHoursWorked(final double hoursWorked) { + this.hours = hoursWorked; + } + + public double getTotalHoursWorked() { + return totalHours; + } + + public void setTotalHoursWorked(final double totalHoursWorked) { + this.totalHours = totalHoursWorked; + } + + } diff --git a/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java b/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java index 06d8552..52c0df8 100644 --- a/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java +++ b/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java @@ -11,4 +11,5 @@ import java.util.UUID; public interface HoursWorkedRepository extends JpaRepository { List findByWeekNumber(int weekNumber); List findByDate(LocalDate date); + List findByEmployeeIdAndWeekNumber(UUID employeeId, int weekNumber); } \ No newline at end of file diff --git a/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java b/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java index dc1b220..72960d9 100644 --- a/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java +++ b/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java @@ -22,6 +22,14 @@ public class HoursWorkedService { return hoursWorkedRepository.findAll(); } + public double getTotalHoursWorkedByEmployeeForWeek(UUID employeeId, int weekNumber) { + List hoursWorkedList = hoursWorkedRepository.findByWeekNumber(weekNumber); + return hoursWorkedList.stream() + .filter(hw -> hw.getEmployee().getId().equals(employeeId)) + .mapToDouble(HoursWorked::getTotalHours) + .sum(); + } + public HoursWorked findHoursWorked(final UUID id) { Optional hoursWorked = hoursWorkedRepository.findById(id); HoursWorked hw = hoursWorked.get(); diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java index 26def46..be01789 100644 --- a/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java +++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java @@ -1,6 +1,7 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.Employee; +import com.primefactorsolutions.model.HoursWorked; import com.primefactorsolutions.model.Team; import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.service.HoursWorkedService; @@ -14,9 +15,12 @@ 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.joda.time.Hours; import org.springframework.context.annotation.Scope; import org.vaadin.firitin.components.grid.PagingGrid; +import java.time.LocalDate; +import java.time.temporal.IsoFields; import java.util.*; import java.util.stream.Collectors; @@ -30,8 +34,7 @@ public class HoursWorkedListView extends Main { private final HoursWorkedService hoursWorkedService; private final EmployeeService employeeService; private final TeamService teamService; - private final PagingGrid hoursWorkedGrid = new PagingGrid<>(); - private final PagingGrid table = new PagingGrid<>(Employee.class); + private final PagingGrid hoursWorkedGrid = new PagingGrid<>(); private List employees = Collections.emptyList(); private ComboBox employeeFilter; private ComboBox teamFilter; @@ -51,34 +54,58 @@ public class HoursWorkedListView extends Main { } private void refreshGridListHoursWorked(final Employee employee, - final Team team) { + final Team team) { hoursWorkedGrid.setPagingDataProvider((page, pageSize) -> { int start = (int) (page * hoursWorkedGrid.getPageSize()); - return fetchFilteredEmployees(start, pageSize, employee, team); + List hoursWorkedList = fetchFilteredHoursWorked(start, pageSize, employee, team); + + double totalHours = hoursWorkedList.stream() + .mapToDouble(HoursWorked::getTotalHours) + .sum(); + + Notification.show("Total de horas trabajadas: " + totalHours, 3000, Notification.Position.BOTTOM_CENTER); + + return hoursWorkedList; }); hoursWorkedGrid.getDataProvider().refreshAll(); } - private List fetchFilteredEmployees(final int start, - final int pageSize, - final Employee employee, - final Team team) { - List filteredEmployees = employeeService.findAllEmployees(); + private List fetchFilteredHoursWorked(final int start, + final int pageSize, + final Employee employee, + final Team team) { + List filteredHoursWorked = hoursWorkedService.findAll(); if (employee != null && !"TODOS".equals(employee.getFirstName())) { - filteredEmployees = filteredEmployees.stream() - .filter(emp -> emp.getId().equals(employee.getId())) + filteredHoursWorked = filteredHoursWorked.stream() + .filter(hw -> hw.getEmployee().getId().equals(employee.getId())) .collect(Collectors.toList()); } if (team != null && !"TODOS".equals(team.getName())) { - filteredEmployees = filteredEmployees.stream() - .filter(emp -> emp.getTeam() != null && emp.getTeam().getId().equals(team.getId())) + filteredHoursWorked = filteredHoursWorked.stream() + .filter(hw -> hw.getEmployee().getTeam() != null && hw.getEmployee().getTeam().getId().equals(team.getId())) .collect(Collectors.toList()); } - int end = Math.min(start + pageSize, filteredEmployees.size()); - return filteredEmployees.subList(start, end); + for (HoursWorked hoursWorked : filteredHoursWorked) { + if (employee != null && hoursWorked.getEmployee().getId().equals(employee.getId())) { + LocalDate date = hoursWorked.getDate(); + int currentWeek = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); + + double totalWorkedInSameWeek = filteredHoursWorked.stream() + .filter(hw -> hw.getEmployee().getId().equals(employee.getId()) && + hw.getDate().get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) == currentWeek) + .mapToDouble(HoursWorked::getHours) + .sum(); + + double updatedPendingHours = totalWorkedInSameWeek - hoursWorked.getHours(); + hoursWorked.setHoraspendientes(updatedPendingHours); + } + } + + int end = Math.min(start + pageSize, filteredHoursWorked.size()); + return filteredHoursWorked.subList(start, end); } private void initializeView() { @@ -95,29 +122,27 @@ public class HoursWorkedListView extends Main { } private void setupListHoursWorkedGrid() { - hoursWorkedGrid.addColumn(this::getEmployeeFullName).setHeader("Empleado"); - hoursWorkedGrid.addColumn(this::getTeamName).setHeader("Equipo"); + hoursWorkedGrid.addColumn(hw -> hw.getDate() != null ? hw.getDate().toString() : "") + .setHeader("Fecha") + .setSortable(true); + hoursWorkedGrid.addColumn(hw -> hw.getEmployee().getFirstName() + " " + hw.getEmployee().getLastName()) + .setHeader("Empleado"); + hoursWorkedGrid.addColumn(hw -> hw.getEmployee().getTeam() != null ? hw.getEmployee().getTeam().getName() : "Sin asignar") + .setHeader("Equipo"); + hoursWorkedGrid.addColumn(HoursWorked::getActividad).setHeader("Actividad"); + hoursWorkedGrid.addColumn(hw -> hw.getHours()).setHeader("Total Horas").setSortable(true); + hoursWorkedGrid.addColumn(hw -> hw.getHoraspendientes()).setHeader("Horas Pendientes").setSortable(true); hoursWorkedGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM); hoursWorkedGrid.setPageSize(5); hoursWorkedGrid.asSingleSelect().addValueChangeListener(event -> { - Employee selectedRequest = event.getValue(); - if (selectedRequest != null) { - selectedEmployeeId = selectedRequest.getId(); + HoursWorked selectedHoursWorked = event.getValue(); + if (selectedHoursWorked != null) { + selectedEmployeeId = selectedHoursWorked.getEmployee().getId(); } }); } - private String getTeamName(final Employee employee) { - Team team = employee.getTeam(); - return team != null ? team.getName() : "Sin asignar"; - } - - private String getTeamLabel(final Team team) { - return "TODOS".equals(team.getName()) ? "TODOS" : team.getName(); - } - - private HorizontalLayout createActionButtons() { Button viewButton = new Button("Ver", event -> { if (selectedEmployeeId != null) { @@ -178,7 +203,7 @@ public class HoursWorkedListView extends Main { List teams = new ArrayList<>(teamService.findAllTeams()); teams.addFirst(createAllTeamsOption()); teamFilter.setItems(teams); - teamFilter.setItemLabelGenerator(this::getTeamLabel); + teamFilter.setItemLabelGenerator(team -> getTeamLabel(team)); teamFilter.setValue(teams.getFirst()); teamFilter.addValueChangeListener(event -> refreshGridListHoursWorked( @@ -189,6 +214,9 @@ public class HoursWorkedListView extends Main { return teamFilter; } + private String getTeamLabel(final Team team) { + return team != null && !"TODOS".equals(team.getName()) ? team.getName() : "TODOS"; + } private Employee createAllEmployeesOption() { Employee allEmployeesOption = new Employee(); @@ -201,11 +229,4 @@ public class HoursWorkedListView extends Main { allTeamsOption.setName("TODOS"); return allTeamsOption; } - - - private void setupPagingGrid() { - table.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM); - table.setPageSize(5); - } - -} +} \ No newline at end of file diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java index c325795..752bad9 100644 --- a/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java +++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java @@ -243,4 +243,6 @@ public class HoursWorkedView extends BeanValidationForm implements } + + } \ No newline at end of file