Compare commits

...

25 Commits

Author SHA1 Message Date
Melina Gutierrez
6fbf6e8fa7 Formulario de registro de horas trabajadas mas el formulario 2024-11-15 10:23:40 -04:00
Melina Gutierrez
97d4bdf508 Formulario de registro de horas trabajadas mas el formulario 2024-11-15 09:31:56 -04:00
Melina Gutierrez
b5427c309f Merge branch 'hoursworked' of https://git.primefactorsolutions.com/PFS/pfs-intra into hoursworked 2024-11-15 07:32:25 -04:00
Melina Gutierrez
30ed3f88ed Formulario de registro de horas trabajadas corregir formato 2024-11-15 07:30:48 -04:00
Melina Gutierrez
d49eee8988 Formulario de registro de horas trabajadas 2024-11-15 07:30:48 -04:00
Melina Gutierrez
50dc006f7e Problema de routes 2024-11-15 07:30:48 -04:00
Melina Gutierrez
e30c7c36f9 Problema de routes 2024-11-15 07:30:48 -04:00
Melina Gutierrez
923dc0b826 #45-Registro Semanal de Horas Trabajadas guardar solo una actividad 2024-11-15 07:30:48 -04:00
Melina Gutierrez
1c4e5323fe #45-Registro Semanal de Horas Trabajadas guardar solo una actividad 2024-11-15 07:30:48 -04:00
Melina Gutierrez
2133f81d26 #45-Registro Semanal de Horas Trabajadas corregir duplicados y actividades 2024-11-15 07:29:49 -04:00
Melina Gutierrez
823dc16205 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-15 07:29:49 -04:00
Melina Gutierrez
64224a2db1 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-15 07:29:49 -04:00
Melina Gutierrez
70eee311c5 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-15 07:29:49 -04:00
Melina Gutierrez
48e06fef1f Formulario de registro de horas trabajadas corregir formato 2024-11-15 07:25:19 -04:00
Melina Gutierrez
9d43cbbd29 Formulario de registro de horas trabajadas 2024-11-15 07:03:31 -04:00
Melina Gutierrez
49ad9dbcca Problema de routes 2024-11-14 20:53:17 -04:00
Melina Gutierrez
c67cdf868e Problema de routes 2024-11-14 20:38:48 -04:00
Melina Gutierrez
aa1f041a4f #45-Registro Semanal de Horas Trabajadas guardar solo una actividad 2024-11-14 13:24:38 -04:00
Melina Gutierrez
3f17eb780b #45-Registro Semanal de Horas Trabajadas guardar solo una actividad
Some checks failed
PR Builder / Build-PR (pull_request) Failing after 20s
2024-11-13 13:00:39 -04:00
Melina Gutierrez
3c626e3c85 Merge remote-tracking branch 'origin/hoursworked' into hoursworked
Some checks failed
PR Builder / Build-PR (pull_request) Failing after 19s
# Conflicts:
#	src/main/java/com/primefactorsolutions/views/HoursWorkedView.java
2024-11-12 20:57:30 -04:00
Melina Gutierrez
e45d0d828f #45-Registro Semanal de Horas Trabajadas corregir duplicados y actividades 2024-11-12 20:55:52 -04:00
Melina Gutierrez
b94ec365c7 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-12 20:29:21 -04:00
Melina Gutierrez
e2f128c301 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-12 20:20:35 -04:00
Melina Gutierrez
ebb5454b29 #45-Registro Semanal de Horas Trabajadas corregir duplicados 2024-11-12 07:00:43 -04:00
Melina Gutierrez
dee4bcaf3b #45-Registro Semanal de Horas Trabajadas corregir duplicados
Some checks failed
PR Builder / Build-PR (pull_request) Failing after 23s
2024-11-12 07:00:06 -04:00
23 changed files with 1267 additions and 946 deletions

View File

@ -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 }}."

View File

@ -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 }}."

View File

@ -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();
}
}

Binary file not shown.

View File

@ -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

View File

@ -4,7 +4,7 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@f0rce/ace-widget": "1.0.2", "@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-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.5.1", "@vaadin/bundles": "24.5.1",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
@ -19,29 +19,30 @@
"@vaadin/vaadin-usage-statistics": "2.1.3", "@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4", "lit": "3.2.1",
"print-js": "1.6.0", "print-js": "1.6.0",
"proj4": "2.12.1", "proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1" "react-router-dom": "6.26.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7", "@babel/preset-react": "7.25.7",
"@rollup/plugin-replace": "5.0.7", "@preact/signals-react-transform": "0.4.0",
"@rollup/pluginutils": "5.1.0", "@rollup/plugin-replace": "6.0.1",
"@types/react": "18.3.3", "@rollup/pluginutils": "5.1.2",
"@types/react-dom": "18.3.0", "@types/react": "18.3.11",
"@vitejs/plugin-react": "4.3.1", "@types/react-dom": "18.3.1",
"async": "3.2.5", "@vitejs/plugin-react": "4.3.3",
"glob": "10.4.1", "async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5", "typescript": "5.6.3",
"vite": "5.3.3", "vite": "5.4.9",
"vite-plugin-checker": "0.6.4", "vite-plugin-checker": "0.8.0",
"workbox-build": "7.1.1", "workbox-build": "7.1.1",
"workbox-core": "7.1.0", "workbox-core": "7.1.0",
"workbox-precaching": "7.1.0" "workbox-precaching": "7.1.0"
@ -49,7 +50,7 @@
"vaadin": { "vaadin": {
"dependencies": { "dependencies": {
"@f0rce/ace-widget": "1.0.2", "@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-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.5.1", "@vaadin/bundles": "24.5.1",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
@ -64,34 +65,35 @@
"@vaadin/vaadin-usage-statistics": "2.1.3", "@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4", "lit": "3.2.1",
"print-js": "1.6.0", "print-js": "1.6.0",
"proj4": "2.12.1", "proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1" "react-router-dom": "6.26.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7", "@babel/preset-react": "7.25.7",
"@rollup/plugin-replace": "5.0.7", "@preact/signals-react-transform": "0.4.0",
"@rollup/pluginutils": "5.1.0", "@rollup/plugin-replace": "6.0.1",
"@types/react": "18.3.3", "@rollup/pluginutils": "5.1.2",
"@types/react-dom": "18.3.0", "@types/react": "18.3.11",
"@vitejs/plugin-react": "4.3.1", "@types/react-dom": "18.3.1",
"async": "3.2.5", "@vitejs/plugin-react": "4.3.3",
"glob": "10.4.1", "async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5", "typescript": "5.6.3",
"vite": "5.3.3", "vite": "5.4.9",
"vite-plugin-checker": "0.6.4", "vite-plugin-checker": "0.8.0",
"workbox-build": "7.1.1", "workbox-build": "7.1.1",
"workbox-core": "7.1.0", "workbox-core": "7.1.0",
"workbox-precaching": "7.1.0" "workbox-precaching": "7.1.0"
}, },
"hash": "1a0f17d48b329307b5862bc57499307d1b89f7d89260121c2b7189f76957c436" "hash": "2dc40a4f634ae025081ca2239cba00b14a35fe94ab78ac0a4dd3023d882081d5"
}, },
"overrides": { "overrides": {
"@vaadin/bundles": "$@vaadin/bundles", "@vaadin/bundles": "$@vaadin/bundles",

539
pfs-intra.eml Normal file
View File

@ -0,0 +1,539 @@
<?xml version="1.0" encoding="UTF-8"?>
<component LANGUAGE_LEVEL="JDK_21" inheritJdk="true">
<output-test url="file://$MODULE_DIR$/target/test-classes"/>
<contentEntry url="file://$MODULE_DIR$">
<testFolder url="file://$MODULE_DIR$/src/test/java"/>
<testFolder url="file://$MODULE_DIR$/src/test/resources"/>
<excludeFolder url="file://$MODULE_DIR$/target"/>
</contentEntry>
<lib name="Maven: io.projectreactor.netty.incubator:reactor-netty-incubator-quic:0.1.20" scope="RUNTIME"/>
<lib name="Maven: io.netty.incubator:netty-incubator-codec-native-quic:linux-x86_64:0.0.63.Final" scope="RUNTIME"/>
<lib name="Maven: io.netty.incubator:netty-incubator-codec-classes-quic:0.0.63.Final" scope="RUNTIME"/>
<lib name="Maven: com.h2database:h2:2.2.224" scope="RUNTIME"/>
<lib name="Maven: org.glassfish.jaxb:jaxb-runtime:4.0.5" scope="RUNTIME"/>
<lib name="Maven: org.glassfish.jaxb:jaxb-core:4.0.5" scope="RUNTIME"/>
<lib name="Maven: org.glassfish.jaxb:txw2:4.0.5" scope="RUNTIME"/>
<lib name="Maven: com.sun.istack:istack-commons-runtime:4.1.2" scope="RUNTIME"/>
<lib name="Maven: jakarta.inject:jakarta.inject-api:2.0.1" scope="RUNTIME"/>
<lib name="Maven: org.eclipse.angus:angus-activation:2.0.2" scope="RUNTIME"/>
<lib name="Maven: org.springframework.boot:spring-boot-starter-test:3.2.7" scope="TEST"/>
<lib name="Maven: org.springframework.boot:spring-boot-test:3.2.7" scope="TEST"/>
<lib name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:3.2.7" scope="TEST"/>
<lib name="Maven: com.jayway.jsonpath:json-path:2.9.0" scope="TEST"/>
<lib name="Maven: net.minidev:json-smart:2.5.1" scope="TEST"/>
<lib name="Maven: net.minidev:accessors-smart:2.5.1" scope="TEST"/>
<lib name="Maven: org.awaitility:awaitility:4.2.1" scope="TEST"/>
<lib name="Maven: org.hamcrest:hamcrest:2.2" scope="TEST"/>
<lib name="Maven: org.junit.jupiter:junit-jupiter:5.10.2" scope="TEST"/>
<lib name="Maven: org.junit.jupiter:junit-jupiter-api:5.10.2" scope="TEST"/>
<lib name="Maven: org.opentest4j:opentest4j:1.3.0" scope="TEST"/>
<lib name="Maven: org.junit.platform:junit-platform-commons:1.10.2" scope="TEST"/>
<lib name="Maven: org.apiguardian:apiguardian-api:1.1.2" scope="TEST"/>
<lib name="Maven: org.junit.jupiter:junit-jupiter-params:5.10.2" scope="TEST"/>
<lib name="Maven: org.junit.jupiter:junit-jupiter-engine:5.10.2" scope="TEST"/>
<lib name="Maven: org.mockito:mockito-junit-jupiter:5.7.0" scope="TEST"/>
<lib name="Maven: org.skyscreamer:jsonassert:1.5.1" scope="TEST"/>
<lib name="Maven: org.springframework:spring-test:6.1.10" scope="TEST"/>
<lib name="Maven: org.xmlunit:xmlunit-core:2.9.1" scope="TEST"/>
<lib name="Maven: org.objenesis:objenesis:3.3" scope="RUNTIME"/>
<lib name="Maven: com.github.mvysny.kaributesting:karibu-testing-v10-spring:2.1.8" scope="TEST"/>
<lib name="Maven: org.apache.lucene:lucene-memory:9.9.2" scope="RUNTIME"/>
<lib name="Maven: com.vaadin:vaadin-testbench-junit5:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-testbench-core-junit5:9.3.5" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-remote-driver:4.25.0" scope="TEST"/>
<lib name="Maven: com.google.auto.service:auto-service-annotations:1.1.1" scope="TEST"/>
<lib name="Maven: io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-api:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-context:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-exporter-logging:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-common:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-api-events:1.31.0-alpha" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-trace:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-metrics:1.31.0" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-extension-incubator:1.31.0-alpha" scope="TEST"/>
<lib name="Maven: io.opentelemetry:opentelemetry-sdk-logs:1.31.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-api:4.25.0" scope="TEST"/>
<lib name="Maven: org.jspecify:jspecify:1.0.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-http:4.25.0" scope="TEST"/>
<lib name="Maven: dev.failsafe:failsafe:3.3.2" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-json:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-manager:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-os:4.25.0" scope="TEST"/>
<lib name="Maven: org.apache.commons:commons-exec:1.4.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-java:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-chromium-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-devtools-v127:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-devtools-v128:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-devtools-v129:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-devtools-v85:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-edge-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-ie-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-safari-driver:4.25.0" scope="TEST"/>
<lib name="Maven: org.seleniumhq.selenium:selenium-support:4.25.0" scope="TEST"/>
<lib name="Maven: org.junit.platform:junit-platform-engine:1.10.2" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-testbench-unit-junit5:9.3.5" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-testbench-unit-shared:9.3.5" scope="TEST"/>
<lib name="Maven: org.jetbrains.kotlin:kotlin-reflect:1.9.24" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-testbench-shared:9.3.5" scope="TEST"/>
<lib name="Maven: com.vaadin:flow-html-components-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-accordion-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-app-layout-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-avatar-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-board-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-button-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-charts-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-checkbox-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-combo-box-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-confirm-dialog-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-context-menu-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-cookie-consent-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-crud-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-custom-field-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-date-picker-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-date-time-picker-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-details-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-dialog-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-form-layout-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-grid-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-grid-pro-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-icons-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-virtual-list-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-list-box-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-login-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-menu-bar-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-messages-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-notification-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-ordered-layout-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-popover-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-progress-bar-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-radio-button-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-rich-text-editor-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-select-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-side-nav-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-split-layout-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-tabs-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-text-field-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-time-picker-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: com.vaadin:vaadin-upload-testbench:24.5.1" scope="TEST"/>
<lib name="Maven: org.assertj:assertj-core:3.25.3" scope="TEST"/>
<levels>
<level name="Maven: com.vaadin:vaadin-core:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-core-internal:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-server:24.5.1" value="project"/>
<level name="Maven: com.vaadin.servletdetector:throw-if-servlet3:1.0.2" value="project"/>
<level name="Maven: org.apache.commons:commons-fileupload2-jakarta:2.0.0-M1" value="project"/>
<level name="Maven: org.apache.commons:commons-fileupload2-core:2.0.0-M1" value="project"/>
<level name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.4" value="project"/>
<level name="Maven: org.jsoup:jsoup:1.18.1" value="project"/>
<level name="Maven: com.helger:ph-css:7.0.2" value="project"/>
<level name="Maven: com.helger.commons:ph-commons:11.1.5" value="project"/>
<level name="Maven: org.ow2.asm:asm:9.7" value="project"/>
<level name="Maven: com.vaadin.external:gentyref:1.2.0.vaadin1" value="project"/>
<level name="Maven: com.vaadin:flow-lit-template:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-react:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-push:24.5.1" value="project"/>
<level name="Maven: com.vaadin.external.atmosphere:atmosphere-runtime:3.0.5.slf4jvaadin1" value="project"/>
<level name="Maven: com.vaadin:flow-client:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-html-components:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-data:24.5.1" value="project"/>
<level name="Maven: com.vaadin:flow-dnd:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-lumo-theme:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-material-theme:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-accordion-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-avatar-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-flow-components-base:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-button-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-checkbox-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-combo-box-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-confirm-dialog-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-custom-field-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-date-picker-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-date-time-picker-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-details-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-time-picker-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-select-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-side-nav-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-dialog-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-form-layout-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-field-highlighter-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-grid-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-icons-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-virtual-list-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-list-box-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-login-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-messages-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-ordered-layout-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-progress-bar-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-popover-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-radio-button-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-renderer-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-split-layout-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-tabs-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-text-field-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-upload-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-notification-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-app-layout-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-context-menu-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-menu-bar-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:collaboration-engine:6.3.0" value="project"/>
<level name="Maven: com.vaadin:vaadin-dev:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-dev-server:24.5.1" value="project"/>
<level name="Maven: com.vaadin:open:8.5.0.3" value="project"/>
<level name="Maven: com.github.javaparser:javaparser-core:3.26.2" value="project"/>
<level name="Maven: io.methvin:directory-watcher:0.18.0" value="project"/>
<level name="Maven: com.vaadin:vaadin-dev-bundle:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-dev:24.5.1" value="project"/>
<level name="Maven: com.vaadin:copilot:24.5.1" value="project"/>
<level name="Maven: io.projectreactor.netty:reactor-netty:1.1.20" value="project"/>
<level name="Maven: io.projectreactor.netty:reactor-netty-core:1.1.20" value="project"/>
<level name="Maven: io.netty:netty-handler:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-common:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-resolver:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-buffer:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-transport:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-transport-native-unix-common:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-codec:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-handler-proxy:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-codec-socks:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-resolver-dns:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-codec-dns:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-resolver-dns-native-macos:osx-x86_64:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-resolver-dns-classes-macos:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-transport-native-epoll:linux-x86_64:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-transport-classes-epoll:4.1.111.Final" value="project"/>
<level name="Maven: io.projectreactor.netty:reactor-netty-http:1.1.20" value="project"/>
<level name="Maven: io.netty:netty-codec-http:4.1.111.Final" value="project"/>
<level name="Maven: io.netty:netty-codec-http2:4.1.111.Final" value="project"/>
<level name="Maven: io.projectreactor.netty.incubator:reactor-netty-incubator-quic:0.1.20" value="project"/>
<level name="Maven: io.netty.incubator:netty-incubator-codec-native-quic:linux-x86_64:0.0.63.Final" value="project"/>
<level name="Maven: io.netty.incubator:netty-incubator-codec-classes-quic:0.0.63.Final" value="project"/>
<level name="Maven: org.apache.commons:commons-configuration2:2.11.0" value="project"/>
<level name="Maven: org.apache.commons:commons-text:1.12.0" value="project"/>
<level name="Maven: com.github.javaparser:javaparser-symbol-solver-core:3.26.2" value="project"/>
<level name="Maven: com.vaadin:ui-tests:1.0.0" value="project"/>
<level name="Maven: com.vaadin:vaadin-spring-boot-starter:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-spring:24.5.1" value="project"/>
<level name="Maven: org.springframework:spring-webmvc:6.1.10" value="project"/>
<level name="Maven: org.springframework:spring-websocket:6.1.10" value="project"/>
<level name="Maven: org.reflections:reflections:0.10.2" value="project"/>
<level name="Maven: org.javassist:javassist:3.30.2-GA" value="project"/>
<level name="Maven: com.vaadin:hilla:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-endpoint:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-engine-core:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-core:24.5.1" value="project"/>
<level name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.4" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-plugin-backbone:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-plugin-nonnull:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-plugin-subtypes:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-plugin-model:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-plugin-transfertypes:24.5.1" value="project"/>
<level name="Maven: io.projectreactor:reactor-core:3.6.7" value="project"/>
<level name="Maven: org.reactivestreams:reactive-streams:1.0.4" value="project"/>
<level name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.15.4" value="project"/>
<level name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.4" value="project"/>
<level name="Maven: com.vaadin:hilla-parser-jvm-utils:24.5.1" value="project"/>
<level name="Maven: io.swagger.core.v3:swagger-core:2.2.22" value="project"/>
<level name="Maven: io.swagger.core.v3:swagger-annotations:2.2.22" value="project"/>
<level name="Maven: io.swagger.core.v3:swagger-models:2.2.22" value="project"/>
<level name="Maven: com.vaadin:hilla-runtime-plugin-transfertypes:24.5.1" value="project"/>
<level name="Maven: com.vaadin:hilla-engine-runtime:24.5.1" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-web:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-json:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-tomcat:3.2.7" value="project"/>
<level name="Maven: org.apache.tomcat.embed:tomcat-embed-core:10.1.25" value="project"/>
<level name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:10.1.25" value="project"/>
<level name="Maven: org.springframework:spring-web:6.1.10" value="project"/>
<level name="Maven: org.parttio:line-awesome:2.0.0" value="project"/>
<level name="Maven: com.h2database:h2:2.2.224" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-data-jpa:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-aop:3.2.7" value="project"/>
<level name="Maven: org.aspectj:aspectjweaver:1.9.22" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-jdbc:3.2.7" value="project"/>
<level name="Maven: com.zaxxer:HikariCP:5.0.1" value="project"/>
<level name="Maven: org.springframework:spring-jdbc:6.1.10" value="project"/>
<level name="Maven: org.hibernate.orm:hibernate-core:6.4.9.Final" value="project"/>
<level name="Maven: org.glassfish.jaxb:jaxb-runtime:4.0.5" value="project"/>
<level name="Maven: org.glassfish.jaxb:jaxb-core:4.0.5" value="project"/>
<level name="Maven: org.glassfish.jaxb:txw2:4.0.5" value="project"/>
<level name="Maven: com.sun.istack:istack-commons-runtime:4.1.2" value="project"/>
<level name="Maven: jakarta.inject:jakarta.inject-api:2.0.1" value="project"/>
<level name="Maven: org.antlr:antlr4-runtime:4.13.0" value="project"/>
<level name="Maven: org.springframework.data:spring-data-jpa:3.2.7" value="project"/>
<level name="Maven: org.springframework.data:spring-data-commons:3.2.7" value="project"/>
<level name="Maven: org.springframework:spring-orm:6.1.10" value="project"/>
<level name="Maven: jakarta.annotation:jakarta.annotation-api:2.1.1" value="project"/>
<level name="Maven: org.springframework:spring-aspects:6.1.10" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-mail:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-logging:3.2.7" value="project"/>
<level name="Maven: ch.qos.logback:logback-classic:1.4.14" value="project"/>
<level name="Maven: ch.qos.logback:logback-core:1.4.14" value="project"/>
<level name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.21.1" value="project"/>
<level name="Maven: org.slf4j:jul-to-slf4j:2.0.13" value="project"/>
<level name="Maven: org.yaml:snakeyaml:2.2" value="project"/>
<level name="Maven: org.springframework:spring-context-support:6.1.10" value="project"/>
<level name="Maven: org.eclipse.angus:jakarta.mail:2.0.3" value="project"/>
<level name="Maven: jakarta.activation:jakarta.activation-api:2.1.3" value="project"/>
<level name="Maven: org.eclipse.angus:angus-activation:2.0.2" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-security:3.2.7" value="project"/>
<level name="Maven: org.springframework:spring-aop:6.1.10" value="project"/>
<level name="Maven: org.springframework.security:spring-security-config:6.2.5" value="project"/>
<level name="Maven: org.springframework.security:spring-security-web:6.2.5" value="project"/>
<level name="Maven: org.springframework:spring-expression:6.1.10" value="project"/>
<level name="Maven: org.springframework.ldap:spring-ldap-core:3.2.4" value="project"/>
<level name="Maven: org.springframework:spring-core:6.1.10" value="project"/>
<level name="Maven: org.springframework:spring-jcl:6.1.10" value="project"/>
<level name="Maven: org.springframework:spring-beans:6.1.10" value="project"/>
<level name="Maven: org.springframework:spring-tx:6.1.10" value="project"/>
<level name="Maven: org.slf4j:slf4j-api:2.0.13" value="project"/>
<level name="Maven: org.springframework.security:spring-security-ldap:6.2.5" value="project"/>
<level name="Maven: org.springframework.security:spring-security-core:6.2.5" value="project"/>
<level name="Maven: org.springframework.security:spring-security-crypto:6.2.5" value="project"/>
<level name="Maven: io.micrometer:micrometer-observation:1.12.7" value="project"/>
<level name="Maven: io.micrometer:micrometer-commons:1.12.7" value="project"/>
<level name="Maven: org.springframework:spring-context:6.1.10" value="project"/>
<level name="Maven: com.unboundid:unboundid-ldapsdk:6.0.11" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-validation:3.2.7" value="project"/>
<level name="Maven: org.apache.tomcat.embed:tomcat-embed-el:10.1.25" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-data-ldap:3.2.7" value="project"/>
<level name="Maven: org.springframework.data:spring-data-ldap:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-devtools:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-autoconfigure:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-starter-test:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-test:3.2.7" value="project"/>
<level name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:3.2.7" value="project"/>
<level name="Maven: com.jayway.jsonpath:json-path:2.9.0" value="project"/>
<level name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:4.0.2" value="project"/>
<level name="Maven: net.minidev:json-smart:2.5.1" value="project"/>
<level name="Maven: net.minidev:accessors-smart:2.5.1" value="project"/>
<level name="Maven: org.awaitility:awaitility:4.2.1" value="project"/>
<level name="Maven: org.hamcrest:hamcrest:2.2" value="project"/>
<level name="Maven: org.junit.jupiter:junit-jupiter:5.10.2" value="project"/>
<level name="Maven: org.junit.jupiter:junit-jupiter-api:5.10.2" value="project"/>
<level name="Maven: org.opentest4j:opentest4j:1.3.0" value="project"/>
<level name="Maven: org.junit.platform:junit-platform-commons:1.10.2" value="project"/>
<level name="Maven: org.apiguardian:apiguardian-api:1.1.2" value="project"/>
<level name="Maven: org.junit.jupiter:junit-jupiter-params:5.10.2" value="project"/>
<level name="Maven: org.junit.jupiter:junit-jupiter-engine:5.10.2" value="project"/>
<level name="Maven: org.mockito:mockito-junit-jupiter:5.7.0" value="project"/>
<level name="Maven: org.skyscreamer:jsonassert:1.5.1" value="project"/>
<level name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" value="project"/>
<level name="Maven: org.springframework:spring-test:6.1.10" value="project"/>
<level name="Maven: org.xmlunit:xmlunit-core:2.9.1" value="project"/>
<level name="Maven: commons-beanutils:commons-beanutils:1.9.4" value="project"/>
<level name="Maven: commons-logging:commons-logging:1.2" value="project"/>
<level name="Maven: commons-collections:commons-collections:3.2.2" value="project"/>
<level name="Maven: com.fasterxml.jackson.core:jackson-core:2.15.4" value="project"/>
<level name="Maven: org.mockito:mockito-core:5.12.0" value="project"/>
<level name="Maven: net.bytebuddy:byte-buddy:1.14.17" value="project"/>
<level name="Maven: net.bytebuddy:byte-buddy-agent:1.14.17" value="project"/>
<level name="Maven: org.objenesis:objenesis:3.3" value="project"/>
<level name="Maven: com.github.mvysny.kaributesting:karibu-testing-v23:2.1.8" value="project"/>
<level name="Maven: com.github.mvysny.kaributesting:karibu-testing-v10:2.1.8" value="project"/>
<level name="Maven: com.github.mvysny.fake-servlet:fake-servlet5:1.1" value="project"/>
<level name="Maven: jakarta.servlet:jakarta.servlet-api:6.0.0" value="project"/>
<level name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24" value="project"/>
<level name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24" value="project"/>
<level name="Maven: com.github.mvysny.karibu-tools:karibu-tools:0.21" value="project"/>
<level name="Maven: org.jetbrains.kotlin:kotlin-test:1.9.24" value="project"/>
<level name="Maven: io.github.classgraph:classgraph:4.8.151" value="project"/>
<level name="Maven: com.github.mvysny.karibu-tools:karibu-tools-23:0.21" value="project"/>
<level name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.9.24" value="project"/>
<level name="Maven: org.jetbrains:annotations:13.0" value="project"/>
<level name="Maven: com.github.mvysny.kaributesting:karibu-testing-v10-spring:2.1.8" value="project"/>
<level name="Maven: org.hibernate.validator:hibernate-validator:8.0.1.Final" value="project"/>
<level name="Maven: jakarta.validation:jakarta.validation-api:3.0.2" value="project"/>
<level name="Maven: org.jboss.logging:jboss-logging:3.5.3.Final" value="project"/>
<level name="Maven: com.fasterxml:classmate:1.6.0" value="project"/>
<level name="Maven: org.hibernate.search:hibernate-search-mapper-orm:7.1.1.Final" value="project"/>
<level name="Maven: org.hibernate.search:hibernate-search-engine:7.1.1.Final" value="project"/>
<level name="Maven: org.hibernate.search:hibernate-search-mapper-pojo-base:7.1.1.Final" value="project"/>
<level name="Maven: org.hibernate.search:hibernate-search-util-common:7.1.1.Final" value="project"/>
<level name="Maven: jakarta.persistence:jakarta.persistence-api:3.1.0" value="project"/>
<level name="Maven: jakarta.transaction:jakarta.transaction-api:2.0.1" value="project"/>
<level name="Maven: org.hibernate.common:hibernate-commons-annotations:6.0.6.Final" value="project"/>
<level name="Maven: io.smallrye:jandex:3.1.2" value="project"/>
<level name="Maven: org.hibernate.search:hibernate-search-backend-lucene:7.1.1.Final" value="project"/>
<level name="Maven: org.apache.lucene:lucene-analysis-common:9.9.2" value="project"/>
<level name="Maven: org.apache.lucene:lucene-join:9.9.2" value="project"/>
<level name="Maven: org.apache.lucene:lucene-facet:9.9.2" value="project"/>
<level name="Maven: com.carrotsearch:hppc:0.9.1" value="project"/>
<level name="Maven: org.apache.lucene:lucene-highlighter:9.9.2" value="project"/>
<level name="Maven: org.apache.lucene:lucene-memory:9.9.2" value="project"/>
<level name="Maven: com.vaadin:vaadin-testbench-junit5:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-testbench-core-junit5:9.3.5" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-remote-driver:4.25.0" value="project"/>
<level name="Maven: com.google.auto.service:auto-service-annotations:1.1.1" value="project"/>
<level name="Maven: io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-api:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-context:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-exporter-logging:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-common:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-api-events:1.31.0-alpha" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-trace:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-metrics:1.31.0" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-extension-incubator:1.31.0-alpha" value="project"/>
<level name="Maven: io.opentelemetry:opentelemetry-sdk-logs:1.31.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-api:4.25.0" value="project"/>
<level name="Maven: org.jspecify:jspecify:1.0.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-http:4.25.0" value="project"/>
<level name="Maven: dev.failsafe:failsafe:3.3.2" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-json:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-manager:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-os:4.25.0" value="project"/>
<level name="Maven: org.apache.commons:commons-exec:1.4.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-java:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-chromium-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-devtools-v127:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-devtools-v128:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-devtools-v129:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-devtools-v85:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-edge-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-ie-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-safari-driver:4.25.0" value="project"/>
<level name="Maven: org.seleniumhq.selenium:selenium-support:4.25.0" value="project"/>
<level name="Maven: org.junit.platform:junit-platform-engine:1.10.2" value="project"/>
<level name="Maven: com.vaadin:license-checker:1.13.0" value="project"/>
<level name="Maven: com.github.oshi:oshi-core:6.4.10" value="project"/>
<level name="Maven: net.java.dev.jna:jna:5.14.0" value="project"/>
<level name="Maven: net.java.dev.jna:jna-platform:5.14.0" value="project"/>
<level name="Maven: com.nimbusds:nimbus-jose-jwt:9.37.3" value="project"/>
<level name="Maven: org.lucee:jcip-annotations:1.0.0" value="project"/>
<level name="Maven: com.vaadin.external.gwt:gwt-elemental:2.8.2.vaadin2" value="project"/>
<level name="Maven: com.vaadin:vaadin-testbench-unit-junit5:9.3.5" value="project"/>
<level name="Maven: com.vaadin:vaadin-testbench-unit-shared:9.3.5" value="project"/>
<level name="Maven: org.jetbrains.kotlin:kotlin-reflect:1.9.24" value="project"/>
<level name="Maven: com.vaadin:vaadin-testbench-shared:9.3.5" value="project"/>
<level name="Maven: com.vaadin:flow-html-components-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-accordion-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-app-layout-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-avatar-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-board-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-button-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-charts-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-checkbox-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-combo-box-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-confirm-dialog-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-context-menu-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-cookie-consent-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-cookie-consent-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-crud-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-custom-field-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-date-picker-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-date-time-picker-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-details-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-dialog-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-form-layout-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-grid-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-grid-pro-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-icons-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-virtual-list-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-list-box-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-login-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-menu-bar-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-messages-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-notification-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-ordered-layout-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-popover-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-progress-bar-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-radio-button-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-rich-text-editor-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-select-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-side-nav-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-split-layout-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-tabs-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-text-field-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-time-picker-testbench:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-upload-testbench:24.5.1" value="project"/>
<level name="Maven: org.assertj:assertj-core:3.25.3" value="project"/>
<level name="Maven: net.openhft:compiler:2.26ea0" value="project"/>
<level name="Maven: com.hilerio:ace-widget:2.0.0" value="project"/>
<level name="Maven: io.hypersistence:hypersistence-utils-hibernate-63:3.7.3" value="project"/>
<level name="Maven: io.hypersistence:hypersistence-tsid:2.1.1" value="project"/>
<level name="Maven: in.virit:viritin:2.8.22" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-ast:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-builder:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-collection:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-data:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-dependency:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-format:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-html:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-misc:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-sequence:0.64.8" value="project"/>
<level name="Maven: com.vladsch.flexmark:flexmark-util-visitor:0.64.8" value="project"/>
<level name="Maven: org.apache.poi:poi-ooxml:5.2.3" value="project"/>
<level name="Maven: org.apache.poi:poi:5.2.3" value="project"/>
<level name="Maven: commons-codec:commons-codec:1.16.1" value="project"/>
<level name="Maven: org.apache.commons:commons-math3:3.6.1" value="project"/>
<level name="Maven: com.zaxxer:SparseBitSet:1.2" value="project"/>
<level name="Maven: org.apache.poi:poi-ooxml-lite:5.2.3" value="project"/>
<level name="Maven: org.apache.xmlbeans:xmlbeans:5.1.1" value="project"/>
<level name="Maven: org.apache.commons:commons-compress:1.21" value="project"/>
<level name="Maven: commons-io:commons-io:2.11.0" value="project"/>
<level name="Maven: com.github.virtuald:curvesapi:1.07" value="project"/>
<level name="Maven: org.apache.logging.log4j:log4j-api:2.21.1" value="project"/>
<level name="Maven: org.apache.commons:commons-collections4:4.4" value="project"/>
<level name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" value="project"/>
<level name="Maven: com.flowingcode.addons:simple-timer:2.2.0" value="project"/>
<level name="Maven: org.vaadin.addons.stefan:clipboard:1.0.3" value="project"/>
<level name="Maven: com.vaadin:vaadin:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-internal:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-board-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-charts-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-crud-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-grid-pro-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-map-flow:24.5.1" value="project"/>
<level name="Maven: com.vaadin:vaadin-rich-text-editor-flow:24.5.1" value="project"/>
<level name="Maven: org.projectlombok:lombok:1.18.32" value="project"/>
<level name="Maven: org.mapstruct:mapstruct:1.5.5.Final" value="project"/>
<level name="Maven: org.mapstruct:mapstruct-processor:1.5.5.Final" value="project"/>
<level name="Maven: org.apache.lucene:lucene-core:9.10.0" value="project"/>
<level name="Maven: org.apache.lucene:lucene-queryparser:9.10.0" value="project"/>
<level name="Maven: org.apache.lucene:lucene-queries:9.10.0" value="project"/>
<level name="Maven: org.apache.lucene:lucene-sandbox:9.10.0" value="project"/>
<level name="Maven: com.google.guava:guava:33.1.0-jre" value="project"/>
<level name="Maven: com.google.guava:failureaccess:1.0.2" value="project"/>
<level name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" value="project"/>
<level name="Maven: com.google.code.findbugs:jsr305:3.0.2" value="project"/>
<level name="Maven: org.checkerframework:checker-qual:3.42.0" value="project"/>
<level name="Maven: com.google.errorprone:error_prone_annotations:2.26.1" value="project"/>
<level name="Maven: com.google.j2objc:j2objc-annotations:3.0.0" value="project"/>
<level name="Maven: org.apache.commons:commons-lang3:3.14.0" value="project"/>
<level name="Maven: org.vaadin.addons.componentfactory:vcf-pdf-viewer:2.8.1" value="project"/>
<level name="Maven: com.openhtmltopdf:openhtmltopdf-pdfbox:1.0.10" value="project"/>
<level name="Maven: org.apache.pdfbox:pdfbox:2.0.24" value="project"/>
<level name="Maven: org.apache.pdfbox:fontbox:2.0.24" value="project"/>
<level name="Maven: org.apache.pdfbox:xmpbox:2.0.24" value="project"/>
<level name="Maven: com.openhtmltopdf:openhtmltopdf-core:1.0.10" value="project"/>
<level name="Maven: de.rototor.pdfbox:graphics2d:0.32" value="project"/>
<level name="Maven: org.freemarker:freemarker:2.3.32" value="project"/>
<level name="Maven: com.auth0:java-jwt:4.4.0" value="project"/>
<level name="Maven: com.fasterxml.jackson.core:jackson-databind:2.15.4" value="project"/>
<level name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.15.4" value="project"/>
<level name="Maven: org.apache.maven.plugins:maven-surefire-plugin:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-api:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-logger-api:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-shared-utils:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-extensions-api:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:maven-surefire-common:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-booter:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.surefire:surefire-extensions-spi:3.3.1" value="project"/>
<level name="Maven: org.apache.maven.resolver:maven-resolver-util:1.4.1" value="project"/>
<level name="Maven: org.apache.maven.resolver:maven-resolver-api:1.4.1" value="project"/>
<level name="Maven: org.apache.maven.shared:maven-common-artifact-filters:3.4.0" value="project"/>
<level name="Maven: org.codehaus.plexus:plexus-java:1.2.0" value="project"/>
<level name="Maven: com.thoughtworks.qdox:qdox:2.0.3" value="project"/>
</levels>
</component>

View File

@ -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);
}
}
}

View File

@ -28,36 +28,42 @@ public class Employee extends BaseEntity implements UserDetails {
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El apellido solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El apellido solo debe contener letras")
private String lastName; private String lastName;
private LocalDate birthday; 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 birthCity;
private String age; 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; 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; private String localAddress;
@Pattern(regexp = "^[0-9]+$", message = "El número de teléfono debe contener solo números") @Pattern(regexp = "^[0-9]+$", message = "El número de teléfono debe contener solo números")
private String phoneNumber; private String phoneNumber;
@Email(message = "El correo personal no tiene un formato válido") @Email(message = "El correo personal no tiene un formato válido")
private String personalEmail; private String personalEmail;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El cargo solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El cargo solo debe contener letras")
private String position; private String position;
@ManyToOne @ManyToOne
@JoinColumn(name = "team_id", nullable = false) @JoinColumn(name = "team_id", nullable = false)
private Team team; 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; private String emergencyCName;
@Size(max = 100, message = "La dirección de contacto de emergencia no debe exceder 100 caracteres")
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;
@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") @Pattern(regexp = "^[0-9]+$", message = "La cantidad de hijos debe contener solo números")
private String numberOfChildren; private String numberOfChildren;
@Pattern(regexp = "^[0-9]+$", message = "El CI debe contener solo números") @Pattern(regexp = "^[0-9]+$", message = "El CI debe contener solo números")
private String ci; private String ci;
private String issuedIn; private String issuedIn;
@Size(max = 100, message = "El título no debe exceder 100 caracteres")
private String pTitle1; private String pTitle1;
private String pTitle2; private String pTitle2;
private String pTitle3; private String pTitle3;
@ -70,9 +76,7 @@ public class Employee extends BaseEntity implements UserDetails {
private String certification2; private String certification2;
private String certification3; private String certification3;
private String certification4; private String certification4;
@Size(max = 255, message = "El reconocimiento no debe exceder 255 caracteres")
private String recognition; private String recognition;
@Size(max = 500, message = "Los logros no deben exceder 500 caracteres")
private String achievements; private String achievements;
private String language; private String language;

View File

@ -1,41 +1,56 @@
package com.primefactorsolutions.model; package com.primefactorsolutions.model;
import jakarta.persistence.Entity; import jakarta.persistence.*;
import jakarta.persistence.GeneratedValue; import lombok.AllArgsConstructor;
import jakarta.persistence.GenerationType; import lombok.Data;
import jakarta.persistence.Id; import lombok.EqualsAndHashCode;
import jakarta.persistence.ManyToOne; import lombok.NoArgsConstructor;
import java.util.UUID; import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.List;
import java.util.Locale;
@Data
@Entity @Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class HoursWorked extends BaseEntity { public class HoursWorked extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
@ManyToOne @ManyToOne
@JoinColumn(name = "employee_id", nullable = true)
private Employee employee; private Employee employee;
@ManyToOne
@JoinColumn(name = "team_id", nullable = true)
private Team team;
private int weekNumber; private int weekNumber;
private LocalDate date;
private String actividad;
private String tareasEspecificas;
private double hours;
private double horasTareasEspecificas;
private double horaspendientes;
private double totalHours; private double totalHours;
public HoursWorked() { } public static double calculateTotalHours(List<HoursWorked> activities) {
return activities.stream()
public UUID getId() { .mapToDouble(activity -> activity.hours + activity.horasTareasEspecificas)
return id; .sum();
} }
public void setId(final UUID id) { public static double calculatePendingHours(List<HoursWorked> activities) {
this.id = id; double totalHoursWorked = calculateTotalHours(activities);
return Math.max(0, 40 - totalHoursWorked);
} }
public Employee getEmployee() { public Employee getEmployee() {
return employee; return employee;
} }
public void setEmployee(final Employee value) { public void setEmployee(final Employee employee) {
this.employee = value; this.employee = employee;
} }
public int getWeekNumber() { public int getWeekNumber() {
@ -45,6 +60,33 @@ public class HoursWorked extends BaseEntity {
public void setWeekNumber(final int weekNumber) { public void setWeekNumber(final int weekNumber) {
this.weekNumber = weekNumber; this.weekNumber = weekNumber;
} }
public LocalDate getDate() {
return date;
}
public void setDate(final LocalDate date) {
this.date = date;
if (date != null) {
WeekFields weekFields = WeekFields.of(Locale.getDefault());
this.weekNumber = date.get(weekFields.weekOfWeekBasedYear());
}
}
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() { public double getTotalHours() {
return totalHours; return totalHours;
@ -53,4 +95,55 @@ public class HoursWorked extends BaseEntity {
public void setTotalHours(final double totalHours) { public void setTotalHours(final double totalHours) {
this.totalHours = 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;
}
} }

View File

@ -11,7 +11,7 @@ public interface EmployeeRepository extends JpaRepository<Employee, UUID> {
Optional<Employee> findByUsername(String username); Optional<Employee> findByUsername(String username);
Optional<Employee> findByPersonalEmail(String personalEmail); Optional<Employee> findByPersonalEmail(String personalEmail);
Optional<Employee> findByTeamId(UUID teamId); Optional<Employee> findByTeamIdAndLeadManagerTrue(UUID teamId);
List<Employee> findByTeamName(String teamName); List<Employee> findByTeamName(String teamName);
} }

View File

@ -2,13 +2,14 @@ package com.primefactorsolutions.repositories;
import com.primefactorsolutions.model.HoursWorked; import com.primefactorsolutions.model.HoursWorked;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.UUID;
@Repository
public interface HoursWorkedRepository extends JpaRepository<HoursWorked, Long> { public interface HoursWorkedRepository extends JpaRepository<HoursWorked, UUID> {
// Puedes definir consultas personalizadas aquí si es necesario.
List<HoursWorked> findByWeekNumber(int weekNumber); List<HoursWorked> findByWeekNumber(int weekNumber);
List<HoursWorked> findByDate(LocalDate date);
List<HoursWorked> findByEmployeeIdAndWeekNumber(UUID employeeId, int weekNumber);
} }

View File

@ -50,7 +50,7 @@ public class EmployeeService {
public String getTeamLeadName(final UUID teamId) { public String getTeamLeadName(final UUID teamId) {
// Encuentra al empleado con el rol de lead_manager en el equipo especificado // Encuentra al empleado con el rol de lead_manager en el equipo especificado
Optional<Employee> leadManager = employeeRepository.findByTeamId(teamId); Optional<Employee> leadManager = employeeRepository.findByTeamIdAndLeadManagerTrue(teamId);
return leadManager.map(employee -> employee.getFirstName() + " " + employee.getLastName()) return leadManager.map(employee -> employee.getFirstName() + " " + employee.getLastName())
.orElse("No asignado"); .orElse("No asignado");

View File

@ -2,10 +2,12 @@ package com.primefactorsolutions.service;
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.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.time.LocalDate;
import java.util.*;
@Service @Service
public class HoursWorkedService { public class HoursWorkedService {
@ -20,6 +22,20 @@ public class HoursWorkedService {
return hoursWorkedRepository.findAll(); return hoursWorkedRepository.findAll();
} }
public double getTotalHoursWorkedByEmployeeForWeek(UUID employeeId, int weekNumber) {
List<HoursWorked> 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> hoursWorked = hoursWorkedRepository.findById(id);
HoursWorked hw = hoursWorked.get();
return hw;
}
public HoursWorked saveHoursWorked(final HoursWorked hoursWorked) { public HoursWorked saveHoursWorked(final HoursWorked hoursWorked) {
return hoursWorkedRepository.save(hoursWorked); return hoursWorkedRepository.save(hoursWorked);
} }
@ -28,13 +44,52 @@ public class HoursWorkedService {
return hoursWorkedRepository.save(hoursWorked); return hoursWorkedRepository.save(hoursWorked);
} }
public void deleteHoursWorked(final Long id) { public double getTotalHoursForEmployee(UUID employeeId, int weekNumber) {
hoursWorkedRepository.deleteById(id); List<HoursWorked> activities = hoursWorkedRepository.findByEmployeeIdAndWeekNumber(employeeId, weekNumber);
return HoursWorked.calculateTotalHours(activities);
}
public double getPendingHoursForEmployee(UUID employeeId, int weekNumber) {
List<HoursWorked> activities = hoursWorkedRepository.findByEmployeeIdAndWeekNumber(employeeId, weekNumber);
return HoursWorked.calculatePendingHours(activities);
} }
public List<HoursWorked> findByWeekNumber(final int weekNumber) { public List<HoursWorked> findByWeekNumber(final int weekNumber) {
return hoursWorkedRepository.findByWeekNumber(weekNumber); return hoursWorkedRepository.findByWeekNumber(weekNumber);
} }
} public List<HoursWorked> findByDate(final LocalDate date) {
return hoursWorkedRepository.findByDate(date);
}
public List<HoursWorked> findByDateAndWeekNumber(final LocalDate date, final int weekNumber) {
return hoursWorkedRepository.findByDate(date);
}
public List<HoursWorked> findHoursWorkeds(
final int start, final int pageSize, final String sortProperty, final boolean asc) {
List<HoursWorked> 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<HoursWorked> findHoursWorkeds(final int start, final int pageSize) {
List<HoursWorked> 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> hoursWorked = hoursWorkedRepository.findById(id);
return hoursWorked.get();
}
}

View File

@ -56,7 +56,6 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private final TimeOffRequestService requestService; private final TimeOffRequestService requestService;
private final TeamService teamService; private final TeamService teamService;
// TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente. // 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 username = createTextField("Username: ", 30, true);
private final TextField firstName = createTextField("Nombres: ", 30, true); private final TextField firstName = createTextField("Nombres: ", 30, true);
@ -65,24 +64,21 @@ 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", 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 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<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox(); private final ComboBox<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox();
private final TextField numberOfChildren = createTextField("Numero de Hijos", 3, false); private final TextField numberOfChildren = createTextField("Numero de Hijos", 2, false);
private final TextField ci = createTextField("CI", 30, false); private final TextField ci = createTextField("CI", 10, false);
private final TextField issuedIn = createTextField("Expedido en ", 30, false); private final TextField issuedIn = createTextField("Expedido en ", 10, false);
private final TextField phoneNumber = createTextField("Teléfono", 8, false); private final TextField phoneNumber = createTextField("Teléfono", 8, false);
private final EmailField personalEmail = createEmailField("E-mail"); private final EmailField personalEmail = createEmailField("E-mail ejemplo: (ejemplo@gmail.com)");
private final TextField cod = createTextField("Codigo de Empleado", 30, false);
private final TextField position = createTextField("Cargo", 30, false);
private final ComboBox<Team> team = new ComboBox<>("Equipo");
private final TextField leadManager = createTextField("Lead/Manager", 30, false);
private final TextField project = createTextField("Proyecto", 30, false);
private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false); 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 emergencyCAddress = createTextField("Dirección de Contacto", 50, false);
private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, 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 MemoryBuffer buffer = new MemoryBuffer();
private final Upload upload = new Upload(buffer); private final Upload upload = new Upload(buffer);
@ -101,10 +97,15 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private final TextField certification4 = createTextField("Certificación 4", 30, false); private final TextField certification4 = createTextField("Certificación 4", 30, false);
private final TextField recognition = createTextField("Reconocimientos", 30, false); private final TextField recognition = createTextField("Reconocimientos", 30, false);
private final TextField achievements = createTextField("Logros Profesionales", 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); 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> 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 dateOfEntry = new VDatePicker("Fecha de Ingreso");
private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro"); private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro");
private final TextField contractType = createTextField("Tipo de Contratación", 30, false); private final TextField contractType = createTextField("Tipo de Contratación", 30, false);
@ -141,7 +142,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
//TITULOS PARA INFORMACIÓN ADMINISTRATIVA //TITULOS PARA INFORMACIÓN ADMINISTRATIVA
private final H2 infoAdm = new H2("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 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"); private final H3 datGest = new H3("Datos Gestora Pública y Seguro Social");
public EmployeeView(final EmployeeService employeeService, public EmployeeView(final EmployeeService employeeService,
@ -176,6 +177,9 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
editButton.setVisible(true); editButton.setVisible(true);
reportButton.setVisible(true); reportButton.setVisible(true);
birthday.addValueChangeListener(event -> calculateAge()); birthday.addValueChangeListener(event -> calculateAge());
birthday.setMax(java.time.LocalDate.now());
dateOfEntry.addValueChangeListener(event -> calculateSeniority());
dateOfEntry.addValueChangeListener(event -> calculateSeniority());
reportButton.addClickListener((ComponentEventListener<ClickEvent<Button>>) buttonClickEvent -> { reportButton.addClickListener((ComponentEventListener<ClickEvent<Button>>) buttonClickEvent -> {
var employee = getEntity(); var employee = getEntity();
@ -203,10 +207,30 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
int birthYear = birthday.getValue().getYear(); int birthYear = birthday.getValue().getYear();
int ages = currentYear - birthYear; int ages = currentYear - birthYear;
age.setValue(String.valueOf(ages)); 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); 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() { private void configureUpload() {
upload.setAcceptedFileTypes("image/jpeg", "image/png"); upload.setAcceptedFileTypes("image/jpeg", "image/png");
upload.setMaxFileSize(1024 * 1024); upload.setMaxFileSize(1024 * 1024);
@ -218,11 +242,15 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
getEntity().setProfileImage(base64Image); getEntity().setProfileImage(base64Image);
profileImagePreview.setSrc("data:image/jpeg;base64," + base64Image); profileImagePreview.setSrc("data:image/png;base64," + base64Image);
profileImagePreview.setMaxWidth("150px"); profileImagePreview.setMaxWidth("150px");
profileImagePreview.setMaxHeight("150px"); profileImagePreview.setMaxHeight("150px");
} catch (IOException e) { } 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<Employee> implements HasUrl
if (employee.getProfileImage() != null && !employee.getProfileImage().isEmpty()) { if (employee.getProfileImage() != null && !employee.getProfileImage().isEmpty()) {
profileImagePreview.setSrc("data:image/jpeg;base64," + employee.getProfileImage()); profileImagePreview.setSrc("data:image/jpeg;base64," + employee.getProfileImage());
profileImagePreview.setVisible(true); profileImagePreview.setVisible(true);
profileImagePreview.setMaxWidth("150px"); profileImagePreview.setMaxWidth("250px");
profileImagePreview.setMaxHeight("150px"); profileImagePreview.setMaxHeight("250px");
upload.setVisible(false); upload.setVisible(true);
} else { } else {
profileImagePreview.setVisible(false); profileImagePreview.setVisible(true);
upload.setVisible(true); upload.setVisible(true);
} }
} }
@ -478,6 +506,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
emergencyCPhone.setReadOnly(false); emergencyCPhone.setReadOnly(false);
emergencyCEmail.setReadOnly(false); emergencyCEmail.setReadOnly(false);
upload.setVisible(false); upload.setVisible(false);
profileImagePreview.setVisible(true);
age.setReadOnly(false); age.setReadOnly(false);
gender.setReadOnly(false); gender.setReadOnly(false);
status.setReadOnly(false); status.setReadOnly(false);
@ -525,7 +554,6 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
birthCity, residenceAddress, localAddress, birthCity, residenceAddress, localAddress,
maritalStatus, ci, issuedIn, numberOfChildren, maritalStatus, ci, issuedIn, numberOfChildren,
phoneNumber, personalEmail, phoneNumber, personalEmail,
cod, position, team, leadManager, project,
contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail, contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail,
infProf, infProf,
titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3, titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3,
@ -533,6 +561,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
logros, recognition, achievements, logros, recognition, achievements,
idioma, language, languageLevel, idioma, language, languageLevel,
infoAdm, infoAdm,
cod, position, team, leadManager, project,
infoCont, dateOfEntry, dateOfExit, contractType, seniority, salary, infoCont, dateOfEntry, dateOfExit, contractType, seniority, salary,
datBanc, bankName, accountNumber, datBanc, bankName, accountNumber,
datGest, gpss, sss, beneficiaries, datGest, gpss, sss, beneficiaries,

View File

@ -0,0 +1,235 @@
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<HoursWorked> hoursWorkedGrid = new PagingGrid<>();
private List<Employee> employees = Collections.emptyList();
private ComboBox<Employee> employeeFilter;
private ComboBox<Team> 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<HoursWorked> 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<HoursWorked> fetchFilteredHoursWorked(final int start,
final int pageSize,
final Employee employee,
final Team team) {
List<HoursWorked> 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.getWeekNumber())
.setHeader("Semana")
.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<Employee> createEmployeeFilter() {
employeeFilter = new ComboBox<>("Empleado");
List<Employee> 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<Team> createTeamFilter() {
teamFilter = new ComboBox<>("Equipo");
List<Team> 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;
}
}

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

@ -1,419 +1,259 @@
package com.primefactorsolutions.views; package com.primefactorsolutions.views;
import com.primefactorsolutions.model.Actividad;
import com.primefactorsolutions.model.Employee; import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.model.HoursWorked; import com.primefactorsolutions.model.HoursWorked;
import com.primefactorsolutions.model.Team;
import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.service.EmployeeService;
import com.primefactorsolutions.service.HoursWorkedService; import com.primefactorsolutions.service.HoursWorkedService;
import com.vaadin.flow.component.datepicker.DatePicker; import com.primefactorsolutions.service.TeamService;
import com.vaadin.flow.component.grid.Grid; 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.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.textfield.TextField;
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.orderedlayout.VerticalLayout; import com.vaadin.flow.router.*;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent; import com.vaadin.flow.spring.annotation.SpringComponent;
import jakarta.annotation.security.PermitAll; 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 org.springframework.context.annotation.Scope;
import com.vaadin.flow.component.html.Label; import org.vaadin.firitin.components.datepicker.VDatePicker;
import org.springframework.web.servlet.HandlerMapping; import org.vaadin.firitin.form.BeanValidationForm;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.time.DayOfWeek;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.IsoFields; import java.time.temporal.IsoFields;
import java.time.temporal.WeekFields;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.UUID;
@SpringComponent @SpringComponent
@PermitAll @PermitAll
@Scope("prototype") @Scope("prototype")
@PageTitle("Hours Worked") @PageTitle("Horas Trabajadas")
@Route(value = "/hours-worked/me", layout = MainLayout.class) @Route(value = "/hours-worked-list/:hours-workedId?/:action?", layout = MainLayout.class)
public class HoursWorkedView extends VerticalLayout { public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements HasUrlParameter<String> {
private final List<Actividad> actividades = new ArrayList<>(); private final VDatePicker dateField = new VDatePicker("Fecha");
private final List<Actividad> actividadesEspecificas = new ArrayList<>(); // Nueva lista para tareas específicas private final ComboBox<Team> teamField = new ComboBox<>("Equipo");
private final Grid<Actividad> grid = new Grid<>(Actividad.class); private ComboBox<Employee> employeeField;
private final Grid<Actividad> gridActividadesEspecificas = new Grid<>(Actividad.class); private final ComboBox<String> 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<Employee> employeeComboBox = new ComboBox<>("Employee"); private final H2 equipoLabel = new H2("Tareas del Cliente/Equipo");
private final ComboBox<String> equipoDropdown = new ComboBox<>("Equipo"); private final H2 empresaLabel = new H2("Tareas de la Empresa");
private final ComboBox<String> 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 Label totalCompletadoLabel = new Label(); 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"); private Button saveButton;
@Autowired
private InternalResourceViewResolver defaultViewResolver;
@Qualifier("defaultServletHandlerMapping")
@Autowired
private HandlerMapping defaultServletHandlerMapping;
public HoursWorkedView(final HoursWorkedService hoursWorkedService,
public HoursWorkedView(final EmployeeService employeeService, final HoursWorkedService hoursWorkedService) { final EmployeeService employeeService,
this.employeeService = employeeService; final TeamService teamService) {
super(HoursWorked.class);
this.hoursWorkedService = hoursWorkedService; this.hoursWorkedService = hoursWorkedService;
configurarVista(); this.employeeService = employeeService;
configurarGrid(); this.teamService = teamService;
configurarGridActividadesEspecificas();
cargarDatos(); initializeDateField();
configurarTareasEspecificas(); initializeTeamField();
initializeEmployeeField();
configureTareasEspecificas();
} }
private void configurarTareasEspecificas() { @Override
tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones", "Colaboraciones", public void setParameter(final BeforeEvent beforeEvent, final String action) {
"Aprendizajes", "Proyectos PFS", "Otros"); 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<Component> 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.setPlaceholder("Selecciona una tarea...");
tareasEspecificasDropdown.addValueChangeListener(event -> { tareasEspecificasDropdown.addValueChangeListener(event -> {
String selected = event.getValue(); String selected = event.getValue();
// Activa el campo de texto si la opción seleccionada es "Otros" boolean isOtros = "Otros".equals(selected);
tareaEspecificaInput.setVisible("Otros".equals(selected)); tareaEspecificaInput.setVisible(isOtros);
if (!"Otros".equals(selected)) { horasTareaEspecificaField.setVisible(true);
if (!isOtros) {
tareaEspecificaInput.clear(); tareaEspecificaInput.clear();
horasTareaEspecificaField.clear();
} }
}); });
tareaEspecificaInput.setVisible(false); tareaEspecificaInput.setVisible(false);
horasTareaEspecificaField.setVisible(false);
} }
private void cargarDatos() { protected Button createSaveButton() {
if (selectedStartOfWeek != null && weekNumber > 0) { saveButton = new Button("Guardar");
actividades.clear(); saveButton.addClickListener(event -> saveHoursWorked());
actividadesEspecificas.clear(); return saveButton;
List<HoursWorked> listaDeHorasTrabajadas = obtenerDatos();
grid.setItems(actividades);
gridActividadesEspecificas.setItems(actividadesEspecificas);
calcularTotalHoras(listaDeHorasTrabajadas);
}
} }
private void setEmployeeComboBoxProperties() { protected Button createCloseButton() {
employeeComboBox.setWidth("250px"); Button closeButton = new Button("Cerrar");
employeeComboBox.setPlaceholder("Buscar empleado..."); closeButton.addClickListener(event -> closeForm());
employeeComboBox.setItems(employeeService.findAllEmployees()); return closeButton;
employeeComboBox.setItemLabelGenerator(employee -> employee.getFirstName() + " " + employee.getLastName()); }
employeeComboBox.setAllowCustomValue(false);
employeeComboBox.addCustomValueSetListener(event -> private void initializeTeamField() {
Notification.show("Selecciona un empleado válido de la lista.") List<Team> 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) { private ComboBox<Employee> initializeEmployeeField() {
return date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); employeeField = new ComboBox<>("Empleado");
List<Employee> employees = new ArrayList<>(employeeService.findAllEmployees());
employeeField.setItems(employees);
employeeField.setItemLabelGenerator(this::getEmployeeFullName);
employeeField.setValue(employees.getFirst());
return employeeField;
} }
private void configurarVista() { private String getEmployeeFullName(final Employee employee) {
fechaPicker.addValueChangeListener(event -> { return "TODOS".equals(employee.getFirstName())
? "TODOS" : employee.getFirstName() + " " + employee.getLastName();
}
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.addValueChangeListener(event -> {
LocalDate selectedDate = event.getValue(); LocalDate selectedDate = event.getValue();
if (selectedDate != null) { if (selectedDate != null) {
selectedStartOfWeek = getStartOfWeek(selectedDate); int weekNumber = selectedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
LocalDate endOfWeek = selectedStartOfWeek.plusDays(6); Notification.show("Número de la semana: " + weekNumber, 3000, Notification.Position.BOTTOM_CENTER);
weekNumber = getWeekOfYear(selectedDate); if (hoursWorked != null) {
fechasLabel.setText("Semana del " + selectedStartOfWeek + " al " + endOfWeek); hoursWorked.setWeekNumber(weekNumber);
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<Employee> 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 void configurarGrid() { private void saveHoursWorked() {
grid.removeAllColumns(); if (isFormValid()) {
grid.setItems(actividades); HoursWorked hoursWorked = getEntity();
grid.addColumn(Actividad::getNombre).setHeader("Actividad"); setFieldValues(hoursWorked);
grid.addColumn(Actividad::getLunes).setHeader("Lunes"); hoursWorkedService.save(hoursWorked);
grid.addColumn(Actividad::getMartes).setHeader("Martes"); Notification.show("Horas trabajadas guardadas correctamente.");
grid.addColumn(Actividad::getMiercoles).setHeader("Miércoles"); closeForm();
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 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;
} }
return Double.parseDouble(value);
} }
private LocalDate getStartOfWeek(final LocalDate date) { private void setFieldValues(final HoursWorked hoursWorked) {
WeekFields weekFields = WeekFields.of(Locale.getDefault()); hoursWorked.setDate(dateField.getValue());
return date.with(weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()); hoursWorked.setTeam(teamField.getValue());
} hoursWorked.setEmployee(employeeField.getValue());
hoursWorked.setActividad(activityField.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);
try { try {
hoursWorkedService.saveHoursWorked(hoursWorked); // Usa saveHoursWorked directamente double hours = Double.parseDouble(hoursField.getValue());
Notification.show("Actividades guardadas correctamente."); hoursWorked.setHours(hours);
System.out.println(hoursWorked); } catch (NumberFormatException e) {
} catch (Exception e) { Notification.show("Por favor, ingrese un número válido para las horas.");
Notification.show("Error al guardar actividades: " + e.getMessage()); }
if ("Otros".equals(tareasEspecificasDropdown.getValue())) {
hoursWorked.setTareasEspecificas(tareaEspecificaInput.getValue());
try {
double horasEspecifica = Double.parseDouble(horasTareaEspecificaField.getValue());
hoursWorked.setHorasTareasEspecificas(horasEspecifica);
double totalHoras = hoursWorked.getHours() + horasEspecifica;
hoursWorked.setTotalHours(totalHoras);
} 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<HoursWorked> listaDeHorasTrabajadas) { private void closeForm() {
return listaDeHorasTrabajadas.stream() getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + hoursWorked.getId().toString()));
.mapToDouble(HoursWorked::getTotalHours)
.sum();
} }
private List<HoursWorked> obtenerDatos() { private boolean isFormValid() {
return new ArrayList<>(); return dateField.getValue() != null
&&
teamField.getValue() != null
&&
employeeField.getValue() != null
&&
!activityField.isEmpty();
} }
private void closeView() { private void configureViewOrEditAction(final String action) {
getUI().ifPresent(ui -> ui.navigate(HoursWorkedView.class)); 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);
}
} }

View File

@ -153,7 +153,7 @@ public class MainLayout extends AppLayout {
LineAwesomeIcon.LIST_ALT.create())); LineAwesomeIcon.LIST_ALT.create()));
SideNavItem timesheet = new SideNavItem("My Timesheet", TimesheetView.class, SideNavItem timesheet = new SideNavItem("My Timesheet", TimesheetView.class,
LineAwesomeIcon.HOURGLASS_START_SOLID.create()); 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())); LineAwesomeIcon.ID_CARD_SOLID.create()));
timesheet.addItem(new SideNavItem("Reporte Horas Trabajadas", ReporteView.class, timesheet.addItem(new SideNavItem("Reporte Horas Trabajadas", ReporteView.class,
LineAwesomeIcon.ID_CARD_SOLID.create())); LineAwesomeIcon.ID_CARD_SOLID.create()));

View File

@ -50,7 +50,6 @@ public class ReporteView extends VerticalLayout {
private final Span semanaInfoSpan = new Span(); private final Span semanaInfoSpan = new Span();
// Obtener el año actual // Obtener el año actual
private int currentYear = LocalDate.now().getYear(); 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` // Listener para actualizar `semanaInfoSpan` con la selección del usuario en `semanaComboBox`
semanaComboBox.addValueChangeListener(event -> { semanaComboBox.addValueChangeListener(event -> {
String selectedWeek = event.getValue(); String selectedWeek = event.getValue();
semanaInfoSpan.setText(selectedWeek != null semanaInfoSpan.setText(selectedWeek != null ? selectedWeek : "Selecciona una semana");
? selectedWeek : "Selecciona una semana");
}); });
Button reportButton = new Button("Generar Reporte de Horas Trabajadas", Button reportButton = new Button("Generar Reporte de Horas Trabajadas",
event -> generateHoursWorkedReport()); event -> generateHoursWorkedReport());
HorizontalLayout filtersLayout = new HorizontalLayout(equipoComboBox, HorizontalLayout filtersLayout = new HorizontalLayout(equipoComboBox, semanaComboBox, reportButton);
semanaComboBox, reportButton);
add(filtersLayout); add(filtersLayout);
// Añadir `headerLayout` al diseño principal para el encabezado dinámico // Añadir `headerLayout` al diseño principal para el encabezado dinámico
add(headerLayout); add(headerLayout);
updateHeaderLayout(null, null); updateHeaderLayout(null, null);
grid.addColumn(map -> map.get("ID")).setHeader("ID") grid.addColumn(map -> map.get("ID")).setHeader("ID").getElement().getStyle().set("font-weight", "bold");
.getElement().getStyle().set("font-weight", "bold");
grid.addColumn(map -> map.get("Employee ID")).setHeader("Employee ID"); grid.addColumn(map -> map.get("Employee ID")).setHeader("Employee ID");
grid.addColumn(map -> map.get("Empleado")).setHeader("Empleado"); grid.addColumn(map -> map.get("Empleado")).setHeader("Empleado");
grid.addColumn(map -> map.get("Horas Trabajadas")).setHeader("Horas Trabajadas"); grid.addColumn(map -> map.get("Horas Trabajadas")).setHeader("Horas Trabajadas");
@ -105,8 +101,7 @@ public class ReporteView extends VerticalLayout {
int year = LocalDate.now().getYear(); int year = LocalDate.now().getYear();
LocalDate startOfYear = LocalDate.of(year, 1, 5); // Suponemos que la semana comienza el 5 de enero. LocalDate startOfYear = LocalDate.of(year, 1, 5); // Suponemos que la semana comienza el 5 de enero.
List<String> semanas = startOfYear.datesUntil(LocalDate List<String> semanas = startOfYear.datesUntil(LocalDate.of(year + 1, 1, 1),
.of(year + 1, 1, 1),
java.time.Period.ofWeeks(1)) java.time.Period.ofWeeks(1))
.map(date -> { .map(date -> {
int weekNumber = date.get(WeekFields.of(DayOfWeek.MONDAY, 1) int weekNumber = date.get(WeekFields.of(DayOfWeek.MONDAY, 1)
@ -133,27 +128,25 @@ public class ReporteView extends VerticalLayout {
String selectedWeek = semanaComboBox.getValue(); String selectedWeek = semanaComboBox.getValue();
if (selectedEquipo == null || selectedWeek == null) { if (selectedEquipo == null || selectedWeek == null) {
Notification.show("Por favor, selecciona un equipo y una semana para generar el reporte.", Notification.show("Por favor, selecciona un equipo y una semana para generar el reporte.",
3000, 3000, Notification.Position.MIDDLE);
Notification.Position.MIDDLE);
return; return;
} }
int weekNumber = Integer.parseInt(selectedWeek.split(" ")[1] int weekNumber = Integer.parseInt(selectedWeek.split(" ")[1].replace(":", ""));
.replace(":", "")); LocalDate selectedDate = LocalDate.now().with(WeekFields.of(DayOfWeek.FRIDAY, 1)
LocalDate selectedDate = LocalDate.now() .weekOfWeekBasedYear(), weekNumber);
.with(WeekFields.of(DayOfWeek.FRIDAY, 1)
.weekOfWeekBasedYear(), weekNumber);
updateHeaderLayout(selectedEquipo, selectedDate); updateHeaderLayout(selectedEquipo, selectedDate);
List<HoursWorked> hoursWorkedList = hoursWorkedService.findAll().stream() List<HoursWorked> hoursWorkedList = hoursWorkedService.findAll().stream()
.filter(hw -> hw.getEmployee().getTeam().getId() .filter(hw -> hw.getEmployee().getTeam().getId().equals(selectedEquipo
.equals(selectedEquipo.getId()) && hw.getWeekNumber() == weekNumber) .getId()) && hw.getWeekNumber() == weekNumber)
.collect(Collectors.toList()); .collect(Collectors.toList());
System.out.println(hoursWorkedList);
if (hoursWorkedList.isEmpty()) { if (hoursWorkedList.isEmpty()) {
Notification.show("No hay horas trabajadas disponibles para generar el reporte.", Notification.show("No hay horas trabajadas disponibles para generar el reporte.",
3000, 3000, Notification.Position.MIDDLE);
Notification.Position.MIDDLE);
return; return;
} }
@ -188,8 +181,8 @@ public class ReporteView extends VerticalLayout {
String formattedEndDate = endOfWeek.getDayOfMonth() + " de " String formattedEndDate = endOfWeek.getDayOfMonth() + " de "
+ endOfWeek.getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault()); + endOfWeek.getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault());
headerLayout.add(new Span("Informe " + String.format("%03d", weekNumber) headerLayout.add(new Span("Informe "
+ "/" + currentYear) {{ + String.format("%03d", weekNumber) + "/" + currentYear) {{
getStyle().set("font-size", "24px"); getStyle().set("font-size", "24px");
getStyle().set("font-weight", "bold"); getStyle().set("font-weight", "bold");
}}); }});
@ -213,14 +206,13 @@ public class ReporteView extends VerticalLayout {
} }
} }
private void generateExcelDownloadLink(final List<Map<String, Object>> data, private void generateExcelDownloadLink(final List<Map<String, Object>> data, final int weekNumber) {
final int weekNumber) {
try { try {
List<String> headers = List.of("ID", "Employee ID", "Empleado", List<String> headers = List.of("ID", "Employee ID", "Empleado",
"Horas Trabajadas", "Horas Pendientes", "Observaciones"); "Horas Trabajadas", "Horas Pendientes", "Observaciones");
String selectedTeam = equipoComboBox.getValue().getName(); String selectedTeam = equipoComboBox.getValue().getName();
byte[] excelBytes = reportService.writeAsExcel("hours_worked_report", byte[] excelBytes = reportService.writeAsExcel(
headers, data, selectedTeam, weekNumber, currentYear); "hours_worked_report", headers, data, selectedTeam, weekNumber, currentYear);
StreamResource excelResource = new StreamResource("hours_worked_report.xlsx", StreamResource excelResource = new StreamResource("hours_worked_report.xlsx",
() -> new ByteArrayInputStream(excelBytes)); () -> new ByteArrayInputStream(excelBytes));
@ -241,13 +233,4 @@ public class ReporteView extends VerticalLayout {
return date.get(WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear()); return date.get(WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear());
} }
public int getCurrentYear() {
return currentYear;
}
// Opcional: Si deseas permitir cambiar el año actual manualmente, agrega un setter
public void setCurrentYear(final int currentYear) {
this.currentYear = currentYear;
}
} }

View File

@ -10,7 +10,7 @@ import org.springframework.context.annotation.Scope;
@SpringComponent @SpringComponent
@Scope("prototype") @Scope("prototype")
@PageTitle("Timesheets") @PageTitle("Timesheets")
@Route(value = "/timesheets", layout = MainLayout.class) @Route(value = "/timesheets-report", layout = MainLayout.class)
@PermitAll @PermitAll
public class TimesheestReportView extends Main { public class TimesheestReportView extends Main {
} }

View File

@ -11,7 +11,7 @@ import org.springframework.context.annotation.Scope;
@PermitAll @PermitAll
@Scope("prototype") @Scope("prototype")
@PageTitle("Timesheet") @PageTitle("Timesheet")
@Route(value = "/timesheets/me", layout = MainLayout.class) @Route(value = "/timesheets", layout = MainLayout.class)
public class TimesheetView extends Main { public class TimesheetView extends Main {
} }

View File

@ -90,3 +90,6 @@ insert into time_off_request (id, version, employee_id, category, state, availab
values ('12ec8b74-983d-4a17-b67e-134f45ae904c', 1, '5c1a7b82-832d-4f24-8377-54b77b91b6a8', 'AÑO_NUEVO', 'SOLICITADO', 1, '2025-01-01', '2025-01-01', '2025-01-01', 1, 0); values ('12ec8b74-983d-4a17-b67e-134f45ae904c', 1, '5c1a7b82-832d-4f24-8377-54b77b91b6a8', 'AÑO_NUEVO', 'SOLICITADO', 1, '2025-01-01', '2025-01-01', '2025-01-01', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('89bc4b2a-943f-487c-a9f3-bacf78145e67', 1, 'cba3efb7-32bc-44be-9fdc-fc5e4f211254', 'LUNES_CARNAVAL', 'APROBADO', 1, '2024-02-12', '2024-02-12', '2024-02-12', 1, 0); values ('89bc4b2a-943f-487c-a9f3-bacf78145e67', 1, 'cba3efb7-32bc-44be-9fdc-fc5e4f211254', 'LUNES_CARNAVAL', 'APROBADO', 1, '2024-02-12', '2024-02-12', '2024-02-12', 1, 0);
INSERT INTO HOURS_WORKED (ID, VERSION, ACTIVIDAD, DATE, HORAS_TAREAS_ESPECIFICAS, HORASPENDIENTES, HOURS, TAREAS_ESPECIFICAS, TOTAL_HOURS, WEEK_NUMBER, EMPLOYEE_ID, TEAM_ID)
VALUES ('6d6b3a71-9b11-4526-8335-b089627a8cd6', 0, 'Scrum Meeting', '2024-11-15', 0.0, 0.0, 2.0, NULL, 0.0, 46, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'b0e8f394-78c1-4d8a-9c57-dc6e8b36a5fa');