#45-Registro Semanal de Horas Trabajadas corregir duplicados #70

Closed
melina.gutierrez wants to merge 12 commits from hoursworked into main
10 changed files with 36 additions and 487 deletions
Showing only changes of commit 48e06fef1f - Show all commits

View File

@ -1,204 +0,0 @@
package com.primefactorsolutions.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.UUID;
@Data
@Entity
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Actividad extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
private String nombre;
private double lunes;
private double martes;
private double miercoles;
private double jueves;
private double viernes;
private double sabado;
private double domingo;
private String tarea;
private double horas;
public Actividad() {}
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;
this.tarea = builder.tarea;
this.horas = builder.horas;
}
public String setNombre(final String nombre) {
this.nombre = nombre;
return nombre;
}
public String getNombre() {
return nombre;
}
public void setLunes(double lunes) {
this.lunes = lunes;
return;
}
public void setMartes(double martes) {
this.martes = martes;
return;
}
public void setMiercoles(double miercoles) {
this.miercoles = miercoles;
return;
}
public void setJueves(double jueves) {
this.jueves = jueves;
return;
}
public void setViernes(double viernes) {
this.viernes = viernes;
return;
}
public void setSabado(double sabado) {
this.sabado = sabado;
return;
}
public void setDomingo(double domingo) {
this.domingo = domingo;
return;
}
public void setTarea(String tarea) {
this.tarea = tarea;
return;
}
public void setHoras(double horas) {
this.horas = horas;
return;
}
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;
}
public String getTarea() { // Cambié aquí también
return tarea;
}
public double getHoras() {
return horas;
}
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;
private String tarea;
private double horas;
public Builder tarea(final String tarea, final double horas) {
this.tarea = tarea;
this.horas = horas;
return this;
}
public Builder tarea(final String tarea) {
this.tarea = tarea;
return this;
}
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);
}
}
}

View File

@ -1,81 +0,0 @@
package com.primefactorsolutions.model;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
@Entity
@Table(name = "Actividades_hours")
public class ActividadesHours {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
@ManyToOne
@JoinColumn(name = "employee_id", nullable = false)
private Employee employee;
@ManyToOne
@JoinColumn(name = "actividad_id", nullable = false)
private Actividad actividad;
@Column(nullable = false)
private double totalHours;
@Column(nullable = false)
private int weekNumber;
@Column(nullable = false)
private LocalDate fecha;
// Getters y Setters
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Actividad getActividad() {
return actividad;
}
public void setActividad(Actividad actividad) {
this.actividad = actividad;
}
public double getTotalHours() {
return totalHours;
}
public void setTotalHours(double totalHours) {
this.totalHours = totalHours;
}
public int getWeekNumber() {
return weekNumber;
}
public void setWeekNumber(int weekNumber) {
this.weekNumber = weekNumber;
}
public LocalDate getFecha() {
return fecha;
}
public void setFecha(LocalDate fecha) {
this.fecha = fecha;
}
}

View File

@ -47,10 +47,12 @@ public class Employee extends BaseEntity implements UserDetails {
@JoinColumn(name = "team_id", nullable = false) @JoinColumn(name = "team_id", nullable = false)
private Team team; private Team team;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El nombre y apellido de contacto de emergencia solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El nombre y apellido de contacto"
+ " de emergencia solo debe contener letras")
private String emergencyCName; private String emergencyCName;
private String emergencyCAddress; private String emergencyCAddress;
@Pattern(regexp = "^[0-9]+$", message = "El teléfono de contacto de emergencia debe contener solo números") @Pattern(regexp = "^[0-9]+$", message = "El teléfono de contacto de emergencia "
+ " debe contener solo números")
private String emergencyCPhone; private String emergencyCPhone;
@Email(message = "El correo de contacto de emergencia no tiene un formato válido") @Email(message = "El correo de contacto de emergencia no tiene un formato válido")
private String emergencyCEmail; private String emergencyCEmail;

View File

@ -7,7 +7,6 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.UUID;
@Data @Data
@Entity @Entity
@ -36,7 +35,7 @@ public class HoursWorked extends BaseEntity {
return employee; return employee;
} }
public void setEmployee(Employee employee) { public void setEmployee(final Employee employee) {
this.employee = employee; this.employee = employee;
} }
@ -44,7 +43,7 @@ public class HoursWorked extends BaseEntity {
return weekNumber; return weekNumber;
} }
public void setWeekNumber(int weekNumber) { public void setWeekNumber(final int weekNumber) {
this.weekNumber = weekNumber; this.weekNumber = weekNumber;
} }
@ -52,7 +51,7 @@ public class HoursWorked extends BaseEntity {
return date; return date;
} }
public void setDate(LocalDate date) { public void setDate(final LocalDate date) {
this.date = date; this.date = date;
} }
@ -60,7 +59,7 @@ public class HoursWorked extends BaseEntity {
return actividad; return actividad;
} }
public void setActividad(String actividad) { public void setActividad(final String actividad) {
this.actividad = actividad; this.actividad = actividad;
} }
@ -68,7 +67,7 @@ public class HoursWorked extends BaseEntity {
return hours; return hours;
} }
public void setHours(double hours) { public void setHours(final double hours) {
this.hours = hours; this.hours = hours;
} }
@ -76,7 +75,7 @@ public class HoursWorked extends BaseEntity {
return totalHours; return totalHours;
} }
public void setTotalHours(double totalHours) { public void setTotalHours(final double totalHours) {
this.totalHours = totalHours; this.totalHours = totalHours;
} }
@ -84,7 +83,7 @@ public class HoursWorked extends BaseEntity {
return team; return team;
} }
public void setTeam(Team team) { public void setTeam(final Team team) {
this.team = team; this.team = team;
} }
@ -92,7 +91,7 @@ public class HoursWorked extends BaseEntity {
return tareasEspecificas; return tareasEspecificas;
} }
public void setTareasEspecificas(String tareasEspecificas) { public void setTareasEspecificas(final String tareasEspecificas) {
this.tareasEspecificas = tareasEspecificas; this.tareasEspecificas = tareasEspecificas;
} }
@ -100,7 +99,7 @@ public class HoursWorked extends BaseEntity {
return horasTareasEspecificas; return horasTareasEspecificas;
} }
public void setHorasTareasEspecificas(double horasTareasEspecificas) { public void setHorasTareasEspecificas(final double horasTareasEspecificas) {
this.tareasEspecificas = tareasEspecificas; this.tareasEspecificas = tareasEspecificas;
} }
} }

View File

@ -1,7 +0,0 @@
package com.primefactorsolutions.repositories;
import com.primefactorsolutions.model.ActividadesHours;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface ActividadesHoursRepository extends JpaRepository<ActividadesHours,UUID> {
}

View File

@ -1,6 +1,5 @@
package com.primefactorsolutions.service; package com.primefactorsolutions.service;
import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.model.HoursWorked; import com.primefactorsolutions.model.HoursWorked;
import com.primefactorsolutions.repositories.HoursWorkedRepository; import com.primefactorsolutions.repositories.HoursWorkedRepository;
import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.beanutils.BeanComparator;
@ -9,7 +8,6 @@ import org.springframework.stereotype.Service;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
public class HoursWorkedService { public class HoursWorkedService {

View File

@ -64,9 +64,11 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private final ComboBox<Employee.Gender> gender = createGenderComboBox(); private final ComboBox<Employee.Gender> gender = createGenderComboBox();
private final VDatePicker birthday = new VDatePicker("Fecha de Nacimiento"); private final VDatePicker birthday = new VDatePicker("Fecha de Nacimiento");
private final TextField age = createTextField("Edad", 3, false); private final TextField age = createTextField("Edad", 3, false);
private final TextField birthCity = createTextField("Ciudad y País de Nacimiento ejemplo: (Ciudad, País) ", 30, false); private final TextField birthCity = createTextField("Ciudad y País de Nacimiento ejemplo: (Ciudad, País) ",
30, false);
private final TextField residenceAddress = createTextField("Dirección de Residencia", 50, false); private final TextField residenceAddress = createTextField("Dirección de Residencia", 50, false);
private final TextField localAddress = createTextField("Departamento y Provincia de Residencia ejemplo: (Departamento-Provincia)", 30, false); private final TextField localAddress = createTextField("Departamento y Provincia de Residencia "
+ " ejemplo: (Departamento-Provincia)", 30, false);
private final ComboBox<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox(); private final ComboBox<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox();
private final TextField numberOfChildren = createTextField("Numero de Hijos", 2, false); private final TextField numberOfChildren = createTextField("Numero de Hijos", 2, false);
private final TextField ci = createTextField("CI", 10, false); private final TextField ci = createTextField("CI", 10, false);

View File

@ -2,19 +2,14 @@ package com.primefactorsolutions.views;
import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.model.Team; import com.primefactorsolutions.model.Team;
import com.primefactorsolutions.model.TimeOffRequest;
import com.primefactorsolutions.model.TimeOffRequestStatus;
import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.service.EmployeeService;
import com.primefactorsolutions.service.HoursWorkedService; import com.primefactorsolutions.service.HoursWorkedService;
import com.primefactorsolutions.service.TeamService; import com.primefactorsolutions.service.TeamService;
import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.data.provider.SortDirection;
import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent; import com.vaadin.flow.spring.annotation.SpringComponent;
@ -153,7 +148,9 @@ public class HoursWorkedListView extends Main {
return createButton("Agregar Actividad", this::navigateToHours); return createButton("Agregar Actividad", this::navigateToHours);
} }
private void navigateToHours() { getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class, "new"));} private void navigateToHours() {
getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class, "new"));
}
private ComboBox<Employee> createEmployeeFilter() { private ComboBox<Employee> createEmployeeFilter() {
employeeFilter = new ComboBox<>("Empleado"); employeeFilter = new ComboBox<>("Empleado");

View File

@ -1,161 +0,0 @@
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.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<Employee> employeeComboBox = new ComboBox<>("Empleado");
private final ComboBox<String> equipoDropdown = new ComboBox<>("Equipo");
private final Grid<Actividad> 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(final 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(final LocalDate month) {
// List<Actividad> 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<Actividad> obtenerActividadesDelMes(final LocalDate month) {
// LocalDate startOfMonth = month.with(TemporalAdjusters.firstDayOfMonth());
// LocalDate endOfMonth = month.with(TemporalAdjusters.lastDayOfMonth());
//
// List<Actividad> 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(final List<Actividad> 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(final 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(""));
}
}

View File

@ -52,9 +52,9 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
private Button saveButton; private Button saveButton;
public HoursWorkedView(HoursWorkedService hoursWorkedService, public HoursWorkedView(final HoursWorkedService hoursWorkedService,
EmployeeService employeeService, final EmployeeService employeeService,
TeamService teamService) { final TeamService teamService) {
super(HoursWorked.class); super(HoursWorked.class);
this.hoursWorkedService = hoursWorkedService; this.hoursWorkedService = hoursWorkedService;
this.employeeService = employeeService; this.employeeService = employeeService;
@ -68,7 +68,7 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
@Override @Override
public void setParameter(BeforeEvent beforeEvent, final String action) { public void setParameter(final BeforeEvent beforeEvent, final String action) {
final RouteParameters params = beforeEvent.getRouteParameters(); final RouteParameters params = beforeEvent.getRouteParameters();
final String s = params.get("hours-workedId").orElse(null); final String s = params.get("hours-workedId").orElse(null);
@ -105,7 +105,8 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
private void configureTareasEspecificas() { private void configureTareasEspecificas() {
tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones", "Colaboraciones", "Aprendizajes", "Proyectos PFS", "Otros"); tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones",
"Colaboraciones", "Aprendizajes", "Proyectos PFS", "Otros");
tareasEspecificasDropdown.setPlaceholder("Selecciona una tarea..."); tareasEspecificasDropdown.setPlaceholder("Selecciona una tarea...");
tareasEspecificasDropdown.addValueChangeListener(event -> { tareasEspecificasDropdown.addValueChangeListener(event -> {
@ -187,7 +188,7 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
} }
private void setFieldValues(HoursWorked hoursWorked) { private void setFieldValues(final HoursWorked hoursWorked) {
hoursWorked.setDate(dateField.getValue()); hoursWorked.setDate(dateField.getValue());
hoursWorked.setTeam(teamField.getValue()); hoursWorked.setTeam(teamField.getValue());
hoursWorked.setEmployee(employeeField.getValue()); hoursWorked.setEmployee(employeeField.getValue());
@ -215,14 +216,17 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
private boolean isFormValid() { private boolean isFormValid() {
return dateField.getValue() != null && return dateField.getValue() != null
teamField.getValue() != null && &&
employeeField.getValue() != null && teamField.getValue() != null
&&
employeeField.getValue() != null
&&
!activityField.isEmpty(); !activityField.isEmpty();
} }
private void configureViewOrEditAction(String action) { private void configureViewOrEditAction(final String action) {
if ("edit".equals(action) && hoursWorked != null) { if ("edit".equals(action) && hoursWorked != null) {
setFieldsReadOnly(false); setFieldsReadOnly(false);
} else if ("view".equals(action) && hoursWorked != null) { } else if ("view".equals(action) && hoursWorked != null) {
@ -231,7 +235,7 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
} }
private void setFieldsReadOnly(boolean readOnly) { private void setFieldsReadOnly(final boolean readOnly) {
dateField.setReadOnly(readOnly); dateField.setReadOnly(readOnly);
teamField.setReadOnly(readOnly); teamField.setReadOnly(readOnly);
employeeField.setReadOnly(readOnly); employeeField.setReadOnly(readOnly);