From 2aec8ff05a4c96826b9ceb5e83b5d48994b8b2bf Mon Sep 17 00:00:00 2001 From: Melina Gutierrez Date: Thu, 17 Oct 2024 15:44:28 -0400 Subject: [PATCH] #46 Perfil de Empleado - Registro Semanal Y Mensual falta bd --- .../primefactorsolutions/model/Actividad.java | 111 ++++++ .../model/HoursWorked.java | 50 +++ .../views/HoursWorkedMonthView.java | 163 +++++++++ .../views/HoursWorkedView.java | 327 ++++++++++-------- 4 files changed, 508 insertions(+), 143 deletions(-) create mode 100644 src/main/java/com/primefactorsolutions/model/Actividad.java create mode 100644 src/main/java/com/primefactorsolutions/model/HoursWorked.java create mode 100644 src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java diff --git a/src/main/java/com/primefactorsolutions/model/Actividad.java b/src/main/java/com/primefactorsolutions/model/Actividad.java new file mode 100644 index 0000000..a12164c --- /dev/null +++ b/src/main/java/com/primefactorsolutions/model/Actividad.java @@ -0,0 +1,111 @@ +package com.primefactorsolutions.model; + +final public class Actividad { + private String nombre; + private double lunes; + private double martes; + private double miercoles; + private double jueves; + private double viernes; + private double sabado; + private double domingo; + + public Actividad(final Builder builder) { + this.nombre = builder.nombre; + this.lunes = builder.lunes; + this.martes = builder.martes; + this.miercoles = builder.miercoles; + this.jueves = builder.jueves; + this.viernes = builder.viernes; + this.sabado = builder.sabado; + this.domingo = builder.domingo; + } + + public String getNombre() { + return nombre; + } + + public double getLunes() { + return lunes; + } + + public double getMartes() { + return martes; + } + + public double getMiercoles() { + return miercoles; + } + + public double getJueves() { + return jueves; + } + + public double getViernes() { + return viernes; + } + + public double getSabado() { + return sabado; + } + + public double getDomingo() { + return domingo; + } + + // Builder para crear instancias de Actividad + public static class Builder { + private String nombre; + private double lunes; + private double martes; + private double miercoles; + private double jueves; + private double viernes; + private double sabado; + private double domingo; + + public Builder nombre(final String nombre) { + this.nombre = nombre; + return this; + } + + public Builder lunes(final double horas) { + this.lunes = horas; + return this; + } + + public Builder martes(final double horas) { + this.martes = horas; + return this; + } + + public Builder miercoles(final double horas) { + this.miercoles = horas; + return this; + } + + public Builder jueves(final double horas) { + this.jueves = horas; + return this; + } + + public Builder viernes(final double horas) { + this.viernes = horas; + return this; + } + + public Builder sabado(final double horas) { + this.sabado = horas; + return this; + } + + public Builder domingo(final double horas) { + this.domingo = horas; + return this; + } + + public Actividad build() { + return new Actividad(this); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/primefactorsolutions/model/HoursWorked.java b/src/main/java/com/primefactorsolutions/model/HoursWorked.java new file mode 100644 index 0000000..3824bfe --- /dev/null +++ b/src/main/java/com/primefactorsolutions/model/HoursWorked.java @@ -0,0 +1,50 @@ +package com.primefactorsolutions.model; + +import com.vaadin.flow.component.template.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; + +import java.util.UUID; + +@Entity +public class HoursWorked extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private Employee employee; + + private int weekNumber; + private double totalHours; + + public HoursWorked() {} + + public void setId(Long id) { + this.id = id; + } + + public Employee getEmployee() { + return employee; + } + + public void setEmployee(Employee value) { + this.employee = value; // Asignar el objeto Employee al campo + } + + public int getWeekNumber() { + return weekNumber; + } + + public void setWeekNumber(int weekNumber) { + this.weekNumber = weekNumber; + } + + public double getTotalHours() { + return totalHours; + } + + public void setTotalHours(double totalHours) { + this.totalHours = totalHours; + } +} diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java new file mode 100644 index 0000000..bd9d704 --- /dev/null +++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java @@ -0,0 +1,163 @@ +package com.primefactorsolutions.views; + +import com.primefactorsolutions.model.Employee; +import com.primefactorsolutions.model.Actividad; +import com.primefactorsolutions.service.EmployeeService; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.datepicker.DatePicker; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.Label; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +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.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; + +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; +import java.util.ArrayList; +import java.util.List; + +@SpringComponent +@PermitAll +@Scope("prototype") +@PageTitle("Hours Worked Month") +@Route(value = "/hours-worked-month/me", layout = MainLayout.class) +public class HoursWorkedMonthView extends VerticalLayout { + private final EmployeeService employeeService; + private final ComboBox employeeComboBox = new ComboBox<>("Empleado"); + private final ComboBox equipoDropdown = new ComboBox<>("Equipo"); + private final Grid grid = new Grid<>(Actividad.class); + + private final Label totalCompletadoLabel = new Label(); + private final Label horasPendientesLabel = new Label(); + private final Label totalAcumuladasLabel = new Label(); + private final Label horasAdeudadasLabel = new Label(); + private final Button actualizarButton = new Button("Actualizar"); + private final Button guardarButton = new Button("Guardar"); + private final Button cerrarButton = new Button("Cerrar"); + + private LocalDate selectedMonth; + + @Autowired + public HoursWorkedMonthView(EmployeeService employeeService) { + this.employeeService = employeeService; + configurarVista(); + } + + private void configurarVista() { + DatePicker monthPicker = new DatePicker("Selecciona un mes"); + monthPicker.setValue(LocalDate.now()); + monthPicker.addValueChangeListener(event -> { + selectedMonth = event.getValue().withDayOfMonth(1); + cargarDatosMes(selectedMonth); + }); + + equipoDropdown.setItems("Equipo 1", "Equipo 2", "Equipo 3"); + equipoDropdown.setWidth("250px"); + + setEmployeeComboBoxProperties(); + + configurarGrid(); + + actualizarButton.addClickListener(event -> actualizarDatos()); + guardarButton.addClickListener(event -> guardarActividades()); + cerrarButton.addClickListener(event -> closeView()); + + HorizontalLayout headerLayout = new HorizontalLayout(monthPicker, equipoDropdown, employeeComboBox); + add( + headerLayout, grid, totalCompletadoLabel, + horasPendientesLabel, totalAcumuladasLabel, + horasAdeudadasLabel, actualizarButton, + guardarButton, cerrarButton); + } + + private void setEmployeeComboBoxProperties() { + employeeComboBox.setWidth("250px"); + employeeComboBox.setPlaceholder("Buscar empleado..."); + employeeComboBox.setItems(employeeService.findAllEmployees()); + employeeComboBox.setItemLabelGenerator(employee -> employee.getFirstName() + " " + employee.getLastName()); + } + + private void configurarGrid() { + grid.removeAllColumns(); + grid.addColumn(Actividad::getLunes).setHeader("Lunes"); + grid.addColumn(Actividad::getMartes).setHeader("Martes"); + grid.addColumn(Actividad::getMiercoles).setHeader("Miércoles"); + grid.addColumn(Actividad::getJueves).setHeader("Jueves"); + grid.addColumn(Actividad::getViernes).setHeader("Viernes"); + grid.addColumn(Actividad::getSabado).setHeader("Sábado"); + grid.addColumn(Actividad::getDomingo).setHeader("Domingo"); + grid.addColumn(this::calcularTotalPorDia).setHeader("Total Semanal").setKey("totalSemanal"); + } + + private void cargarDatosMes(LocalDate month) { + List actividadesDelMes = obtenerActividadesDelMes(month); + grid.setItems(actividadesDelMes); + + double totalCompletado = calcularTotalCompletado(actividadesDelMes); + double horasPendientes = calcularHorasPendientes(totalCompletado); + double totalAcumuladas = 166; + double horasAdeudadas = 2; + + totalCompletadoLabel.setText("Prom. Hrs/Semana Completadas: " + totalCompletado); + horasPendientesLabel.setText("Prom. Hrs/Semana Pendientes: " + horasPendientes); + totalAcumuladasLabel.setText("Total Hrs./Mes Acumuladas: " + totalAcumuladas); + horasAdeudadasLabel.setText("Total Hrs./Mes Adeudadas: " + horasAdeudadas); + } + + private List obtenerActividadesDelMes(final LocalDate month) { + LocalDate startOfMonth = month.with(TemporalAdjusters.firstDayOfMonth()); + LocalDate endOfMonth = month.with(TemporalAdjusters.lastDayOfMonth()); + + List actividadesDelMes = new ArrayList<>(); + + for (LocalDate date = startOfMonth; date.isBefore(endOfMonth.plusDays(1)); date = date.plusDays(1)) { + Actividad actividad = new Actividad.Builder() + .lunes(0) + .martes(0) + .miercoles(0) + .jueves(0) + .viernes(0) + .sabado(0) + .domingo(0) + .build(); + actividadesDelMes.add(actividad); + } + + return actividadesDelMes; + } + + private double calcularTotalCompletado(List actividades) { + return actividades.stream() + .mapToDouble(this::calcularTotalPorDia) + .sum(); + } + + private double calcularTotalPorDia(final Actividad actividad) { + return actividad.getLunes() + actividad.getMartes() + actividad.getMiercoles() + + actividad.getJueves() + actividad.getViernes() + actividad.getSabado() + + actividad.getDomingo(); + } + + private double calcularHorasPendientes(double totalCompletado) { + return 40 - totalCompletado; + } + + private void actualizarDatos() { + Notification.show("Datos actualizados."); + } + + private void guardarActividades() { + Notification.show("Actividades guardadas correctamente."); + } + + private void closeView() { + getUI().ifPresent(ui -> ui.navigate("")); + } +} \ 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 faa4208..0fd5604 100644 --- a/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java +++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java @@ -1,19 +1,32 @@ package com.primefactorsolutions.views; - +import com.primefactorsolutions.model.Actividad; +import com.primefactorsolutions.model.Employee; +import com.primefactorsolutions.model.HoursWorked; +import com.primefactorsolutions.service.EmployeeService; import com.vaadin.flow.component.datepicker.DatePicker; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.html.H2; 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.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; +import com.vaadin.flow.component.html.Label; + + +import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.temporal.IsoFields; +import java.time.temporal.WeekFields; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; @SpringComponent @PermitAll @@ -21,20 +34,102 @@ import java.time.LocalDate; @PageTitle("Hours Worked") @Route(value = "/hours-worked/me", layout = MainLayout.class) public class HoursWorkedView extends VerticalLayout { - public HoursWorkedView() { - H2 title = new H2("Registro de Horas Trabajadas"); + private final List actividades = new ArrayList<>(); + private final Grid grid = new Grid<>(Actividad.class); + private final ComboBox employeeComboBox = new ComboBox<>("Employee"); + private LocalDate selectedStartOfWeek; + private int weekNumber; - DatePicker datePicker = new DatePicker("Selecciona una fecha"); - datePicker.setValue(LocalDate.now()); + @Autowired + private final EmployeeService employeeService; + + private final Label fechasLabel = new Label("Selecciona una semana para ver las fechas."); + private final Label totalCompletadoLabel = new Label(); + private final Label horasPendientesLabel = new Label(); + + @Autowired + public HoursWorkedView(final EmployeeService employeeService) { + this.employeeService = employeeService; + configurarVista(); + cargarDatos(); + } + + private void cargarDatos() { + List listaDeHorasTrabajadas = obtenerDatos(); // Obtenemos la lista aquí + grid.setItems(actividades); + + double totalHoras = calcularTotalHoras(listaDeHorasTrabajadas); // Pasa la lista aquí + } + + private void setEmployeeComboBoxProperties() { + employeeComboBox.setWidth("250px"); + employeeComboBox.setPlaceholder("Buscar empleado..."); + employeeComboBox.setItems(employeeService.findAllEmployees()); + employeeComboBox.setItemLabelGenerator(employee -> employee.getFirstName() + " " + employee.getLastName()); + + employeeComboBox.setAllowCustomValue(false); + employeeComboBox.addCustomValueSetListener(event -> + Notification.show("Selecciona un empleado válido de la lista.") + ); + + employeeComboBox.addValueChangeListener(event -> { + Employee selectedEmployee = event.getValue(); + if (selectedEmployee != null) { + Notification.show("Empleado seleccionado: " + + selectedEmployee.getFirstName() + " " + selectedEmployee.getLastName()); + } + }); + } + + private int getWeekOfYear(LocalDate date) { + return date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); + } + + private void configurarVista() { + DatePicker fechaPicker = new DatePicker("Selecciona una fecha"); + fechaPicker.addValueChangeListener(event -> { + LocalDate selectedDate = event.getValue(); + if (selectedDate != null) { + selectedStartOfWeek = getStartOfWeek(selectedDate); + LocalDate endOfWeek = selectedStartOfWeek.plusDays(6); + fechasLabel.setText("Semana del " + selectedStartOfWeek + " al " + endOfWeek); + weekNumber = getWeekOfYear(selectedDate); + } + }); + + Button verMesButton = new Button("Ver Mes", event -> { + getUI().ifPresent(ui -> ui.navigate(HoursWorkedMonthView.class)); + }); ComboBox equipoDropdown = new ComboBox<>("Equipo"); - equipoDropdown.setItems("Equipo 1", "Equipo 2", "Equipo 3"); // Ejemplo de datos + equipoDropdown.setItems("Equipo 1", "Equipo 2", "Equipo 3"); + equipoDropdown.setWidth("250px"); - TextField empleadoSearch = new TextField("Empleado (Search)"); + setEmployeeComboBoxProperties(); - HorizontalLayout filtersLayout = new HorizontalLayout(equipoDropdown, empleadoSearch); + HorizontalLayout filtersLayout = new HorizontalLayout(equipoDropdown, employeeComboBox); + filtersLayout.setSpacing(true); - Grid grid = new Grid<>(Actividad.class, false); + configurarGrid(); + HorizontalLayout actividadFormLayout = configurarFormularioActividades(); + + Button actualizarButton = new Button("Actualizar Totales", event -> actualizarTotales()); + Button guardarButton = new Button("Guardar", event -> guardarActividades()); + Button cerrarButton = new Button("Cerrar", event -> this.closeView()); + + HorizontalLayout buttonsLayout = new HorizontalLayout(actualizarButton, guardarButton, cerrarButton, verMesButton); + + VerticalLayout totalesLayout = new VerticalLayout(totalCompletadoLabel, horasPendientesLabel); + totalesLayout.setSpacing(true); + totalesLayout.setPadding(true); + + add(fechaPicker, fechasLabel, filtersLayout, grid, actividadFormLayout, buttonsLayout, totalesLayout); + + } + + private void configurarGrid() { + grid.removeAllColumns(); + grid.setItems(actividades); grid.addColumn(Actividad::getNombre).setHeader("Actividad"); grid.addColumn(Actividad::getLunes).setHeader("Lunes"); grid.addColumn(Actividad::getMartes).setHeader("Martes"); @@ -43,155 +138,101 @@ public class HoursWorkedView extends VerticalLayout { grid.addColumn(Actividad::getViernes).setHeader("Viernes"); grid.addColumn(Actividad::getSabado).setHeader("Sábado"); grid.addColumn(Actividad::getDomingo).setHeader("Domingo"); - - grid.setItems( - new Actividad.Builder() - .nombre("Actividad 1") - .lunes(3) - .martes(3) - .miercoles(3) - .jueves(3) - .viernes(3) - .sabado(1) - .domingo(2) - .build(), - new Actividad.Builder() - .nombre("Actividad 2") - .lunes(2) - .martes(2) - .miercoles(2) - .jueves(2) - .viernes(2) - .sabado(0) - .domingo(1) - .build(), - new Actividad.Builder() - .nombre("Meeting 1") - .lunes(0) - .martes(0.5) - .miercoles(0.5) - .jueves(0) - .viernes(0) - .sabado(0.5) - .domingo(0) - .build() - ); - - Button actualizarButton = new Button("Actualizar"); - Button guardarButton = new Button("Guardar"); - Button cerrarButton = new Button("Cerrar"); - - HorizontalLayout buttonsLayout = new HorizontalLayout(actualizarButton, guardarButton, cerrarButton); - - add(title, datePicker, filtersLayout, grid, buttonsLayout); + grid.addColumn(this::calcularTotalPorDia).setHeader("Total Día").setKey("totalDia"); } - public static final class Actividad { - private final String nombre; - private final double lunes; - private final double martes; - private final double miercoles; - private final double jueves; - private final double viernes; - private final double sabado; - private final double domingo; + private HorizontalLayout configurarFormularioActividades() { + TextField actividadNombre = new TextField("Actividad"); + actividadNombre.setWidth("200px"); - private Actividad(final Builder builder) { - this.nombre = builder.nombre; - this.lunes = builder.lunes; - this.martes = builder.martes; - this.miercoles = builder.miercoles; - this.jueves = builder.jueves; - this.viernes = builder.viernes; - this.sabado = builder.sabado; - this.domingo = builder.domingo; - } + TextField lunesHoras = crearCampoHora("Lunes"); + TextField martesHoras = crearCampoHora("Martes"); + TextField miercolesHoras = crearCampoHora("Miércoles"); + TextField juevesHoras = crearCampoHora("Jueves"); + TextField viernesHoras = crearCampoHora("Viernes"); + TextField sabadoHoras = crearCampoHora("Sábado"); + TextField domingoHoras = crearCampoHora("Domingo"); - public static class Builder { - private String nombre; - private double lunes; - private double martes; - private double miercoles; - private double jueves; - private double viernes; - private double sabado; - private double domingo; + Button agregarActividadButton = new Button("Agregar Actividad", e -> { + try { + Actividad nuevaActividad = new Actividad.Builder() + .nombre(actividadNombre.getValue()) + .lunes(parseHoras(lunesHoras.getValue())) + .martes(parseHoras(martesHoras.getValue())) + .miercoles(parseHoras(miercolesHoras.getValue())) + .jueves(parseHoras(juevesHoras.getValue())) + .viernes(parseHoras(viernesHoras.getValue())) + .sabado(parseHoras(sabadoHoras.getValue())) + .domingo(parseHoras(domingoHoras.getValue())) + .build(); - public Builder nombre(final String nombre) { - this.nombre = nombre; - return this; + actividades.add(nuevaActividad); + grid.setItems(actividades); + actualizarTotales(); + Notification.show("Actividad agregada correctamente"); + } catch (NumberFormatException ex) { + Notification.show("Error: Por favor ingresa números válidos para las horas."); } + }); - public Builder lunes(final double lunes) { - this.lunes = lunes; - return this; - } + return new HorizontalLayout( + actividadNombre, lunesHoras, martesHoras, miercolesHoras, + juevesHoras, viernesHoras, sabadoHoras, domingoHoras, agregarActividadButton); + } - public Builder martes(final double martes) { - this.martes = martes; - return this; - } + private TextField crearCampoHora(String placeholder) { + TextField field = new TextField(placeholder); + field.setWidth("80px"); + field.setPlaceholder("0.0"); + return field; + } - public Builder miercoles(final double miercoles) { - this.miercoles = miercoles; - return this; - } - - public Builder jueves(final double jueves) { - this.jueves = jueves; - return this; - } - - public Builder viernes(final double viernes) { - this.viernes = viernes; - return this; - } - - public Builder sabado(final double sabado) { - this.sabado = sabado; - return this; - } - - public Builder domingo(final double domingo) { - this.domingo = domingo; - return this; - } - - public Actividad build() { - return new Actividad(this); - } + private double parseHoras(String value) { + if (value == null || value.trim().isEmpty()) { + return 0.0; } + return Double.parseDouble(value); + } - public String getNombre() { - return nombre; - } + private LocalDate getStartOfWeek(final LocalDate date) { + WeekFields weekFields = WeekFields.of(Locale.getDefault()); + return date.with(weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()); + } - public double getLunes() { - return lunes; - } + private double calcularTotalPorDia(final Actividad actividad) { + return actividad.getLunes() + actividad.getMartes() + actividad.getMiercoles() + + actividad.getJueves() + actividad.getViernes() + actividad.getSabado() + actividad.getDomingo(); + } - public double getMartes() { - return martes; - } + private void actualizarTotales() { + double totalSemanaCompletada = actividades.stream() + .mapToDouble(this::calcularTotalPorDia) + .sum(); + double horasPendientes = 40 - totalSemanaCompletada; - public double getMiercoles() { - return miercoles; - } + totalCompletadoLabel.setText("Total Hrs/Semana Completadas: " + totalSemanaCompletada); + horasPendientesLabel.setText("Horas Pendientes: " + horasPendientes); + } - public double getJueves() { - return jueves; - } + private void guardarActividades() { + HoursWorked hoursWorked = new HoursWorked(); + hoursWorked.setEmployee(employeeComboBox.getValue()); + hoursWorked.setWeekNumber(weekNumber); - public double getViernes() { - return viernes; - } + Notification.show("Actividades guardadas correctamente."); + } - public double getSabado() { - return sabado; - } + private double calcularTotalHoras(List listaDeHorasTrabajadas) { + return listaDeHorasTrabajadas.stream() + .mapToDouble(HoursWorked::getTotalHours) + .sum(); + } - public double getDomingo() { - return domingo; - } + private List obtenerDatos() { + return new ArrayList<>(); + } + + private void closeView() { + getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class)); } }