diff --git a/.gitea/workflows/build-pr.yaml b/.gitea/workflows/build-pr.yaml
deleted file mode 100644
index 90aad01..0000000
--- a/.gitea/workflows/build-pr.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: PR Builder
-run-name: ${{ gitea.actor }} building PR
-on: [pull_request]
-
-jobs:
- Build-PR:
- runs-on: ubuntu-22.04
- steps:
- - run: echo "The job was automatically triggered by a ${{ gitea.event_name }} event on branch ${{ gitea.head_ref }} and ref is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- - name: Build PR
- if: gitea.base_ref == 'main'
- run: |
- git clone --single-branch --branch "${{ gitea.head_ref }}" https://git.primefactorsolutions.com/PFS/pfs-intra.git && cd pfs-intra && ./mvnw clean package -Pproduction
- - run: echo "This job's status is ${{ job.status }}."
diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml
deleted file mode 100644
index e64cc3a..0000000
--- a/.gitea/workflows/build.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Builder
-run-name: ${{ gitea.actor }} building
-on:
- push:
- branches:
- - main
-
-jobs:
- Build-Project:
- runs-on: ubuntu-22.04
- steps:
- - run: echo "The job was automatically triggered by a ${{ gitea.event_name }} event on branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- - name: Build package
- run: |
- git clone --single-branch --branch main https://git.primefactorsolutions.com/PFS/pfs-intra.git && cd pfs-intra && ./mvnw clean package -Pproduction && unlink /home/ubuntu/pfs-intra/app.jar && cp target/*.jar /home/ubuntu/pfs-intra/app.jar && sudo systemctl restart pfs-intra
- - run: echo "This job's status is ${{ job.status }}."
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
deleted file mode 100644
index 8895dd4..0000000
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2007-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import java.io.*;
-import java.net.*;
-import java.nio.channels.*;
-import java.util.Properties;
-
-public class MavenWrapperDownloader {
-
- private static final String WRAPPER_VERSION = "0.5.6";
- /**
- * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is
- * provided.
- */
- private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
- + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
-
- /**
- * Path to the maven-wrapper.properties file, which might contain a downloadUrl
- * property to use instead of the default one.
- */
- private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties";
-
- /**
- * Path where the maven-wrapper.jar will be saved to.
- */
- private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar";
-
- /**
- * Name of the property which should be used to override the default download
- * url for the wrapper.
- */
- private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
-
- public static void main(String args[]) {
- System.out.println("- Downloader started");
- File baseDirectory = new File(args[0]);
- System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
-
- // If the maven-wrapper.properties exists, read it and check if it contains a
- // custom
- // wrapperUrl parameter.
- File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
- String url = DEFAULT_DOWNLOAD_URL;
- if (mavenWrapperPropertyFile.exists()) {
- FileInputStream mavenWrapperPropertyFileInputStream = null;
- try {
- mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
- Properties mavenWrapperProperties = new Properties();
- mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
- url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
- } catch (IOException e) {
- System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
- } finally {
- try {
- if (mavenWrapperPropertyFileInputStream != null) {
- mavenWrapperPropertyFileInputStream.close();
- }
- } catch (IOException e) {
- // Ignore ...
- }
- }
- }
- System.out.println("- Downloading from: " + url);
-
- File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
- if (!outputFile.getParentFile().exists()) {
- if (!outputFile.getParentFile().mkdirs()) {
- System.out.println(
- "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
- }
- }
- System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
- try {
- downloadFileFromURL(url, outputFile);
- System.out.println("Done");
- System.exit(0);
- } catch (Throwable e) {
- System.out.println("- Error downloading");
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static void downloadFileFromURL(String urlString, File destination) throws Exception {
- if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
- String username = System.getenv("MVNW_USERNAME");
- char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
- Authenticator.setDefault(new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- }
- URL website = new URL(urlString);
- ReadableByteChannel rbc;
- rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(destination);
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
- fos.close();
- rbc.close();
- }
-
-}
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index c1dd12f..0000000
Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index 8c79a83..0000000
--- a/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
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/pfs-intra.eml b/pfs-intra.eml
new file mode 100644
index 0000000..238063b
--- /dev/null
+++ b/pfs-intra.eml
@@ -0,0 +1,539 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/primefactorsolutions/model/Actividad.java b/src/main/java/com/primefactorsolutions/model/Actividad.java
deleted file mode 100644
index 6b0a4b1..0000000
--- a/src/main/java/com/primefactorsolutions/model/Actividad.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.primefactorsolutions.model;
-
-public final 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;
- private String tarea;
- private double horas;
-
- 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 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;
- }
-
- public String getTarea() { // Cambié aquí también
- return tarea;
- }
-
- public double getHoras() {
- return horas;
- }
-
- // 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;
- private String tarea; // Cambié 'tarea' por 'descripcion'
- 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);
- }
- }
-}
diff --git a/src/main/java/com/primefactorsolutions/model/Employee.java b/src/main/java/com/primefactorsolutions/model/Employee.java
index 1d3df41..f4d3236 100644
--- a/src/main/java/com/primefactorsolutions/model/Employee.java
+++ b/src/main/java/com/primefactorsolutions/model/Employee.java
@@ -28,36 +28,42 @@ public class Employee extends BaseEntity implements UserDetails {
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El apellido solo debe contener letras")
private String lastName;
private LocalDate birthday;
- @Pattern(regexp = "^[a-zA-Z ]+$", message = "La ciudad de nacimiento solo debe contener letras")
+ @Pattern(regexp = "^[a-zA-Z ,]+$", message = "La ciudad de nacimiento solo debe contener letras, espacios o comas")
private String birthCity;
private String age;
- @Size(max = 100, message = "La dirección de residencia no debe exceder 100 caracteres")
+ @Size(max = 50, message = "La dirección de residencia no debe exceder 50 caracteres")
private String residenceAddress;
- @Size(max = 100, message = "La dirección local no debe exceder 100 caracteres")
+ @Size(max = 30, message = "La dirección local no debe exceder 100 caracteres")
+ @Pattern(regexp = "^[a-zA-Z -]+$", message = "La dirección local solo debe contener letras y guion")
private String localAddress;
@Pattern(regexp = "^[0-9]+$", message = "El número de teléfono debe contener solo números")
private String phoneNumber;
@Email(message = "El correo personal no tiene un formato válido")
private String personalEmail;
+
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El cargo solo debe contener letras")
private String position;
@ManyToOne
@JoinColumn(name = "team_id", nullable = false)
private Team team;
- @Size(max = 100, message = "El nombre de contacto de emergencia no debe exceder 100 caracteres")
+
+ @Pattern(regexp = "^[a-zA-Z ]+$", message = "El nombre y apellido de contacto"
+ + " de emergencia solo debe contener letras")
private String emergencyCName;
- @Size(max = 100, message = "La dirección de contacto de emergencia no debe exceder 100 caracteres")
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;
@Email(message = "El correo de contacto de emergencia no tiene un formato válido")
private String emergencyCEmail;
+
+ @Max(value = 10, message = "El número de hijos no puede exceder a 10")
@Pattern(regexp = "^[0-9]+$", message = "La cantidad de hijos debe contener solo números")
private String numberOfChildren;
+
@Pattern(regexp = "^[0-9]+$", message = "El CI debe contener solo números")
private String ci;
private String issuedIn;
- @Size(max = 100, message = "El título no debe exceder 100 caracteres")
private String pTitle1;
private String pTitle2;
private String pTitle3;
@@ -70,9 +76,7 @@ public class Employee extends BaseEntity implements UserDetails {
private String certification2;
private String certification3;
private String certification4;
- @Size(max = 255, message = "El reconocimiento no debe exceder 255 caracteres")
private String recognition;
- @Size(max = 500, message = "Los logros no deben exceder 500 caracteres")
private String achievements;
private String language;
diff --git a/src/main/java/com/primefactorsolutions/model/HoursWorked.java b/src/main/java/com/primefactorsolutions/model/HoursWorked.java
index d02310f..32f465b 100644
--- a/src/main/java/com/primefactorsolutions/model/HoursWorked.java
+++ b/src/main/java/com/primefactorsolutions/model/HoursWorked.java
@@ -1,41 +1,42 @@
package com.primefactorsolutions.model;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.ManyToOne;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
-import java.util.UUID;
+import java.time.LocalDate;
+@Data
@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
public class HoursWorked extends BaseEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.UUID)
- private UUID id;
-
@ManyToOne
+ @JoinColumn(name = "employee_id", nullable = true)
private Employee employee;
+ @ManyToOne
+ @JoinColumn(name = "team_id", nullable = true)
+ private Team team;
+
private int weekNumber;
+ private LocalDate date;
+ private String actividad;
+ private String tareasEspecificas;
+ private double hours;
+ private double horasTareasEspecificas;
+ private double horaspendientes;
private double totalHours;
- public HoursWorked() { }
-
- public UUID getId() {
- return id;
- }
-
- public void setId(final UUID id) {
- this.id = id;
- }
-
public Employee getEmployee() {
return employee;
}
- public void setEmployee(final Employee value) {
- this.employee = value;
+ public void setEmployee(final Employee employee) {
+ this.employee = employee;
}
public int getWeekNumber() {
@@ -46,6 +47,30 @@ public class HoursWorked extends BaseEntity {
this.weekNumber = weekNumber;
}
+ public LocalDate getDate() {
+ return date;
+ }
+
+ public void setDate(final LocalDate date) {
+ this.date = date;
+ }
+
+ public String getActividad() {
+ return actividad;
+ }
+
+ public void setActividad(final String actividad) {
+ this.actividad = actividad;
+ }
+
+ public double getHours() {
+ return hours;
+ }
+
+ public void setHours(final double hours) {
+ this.hours = hours;
+ }
+
public double getTotalHours() {
return totalHours;
}
@@ -53,4 +78,55 @@ public class HoursWorked extends BaseEntity {
public void setTotalHours(final double totalHours) {
this.totalHours = totalHours;
}
+
+ public Team getTeam() {
+ return team;
+ }
+
+ public void setTeam(final Team team) {
+ this.team = team;
+ }
+
+ public String getTareasEspecificas() {
+ return tareasEspecificas;
+ }
+
+ public void setTareasEspecificas(final String tareasEspecificas) {
+ this.tareasEspecificas = tareasEspecificas;
+ }
+
+ public double getHorasTareasEspecificas() {
+ return horasTareasEspecificas;
+ }
+
+ 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/EmployeeRepository.java b/src/main/java/com/primefactorsolutions/repositories/EmployeeRepository.java
index d57397f..3f09154 100644
--- a/src/main/java/com/primefactorsolutions/repositories/EmployeeRepository.java
+++ b/src/main/java/com/primefactorsolutions/repositories/EmployeeRepository.java
@@ -11,7 +11,7 @@ public interface EmployeeRepository extends JpaRepository {
Optional findByUsername(String username);
Optional findByPersonalEmail(String personalEmail);
- Optional findByTeamId(UUID teamId);
+ Optional findByTeamIdAndLeadManagerTrue(UUID teamId);
List findByTeamName(String teamName);
}
diff --git a/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java b/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java
index 6e0e69c..52c0df8 100644
--- a/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java
+++ b/src/main/java/com/primefactorsolutions/repositories/HoursWorkedRepository.java
@@ -2,13 +2,14 @@ package com.primefactorsolutions.repositories;
import com.primefactorsolutions.model.HoursWorked;
import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
+import java.time.LocalDate;
import java.util.List;
+import java.util.UUID;
-@Repository
-public interface HoursWorkedRepository extends JpaRepository {
- // Puedes definir consultas personalizadas aquí si es necesario.
+
+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/EmployeeService.java b/src/main/java/com/primefactorsolutions/service/EmployeeService.java
index 52c15dd..646278a 100644
--- a/src/main/java/com/primefactorsolutions/service/EmployeeService.java
+++ b/src/main/java/com/primefactorsolutions/service/EmployeeService.java
@@ -50,7 +50,7 @@ public class EmployeeService {
public String getTeamLeadName(final UUID teamId) {
// Encuentra al empleado con el rol de lead_manager en el equipo especificado
- Optional leadManager = employeeRepository.findByTeamId(teamId);
+ Optional leadManager = employeeRepository.findByTeamIdAndLeadManagerTrue(teamId);
return leadManager.map(employee -> employee.getFirstName() + " " + employee.getLastName())
.orElse("No asignado");
diff --git a/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java b/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java
index 2bfe882..72960d9 100644
--- a/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java
+++ b/src/main/java/com/primefactorsolutions/service/HoursWorkedService.java
@@ -2,10 +2,12 @@ package com.primefactorsolutions.service;
import com.primefactorsolutions.model.HoursWorked;
import com.primefactorsolutions.repositories.HoursWorkedRepository;
+import org.apache.commons.beanutils.BeanComparator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.List;
+import java.time.LocalDate;
+import java.util.*;
@Service
public class HoursWorkedService {
@@ -20,6 +22,20 @@ 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();
+ return hw;
+ }
+
public HoursWorked saveHoursWorked(final HoursWorked hoursWorked) {
return hoursWorkedRepository.save(hoursWorked);
}
@@ -28,13 +44,42 @@ public class HoursWorkedService {
return hoursWorkedRepository.save(hoursWorked);
}
- public void deleteHoursWorked(final Long id) {
- hoursWorkedRepository.deleteById(id);
- }
-
public List findByWeekNumber(final int weekNumber) {
return hoursWorkedRepository.findByWeekNumber(weekNumber);
}
-}
+ public List findByDate(final LocalDate date) {
+ return hoursWorkedRepository.findByDate(date);
+ }
+ public List findByDateAndWeekNumber(final LocalDate date, final int weekNumber) {
+ return hoursWorkedRepository.findByDate(date);
+ }
+
+ public List findHoursWorkeds(
+ final int start, final int pageSize, final String sortProperty, final boolean asc) {
+ List hoursWorkeds = hoursWorkedRepository.findAll();
+
+ int end = Math.min(start + pageSize, hoursWorkeds.size());
+ hoursWorkeds.sort(new BeanComparator<>(sortProperty));
+
+ if (!asc) {
+ Collections.reverse(hoursWorkeds);
+ }
+
+ return hoursWorkeds.subList(start, end);
+ }
+
+ public List findHoursWorkeds(final int start, final int pageSize) {
+ List hoursWorkeds = hoursWorkedRepository.findAll();
+
+ int end = Math.min(start + pageSize, hoursWorkeds.size());
+ return hoursWorkeds.subList(start, end);
+ }
+
+ public HoursWorked getHoursWorked(final UUID id) {
+ final Optional hoursWorked = hoursWorkedRepository.findById(id);
+ return hoursWorked.get();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/primefactorsolutions/views/EmployeeView.java b/src/main/java/com/primefactorsolutions/views/EmployeeView.java
index 35b99ad..4e34abb 100644
--- a/src/main/java/com/primefactorsolutions/views/EmployeeView.java
+++ b/src/main/java/com/primefactorsolutions/views/EmployeeView.java
@@ -56,7 +56,6 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
private final TimeOffRequestService requestService;
private final TeamService teamService;
-
// TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente.
private final TextField username = createTextField("Username: ", 30, true);
private final TextField firstName = createTextField("Nombres: ", 30, true);
@@ -65,24 +64,21 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
private final ComboBox gender = createGenderComboBox();
private final VDatePicker birthday = new VDatePicker("Fecha de Nacimiento");
private final TextField age = createTextField("Edad", 3, false);
- private final TextField birthCity = createTextField("Ciudad y País de Nacimiento", 20, 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 localAddress = createTextField("Dep/Provincia de Residencia", 10, false);
+ private final TextField localAddress = createTextField("Departamento y Provincia de Residencia "
+ + " ejemplo: (Departamento-Provincia)", 30, false);
private final ComboBox maritalStatus = createMaritalStatusComboBox();
- private final TextField numberOfChildren = createTextField("Numero de Hijos", 3, false);
- private final TextField ci = createTextField("CI", 30, false);
- private final TextField issuedIn = createTextField("Expedido en ", 30, false);
+ private final TextField numberOfChildren = createTextField("Numero de Hijos", 2, false);
+ private final TextField ci = createTextField("CI", 10, false);
+ private final TextField issuedIn = createTextField("Expedido en ", 10, false);
private final TextField phoneNumber = createTextField("Teléfono", 8, false);
- private final EmailField personalEmail = createEmailField("E-mail");
- private final TextField cod = createTextField("Codigo de Empleado", 30, false);
- private final TextField position = createTextField("Cargo", 30, false);
- private final ComboBox team = new ComboBox<>("Equipo");
- private final TextField leadManager = createTextField("Lead/Manager", 30, false);
- private final TextField project = createTextField("Proyecto", 30, false);
+ private final EmailField personalEmail = createEmailField("E-mail ejemplo: (ejemplo@gmail.com)");
private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false);
private final TextField emergencyCAddress = createTextField("Dirección de Contacto", 50, false);
private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, false);
- private final EmailField emergencyCEmail = createEmailField("Email de Contacto");
+ private final EmailField emergencyCEmail = createEmailField("Email de Contacto ejemplo: (ejemplo@gmail.com)");
private final MemoryBuffer buffer = new MemoryBuffer();
private final Upload upload = new Upload(buffer);
@@ -101,10 +97,15 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
private final TextField certification4 = createTextField("Certificación 4", 30, false);
private final TextField recognition = createTextField("Reconocimientos", 30, false);
private final TextField achievements = createTextField("Logros Profesionales", 30, false);
- private final TextField language = createTextField("Idioma", 30, false);
+ private final TextField language = createTextField("Idioma", 50, false);
private final TextField languageLevel = createTextField("Nivel de Idioma", 30, false);
- //INFORMACION DE CONTRATACION
+ //INFORMACION ADMINISTRATIVA
+ private final TextField cod = createTextField("Codigo de Empleado", 20, false);
+ private final TextField position = createTextField("Cargo", 30, false);
+ private final ComboBox team = new ComboBox<>("Equipo");
+ private final TextField leadManager = createTextField("Lead/Manager", 30, false);
+ private final TextField project = createTextField("Proyecto", 30, false);
private final VDatePicker dateOfEntry = new VDatePicker("Fecha de Ingreso");
private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro");
private final TextField contractType = createTextField("Tipo de Contratación", 30, false);
@@ -141,7 +142,7 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
//TITULOS PARA INFORMACIÓN ADMINISTRATIVA
private final H2 infoAdm = new H2("Información Administrativa");
private final H3 infoCont = new H3("Información de Contratación");
- private final H3 datBanc = new H3("Datos Bancados");
+ private final H3 datBanc = new H3("Datos Bancarios");
private final H3 datGest = new H3("Datos Gestora Pública y Seguro Social");
public EmployeeView(final EmployeeService employeeService,
@@ -176,6 +177,9 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
editButton.setVisible(true);
reportButton.setVisible(true);
birthday.addValueChangeListener(event -> calculateAge());
+ birthday.setMax(java.time.LocalDate.now());
+ dateOfEntry.addValueChangeListener(event -> calculateSeniority());
+ dateOfEntry.addValueChangeListener(event -> calculateSeniority());
reportButton.addClickListener((ComponentEventListener>) buttonClickEvent -> {
var employee = getEntity();
@@ -203,10 +207,30 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
int birthYear = birthday.getValue().getYear();
int ages = currentYear - birthYear;
age.setValue(String.valueOf(ages));
+ if (ages < 18) {
+ birthday.setInvalid(true);
+ birthday.setErrorMessage("La edad no puede ser menor a 18 años.");
+ Notification.show("La edad ingresada no es válida, debe ser mayor o igual a 18 años.");
+ } else {
+ birthday.setInvalid(false);
+ }
System.out.println(age);
}
}
+ private void calculateSeniority() {
+ LocalDate entryDate = dateOfEntry.getValue();
+ LocalDate exitDate = dateOfExit.getValue() != null ? dateOfExit.getValue() : LocalDate.now();
+
+ if (entryDate != null) {
+ long yearsOfService = ChronoUnit.YEARS.between(entryDate, exitDate);
+ String seniorityValue = yearsOfService + " años ";
+ seniority.setValue(seniorityValue);
+ } else {
+ seniority.setValue("No disponible");
+ }
+ }
+
private void configureUpload() {
upload.setAcceptedFileTypes("image/jpeg", "image/png");
upload.setMaxFileSize(1024 * 1024);
@@ -218,11 +242,15 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
getEntity().setProfileImage(base64Image);
- profileImagePreview.setSrc("data:image/jpeg;base64," + base64Image);
+ profileImagePreview.setSrc("data:image/png;base64," + base64Image);
profileImagePreview.setMaxWidth("150px");
profileImagePreview.setMaxHeight("150px");
} catch (IOException e) {
- Notification.show("Error al subir la imagen.");
+ Notification.show("Error al subir la imagen: " + e.getMessage());
+ e.printStackTrace();
+ } catch (Exception e) {
+ Notification.show("Error en el servidor al procesar la imagen.");
+ e.printStackTrace();
}
});
}
@@ -393,12 +421,12 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
if (employee.getProfileImage() != null && !employee.getProfileImage().isEmpty()) {
profileImagePreview.setSrc("data:image/jpeg;base64," + employee.getProfileImage());
profileImagePreview.setVisible(true);
- profileImagePreview.setMaxWidth("150px");
- profileImagePreview.setMaxHeight("150px");
+ profileImagePreview.setMaxWidth("250px");
+ profileImagePreview.setMaxHeight("250px");
- upload.setVisible(false);
+ upload.setVisible(true);
} else {
- profileImagePreview.setVisible(false);
+ profileImagePreview.setVisible(true);
upload.setVisible(true);
}
}
@@ -478,6 +506,7 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
emergencyCPhone.setReadOnly(false);
emergencyCEmail.setReadOnly(false);
upload.setVisible(false);
+ profileImagePreview.setVisible(true);
age.setReadOnly(false);
gender.setReadOnly(false);
status.setReadOnly(false);
@@ -525,7 +554,6 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
birthCity, residenceAddress, localAddress,
maritalStatus, ci, issuedIn, numberOfChildren,
phoneNumber, personalEmail,
- cod, position, team, leadManager, project,
contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail,
infProf,
titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3,
@@ -533,6 +561,7 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
logros, recognition, achievements,
idioma, language, languageLevel,
infoAdm,
+ cod, position, team, leadManager, project,
infoCont, dateOfEntry, dateOfExit, contractType, seniority, salary,
datBanc, bankName, accountNumber,
datGest, gpss, sss, beneficiaries,
diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java
new file mode 100644
index 0000000..be01789
--- /dev/null
+++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedListView.java
@@ -0,0 +1,232 @@
+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;
+import com.primefactorsolutions.service.TeamService;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.combobox.ComboBox;
+import com.vaadin.flow.component.html.Main;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+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;
+
+@SpringComponent
+@PermitAll
+@Scope("prototype")
+@PageTitle("Registro de Horas Trabajadas")
+@Route(value = "/hours-worked-list", layout = MainLayout.class)
+public class HoursWorkedListView extends Main {
+
+ private final HoursWorkedService hoursWorkedService;
+ private final EmployeeService employeeService;
+ private final TeamService teamService;
+ private final PagingGrid hoursWorkedGrid = new PagingGrid<>();
+ private List employees = Collections.emptyList();
+ private ComboBox employeeFilter;
+ private ComboBox teamFilter;
+ private UUID selectedEmployeeId;
+
+
+ public HoursWorkedListView(final HoursWorkedService hoursWorkedService,
+ final EmployeeService employeeService,
+ final TeamService teamService) {
+ this.hoursWorkedService = hoursWorkedService;
+ this.employeeService = employeeService;
+ this.teamService = teamService;
+ this.employees = employeeService.findAllEmployees();
+
+ initializeView();
+ refreshGridListHoursWorked(null, null);
+ }
+
+ private void refreshGridListHoursWorked(final Employee employee,
+ final Team team) {
+ hoursWorkedGrid.setPagingDataProvider((page, pageSize) -> {
+ int start = (int) (page * hoursWorkedGrid.getPageSize());
+ 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 fetchFilteredHoursWorked(final int start,
+ final int pageSize,
+ final Employee employee,
+ final Team team) {
+ List filteredHoursWorked = hoursWorkedService.findAll();
+
+ if (employee != null && !"TODOS".equals(employee.getFirstName())) {
+ filteredHoursWorked = filteredHoursWorked.stream()
+ .filter(hw -> hw.getEmployee().getId().equals(employee.getId()))
+ .collect(Collectors.toList());
+ }
+
+ if (team != null && !"TODOS".equals(team.getName())) {
+ filteredHoursWorked = filteredHoursWorked.stream()
+ .filter(hw -> hw.getEmployee().getTeam() != null && hw.getEmployee().getTeam().getId().equals(team.getId()))
+ .collect(Collectors.toList());
+ }
+
+ 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() {
+ setupFilters();
+ add(createAddHoursWorked());
+ setupListHoursWorkedGrid();
+ add(hoursWorkedGrid);
+ add(createActionButtons());
+ }
+
+ private void setupFilters() {
+ add(createEmployeeFilter());
+ add(createTeamFilter());
+ }
+
+ private void setupListHoursWorkedGrid() {
+ 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 -> {
+ HoursWorked selectedHoursWorked = event.getValue();
+ if (selectedHoursWorked != null) {
+ selectedEmployeeId = selectedHoursWorked.getEmployee().getId();
+ }
+ });
+ }
+
+ private HorizontalLayout createActionButtons() {
+ Button viewButton = new Button("Ver", event -> {
+ if (selectedEmployeeId != null) {
+ navigateToHoursWorkedView(selectedEmployeeId);
+ } else {
+ Notification.show("Seleccione una solicitud.", 3000, Notification.Position.MIDDLE);
+ }
+ });
+ Button closeButton = new Button("Salir", event -> navigateToListView());
+ return new HorizontalLayout(viewButton, closeButton);
+ }
+
+ private void navigateToListView() {
+ getUI().ifPresent(ui -> ui.navigate(MainView.class));
+ }
+
+ private void navigateToHoursWorkedView(final UUID idEmployee) {
+ getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + idEmployee.toString()));
+ }
+
+ private Button createButton(final String label, final Runnable onClickAction) {
+ Button button = new Button(label);
+ button.addClickListener(event -> onClickAction.run());
+ return button;
+ }
+
+ private Button createAddHoursWorked() {
+ return createButton("Agregar Actividad", this::navigateToHours);
+ }
+
+ private void navigateToHours() {
+ getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class, "new"));
+ }
+
+ private ComboBox createEmployeeFilter() {
+ employeeFilter = new ComboBox<>("Empleado");
+ List employees = new ArrayList<>(employeeService.findAllEmployees());
+ employees.addFirst(createAllEmployeesOption());
+ employeeFilter.setItems(employees);
+ employeeFilter.setItemLabelGenerator(this::getEmployeeFullName);
+ employeeFilter.setValue(employees.getFirst());
+ employeeFilter.addValueChangeListener(event ->
+ refreshGridListHoursWorked(
+ event.getValue(),
+ teamFilter.getValue()
+ )
+ );
+ return employeeFilter;
+ }
+
+ private String getEmployeeFullName(final Employee employee) {
+ return "TODOS".equals(employee.getFirstName())
+ ? "TODOS" : employee.getFirstName() + " " + employee.getLastName();
+ }
+
+ private ComboBox createTeamFilter() {
+ teamFilter = new ComboBox<>("Equipo");
+ List teams = new ArrayList<>(teamService.findAllTeams());
+ teams.addFirst(createAllTeamsOption());
+ teamFilter.setItems(teams);
+ teamFilter.setItemLabelGenerator(team -> getTeamLabel(team));
+ teamFilter.setValue(teams.getFirst());
+ teamFilter.addValueChangeListener(event ->
+ refreshGridListHoursWorked(
+ employeeFilter.getValue(),
+ event.getValue()
+ )
+ );
+ 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();
+ allEmployeesOption.setFirstName("TODOS");
+ return allEmployeesOption;
+ }
+
+ private Team createAllTeamsOption() {
+ Team allTeamsOption = new Team();
+ allTeamsOption.setName("TODOS");
+ return allTeamsOption;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java
deleted file mode 100644
index 88d86e6..0000000
--- a/src/main/java/com/primefactorsolutions/views/HoursWorkedMonthView.java
+++ /dev/null
@@ -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 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(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 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(final 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(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(""));
- }
-}
diff --git a/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java b/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java
index 7c1f644..752bad9 100644
--- a/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java
+++ b/src/main/java/com/primefactorsolutions/views/HoursWorkedView.java
@@ -1,419 +1,248 @@
package com.primefactorsolutions.views;
-import com.primefactorsolutions.model.Actividad;
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;
-import com.vaadin.flow.component.datepicker.DatePicker;
-import com.vaadin.flow.component.grid.Grid;
+import com.primefactorsolutions.service.TeamService;
+import com.vaadin.flow.component.Component;
+import com.vaadin.flow.component.html.H2;
+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.textfield.TextField;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.router.PageTitle;
-import com.vaadin.flow.router.Route;
+import com.vaadin.flow.router.*;
import com.vaadin.flow.spring.annotation.SpringComponent;
import jakarta.annotation.security.PermitAll;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
-import com.vaadin.flow.component.html.Label;
-import org.springframework.web.servlet.HandlerMapping;
-import org.springframework.web.servlet.view.InternalResourceViewResolver;
+import org.vaadin.firitin.components.datepicker.VDatePicker;
+import org.vaadin.firitin.form.BeanValidationForm;
-
-import java.time.DayOfWeek;
import java.time.LocalDate;
-import java.time.temporal.IsoFields;
-import java.time.temporal.WeekFields;
+import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
+import java.util.UUID;
@SpringComponent
@PermitAll
@Scope("prototype")
-@PageTitle("Hours Worked")
-@Route(value = "/hours-worked/me", layout = MainLayout.class)
-public class HoursWorkedView extends VerticalLayout {
- private final List actividades = new ArrayList<>();
- private final List actividadesEspecificas = new ArrayList<>(); // Nueva lista para tareas específicas
- private final Grid grid = new Grid<>(Actividad.class);
- private final Grid gridActividadesEspecificas = new Grid<>(Actividad.class);
+@PageTitle("Horas Trabajadas")
+@Route(value = "/hours-worked-list/:hours-workedId?/:action?", layout = MainLayout.class)
+public class HoursWorkedView extends BeanValidationForm implements HasUrlParameter {
+ private final VDatePicker dateField = new VDatePicker("Fecha");
+ private final ComboBox teamField = new ComboBox<>("Equipo");
+ private ComboBox employeeField;
+ private final ComboBox tareasEspecificasDropdown = new ComboBox<>("Tarea Específica");
+ private final TextField tareaEspecificaInput = new TextField("Otra Tarea Específica");
+ private final TextField horasTareaEspecificaField = new TextField("Horas Tarea Específica");
+ private final TextField activityField = new TextField("Actividad");
+ private final TextField hoursField = new TextField("Horas");
- private final ComboBox employeeComboBox = new ComboBox<>("Employee");
- private final ComboBox equipoDropdown = new ComboBox<>("Equipo");
-
- private final ComboBox tareasEspecificasDropdown = new ComboBox<>("Tareas Específicas");
- private final TextField tareaEspecificaInput = new TextField("Especificar Tarea");
- private TextField horasTareaInput = crearCampoHora("Horas Tareas");
-
- private LocalDate selectedStartOfWeek;
- private int weekNumber;
-
- @Autowired
- private final EmployeeService employeeService;
- @Autowired
- private final HoursWorkedService hoursWorkedService;
-
- private final Label fechasLabel = new Label("Selecciona una semana para ver las fechas.");
+ private final H2 equipoLabel = new H2("Tareas del Cliente/Equipo");
+ private final H2 empresaLabel = new H2("Tareas de la Empresa");
private final Label totalCompletadoLabel = new Label();
- private final Label horasPendientesLabel = new Label();
- private final Label numeroSemanaLabel = new Label("Número de la Semana: ");
+ private final HoursWorkedService hoursWorkedService;
+ private final EmployeeService employeeService;
+ private final TeamService teamService;
+ private HoursWorked hoursWorked;
+ private Employee employee;
- private DatePicker fechaPicker = new DatePicker("Selecciona una fecha");
- @Autowired
- private InternalResourceViewResolver defaultViewResolver;
- @Qualifier("defaultServletHandlerMapping")
- @Autowired
- private HandlerMapping defaultServletHandlerMapping;
+ private Button saveButton;
-
- public HoursWorkedView(final EmployeeService employeeService, final HoursWorkedService hoursWorkedService) {
- this.employeeService = employeeService;
+ public HoursWorkedView(final HoursWorkedService hoursWorkedService,
+ final EmployeeService employeeService,
+ final TeamService teamService) {
+ super(HoursWorked.class);
this.hoursWorkedService = hoursWorkedService;
- configurarVista();
- configurarGrid();
- configurarGridActividadesEspecificas();
- cargarDatos();
- configurarTareasEspecificas();
+ this.employeeService = employeeService;
+ this.teamService = teamService;
+
+ initializeDateField();
+ initializeTeamField();
+ initializeEmployeeField();
+ configureTareasEspecificas();
+
}
- private void configurarTareasEspecificas() {
- tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones", "Colaboraciones",
- "Aprendizajes", "Proyectos PFS", "Otros");
+ @Override
+ public void setParameter(final BeforeEvent beforeEvent, final String action) {
+ final RouteParameters params = beforeEvent.getRouteParameters();
+ final String s = params.get("hours-workedId").orElse(null);
+
+ if ("new".equals(action)) {
+ setEntityWithEnabledSave(new HoursWorked());
+ } else {
+ UUID hoursWorkedId = UUID.fromString(s);
+ var hoursWorked = hoursWorkedService.getHoursWorked(hoursWorkedId);
+ setEntityWithEnabledSave(hoursWorked);
+
+ if ("edit".equals(action) && !s.isEmpty()) {
+ saveButton.setVisible(true);
+ } else if ("view".equals(action) && !s.isEmpty()) {
+ saveButton.setVisible(false);
+ }
+ }
+ }
+
+ @Override
+ protected List getFormComponents() {
+ return List.of(
+ dateField,
+ teamField,
+ employeeField,
+ equipoLabel,
+ activityField,
+ hoursField,
+ empresaLabel,
+ tareasEspecificasDropdown,
+ tareaEspecificaInput,
+ horasTareaEspecificaField,
+ createCloseButton()
+ );
+ }
+
+ private void configureTareasEspecificas() {
+ tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones",
+ "Colaboraciones", "Aprendizajes", "Proyectos PFS", "Otros");
tareasEspecificasDropdown.setPlaceholder("Selecciona una tarea...");
tareasEspecificasDropdown.addValueChangeListener(event -> {
String selected = event.getValue();
- // Activa el campo de texto si la opción seleccionada es "Otros"
- tareaEspecificaInput.setVisible("Otros".equals(selected));
- if (!"Otros".equals(selected)) {
+ boolean isOtros = "Otros".equals(selected);
+ tareaEspecificaInput.setVisible(isOtros);
+ horasTareaEspecificaField.setVisible(true);
+ if (!isOtros) {
tareaEspecificaInput.clear();
+ horasTareaEspecificaField.clear();
}
});
tareaEspecificaInput.setVisible(false);
+ horasTareaEspecificaField.setVisible(false);
}
- private void cargarDatos() {
- if (selectedStartOfWeek != null && weekNumber > 0) {
- actividades.clear();
- actividadesEspecificas.clear();
- List listaDeHorasTrabajadas = obtenerDatos();
- grid.setItems(actividades);
- gridActividadesEspecificas.setItems(actividadesEspecificas);
- calcularTotalHoras(listaDeHorasTrabajadas);
- }
+ protected Button createSaveButton() {
+ saveButton = new Button("Guardar");
+ saveButton.addClickListener(event -> saveHoursWorked());
+ return saveButton;
}
- 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.")
+ protected Button createCloseButton() {
+ Button closeButton = new Button("Cerrar");
+ closeButton.addClickListener(event -> closeForm());
+ return closeButton;
+ }
+
+ private void initializeTeamField() {
+ List teams = new ArrayList<>(teamService.findAllTeams());
+ teamField.setItems(teamService.findAllTeams());
+ teamField.setItemLabelGenerator(Team::getName);
+ teamField.setValue(teams.getFirst());
+ teamField.addValueChangeListener(event -> {
+ if (teams != null) {
+ employeeField.getValue();
+ event.getValue();
+ }
+ }
);
-
- employeeComboBox.addValueChangeListener(event -> {
- Employee selectedEmployee = event.getValue();
- if (selectedEmployee != null) {
- Notification.show("Empleado seleccionado: "
- + selectedEmployee.getFirstName() + " "
- + selectedEmployee.getLastName());
- }
- });
}
- private int getWeekOfYear(final LocalDate date) {
- return date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
+ private ComboBox initializeEmployeeField() {
+ employeeField = new ComboBox<>("Empleado");
+ List employees = new ArrayList<>(employeeService.findAllEmployees());
+ employeeField.setItems(employees);
+ employeeField.setItemLabelGenerator(this::getEmployeeFullName);
+ employeeField.setValue(employees.getFirst());
+ return employeeField;
}
- private void configurarVista() {
- fechaPicker.addValueChangeListener(event -> {
- LocalDate selectedDate = event.getValue();
- if (selectedDate != null) {
- selectedStartOfWeek = getStartOfWeek(selectedDate);
- LocalDate endOfWeek = selectedStartOfWeek.plusDays(6);
- weekNumber = getWeekOfYear(selectedDate);
- fechasLabel.setText("Semana del " + selectedStartOfWeek + " al " + endOfWeek);
- numeroSemanaLabel.setText("Número de la Semana: " + weekNumber);
- cargarDatos();
- }
- });
-
- Button verMesButton = new Button("Ver Mes", event -> {
- getUI().ifPresent(ui -> ui.navigate(HoursWorkedMonthView.class));
- });
-
- equipoDropdown.setItems("ABC", "DEF", "XYZ");
- equipoDropdown.setWidth("250px");
-
- equipoDropdown.addValueChangeListener(event -> {
- String selectedEquipo = event.getValue();
- if (selectedEquipo != null) {
- // Filtra la lista de empleados según el equipo seleccionado
- List filteredEmployees = employeeService.findEmployeesByTeam(selectedEquipo);
- employeeComboBox.setItems(filteredEmployees);
- }
- });
-
- setEmployeeComboBoxProperties();
-
- HorizontalLayout filtersLayout = new HorizontalLayout(equipoDropdown, employeeComboBox);
- filtersLayout.setSpacing(true);
-
- HorizontalLayout actividadFormLayout = configurarFormularioActividades();
- HorizontalLayout tareasEspecificasLayout = configurarTareasEspecificasLayout();
-
-
- 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, numeroSemanaLabel, filtersLayout, actividadFormLayout,
- tareasEspecificasLayout, grid, gridActividadesEspecificas, buttonsLayout, totalesLayout);
+ private String getEmployeeFullName(final Employee employee) {
+ return "TODOS".equals(employee.getFirstName())
+ ? "TODOS" : employee.getFirstName() + " " + employee.getLastName();
}
- 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");
- 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 Día").setKey("totalDia");
+ private void initializeDateField() {
+ LocalDate today = LocalDate.now();
+ YearMonth currentMonth = YearMonth.of(today.getYear(), today.getMonth());
+
+ LocalDate startOfMonth = currentMonth.atDay(1);
+
+ LocalDate maxSelectableDate = today;
+
+ dateField.setMin(startOfMonth);
+ dateField.setMax(maxSelectableDate);
+ dateField.setValue(today);
+
+ dateField.setLabel("Fecha");
}
- private void configurarGridActividadesEspecificas() {
- gridActividadesEspecificas.removeAllColumns();
- gridActividadesEspecificas.setItems(actividadesEspecificas);
- gridActividadesEspecificas.addColumn(Actividad::getTarea).setHeader("Actividad");
- gridActividadesEspecificas.addColumn(Actividad::getLunes).setHeader("Lunes");
- gridActividadesEspecificas.addColumn(Actividad::getMartes).setHeader("Martes");
- gridActividadesEspecificas.addColumn(Actividad::getMiercoles).setHeader("Miércoles");
- gridActividadesEspecificas.addColumn(Actividad::getJueves).setHeader("Jueves");
- gridActividadesEspecificas.addColumn(Actividad::getViernes).setHeader("Viernes");
- gridActividadesEspecificas.addColumn(Actividad::getSabado).setHeader("Sábado");
- gridActividadesEspecificas.addColumn(Actividad::getDomingo).setHeader("Domingo");
- gridActividadesEspecificas.addColumn(this::calcularTotalPorDia).setHeader("Total Día Específico")
- .setKey("totalDiaEspecifico");
- }
-
- private HorizontalLayout configurarFormularioActividades() {
- TextField actividadNombre = new TextField("Actividad");
- actividadNombre.setWidth("200px");
-
- TextField horasInput = crearCampoHora("Horas");
-
- Button agregarActividadButton = new Button("Agregar Actividad", e -> {
- try {
- LocalDate selectedDate = fechaPicker.getValue();
- if (selectedDate == null) {
- Notification.show("Por favor, selecciona una fecha.");
- return;
- }
- DayOfWeek selectedDay = selectedDate.getDayOfWeek();
-
- Actividad.Builder actividadBuilder = new Actividad.Builder()
- .nombre(actividadNombre.getValue());
-
- double horas = parseHoras(horasInput.getValue());
- switch (selectedDay) {
- case MONDAY -> actividadBuilder.lunes(horas);
- case TUESDAY -> actividadBuilder.martes(horas);
- case WEDNESDAY -> actividadBuilder.miercoles(horas);
- case THURSDAY -> actividadBuilder.jueves(horas);
- case FRIDAY -> actividadBuilder.viernes(horas);
- case SATURDAY -> actividadBuilder.sabado(horas);
- case SUNDAY -> actividadBuilder.domingo(horas);
- default -> throw new IllegalArgumentException("Día seleccionado no válido: " + selectedDay);
- }
-
- String tareaSeleccionada = tareasEspecificasDropdown.getValue();
- double horasTarea = parseHoras(horasTareaInput.getValue());
-
- if (tareaSeleccionada != null && !tareaSeleccionada.isEmpty()) {
- actividadBuilder.tarea(tareaSeleccionada).lunes(horasTarea);
- Actividad nuevaActividadEspecifica = actividadBuilder.build();
- actividadesEspecificas.add(nuevaActividadEspecifica);
- gridActividadesEspecificas.setItems(actividadesEspecificas);
- } else {
- Actividad nuevaActividad = actividadBuilder.build();
- actividades.add(nuevaActividad);
- grid.setItems(actividades);
- }
- actualizarTotales();
- Notification.show("Actividad agregada correctamente");
- actividadNombre.clear();
- horasInput.clear();
- tareasEspecificasDropdown.clear();
- horasTareaInput.clear();
- } catch (NumberFormatException ex) {
- Notification.show("Error: Por favor ingresa números válidos para las horas.");
- }
- });
-
- return new HorizontalLayout(actividadNombre, horasInput, agregarActividadButton);
- }
-
- private HorizontalLayout configurarTareasEspecificasLayout() {
-
- Button agregarTareaButton = new Button("Agregar Tarea PFS", e -> {
- try {
- String tareaSeleccionada = tareasEspecificasDropdown.getValue();
- String tareaNombre = "Otros"
- .equals(tareaSeleccionada) ? tareaEspecificaInput
- .getValue() : tareaSeleccionada;
-
- if (tareaNombre == null || tareaNombre.isEmpty()) {
- Notification.show("Por favor, especifica la tarea.");
- return;
- }
-
- double horasTarea = parseHoras(horasTareaInput.getValue());
- if (horasTarea <= 0) {
- Notification.show("Por favor, ingresa un número válido para las horas.");
- return;
- }
-
- if (tareaSeleccionada != null && !tareaSeleccionada.isEmpty() && horasTarea > 0) {
- LocalDate selectedDate = fechaPicker.getValue();
- if (selectedDate == null) {
- Notification.show("Selecciona una fecha para asignar la tarea.");
- return;
- }
-
- DayOfWeek selectedDay = selectedDate.getDayOfWeek();
- Actividad.Builder actividadBuilder = new Actividad.Builder().tarea(tareaNombre);
-
- switch (selectedDay) {
- case MONDAY -> actividadBuilder.lunes(horasTarea);
- case TUESDAY -> actividadBuilder.martes(horasTarea);
- case WEDNESDAY -> actividadBuilder.miercoles(horasTarea);
- case THURSDAY -> actividadBuilder.jueves(horasTarea);
- case FRIDAY -> actividadBuilder.viernes(horasTarea);
- case SATURDAY -> actividadBuilder.sabado(horasTarea);
- case SUNDAY -> actividadBuilder.domingo(horasTarea);
- default -> throw new IllegalArgumentException("Día seleccionado no válido: " + selectedDay);
- }
-
- Actividad nuevaActividadEspecifica = actividadBuilder.build();
- actividadesEspecificas.add(nuevaActividadEspecifica);
-
- gridActividadesEspecificas.setItems(actividadesEspecificas);
- actualizarTotales();
-
- tareasEspecificasDropdown.clear();
- tareaEspecificaInput.clear();
- horasTareaInput.clear();
-
- Notification.show("Tarea específica agregada correctamente");
- } else {
- Notification.show("Selecciona una tarea y asegúrate de ingresar horas válidas.");
- }
- } catch (NumberFormatException ex) {
- Notification.show("Error: Por favor ingresa un número válido para las horas.");
- }
- });
-
- HorizontalLayout layout = new HorizontalLayout(tareasEspecificasDropdown,
- tareaEspecificaInput, horasTareaInput, agregarTareaButton);
- layout.setSpacing(true);
- return layout;
- }
-
- private TextField crearCampoHora(final String placeholder) {
- TextField field = new TextField(placeholder);
- field.setWidth("80px");
- field.setPlaceholder("0.0");
- return field;
- }
-
- private double parseHoras(final String value) {
- if (value == null || value.trim().isEmpty()) {
- return 0.0;
+ private void saveHoursWorked() {
+ if (isFormValid()) {
+ HoursWorked hoursWorked = getEntity();
+ setFieldValues(hoursWorked);
+ hoursWorkedService.save(hoursWorked);
+ Notification.show("Horas trabajadas guardadas correctamente.");
+ closeForm();
}
- return Double.parseDouble(value);
}
- private LocalDate getStartOfWeek(final LocalDate date) {
- WeekFields weekFields = WeekFields.of(Locale.getDefault());
- return date.with(weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
- }
-
- private double calcularTotalPorDia(final Actividad actividad) {
- return actividad.getLunes() + actividad.getMartes() + actividad.getMiercoles()
- + actividad.getJueves() + actividad.getViernes() + actividad.getSabado() + actividad.getDomingo();
- }
-
- private void actualizarTotales() {
- double totalActividadesGenerales = actividades.stream()
- .mapToDouble(this::calcularTotalPorDia)
- .sum();
- double totalActividadesEspecificas = actividadesEspecificas.stream()
- .mapToDouble(this::calcularTotalPorDia)
- .sum();
- double totalFinal = totalActividadesGenerales + totalActividadesEspecificas;
- double horasPendientes = 40 - totalFinal;
-
- totalCompletadoLabel.setText("Total Hrs/Semana Completadas: " + totalFinal);
- horasPendientesLabel.setText("Horas Pendientes: " + horasPendientes);
- }
-
- private void guardarActividades() {
- Employee selectedEmployee = employeeComboBox.getValue();
- String selectedEquipo = equipoDropdown.getValue();
-
- if (selectedEmployee == null || selectedEquipo == null) {
- Notification.show("Por favor selecciona un equipo y un empleado.");
- return;
- }
-
- double totalHorasSemana = actividades.stream()
- .mapToDouble(this::calcularTotalPorDia)
- .sum();
-
- HoursWorked hoursWorked = new HoursWorked();
- hoursWorked.setEmployee(selectedEmployee);
- hoursWorked.setWeekNumber(weekNumber);
- hoursWorked.setTotalHours(totalHorasSemana);
-
+ private void setFieldValues(final HoursWorked hoursWorked) {
+ hoursWorked.setDate(dateField.getValue());
+ hoursWorked.setTeam(teamField.getValue());
+ hoursWorked.setEmployee(employeeField.getValue());
+ hoursWorked.setActividad(activityField.getValue());
try {
- hoursWorkedService.saveHoursWorked(hoursWorked); // Usa saveHoursWorked directamente
- Notification.show("Actividades guardadas correctamente.");
- System.out.println(hoursWorked);
- } catch (Exception e) {
- Notification.show("Error al guardar actividades: " + e.getMessage());
+ double hours = Double.parseDouble(hoursField.getValue());
+ hoursWorked.setHours(hours);
+ } catch (NumberFormatException e) {
+ Notification.show("Por favor, ingrese un número válido para las horas.");
+ }
+ if ("Otros".equals(tareasEspecificasDropdown.getValue())) {
+ // Maneja horas y actividad específica adicional
+ hoursWorked.setTareasEspecificas(tareaEspecificaInput.getValue());
+ try {
+ double horasEspecifica = Double.parseDouble(horasTareaEspecificaField.getValue());
+ hoursWorked.setHorasTareasEspecificas(horasEspecifica);
+ } catch (NumberFormatException e) {
+ Notification.show("Por favor, ingrese un número válido para las horas de la tarea específica.");
+ }
}
}
- private double calcularTotalHoras(final List listaDeHorasTrabajadas) {
- return listaDeHorasTrabajadas.stream()
- .mapToDouble(HoursWorked::getTotalHours)
- .sum();
+ private void closeForm() {
+ getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + hoursWorked.getId().toString()));
}
- private List obtenerDatos() {
- return new ArrayList<>();
+ private boolean isFormValid() {
+ return dateField.getValue() != null
+ &&
+ teamField.getValue() != null
+ &&
+ employeeField.getValue() != null
+ &&
+ !activityField.isEmpty();
+
}
- private void closeView() {
- getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class));
+ private void configureViewOrEditAction(final String action) {
+ if ("edit".equals(action) && hoursWorked != null) {
+ setFieldsReadOnly(false);
+ } else if ("view".equals(action) && hoursWorked != null) {
+ setFieldsReadOnly(true);
+ saveButton.setEnabled(false);
+ }
}
+
+ private void setFieldsReadOnly(final boolean readOnly) {
+ dateField.setReadOnly(readOnly);
+ teamField.setReadOnly(readOnly);
+ employeeField.setReadOnly(readOnly);
+ activityField.setReadOnly(readOnly);
+ }
+
+
+
+
}
\ No newline at end of file
diff --git a/src/main/java/com/primefactorsolutions/views/MainLayout.java b/src/main/java/com/primefactorsolutions/views/MainLayout.java
index a6dfaa0..8b23940 100644
--- a/src/main/java/com/primefactorsolutions/views/MainLayout.java
+++ b/src/main/java/com/primefactorsolutions/views/MainLayout.java
@@ -153,7 +153,7 @@ public class MainLayout extends AppLayout {
LineAwesomeIcon.LIST_ALT.create()));
SideNavItem timesheet = new SideNavItem("My Timesheet", TimesheetView.class,
LineAwesomeIcon.HOURGLASS_START_SOLID.create());
- timesheet.addItem(new SideNavItem("Horas Trabajadas", HoursWorkedView.class,
+ timesheet.addItem(new SideNavItem("Registro de Horas Trabajadas", HoursWorkedListView.class,
LineAwesomeIcon.ID_CARD_SOLID.create()));
timesheet.addItem(new SideNavItem("Reporte Horas Trabajadas", ReporteView.class,
LineAwesomeIcon.ID_CARD_SOLID.create()));
diff --git a/src/main/java/com/primefactorsolutions/views/ReporteView.java b/src/main/java/com/primefactorsolutions/views/ReporteView.java
index 1594cc5..3e10457 100644
--- a/src/main/java/com/primefactorsolutions/views/ReporteView.java
+++ b/src/main/java/com/primefactorsolutions/views/ReporteView.java
@@ -50,7 +50,6 @@ public class ReporteView extends VerticalLayout {
private final Span semanaInfoSpan = new Span();
-
// Obtener el año actual
private int currentYear = LocalDate.now().getYear();
@@ -76,22 +75,19 @@ public class ReporteView extends VerticalLayout {
// Listener para actualizar `semanaInfoSpan` con la selección del usuario en `semanaComboBox`
semanaComboBox.addValueChangeListener(event -> {
String selectedWeek = event.getValue();
- semanaInfoSpan.setText(selectedWeek != null
- ? selectedWeek : "Selecciona una semana");
+ semanaInfoSpan.setText(selectedWeek != null ? selectedWeek : "Selecciona una semana");
});
Button reportButton = new Button("Generar Reporte de Horas Trabajadas",
event -> generateHoursWorkedReport());
- HorizontalLayout filtersLayout = new HorizontalLayout(equipoComboBox,
- semanaComboBox, reportButton);
+ HorizontalLayout filtersLayout = new HorizontalLayout(equipoComboBox, semanaComboBox, reportButton);
add(filtersLayout);
// Añadir `headerLayout` al diseño principal para el encabezado dinámico
add(headerLayout);
updateHeaderLayout(null, null);
- grid.addColumn(map -> map.get("ID")).setHeader("ID")
- .getElement().getStyle().set("font-weight", "bold");
+ grid.addColumn(map -> map.get("ID")).setHeader("ID").getElement().getStyle().set("font-weight", "bold");
grid.addColumn(map -> map.get("Employee ID")).setHeader("Employee ID");
grid.addColumn(map -> map.get("Empleado")).setHeader("Empleado");
grid.addColumn(map -> map.get("Horas Trabajadas")).setHeader("Horas Trabajadas");
@@ -105,8 +101,7 @@ public class ReporteView extends VerticalLayout {
int year = LocalDate.now().getYear();
LocalDate startOfYear = LocalDate.of(year, 1, 5); // Suponemos que la semana comienza el 5 de enero.
- List semanas = startOfYear.datesUntil(LocalDate
- .of(year + 1, 1, 1),
+ List semanas = startOfYear.datesUntil(LocalDate.of(year + 1, 1, 1),
java.time.Period.ofWeeks(1))
.map(date -> {
int weekNumber = date.get(WeekFields.of(DayOfWeek.MONDAY, 1)
@@ -133,27 +128,23 @@ public class ReporteView extends VerticalLayout {
String selectedWeek = semanaComboBox.getValue();
if (selectedEquipo == null || selectedWeek == null) {
Notification.show("Por favor, selecciona un equipo y una semana para generar el reporte.",
- 3000,
- Notification.Position.MIDDLE);
+ 3000, Notification.Position.MIDDLE);
return;
}
- int weekNumber = Integer.parseInt(selectedWeek.split(" ")[1]
- .replace(":", ""));
- LocalDate selectedDate = LocalDate.now()
- .with(WeekFields.of(DayOfWeek.FRIDAY, 1)
- .weekOfWeekBasedYear(), weekNumber);
+ int weekNumber = Integer.parseInt(selectedWeek.split(" ")[1].replace(":", ""));
+ LocalDate selectedDate = LocalDate.now().with(WeekFields.of(DayOfWeek.FRIDAY, 1)
+ .weekOfWeekBasedYear(), weekNumber);
updateHeaderLayout(selectedEquipo, selectedDate);
List hoursWorkedList = hoursWorkedService.findAll().stream()
- .filter(hw -> hw.getEmployee().getTeam().getId()
- .equals(selectedEquipo.getId()) && hw.getWeekNumber() == weekNumber)
+ .filter(hw -> hw.getEmployee().getTeam().getId().equals(selectedEquipo
+ .getId()) && hw.getWeekNumber() == weekNumber)
.collect(Collectors.toList());
if (hoursWorkedList.isEmpty()) {
Notification.show("No hay horas trabajadas disponibles para generar el reporte.",
- 3000,
- Notification.Position.MIDDLE);
+ 3000, Notification.Position.MIDDLE);
return;
}
@@ -188,8 +179,8 @@ public class ReporteView extends VerticalLayout {
String formattedEndDate = endOfWeek.getDayOfMonth() + " de "
+ endOfWeek.getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault());
- headerLayout.add(new Span("Informe " + String.format("%03d", weekNumber)
- + "/" + currentYear) {{
+ headerLayout.add(new Span("Informe "
+ + String.format("%03d", weekNumber) + "/" + currentYear) {{
getStyle().set("font-size", "24px");
getStyle().set("font-weight", "bold");
}});
@@ -213,14 +204,13 @@ public class ReporteView extends VerticalLayout {
}
}
- private void generateExcelDownloadLink(final List