http://gitea.jumapacelaya.gob.mx:3000/dbaylonv/Sistema_mantenimiento_correctivo_y_prffde Por alguna razon el repositorio local de este proyecto desaparecio
| @ -0,0 +1,22 @@ | |||||
| /target/ | |||||
| .idea/ | |||||
| .vscode/ | |||||
| .settings | |||||
| .project | |||||
| .classpath | |||||
| *.iml | |||||
| .DS_Store | |||||
| # The following files are generated/updated by vaadin-maven-plugin | |||||
| node_modules/ | |||||
| src/main/frontend/generated/ | |||||
| pnpmfile.js | |||||
| vite.generated.ts | |||||
| # Browser drivers for local integration tests | |||||
| drivers/ | |||||
| # Error screenshots generated by TestBench for failed integration tests | |||||
| error-screenshots/ | |||||
| webpack.generated.js | |||||
| /bin/ | |||||
| @ -0,0 +1,118 @@ | |||||
| /* | |||||
| * 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(); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| # 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 | |||||
| @ -0,0 +1,24 @@ | |||||
| This is free and unencumbered software released into the public domain. | |||||
| Anyone is free to copy, modify, publish, use, compile, sell, or | |||||
| distribute this software, either in source code form or as a compiled | |||||
| binary, for any purpose, commercial or non-commercial, and by any | |||||
| means. | |||||
| In jurisdictions that recognize copyright laws, the author or authors | |||||
| of this software dedicate any and all copyright interest in the | |||||
| software to the public domain. We make this dedication for the benefit | |||||
| of the public at large and to the detriment of our heirs and | |||||
| successors. We intend this dedication to be an overt act of | |||||
| relinquishment in perpetuity of all present and future rights to this | |||||
| software under copyright law. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||||
| IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||||
| ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||||
| OTHER DEALINGS IN THE SOFTWARE. | |||||
| For more information, please refer to <http://unlicense.org> | |||||
| @ -0,0 +1,45 @@ | |||||
| # Sistema de Mantenimiento | |||||
| This project can be used as a starting point to create your own Vaadin application with Spring Boot. | |||||
| It contains all the necessary configuration and some placeholder files to get you started. | |||||
| ## Running the application | |||||
| The project is a standard Maven project. To run it from the command line, | |||||
| type `mvnw` (Windows), or `./mvnw` (Mac & Linux), then open | |||||
| http://localhost:8080 in your browser. | |||||
| You can also import the project to your IDE of choice as you would with any | |||||
| Maven project. Read more on [how to import Vaadin projects to different IDEs](https://vaadin.com/docs/latest/guide/step-by-step/importing) (Eclipse, IntelliJ IDEA, NetBeans, and VS Code). | |||||
| ## Deploying to Production | |||||
| To create a production build, call `mvnw clean package -Pproduction` (Windows), | |||||
| or `./mvnw clean package -Pproduction` (Mac & Linux). | |||||
| This will build a JAR file with all the dependencies and front-end resources, | |||||
| ready to be deployed. The file can be found in the `target` folder after the build completes. | |||||
| Once the JAR file is built, you can run it using | |||||
| `java -jar target/sistema-mantenimiento-1.0-SNAPSHOT.jar` | |||||
| ## Project structure | |||||
| - `MainLayout.java` in `src/main/java` contains the navigation setup (i.e., the | |||||
| side/top bar and the main menu). This setup uses | |||||
| [App Layout](https://vaadin.com/docs/components/app-layout). | |||||
| - `views` package in `src/main/java` contains the server-side Java views of your application. | |||||
| - `views` folder in `src/main/frontend` contains the client-side JavaScript views of your application. | |||||
| - `themes` folder in `src/main/frontend` contains the custom CSS styles. | |||||
| ## Useful links | |||||
| - Read the documentation at [vaadin.com/docs](https://vaadin.com/docs). | |||||
| - Follow the tutorial at [vaadin.com/docs/latest/tutorial/overview](https://vaadin.com/docs/latest/tutorial/overview). | |||||
| - Create new projects at [start.vaadin.com](https://start.vaadin.com/). | |||||
| - Search UI components and their usage examples at [vaadin.com/docs/latest/components](https://vaadin.com/docs/latest/components). | |||||
| - View use case applications that demonstrate Vaadin capabilities at [vaadin.com/examples-and-demos](https://vaadin.com/examples-and-demos). | |||||
| - Build any UI without custom CSS by discovering Vaadin's set of [CSS utility classes](https://vaadin.com/docs/styling/lumo/utility-classes). | |||||
| - Find a collection of solutions to common use cases at [cookbook.vaadin.com](https://cookbook.vaadin.com/). | |||||
| - Find add-ons at [vaadin.com/directory](https://vaadin.com/directory). | |||||
| - Ask questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/vaadin) or join our [Discord channel](https://discord.gg/MYFq5RTbBn). | |||||
| - Report issues, create pull requests in [GitHub](https://github.com/vaadin). | |||||
| @ -0,0 +1,316 @@ | |||||
| #!/bin/sh | |||||
| # ---------------------------------------------------------------------------- | |||||
| # 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. | |||||
| # ---------------------------------------------------------------------------- | |||||
| # ---------------------------------------------------------------------------- | |||||
| # Maven Start Up Batch script | |||||
| # | |||||
| # Required ENV vars: | |||||
| # ------------------ | |||||
| # JAVA_HOME - location of a JDK home dir | |||||
| # | |||||
| # Optional ENV vars | |||||
| # ----------------- | |||||
| # M2_HOME - location of maven2's installed home dir | |||||
| # MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||||
| # e.g. to debug Maven itself, use | |||||
| # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||||
| # MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||||
| # ---------------------------------------------------------------------------- | |||||
| if [ -z "$MAVEN_SKIP_RC" ] ; then | |||||
| if [ -f /usr/local/etc/mavenrc ] ; then | |||||
| . /usr/local/etc/mavenrc | |||||
| fi | |||||
| if [ -f /etc/mavenrc ] ; then | |||||
| . /etc/mavenrc | |||||
| fi | |||||
| if [ -f "$HOME/.mavenrc" ] ; then | |||||
| . "$HOME/.mavenrc" | |||||
| fi | |||||
| fi | |||||
| # OS specific support. $var _must_ be set to either true or false. | |||||
| cygwin=false; | |||||
| darwin=false; | |||||
| mingw=false | |||||
| case "`uname`" in | |||||
| CYGWIN*) cygwin=true ;; | |||||
| MINGW*) mingw=true;; | |||||
| Darwin*) darwin=true | |||||
| # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home | |||||
| # See https://developer.apple.com/library/mac/qa/qa1170/_index.html | |||||
| if [ -z "$JAVA_HOME" ]; then | |||||
| if [ -x "/usr/libexec/java_home" ]; then | |||||
| export JAVA_HOME="`/usr/libexec/java_home`" | |||||
| else | |||||
| export JAVA_HOME="/Library/Java/Home" | |||||
| fi | |||||
| fi | |||||
| ;; | |||||
| esac | |||||
| if [ -z "$JAVA_HOME" ] ; then | |||||
| if [ -r /etc/gentoo-release ] ; then | |||||
| JAVA_HOME=`java-config --jre-home` | |||||
| fi | |||||
| fi | |||||
| if [ -z "$M2_HOME" ] ; then | |||||
| ## resolve links - $0 may be a link to maven's home | |||||
| PRG="$0" | |||||
| # need this for relative symlinks | |||||
| while [ -h "$PRG" ] ; do | |||||
| ls=`ls -ld "$PRG"` | |||||
| link=`expr "$ls" : '.*-> \(.*\)$'` | |||||
| if expr "$link" : '/.*' > /dev/null; then | |||||
| PRG="$link" | |||||
| else | |||||
| PRG="`dirname "$PRG"`/$link" | |||||
| fi | |||||
| done | |||||
| saveddir=`pwd` | |||||
| M2_HOME=`dirname "$PRG"`/.. | |||||
| # make it fully qualified | |||||
| M2_HOME=`cd "$M2_HOME" && pwd` | |||||
| cd "$saveddir" | |||||
| # echo Using m2 at $M2_HOME | |||||
| fi | |||||
| # For Cygwin, ensure paths are in UNIX format before anything is touched | |||||
| if $cygwin ; then | |||||
| [ -n "$M2_HOME" ] && | |||||
| M2_HOME=`cygpath --unix "$M2_HOME"` | |||||
| [ -n "$JAVA_HOME" ] && | |||||
| JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | |||||
| [ -n "$CLASSPATH" ] && | |||||
| CLASSPATH=`cygpath --path --unix "$CLASSPATH"` | |||||
| fi | |||||
| # For Mingw, ensure paths are in UNIX format before anything is touched | |||||
| if $mingw ; then | |||||
| [ -n "$M2_HOME" ] && | |||||
| M2_HOME="`(cd "$M2_HOME"; pwd)`" | |||||
| [ -n "$JAVA_HOME" ] && | |||||
| JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" | |||||
| fi | |||||
| if [ -z "$JAVA_HOME" ]; then | |||||
| javaExecutable="`which javac`" | |||||
| if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then | |||||
| # readlink(1) is not available as standard on Solaris 10. | |||||
| readLink=`which readlink` | |||||
| if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then | |||||
| if $darwin ; then | |||||
| javaHome="`dirname \"$javaExecutable\"`" | |||||
| javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" | |||||
| else | |||||
| javaExecutable="`readlink -f \"$javaExecutable\"`" | |||||
| fi | |||||
| javaHome="`dirname \"$javaExecutable\"`" | |||||
| javaHome=`expr "$javaHome" : '\(.*\)/bin'` | |||||
| JAVA_HOME="$javaHome" | |||||
| export JAVA_HOME | |||||
| fi | |||||
| fi | |||||
| fi | |||||
| if [ -z "$JAVACMD" ] ; then | |||||
| if [ -n "$JAVA_HOME" ] ; then | |||||
| if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |||||
| # IBM's JDK on AIX uses strange locations for the executables | |||||
| JAVACMD="$JAVA_HOME/jre/sh/java" | |||||
| else | |||||
| JAVACMD="$JAVA_HOME/bin/java" | |||||
| fi | |||||
| else | |||||
| JAVACMD="`\\unset -f command; \\command -v java`" | |||||
| fi | |||||
| fi | |||||
| if [ ! -x "$JAVACMD" ] ; then | |||||
| echo "Error: JAVA_HOME is not defined correctly." >&2 | |||||
| echo " We cannot execute $JAVACMD" >&2 | |||||
| exit 1 | |||||
| fi | |||||
| if [ -z "$JAVA_HOME" ] ; then | |||||
| echo "Warning: JAVA_HOME environment variable is not set." | |||||
| fi | |||||
| CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher | |||||
| # traverses directory structure from process work directory to filesystem root | |||||
| # first directory with .mvn subdirectory is considered project base directory | |||||
| find_maven_basedir() { | |||||
| if [ -z "$1" ] | |||||
| then | |||||
| echo "Path not specified to find_maven_basedir" | |||||
| return 1 | |||||
| fi | |||||
| basedir="$1" | |||||
| wdir="$1" | |||||
| while [ "$wdir" != '/' ] ; do | |||||
| if [ -d "$wdir"/.mvn ] ; then | |||||
| basedir=$wdir | |||||
| break | |||||
| fi | |||||
| # workaround for JBEAP-8937 (on Solaris 10/Sparc) | |||||
| if [ -d "${wdir}" ]; then | |||||
| wdir=`cd "$wdir/.."; pwd` | |||||
| fi | |||||
| # end of workaround | |||||
| done | |||||
| echo "${basedir}" | |||||
| } | |||||
| # concatenates all lines of a file | |||||
| concat_lines() { | |||||
| if [ -f "$1" ]; then | |||||
| echo "$(tr -s '\n' ' ' < "$1")" | |||||
| fi | |||||
| } | |||||
| BASE_DIR=`find_maven_basedir "$(pwd)"` | |||||
| if [ -z "$BASE_DIR" ]; then | |||||
| exit 1; | |||||
| fi | |||||
| ########################################################################################## | |||||
| # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||||
| # This allows using the maven wrapper in projects that prohibit checking in binary data. | |||||
| ########################################################################################## | |||||
| if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Found .mvn/wrapper/maven-wrapper.jar" | |||||
| fi | |||||
| else | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." | |||||
| fi | |||||
| if [ -n "$MVNW_REPOURL" ]; then | |||||
| jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||||
| else | |||||
| jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||||
| fi | |||||
| while IFS="=" read key value; do | |||||
| case "$key" in (wrapperUrl) jarUrl="$value"; break ;; | |||||
| esac | |||||
| done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Downloading from: $jarUrl" | |||||
| fi | |||||
| wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" | |||||
| if $cygwin; then | |||||
| wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` | |||||
| fi | |||||
| if command -v wget > /dev/null; then | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Found wget ... using wget" | |||||
| fi | |||||
| if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||||
| wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||||
| else | |||||
| wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |||||
| fi | |||||
| elif command -v curl > /dev/null; then | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Found curl ... using curl" | |||||
| fi | |||||
| if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |||||
| curl -o "$wrapperJarPath" "$jarUrl" -f | |||||
| else | |||||
| curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f | |||||
| fi | |||||
| else | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo "Falling back to using Java to download" | |||||
| fi | |||||
| javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" | |||||
| # For Cygwin, switch paths to Windows format before running javac | |||||
| if $cygwin; then | |||||
| javaClass=`cygpath --path --windows "$javaClass"` | |||||
| fi | |||||
| if [ -e "$javaClass" ]; then | |||||
| if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo " - Compiling MavenWrapperDownloader.java ..." | |||||
| fi | |||||
| # Compiling the Java class | |||||
| ("$JAVA_HOME/bin/javac" "$javaClass") | |||||
| fi | |||||
| if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then | |||||
| # Running the downloader | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo " - Running MavenWrapperDownloader.java ..." | |||||
| fi | |||||
| ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") | |||||
| fi | |||||
| fi | |||||
| fi | |||||
| fi | |||||
| ########################################################################################## | |||||
| # End of extension | |||||
| ########################################################################################## | |||||
| export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} | |||||
| if [ "$MVNW_VERBOSE" = true ]; then | |||||
| echo $MAVEN_PROJECTBASEDIR | |||||
| fi | |||||
| MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" | |||||
| # For Cygwin, switch paths to Windows format before running java | |||||
| if $cygwin; then | |||||
| [ -n "$M2_HOME" ] && | |||||
| M2_HOME=`cygpath --path --windows "$M2_HOME"` | |||||
| [ -n "$JAVA_HOME" ] && | |||||
| JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` | |||||
| [ -n "$CLASSPATH" ] && | |||||
| CLASSPATH=`cygpath --path --windows "$CLASSPATH"` | |||||
| [ -n "$MAVEN_PROJECTBASEDIR" ] && | |||||
| MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` | |||||
| fi | |||||
| # Provide a "standardized" way to retrieve the CLI args that will | |||||
| # work with both Windows and non-Windows executions. | |||||
| MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" | |||||
| export MAVEN_CMD_LINE_ARGS | |||||
| WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||||
| exec "$JAVACMD" \ | |||||
| $MAVEN_OPTS \ | |||||
| $MAVEN_DEBUG_OPTS \ | |||||
| -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ | |||||
| "-Dmaven.home=${M2_HOME}" \ | |||||
| "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ | |||||
| ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" | |||||
| @ -0,0 +1,188 @@ | |||||
| @REM ---------------------------------------------------------------------------- | |||||
| @REM Licensed to the Apache Software Foundation (ASF) under one | |||||
| @REM or more contributor license agreements. See the NOTICE file | |||||
| @REM distributed with this work for additional information | |||||
| @REM regarding copyright ownership. The ASF licenses this file | |||||
| @REM to you under the Apache License, Version 2.0 (the | |||||
| @REM "License"); you may not use this file except in compliance | |||||
| @REM with the License. You may obtain a copy of the License at | |||||
| @REM | |||||
| @REM http://www.apache.org/licenses/LICENSE-2.0 | |||||
| @REM | |||||
| @REM Unless required by applicable law or agreed to in writing, | |||||
| @REM software distributed under the License is distributed on an | |||||
| @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||||
| @REM KIND, either express or implied. See the License for the | |||||
| @REM specific language governing permissions and limitations | |||||
| @REM under the License. | |||||
| @REM ---------------------------------------------------------------------------- | |||||
| @REM ---------------------------------------------------------------------------- | |||||
| @REM Maven Start Up Batch script | |||||
| @REM | |||||
| @REM Required ENV vars: | |||||
| @REM JAVA_HOME - location of a JDK home dir | |||||
| @REM | |||||
| @REM Optional ENV vars | |||||
| @REM M2_HOME - location of maven2's installed home dir | |||||
| @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands | |||||
| @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending | |||||
| @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven | |||||
| @REM e.g. to debug Maven itself, use | |||||
| @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |||||
| @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |||||
| @REM ---------------------------------------------------------------------------- | |||||
| @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' | |||||
| @echo off | |||||
| @REM set title of command window | |||||
| title %0 | |||||
| @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' | |||||
| @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% | |||||
| @REM set %HOME% to equivalent of $HOME | |||||
| if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") | |||||
| @REM Execute a user defined script before this one | |||||
| if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre | |||||
| @REM check for pre script, once with legacy .bat ending and once with .cmd ending | |||||
| if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* | |||||
| if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* | |||||
| :skipRcPre | |||||
| @setlocal | |||||
| set ERROR_CODE=0 | |||||
| @REM To isolate internal variables from possible post scripts, we use another setlocal | |||||
| @setlocal | |||||
| @REM ==== START VALIDATION ==== | |||||
| if not "%JAVA_HOME%" == "" goto OkJHome | |||||
| echo. | |||||
| echo Error: JAVA_HOME not found in your environment. >&2 | |||||
| echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||||
| echo location of your Java installation. >&2 | |||||
| echo. | |||||
| goto error | |||||
| :OkJHome | |||||
| if exist "%JAVA_HOME%\bin\java.exe" goto init | |||||
| echo. | |||||
| echo Error: JAVA_HOME is set to an invalid directory. >&2 | |||||
| echo JAVA_HOME = "%JAVA_HOME%" >&2 | |||||
| echo Please set the JAVA_HOME variable in your environment to match the >&2 | |||||
| echo location of your Java installation. >&2 | |||||
| echo. | |||||
| goto error | |||||
| @REM ==== END VALIDATION ==== | |||||
| :init | |||||
| @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". | |||||
| @REM Fallback to current working directory if not found. | |||||
| set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% | |||||
| IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir | |||||
| set EXEC_DIR=%CD% | |||||
| set WDIR=%EXEC_DIR% | |||||
| :findBaseDir | |||||
| IF EXIST "%WDIR%"\.mvn goto baseDirFound | |||||
| cd .. | |||||
| IF "%WDIR%"=="%CD%" goto baseDirNotFound | |||||
| set WDIR=%CD% | |||||
| goto findBaseDir | |||||
| :baseDirFound | |||||
| set MAVEN_PROJECTBASEDIR=%WDIR% | |||||
| cd "%EXEC_DIR%" | |||||
| goto endDetectBaseDir | |||||
| :baseDirNotFound | |||||
| set MAVEN_PROJECTBASEDIR=%EXEC_DIR% | |||||
| cd "%EXEC_DIR%" | |||||
| :endDetectBaseDir | |||||
| IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig | |||||
| @setlocal EnableExtensions EnableDelayedExpansion | |||||
| for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a | |||||
| @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% | |||||
| :endReadAdditionalConfig | |||||
| SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" | |||||
| set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" | |||||
| set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |||||
| set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||||
| FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( | |||||
| IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B | |||||
| ) | |||||
| @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |||||
| @REM This allows using the maven wrapper in projects that prohibit checking in binary data. | |||||
| if exist %WRAPPER_JAR% ( | |||||
| if "%MVNW_VERBOSE%" == "true" ( | |||||
| echo Found %WRAPPER_JAR% | |||||
| ) | |||||
| ) else ( | |||||
| if not "%MVNW_REPOURL%" == "" ( | |||||
| SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" | |||||
| ) | |||||
| if "%MVNW_VERBOSE%" == "true" ( | |||||
| echo Couldn't find %WRAPPER_JAR%, downloading it ... | |||||
| echo Downloading from: %DOWNLOAD_URL% | |||||
| ) | |||||
| powershell -Command "&{"^ | |||||
| "$webclient = new-object System.Net.WebClient;"^ | |||||
| "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ | |||||
| "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ | |||||
| "}"^ | |||||
| "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ | |||||
| "}" | |||||
| if "%MVNW_VERBOSE%" == "true" ( | |||||
| echo Finished downloading %WRAPPER_JAR% | |||||
| ) | |||||
| ) | |||||
| @REM End of extension | |||||
| @REM Provide a "standardized" way to retrieve the CLI args that will | |||||
| @REM work with both Windows and non-Windows executions. | |||||
| set MAVEN_CMD_LINE_ARGS=%* | |||||
| %MAVEN_JAVA_EXE% ^ | |||||
| %JVM_CONFIG_MAVEN_PROPS% ^ | |||||
| %MAVEN_OPTS% ^ | |||||
| %MAVEN_DEBUG_OPTS% ^ | |||||
| -classpath %WRAPPER_JAR% ^ | |||||
| "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ | |||||
| %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* | |||||
| if ERRORLEVEL 1 goto error | |||||
| goto end | |||||
| :error | |||||
| set ERROR_CODE=1 | |||||
| :end | |||||
| @endlocal & set ERROR_CODE=%ERROR_CODE% | |||||
| if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost | |||||
| @REM check for post script, once with legacy .bat ending and once with .cmd ending | |||||
| if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" | |||||
| if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" | |||||
| :skipRcPost | |||||
| @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' | |||||
| if "%MAVEN_BATCH_PAUSE%"=="on" pause | |||||
| if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% | |||||
| cmd /C exit /B %ERROR_CODE% | |||||
| @ -0,0 +1,113 @@ | |||||
| { | |||||
| "name": "no-name", | |||||
| "license": "UNLICENSED", | |||||
| "type": "module", | |||||
| "dependencies": { | |||||
| "@polymer/polymer": "3.5.2", | |||||
| "@vaadin/bundles": "24.5.5", | |||||
| "@vaadin/common-frontend": "0.0.19", | |||||
| "@vaadin/polymer-legacy-adapter": "24.5.5", | |||||
| "@vaadin/react-components": "24.5.5", | |||||
| "@vaadin/react-components-pro": "24.5.5", | |||||
| "@vaadin/vaadin-development-mode-detector": "2.0.7", | |||||
| "@vaadin/vaadin-lumo-styles": "24.5.5", | |||||
| "@vaadin/vaadin-material-styles": "24.5.5", | |||||
| "@vaadin/vaadin-themable-mixin": "24.5.5", | |||||
| "@vaadin/vaadin-usage-statistics": "2.1.3", | |||||
| "construct-style-sheets-polyfill": "3.1.0", | |||||
| "date-fns": "2.29.3", | |||||
| "lit": "3.2.1", | |||||
| "proj4": "2.12.1", | |||||
| "react": "18.3.1", | |||||
| "react-dom": "18.3.1", | |||||
| "react-router-dom": "6.28.0", | |||||
| "signature_pad": "4.1.5" | |||||
| }, | |||||
| "devDependencies": { | |||||
| "@babel/preset-react": "7.26.3", | |||||
| "@preact/signals-react-transform": "0.4.0", | |||||
| "@rollup/plugin-replace": "6.0.1", | |||||
| "@rollup/pluginutils": "5.1.3", | |||||
| "@types/react": "18.3.13", | |||||
| "@types/react-dom": "18.3.1", | |||||
| "@vitejs/plugin-react": "4.3.3", | |||||
| "async": "3.2.6", | |||||
| "glob": "10.4.5", | |||||
| "rollup-plugin-brotli": "3.1.0", | |||||
| "rollup-plugin-visualizer": "5.12.0", | |||||
| "strip-css-comments": "5.0.0", | |||||
| "transform-ast": "2.4.4", | |||||
| "typescript": "5.6.3", | |||||
| "vite": "5.4.11", | |||||
| "vite-plugin-checker": "0.8.0", | |||||
| "workbox-build": "7.3.0", | |||||
| "workbox-core": "7.3.0", | |||||
| "workbox-precaching": "7.3.0" | |||||
| }, | |||||
| "vaadin": { | |||||
| "dependencies": { | |||||
| "@polymer/polymer": "3.5.2", | |||||
| "@vaadin/bundles": "24.5.5", | |||||
| "@vaadin/common-frontend": "0.0.19", | |||||
| "@vaadin/polymer-legacy-adapter": "24.5.5", | |||||
| "@vaadin/react-components": "24.5.5", | |||||
| "@vaadin/react-components-pro": "24.5.5", | |||||
| "@vaadin/vaadin-development-mode-detector": "2.0.7", | |||||
| "@vaadin/vaadin-lumo-styles": "24.5.5", | |||||
| "@vaadin/vaadin-material-styles": "24.5.5", | |||||
| "@vaadin/vaadin-themable-mixin": "24.5.5", | |||||
| "@vaadin/vaadin-usage-statistics": "2.1.3", | |||||
| "construct-style-sheets-polyfill": "3.1.0", | |||||
| "date-fns": "2.29.3", | |||||
| "lit": "3.2.1", | |||||
| "proj4": "2.12.1", | |||||
| "react": "18.3.1", | |||||
| "react-dom": "18.3.1", | |||||
| "react-router-dom": "6.28.0", | |||||
| "signature_pad": "4.1.5" | |||||
| }, | |||||
| "devDependencies": { | |||||
| "@babel/preset-react": "7.26.3", | |||||
| "@preact/signals-react-transform": "0.4.0", | |||||
| "@rollup/plugin-replace": "6.0.1", | |||||
| "@rollup/pluginutils": "5.1.3", | |||||
| "@types/react": "18.3.13", | |||||
| "@types/react-dom": "18.3.1", | |||||
| "@vitejs/plugin-react": "4.3.3", | |||||
| "async": "3.2.6", | |||||
| "glob": "10.4.5", | |||||
| "rollup-plugin-brotli": "3.1.0", | |||||
| "rollup-plugin-visualizer": "5.12.0", | |||||
| "strip-css-comments": "5.0.0", | |||||
| "transform-ast": "2.4.4", | |||||
| "typescript": "5.6.3", | |||||
| "vite": "5.4.11", | |||||
| "vite-plugin-checker": "0.8.0", | |||||
| "workbox-build": "7.3.0", | |||||
| "workbox-core": "7.3.0", | |||||
| "workbox-precaching": "7.3.0" | |||||
| }, | |||||
| "hash": "6126bd412c2a8696938f50edd1abae217c30c0119a0496af47b9d6ba1762921f" | |||||
| }, | |||||
| "overrides": { | |||||
| "@vaadin/bundles": "$@vaadin/bundles", | |||||
| "@vaadin/polymer-legacy-adapter": "$@vaadin/polymer-legacy-adapter", | |||||
| "@vaadin/vaadin-development-mode-detector": "$@vaadin/vaadin-development-mode-detector", | |||||
| "@vaadin/vaadin-usage-statistics": "$@vaadin/vaadin-usage-statistics", | |||||
| "@vaadin/react-components": "$@vaadin/react-components", | |||||
| "@vaadin/react-components-pro": "$@vaadin/react-components-pro", | |||||
| "@vaadin/common-frontend": "$@vaadin/common-frontend", | |||||
| "react-dom": "$react-dom", | |||||
| "construct-style-sheets-polyfill": "$construct-style-sheets-polyfill", | |||||
| "react-router-dom": "$react-router-dom", | |||||
| "lit": "$lit", | |||||
| "@polymer/polymer": "$@polymer/polymer", | |||||
| "react": "$react", | |||||
| "date-fns": "$date-fns", | |||||
| "proj4": "$proj4", | |||||
| "@vaadin/vaadin-themable-mixin": "$@vaadin/vaadin-themable-mixin", | |||||
| "@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles", | |||||
| "@vaadin/vaadin-material-styles": "$@vaadin/vaadin-material-styles", | |||||
| "signature_pad": "$signature_pad" | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,295 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||||
| <modelVersion>4.0.0</modelVersion> | |||||
| <!-- Project from https://start.vaadin.com/project/d0aaac74-a0be-4584-96f9-8bc2489b2c80 --> | |||||
| <groupId>mx.gob.jumapacelaya</groupId> | |||||
| <artifactId>sistema-mantenimiento</artifactId> | |||||
| <name>sistema-mantenimiento</name> | |||||
| <version>1.0-SNAPSHOT</version> | |||||
| <packaging>jar</packaging> | |||||
| <properties> | |||||
| <java.version>17</java.version> | |||||
| <vaadin.version>24.5.8</vaadin.version> | |||||
| </properties> | |||||
| <parent> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-parent</artifactId> | |||||
| <version>3.2.8</version> | |||||
| </parent> | |||||
| <repositories> | |||||
| <repository> | |||||
| <id>central</id> | |||||
| <url>https://repo.maven.apache.org/maven2</url> | |||||
| <releases> | |||||
| <enabled>true</enabled> | |||||
| </releases> | |||||
| <snapshots> | |||||
| <enabled>false</enabled> | |||||
| </snapshots> | |||||
| </repository> | |||||
| <repository> | |||||
| <id>Vaadin Directory</id> | |||||
| <url>https://maven.vaadin.com/vaadin-addons</url> | |||||
| <snapshots> | |||||
| <enabled>false</enabled> | |||||
| </snapshots> | |||||
| </repository> | |||||
| <repository> | |||||
| <id>oracle-public</id> | |||||
| <url>https://maven.oracle.com/public</url> | |||||
| </repository> | |||||
| </repositories> | |||||
| <dependencyManagement> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-bom</artifactId> | |||||
| <version>${vaadin.version}</version> | |||||
| <type>pom</type> | |||||
| <scope>import</scope> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| </dependencyManagement> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <!-- Replace artifactId with vaadin-core to use only free components --> | |||||
| <artifactId>vaadin</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-spring-boot-starter</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.parttio</groupId> | |||||
| <artifactId>line-awesome</artifactId> | |||||
| <version>2.0.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.h2database</groupId> | |||||
| <artifactId>h2</artifactId> | |||||
| <scope>runtime</scope> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <!-- Dependencia para utilizar JDBC en la Base de Datos --> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-jdbc</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <!-- Conector a base de datos Oracle--> | |||||
| <groupId>com.oracle.database.jdbc</groupId> | |||||
| <artifactId>ojdbc8</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>mysql</groupId> | |||||
| <artifactId>mysql-connector-java</artifactId> | |||||
| <version>8.0.33</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <!-- Dependencia para poder enviar correos --> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-mail</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-security</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-validation</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-devtools</artifactId> | |||||
| <optional>true</optional> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.security</groupId> | |||||
| <artifactId>spring-security-ldap</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-test</artifactId> | |||||
| <scope>test</scope> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-data-ldap</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.ldap</groupId> | |||||
| <artifactId>spring-ldap-core</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-testbench-junit5</artifactId> | |||||
| <scope>test</scope> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>de.f0rce.signaturepad</groupId> | |||||
| <artifactId>signature-widget</artifactId> | |||||
| <version>3.1.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.apache.poi</groupId> | |||||
| <artifactId>poi-ooxml</artifactId> | |||||
| <version>5.2.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>commons-io</groupId> | |||||
| <artifactId>commons-io</artifactId> | |||||
| <version>2.16.1</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>net.sf.jasperreports</groupId> | |||||
| <artifactId>jasperreports</artifactId> | |||||
| <version>7.0.3</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>net.sf.jasperreports</groupId> | |||||
| <artifactId>jasperreports-pdf</artifactId> | |||||
| <version>7.0.3</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.google.code.gson</groupId> | |||||
| <artifactId>gson</artifactId> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| <build> | |||||
| <defaultGoal>spring-boot:run</defaultGoal> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||||
| </plugin> | |||||
| <plugin> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-maven-plugin</artifactId> | |||||
| <version>${vaadin.version}</version> | |||||
| <executions> | |||||
| <execution> | |||||
| <goals> | |||||
| <goal>prepare-frontend</goal> | |||||
| </goals> | |||||
| </execution> | |||||
| </executions> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| <profiles> | |||||
| <profile> | |||||
| <!-- Production mode is activated using -Pproduction --> | |||||
| <id>production</id> | |||||
| <dependencies> | |||||
| <!-- Exclude development dependencies from production --> | |||||
| <dependency> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-core</artifactId> | |||||
| <exclusions> | |||||
| <exclusion> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-dev</artifactId> | |||||
| </exclusion> | |||||
| </exclusions> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>com.vaadin</groupId> | |||||
| <artifactId>vaadin-maven-plugin</artifactId> | |||||
| <version>${vaadin.version}</version> | |||||
| <executions> | |||||
| <execution> | |||||
| <goals> | |||||
| <goal>build-frontend</goal> | |||||
| </goals> | |||||
| <phase>compile</phase> | |||||
| </execution> | |||||
| </executions> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </profile> | |||||
| <profile> | |||||
| <id>it</id> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||||
| <executions> | |||||
| <execution> | |||||
| <id>start-spring-boot</id> | |||||
| <phase>pre-integration-test</phase> | |||||
| <goals> | |||||
| <goal>start</goal> | |||||
| </goals> | |||||
| </execution> | |||||
| <execution> | |||||
| <id>stop-spring-boot</id> | |||||
| <phase>post-integration-test</phase> | |||||
| <goals> | |||||
| <goal>stop</goal> | |||||
| </goals> | |||||
| </execution> | |||||
| </executions> | |||||
| </plugin> | |||||
| <!-- Runs the integration tests (*IT) after the server is started --> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-failsafe-plugin</artifactId> | |||||
| <executions> | |||||
| <execution> | |||||
| <goals> | |||||
| <goal>integration-test</goal> | |||||
| <goal>verify</goal> | |||||
| </goals> | |||||
| </execution> | |||||
| </executions> | |||||
| <configuration> | |||||
| <trimStackTrace>false</trimStackTrace> | |||||
| <enableAssertions>true</enableAssertions> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </profile> | |||||
| </profiles> | |||||
| </project> | |||||
| @ -0,0 +1,32 @@ | |||||
| This directory is automatically generated by Vaadin and contains the pre-compiled | |||||
| frontend files/resources for your project (frontend development bundle). | |||||
| It should be added to Version Control System and committed, so that other developers | |||||
| do not have to compile it again. | |||||
| Frontend development bundle is automatically updated when needed: | |||||
| - an npm/pnpm package is added with @NpmPackage or directly into package.json | |||||
| - CSS, JavaScript or TypeScript files are added with @CssImport, @JsModule or @JavaScript | |||||
| - Vaadin add-on with front-end customizations is added | |||||
| - Custom theme imports/assets added into 'theme.json' file | |||||
| - Exported web component is added. | |||||
| If your project development needs a hot deployment of the frontend changes, | |||||
| you can switch Flow to use Vite development server (default in Vaadin 23.3 and earlier versions): | |||||
| - set `vaadin.frontend.hotdeploy=true` in `application.properties` | |||||
| - configure `vaadin-maven-plugin`: | |||||
| ``` | |||||
| <configuration> | |||||
| <frontendHotdeploy>true</frontendHotdeploy> | |||||
| </configuration> | |||||
| ``` | |||||
| - configure `jetty-maven-plugin`: | |||||
| ``` | |||||
| <configuration> | |||||
| <systemProperties> | |||||
| <vaadin.frontend.hotdeploy>true</vaadin.frontend.hotdeploy> | |||||
| </systemProperties> | |||||
| </configuration> | |||||
| ``` | |||||
| Read more [about Vaadin development mode](https://vaadin.com/docs/next/flow/configuration/development-mode#precompiled-bundle). | |||||
| @ -0,0 +1,23 @@ | |||||
| <!DOCTYPE html> | |||||
| <!-- | |||||
| This file is auto-generated by Vaadin. | |||||
| --> | |||||
| <html> | |||||
| <head> | |||||
| <meta charset="UTF-8" /> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |||||
| <style> | |||||
| body, #outlet { | |||||
| height: 100vh; | |||||
| width: 100%; | |||||
| margin: 0; | |||||
| } | |||||
| </style> | |||||
| <!-- index.ts is included here automatically (either by the dev server or during the build) --> | |||||
| </head> | |||||
| <body> | |||||
| <!-- This outlet div is where the views are rendered --> | |||||
| <div id="outlet"></div> | |||||
| </body> | |||||
| </html> | |||||
| @ -0,0 +1,20 @@ | |||||
| vaadin-scroller[slot="drawer"] { | |||||
| padding: var(--lumo-space-s); | |||||
| } | |||||
| vaadin-side-nav-item vaadin-icon { | |||||
| padding: 0; | |||||
| } | |||||
| [slot="drawer"]:is(header, footer) { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| gap: var(--lumo-space-s); | |||||
| padding: var(--lumo-space-s) var(--lumo-space-m); | |||||
| min-height: var(--lumo-size-xl); | |||||
| box-sizing: border-box; | |||||
| } | |||||
| [slot="drawer"]:is(header, footer):is(:empty) { | |||||
| display: none; | |||||
| } | |||||
| @ -0,0 +1,294 @@ | |||||
| @import url('./main-layout.css'); | |||||
| /* ----------- Estilos para el MainLayout.java ----------- */ | |||||
| /* Estilos para el DrawerToggle*/ | |||||
| .drawer-toggle { | |||||
| background-color: #bc955b; | |||||
| } | |||||
| /* Estilos para el encabezado */ | |||||
| .header-content { | |||||
| height: 64px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| width: 100%; | |||||
| } | |||||
| /* Estilo para el boton de cerrar sesion */ | |||||
| .logout-button { | |||||
| margin-right: 30px; | |||||
| } | |||||
| /* Estilos para el drawer */ | |||||
| .drawer-logo { | |||||
| width: 300px; | |||||
| } | |||||
| /* Estilos para el fondo de la aplicacion */ | |||||
| .app-layout { | |||||
| background-image: url('/images/bckgndNvo.png'); | |||||
| background-size: cover; | |||||
| background-position: center; | |||||
| background-repeat: no-repeat; | |||||
| } | |||||
| /* ------------------ FIN -------------------------------------- */ | |||||
| /* | |||||
| /* | |||||
| */ | |||||
| /*!--------------------- Estilos para MantenimientosView.java ------------------- */ | |||||
| /* Estilo para el fondo del header */ | |||||
| .plan-anual-header { | |||||
| background-color: #a02142; | |||||
| padding: 0; | |||||
| } | |||||
| /* Estilo para el titulo */ | |||||
| .plan-anual-titulo { | |||||
| text-align: center; | |||||
| font-size: 24px; | |||||
| color: #ddc9a3; | |||||
| } | |||||
| /* Estilo para el subtitulo */ | |||||
| .plan-anual-titulo1 { | |||||
| text-align: center; | |||||
| font-size: 18px; | |||||
| color: #ddc9a3; | |||||
| } | |||||
| /* Estilo para el campo de texto nomenclatura */ | |||||
| .nomenclatura-txt { | |||||
| margin-top: 15px; | |||||
| margin-right: 15px; | |||||
| } | |||||
| /* Estilo para el logo CELAYA */ | |||||
| .celaya-logo { | |||||
| width: 100px; | |||||
| margin-left: 15px; | |||||
| margin-top: 15px; | |||||
| } | |||||
| /* ------------------------ FIN -------------------------- */ | |||||
| /* | |||||
| /* | |||||
| */ | |||||
| /* --------------- Estilos para la vista de ActDiaria.java -------------- */ | |||||
| /* Estilo para el header */ | |||||
| .act-diaria-header { | |||||
| background-color: #3E8BEA; | |||||
| padding: 10px; | |||||
| } | |||||
| /* Estilo para el titulo */ | |||||
| .act-diaria-titulo { | |||||
| color: white; | |||||
| font-size: 24px; | |||||
| text-align: center; | |||||
| } | |||||
| /* Estilo para el grid */ | |||||
| .act-diaria-grid { | |||||
| margin-top: 20px; | |||||
| } | |||||
| /* ---------------------------- FIN------------------------ */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* Estilos especificos para el TextField, TextArea y Fecha*/ | |||||
| vaadin-text-field::part(label), vaadin-text-area::part(label), vaadin-date-picker::part(label) { | |||||
| color: #691b31; /* Color de la etiqueta */ | |||||
| } | |||||
| vaadin-text-field::part(input-field), vaadin-text-area::part(input-field), vaadin-password-field::part(input-field), | |||||
| vaadin-number-field::part(input-field), vaadin-date-picker::part(input-field) { | |||||
| border: 1px solid #691b31; /* Color del borde */ | |||||
| color: #691b31; /* Color del texto */ | |||||
| } | |||||
| vaadin-month-calendar::part(date) { | |||||
| color: #691b31; /* Color para los dias del calendario */ | |||||
| } | |||||
| vaadin-month-calendar::part(date):hover /* Estilos para cuando se posiciona el puntero sobre el dia */{ | |||||
| background-color: #a02142; | |||||
| opacity: 50%; | |||||
| border-radius: 5px; | |||||
| } | |||||
| vaadin-month-calendar::part(date focused) { | |||||
| background-color: #ddc9a3; /* Color de la fecha seleccionada */ | |||||
| } | |||||
| vaadin-date-picker-overlay-content > vaadin-button, vaadin-date-picker-year::part(year-number) { | |||||
| color: #691b31; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* Estilos específicos para el Upload */ | |||||
| vaadin-upload > vaadin-button { | |||||
| color: #691b31; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* Estilos específicos para el ComboBox */ | |||||
| vaadin-combo-box::part(input-field) { | |||||
| background-color: #ddc9a3; /* Color de fondo */ | |||||
| color: #691b31; /* Color del texto */ | |||||
| border: 1px solid #691b31; /* Color del borde */ | |||||
| } | |||||
| vaadin-combo-box::part(label) { | |||||
| color: #691b31; /* Color de las etiquetas */ | |||||
| } | |||||
| vaadin-combo-box::part(dropdown) { | |||||
| background-color: rgba(221, 201, 163, 1); /* Color del fondo del dropdown */ | |||||
| } | |||||
| vaadin-combo-box-item::part(checkmark)::before, vaadin-combo-box-item:hover | |||||
| { | |||||
| color: #691b31; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) INDICADOR DE CARGA DE LA APLICACION (*)(*) (*)(*) */ | |||||
| .v-loading-indicator { /* Cambiar el color de la barra de carga que sale cuando la aplicacion esta cargando */ | |||||
| background: #691b31 !important; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) ESTILOS PARA LA SIDEBAR (*)(*) (*)(*) */ | |||||
| vaadin-side-nav-item[aria-current="page"]::part(content) { | |||||
| color: #691b31; /* Color de texto seleccionado */ | |||||
| } | |||||
| vaadin-side-nav-item:hover::part(content) { | |||||
| background-color: #ddc9a3; /* Color de fondo al hacer hover*/ | |||||
| fill-opacity: 50%; | |||||
| border-radius: 5px; | |||||
| } | |||||
| vaadin-side-nav-item::part(content) { | |||||
| color: #a02142; /* Color del texto deseado */ | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /*Estilos especificos para el Grid */ | |||||
| vaadin-grid::part(selected-row-cell) { | |||||
| background-color: #ddc9a3; | |||||
| opacity: 100%; | |||||
| } | |||||
| vaadin-grid::part(selected-row) { | |||||
| color: #691b31; | |||||
| font-weight: bold; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /*Estilos especificos para los botones */ | |||||
| vaadin-button[theme~="primary"] { | |||||
| background-color: #691b31; | |||||
| } | |||||
| vaadin-button:not([theme]) { | |||||
| color: #a02142; | |||||
| } | |||||
| vaadin-button[theme~="tertiary-inline"], vaadin-button[theme~="icon"] { | |||||
| color: #a02142; | |||||
| } | |||||
| /* Estilos para el theme personalizado 'subir-archivo' */ | |||||
| vaadin-button[theme~="subir-archivo"] { | |||||
| background-color: #691b31; | |||||
| color: #ffffff; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /*Estilos especificos para los CheckBox y RadioButtons */ | |||||
| vaadin-checkbox[checked]::part(checkbox) { | |||||
| background-color: #691b31; /* Cambia el color del CheckBox */ | |||||
| } | |||||
| vaadin-checkbox-group::part(label), vaadin-radio-group::part(label) { | |||||
| color: #691b31; | |||||
| } | |||||
| vaadin-radio-button[checked]::part(radio) { | |||||
| background-color: #691b31; | |||||
| } | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) (*)(*) */ | |||||
| /* Estilo especificos para el login form */ | |||||
| vaadin-login-form.special, vaadin-login-form.special::part(container) { | |||||
| background-color: rgba(105, 27, 49, 0.8); | |||||
| border-radius: 30px; | |||||
| } | |||||
| vaadin-login-form-wrapper { | |||||
| background-color: rgba(221, 201, 163, 1); | |||||
| border-radius: 30px; | |||||
| } | |||||
| /*letras de los label*/ | |||||
| vaadin-login-form-wrapper ::part(label) { | |||||
| color: #6f7271; | |||||
| /*transform: scale(1.2);*/ | |||||
| } | |||||
| vaadin-login-form vaadin-button[theme~="submit"] { | |||||
| background-color: #691b31; | |||||
| } | |||||
| vaadin-login-form-wrapper::part(form-title) { | |||||
| color: #691b31; | |||||
| } | |||||
| vaadin-login-form-wrapper::part(error-message) { | |||||
| color: #a02142; | |||||
| } | |||||
| vaadin-popover-overlay::part(overlay) { | |||||
| border-radius: 12px; | |||||
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); | |||||
| } | |||||
| @media (max-width: 900px) { | |||||
| .v-horizontallayout { | |||||
| flex-direction: column !important; | |||||
| align-items: stretch !important; | |||||
| } | |||||
| .mantenimiento-text-field, | |||||
| .mantenimiento-combo, | |||||
| vaadin-text-field, | |||||
| vaadin-combo-box { | |||||
| min-width: 0; | |||||
| width: 100% !important; | |||||
| box-sizing: border-box; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,3 @@ | |||||
| { | |||||
| "lumoImports" : [ "typography", "color", "spacing", "badge", "utility" ] | |||||
| } | |||||
| @ -0,0 +1,28 @@ | |||||
| package mx.gob.jumapacelaya; | |||||
| import com.vaadin.flow.component.page.AppShellConfigurator; | |||||
| import com.vaadin.flow.server.PWA; | |||||
| import com.vaadin.flow.theme.Theme; | |||||
| import mx.gob.jumapacelaya.services.DatabaseService; | |||||
| import org.springframework.boot.SpringApplication; | |||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
| import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; | |||||
| import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; | |||||
| /** | |||||
| * The entry point of the Spring Boot application. | |||||
| * | |||||
| * Use the @PWA annotation make the application installable on phones, tablets | |||||
| * and some desktop browsers. | |||||
| * | |||||
| */ | |||||
| @SpringBootApplication | |||||
| @Theme(value = "sistema-mantenimiento") | |||||
| @PWA(name = "Aplicacion de Mantenimiento de Equipo de Computo", shortName = "Mantenimiento de Computo", iconPath = "icons/icon.png") | |||||
| public class Application implements AppShellConfigurator { | |||||
| public static void main(String[] args) { | |||||
| SpringApplication.run(Application.class, args); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,337 @@ | |||||
| package mx.gob.jumapacelaya.api; | |||||
| import com.google.gson.*; | |||||
| import mx.gob.jumapacelaya.models.RedmineUser; | |||||
| import mx.gob.jumapacelaya.models.Ticket; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.stereotype.Component; | |||||
| import java.io.IOException; | |||||
| import java.net.URI; | |||||
| import java.net.http.HttpClient; | |||||
| import java.net.http.HttpRequest; | |||||
| import java.net.http.HttpResponse; | |||||
| import java.time.LocalDate; | |||||
| import java.time.format.DateTimeFormatter; | |||||
| import java.time.format.DateTimeParseException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| @Component | |||||
| public class RedmineClient { | |||||
| private static final int PAGE_SIZE = 25; | |||||
| static String REDMINE_URL; | |||||
| static String API_KEY; | |||||
| public static final Gson GSON = new Gson(); | |||||
| public RedmineClient(@Value("${redmine.url}") String redmineUrl, @Value("${redmine.api_key}") String apiKey) { | |||||
| REDMINE_URL = redmineUrl; | |||||
| API_KEY = apiKey; | |||||
| } | |||||
| //AQUI OBTENGO LOS TICKETS DESDE REDMINE | |||||
| public List<Ticket> getTickets(RedmineUser user, boolean includeClosed) { | |||||
| List<Ticket> tickets = new ArrayList<>(); | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| int offset = 0; | |||||
| // Si includeClose es true, incluira todos los tikets si no, incluira solo los que estan abiertos | |||||
| String statusFilter = includeClosed ? "&status_id=*" : "&status_id=open"; | |||||
| while (true) { | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + statusFilter + "&offset=" + offset)) | |||||
| .header("Content-Type", "application/json") | |||||
| .build(); | |||||
| try { | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| if (response.statusCode() == 200) { | |||||
| String responseBody = response.body(); | |||||
| List<Ticket> pageTickets = parseTickets(responseBody); | |||||
| tickets.addAll(pageTickets); | |||||
| if (pageTickets.size() < PAGE_SIZE) { | |||||
| break; | |||||
| } | |||||
| offset += PAGE_SIZE; | |||||
| } else { | |||||
| System.err.println("Error en la respuesta: " + response.statusCode()); | |||||
| break; | |||||
| } | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| break; | |||||
| } | |||||
| } | |||||
| System.out.println("Total tickets obtenidos: " + tickets.size()); | |||||
| return tickets; | |||||
| } | |||||
| //AQUI OBTENGO LOS TICKETS DESDE REDMINE | |||||
| public List<Ticket> getTicketsAuthor(RedmineUser user, boolean includeClosed) { | |||||
| List<Ticket> tickets = new ArrayList<>(); | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| int offset = 0; | |||||
| // Si includeClose es true, incluira todos los tikets si no, incluira solo los que estan abiertos | |||||
| String statusFilter = includeClosed ? "&status_id=*" : "&status_id=open"; | |||||
| while (true) { | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + "&author_id=" + user.getId() + statusFilter + "&offset=" + offset)) | |||||
| .header("Content-Type", "application/json") | |||||
| .build(); | |||||
| try { | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| if (response.statusCode() == 200) { | |||||
| String responseBody = response.body(); | |||||
| List<Ticket> pageTickets = parseTickets(responseBody); | |||||
| tickets.addAll(pageTickets); | |||||
| if (pageTickets.size() < PAGE_SIZE) { | |||||
| break; | |||||
| } | |||||
| offset += PAGE_SIZE; | |||||
| } else { | |||||
| System.err.println("Error en la respuesta: " + response.statusCode()); | |||||
| break; | |||||
| } | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| break; | |||||
| } | |||||
| } | |||||
| System.out.println("Total tickets obtenidos: " + tickets.size()); | |||||
| return tickets; | |||||
| } | |||||
| // Aquí se parsean todos los tickets que existen y se les da un formato con los campos a mostrarse | |||||
| private List<Ticket> parseTickets(String json) { | |||||
| List<Ticket> tickets = new ArrayList<>(); | |||||
| try { | |||||
| JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||||
| JsonArray issues = jsonObject.getAsJsonArray("issues"); | |||||
| if (issues != null) { | |||||
| for (JsonElement issueElement : issues) { | |||||
| JsonObject issue = issueElement.getAsJsonObject(); | |||||
| // Verifica y obtiene el ID | |||||
| int id = issue.has("id") && !issue.get("id").isJsonNull() ? issue.get("id").getAsInt() : 0; | |||||
| // Verifica y obtiene el subject | |||||
| String subject = issue.has("subject") && !issue.get("subject").isJsonNull() ? issue.get("subject").getAsString() : ""; | |||||
| // Verifica y obtiene la descripción | |||||
| String description = issue.has("description") && !issue.get("description").isJsonNull() ? issue.get("description").getAsString() : ""; | |||||
| // Verifica y obtiene el status | |||||
| String status = "Unknown"; | |||||
| if (issue.has("status") && !issue.get("status").isJsonNull()) { | |||||
| JsonObject statusObject = issue.getAsJsonObject("status"); | |||||
| if (statusObject.has("name") && !statusObject.get("name").isJsonNull()) { | |||||
| status = statusObject.get("name").getAsString(); | |||||
| } | |||||
| } | |||||
| // Verifica y obtiene la fecha de creación | |||||
| String dateString = issue.has("created_on") && !issue.get("created_on").isJsonNull() ? issue.get("created_on").getAsString() : ""; | |||||
| LocalDate dateCreate = null; | |||||
| if (!dateString.isEmpty()) { | |||||
| try { | |||||
| DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; | |||||
| dateCreate = LocalDate.parse(dateString, formatter); | |||||
| } catch (DateTimeParseException e) { | |||||
| System.err.println("Error al parsear la fecha: " + dateString); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| // Verifica y obtiene la fecha de cierre | |||||
| String closeDateString = issue.has("closed_on") && !issue.get("closed_on").isJsonNull() ? issue.get("closed_on").getAsString() : ""; | |||||
| LocalDate dateClose = null; | |||||
| if (!closeDateString.isEmpty()) { | |||||
| try { | |||||
| DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; | |||||
| dateClose = LocalDate.parse(closeDateString, formatter); | |||||
| } catch (DateTimeParseException e) { | |||||
| System.err.println("Error al parsear la fecha de cierre: " + closeDateString); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| //Verifica y obtiene el ID del tipo de ticket | |||||
| Integer trackerId = null; | |||||
| if (issue.has("tracker") && !issue.get("tracker").isJsonNull()) { | |||||
| JsonObject trackerObject = issue.getAsJsonObject("tracker"); | |||||
| if (trackerObject.has("id") && !trackerObject.get("id").isJsonNull()) { | |||||
| trackerId = trackerObject.get("id").getAsInt(); | |||||
| } | |||||
| } | |||||
| // Agrega el ticket a la lista | |||||
| tickets.add(new Ticket(id, subject, description, status, | |||||
| dateCreate != null ? dateCreate.toString() : "", | |||||
| dateClose != null ? dateClose.toString() : "", | |||||
| trackerId, "Tipo Desconocido")); | |||||
| } | |||||
| } else { | |||||
| System.out.println("La respuesta JSON no contiene la clave 'issues'"); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| System.out.println("Ocurrió un error al parsear los tickets: " + e.getMessage()); | |||||
| } | |||||
| return tickets; | |||||
| } | |||||
| public RedmineUser getMyAccount(String username) { | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/my/account.json")) | |||||
| .header("Content-Type", "application/json") | |||||
| .header("X-Redmine-Switch-User", username) | |||||
| .header("X-Redmine-API-Key", API_KEY) | |||||
| .GET() | |||||
| .build(); | |||||
| try { | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); | |||||
| JsonObject userJson = jsonObject.get("user").getAsJsonObject(); | |||||
| RedmineUser user = new RedmineUser(); | |||||
| user.setId(userJson.get("id").getAsInt()); | |||||
| user.setLogin(userJson.get("login").getAsString()); | |||||
| user.setFirstname(userJson.get("firstname").getAsString()); | |||||
| user.setLastname(userJson.get("lastname").getAsString()); | |||||
| user.setMail(userJson.get("mail").getAsString()); | |||||
| user.setKey(userJson.get("api_key").getAsString()); | |||||
| return user; | |||||
| //return response.body(); | |||||
| } catch (IOException | InterruptedException e) { | |||||
| e.printStackTrace(); | |||||
| return null; | |||||
| } | |||||
| } | |||||
| public static RedmineUser createRedmineUser(String username, String firstname, String lastname, String mail) { | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| Map<String, Object> user = new HashMap<>(); | |||||
| user.put("login", username); | |||||
| user.put("firstname", firstname); | |||||
| user.put("lastname", lastname); | |||||
| user.put("mail", mail); | |||||
| user.put("auth_source_id", "1"); | |||||
| Map<String, Object> payload = new HashMap<>(); | |||||
| payload.put("user", user); | |||||
| String jsonPayload = new Gson().toJson(payload); | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/users.json")) | |||||
| .header("Content-Type", "application/json") | |||||
| .header("X-Redmine-API-Key", API_KEY) | |||||
| .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) | |||||
| .build(); | |||||
| try { | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); | |||||
| JsonObject userJson = jsonObject.get("user").getAsJsonObject(); | |||||
| RedmineUser newUser = new RedmineUser(); | |||||
| newUser.setId(userJson.get("id").getAsInt()); | |||||
| newUser.setLogin(userJson.get("login").getAsString()); | |||||
| newUser.setFirstname(userJson.get("firstname").getAsString()); | |||||
| newUser.setLastname(userJson.get("lastname").getAsString()); | |||||
| newUser.setMail(userJson.get("mail").getAsString()); | |||||
| return newUser; | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| return null; | |||||
| } | |||||
| } | |||||
| //AQUI OBTENGO A LOS USUARIOS | |||||
| //Se devuelven en formato Json | |||||
| public RedmineUser getUserByUsername(String username) { | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/users.json?name=" + username )) | |||||
| .header("Content-Type", "application/json") | |||||
| .header("X-Redmine-API-Key", API_KEY) | |||||
| .build(); | |||||
| try { | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| if (response.statusCode() == 200) { | |||||
| String responseBody = response.body(); | |||||
| System.out.println("Datos del usuario " + responseBody); | |||||
| return parseUser(responseBody); | |||||
| } else { | |||||
| System.err.println("Error en la respuesta: " + response.statusCode()); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| //Aqui se parsean a los usuarios y se les da un formato con los campos a mostrarse | |||||
| private RedmineUser parseUser(String json) { | |||||
| JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||||
| JsonObject userJson = jsonObject.getAsJsonArray("users").get(0).getAsJsonObject(); | |||||
| RedmineUser user = new RedmineUser(); | |||||
| user.setId(userJson.get("id").getAsInt()); | |||||
| user.setLogin(userJson.get("login").getAsString()); | |||||
| user.setFirstname(userJson.get("firstname").getAsString()); | |||||
| user.setLastname(userJson.get("lastname").getAsString()); | |||||
| user.setMail(userJson.get("mail").getAsString()); | |||||
| //user.setKey(userJson.get("key").getAsString()); | |||||
| return user; | |||||
| } | |||||
| /*Este metodo sirve para actualizar el estatus de los tickets | |||||
| en este caso se actualiza al estatus TERMINADO */ | |||||
| public void closeTicket(int ticketId, RedmineUser user) throws IOException, InterruptedException { | |||||
| int closedStatusId = 5; //este es el ID del estado TERMINADO, se debe poner el id a según corresponda | |||||
| Map<String, Object> payload = new HashMap<>(); | |||||
| Map<String, Object> issue = new HashMap<>(); | |||||
| issue.put("status_id", closedStatusId); | |||||
| payload.put("issue", issue); | |||||
| String jsonPayload = GSON.toJson(payload); | |||||
| HttpRequest request = HttpRequest.newBuilder() | |||||
| .uri(URI.create(REDMINE_URL + "/issues/" + ticketId + ".json?key=" + user.getKey())) | |||||
| .header("Content-Type", "application/json") | |||||
| .PUT(HttpRequest.BodyPublishers.ofString(jsonPayload)) | |||||
| .build(); | |||||
| HttpClient client = HttpClient.newHttpClient(); | |||||
| HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||||
| if (response.statusCode() == 204) { | |||||
| String responseBody = response.body(); | |||||
| System.out.println("Ticket " + ticketId + " cerrado correctamente."); | |||||
| } else { | |||||
| System.err.println("Error al cerrar el ticket: " + response.statusCode()); | |||||
| System.err.println(response.body()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1 @@ | |||||
| package mx.gob.jumapacelaya.api; | |||||
| @ -0,0 +1,13 @@ | |||||
| package mx.gob.jumapacelaya.api; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.stereotype.Component; | |||||
| @Component | |||||
| public class ServerProperties { | |||||
| @Value("${redmine.url}") | |||||
| public String REDMINE_URL; | |||||
| @Value("${redmine.api_key}") | |||||
| public String API_KEY; | |||||
| } | |||||
| @ -0,0 +1,94 @@ | |||||
| package mx.gob.jumapacelaya.controller; | |||||
| import com.vaadin.flow.spring.security.VaadinWebSecurity; | |||||
| import mx.gob.jumapacelaya.ui.login.LoginView; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.http.HttpMethod; | |||||
| import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | |||||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | |||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | |||||
| import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider; | |||||
| import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | |||||
| import org.springframework.ldap.core.support.LdapContextSource; | |||||
| @EnableWebSecurity | |||||
| @Configuration | |||||
| public class SecurityConfiguration extends VaadinWebSecurity { | |||||
| @Override | |||||
| protected void configure(HttpSecurity http) throws Exception { | |||||
| http.authorizeHttpRequests(auth -> auth | |||||
| .requestMatchers( | |||||
| AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/icons/*.png"), | |||||
| AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/images/*.png") | |||||
| ).permitAll() | |||||
| .requestMatchers( | |||||
| AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login*") | |||||
| ).permitAll() | |||||
| ); | |||||
| super.configure(http); | |||||
| setLoginView(http, LoginView.class); | |||||
| } | |||||
| // !Esta es la real autenticacion con ldap | |||||
| @Autowired | |||||
| public void configure(AuthenticationManagerBuilder auth) throws Exception { | |||||
| ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("JUMAPACELAYA.GOB.MX", "ldap://172.16.0.1"); | |||||
| provider.setConvertSubErrorCodesToExceptions(true); | |||||
| provider.setUseAuthenticationRequestCredentials(true); | |||||
| auth.authenticationProvider(provider); | |||||
| } | |||||
| // !Autenticacion local solo para que lo vea el departamento de calidad | |||||
| /*@Autowired | |||||
| public void configure(AuthenticationManagerBuilder auth) throws Exception { | |||||
| // Configura la autenticación en memoria con un usuario local | |||||
| auth.inMemoryAuthentication() | |||||
| .withUser("admin") | |||||
| .password("{noop}admin") // {noop} indica que la contraseña no está cifrada (solo para pruebas) | |||||
| .roles("ADMIN") | |||||
| .and() | |||||
| .withUser("jlermal") | |||||
| .password("{noop}Temporal1") | |||||
| .roles("USER") | |||||
| .and() | |||||
| .withUser("mramirezg") | |||||
| .password("{noop}Temporal1") | |||||
| .roles("ADMIN"); | |||||
| }*/ | |||||
| @Value("${spring.ldap.urls}") | |||||
| private String ldapUrls; | |||||
| @Value("${spring.ldap.base}") | |||||
| private String ldapBase; | |||||
| @Value("${spring.ldap.password}") | |||||
| private String ldapPassword; | |||||
| @Bean | |||||
| public LdapContextSource ldapContextSource() { | |||||
| LdapContextSource contextSource = new LdapContextSource(); | |||||
| contextSource.setUrl(ldapUrls); | |||||
| contextSource.setBase(ldapBase); | |||||
| contextSource.setUserDn("administrator"); | |||||
| contextSource.setPassword(ldapPassword); | |||||
| contextSource.setPooled(true); | |||||
| contextSource.setReferral("follow"); | |||||
| return contextSource; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,31 @@ | |||||
| package mx.gob.jumapacelaya.datasource; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.annotation.Qualifier; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| import org.springframework.boot.jdbc.DataSourceBuilder; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.context.annotation.Primary; | |||||
| import org.springframework.jdbc.core.JdbcTemplate; | |||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | |||||
| import javax.sql.DataSource; | |||||
| @Configuration | |||||
| public class MysqlDataSource { | |||||
| @Bean(name= "mysqlDB") | |||||
| @Primary | |||||
| @ConfigurationProperties(prefix = "spring.datasource") | |||||
| public DataSource mysqlDataSource() { | |||||
| return DataSourceBuilder.create().build(); | |||||
| } | |||||
| @Bean(name = "mysqlJdbcTemplate") | |||||
| @Autowired | |||||
| public JdbcTemplate mysqlTemplate(@Qualifier("mysqlDB") DataSource mysqlDB) { | |||||
| return new JdbcTemplate(mysqlDB); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,27 @@ | |||||
| package mx.gob.jumapacelaya.datasource; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.annotation.Qualifier; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| import org.springframework.boot.jdbc.DataSourceBuilder; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.jdbc.core.JdbcTemplate; | |||||
| import javax.sql.DataSource; | |||||
| @Configuration | |||||
| public class OracleDataSource { | |||||
| @Bean(name = "oracleDB") | |||||
| @ConfigurationProperties(prefix = "spring.datasource.secondary") | |||||
| public DataSource oracleDataSource() { | |||||
| return DataSourceBuilder.create().build(); | |||||
| } | |||||
| @Bean(name = "oracleTemplate") | |||||
| @Autowired | |||||
| public JdbcTemplate oracleJdbcTemplate(@Qualifier("oracleDB") DataSource oracleDB) { | |||||
| return new JdbcTemplate(oracleDB); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,87 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.util.Date; | |||||
| public class ActividadDiaria { | |||||
| private int numero; | |||||
| private String proyecto; | |||||
| private String tipo; | |||||
| private String estado; | |||||
| private String asunto; | |||||
| private Date fechaInicial; | |||||
| private Date fechaCierre; | |||||
| public int getNumero() { | |||||
| return numero; | |||||
| } | |||||
| public void setNumero(int numero) { | |||||
| this.numero = numero; | |||||
| } | |||||
| public String getProyecto() { | |||||
| return proyecto; | |||||
| } | |||||
| public void setProyecto(String proyecto) { | |||||
| this.proyecto = proyecto; | |||||
| } | |||||
| public String getTipo() { | |||||
| return tipo; | |||||
| } | |||||
| public void setTipo(String tipo) { | |||||
| this.tipo = tipo; | |||||
| } | |||||
| public String getEstado() { | |||||
| return estado; | |||||
| } | |||||
| public void setEstado(String estado) { | |||||
| this.estado = estado; | |||||
| } | |||||
| public String getAsunto() { | |||||
| return asunto; | |||||
| } | |||||
| public void setAsunto(String asunto) { | |||||
| this.asunto = asunto; | |||||
| } | |||||
| public Date getFechaInicial() { | |||||
| return fechaInicial; | |||||
| } | |||||
| public void setFechaInicial(Date fechaInicial) { | |||||
| this.fechaInicial = fechaInicial; | |||||
| } | |||||
| public Date getFechaCierre() { | |||||
| return fechaCierre; | |||||
| } | |||||
| public void setFechaCierre(Date fechaCierre) { | |||||
| this.fechaCierre = fechaCierre; | |||||
| } | |||||
| public ActividadDiaria(int numero, String proyecto, String estado, String tipo, String asunto, Date fechaInicial, Date fechaCierre) { | |||||
| this.numero = numero; | |||||
| this.proyecto = proyecto; | |||||
| this.estado = estado; | |||||
| this.tipo = tipo; | |||||
| this.asunto = asunto; | |||||
| this.fechaInicial = fechaInicial; | |||||
| this.fechaCierre = fechaCierre; | |||||
| } | |||||
| public ActividadDiaria() { | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,27 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class ActualizacioneSeguridadModel { | |||||
| private int actualizacionsegId; | |||||
| private String descripcion; | |||||
| private String otrasactualizaciones; | |||||
| private int mantenimientoId; | |||||
| public ActualizacioneSeguridadModel(int actualizacionsegId, String descripcion, String otrasactualizaciones, int mantenimientoId) { | |||||
| this.actualizacionsegId = actualizacionsegId; | |||||
| this.descripcion = descripcion; | |||||
| this.otrasactualizaciones = otrasactualizaciones; | |||||
| this.mantenimientoId = mantenimientoId; | |||||
| } | |||||
| public int getActualizacionsegId() { return actualizacionsegId; } | |||||
| public String getDescripcion() { return descripcion; } | |||||
| public String getOtrasactualizaciones() { return otrasactualizaciones; } | |||||
| public int getMantenimientoId() { return mantenimientoId; } | |||||
| public void setActualizacionsegId(int actualizacionsegId) { this.actualizacionsegId = actualizacionsegId; } | |||||
| public void setDescripcion(String descripcion) { this.descripcion = descripcion; } | |||||
| public void setOtrasactualizaciones(String otrasactualizaciones) { this.otrasactualizaciones = otrasactualizaciones; } | |||||
| public void setMantenimientoId(int mantenimientoId) { this.mantenimientoId = mantenimientoId;} | |||||
| } | |||||
| @ -0,0 +1,84 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import org.springframework.security.core.GrantedAuthority; | |||||
| import org.springframework.security.core.userdetails.UserDetails; | |||||
| import java.util.Collection; | |||||
| public class CustomUserDetails implements UserDetails { | |||||
| private String username; | |||||
| private String firstName; | |||||
| private String lastName; | |||||
| private String email; | |||||
| private Collection<? extends GrantedAuthority> authorities; | |||||
| private String password; | |||||
| public CustomUserDetails(String username, String firstName, String lastName, String email, Collection<? extends GrantedAuthority> authorities, String password) { | |||||
| this.username = username; | |||||
| this.firstName = firstName; | |||||
| this.lastName = lastName; | |||||
| this.email = email; | |||||
| this.authorities = authorities; | |||||
| this.password = password; | |||||
| } | |||||
| // Getters and setters | |||||
| public String getFirstName() { | |||||
| return firstName; | |||||
| } | |||||
| public void setFirstName(String firstName) { | |||||
| this.firstName = firstName; | |||||
| } | |||||
| public String getLastName() { | |||||
| return lastName; | |||||
| } | |||||
| public void setLastName(String lastName) { | |||||
| this.lastName = lastName; | |||||
| } | |||||
| public String getEmail() { | |||||
| return email; | |||||
| } | |||||
| public void setEmail(String email) { | |||||
| this.email = email; | |||||
| } | |||||
| @Override | |||||
| public Collection<? extends GrantedAuthority> getAuthorities() { | |||||
| return authorities; | |||||
| } | |||||
| @Override | |||||
| public String getPassword() { | |||||
| return password; | |||||
| } | |||||
| @Override | |||||
| public String getUsername() { | |||||
| return username; | |||||
| } | |||||
| @Override | |||||
| public boolean isAccountNonExpired() { | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public boolean isAccountNonLocked() { | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public boolean isCredentialsNonExpired() { | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public boolean isEnabled() { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,33 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class DepartamentosModel { | |||||
| private String departamentoId; | |||||
| private String nombre; | |||||
| public DepartamentosModel(String departamentoId, String nombre) { | |||||
| this.departamentoId = departamentoId; | |||||
| this.nombre = nombre; | |||||
| } | |||||
| public String getDepartamentoId() { | |||||
| return departamentoId; | |||||
| } | |||||
| public void setDepartamentoId(String departamentoId) { | |||||
| this.departamentoId = departamentoId; | |||||
| } | |||||
| public String getNombre() { | |||||
| return nombre; | |||||
| } | |||||
| public void setNombre(String nombre) { | |||||
| this.nombre = nombre; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return nombre; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,66 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import java.time.LocalDate; | |||||
| public class DetalleMantenimientoModel { | |||||
| private int id; | |||||
| private int planAnualId; | |||||
| private String tipo; | |||||
| private String departamento; | |||||
| private String usuario; | |||||
| private LocalDate fechaprog; | |||||
| private LocalDate fecha; | |||||
| private String nombreEquipo; | |||||
| private String formaMant; | |||||
| private String firmaUser; | |||||
| private String firmaSmt; | |||||
| private String firmaGcia; | |||||
| private String situacion; | |||||
| public DetalleMantenimientoModel(int id, int planAnualId, String tipo, String departamento, | |||||
| String usuario, LocalDate fechaprog, LocalDate fecha, String nombreEquipo, String formaMant, | |||||
| String firmaUser, String firmaSmt, String firmaGcia, String situacion) { | |||||
| this.id = id; | |||||
| this.planAnualId = planAnualId; | |||||
| this.tipo = tipo; | |||||
| this.departamento = departamento; | |||||
| this.usuario = usuario; | |||||
| this.fechaprog = fechaprog; | |||||
| this.fecha = fecha; | |||||
| this.nombreEquipo = nombreEquipo; | |||||
| this.formaMant = formaMant; | |||||
| this.firmaUser = firmaUser; | |||||
| this.firmaSmt = firmaSmt; | |||||
| this.firmaGcia = firmaGcia; | |||||
| this.situacion = situacion; | |||||
| } | |||||
| public int getId() { return id; } | |||||
| public int getPlanAnualId() { return planAnualId; } | |||||
| public String getTipo() { return tipo; } | |||||
| public String getDepartamento() { return departamento; } | |||||
| public String getUsuario() { return usuario; } | |||||
| public LocalDate getFechaprog() { return fechaprog; } | |||||
| public LocalDate getFecha() { return fecha; } | |||||
| public String getNombreEquipo() { return nombreEquipo; } | |||||
| public String getFormaMant() { return formaMant; } | |||||
| public String getFirmaUser() { return firmaUser; } | |||||
| public String getFirmaSmt() { return firmaSmt; } | |||||
| public String getFirmaGcia() { return firmaGcia; } | |||||
| public String getSituacion() { return situacion; } | |||||
| public void setId(int id) { this.id = id; } | |||||
| public void setPlanAnualId(int planAnualId) { this.planAnualId = planAnualId; } | |||||
| public void setTipo(String tipo) { this.tipo = tipo; } | |||||
| public void setDepartamento(String departamento) { this.departamento = departamento; } | |||||
| public void setUsuario(String usuario) { this.usuario = usuario; } | |||||
| public void setFechaprog(LocalDate fechaprog) { this.fechaprog = fechaprog; } | |||||
| public void setFecha(LocalDate fecha) { this.fecha = fecha; } | |||||
| public void setNombreEquipo(String nombreEquipo) { this.nombreEquipo = nombreEquipo; } | |||||
| public void setFormaMant(String formaMant) { this.formaMant = formaMant; } | |||||
| public void setFirmaUser(String firmaUser) { this.firmaUser = firmaUser; } | |||||
| public void setFirmaSmt(String firmaSmt) { this.firmaSmt = firmaSmt; } | |||||
| public void setFirmaGcia(String firmaGcia) { this.firmaGcia = firmaGcia; } | |||||
| public void setSituacion(String situacion) { this.situacion = situacion; } | |||||
| } | |||||
| @ -0,0 +1,35 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class HardwareDetalle { | |||||
| private int mantenimientoId; | |||||
| private int hardwareDetId; | |||||
| private String descripcion; | |||||
| private String modelo; | |||||
| private String numSerie; | |||||
| private String placa; | |||||
| public HardwareDetalle(int mantenimientoId, int hardwareDetId, String descripcion, | |||||
| String modelo, String numSerie, String placa) { | |||||
| this.mantenimientoId = mantenimientoId; | |||||
| this.hardwareDetId = hardwareDetId; | |||||
| this.descripcion = descripcion; | |||||
| this.modelo = modelo; | |||||
| this.numSerie = numSerie; | |||||
| this.placa = placa; | |||||
| } | |||||
| public int getMantenimientoId() { return mantenimientoId; } | |||||
| public int getHardwareDetId() { return hardwareDetId; } | |||||
| public String getDescripcion() { return descripcion; } | |||||
| public String getModelo() { return modelo; } | |||||
| public String getNumSerie() { return numSerie; } | |||||
| public String getPlaca() { return placa; } | |||||
| public void setMantenimientoId(int mantenimientoId) { this.mantenimientoId = mantenimientoId; } | |||||
| public void setHardwareDetId(int hardwareDetId) { this.hardwareDetId = hardwareDetId; } | |||||
| public void setDescripcion(String descripcion) { this.descripcion = descripcion; } | |||||
| public void setModelo(String modelo) { this.modelo = modelo; } | |||||
| public void setNumSerie(String numSerie) { this.numSerie = numSerie; } | |||||
| public void setPlaca(String placa) { this.placa = placa; } | |||||
| } | |||||
| @ -0,0 +1,91 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import java.time.LocalDate; | |||||
| public class MantCorrectivosModel { | |||||
| private int mantenimientoId; | |||||
| private LocalDate fecha; | |||||
| private String tipo; | |||||
| private String area; | |||||
| private String nombre; | |||||
| private String forma; | |||||
| private String nomequipo; | |||||
| private String reparacion; | |||||
| public MantCorrectivosModel(int mantenimientoId, LocalDate fecha, String tipo, | |||||
| String area, String nombre, String forma, String nomequipo, String reparacion) { | |||||
| this.mantenimientoId = mantenimientoId; | |||||
| this.fecha = fecha; | |||||
| this.tipo = tipo; | |||||
| this.area = area; | |||||
| this.nombre = nombre; | |||||
| this.forma = forma; | |||||
| this.nomequipo = nomequipo; | |||||
| this.reparacion = reparacion; | |||||
| } | |||||
| public int getMantenimientoId() { | |||||
| return mantenimientoId; | |||||
| } | |||||
| public void setMantenimientoId(int mantenimientoId) { | |||||
| this.mantenimientoId = mantenimientoId; | |||||
| } | |||||
| public LocalDate getFecha() { | |||||
| return fecha; | |||||
| } | |||||
| public void setFecha(LocalDate fecha) { | |||||
| this.fecha = fecha; | |||||
| } | |||||
| public String getTipo() { | |||||
| return tipo; | |||||
| } | |||||
| public void setTipo(String tipo) { | |||||
| this.tipo = tipo; | |||||
| } | |||||
| public String getArea() { | |||||
| return area; | |||||
| } | |||||
| public void setArea(String area) { | |||||
| this.area = area; | |||||
| } | |||||
| public String getNombre() { | |||||
| return nombre; | |||||
| } | |||||
| public void setNombre(String nombre) { | |||||
| this.nombre = nombre; | |||||
| } | |||||
| public String getForma() { | |||||
| return forma; | |||||
| } | |||||
| public void setForma(String forma) { | |||||
| this.forma = forma; | |||||
| } | |||||
| public String getNomequipo() { | |||||
| return nomequipo; | |||||
| } | |||||
| public void setNomequipo(String nomequipo) { | |||||
| this.nomequipo = nomequipo; | |||||
| } | |||||
| public String getReparacion() { | |||||
| return reparacion; | |||||
| } | |||||
| public void setReparacion(String reparacion) { | |||||
| this.reparacion = reparacion; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,145 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import java.time.LocalDate; | |||||
| public class PlanAnual { | |||||
| private int numero; | |||||
| private String nomEquipo; | |||||
| private String departamento; | |||||
| private boolean monitor; // Cambiado a boolean | |||||
| private boolean teclado; // Cambiado a boolean | |||||
| private boolean mouse; // Cambiado a boolean | |||||
| private boolean regulador; // Cambiado a boolean | |||||
| private boolean cpu; // Cambiado a boolean | |||||
| private boolean impresora; // Cambiado a boolean | |||||
| private boolean miniPrint; // Cambiado a boolean | |||||
| private boolean laptop; // Cambiado a boolean | |||||
| private boolean escaner; // Cambiado a boolean | |||||
| private LocalDate fechaProgramada; | |||||
| private LocalDate fechaMantenimiento; | |||||
| private String mesplaneado; | |||||
| private String smt; | |||||
| private String estado; | |||||
| private String situacion; | |||||
| // Constructor | |||||
| public PlanAnual(int numero, String nomEquipo, String departamento, boolean monitor, | |||||
| boolean teclado, boolean mouse, boolean regulador, | |||||
| boolean cpu, boolean impresora, boolean miniPrint, | |||||
| boolean laptop, boolean escaner, LocalDate fechaProgramada, | |||||
| LocalDate fechaMantenimiento, String mesplaneado, String smt, String estado, String situacion) { | |||||
| this.numero = numero; | |||||
| this.nomEquipo = nomEquipo; | |||||
| this.departamento = departamento; | |||||
| this.monitor = monitor; | |||||
| this.teclado = teclado; | |||||
| this.mouse = mouse; | |||||
| this.regulador = regulador; | |||||
| this.cpu = cpu; | |||||
| this.impresora = impresora; | |||||
| this.miniPrint = miniPrint; | |||||
| this.laptop = laptop; | |||||
| this.escaner = escaner; | |||||
| this.fechaProgramada = fechaProgramada; | |||||
| this.fechaMantenimiento = fechaMantenimiento; | |||||
| this.mesplaneado = mesplaneado; | |||||
| this.smt = smt; | |||||
| this.estado = estado; | |||||
| this.situacion = situacion; | |||||
| } | |||||
| // Getters | |||||
| public int getNumero() { | |||||
| return numero; | |||||
| } | |||||
| public String getNomEquipo() { | |||||
| return nomEquipo; | |||||
| } | |||||
| public String getDepartamento() { | |||||
| return departamento; | |||||
| } | |||||
| public boolean isMonitor() { | |||||
| return monitor; | |||||
| } | |||||
| public boolean isTeclado() { | |||||
| return teclado; | |||||
| } | |||||
| public boolean isMouse() { | |||||
| return mouse; | |||||
| } | |||||
| public boolean isRegulador() { | |||||
| return regulador; | |||||
| } | |||||
| public boolean isCpu() { | |||||
| return cpu; | |||||
| } | |||||
| public boolean isImpresora() { | |||||
| return impresora; | |||||
| } | |||||
| public boolean isMiniPrint() { | |||||
| return miniPrint; | |||||
| } | |||||
| public boolean isLaptop() { | |||||
| return laptop; | |||||
| } | |||||
| public boolean isEscaner() { | |||||
| return escaner; | |||||
| } | |||||
| public String getSmt() { | |||||
| return smt; | |||||
| } | |||||
| public String getEstado() { | |||||
| return estado; | |||||
| } | |||||
| public void setNumero(int numero) { | |||||
| this.numero = numero; | |||||
| } | |||||
| public LocalDate getFechaMantenimiento() { | |||||
| return fechaMantenimiento; | |||||
| } | |||||
| public void setFechaMantenimiento(LocalDate fechaMantenimiento) { | |||||
| this.fechaMantenimiento = fechaMantenimiento; | |||||
| } | |||||
| public LocalDate getFechaProgramada() { | |||||
| return fechaProgramada; | |||||
| } | |||||
| public void setFechaProgramada(LocalDate fechaProgramada) { | |||||
| this.fechaProgramada = fechaProgramada; | |||||
| } | |||||
| public String getMesplaneado() { | |||||
| return mesplaneado; | |||||
| } | |||||
| public void setMesplaneado(String mesplaneado) { | |||||
| this.mesplaneado = mesplaneado; | |||||
| } | |||||
| public String getSituacion() { | |||||
| return situacion; | |||||
| } | |||||
| public void setSituacion(String situacion) { | |||||
| this.situacion = situacion; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,72 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class RedmineUser { | |||||
| private int id; | |||||
| private String login; | |||||
| private String firstname; | |||||
| private String lastname; | |||||
| private String mail; | |||||
| private String key; | |||||
| public int getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(int id) { | |||||
| this.id = id; | |||||
| } | |||||
| public String getLogin() { | |||||
| return login; | |||||
| } | |||||
| public void setLogin(String login) { | |||||
| this.login = login; | |||||
| } | |||||
| public String getFirstname() { | |||||
| return firstname; | |||||
| } | |||||
| public void setFirstname(String firstname) { | |||||
| this.firstname = firstname; | |||||
| } | |||||
| public String getLastname() { | |||||
| return lastname; | |||||
| } | |||||
| public void setLastname(String lastname) { | |||||
| this.lastname = lastname; | |||||
| } | |||||
| public String getMail() { | |||||
| return mail; | |||||
| } | |||||
| public void setMail(String mail) { | |||||
| this.mail = mail; | |||||
| } | |||||
| public String getKey() { | |||||
| return key; | |||||
| } | |||||
| public void setKey(String key) { | |||||
| this.key = key; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return "RedmineUser{" + | |||||
| "id=" + id + | |||||
| ", login='" + login + '\'' + | |||||
| ", firstname='" + firstname + '\'' + | |||||
| ", lastname='" + lastname + '\'' + | |||||
| ", mail='" + mail + '\'' + | |||||
| ", key='" + key + '\'' + | |||||
| '}'; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| @ -0,0 +1,153 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| import java.sql.Date; | |||||
| import java.time.LocalDate; | |||||
| public class Ticket { | |||||
| private final int id; | |||||
| private final String subject; | |||||
| private final String description; | |||||
| private final String status; | |||||
| private final LocalDate dateCreate; | |||||
| private LocalDate dateClose; | |||||
| private User author; | |||||
| private Integer trackerId; | |||||
| private String type; | |||||
| public Ticket(int id, String subject, String description, String status, String dateCreate, String dateClose, Integer trackerId, String type) { | |||||
| this.id = id; | |||||
| this.subject = subject; | |||||
| this.description = description; | |||||
| this.status = status; | |||||
| // Manejo de la fecha de creación | |||||
| if (dateCreate != null && !dateCreate.isEmpty()) { | |||||
| this.dateCreate = LocalDate.parse(dateCreate); // Solo se parsea si no está vacío | |||||
| } else { | |||||
| this.dateCreate = null; // Si está vacío, asignar null | |||||
| } | |||||
| // Manejo de la fecha de cierre | |||||
| if (dateClose != null && !dateClose.isEmpty()) { | |||||
| this.dateClose = LocalDate.parse(dateClose); // Solo se parsea si no está vacío | |||||
| } else { | |||||
| this.dateClose = null; // Si está vacío, asignar null | |||||
| } | |||||
| this.author = author; | |||||
| this.trackerId = trackerId; | |||||
| this.type = type; | |||||
| } | |||||
| public int getId() { | |||||
| return id; | |||||
| } | |||||
| public String getSubject() { | |||||
| return subject; | |||||
| } | |||||
| public String getDescription() { | |||||
| return description; | |||||
| } | |||||
| public String getStatus() { | |||||
| return status; | |||||
| } | |||||
| public User getAuthor() { | |||||
| return author; | |||||
| } | |||||
| public void setAuthor(User author) { | |||||
| this.author = author; | |||||
| } | |||||
| public Date getDateCreate() { | |||||
| return java.sql.Date.valueOf(this.dateCreate); | |||||
| } | |||||
| public Integer getTrackerId() { | |||||
| return trackerId; | |||||
| } | |||||
| public void setTrackerId(Integer tipoId) { | |||||
| this.trackerId = tipoId; | |||||
| } | |||||
| public LocalDate getDateClose() { | |||||
| return dateClose; | |||||
| } | |||||
| public void setDateClose(LocalDate dateClose) { | |||||
| this.dateClose = dateClose; | |||||
| } | |||||
| public void setType(String type) { | |||||
| this.type = type; | |||||
| } | |||||
| public static class User { | |||||
| private String username; | |||||
| public User(String username) { | |||||
| this.username = username; | |||||
| } | |||||
| public String getUsername() { | |||||
| return username; | |||||
| } | |||||
| public void setUsername(String username) { | |||||
| this.username = username; | |||||
| } | |||||
| } | |||||
| public String tiempoEst(Integer trackerId) { | |||||
| if (trackerId == null) { | |||||
| return "Desconocido"; | |||||
| } | |||||
| switch (trackerId) { | |||||
| case 1,3,4,7: | |||||
| return "1-2 dias Max"; | |||||
| case 2,12: | |||||
| return "2 hrs Max"; | |||||
| case 5: | |||||
| return "5 dias aprox."; | |||||
| case 8,11: | |||||
| return "2-6 hrs Max"; | |||||
| case 9,10: | |||||
| return "2 hrs Max"; | |||||
| default: | |||||
| return "N/A"; | |||||
| } | |||||
| } | |||||
| public String getType() { | |||||
| if (trackerId == null) { | |||||
| return "Desconocido"; | |||||
| } | |||||
| return switch (trackerId) { | |||||
| case 5 -> "Acceso/Permiso/Bajas"; | |||||
| case 6 -> "Soporte de Software"; | |||||
| case 7 -> "Capacitacion de Software"; | |||||
| case 8 -> "Configuracion de Software"; | |||||
| case 9 -> "Desarrollo de Software"; | |||||
| case 10 -> "Digitalizacion GIS"; | |||||
| case 11 -> "Documento"; | |||||
| case 12 -> "Reporte"; | |||||
| case 13 -> "Mantenimiento Correctivo"; | |||||
| case 14 -> "Actividad"; | |||||
| case 15 -> "Entrega de Consumibles"; | |||||
| case 16 -> "Instalacion/Configuracion GIS"; | |||||
| //case 17 -> "DDL"; | |||||
| //case 18 -> "DCL"; | |||||
| //case 19 -> "DML"; | |||||
| default -> "N/A"; | |||||
| }; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,34 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class TiposHardware { | |||||
| private String tipoHardwareId; | |||||
| private String nombreHardware; | |||||
| public TiposHardware(String tipoHardwareId, String nombreHardware) { | |||||
| this.tipoHardwareId = tipoHardwareId; | |||||
| this.nombreHardware = nombreHardware; | |||||
| } | |||||
| public String getTipoHardwareId() { | |||||
| return tipoHardwareId; | |||||
| } | |||||
| public void setTipoHardwareId(String tipoHardwareId) { | |||||
| this.tipoHardwareId = tipoHardwareId; | |||||
| } | |||||
| public String getNombreHardware() { | |||||
| return nombreHardware; | |||||
| } | |||||
| public void setNombreHardware(String nombreHardware) { | |||||
| this.nombreHardware = nombreHardware; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return nombreHardware; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,32 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class TiposMantenimiento { | |||||
| private String tipomantId; | |||||
| private String nombre; | |||||
| public TiposMantenimiento(String tipomantId, String nombre) { | |||||
| this.tipomantId = tipomantId; | |||||
| this.nombre = nombre; | |||||
| } | |||||
| public String getTipomantId() { | |||||
| return tipomantId; | |||||
| } | |||||
| public void setTipomantId(String tipomantId) { | |||||
| this.tipomantId = tipomantId; | |||||
| } | |||||
| public String getNombre() { | |||||
| return nombre; | |||||
| } | |||||
| public void setNombre(String nombre) { | |||||
| this.nombre = nombre; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return nombre; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| package mx.gob.jumapacelaya.models; | |||||
| public class Usuario { | |||||
| private String empleadoId; | |||||
| private String nombre; | |||||
| private String email; | |||||
| public Usuario(String empleadoId, String nombre, String email) { | |||||
| this.empleadoId = empleadoId; | |||||
| this.nombre = nombre; | |||||
| this.email = email; | |||||
| } | |||||
| public String getEmpleadoId() { | |||||
| return empleadoId; | |||||
| } | |||||
| public void setEmpleadoId(String empleadoId) { | |||||
| this.empleadoId = empleadoId; | |||||
| } | |||||
| public String getNombre() { | |||||
| return nombre; | |||||
| } | |||||
| public void setNombre(String nombre) { | |||||
| this.nombre = nombre; | |||||
| } | |||||
| public String getEmail() { | |||||
| return email; | |||||
| } | |||||
| public void setEmail(String email) { | |||||
| this.email = email; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return nombre; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,899 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import mx.gob.jumapacelaya.models.*; | |||||
| import oracle.jdbc.OracleConnection; | |||||
| import oracle.jdbc.OraclePreparedStatement; | |||||
| import oracle.sql.CLOB; | |||||
| import org.apache.poi.ss.usermodel.*; | |||||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.StringReader; | |||||
| import java.security.interfaces.RSAKey; | |||||
| import java.sql.*; | |||||
| import java.time.LocalDate; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| @Service | |||||
| public class DatabaseService { | |||||
| @Value("${db.url}") | |||||
| private String dbUrl; | |||||
| @Value("${db.user}") | |||||
| private String dbUser; | |||||
| @Value("${db.pass}") | |||||
| private String dbPass; | |||||
| private Connection getMysqlConnection() throws SQLException { | |||||
| return DriverManager.getConnection(dbUrl, dbUser, dbPass); | |||||
| } | |||||
| /*private Connection getOracleConnection() throws SQLException { | |||||
| String url = "jdbc:oracle:thin:@//svradminfinan:1521/admfinpdb.JUMAPACELAYA.GOB.MX"; | |||||
| String user = "Finanzas"; | |||||
| String pass = "finanzas"; | |||||
| return DriverManager.getConnection(url, user, pass); | |||||
| }*/ | |||||
| // Método para obtener los tipos de mantenimientos | |||||
| public List<TiposMantenimiento> getTiposDeMantenimientos() { | |||||
| List<TiposMantenimiento> tiposDeMantenimientos = new ArrayList<>(); | |||||
| String query = "SELECT tipomantid, nombre FROM TIPOMANT"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| Statement statement = connection.createStatement(); | |||||
| ResultSet resultSet = statement.executeQuery(query)) { | |||||
| while (resultSet.next()) { | |||||
| TiposMantenimiento tipo = new TiposMantenimiento( | |||||
| resultSet.getString("tipomantid"), | |||||
| resultSet.getString("nombre") | |||||
| ); | |||||
| tiposDeMantenimientos.add(tipo); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return tiposDeMantenimientos; | |||||
| } | |||||
| // Método para obtener las nomenclaturas | |||||
| public String getNomenclatura(String tipoMantenimiento) { | |||||
| String nomenclatura = ""; | |||||
| String query = "SELECT nomenclatura FROM TIPOMANT where TIPOMANTID = ?"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |||||
| preparedStatement.setString(1, tipoMantenimiento); | |||||
| try (ResultSet resultSet = preparedStatement.executeQuery()) { | |||||
| if (resultSet.next()) { | |||||
| nomenclatura = resultSet.getString("nomenclatura"); | |||||
| } | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| System.err.println("Error al obtener nomenclatura: " + e.getMessage()); | |||||
| } | |||||
| return nomenclatura; | |||||
| } | |||||
| /* -------------- Metodo para obtener a los usuarios ---------------- */ | |||||
| public List<Usuario> getUsuarios() { | |||||
| List<Usuario> usuarios = new ArrayList<>(); | |||||
| String query = "SELECT u.* \n" + | |||||
| "FROM USUARIOS u"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| Statement statement = connection.createStatement(); | |||||
| ResultSet resultSet = statement.executeQuery(query)) { | |||||
| while (resultSet.next()) { | |||||
| Usuario usuario = new Usuario( | |||||
| resultSet.getString("empleadoid"), | |||||
| resultSet.getString("nombre"), | |||||
| resultSet.getString("email") | |||||
| ); | |||||
| usuarios.add(usuario); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return usuarios; | |||||
| } | |||||
| /* -------------- Metodo para obtener los departamentos ---------------- */ | |||||
| public List<DepartamentosModel> getDepartamentos() { | |||||
| List<DepartamentosModel> departamentos = new ArrayList<>(); | |||||
| String query = "select DEPARTAMENTOID, DESCRIPCION from DEPARTAMENTOS"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| Statement statement = connection.createStatement(); | |||||
| ResultSet resultSet = statement.executeQuery(query)) { | |||||
| while (resultSet.next()) { | |||||
| DepartamentosModel departamentosModel = new DepartamentosModel( | |||||
| resultSet.getString("departamentoid"), | |||||
| resultSet.getString("descripcion") | |||||
| ); | |||||
| departamentos.add(departamentosModel); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return departamentos; | |||||
| } | |||||
| /* -------------- Metodo para obtener los tipos de hardware ---------------- */ | |||||
| public List<TiposHardware> getTiposHardware() { | |||||
| List<TiposHardware> tiposHardware = new ArrayList<>(); | |||||
| String query = "select TIPOHARDWAREID, DESCRIPCION from TIPOSHARDWARE"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| Statement statement = connection.createStatement(); | |||||
| ResultSet resultSet = statement.executeQuery(query)) { | |||||
| while (resultSet.next()) { | |||||
| TiposHardware tiposHardwareModel = new TiposHardware( | |||||
| resultSet.getString("tipohardwareid"), | |||||
| resultSet.getString("descripcion") | |||||
| ); | |||||
| tiposHardware.add(tiposHardwareModel); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return tiposHardware; | |||||
| } | |||||
| /* ----------------Obtener el Plan Anual de Mantenimiento ---------------- */ | |||||
| public List<PlanAnual> getPlanAnual() { | |||||
| List<PlanAnual> planAnualList = new ArrayList<>(); | |||||
| String query = "SELECT p.plananualid, p.nomEquipo, p.area,\n" + | |||||
| " p.monitor, p.teclado, p.mouse, p.regulador,\n" + | |||||
| " p.cpu, p.impresora, p.miniPrint, p.laptop, p.escaner,\n" + | |||||
| " p.fechaprog, m.fecha AS fechaMantenimiento,\n" + | |||||
| " me.NOMBRE AS MESPLANEADO, p.tecnicosmt, p.estado,\n" + | |||||
| " COALESCE(v.SITUACION, 'NO REALIZADO') AS SITUACION\n" + | |||||
| " FROM PLANANUAL p\n" + | |||||
| " LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\n" + | |||||
| " LEFT JOIN MESES me ON p.MESID = me.MESID\n" + | |||||
| " LEFT JOIN VW_SITUACION_MANTENIMIENTO v ON v.PLANANUALID = p.PLANANUALID\n" + | |||||
| " ORDER BY p.FECHAPROG ASC"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| Statement statement = connection.createStatement(); | |||||
| ResultSet resultSet = statement.executeQuery(query)) { | |||||
| while (resultSet.next()) { | |||||
| PlanAnual planAnual = new PlanAnual( | |||||
| resultSet.getInt("plananualid"), | |||||
| resultSet.getString("nomEquipo"), | |||||
| resultSet.getString("area"), | |||||
| resultSet.getBoolean("monitor"), | |||||
| resultSet.getBoolean("teclado"), | |||||
| resultSet.getBoolean("mouse"), | |||||
| resultSet.getBoolean("regulador"), | |||||
| resultSet.getBoolean("cpu"), | |||||
| resultSet.getBoolean("impresora"), | |||||
| resultSet.getBoolean("miniPrint"), | |||||
| resultSet.getBoolean("laptop"), | |||||
| resultSet.getBoolean("escaner"), | |||||
| resultSet.getDate("fechaprog").toLocalDate(), // Cambiado a LocalDate | |||||
| resultSet.getDate("fechaMantenimiento") != null ? resultSet.getDate("fechaMantenimiento").toLocalDate() : null, // Cambiado a LocalDate | |||||
| resultSet.getString("mesplaneado"), | |||||
| resultSet.getString("tecnicosmt"), | |||||
| resultSet.getString("estado"), | |||||
| resultSet.getString("SITUACION") | |||||
| ); | |||||
| planAnualList.add(planAnual); | |||||
| } | |||||
| System.out.println("Registros obtenidos: " + planAnualList.size()); | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return planAnualList; | |||||
| } | |||||
| /* ----------------Obtener el Plan Anual de Mantenimiento por ID ---------------- */ | |||||
| public PlanAnual getPlanAnualPorId(int id) { | |||||
| String query = "SELECT p.plananualid, p.nomEquipo, p.area,\n" + | |||||
| " p.monitor, p.teclado, p.mouse, p.regulador,\n" + | |||||
| " p.cpu, p.impresora, p.miniPrint, p.laptop, p.escaner,\n" + | |||||
| " p.fechaprog, m.fecha AS fechaMantenimiento,\n" + | |||||
| " me.NOMBRE AS MESPLANEADO, p.tecnicosmt, p.estado,\n" + | |||||
| " COALESCE(v.SITUACION, 'NO REALIZADO') AS SITUACION\n" + | |||||
| " FROM PLANANUAL p\n" + | |||||
| " LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\n" + | |||||
| " LEFT JOIN MESES me ON p.MESID = me.MESID\n" + | |||||
| " LEFT JOIN VW_SITUACION_MANTENIMIENTO v ON v.PLANANUALID = p.PLANANUALID\n" + | |||||
| " where p.plananualid = ?"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| PreparedStatement statement = connection.prepareStatement(query)) { | |||||
| statement.setInt(1, id); | |||||
| try (ResultSet resultSet = statement.executeQuery()) { | |||||
| if (resultSet.next()) { | |||||
| return new PlanAnual( | |||||
| resultSet.getInt("plananualid"), | |||||
| resultSet.getString("nomEquipo"), | |||||
| resultSet.getString("area"), | |||||
| resultSet.getBoolean("monitor"), | |||||
| resultSet.getBoolean("teclado"), | |||||
| resultSet.getBoolean("mouse"), | |||||
| resultSet.getBoolean("regulador"), | |||||
| resultSet.getBoolean("cpu"), | |||||
| resultSet.getBoolean("impresora"), | |||||
| resultSet.getBoolean("miniPrint"), | |||||
| resultSet.getBoolean("laptop"), | |||||
| resultSet.getBoolean("escaner"), | |||||
| resultSet.getDate("fechaprog").toLocalDate(), // Cambiado a LocalDate | |||||
| resultSet.getDate("fechaMantenimiento") != null ? resultSet.getDate("fechaMantenimiento").toLocalDate() : null, // Cambiado a LocalDate | |||||
| resultSet.getString("mesplaneado"), | |||||
| resultSet.getString("tecnicosmt"), | |||||
| resultSet.getString("estado"), | |||||
| resultSet.getString("SITUACION") | |||||
| ); | |||||
| } | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /* ----------------Obtener detalles del mantenimiento ---------------- */ | |||||
| public DetalleMantenimientoModel getDetalleMantenimientoPorPlanAnualId(int planAnualId) { | |||||
| String query = "SELECT\n" + | |||||
| " m.MANTENIMIENTOID AS ID,\n" + | |||||
| " p.PLANANUALID,\n" + | |||||
| " t.NOMBRE AS TIPO,\n" + | |||||
| " d.DESCRIPCION AS DEPARTAMENTO,\n" + | |||||
| " u.NOMBRE AS USUARIO,\n" + | |||||
| " v.FECHAPROG,\n" + | |||||
| " v.FECHAREALIZADO,\n" + | |||||
| " NOMBREEQUIPO,\n" + | |||||
| " FORMAMANT,\n" + | |||||
| " FIRMAUSUARIO,\n" + | |||||
| " FIRMASMT,\n" + | |||||
| " FIRMAGCIA,\n" + | |||||
| " v.SITUACION\n" + | |||||
| "FROM MANTENIMIENTOS m\n" + | |||||
| "INNER JOIN TIPOMANT t ON m.TIPOMANTID = t.TIPOMANTID\n" + | |||||
| "INNER JOIN DEPARTAMENTOS d ON m.DEPARTAMENTOID = d.DEPARTAMENTOID\n" + | |||||
| "INNER JOIN USUARIOS u ON u.EMPLEADOID = m.EMPLEADOID\n" + | |||||
| "INNER JOIN PLANANUAL p ON m.PLANANUALID = p.PLANANUALID\n" + | |||||
| "INNER JOIN PLANANUAL pa ON m.PLANANUALID = pa.PLANANUALID\n" + | |||||
| "INNER JOIN VW_SITUACION_MANTENIMIENTO v ON v.MANTENIMIENTOID = m.MANTENIMIENTOID\n" + | |||||
| "WHERE p.PLANANUALID = ?"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| PreparedStatement statement = connection.prepareStatement(query)) { | |||||
| statement.setInt(1, planAnualId); | |||||
| try (ResultSet rs = statement.executeQuery()) { | |||||
| if (rs.next()) { | |||||
| return new DetalleMantenimientoModel( | |||||
| rs.getInt("ID"), | |||||
| rs.getInt("PLANANUALID"), | |||||
| rs.getString("TIPO"), | |||||
| rs.getString("DEPARTAMENTO"), | |||||
| rs.getString("USUARIO"), | |||||
| rs.getDate("FECHAPROG").toLocalDate(), | |||||
| rs.getDate("FECHAREALIZADO").toLocalDate(), | |||||
| rs.getString("NOMBREEQUIPO"), | |||||
| rs.getString("FORMAMANT"), | |||||
| rs.getString("FIRMAUSUARIO"), | |||||
| rs.getString("FIRMASMT"), | |||||
| rs.getString("FIRMAGCIA"), | |||||
| rs.getString("SITUACION") | |||||
| ); | |||||
| } | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /* ----------------Obtener detalles del hardaware por ID ---------------- */ | |||||
| public List<HardwareDetalle> getHardwaredetallePorMantId(int mantenimientoId) { | |||||
| List<HardwareDetalle> detalles = new ArrayList<>(); | |||||
| String query = "SELECT h.MANTENIMIENTOID, h.HARDWAREDETID, t.DESCRIPCION, h.MODELO, h.NUMSERIE, h.PLACA\r\n" + // | |||||
| "FROM HARDWAREDET h\r\n" + // | |||||
| "INNER JOIN TIPOSHARDWARE t ON h.TIPOHARDWAREID = t.TIPOHARDWAREID \r\n" + // | |||||
| "WHERE h.MANTENIMIENTOID = ?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(query)) { | |||||
| stmt.setInt(1, mantenimientoId); | |||||
| ResultSet rs = stmt.executeQuery(); | |||||
| while (rs.next()) { | |||||
| HardwareDetalle detalle = new HardwareDetalle( | |||||
| rs.getInt("MANTENIMIENTOID"), | |||||
| rs.getInt("HARDWAREDETID"), | |||||
| rs.getString("DESCRIPCION"), | |||||
| rs.getString("MODELO"), | |||||
| rs.getString("NUMSERIE"), | |||||
| rs.getString("PLACA") | |||||
| ); | |||||
| detalles.add(detalle); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return detalles; | |||||
| } | |||||
| /* ---------------- Obtener las actualizaciones de seguridad ---------------- */ | |||||
| public List<ActualizacioneSeguridadModel> getActualizacionesSeg(int mantenimientoId) { | |||||
| List<ActualizacioneSeguridadModel> actualizaciones = new ArrayList<>(); | |||||
| String query = "SELECT *\r\n" + // | |||||
| "FROM ACTUALIZACIONESSEG a\r\n" + // | |||||
| "WHERE a.MANTENIMIENTOID = ?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(query)) { | |||||
| stmt.setInt(1, mantenimientoId); | |||||
| ResultSet rs = stmt.executeQuery(); | |||||
| while (rs.next()) { | |||||
| ActualizacioneSeguridadModel actualizacion = new ActualizacioneSeguridadModel( | |||||
| rs.getInt("ACTUALIZACIONSEGID"), | |||||
| rs.getString("DESCRIPCION"), | |||||
| rs.getString("OTRASACTUALIZACIONES"), | |||||
| rs.getInt("MANTENIMIENTOID") | |||||
| ); | |||||
| actualizaciones.add(actualizacion); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return actualizaciones; | |||||
| } | |||||
| /* ---------------- Obtener los mantenimientos correctivos ---------------- */ | |||||
| public List<MantCorrectivosModel> getMantenimientosCorrectivos(int tipomantId) { | |||||
| List<MantCorrectivosModel> mantCorrectivos = new ArrayList<>(); | |||||
| String query = "select\n" + | |||||
| "\tm.MANTENIMIENTOID,\n" + | |||||
| "\tm.FECHA,\n" + | |||||
| "\tt.NOMBRE TIPO,\n" + | |||||
| "\td.DESCRIPCION AREA,\n" + | |||||
| "\tu.NOMBRE,\n" + | |||||
| "\tCASE\n" + | |||||
| "\t\tWHEN formamant = 'M' then 'MANUAL'\n" + | |||||
| "\t\tELSE 'REMOTO'\n" + | |||||
| "\tEND as FORMA,\n" + | |||||
| "\tm.NOMBREEQUIPO,\n" + | |||||
| "\tm.REPARACION\n" + | |||||
| "from MANTENIMIENTOS m\n" + | |||||
| "inner join TIPOMANT t on t.TIPOMANTID = m.TIPOMANTID\n" + | |||||
| "inner join DEPARTAMENTOS d on d.DEPARTAMENTOID = m.DEPARTAMENTOID\n" + | |||||
| "inner join USUARIOS u on u.EMPLEADOID = m.EMPLEADOID\n" + | |||||
| "where m.TIPOMANTID = ?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement statement = conn.prepareStatement(query)) { | |||||
| statement.setInt(1, tipomantId); | |||||
| try (ResultSet rs = statement.executeQuery()) { | |||||
| while (rs.next()) { | |||||
| MantCorrectivosModel model = new MantCorrectivosModel( | |||||
| rs.getInt("MANTENIMIENTOID"), | |||||
| rs.getDate("FECHA").toLocalDate(), | |||||
| rs.getString("TIPO"), | |||||
| rs.getString("AREA"), | |||||
| rs.getString("NOMBRE"), | |||||
| rs.getString("FORMA"), | |||||
| rs.getString("NOMBREEQUIPO"), | |||||
| rs.getString("REPARACION") | |||||
| ); | |||||
| mantCorrectivos.add(model); | |||||
| } | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return mantCorrectivos; | |||||
| } | |||||
| /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/ | |||||
| /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/ | |||||
| /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/ | |||||
| /*-=iii=<() *-=iii=<() *-=iii=<()*/ | |||||
| /*-=iii=<() *-=iii=<()*/ | |||||
| /* ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) */ | |||||
| // INSERTAR EN TABLA: MANTENIMINETOS | |||||
| public int insertarMantenimiento(LocalDate fecha, String tipoMantId, String departamentoId, String empleadoId, | |||||
| String formaMant, String equipoId, String userSignatureBase64, | |||||
| String smtSignatureBase64, String planAnualId, String justificacion, String reparacion) { | |||||
| String query = "INSERT INTO MANTENIMIENTOS (fecha, tipoMantId, departamentoId, empleadoId, formaMant, nombreequipo," + | |||||
| " firmaUsuario, firmaSmt, planAnualId, justificacion, reparacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | |||||
| String updateStatusQuery = "UPDATE PLANANUAL SET estado = 'REALIZADO' WHERE planAnualId = ?"; | |||||
| int nuevoId = -1; | |||||
| Connection connection = null; | |||||
| try { | |||||
| connection = getMysqlConnection(); | |||||
| if (connection == null) { | |||||
| throw new SQLException("No se pudo establecer la conexion con la base de datos."); | |||||
| } | |||||
| connection.setAutoCommit(false); | |||||
| // Paso 1: primero inserta el mantenimiento | |||||
| try (PreparedStatement preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { | |||||
| preparedStatement.setDate(1, Date.valueOf(fecha)); | |||||
| preparedStatement.setLong(2, Long.parseLong(tipoMantId)); | |||||
| preparedStatement.setString(3, departamentoId); | |||||
| preparedStatement.setLong(4, Long.parseLong(empleadoId)); | |||||
| preparedStatement.setString(5, formaMant); | |||||
| preparedStatement.setString(6, equipoId); | |||||
| if (userSignatureBase64 != null) { | |||||
| preparedStatement.setString(7, userSignatureBase64); | |||||
| } else { | |||||
| preparedStatement.setNull(7, Types.VARCHAR); | |||||
| } | |||||
| if (smtSignatureBase64 != null) { | |||||
| preparedStatement.setString(8, smtSignatureBase64); | |||||
| } else { | |||||
| preparedStatement.setNull(8, Types.VARCHAR); | |||||
| } | |||||
| if (planAnualId != null && !planAnualId.isEmpty()) { | |||||
| preparedStatement.setLong(9, Long.parseLong(planAnualId)); | |||||
| } else { | |||||
| preparedStatement.setNull(9, Types.BIGINT); | |||||
| } | |||||
| preparedStatement.setString(10, justificacion); | |||||
| preparedStatement.setString(11, reparacion); | |||||
| preparedStatement.executeUpdate(); | |||||
| try (ResultSet rs = preparedStatement.getGeneratedKeys()) { | |||||
| if (rs.next()) { | |||||
| nuevoId = rs.getInt(1); | |||||
| } | |||||
| } | |||||
| } | |||||
| // Paso 2: Si se inserto el mantenimiento, se actualiza el estado en MTTOPROGRAMADOS | |||||
| if (nuevoId != -1) { | |||||
| try (PreparedStatement updateStatement = connection.prepareStatement(updateStatusQuery)) { | |||||
| updateStatement.setString(1, planAnualId); | |||||
| updateStatement.executeUpdate(); | |||||
| } | |||||
| } | |||||
| // Confirmar la transaccion si ambos pasos son exitosos | |||||
| connection.commit(); | |||||
| } catch (SQLException e) { | |||||
| System.err.println("Error al insertar mantenimiento: " + e.getMessage()); | |||||
| e.printStackTrace(); | |||||
| // En caso de error, se hace rollback | |||||
| if (connection != null) { | |||||
| try { | |||||
| connection.rollback(); | |||||
| } catch (SQLException rollbackEx) { | |||||
| System.err.println("Error al hacer rollback: " + rollbackEx.getMessage()); | |||||
| } | |||||
| } | |||||
| } finally { | |||||
| // Cerrar la conexion | |||||
| if (connection != null) { | |||||
| try { | |||||
| connection.close(); | |||||
| } catch (SQLException closeEx) { | |||||
| System.err.println("Error al cerrar la conexion: " + closeEx.getMessage()); | |||||
| } | |||||
| } | |||||
| } | |||||
| return nuevoId; | |||||
| } | |||||
| /*( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■) */ | |||||
| /* ˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀ */ | |||||
| // INSERTAR EN LA TABLA: HARDWAREDET | |||||
| public boolean insertarHardware(String tipoHardwareId, String numSerie, String modelo, String placa, int mantenimientoId) { | |||||
| String query = "INSERT INTO HARDWAREDET (tipoHardwareId, numSerie, modelo, placa, mantenimientoId) VALUES (?, ?, ?, ?, ?)"; | |||||
| boolean isInserted = false; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |||||
| preparedStatement.setInt(1, Integer.parseInt(tipoHardwareId)); | |||||
| preparedStatement.setString(2, numSerie); | |||||
| preparedStatement.setString(3, modelo); | |||||
| preparedStatement.setString(4, placa); | |||||
| preparedStatement.setInt(5, mantenimientoId); | |||||
| int rowsAffected = preparedStatement.executeUpdate(); | |||||
| isInserted = rowsAffected > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return isInserted; | |||||
| } | |||||
| public int getUltimoMantenimientoId() { | |||||
| int ultimoId = -1; | |||||
| try (Connection connection = getMysqlConnection()) { | |||||
| String query = "SELECT MAX(mantenimientoid) FROM MANTENIMIENTOS"; | |||||
| try (PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |||||
| ResultSet resultSet = preparedStatement.executeQuery(); | |||||
| if (resultSet.next()) { | |||||
| ultimoId = resultSet.getInt(1); | |||||
| } | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return ultimoId; | |||||
| } | |||||
| // INSERTAR EN LA TABLA: ACTUALIZACIONESSEG | |||||
| public boolean insertActualizacionSeg(String descripcion, String otras, int mantenimientoId) { | |||||
| String query = "INSERT INTO ACTUALIZACIONESSEG (descripcion, otrasactualizaciones, mantenimientoid) VALUES (?, ?, ?)"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |||||
| preparedStatement.setString(1, descripcion); | |||||
| preparedStatement.setString(2, otras); | |||||
| preparedStatement.setInt(3, mantenimientoId); | |||||
| int rowsInserted = preparedStatement.executeUpdate(); | |||||
| return rowsInserted > 0; | |||||
| } catch (SQLException e) { | |||||
| System.err.println("Error al insertar actualizacionSeg: " + e.getMessage()); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| // INSERTAR ARCHIVO EXCEL EN LA TABLA: PLANANUAL | |||||
| public void insertarDesdeExcel(InputStream inputStream) { | |||||
| String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO, MOUSE, " + | |||||
| "REGULADOR, CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG, TECNICOSMT, ESTADO) " + | |||||
| "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | |||||
| try (Connection connection = getMysqlConnection(); | |||||
| //FileInputStream file = new FileInputStream(rutaArchivoExcel); | |||||
| Workbook workbook = new XSSFWorkbook(inputStream)) { | |||||
| Sheet sheet = workbook.getSheetAt(0); // Primera hoja del archivo Excel | |||||
| for (Row row : sheet) { | |||||
| if (row.getRowNum() == 0) continue; // Saltar la primera fila si contiene encabezados | |||||
| try { | |||||
| // Leer cada celda de la fila según el índice correcto | |||||
| String nomequipo = getStringCellValue(row.getCell(0)); // Columna 1 | |||||
| String area = getStringCellValue(row.getCell(1)); // Columna 2 | |||||
| boolean monitor = getBooleanCellValue(row.getCell(2)); // Columna 3 | |||||
| boolean teclado = getBooleanCellValue(row.getCell(3)); // Columna 4 | |||||
| boolean mouse = getBooleanCellValue(row.getCell(4)); // Columna 5 | |||||
| boolean regulador = getBooleanCellValue(row.getCell(5)); // Columna 6 | |||||
| boolean cpu = getBooleanCellValue(row.getCell(6)); // Columna 7 | |||||
| boolean impresora = getBooleanCellValue(row.getCell(7)); // Columna 8 | |||||
| boolean miniprint = getBooleanCellValue(row.getCell(8)); // Columna 9 | |||||
| boolean laptop = getBooleanCellValue(row.getCell(9)); // Columna 10 | |||||
| boolean escaner = getBooleanCellValue(row.getCell(10)); // Columna 11 | |||||
| // Leer la fecha de la columna correcta | |||||
| Date fechaprog = getDateCellValue(row.getCell(11)); // Columna 12 | |||||
| String tecnicosmt = getStringCellValue(row.getCell(12)); // Columna 13 | |||||
| String estado = getStringCellValue(row.getCell(13)); // Columna 14 | |||||
| Date fecharealizado = getDateCellValue(row.getCell(14)); // Columna 15 | |||||
| // Insertar datos en la base de datos | |||||
| try (PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |||||
| preparedStatement.setString(1, nomequipo); | |||||
| preparedStatement.setString(2, area); | |||||
| preparedStatement.setBoolean(3, monitor); | |||||
| preparedStatement.setBoolean(4, teclado); | |||||
| preparedStatement.setBoolean(5, mouse); | |||||
| preparedStatement.setBoolean(6, regulador); | |||||
| preparedStatement.setBoolean(7, cpu); | |||||
| preparedStatement.setBoolean(8, impresora); | |||||
| preparedStatement.setBoolean(9, miniprint); | |||||
| preparedStatement.setBoolean(10, laptop); | |||||
| preparedStatement.setBoolean(11, escaner); | |||||
| // Manejo de fechas | |||||
| if (fechaprog != null) { | |||||
| preparedStatement.setDate(12, new java.sql.Date(fechaprog.getTime())); | |||||
| } else { | |||||
| preparedStatement.setNull(12, java.sql.Types.DATE); // Manejo de valor nulo | |||||
| } | |||||
| preparedStatement.setString(13, tecnicosmt); | |||||
| preparedStatement.setString(14, estado); | |||||
| preparedStatement.executeUpdate(); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| System.err.println("Error procesando la fila " + row.getRowNum() + ": " + e.getMessage()); | |||||
| } | |||||
| } | |||||
| System.out.println("Datos insertados desde Excel con éxito en PLANANUAL."); | |||||
| } catch (IOException e) { | |||||
| System.err.println("Error al leer el archivo Excel: " + e.getMessage()); | |||||
| } catch (SQLException e) { | |||||
| System.err.println("Error al insertar datos en la BD: " + e.getMessage()); | |||||
| } | |||||
| } | |||||
| // INSERTAR NUEVO EQUIPO INDIVIDUAL EN PLANANUAL | |||||
| public void insertarNuevoEquipo(String nomequipo, String area, boolean monitor, boolean teclado, | |||||
| boolean mouse, boolean regulador, boolean cpu, boolean impresora, | |||||
| boolean miniprint, boolean laptop, boolean escaner, Date fechaprog, | |||||
| String tecnicosmt, String estado, Integer mesId) { | |||||
| String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO,MOUSE, REGULADOR,\n" + | |||||
| "CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG,\n" + | |||||
| "TECNICOSMT, ESTADO, MESID)\n" + | |||||
| "VALUES (?, ?,\n" + | |||||
| "?, ?, ?, ?, ?, ?, ?, ?, ?,\n" + | |||||
| "?, ?, ?, ?)"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(query)) { | |||||
| stmt.setString(1, nomequipo); | |||||
| stmt.setString(2, area); | |||||
| stmt.setBoolean(3, monitor); | |||||
| stmt.setBoolean(4, teclado); | |||||
| stmt.setBoolean(5, mouse); | |||||
| stmt.setBoolean(6, regulador); | |||||
| stmt.setBoolean(7, cpu); | |||||
| stmt.setBoolean(8, impresora); | |||||
| stmt.setBoolean(9, miniprint); | |||||
| stmt.setBoolean(10, laptop); | |||||
| stmt.setBoolean(11, escaner); | |||||
| // Manejo de fechas | |||||
| if (fechaprog != null) { | |||||
| stmt.setDate(12, new java.sql.Date(fechaprog.getTime())); | |||||
| } else { | |||||
| stmt.setNull(12, java.sql.Types.DATE); // Manejo de valor nulo | |||||
| } | |||||
| stmt.setString(13, tecnicosmt); | |||||
| stmt.setString(14, estado); | |||||
| stmt.setInt(15, mesId); | |||||
| stmt.executeUpdate(); | |||||
| } catch (SQLException e) { | |||||
| System.err.println("Error al insertar nuevo equipo en PLANANUAL: " + e.getMessage()); | |||||
| } | |||||
| } | |||||
| // Método auxiliar para obtener un valor de tipo Date de una celda | |||||
| private Date getDateCellValue(Cell cell) { | |||||
| if (cell != null) { | |||||
| switch (cell.getCellType()) { | |||||
| case NUMERIC: | |||||
| return new Date(cell.getDateCellValue().getTime()); // Retorna la fecha directamente | |||||
| case STRING: | |||||
| try { | |||||
| return Date.valueOf(LocalDate.parse(cell.getStringCellValue().trim())); // Asume formato ISO | |||||
| } catch (Exception e) { | |||||
| System.err.println("No se puede convertir la cadena a fecha: " + cell.getStringCellValue()); | |||||
| } | |||||
| break; | |||||
| case BLANK: | |||||
| return null; // Devuelve null si la celda está vacía | |||||
| default: | |||||
| System.err.println("Tipo de celda inesperado en la fila " + cell.getRowIndex()); | |||||
| break; | |||||
| } | |||||
| } | |||||
| return null; // Retorna null si no se puede obtener una fecha | |||||
| } | |||||
| // Método auxiliar para obtener un valor de tipo String de una celda | |||||
| private String getStringCellValue(Cell cell) { | |||||
| if (cell != null) { | |||||
| switch (cell.getCellType()) { | |||||
| case STRING: | |||||
| return cell.getStringCellValue().trim(); | |||||
| case NUMERIC: | |||||
| return String.valueOf((int) cell.getNumericCellValue()); // Convierte el número a cadena | |||||
| default: | |||||
| return ""; // Devuelve cadena vacía si la celda no es de tipo STRING o NUMERIC | |||||
| } | |||||
| } | |||||
| return ""; // Devuelve cadena vacía si la celda es nula | |||||
| } | |||||
| // Método auxiliar para obtener un valor de tipo boolean de una celda | |||||
| private boolean getBooleanCellValue(Cell cell) { | |||||
| if (cell != null) { | |||||
| switch (cell.getCellType()) { | |||||
| case NUMERIC: | |||||
| return cell.getNumericCellValue() != 0; // Considera 0 como false, cualquier otro número como true | |||||
| case BOOLEAN: | |||||
| return cell.getBooleanCellValue(); | |||||
| case STRING: | |||||
| return Boolean.parseBoolean(cell.getStringCellValue().trim()); // Conversión de string a boolean | |||||
| default: | |||||
| return false; // Valor por defecto | |||||
| } | |||||
| } | |||||
| return false; // Valor por defecto si la celda es nula | |||||
| } | |||||
| /* ----------------Actualizar los detalles del del mantenimiento por ID ---------------- */ | |||||
| public boolean actualizarPlanAnual(int planAnualId, String nombreEquipo) { | |||||
| String sql = "UPDATE PLANANUAL SET NOMEQUIPO=? WHERE PLANANUALID=?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(sql)) { | |||||
| stmt.setString(1, nombreEquipo); | |||||
| stmt.setInt(2, planAnualId); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| public boolean actualizarMantenimiento(int mantenimientoId, int tipoId, String departamentoId, int empleadoId, LocalDate fechaRealizado, String nombreEquipo, String firmausuario, String firmasmt) { | |||||
| String sql = "UPDATE MANTENIMIENTOS SET TIPOMANTID=?, DEPARTAMENTOID=?, EMPLEADOID=?, FECHA=?, NOMBREEQUIPO=?, FIRMAUSUARIO=?, FIRMASMT=? WHERE MANTENIMIENTOID=?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(sql)) { | |||||
| stmt.setInt(1, tipoId); // tipoId es int | |||||
| stmt.setString(2, departamentoId); // departamentoId es String | |||||
| stmt.setInt(3, empleadoId); // empleadoId es int | |||||
| stmt.setDate(4, fechaRealizado != null ? Date.valueOf(fechaRealizado) : null); | |||||
| stmt.setString(5, nombreEquipo); | |||||
| if (firmausuario != null) { | |||||
| stmt.setString(6, firmausuario); | |||||
| } else { | |||||
| stmt.setNull(6, Types.VARCHAR); | |||||
| } | |||||
| if (firmasmt != null) { | |||||
| stmt.setString(7, firmasmt); | |||||
| } else { | |||||
| stmt.setNull(7, Types.VARCHAR); | |||||
| } | |||||
| stmt.setInt(8, mantenimientoId); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* ----------------Actualizar los detalles del hardaware por ID ---------------- */ | |||||
| public boolean actualizarHardwareDetalle(HardwareDetalle detalle) { | |||||
| String sql = "UPDATE HARDWAREDET SET MODELO=?, NUMSERIE=?, PLACA=? WHERE HARDWAREDETID=?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(sql)) { | |||||
| stmt.setString(1, detalle.getModelo()); | |||||
| stmt.setString(2, detalle.getNumSerie()); | |||||
| stmt.setString(3, detalle.getPlaca()); | |||||
| stmt.setInt(4, detalle.getHardwareDetId()); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* ----------------Actualizar las actualizaciones de seguridad por ID ---------------- */ | |||||
| public boolean actualizarActualizacionSeg(ActualizacioneSeguridadModel actualizacion) { | |||||
| String sql = "UPDATE ACTUALIZACIONESSEG SET OTRASACTUALIZACIONES=? WHERE ACTUALIZACIONSEGID=?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(sql)) { | |||||
| stmt.setString(1, actualizacion.getOtrasactualizaciones()); | |||||
| stmt.setInt(2, actualizacion.getActualizacionsegId()); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* ---------------- Insertar en bitacora ---------------- */ | |||||
| public boolean insertarBitacora(int mantenimientoid, String usuarioid, LocalDate fechora, String motivo) { | |||||
| String query = "INSERT INTO BITACORACTUALIZACIONES (MANTENIMIENTOID, USUARIOID, FECHORA, MOTIVO) VALUES (?, ?, ?, ?)"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(query)) { | |||||
| stmt.setInt(1, mantenimientoid); | |||||
| stmt.setString(2, usuarioid); | |||||
| stmt.setDate(3, fechora != null ? Date.valueOf(fechora) : null); | |||||
| stmt.setString(4, motivo); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* ---------------- Insertar en bitacora de eliminacion de equipos ---------------- */ | |||||
| public boolean insertarBitacoraEliminacion(int plananualid, String usuarioid, LocalDate fechora, String motivo) { | |||||
| String query = "INSERT INTO BITACORAELIMINACIONES (PLANANUALID, USUARIOID, FECHAHORA, MOTIVO) VALUES (?, ?, ?, ?)"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(query)) { | |||||
| stmt.setInt(1, plananualid); | |||||
| stmt.setString(2, usuarioid); | |||||
| stmt.setDate(3, fechora != null ? Date.valueOf(fechora) : null); | |||||
| stmt.setString(4, motivo); | |||||
| return stmt.executeUpdate() > 0; | |||||
| } catch (SQLException e) { | |||||
| e.printStackTrace(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* ---------------- Eliminar equipo de PLAN ANUAL ---------------- */ | |||||
| public void eliminarEquipoPlanAnual(int planAnualId) { | |||||
| String sql = "DELETE FROM PLANANUAL WHERE PLANANUALID = ?"; | |||||
| try (Connection conn = getMysqlConnection(); | |||||
| PreparedStatement stmt = conn.prepareStatement(sql)) { | |||||
| stmt.setInt(1, planAnualId); | |||||
| int rowsAffected = stmt.executeUpdate(); | |||||
| if (rowsAffected > 0) { | |||||
| System.out.println(planAnualId + " eliminado correctamente."); | |||||
| } else { | |||||
| System.out.println("No se encontró el equipo con ID: " + planAnualId); | |||||
| } | |||||
| } catch (SQLException e) { | |||||
| System.err.println("Error al eliminar el equipo de PLANANUAL: " + e.getMessage()); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,48 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import jakarta.activation.DataSource; | |||||
| import jakarta.mail.internet.MimeMessage; | |||||
| import jakarta.mail.util.ByteArrayDataSource; | |||||
| import mx.gob.jumapacelaya.models.Usuario; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.core.io.ClassPathResource; | |||||
| import org.springframework.core.io.InputStreamResource; | |||||
| import org.springframework.mail.SimpleMailMessage; | |||||
| import org.springframework.mail.javamail.JavaMailSender; | |||||
| import org.springframework.mail.javamail.MimeMailMessage; | |||||
| import org.springframework.mail.javamail.MimeMessageHelper; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.io.File; | |||||
| import java.io.InputStream; | |||||
| @Service | |||||
| public class EmailService { | |||||
| @Autowired | |||||
| private JavaMailSender mailSender; | |||||
| public void enviarCorreo(String destinatario, String asunto, String cuerpo, String imagePath) { | |||||
| try { | |||||
| MimeMessage mensaje = mailSender.createMimeMessage(); | |||||
| MimeMessageHelper helper = new MimeMessageHelper(mensaje, true); | |||||
| helper.setTo(destinatario); | |||||
| helper.setSubject(asunto); | |||||
| helper.setFrom("noreply@jumapacelaya.gob.mx"); | |||||
| helper.setText(cuerpo, true); | |||||
| ClassPathResource imgResource = new ClassPathResource(imagePath); | |||||
| helper.addInline("image_id", imgResource); | |||||
| mailSender.send(mensaje); | |||||
| System.out.println("Correo enviado con imagen exitosamente"); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| throw new RuntimeException("Error al enviar el correo: " + e.getMessage()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,46 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import mx.gob.jumapacelaya.models.CustomUserDetails; | |||||
| import org.springframework.ldap.core.LdapTemplate; | |||||
| import org.springframework.ldap.filter.EqualsFilter; | |||||
| import org.springframework.stereotype.Service; | |||||
| import javax.naming.NamingException; | |||||
| import javax.naming.directory.Attributes; | |||||
| import javax.naming.directory.SearchControls; | |||||
| import java.util.List; | |||||
| @Service | |||||
| public class LdapService { | |||||
| private final LdapTemplate ldapTemplate; | |||||
| public LdapService(LdapTemplate ldapTemplate) { | |||||
| this.ldapTemplate = ldapTemplate; | |||||
| } | |||||
| public CustomUserDetails getUserDetails(String username) { | |||||
| EqualsFilter filter = new EqualsFilter("sAMAccountName", username); | |||||
| SearchControls searchControls = new SearchControls(); | |||||
| searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); | |||||
| searchControls.setReturningAttributes(new String[]{"givenName", "sn", "mail"}); | |||||
| searchControls.setReturningObjFlag(true); | |||||
| List<CustomUserDetails> result = ldapTemplate.search("", filter.encode(), searchControls, (Attributes attrs) -> { | |||||
| String firstName = getAttribute(attrs, "givenName"); | |||||
| String lastName = getAttribute(attrs, "sn"); | |||||
| String email = getAttribute(attrs, "mail"); | |||||
| return new CustomUserDetails(username, firstName, lastName, email, null, null); // Ajustar los últimos dos parámetros si es necesario | |||||
| }); | |||||
| return result.isEmpty() ? null : result.get(0); | |||||
| } | |||||
| private String getAttribute(Attributes attributes, String attributeName) { | |||||
| try { | |||||
| return attributes.get(attributeName) != null ? attributes.get(attributeName).get().toString(): null; | |||||
| } catch (NamingException e) { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,41 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import net.sf.jasperreports.engine.JasperExportManager; | |||||
| import net.sf.jasperreports.engine.JasperFillManager; | |||||
| import net.sf.jasperreports.engine.JasperPrint; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.io.InputStream; | |||||
| import java.sql.Connection; | |||||
| import java.sql.DriverManager; | |||||
| import java.util.Map; | |||||
| @Service | |||||
| public class ReportService { | |||||
| @Value("${db.url}") | |||||
| private String dbUrl; | |||||
| @Value("${db.user}") | |||||
| private String dbUser; | |||||
| @Value("${db.pass}") | |||||
| private String dbPass; | |||||
| public byte[] generarReporte(String nombreReporte, Map<String, Object> parametros) throws Exception { | |||||
| InputStream logo = getClass().getResourceAsStream("/META-INF/resources/images/LOGO_24'27.png"); | |||||
| parametros.put("logo", logo); | |||||
| InputStream firmaGcia = getClass().getResourceAsStream("/META-INF/resources/images/FirmaGerenteTI.png"); | |||||
| parametros.put("firmaGcia", firmaGcia); | |||||
| InputStream jasperStream = getClass().getResourceAsStream("/META-INF/resources/reportes/" + nombreReporte + ".jasper"); | |||||
| if (jasperStream == null) { | |||||
| throw new IllegalArgumentException("No se encontro el archivo del reporte: " + nombreReporte); | |||||
| } | |||||
| try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPass)) { | |||||
| JasperPrint jasperPrint = JasperFillManager.fillReport(jasperStream, parametros, conn); | |||||
| return JasperExportManager.exportReportToPdf(jasperPrint); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,30 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import com.vaadin.flow.spring.security.AuthenticationContext; | |||||
| import org.springframework.security.core.Authentication; | |||||
| import org.springframework.security.core.context.SecurityContextHolder; | |||||
| import org.springframework.stereotype.Component; | |||||
| @Component | |||||
| public class SecurityService { | |||||
| private final AuthenticationContext authenticationContext; | |||||
| public SecurityService(AuthenticationContext authenticationContext) { | |||||
| this.authenticationContext = authenticationContext; | |||||
| } | |||||
| public String getAuthenticatedUser() { | |||||
| Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |||||
| if (authentication != null) { | |||||
| return authentication.getName(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public void logout() { | |||||
| authenticationContext.logout(); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,89 @@ | |||||
| package mx.gob.jumapacelaya.services; | |||||
| import com.vaadin.flow.server.VaadinService; | |||||
| import mx.gob.jumapacelaya.api.RedmineClient; | |||||
| import mx.gob.jumapacelaya.services.SecurityService; | |||||
| import mx.gob.jumapacelaya.models.CustomUserDetails; | |||||
| import mx.gob.jumapacelaya.models.RedmineUser; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.stereotype.Service; | |||||
| @Service | |||||
| public class UserService { | |||||
| private final SecurityService securityService; | |||||
| private final RedmineClient redmineClient; | |||||
| private static final Logger logger = LoggerFactory.getLogger(UserService.class); | |||||
| private final LdapService ldpaService; | |||||
| public UserService(SecurityService securityService, RedmineClient redmineClient, LdapService ldpaService) { | |||||
| this.securityService = securityService; | |||||
| this.redmineClient = redmineClient; | |||||
| this.ldpaService = ldpaService; | |||||
| } | |||||
| public RedmineUser getAuthenticatedRedmineUser() { | |||||
| try { | |||||
| String username = securityService.getAuthenticatedUser(); | |||||
| logger.info("Usuario autenticado: " + username); | |||||
| if (username != null) { | |||||
| RedmineUser user = redmineClient.getUserByUsername(username); | |||||
| if (user == null) { | |||||
| CustomUserDetails userDetails = ldpaService.getUserDetails(username); | |||||
| if (userDetails != null) { | |||||
| if (userDetails.getEmail() == null || userDetails.getEmail().isEmpty()) { | |||||
| logger.error("El usuario: " + username + " no tiene correo electronico."); | |||||
| return null; | |||||
| } | |||||
| RedmineUser newUser = RedmineClient.createRedmineUser( | |||||
| username, | |||||
| userDetails.getFirstName(), | |||||
| userDetails.getLastName(), | |||||
| userDetails.getEmail() | |||||
| ); | |||||
| if (newUser != null) { | |||||
| logger.info("Usuario creado en Redmine: " + newUser); | |||||
| return newUser; | |||||
| } else { | |||||
| logger.error("Error al crear el usuario en Redmine"); | |||||
| } | |||||
| } else { | |||||
| logger.error("No se encontraron detalles del usuario en LDAP"); | |||||
| } | |||||
| } else { | |||||
| logger.info("Usuario autenticado en Redmine: " + user); | |||||
| } | |||||
| return user; | |||||
| } | |||||
| } catch (Exception e) { | |||||
| logger.error("Error al obtener al usuario autenticado en Redmine", e); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public RedmineUser getRedmineUser() { | |||||
| RedmineUser userclient = (RedmineUser) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("myaccount"); | |||||
| if (userclient == null) { | |||||
| RedmineUser user = getAuthenticatedRedmineUser(); | |||||
| if (user != null) { | |||||
| RedmineUser myAccount = redmineClient.getMyAccount(user.getLogin()); | |||||
| if (myAccount != null && !myAccount.getKey().isEmpty()) { | |||||
| userclient = myAccount; | |||||
| VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); | |||||
| } else { | |||||
| // Crear un nuevo usuario si no existe | |||||
| myAccount = RedmineClient.createRedmineUser(user.getLogin(), user.getFirstname(), user.getLastname(), user.getMail()); | |||||
| if (myAccount != null && !myAccount.getKey().isEmpty()) { | |||||
| userclient = myAccount; | |||||
| VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return userclient; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,223 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.component.button.ButtonVariant; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.dialog.Dialog; | |||||
| import com.vaadin.flow.component.grid.Grid; | |||||
| import com.vaadin.flow.component.grid.GridVariant; | |||||
| import com.vaadin.flow.component.html.H3; | |||||
| import com.vaadin.flow.component.html.Span; | |||||
| import com.vaadin.flow.component.icon.Icon; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import com.vaadin.flow.component.notification.NotificationVariant; | |||||
| import com.vaadin.flow.component.orderedlayout.FlexComponent; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.richtexteditor.RichTextEditor; | |||||
| import com.vaadin.flow.data.renderer.ComponentRenderer; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import jakarta.annotation.security.PermitAll; | |||||
| import mx.gob.jumapacelaya.api.RedmineClient; | |||||
| import mx.gob.jumapacelaya.api.ServerProperties; | |||||
| import mx.gob.jumapacelaya.models.ActividadDiaria; | |||||
| import mx.gob.jumapacelaya.models.RedmineUser; | |||||
| import mx.gob.jumapacelaya.models.Ticket; | |||||
| import mx.gob.jumapacelaya.services.LdapService; | |||||
| import mx.gob.jumapacelaya.services.UserService; | |||||
| import java.io.IOException; | |||||
| import java.text.SimpleDateFormat; | |||||
| import java.time.LocalDate; | |||||
| import java.time.format.DateTimeFormatter; | |||||
| import java.util.*; | |||||
| @PermitAll | |||||
| @PageTitle("Actividades Diarias") | |||||
| @Route(value = "actdiaria", layout = MainLayout.class) | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class ActDiariaView extends VerticalLayout { | |||||
| private final RedmineClient redmineClient; | |||||
| private final UserService userService; | |||||
| private final Grid<Ticket> grid; | |||||
| public ActDiariaView(ServerProperties properties, RedmineClient redmineClient, UserService userService) { | |||||
| this.userService = userService; | |||||
| this.redmineClient = redmineClient; | |||||
| this.grid = new Grid<>(Ticket.class, false); | |||||
| // Configuración de columnas del grid | |||||
| grid.addColumn(Ticket::getId).setHeader("No.") | |||||
| .setAutoWidth(true).setFlexGrow(0).setSortable(true); | |||||
| grid.addColumn(Ticket::getType) | |||||
| .setHeader("Tipo") | |||||
| .setAutoWidth(true); | |||||
| grid.addColumn(Ticket::getSubject).setHeader("Asunto") | |||||
| .setWidth("25em"); | |||||
| grid.addColumn(createStatusRender()).setHeader("Estado"); | |||||
| grid.addColumn(ticket -> { | |||||
| Date date = ticket.getDateCreate(); | |||||
| if (date != null) { | |||||
| SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); | |||||
| return formatter.format(date); | |||||
| } else { | |||||
| return ""; | |||||
| } | |||||
| }).setHeader("Fecha creacion").setAutoWidth(true); | |||||
| grid.addColumn(ticket -> { | |||||
| LocalDate fechaCierre = ticket.getDateClose(); | |||||
| if (fechaCierre != null) { | |||||
| DateTimeFormatter formatterClose = DateTimeFormatter.ofPattern("dd/MM/yyyy"); | |||||
| return fechaCierre.format(formatterClose); | |||||
| } else { | |||||
| return ""; | |||||
| } | |||||
| }).setHeader("Fecha cierre").setAutoWidth(true); | |||||
| //grid.addColumn(ticket -> ticket.tiempoEst(ticket.getTrackerId())).setHeader("Tiempo estimado de atencion").setAutoWidth(false); | |||||
| grid.addComponentColumn(ticket -> { | |||||
| Button btnVer = new Button(new Icon(VaadinIcon.EYE)); | |||||
| btnVer.addClickListener(event -> showDescription(ticket)); | |||||
| btnVer.getStyle().set("color", "#A02142"); | |||||
| return btnVer; | |||||
| }).setAutoWidth(true); | |||||
| grid.addColumn(buttonTicketComponentRenderer()).setAutoWidth(true); | |||||
| grid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT); | |||||
| grid.getStyle().set("opacity", "0.8"); | |||||
| grid.setAllRowsVisible(false); | |||||
| grid.setSizeFull(); | |||||
| // Ajustar tamaño del Grid y Layout | |||||
| grid.setSizeFull(); | |||||
| setSizeFull(); | |||||
| add(grid); | |||||
| //expand(grid); | |||||
| setMargin(false); | |||||
| loadTickets(); | |||||
| } | |||||
| private void loadTickets() { | |||||
| try { | |||||
| List<Ticket> tickets = redmineClient.getTickets(userService.getRedmineUser(), true); | |||||
| List<Ticket> filteredTickets = tickets.stream() | |||||
| .filter(ticket -> ticket.getTrackerId() == 13 || ticket.getTrackerId() == 14) | |||||
| .toList(); | |||||
| grid.setItems(filteredTickets); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| // Manejo de error al cargar los tickets | |||||
| } | |||||
| } | |||||
| private ComponentRenderer<Span, Ticket> createStatusRender() { | |||||
| return new ComponentRenderer<>(ticket -> { | |||||
| // Creamos un Span para mostrar el estado | |||||
| Span span = new Span(ticket.getStatus()); | |||||
| // Estilos basados en el estado del ticket | |||||
| switch (ticket.getStatus().toLowerCase()) { | |||||
| case "análisis": | |||||
| span.getElement().getStyle().set("color","orange"); | |||||
| break; | |||||
| case "desarrollo": | |||||
| span.getElement().getStyle().set("color","blue"); | |||||
| break; | |||||
| case "rechazada": | |||||
| span.getElement().getStyle().set("color","red"); | |||||
| break; | |||||
| case "cerrada": | |||||
| span.getElement().getStyle().set("color","grey"); | |||||
| break; | |||||
| case "solicitado": | |||||
| span.getElement().getStyle().set("color","purple"); | |||||
| break; | |||||
| case "qa": | |||||
| span.getElement().getStyle().set("color","#C21DF2"); | |||||
| break; | |||||
| default: | |||||
| span.getElement().getStyle().set("color","green"); | |||||
| break; | |||||
| } | |||||
| return span; | |||||
| }); | |||||
| } | |||||
| public ComponentRenderer<Button, Ticket> buttonTicketComponentRenderer() { | |||||
| return new ComponentRenderer<>(ticket -> { | |||||
| Button button = new Button(new Icon(VaadinIcon.EDIT) ); | |||||
| button.getStyle().set("color", "#A02142"); | |||||
| button.addClickListener(e -> { | |||||
| RedmineUser currentUser = userService.getRedmineUser(); | |||||
| if (ticket.getTrackerId() == 13) { | |||||
| UI.getCurrent().navigate("mantenimiento"); | |||||
| } else if (ticket.getTrackerId() == 14) { | |||||
| cerrarTicket(ticket, currentUser); | |||||
| } else { | |||||
| Notification.show("El ticket no es de tipo Mantenimiento o Actividad."); | |||||
| } | |||||
| }); | |||||
| return button; | |||||
| }); | |||||
| } | |||||
| public void cerrarTicket(Ticket ticket, RedmineUser user) { | |||||
| try { | |||||
| //Llamar al metodo para cambiar el estado del ticket | |||||
| redmineClient.closeTicket(ticket.getId(), user); | |||||
| Notification.show("El ticket " + ticket.getId() + " se ha cerrado exitosamente.", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| UI.getCurrent().getPage().executeJs("setTimeout(() => { window.location.reload(); }, 3000);"); | |||||
| } catch (IOException | InterruptedException e) { | |||||
| e.printStackTrace(); | |||||
| Notification.show("Error al cerrar el ticket " + ticket.getId()); | |||||
| } | |||||
| } | |||||
| // Metodo para mostrar las descripciones en un componente Dialog | |||||
| private void showDescription(Ticket ticket) { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.getElement().setAttribute("arial-label", "Add note"); | |||||
| dialog.setMaxHeight("500px"); | |||||
| dialog.setMaxWidth("1100px"); | |||||
| RichTextEditor textEditor = new RichTextEditor(); | |||||
| textEditor.setValue(ticket.getDescription()); | |||||
| textEditor.setReadOnly(true); | |||||
| Button closeButton = new Button("Cerrar", new Icon(VaadinIcon.CLOSE)); | |||||
| closeButton.addThemeVariants(ButtonVariant.LUMO_ERROR); | |||||
| closeButton.addClickListener(e -> dialog.close()); | |||||
| HorizontalLayout buttonLayout = new HorizontalLayout(closeButton); | |||||
| buttonLayout.setWidthFull(); | |||||
| buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END); | |||||
| buttonLayout.add(closeButton); | |||||
| dialog.add(textEditor, buttonLayout); | |||||
| dialog.open(); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,607 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import java.io.ByteArrayInputStream; | |||||
| import java.time.LocalDate; | |||||
| import java.time.format.DateTimeFormatter; | |||||
| import java.util.Base64; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.html.Anchor; | |||||
| import com.vaadin.flow.server.StreamRegistration; | |||||
| import com.vaadin.flow.server.StreamResource; | |||||
| import mx.gob.jumapacelaya.services.ReportService; | |||||
| import org.springframework.security.core.Authentication; | |||||
| import org.springframework.security.core.context.SecurityContextHolder; | |||||
| import org.vaadin.lineawesome.LineAwesomeIcon; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.component.combobox.ComboBox; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.dialog.Dialog; | |||||
| import com.vaadin.flow.component.grid.GridVariant; | |||||
| import com.vaadin.flow.component.gridpro.GridPro; | |||||
| import com.vaadin.flow.component.html.H3; | |||||
| import com.vaadin.flow.component.html.Image; | |||||
| import com.vaadin.flow.component.html.Span; | |||||
| import com.vaadin.flow.component.icon.Icon; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import com.vaadin.flow.component.notification.NotificationVariant; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.textfield.TextField; | |||||
| import com.vaadin.flow.router.BeforeEnterEvent; | |||||
| import com.vaadin.flow.router.BeforeEnterObserver; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import de.f0rce.signaturepad.SignaturePad; | |||||
| import jakarta.annotation.security.PermitAll; | |||||
| import mx.gob.jumapacelaya.models.ActualizacioneSeguridadModel; | |||||
| import mx.gob.jumapacelaya.models.DepartamentosModel; | |||||
| import mx.gob.jumapacelaya.models.DetalleMantenimientoModel; | |||||
| import mx.gob.jumapacelaya.models.HardwareDetalle; | |||||
| import mx.gob.jumapacelaya.models.TiposMantenimiento; | |||||
| import mx.gob.jumapacelaya.models.Usuario; | |||||
| import mx.gob.jumapacelaya.services.DatabaseService; | |||||
| import mx.gob.jumapacelaya.services.SecurityService; | |||||
| @PageTitle("Detalles del mantenimiento") | |||||
| @Route(value = "detalles", layout = MainLayout.class) | |||||
| @PermitAll | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class DetallesMantView extends VerticalLayout implements BeforeEnterObserver { | |||||
| private H3 id; | |||||
| private VerticalLayout mainLayout; | |||||
| private HorizontalLayout headerLayout; | |||||
| private HorizontalLayout layout2; | |||||
| private HorizontalLayout layout3; | |||||
| private HorizontalLayout botonesLayout; | |||||
| private HorizontalLayout fechasLayout; | |||||
| private TextField txtId; | |||||
| private TextField txtEquipo; | |||||
| private ComboBox<TiposMantenimiento> cbTipo; | |||||
| private TextField txtFecha; | |||||
| private TextField txtFechaProgramada; | |||||
| private TextField txtSituacion; | |||||
| private ComboBox<Usuario> cbUsuario; | |||||
| private ComboBox<DepartamentosModel> cbDepartamento; | |||||
| private GridPro<HardwareDetalle> gridHardware; | |||||
| private GridPro<ActualizacioneSeguridadModel> gridActualizaciones; | |||||
| private Button btnEditar; | |||||
| private Button btnEditarFirmas; | |||||
| private Button btnImprimirRepo; | |||||
| private Button btnCancelar; | |||||
| private Button btnGuardar; | |||||
| private int planAnualIdActual; | |||||
| private int mantenimientoIdActual; | |||||
| private Dialog confirmDialog; | |||||
| private SignaturePad userSignPad; | |||||
| private SignaturePad smtSignPad; | |||||
| private SignaturePad gciaSignPad; | |||||
| private final HorizontalLayout firmasLAyout = new HorizontalLayout(); | |||||
| private Image firmaUsuarioImg; | |||||
| private Image firmaSmtImg; | |||||
| private Image firmaGciaImg; | |||||
| private VerticalLayout userSignLayout; | |||||
| private VerticalLayout smtSignLayout; | |||||
| private VerticalLayout gciaSignLayout; | |||||
| private final SecurityService securityService; | |||||
| private final DatabaseService service; | |||||
| private final ReportService reportService; | |||||
| public DetallesMantView(SecurityService securityService, DatabaseService service, ReportService reportService) { | |||||
| this.service = service; | |||||
| this.securityService = securityService; | |||||
| this.reportService = reportService; | |||||
| setPadding(true); | |||||
| mainLayout = new VerticalLayout(); | |||||
| mainLayout.setHeightFull(); | |||||
| mainLayout.getStyle() | |||||
| .set("box-shadow","0 4px 8px rgba(0,0,0,0.2)") | |||||
| .set("border-radius", "12px") | |||||
| .set("background-color", "white") | |||||
| .set("padding", "1rem") | |||||
| .set("margin", "1rem auto"); | |||||
| id = new H3(); | |||||
| headerLayout = new HorizontalLayout(); | |||||
| headerLayout.setWidthFull(); | |||||
| headerLayout.add(id); | |||||
| cbTipo = new ComboBox<>("Tipo:"); | |||||
| cbTipo.setItems(service.getTiposDeMantenimientos()); | |||||
| cbTipo.setItemLabelGenerator(TiposMantenimiento::getNombre); | |||||
| cbUsuario = new ComboBox<>("Usuario:"); | |||||
| cbUsuario.setItems(service.getUsuarios()); | |||||
| cbUsuario.setItemLabelGenerator(Usuario::getNombre); | |||||
| cbDepartamento = new ComboBox<>("Area:"); | |||||
| cbDepartamento.setItems(service.getDepartamentos()); | |||||
| cbDepartamento.setItemLabelGenerator(DepartamentosModel::getNombre); | |||||
| layout2 = new HorizontalLayout(); | |||||
| layout2.setWidthFull(); | |||||
| txtEquipo = new TextField("Equipo:"); | |||||
| txtEquipo.setReadOnly(true); | |||||
| cbTipo.setReadOnly(true); | |||||
| layout2.add(txtEquipo,cbTipo); | |||||
| fechasLayout = new HorizontalLayout(); | |||||
| fechasLayout.setWidthFull(); | |||||
| txtFecha = new TextField("Fecha realización:"); | |||||
| txtFechaProgramada = new TextField("Fecha programada:"); | |||||
| txtSituacion = new TextField("Situación:"); | |||||
| txtFecha.setReadOnly(true); | |||||
| txtFechaProgramada.setReadOnly(true); | |||||
| txtSituacion.setReadOnly(true); | |||||
| fechasLayout.add(txtFechaProgramada,txtFecha,txtSituacion); | |||||
| layout3 = new HorizontalLayout(); | |||||
| layout3.setWidthFull(); | |||||
| cbUsuario.setReadOnly(true); | |||||
| cbDepartamento.setReadOnly(true); | |||||
| cbUsuario.setWidthFull(); | |||||
| cbDepartamento.setWidthFull(); | |||||
| layout3.add(cbUsuario,cbDepartamento); | |||||
| // Grid que muestra los detalles del hardware | |||||
| gridHardware = new GridPro<>(); | |||||
| gridHardware.addColumn(item -> item.getDescripcion()) | |||||
| .setHeader("Descripción"); | |||||
| gridHardware.addEditColumn(HardwareDetalle::getNumSerie) | |||||
| .text((item, newValue) -> item.setNumSerie(newValue)) | |||||
| .setHeader("No. Serie") | |||||
| .setEditorComponent(new TextField()); | |||||
| gridHardware.addEditColumn(HardwareDetalle::getModelo) | |||||
| .text((item, newValue) -> item.setModelo(newValue)) | |||||
| .setHeader("Modelo") | |||||
| .setEditorComponent(new TextField()); | |||||
| gridHardware.addEditColumn(HardwareDetalle::getPlaca) | |||||
| .text((item, newValue) -> item.setPlaca(newValue)) | |||||
| .setHeader("Placa") | |||||
| .setEditorComponent(new TextField()); | |||||
| gridHardware.setWidthFull(); | |||||
| gridHardware.setEditOnClick(false); | |||||
| gridHardware.setHeight("250px"); | |||||
| gridHardware.addThemeVariants(GridVariant.LUMO_ROW_STRIPES); | |||||
| // Grid que muestra las actualizaciones de seguridad | |||||
| gridActualizaciones = new GridPro<>(); | |||||
| gridActualizaciones.addEditColumn(ActualizacioneSeguridadModel::getDescripcion) | |||||
| .text((item, newValue) -> item.setDescripcion(newValue)) | |||||
| .setHeader("Descripción") | |||||
| .setEditorComponent(new TextField()); | |||||
| gridActualizaciones.addEditColumn(ActualizacioneSeguridadModel::getOtrasactualizaciones) | |||||
| .text((item, newValue) -> item.setOtrasactualizaciones(newValue)) | |||||
| .setHeader("Otras Actualizaciones") | |||||
| .setEditorComponent(new TextField()); | |||||
| gridActualizaciones.setWidthFull(); | |||||
| gridActualizaciones.setEditOnClick(false); | |||||
| gridActualizaciones.setHeight("200px"); | |||||
| gridActualizaciones.addThemeVariants(GridVariant.LUMO_ROW_STRIPES); | |||||
| botonesLayout = new HorizontalLayout(); | |||||
| botonesLayout.setWidthFull(); | |||||
| botonesLayout.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| btnEditar = new Button("Editar", new Icon(VaadinIcon.EDIT)); | |||||
| btnImprimirRepo = new Button("Imprimir Reporte", new Icon(VaadinIcon.PRINT)); | |||||
| btnEditarFirmas = new Button("Editar firmas", LineAwesomeIcon.SIGNATURE_SOLID.create()); | |||||
| btnGuardar = new Button("Guardar", LineAwesomeIcon.SAVE_SOLID.create()); | |||||
| btnCancelar = new Button("Cancelar", new Icon(VaadinIcon.CLOSE_CIRCLE_O)); | |||||
| botonesLayout.add(btnEditar,btnEditarFirmas,btnImprimirRepo,btnGuardar,btnCancelar); | |||||
| btnGuardar.setVisible(false); | |||||
| btnGuardar.getStyle().set("background-color", "#008000"); | |||||
| btnGuardar.getStyle().set("color", "white"); | |||||
| btnCancelar.setVisible(false); | |||||
| btnCancelar.getStyle().set("background-color", "red"); | |||||
| btnCancelar.getStyle().set("color", "white"); | |||||
| btnEditar.addClickListener(e -> { | |||||
| txtEquipo.setReadOnly(false); | |||||
| cbTipo.setReadOnly(false); | |||||
| txtFecha.setReadOnly(false); | |||||
| cbUsuario.setReadOnly(false); | |||||
| cbDepartamento.setReadOnly(false); | |||||
| btnImprimirRepo.setVisible(false); | |||||
| btnEditar.setVisible(false); | |||||
| btnGuardar.setVisible(true); | |||||
| btnCancelar.setVisible(true); | |||||
| btnEditarFirmas.setVisible(false); | |||||
| gridHardware.setEditOnClick(true); | |||||
| gridActualizaciones.setEditOnClick(true); | |||||
| }); | |||||
| btnEditarFirmas.addClickListener(e -> { | |||||
| btnCancelar.setVisible(true); | |||||
| btnGuardar.setVisible(true); | |||||
| btnEditar.setVisible(false); | |||||
| btnImprimirRepo.setVisible(false); | |||||
| btnEditarFirmas.setVisible(false); | |||||
| if (firmaUsuarioImg != null && firmaUsuarioImg.getParent().isPresent()) { | |||||
| userSignLayout.replace(firmaUsuarioImg, userSignPad); | |||||
| } | |||||
| if (firmaSmtImg != null && firmaSmtImg.getParent().isPresent()) { | |||||
| smtSignLayout.replace(firmaSmtImg, smtSignPad); | |||||
| } | |||||
| }); | |||||
| btnCancelar.addClickListener(e -> { | |||||
| txtEquipo.setReadOnly(true); | |||||
| cbTipo.setReadOnly(true); | |||||
| txtFecha.setReadOnly(true); | |||||
| cbUsuario.setReadOnly(true); | |||||
| cbDepartamento.setReadOnly(true); | |||||
| btnImprimirRepo.setVisible(true); | |||||
| btnEditar.setVisible(true); | |||||
| btnGuardar.setVisible(false); | |||||
| btnCancelar.setVisible(false); | |||||
| btnEditarFirmas.setVisible(true); | |||||
| gridHardware.setEditOnClick(false); | |||||
| gridHardware.getEditor().cancel(); | |||||
| gridActualizaciones.setEditOnClick(false); | |||||
| gridActualizaciones.getEditor().cancel(); | |||||
| if (firmaUsuarioImg != null && userSignPad.getParent().isPresent()) { | |||||
| userSignLayout.replace(userSignPad, firmaUsuarioImg); | |||||
| } | |||||
| if (firmaSmtImg != null && smtSignPad.getParent().isPresent()) { | |||||
| smtSignLayout.replace(smtSignPad, firmaSmtImg); | |||||
| } | |||||
| }); | |||||
| btnImprimirRepo.addClickListener(e -> { | |||||
| try { | |||||
| // Prepara los parámetros para el reporte | |||||
| Map<String, Object> parametros = new HashMap<>(); | |||||
| parametros.put("PLAN_ID", planAnualIdActual); | |||||
| // Genera el PDF | |||||
| byte[] pdf = reportService.generarReporte("mantenimientoReport", parametros); | |||||
| // Se crea el recurso para descarga | |||||
| StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf)); | |||||
| /*Anchor downloadLink = new Anchor(resource, "Descargar Reporte"); | |||||
| downloadLink.setTarget("_blank"); | |||||
| downloadLink.setId("descargar-reporte-link"); | |||||
| add(downloadLink); | |||||
| getUI().ifPresent(ui -> | |||||
| ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();") | |||||
| );*/ | |||||
| StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource); | |||||
| UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')"); | |||||
| } catch (Exception ex) { | |||||
| Notification.show("Error al generar el reporte: " + ex.getMessage(), 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| ex.printStackTrace(); | |||||
| } | |||||
| }); | |||||
| // Se dispara el dialogo de confirmacion | |||||
| btnGuardar.addClickListener(e -> confirmDialog.open()); | |||||
| // Dialogo de confirmación de actualización | |||||
| confirmDialog = new Dialog(); | |||||
| confirmDialog.setHeaderTitle("Actualizar Mantenimiento"); | |||||
| TextField txtJustificacion = new TextField("Justificacion"); | |||||
| txtJustificacion.setWidthFull(); | |||||
| txtJustificacion.setRequired(true); | |||||
| confirmDialog.add( | |||||
| new VerticalLayout( | |||||
| new Span("¿Estás seguro de que deseas actualizar el mantenimiento?"), | |||||
| txtJustificacion | |||||
| ) | |||||
| ); | |||||
| Button btnConfirmar = new Button("Actualizar", event -> { | |||||
| String justificacion = txtJustificacion.getValue(); | |||||
| if (justificacion.isEmpty()) { | |||||
| txtJustificacion.setErrorMessage("Por favor, ingresa una justificación."); | |||||
| txtJustificacion.setInvalid(true); | |||||
| return; | |||||
| } | |||||
| txtJustificacion.setInvalid(false); | |||||
| confirmDialog.close(); | |||||
| Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |||||
| String usuarioId = authentication != null ? authentication.getName().toUpperCase() : "DESCONOCIDO"; | |||||
| LocalDate fecha = LocalDate.now(); | |||||
| service.insertarBitacora(mantenimientoIdActual, usuarioId, fecha, justificacion); | |||||
| realizarActualizacion(); | |||||
| txtJustificacion.clear(); | |||||
| }); | |||||
| Button btnCancelarDialog = new Button("Cancelar", event -> { | |||||
| confirmDialog.close(); | |||||
| txtEquipo.setReadOnly(true); | |||||
| cbTipo.setReadOnly(true); | |||||
| txtFecha.setReadOnly(true); | |||||
| cbUsuario.setReadOnly(true); | |||||
| cbDepartamento.setReadOnly(true); | |||||
| btnImprimirRepo.setVisible(true); | |||||
| btnEditar.setVisible(true); | |||||
| btnGuardar.setVisible(false); | |||||
| btnCancelar.setVisible(false); | |||||
| gridHardware.setEditOnClick(false); | |||||
| gridHardware.getEditor().cancel(); | |||||
| if (firmaUsuarioImg != null && userSignPad.getParent().isPresent()) { | |||||
| userSignLayout.replace(userSignPad, firmaUsuarioImg); | |||||
| } | |||||
| if (firmaSmtImg != null && smtSignPad.getParent().isPresent()) { | |||||
| smtSignLayout.replace(smtSignPad, firmaSmtImg); | |||||
| } | |||||
| }); | |||||
| HorizontalLayout dialogButtons = new HorizontalLayout(btnConfirmar, btnCancelarDialog); | |||||
| confirmDialog.getFooter().add(dialogButtons); | |||||
| addSignatureSection(); | |||||
| mainLayout.add(headerLayout,layout2,fechasLayout,layout3,gridHardware,gridActualizaciones,firmasLAyout,botonesLayout); | |||||
| add(mainLayout); | |||||
| } | |||||
| private void realizarActualizacion() { | |||||
| boolean exito = true; | |||||
| // Obtén los objetos seleccionados | |||||
| TiposMantenimiento tipoSeleccionado = cbTipo.getValue(); | |||||
| Usuario usuarioSeleccionado = cbUsuario.getValue(); | |||||
| DepartamentosModel departamentoSeleccionado = cbDepartamento.getValue(); | |||||
| int tipoId = tipoSeleccionado != null ? Integer.parseInt(tipoSeleccionado.getTipomantId()) : 0; | |||||
| int empleadoId = usuarioSeleccionado != null ? Integer.parseInt(usuarioSeleccionado.getEmpleadoId()) : 0; | |||||
| String departamentoId = departamentoSeleccionado != null ? departamentoSeleccionado.getDepartamentoId() : null; | |||||
| // Fechas (corrige el campo) | |||||
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); | |||||
| LocalDate fechaProg = !txtFechaProgramada.getValue().isEmpty() ? LocalDate.parse(txtFechaProgramada.getValue(), formatter) : null; | |||||
| LocalDate fechaRealizado = !txtFecha.getValue().isEmpty() ? LocalDate.parse(txtFecha.getValue(), formatter) : null; | |||||
| // Obtener las firmas como en MantenimientoView | |||||
| byte[] userSignatureBytes = userSignPad.getImageBase64(); | |||||
| byte[] smtSignatureBytes = smtSignPad.getImageBase64(); | |||||
| String userSignatureBase64 = (userSignatureBytes != null) ? Base64.getEncoder().encodeToString(userSignatureBytes) : null; | |||||
| String smtSignatureBase64 = (smtSignatureBytes != null) ? Base64.getEncoder().encodeToString(smtSignatureBytes) : null; | |||||
| // Si la firma está vacía, conserva la anterior | |||||
| if (userSignatureBase64 == null || esFirmaVacia(userSignatureBase64)) { | |||||
| userSignatureBase64 = service.getDetalleMantenimientoPorPlanAnualId(planAnualIdActual).getFirmaUser(); | |||||
| } | |||||
| if (smtSignatureBase64 == null || esFirmaVacia(smtSignatureBase64)) { | |||||
| smtSignatureBase64 = service.getDetalleMantenimientoPorPlanAnualId(planAnualIdActual).getFirmaSmt(); | |||||
| } | |||||
| // ACTUALIZA PLANANUAL (nombre del equipo y fecha programada) | |||||
| if (!service.actualizarPlanAnual(planAnualIdActual, txtEquipo.getValue())) { | |||||
| exito = false; | |||||
| } | |||||
| // ACTUALIZA MANTENIMIENTOS (tipo, departamento, usuario, fecha realizado) | |||||
| if (!service.actualizarMantenimiento( | |||||
| mantenimientoIdActual, | |||||
| tipoId, | |||||
| departamentoId, | |||||
| empleadoId, | |||||
| fechaRealizado, | |||||
| txtEquipo.getValue(), | |||||
| userSignatureBase64, | |||||
| smtSignatureBase64 | |||||
| )) { | |||||
| exito = false; | |||||
| } | |||||
| // ACTUALIZA HARDWARE (grid) | |||||
| for (HardwareDetalle detalle : gridHardware.getListDataView().getItems().toList()) { | |||||
| if (!service.actualizarHardwareDetalle(detalle)) { | |||||
| exito = false; | |||||
| } | |||||
| } | |||||
| // ACTUALIZA ACTUALIZACIONES DE SEGURIDAD (grid) | |||||
| for (ActualizacioneSeguridadModel actualizacion : gridActualizaciones.getListDataView().getItems().toList()) { | |||||
| if (!service.actualizarActualizacionSeg(actualizacion)) { | |||||
| exito = false; | |||||
| } | |||||
| } | |||||
| if (exito) { | |||||
| Notification.show("Registros actualizados correctamente", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| } else { | |||||
| Notification.show("Error al actualizar uno o más registros", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| } | |||||
| // Opcional: volver a modo solo lectura | |||||
| txtEquipo.setReadOnly(true); | |||||
| cbTipo.setReadOnly(true); | |||||
| txtFecha.setReadOnly(true); | |||||
| cbUsuario.setReadOnly(true); | |||||
| cbDepartamento.setReadOnly(true); | |||||
| btnImprimirRepo.setVisible(true); | |||||
| btnEditar.setVisible(true); | |||||
| btnEditarFirmas.setVisible(true); | |||||
| btnGuardar.setVisible(false); | |||||
| btnCancelar.setVisible(false); | |||||
| gridHardware.setEditOnClick(false); | |||||
| gridHardware.getEditor().cancel(); | |||||
| if (firmaUsuarioImg != null && userSignPad.getParent().isPresent()) { | |||||
| userSignLayout.replace(userSignPad, firmaUsuarioImg); | |||||
| } | |||||
| if (firmaSmtImg != null && smtSignPad.getParent().isPresent()) { | |||||
| smtSignLayout.replace(smtSignPad, firmaSmtImg); | |||||
| } | |||||
| } | |||||
| // Metodo para verificar si la firma corresponde a una cadena de firma vacia | |||||
| private boolean esFirmaVacia(String firmaBase64) { | |||||
| String firmaVacia = "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD8CAYAAACSCdTiAAAIbElEQVR4Xu3UAQ0AIAwDQeZfNCPI+Nwc9Lp07rvjCBAgQCApMEY+2atQBAgQ+AJG3iMQIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBBYAuXtOkIWm1QAAAAASUVORK5CYII="; | |||||
| return firmaBase64.equals(firmaVacia); | |||||
| } | |||||
| private void addSignatureSection() { | |||||
| // Usa los atributos de clase, no variables locales | |||||
| userSignLayout = new VerticalLayout(); | |||||
| userSignLayout.setWidthFull(); | |||||
| userSignLayout.setAlignItems(Alignment.CENTER); | |||||
| userSignPad = new SignaturePad(); | |||||
| userSignPad.setHeight("200px"); | |||||
| userSignPad.setWidthFull(); | |||||
| userSignLayout.add(userSignPad, new Span("Usuario Interno")); | |||||
| smtSignLayout = new VerticalLayout(); | |||||
| smtSignLayout.setWidthFull(); | |||||
| smtSignLayout.setAlignItems(Alignment.CENTER); | |||||
| smtSignPad = new SignaturePad(); | |||||
| smtSignPad.setHeight("200px"); | |||||
| smtSignPad.setWidthFull(); | |||||
| smtSignLayout.add(smtSignPad, new Span("Responsable de Soporte")); | |||||
| gciaSignLayout = new VerticalLayout(); | |||||
| gciaSignLayout.setWidthFull(); | |||||
| gciaSignLayout.setAlignItems(Alignment.CENTER); | |||||
| gciaSignPad = new SignaturePad(); | |||||
| gciaSignPad.setHeight("200px"); | |||||
| gciaSignPad.setWidthFull(); | |||||
| gciaSignLayout.add(gciaSignPad, new Span("Gcia. de T.I")); | |||||
| firmasLAyout.removeAll(); | |||||
| firmasLAyout.setWidthFull(); | |||||
| firmasLAyout.setSpacing(false); | |||||
| firmasLAyout.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| firmasLAyout.add(userSignLayout, smtSignLayout, gciaSignLayout); | |||||
| } | |||||
| @Override | |||||
| public void beforeEnter(BeforeEnterEvent event) { | |||||
| String idParam = event.getLocation().getQueryParameters().getParameters().get("id") != null | |||||
| ? event.getLocation().getQueryParameters().getParameters().get("id").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| if (idParam != null) { | |||||
| try { | |||||
| int planId = Integer.parseInt(idParam); | |||||
| DetalleMantenimientoModel detalle = service.getDetalleMantenimientoPorPlanAnualId(planId); | |||||
| if (detalle != null) { | |||||
| this.planAnualIdActual = detalle.getPlanAnualId(); | |||||
| this.mantenimientoIdActual = detalle.getId(); | |||||
| id.setText("Plan ID: " + idParam); | |||||
| txtEquipo.setValue(String.valueOf(detalle.getNombreEquipo())); | |||||
| cbTipo.setValue( | |||||
| cbTipo.getListDataView().getItems() | |||||
| .filter(t -> t.getNombre().equals(detalle.getTipo())) | |||||
| .findFirst().orElse(null) | |||||
| ); | |||||
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); | |||||
| String fechaProg = detalle.getFechaprog() != null ? detalle.getFechaprog().format(formatter) : ""; | |||||
| String fechaReal = detalle.getFecha() != null ? detalle.getFecha().format(formatter) : ""; | |||||
| String situacion = detalle.getSituacion() != null ? detalle.getSituacion() : ""; | |||||
| txtFechaProgramada.setValue(fechaProg); | |||||
| txtFecha.setValue(fechaReal); | |||||
| txtSituacion.setValue(situacion); | |||||
| cbUsuario.setValue( | |||||
| cbUsuario.getListDataView().getItems() | |||||
| .filter(u -> u.getNombre().equals(detalle.getUsuario())) | |||||
| .findFirst().orElse(null) | |||||
| ); | |||||
| cbDepartamento.setValue( | |||||
| cbDepartamento.getListDataView().getItems() | |||||
| .filter(d -> d.getNombre().equals(detalle.getDepartamento())) | |||||
| .findFirst().orElse(null) | |||||
| ); | |||||
| int mantId = detalle.getId(); | |||||
| List<HardwareDetalle> listaHardware = service.getHardwaredetallePorMantId(mantId); | |||||
| gridHardware.setItems(listaHardware); | |||||
| List<ActualizacioneSeguridadModel> listaActualizaciones = service.getActualizacionesSeg(mantId); | |||||
| gridActualizaciones.setItems(listaActualizaciones); | |||||
| gridActualizaciones.setVisible(!listaActualizaciones.isEmpty()); | |||||
| // --- Mostrar firmas como imagen si existen --- | |||||
| // Firma usuario | |||||
| if (detalle.getFirmaUser() != null && !detalle.getFirmaUser().isEmpty()) { | |||||
| String firmaUser = detalle.getFirmaUser(); | |||||
| if (!firmaUser.startsWith("data:image")) { | |||||
| firmaUser = "data:image/png;base64," + firmaUser; | |||||
| } | |||||
| firmaUsuarioImg = new Image(firmaUser, "Firma del usuario"); | |||||
| firmaUsuarioImg.setHeight("200px"); | |||||
| firmaUsuarioImg.setWidthFull(); | |||||
| userSignLayout.replace(userSignPad, firmaUsuarioImg); | |||||
| } | |||||
| // Firma soporte | |||||
| if (detalle.getFirmaSmt() != null && !detalle.getFirmaSmt().isEmpty()) { | |||||
| String firmaSmt = detalle.getFirmaSmt(); | |||||
| if (!firmaSmt.startsWith("data:image")) { | |||||
| firmaSmt = "data:image/png;base64," + firmaSmt; | |||||
| } | |||||
| firmaSmtImg = new Image(firmaSmt, "Firma del usuario de soporte"); | |||||
| firmaSmtImg.setHeight("200px"); | |||||
| firmaSmtImg.setWidthFull(); | |||||
| smtSignLayout.replace(smtSignPad, firmaSmtImg); | |||||
| } | |||||
| Image firmaGcia = new Image("images/FirmaGerenteTI.png", "Firma de la Gcia. de T.I"); | |||||
| firmaGcia.setHeight("200px"); | |||||
| firmaGcia.setWidthFull(); | |||||
| gciaSignLayout.replace(gciaSignPad, firmaGcia); | |||||
| } else { | |||||
| id.setText("No se encontro informacion para el Plan ID: " + planId); | |||||
| } | |||||
| } catch (NumberFormatException e) { | |||||
| id.setText("ID no valido"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,109 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import com.vaadin.flow.component.applayout.AppLayout; | |||||
| import com.vaadin.flow.component.applayout.DrawerToggle; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.component.button.ButtonVariant; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.html.*; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.orderedlayout.FlexComponent; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.Scroller; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.sidenav.SideNav; | |||||
| import com.vaadin.flow.component.sidenav.SideNavItem; | |||||
| import com.vaadin.flow.theme.lumo.LumoUtility; | |||||
| import mx.gob.jumapacelaya.services.SecurityService; | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class MainLayout extends AppLayout { | |||||
| private H2 viewTitle; | |||||
| private final SecurityService securityService; | |||||
| public MainLayout(SecurityService securityService) { | |||||
| this.securityService = securityService; | |||||
| this.addClassName("app-layout"); | |||||
| setPrimarySection(Section.DRAWER); | |||||
| addDrawerContent(); | |||||
| addHeaderContent(); | |||||
| } | |||||
| private void addHeaderContent() { | |||||
| DrawerToggle toggle = new DrawerToggle(); | |||||
| toggle.setAriaLabel("Menu toggle"); | |||||
| toggle.addClassName("drawer-toggle"); | |||||
| viewTitle = new H2(); | |||||
| viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE); | |||||
| viewTitle.getStyle().set("font-weight", "bold"); | |||||
| viewTitle.getStyle().set("color", "#691B31"); | |||||
| viewTitle.getStyle().set("font-size", "25px"); | |||||
| String u = securityService.getAuthenticatedUser(); | |||||
| Span usrNameLabel = new Span(u); | |||||
| usrNameLabel.getStyle().set("color", "#691b31"); | |||||
| usrNameLabel.getStyle().set("font-weight", "bold"); | |||||
| usrNameLabel.getStyle().set("font-size", "20px"); | |||||
| Button logoutButton = new Button("Cerrar sesión", VaadinIcon.SIGN_OUT.create(),event -> { | |||||
| securityService.logout(); | |||||
| }); | |||||
| logoutButton.addClassName("logout-button"); | |||||
| logoutButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY ,ButtonVariant.LUMO_ERROR); | |||||
| HorizontalLayout headerContent = new HorizontalLayout(); | |||||
| headerContent.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); | |||||
| headerContent.addClassName("header-content"); | |||||
| headerContent.add(viewTitle); | |||||
| headerContent.setFlexGrow(1, viewTitle); | |||||
| headerContent.add(usrNameLabel, logoutButton); | |||||
| addToNavbar(false, toggle, headerContent); | |||||
| } | |||||
| private void addDrawerContent() { | |||||
| VerticalLayout headerLayout = new VerticalLayout(); | |||||
| headerLayout.setPadding(true); | |||||
| headerLayout.setSpacing(false); | |||||
| headerLayout.setAlignItems(FlexComponent.Alignment.CENTER); | |||||
| headerLayout.getStyle().set("background-color", "#DDC9A3"); | |||||
| Image imgLogo = new Image("images/LOGO_900X160.png", "Logo"); | |||||
| imgLogo.setWidthFull(); | |||||
| headerLayout.add(imgLogo); | |||||
| Scroller scroller = new Scroller(createNavigation()); | |||||
| scroller.getStyle().set("background-color", "#691b31"); | |||||
| addToDrawer(headerLayout, scroller, createFooter()); | |||||
| } | |||||
| private SideNav createNavigation() { | |||||
| SideNav nav = new SideNav(); | |||||
| nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create())); | |||||
| nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create())); | |||||
| nav.addItem(new SideNavItem("Mantenimiento Correctivo", MantCorrectivoView.class, VaadinIcon.WRENCH.create())); | |||||
| nav.getStyle().set("background-color", "white"); | |||||
| nav.getStyle().set("border-radius", "5px"); | |||||
| nav.getStyle().set("opacity", "0.9"); | |||||
| return nav; | |||||
| } | |||||
| private Footer createFooter() { | |||||
| Footer layout = new Footer(); | |||||
| return layout; | |||||
| } | |||||
| @Override | |||||
| protected void afterNavigation() { | |||||
| super.afterNavigation(); | |||||
| viewTitle.setText("Mantenimiento de Hardware"); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,693 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import com.vaadin.flow.component.Text; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.component.button.ButtonVariant; | |||||
| import com.vaadin.flow.component.checkbox.CheckboxGroup; | |||||
| import com.vaadin.flow.component.combobox.ComboBox; | |||||
| import com.vaadin.flow.component.datepicker.DatePicker; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.dialog.Dialog; | |||||
| import com.vaadin.flow.component.formlayout.FormLayout; | |||||
| import com.vaadin.flow.component.grid.Grid; | |||||
| import com.vaadin.flow.component.grid.GridVariant; | |||||
| import com.vaadin.flow.component.html.Image; | |||||
| import com.vaadin.flow.component.html.Span; | |||||
| import com.vaadin.flow.component.icon.Icon; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import com.vaadin.flow.component.notification.NotificationVariant; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.radiobutton.RadioButtonGroup; | |||||
| import com.vaadin.flow.component.textfield.TextArea; | |||||
| import com.vaadin.flow.component.textfield.TextField; | |||||
| import com.vaadin.flow.data.renderer.ComponentRenderer; | |||||
| import com.vaadin.flow.function.ValueProvider; | |||||
| import com.vaadin.flow.router.BeforeEnterEvent; | |||||
| import com.vaadin.flow.router.BeforeEnterObserver; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import de.f0rce.signaturepad.SignaturePad; | |||||
| import jakarta.annotation.security.PermitAll; | |||||
| import mx.gob.jumapacelaya.models.*; | |||||
| import mx.gob.jumapacelaya.services.DatabaseService; | |||||
| import mx.gob.jumapacelaya.services.EmailService; | |||||
| import mx.gob.jumapacelaya.services.SecurityService; | |||||
| import mx.gob.jumapacelaya.services.UserService; | |||||
| import org.vaadin.lineawesome.LineAwesomeIcon; | |||||
| import java.time.LocalDate; | |||||
| import java.time.format.DateTimeFormatter; | |||||
| import java.util.*; | |||||
| @PermitAll | |||||
| @PageTitle("Correctivo") | |||||
| @Route(value = "correctivo", layout = MainLayout.class) | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class MantCorrectivoView extends VerticalLayout { | |||||
| private VerticalLayout mainLayout; | |||||
| private final SecurityService securityService; | |||||
| private final VerticalLayout controlsLayout; | |||||
| private final DatabaseService databaseService; | |||||
| private final VerticalLayout actualizacionesLayout; | |||||
| //private final VerticalLayout etiquetaLayout; | |||||
| private final HorizontalLayout firmasLayout; | |||||
| private final DatePicker fecha; | |||||
| private final ComboBox<TiposMantenimiento> tipoMantt; | |||||
| private final ComboBox<DepartamentosModel> area; | |||||
| private final ComboBox<Usuario> usuario; | |||||
| private final TextField txtNombreEquipo; | |||||
| private final UserService userService; | |||||
| private final EmailService emailService; | |||||
| private RadioButtonGroup<String> formaGroup; | |||||
| private CheckboxGroup<String> actualizaciones; | |||||
| private final HorizontalLayout botonesLayout; | |||||
| private TextArea txtCuales; | |||||
| private RadioButtonGroup<String> masActualizacionesGroup; | |||||
| private SignaturePad userSignPad; | |||||
| private SignaturePad smtSignPad; | |||||
| private SignaturePad gciatiSignPad; | |||||
| private PlanAnual planAnualActual; | |||||
| private LocalDate fechaProgramada; | |||||
| private LocalDate fechaSeleccionada; | |||||
| private TextArea jsutificacion; | |||||
| Span userSignSpan = new Span("Nombre Usuario"); | |||||
| private TextArea txtReparacion; | |||||
| private HorizontalLayout headerLayout; | |||||
| public MantCorrectivoView(UserService userService, SecurityService securityService, EmailService emailService, DatabaseService databaseService) { | |||||
| this.databaseService = databaseService; | |||||
| this.controlsLayout = new VerticalLayout(); | |||||
| this.actualizacionesLayout = new VerticalLayout(); | |||||
| //this.etiquetaLayout = new VerticalLayout(); | |||||
| this.firmasLayout = new HorizontalLayout(); | |||||
| this.botonesLayout = new HorizontalLayout(); | |||||
| this.securityService = securityService; | |||||
| this.userService = userService; | |||||
| this.emailService = emailService; | |||||
| headerLayout = new HorizontalLayout(); | |||||
| headerLayout.setWidthFull(); | |||||
| headerLayout.setMargin(false); | |||||
| headerLayout.getStyle() | |||||
| .set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)") | |||||
| .set("border-radius", "10px") | |||||
| .set("background-color", "white") | |||||
| .set("padding", "1rem") | |||||
| .set("margin", "1rem auto"); | |||||
| mainLayout = new VerticalLayout(); | |||||
| mainLayout.setHeightFull(); | |||||
| mainLayout.setMargin(false); | |||||
| mainLayout.getStyle() | |||||
| .set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)") | |||||
| .set("border-radius", "12px") | |||||
| .set("background-color", "white") | |||||
| .set("padding", "1rem") | |||||
| .set("margin", "1rem auto"); | |||||
| TextField nomenclatura = new TextField("Nomenclatura"); | |||||
| nomenclatura.setReadOnly(true); | |||||
| nomenclatura.addClassName("mantenimiento-text-field"); | |||||
| Button btnListado = new Button("Mantenimientos realizados", VaadinIcon.CLIPBOARD_CHECK.create()); | |||||
| btnListado.addClickListener(e -> verListadoMantenimientos()); | |||||
| fecha = new DatePicker("Fecha:"); | |||||
| fecha.setRequired(true); | |||||
| fecha.setLocale(new Locale("es", "MX")); | |||||
| DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() | |||||
| .setWeekdays(List.of("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado")) | |||||
| .setWeekdaysShort(List.of("Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb")) | |||||
| .setMonthNames(List.of("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")) | |||||
| .setFirstDayOfWeek(1) | |||||
| .setToday("Hoy") | |||||
| .setCancel("Cancelar") | |||||
| .setDateFormat("dd/MM/yyyy"); | |||||
| fecha.setI18n(i18n); | |||||
| tipoMantt = new ComboBox<>("Tipo de Mantenimiento"); | |||||
| List<TiposMantenimiento> tiposMantenimiento = databaseService.getTiposDeMantenimientos(); | |||||
| tipoMantt.setItems(tiposMantenimiento); | |||||
| tipoMantt.addClassName("mantenimiento-combo"); | |||||
| // Listener para manejar el cambio en el tipo de mantenimiento | |||||
| tipoMantt.addValueChangeListener(e -> { | |||||
| TiposMantenimiento tipoSeleccionado = e.getValue(); | |||||
| if (tipoSeleccionado != null) { | |||||
| String nomenclaturaValue = databaseService.getNomenclatura(tipoSeleccionado.getTipomantId()); | |||||
| nomenclatura.setValue(nomenclaturaValue); | |||||
| fecha.setValue(LocalDate.now()); | |||||
| } | |||||
| }); | |||||
| HorizontalLayout fechaLayout = new HorizontalLayout(); | |||||
| fechaLayout.add(fecha); | |||||
| fechaLayout.addAndExpand(new HorizontalLayout()); | |||||
| fechaLayout.add(tipoMantt, nomenclatura); | |||||
| fechaLayout.setWidthFull(); | |||||
| HorizontalLayout departamentoUsuarioLayout = new HorizontalLayout(); | |||||
| area = new ComboBox<>("Área o Departamento:"); | |||||
| area.setRequired(true); | |||||
| List<DepartamentosModel> areas = databaseService.getDepartamentos(); | |||||
| area.setItems(areas); | |||||
| usuario = new ComboBox<>("Usuario:"); | |||||
| List<Usuario> usuarios = databaseService.getUsuarios(); | |||||
| usuario.setItems(usuarios); | |||||
| usuario.setItemLabelGenerator(Usuario::getNombre); | |||||
| usuario.setRequired(true); | |||||
| usuario.addValueChangeListener(e -> { | |||||
| Usuario usuarioSeleccionado = e.getValue(); | |||||
| if (usuarioSeleccionado != null) { | |||||
| String empleadoId = usuarioSeleccionado.getEmpleadoId(); | |||||
| String nombreUsuario = usuarioSeleccionado.getNombre(); | |||||
| //userSignSpan.setText(nombreUsuario); | |||||
| } else { | |||||
| //userSignSpan.setText("S.M.T Nombre"); | |||||
| } | |||||
| }); | |||||
| txtNombreEquipo = new TextField("Nombre del Equipo:"); | |||||
| departamentoUsuarioLayout.add(area, usuario, txtNombreEquipo); | |||||
| departamentoUsuarioLayout.setWidthFull(); | |||||
| createHardwareSection(databaseService); | |||||
| addActualizacionesSection(); | |||||
| signLayout(); | |||||
| buttons(); | |||||
| headerLayout.add(btnListado); | |||||
| mainLayout.add(fechaLayout, departamentoUsuarioLayout, controlsLayout, actualizacionesLayout, firmasLayout, botonesLayout); | |||||
| add(headerLayout, mainLayout); | |||||
| } | |||||
| // Metodo para inicializar el formulario de hardware | |||||
| private void createHardwareSection(DatabaseService databaseService) { | |||||
| HorizontalLayout etiquetaLayout = new HorizontalLayout(); | |||||
| Span etiqueta = new Span("Limpieza de Equipo Realizada"); | |||||
| Button btnAgregarTipo = new Button(new Icon(VaadinIcon.PLUS)); | |||||
| btnAgregarTipo.addThemeVariants(ButtonVariant.LUMO_ICON); | |||||
| btnAgregarTipo.setAriaLabel("Agregar Equipo"); | |||||
| btnAgregarTipo.addClickListener(e -> { | |||||
| addNuevoTipo(); | |||||
| }); | |||||
| etiquetaLayout.add(etiqueta, btnAgregarTipo); | |||||
| controlsLayout.add(etiquetaLayout); | |||||
| controlsLayout.setSpacing(false); | |||||
| addNuevoTipo(); | |||||
| } | |||||
| // Método para crear el combo box y campos de texto para eñ hardware en tiempo de ejecución | |||||
| private List<HorizontalLayout> hardwareLayouts = new ArrayList<>(); | |||||
| private void addNuevoTipo() { | |||||
| ComboBox<TiposHardware> tipoHardware = new ComboBox<>(); | |||||
| tipoHardware.setPlaceholder("Tipos de Hardware"); | |||||
| tipoHardware.setItemLabelGenerator(TiposHardware::getNombreHardware); | |||||
| tipoHardware.setItems(databaseService.getTiposHardware()); | |||||
| tipoHardware.setSizeFull(); | |||||
| TextField noSerie = new TextField(); | |||||
| noSerie.setEnabled(false); | |||||
| noSerie.setRequired(true); | |||||
| noSerie.setPlaceholder("No. de Serie"); | |||||
| noSerie.setSizeFull(); | |||||
| noSerie.addValueChangeListener(e -> { | |||||
| String upperCaseValue = e.getValue().toUpperCase(); | |||||
| noSerie.setValue(upperCaseValue); | |||||
| }); | |||||
| TextField modelo = new TextField(); | |||||
| modelo.setEnabled(false); | |||||
| modelo.setRequired(true); | |||||
| modelo.setPlaceholder("Modelo"); | |||||
| modelo.setSizeFull(); | |||||
| modelo.addValueChangeListener(event -> { | |||||
| String upperCaseValue = event.getValue().toUpperCase(); | |||||
| modelo.setValue(upperCaseValue); | |||||
| }); | |||||
| TextField placa = new TextField(); | |||||
| placa.setEnabled(false); | |||||
| placa.setRequired(true); | |||||
| placa.setPlaceholder("Placa"); | |||||
| placa.setSizeFull(); | |||||
| // Validacion para que este campo solo acepte numeros | |||||
| placa.getElement().executeJs( | |||||
| "this.addEventListener('input', function(e) { " + | |||||
| " e.target.value = e.target.value.replace(/[^0-9]/g, '');" + // Solo permite dígitos | |||||
| "});" | |||||
| ); | |||||
| tipoHardware.addValueChangeListener(event -> { | |||||
| TiposHardware tipoSeleccionado = event.getValue(); | |||||
| if (tipoSeleccionado != null) { | |||||
| String nombreTipo = tipoSeleccionado.getNombreHardware(); | |||||
| if ("TECLADO".equals(nombreTipo)) { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } else if ("MOUSE".equals(nombreTipo)) { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } else { | |||||
| noSerie.setEnabled(true); | |||||
| modelo.setEnabled(true); | |||||
| placa.setEnabled(true); | |||||
| } | |||||
| } else { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } | |||||
| }); | |||||
| Button btnEliminar = new Button(new Icon(VaadinIcon.TRASH)); | |||||
| btnEliminar.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_ERROR); | |||||
| btnEliminar.setAriaLabel("Eliminar Tipo"); | |||||
| //Crear nuevo layout horizontal con estos campos | |||||
| HorizontalLayout hardwareDetailsLayout = new HorizontalLayout(); | |||||
| hardwareDetailsLayout.add(tipoHardware, noSerie, modelo, placa, btnEliminar); | |||||
| hardwareDetailsLayout.setWidthFull(); | |||||
| hardwareLayouts.add(hardwareDetailsLayout); | |||||
| controlsLayout.add(hardwareDetailsLayout); | |||||
| //Listener para eliminar el tipo | |||||
| btnEliminar.addClickListener(event -> { | |||||
| controlsLayout.remove(hardwareDetailsLayout); | |||||
| }); | |||||
| controlsLayout.add(hardwareDetailsLayout); | |||||
| controlsLayout.setSizeFull(); | |||||
| } | |||||
| private void addActualizacionesSection() { | |||||
| VerticalLayout etiquetaLayout = new VerticalLayout(); | |||||
| Span Titulo = new Span("Actualizaciones de Seguridad Informatica:"); | |||||
| etiquetaLayout.add(Titulo); | |||||
| actualizaciones = new CheckboxGroup<>(); | |||||
| actualizaciones.setLabel("Actualizaciones Necesarias"); | |||||
| actualizaciones.setItems("S.O", "Antivirus", "Firewall"); | |||||
| formaGroup = new RadioButtonGroup<>(); | |||||
| formaGroup.setLabel("Actividad Realizada de Forma:"); | |||||
| formaGroup.setRequired(true); | |||||
| formaGroup.setItems("Remota", "Manual"); | |||||
| txtCuales = new TextArea(); | |||||
| txtCuales.setLabel("¿Cuáles?"); | |||||
| txtCuales.setEnabled(false); | |||||
| txtCuales.setWidthFull(); | |||||
| masActualizacionesGroup = new RadioButtonGroup<>(); | |||||
| masActualizacionesGroup.setRequired(true); | |||||
| masActualizacionesGroup.setLabel("¿Requiere más actualizaciones?"); | |||||
| masActualizacionesGroup.setItems("Si", "No"); | |||||
| masActualizacionesGroup.addValueChangeListener(e -> { | |||||
| if ("Si".equals(e.getValue())) { | |||||
| txtCuales.setEnabled(true); | |||||
| txtCuales.setRequired(true); | |||||
| txtCuales.clear(); | |||||
| } else { | |||||
| txtCuales.setEnabled(false); | |||||
| txtCuales.setRequired(false); | |||||
| txtCuales.clear(); | |||||
| } | |||||
| }); | |||||
| txtReparacion = new TextArea("Reparación Realizada:"); | |||||
| txtReparacion.setWidthFull(); | |||||
| txtReparacion.setHeight("100px"); | |||||
| HorizontalLayout formasLayout = new HorizontalLayout(); | |||||
| formasLayout.add(formaGroup, masActualizacionesGroup, txtCuales); | |||||
| formasLayout.setSizeFull(); | |||||
| actualizacionesLayout.add(Titulo, actualizaciones, formasLayout, txtReparacion); | |||||
| actualizacionesLayout.setSpacing(false); | |||||
| } | |||||
| private void signLayout() { | |||||
| VerticalLayout userSignLayout = new VerticalLayout(); | |||||
| userSignPad = new SignaturePad(); | |||||
| userSignPad.setBackgroundColor("#FFFFFF"); | |||||
| userSignPad.setHeight("200px"); | |||||
| userSignPad.setPenColor("#000000"); | |||||
| userSignPad.getElement().getStyle().set("border", "1px solid black"); | |||||
| Span tituloUser = new Span("Usuario Interno"); | |||||
| userSignLayout.setSizeFull(); | |||||
| userSignLayout.setSpacing(true); | |||||
| userSignLayout.setSpacing(false); | |||||
| userSignLayout.setAlignItems(Alignment.CENTER); | |||||
| userSignLayout.add(userSignPad, userSignSpan, tituloUser); | |||||
| VerticalLayout smtSignLayout = new VerticalLayout(); | |||||
| smtSignPad = new SignaturePad(); | |||||
| smtSignPad.setHeight("200px"); | |||||
| smtSignPad.setBackgroundColor("#FFFFFF"); | |||||
| smtSignPad.setPenColor("#000000"); | |||||
| smtSignPad.getElement().getStyle().set("border", "1px solid black"); | |||||
| String u = securityService.getAuthenticatedUser(); | |||||
| Span smtSignSpan = new Span(u); | |||||
| Span tituloSMT = new Span("Responsable de Soporte"); | |||||
| smtSignLayout.setSizeFull(); | |||||
| smtSignLayout.setSpacing(true); | |||||
| smtSignLayout.setSpacing(false); | |||||
| smtSignLayout.setAlignItems(Alignment.CENTER); | |||||
| smtSignLayout.add(smtSignPad, smtSignSpan, tituloSMT); | |||||
| VerticalLayout gcialSignLayout = new VerticalLayout(); | |||||
| Image firmaGcia = new Image("images/FirmaGerenteTI.png", "Firma Gerente de Sistemas"); | |||||
| firmaGcia.setHeight("200px"); | |||||
| firmaGcia.setWidthFull(); | |||||
| Span gciatiSignSpan = new Span("Ing. Javier Patiño Martinez"); | |||||
| Span tituloGerente = new Span("Gerente de T.I"); | |||||
| gcialSignLayout.setSizeFull(); | |||||
| gcialSignLayout.setSpacing(false); | |||||
| gcialSignLayout.setAlignItems(Alignment.CENTER); | |||||
| gcialSignLayout.add(firmaGcia, gciatiSignSpan, tituloGerente); | |||||
| firmasLayout.add(userSignLayout, smtSignLayout, gcialSignLayout); | |||||
| firmasLayout.setWidthFull(); | |||||
| firmasLayout.setSpacing(false); | |||||
| firmasLayout.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| } | |||||
| // Metodo para verificar si la firma corresponde a una cadena de firma vacia | |||||
| private boolean esFirmaVacia(String firmaBase64) { | |||||
| String firmaVacia = "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD8CAYAAACSCdTiAAAIbElEQVR4Xu3UAQ0AIAwDQeZfNCPI+Nwc9Lp07rvjCBAgQCApMEY+2atQBAgQ+AJG3iMQIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBBYAuXtOkIWm1QAAAAASUVORK5CYII="; | |||||
| return firmaBase64.equals(firmaVacia); | |||||
| } | |||||
| private void buttons() { | |||||
| VerticalLayout buttonsLayout = new VerticalLayout(); | |||||
| Button btnGuardar = new Button("Guardar", LineAwesomeIcon.SAVE.create()); | |||||
| btnGuardar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| btnGuardar.addThemeVariants(ButtonVariant.LUMO_LARGE); | |||||
| btnGuardar.addClickListener(event -> { | |||||
| fechaSeleccionada = fecha.getValue(); | |||||
| guardarMantenimiento(); | |||||
| }); | |||||
| buttonsLayout.setSizeFull(); | |||||
| buttonsLayout.add(btnGuardar); | |||||
| buttonsLayout.setAlignItems(Alignment.CENTER); | |||||
| botonesLayout.add(buttonsLayout); | |||||
| botonesLayout.setSizeFull(); | |||||
| //botonesLayout.setAlignItems(Alignment.CENTER); | |||||
| } | |||||
| // METODO PARA ENVIAR CORREOS ELECTRONICOS | |||||
| private void enviarCorreo() { | |||||
| Usuario usuarioSeleccionado = usuario.getValue(); | |||||
| if (usuarioSeleccionado != null && usuarioSeleccionado.getEmail() != null) { | |||||
| String destinatario = usuarioSeleccionado.getEmail(); | |||||
| String asunto = "MANTENIMIENTO DE EQUIPO DE COMPUTO REALIZADO"; | |||||
| String cuerpo = "<html>" + | |||||
| "<body>" + | |||||
| "<img src='cid:image_id'/>" + | |||||
| "</body>" + | |||||
| "</html>"; | |||||
| String imagePath = "META-INF/resources/images/imgCorreo/correoMantt.png"; | |||||
| emailService.enviarCorreo(destinatario, asunto, cuerpo, imagePath); | |||||
| } else { | |||||
| Notification.show("Por favor selecciona un usuario", 4000, Notification.Position.MIDDLE); | |||||
| } | |||||
| } | |||||
| private void guardarMantenimiento() { | |||||
| TiposMantenimiento tiposMantenimiento = tipoMantt.getValue(); | |||||
| String tipoMantId = tiposMantenimiento != null ? tiposMantenimiento.getTipomantId() : null; | |||||
| String justificacionValue = jsutificacion != null ? jsutificacion.getValue() : null; | |||||
| String reparacionValue = txtReparacion != null ? txtReparacion.getValue() : null; | |||||
| DepartamentosModel departamentoSeleccionado = area.getValue(); | |||||
| String departamentoId = departamentoSeleccionado != null ? departamentoSeleccionado.getDepartamentoId().toString() : null; | |||||
| Usuario usuarioSeleccionado = usuario.getValue(); | |||||
| String empleadoId = usuarioSeleccionado != null ? usuarioSeleccionado.getEmpleadoId().toString() : null; | |||||
| String equipoId = txtNombreEquipo.getValue(); | |||||
| String formaSeleccionada = formaGroup.getValue(); | |||||
| String formaMantt = null; | |||||
| if ("Remota".equals(formaSeleccionada)) { | |||||
| formaMantt = "R"; | |||||
| } else if ("Manual".equals(formaSeleccionada)) { | |||||
| formaMantt = "M"; | |||||
| } | |||||
| // Validación de campos obligatorios | |||||
| if (fechaSeleccionada == null || tipoMantId == null || departamentoId == null || empleadoId == null || | |||||
| equipoId == null || equipoId.trim().isEmpty() || formaMantt == null) { | |||||
| Notification.show("Por favor, completa todos los campos requeridos", 4000, Notification.Position.MIDDLE); | |||||
| return; | |||||
| } | |||||
| byte[] userSignatureBytes = userSignPad.getImageBase64(); | |||||
| byte[] smtSignatureBytes = smtSignPad.getImageBase64(); | |||||
| //byte[] gciaSignatureBytes = gciatiSignPad.getImageBase64(); | |||||
| String userSignatureBase64 = Base64.getEncoder().encodeToString(userSignatureBytes); | |||||
| String smtSignatureBase64 = Base64.getEncoder().encodeToString(smtSignatureBytes); | |||||
| //String gciaSignatureBase64 = Base64.getEncoder().encodeToString(gciaSignatureBytes); | |||||
| if (esFirmaVacia(userSignatureBase64)) userSignatureBase64 = null; | |||||
| if (esFirmaVacia(smtSignatureBase64)) smtSignatureBase64 = null; | |||||
| //if (esFirmaVacia(gciaSignatureBase64)) gciaSignatureBase64 = null; | |||||
| // Validación de campos de hardware | |||||
| List<Map<String, String>> detallesHardware = new ArrayList<>(); | |||||
| for (HorizontalLayout layout : hardwareLayouts) { | |||||
| ComboBox<TiposHardware> tipoHardware = (ComboBox<TiposHardware>) layout.getComponentAt(0); | |||||
| TextField noSerie = (TextField) layout.getComponentAt(1); | |||||
| TextField modelo = (TextField) layout.getComponentAt(2); | |||||
| TextField placa = (TextField) layout.getComponentAt(3); | |||||
| TiposHardware tipoSeleccionado = tipoHardware.getValue(); | |||||
| if (tipoSeleccionado == null) { | |||||
| Notification.show("Por favor, selecciona un tipo de hardware", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| boolean esOpcional = Arrays.asList("TECLADO", "MOUSE").contains(tipoSeleccionado.getNombreHardware()); | |||||
| String numSerie = noSerie.getValue(); | |||||
| String modeloVal = modelo.getValue(); | |||||
| String placaVal = placa.getValue(); | |||||
| if (!esOpcional && (modeloVal == null || modeloVal.isEmpty() || numSerie == null || numSerie.isEmpty() || placaVal == null || placaVal.isEmpty())) { | |||||
| Notification.show("Por favor, completa todos los campos de hardware.", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| Map<String, String> hw = new HashMap<>(); | |||||
| hw.put("tipoHardwareId", tipoSeleccionado.getTipoHardwareId()); | |||||
| hw.put("numSerie", numSerie); | |||||
| hw.put("modelo", modeloVal); | |||||
| hw.put("placa", placaVal); | |||||
| detallesHardware.add(hw); | |||||
| } | |||||
| Set<String> actualizacionesSeleccionadas = actualizaciones.getSelectedItems(); | |||||
| String otrasActualizaciones = null; | |||||
| if ("Si".equals(masActualizacionesGroup.getValue())) { | |||||
| otrasActualizaciones = txtCuales.getValue(); | |||||
| if (otrasActualizaciones == null || otrasActualizaciones.trim().isEmpty()) { | |||||
| Notification.show("Especifica las otras actualizaciones", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // Una vez que validamos todos los campos del formulario, procedemos a insertar en BD | |||||
| try { | |||||
| int isInserted = databaseService.insertarMantenimiento(fechaSeleccionada, tipoMantId, departamentoId, empleadoId, formaMantt, equipoId, userSignatureBase64, smtSignatureBase64, null, justificacionValue, reparacionValue); | |||||
| if (isInserted <= 0) { | |||||
| Notification.show("Error al guardar el mantenimiento", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| int mantenimientoId = databaseService.getUltimoMantenimientoId(); | |||||
| for (Map<String, String> hw : detallesHardware) { | |||||
| boolean ok = databaseService.insertarHardware( | |||||
| hw.get("tipoHardwareId"), | |||||
| hw.get("numSerie"), | |||||
| hw.get("modelo"), | |||||
| hw.get("placa"), | |||||
| mantenimientoId | |||||
| ); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar detalles del hardware: ", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| for (String act : actualizacionesSeleccionadas) { | |||||
| boolean ok = databaseService.insertActualizacionSeg(act, null, mantenimientoId); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar actualización de seguridad", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| if (otrasActualizaciones != null) { | |||||
| boolean ok = databaseService.insertActualizacionSeg("Otras", otrasActualizaciones, mantenimientoId); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar otras actualizaciones", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // === EXITO === | |||||
| Notification.show("¡Mantenimiento guardado exitosamente!", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| try { | |||||
| enviarCorreo(); | |||||
| } catch (Exception e) { | |||||
| Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| // Limpiar campos | |||||
| fecha.clear(); | |||||
| tipoMantt.clear(); | |||||
| area.clear(); | |||||
| usuario.clear(); | |||||
| txtNombreEquipo.clear(); | |||||
| formaGroup.clear(); | |||||
| actualizaciones.clear(); | |||||
| masActualizacionesGroup.clear(); | |||||
| txtCuales.clear(); | |||||
| userSignPad.clear(); | |||||
| smtSignPad.clear(); | |||||
| //gciatiSignPad.clear(); | |||||
| txtReparacion.clear(); | |||||
| for (HorizontalLayout layout : hardwareLayouts) { | |||||
| ((ComboBox<?>) layout.getComponentAt(0)).clear(); | |||||
| ((TextField) layout.getComponentAt(1)).clear(); | |||||
| ((TextField) layout.getComponentAt(2)).clear(); | |||||
| ((TextField) layout.getComponentAt(3)).clear(); | |||||
| } | |||||
| UI.getCurrent().navigate("/"); | |||||
| } catch (Exception ex) { | |||||
| Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| ex.printStackTrace(); | |||||
| } | |||||
| } | |||||
| // Muestra un dialogo con el listado de los mantenimientos correctivos realizados | |||||
| private void verListadoMantenimientos() { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.setSizeFull(); | |||||
| dialog.setCloseOnEsc(true); | |||||
| dialog.setCloseOnOutsideClick(true); | |||||
| dialog.setHeaderTitle("Listado de Mantenimientos Correctivos"); | |||||
| Grid<MantCorrectivosModel> grid = new Grid<>(MantCorrectivosModel.class, false); | |||||
| grid.addColumn(MantCorrectivosModel::getMantenimientoId) | |||||
| .setHeader("No.").setAutoWidth(true); | |||||
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); | |||||
| grid.addColumn(item -> item.getFecha() != null ? item.getFecha().format(formatter) : "N/A") | |||||
| .setHeader("Fecha:").setAutoWidth(true); | |||||
| grid.addColumn(MantCorrectivosModel::getTipo) | |||||
| .setHeader("Tipo:").setAutoWidth(true); | |||||
| grid.addColumn(MantCorrectivosModel::getArea) | |||||
| .setHeader("Área:").setAutoWidth(true); | |||||
| grid.addColumn(MantCorrectivosModel::getNombre) | |||||
| .setHeader("Usuario:").setAutoWidth(true); | |||||
| grid.addColumn(MantCorrectivosModel::getForma) | |||||
| .setHeader("Forma:").setAutoWidth(true); | |||||
| grid.addColumn(MantCorrectivosModel::getNomequipo) | |||||
| .setHeader("Equipo:").setAutoWidth(true); | |||||
| grid.setItems(databaseService.getMantenimientosCorrectivos(2)); | |||||
| grid.setItemDetailsRenderer(ReparacionDetails.createReparacionesDetails()); | |||||
| grid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES); | |||||
| Button closeButton = new Button("Cerrar", e -> dialog.close()); | |||||
| closeButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| dialog.add(grid, closeButton); | |||||
| dialog.open(); | |||||
| } | |||||
| private static class ReparacionDetails extends FormLayout { | |||||
| private final TextArea txtReparacion = new TextArea("Reparación realizada:"); | |||||
| public ReparacionDetails() { | |||||
| txtReparacion.setReadOnly(true); | |||||
| add(txtReparacion); | |||||
| setResponsiveSteps(new ResponsiveStep("0", 1)); | |||||
| setColspan(txtReparacion, 1); | |||||
| } | |||||
| public void setModel(MantCorrectivosModel model) { | |||||
| txtReparacion.setValue(model.getReparacion() != null ? model.getReparacion() : ""); | |||||
| } | |||||
| private static ComponentRenderer<ReparacionDetails, MantCorrectivosModel> createReparacionesDetails() { | |||||
| return new ComponentRenderer<>(ReparacionDetails::new, ReparacionDetails::setModel); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,853 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import com.vaadin.flow.component.Component; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.button.ButtonVariant; | |||||
| import com.vaadin.flow.component.checkbox.CheckboxGroup; | |||||
| import com.vaadin.flow.component.combobox.ComboBox; | |||||
| import com.vaadin.flow.component.datepicker.DatePicker; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.dialog.Dialog; | |||||
| import com.vaadin.flow.component.html.H1; | |||||
| import com.vaadin.flow.component.html.H2; | |||||
| import com.vaadin.flow.component.html.Image; | |||||
| import com.vaadin.flow.component.html.Span; | |||||
| import com.vaadin.flow.component.icon.Icon; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import com.vaadin.flow.component.notification.NotificationVariant; | |||||
| import com.vaadin.flow.component.orderedlayout.FlexComponent; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.radiobutton.RadioButtonGroup; | |||||
| import com.vaadin.flow.component.textfield.NumberField; | |||||
| import com.vaadin.flow.component.textfield.TextArea; | |||||
| import com.vaadin.flow.component.textfield.TextField; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.router.BeforeEnterEvent; | |||||
| import com.vaadin.flow.router.BeforeEnterObserver; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import de.f0rce.signaturepad.SignaturePad; | |||||
| import jakarta.annotation.security.PermitAll; | |||||
| import mx.gob.jumapacelaya.models.*; | |||||
| import mx.gob.jumapacelaya.services.DatabaseService; | |||||
| import mx.gob.jumapacelaya.services.EmailService; | |||||
| import mx.gob.jumapacelaya.services.SecurityService; | |||||
| import mx.gob.jumapacelaya.services.UserService; | |||||
| import oracle.net.aso.h; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.vaadin.lineawesome.LineAwesomeIcon; | |||||
| import java.time.LocalDate; | |||||
| import java.util.*; | |||||
| @PermitAll | |||||
| @PageTitle("Mantenimiento") | |||||
| @Route(value = "mantenimiento", layout = MainLayout.class) | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class MantenimientoView extends VerticalLayout implements BeforeEnterObserver { | |||||
| private final SecurityService securityService; | |||||
| private final VerticalLayout controlsLayout; | |||||
| private final DatabaseService databaseService; | |||||
| private final VerticalLayout actualizacionesLayout; | |||||
| private final VerticalLayout etiquetaLayout; | |||||
| private final HorizontalLayout firmasLayout; | |||||
| private final DatePicker fecha; | |||||
| private final TextField txtPlananualID; | |||||
| private final ComboBox<TiposMantenimiento> tipoMantt; | |||||
| private final ComboBox<DepartamentosModel> area; | |||||
| private final ComboBox<Usuario> usuario; | |||||
| private final TextField txtNombreEquipo; | |||||
| private final UserService userService; | |||||
| private final EmailService emailService; | |||||
| private RadioButtonGroup<String> formaGroup; | |||||
| private CheckboxGroup<String> actualizaciones; | |||||
| private final HorizontalLayout botonesLayout; | |||||
| private TextArea txtCuales; | |||||
| private RadioButtonGroup<String> masActualizacionesGroup; | |||||
| private SignaturePad userSignPad; | |||||
| private SignaturePad smtSignPad; | |||||
| //private SignaturePad gciatiSignPad; | |||||
| private PlanAnual planAnualActual; | |||||
| private LocalDate fechaProgramada; | |||||
| private LocalDate fechaSeleccionada; | |||||
| private TextArea jsutificacion; | |||||
| private VerticalLayout mainLayout; | |||||
| Span userSignSpan = new Span("Nombre Usuario"); | |||||
| public MantenimientoView(UserService userService, SecurityService securityService, EmailService emailService, DatabaseService databaseService) { | |||||
| this.databaseService = databaseService; | |||||
| this.controlsLayout = new VerticalLayout(); | |||||
| this.actualizacionesLayout = new VerticalLayout(); | |||||
| this.etiquetaLayout = new VerticalLayout(); | |||||
| this.firmasLayout = new HorizontalLayout(); | |||||
| this.botonesLayout = new HorizontalLayout(); | |||||
| this.securityService = securityService; | |||||
| this.userService = userService; | |||||
| this.emailService = emailService; | |||||
| mainLayout = new VerticalLayout(); | |||||
| mainLayout.setHeightFull(); | |||||
| mainLayout.getStyle() | |||||
| .set("box-shadow","0 4px 8px rgba(0,0,0,0.2)") | |||||
| .set("border-radius", "12px") | |||||
| .set("background-color", "white") | |||||
| .set("padding", "1rem") | |||||
| .set("margin", "1rem auto"); | |||||
| HorizontalLayout fechaLayout = new HorizontalLayout(); | |||||
| //Componentes de texto | |||||
| TextField nomenclatura = new TextField("Nomenclatura"); | |||||
| nomenclatura.setReadOnly(true); | |||||
| nomenclatura.addClassName("mantenimiento-text-field"); | |||||
| TextArea otras = new TextArea("¿Cuales?"); | |||||
| otras.setEnabled(false); | |||||
| otras.addClassName("mantenimiento-text-field"); | |||||
| //Selector de fecha | |||||
| this.fecha = new DatePicker("Fecha"); | |||||
| fecha.setRequired(true); | |||||
| fecha.setLocale(new Locale("es", "MX")); | |||||
| DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() | |||||
| .setWeekdays(List.of("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")) | |||||
| .setWeekdaysShort(List.of("Dom","Lun","Mar","Mié","Jue","Vie","Sáb")) | |||||
| .setMonthNames(List.of("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")) | |||||
| .setFirstDayOfWeek(1) | |||||
| .setToday("Hoy") | |||||
| .setCancel("Cancelar") | |||||
| .setDateFormat("dd/MM/yyyy"); | |||||
| fecha.setI18n(i18n); | |||||
| // Campo de texto para el ID de MTTOPROGRAMADO | |||||
| this.txtPlananualID = new TextField("Plan Anual ID"); | |||||
| txtPlananualID.setReadOnly(true); | |||||
| txtPlananualID.addClassName("mantenimiento-text-field"); | |||||
| // ComboBox Tipo de Mantenimiento | |||||
| this.tipoMantt = new ComboBox<>("Tipo de Mantenimiento"); | |||||
| List<TiposMantenimiento> tiposMantenimiento = databaseService.getTiposDeMantenimientos(); | |||||
| tipoMantt.setItems(tiposMantenimiento); | |||||
| tipoMantt.addClassName("mantenimiento-combo"); | |||||
| // Listener para manejar el cambio en el tipo de mantenimiento | |||||
| tipoMantt.addValueChangeListener(event -> { | |||||
| TiposMantenimiento tipoSeleccionado = event.getValue(); | |||||
| if (tipoSeleccionado != null) { | |||||
| // Actualizar nomenclatura dependiendo del tipo de mantenimiento | |||||
| String nomenclaturaValue = databaseService.getNomenclatura(tipoSeleccionado.getTipomantId()); | |||||
| nomenclatura.setValue(nomenclaturaValue); | |||||
| // Si el tipo es preventivo se establecerá la fecha automáticamente a la fecha del sistema | |||||
| if ("1".equals(tipoSeleccionado.getTipomantId())) { // 1 es para PREVENTIVO | |||||
| this.fecha.setValue(LocalDate.now()); | |||||
| etiquetaLayout.setVisible(false); | |||||
| // Limpiar el layout de correctivo si es necesario | |||||
| etiquetaLayout.removeAll(); | |||||
| } else if ("2".equals(tipoSeleccionado.getTipomantId())) { // 2 es para CORRECTIVO | |||||
| this.fecha.clear(); | |||||
| etiquetaLayout.setVisible(true); | |||||
| //correctivoLayout(); | |||||
| } else { | |||||
| // Para otros tipos de mantenimiento | |||||
| this.fecha.clear(); | |||||
| etiquetaLayout.setVisible(false); | |||||
| etiquetaLayout.removeAll(); // Limpia el layout para otros tipos | |||||
| } | |||||
| } else { | |||||
| nomenclatura.clear(); | |||||
| this.fecha.clear(); | |||||
| etiquetaLayout.setVisible(false); | |||||
| etiquetaLayout.removeAll(); // Limpia el layout | |||||
| } | |||||
| }); | |||||
| fechaLayout.add(this.fecha/*, this.txtPlananualID*/); | |||||
| fechaLayout.addAndExpand(new HorizontalLayout()); | |||||
| fechaLayout.add(tipoMantt, nomenclatura); | |||||
| fechaLayout.setWidthFull(); | |||||
| HorizontalLayout departamentoLayout = new HorizontalLayout(); | |||||
| //ComboBox Area o Departamento | |||||
| this.area = new ComboBox<>("Area o Departamento"); | |||||
| area.setRequired(true); | |||||
| List<DepartamentosModel> areas = databaseService.getDepartamentos(); | |||||
| area.setItems(areas); | |||||
| this.usuario = new ComboBox<>("Usuario"); | |||||
| List<Usuario> usuarios = databaseService.getUsuarios(); | |||||
| usuario.setItems(usuarios); | |||||
| usuario.setItemLabelGenerator(Usuario::getNombre); | |||||
| usuario.setRequired(true); | |||||
| usuario.addValueChangeListener(event -> { | |||||
| Usuario usuarioSeleccionado = event.getValue(); | |||||
| if (usuarioSeleccionado != null) { | |||||
| String empleadoId = usuarioSeleccionado.getEmpleadoId(); | |||||
| String nombreUsuario = usuarioSeleccionado.getNombre(); | |||||
| userSignSpan.setText(nombreUsuario); | |||||
| } else { | |||||
| userSignSpan.setText("S.M.T Nombre"); | |||||
| } | |||||
| }); | |||||
| // Boton auxiliar para probar el envio de los correos electronicos | |||||
| Button btnEnviarCorreo = new Button("Enviar correo de prueba"); | |||||
| btnEnviarCorreo.addClickListener(event -> enviarCorreo()); | |||||
| this.txtNombreEquipo = new TextField("Nombre del Equipo"); | |||||
| txtNombreEquipo.setRequired(true); | |||||
| //txtNombreEquipo.setReadOnly(true); | |||||
| departamentoLayout.add(area, usuario/*, btnEnviarCorreo*/, txtNombreEquipo); | |||||
| departamentoLayout.setWidthFull(); | |||||
| createHardwareSection(databaseService); | |||||
| addActualizacionesSection(); | |||||
| //correctivoLayout(); | |||||
| signLayout(); | |||||
| buttons(); | |||||
| mainLayout.add(fechaLayout, departamentoLayout, controlsLayout, actualizacionesLayout, etiquetaLayout, firmasLayout, botonesLayout); | |||||
| add(mainLayout); | |||||
| } | |||||
| private void createHardwareSection(DatabaseService databaseService) { | |||||
| HorizontalLayout etiquetaLayout = new HorizontalLayout(); | |||||
| Span etiqueta = new Span("Limpieza de Equipo Realizada"); | |||||
| //Boton para agregar otro tipo de hardware | |||||
| Button btnAgregarTipo = new Button(new Icon(VaadinIcon.PLUS)); | |||||
| btnAgregarTipo.addThemeVariants(ButtonVariant.LUMO_ICON); | |||||
| btnAgregarTipo.setAriaLabel("Agregar Tipo"); | |||||
| //Listener del boton para agregar mas | |||||
| btnAgregarTipo.addClickListener(event -> { | |||||
| addNuevoTipo(); | |||||
| }); | |||||
| etiquetaLayout.add(etiqueta, btnAgregarTipo); | |||||
| controlsLayout.add(etiquetaLayout); | |||||
| controlsLayout.setSpacing(false); | |||||
| addNuevoTipo(); | |||||
| } | |||||
| //Metodo para agregar un nuevo ComboBox de tipo de hardware y campos de texto | |||||
| private List<HorizontalLayout> hardwareLayouts = new ArrayList<>(); | |||||
| private void addNuevoTipo() { | |||||
| ComboBox<TiposHardware> tipoHardware = new ComboBox<>(); | |||||
| tipoHardware.setPlaceholder("Tipo de hardware"); | |||||
| tipoHardware.setItemLabelGenerator(TiposHardware::getNombreHardware); | |||||
| tipoHardware.setItems(databaseService.getTiposHardware()); | |||||
| tipoHardware.setSizeFull(); | |||||
| TextField noSerie = new TextField(); | |||||
| noSerie.setEnabled(false); | |||||
| noSerie.setRequired(true); | |||||
| noSerie.setPlaceholder("No. Serie"); | |||||
| noSerie.setSizeFull(); | |||||
| noSerie.addValueChangeListener(event -> { | |||||
| String upperCaseValue = event.getValue().toUpperCase(); | |||||
| noSerie.setValue(upperCaseValue); | |||||
| }); | |||||
| // Validacion para que este campo solo acepte numeros | |||||
| /*noSerie.getElement().executeJs( | |||||
| "this.addEventListener('input', function(e) { " + | |||||
| " e.target.value = e.target.value.replace(/[^0-9]/g, '');" + // Solo permite dígitos | |||||
| "});" | |||||
| );*/ | |||||
| TextField modelo = new TextField(); | |||||
| modelo.setEnabled(false); | |||||
| modelo.setRequired(true); | |||||
| modelo.setPlaceholder("Modelo"); | |||||
| modelo.setSizeFull(); | |||||
| modelo.addValueChangeListener(event -> { | |||||
| String upperCaseValue = event.getValue().toUpperCase(); | |||||
| modelo.setValue(upperCaseValue); | |||||
| }); | |||||
| TextField placa = new TextField(); | |||||
| placa.setEnabled(false); | |||||
| placa.setRequired(true); | |||||
| placa.setPlaceholder("Placa"); | |||||
| placa.setSizeFull(); | |||||
| // Validacion para que este campo solo acepte numeros | |||||
| placa.getElement().executeJs( | |||||
| "this.addEventListener('input', function(e) { " + | |||||
| " e.target.value = e.target.value.replace(/[^0-9]/g, '');" + // Solo permite dígitos | |||||
| "});" | |||||
| ); | |||||
| tipoHardware.addValueChangeListener(event -> { | |||||
| TiposHardware tipoSeleccionado = event.getValue(); | |||||
| if (tipoSeleccionado != null) { | |||||
| String nombreTipo = tipoSeleccionado.getNombreHardware(); | |||||
| if ("TECLADO".equals(nombreTipo)) { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } else if ("MOUSE".equals(nombreTipo)) { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } else { | |||||
| noSerie.setEnabled(true); | |||||
| modelo.setEnabled(true); | |||||
| placa.setEnabled(true); | |||||
| } | |||||
| } else { | |||||
| noSerie.setEnabled(false); | |||||
| modelo.setEnabled(false); | |||||
| placa.setEnabled(false); | |||||
| } | |||||
| }); | |||||
| //Boton para eliminar ese conjunto de hardware | |||||
| Button btnEliminar = new Button(new Icon(VaadinIcon.TRASH)); | |||||
| btnEliminar.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_ERROR); | |||||
| btnEliminar.setAriaLabel("Eliminar Tipo"); | |||||
| //Crear nuevo layout horizontal con estos campos | |||||
| HorizontalLayout hardwareDetailsLayout = new HorizontalLayout(); | |||||
| hardwareDetailsLayout.add(tipoHardware, noSerie, modelo, placa, btnEliminar); | |||||
| hardwareDetailsLayout.setWidthFull(); | |||||
| hardwareLayouts.add(hardwareDetailsLayout); | |||||
| controlsLayout.add(hardwareDetailsLayout); | |||||
| //Listener para eliminar el tipo | |||||
| btnEliminar.addClickListener(event -> { | |||||
| controlsLayout.remove(hardwareDetailsLayout); | |||||
| }); | |||||
| controlsLayout.add(hardwareDetailsLayout); | |||||
| controlsLayout.setSizeFull(); | |||||
| } | |||||
| private void addActualizacionesSection() { | |||||
| VerticalLayout etiquetaLayout = new VerticalLayout(); | |||||
| Span Titulo = new Span("Actualizaciones de Seguridad Informatica:"); | |||||
| etiquetaLayout.add(Titulo); | |||||
| this.actualizaciones = new CheckboxGroup<>(); | |||||
| actualizaciones.setLabel("Actualizaciones Necesarias"); | |||||
| actualizaciones.setItems("S.O", "Antivirus", "Firewall"); | |||||
| this.formaGroup = new RadioButtonGroup<>(); | |||||
| formaGroup.setRequired(true); | |||||
| formaGroup.setLabel("Actividad Realizada de Forma:"); | |||||
| formaGroup.setItems("Remota", "Manual"); | |||||
| this.txtCuales = new TextArea(); | |||||
| txtCuales.setLabel("¿Cuales?"); | |||||
| txtCuales.setEnabled(false); | |||||
| txtCuales.setWidthFull(); | |||||
| this.masActualizacionesGroup= new RadioButtonGroup<>(); | |||||
| masActualizacionesGroup.setRequired(true); | |||||
| masActualizacionesGroup.setLabel("¿Requiere Más Actualizaciones?"); | |||||
| masActualizacionesGroup.setItems("Si","No"); | |||||
| masActualizacionesGroup.addValueChangeListener(event -> { | |||||
| if ("Si".equals(event.getValue())) { | |||||
| txtCuales.setEnabled(true); | |||||
| txtCuales.setRequired(true); | |||||
| txtCuales.setMaxHeight("100px"); | |||||
| } else { | |||||
| txtCuales.setEnabled(false); | |||||
| txtCuales.setRequired(false); | |||||
| txtCuales.clear(); | |||||
| } | |||||
| }); | |||||
| /*VerticalLayout actualizacionesGroup = new VerticalLayout(); | |||||
| actualizacionesGroup.add(actualizaciones);*/ | |||||
| HorizontalLayout formasLayout = new HorizontalLayout(); | |||||
| formasLayout.add(formaGroup, masActualizacionesGroup, txtCuales); | |||||
| formasLayout.setSizeFull(); | |||||
| actualizacionesLayout.add(Titulo, actualizaciones, formasLayout); | |||||
| actualizacionesLayout.setSpacing(false); | |||||
| } | |||||
| /* Formulario para cuando el mnatenimiento es de tipo CORRECTIVO */ | |||||
| /*private void correctivoLayout() { | |||||
| Span Titulo = new Span("Reparación Realizada al Equipo: "); | |||||
| // Verificar el ID del tipo de mantenimiento | |||||
| TiposMantenimiento tiposMantenimiento = tipoMantt.getValue(); | |||||
| if (tiposMantenimiento != null && "2".equals(tiposMantenimiento.getTipomantId())) { // Solo si el tipo es CORRECTIVO | |||||
| TextField txtModelo = new TextField(); | |||||
| txtModelo.setPlaceholder("Modelo"); | |||||
| txtModelo.setWidth("240px"); | |||||
| NumberField txtSerie = new NumberField(); | |||||
| txtSerie.setPlaceholder("No. Serie"); | |||||
| txtSerie.setWidth("240px"); | |||||
| TextField txtSoft = new TextField(); | |||||
| txtSoft.setPlaceholder("Instalación de Software"); | |||||
| txtSoft.setWidth("500px"); | |||||
| TextField txtRepHard = new TextField(); | |||||
| txtRepHard.setPlaceholder("Reparación de Hardware"); | |||||
| txtRepHard.setWidth("500px"); | |||||
| TextField txtCamDisp = new TextField(); | |||||
| txtCamDisp.setPlaceholder("Cambio de Dispositivo"); | |||||
| txtCamDisp.setWidth("500px"); | |||||
| HorizontalLayout model = new HorizontalLayout(); | |||||
| model.add(txtModelo, txtSerie, txtSoft); | |||||
| model.setSizeFull(); | |||||
| HorizontalLayout hard = new HorizontalLayout(); | |||||
| hard.add(txtRepHard, txtCamDisp); | |||||
| hard.setSizeFull(); | |||||
| etiquetaLayout.add(Titulo, model, hard); | |||||
| etiquetaLayout.setVisible(true); // Asegúrate de que el layout esté visible | |||||
| } else { | |||||
| etiquetaLayout.setVisible(false); // Ocultar si no es correctivo | |||||
| } | |||||
| }*/ | |||||
| private String emptySignature; | |||||
| private void signLayout() { | |||||
| VerticalLayout userSignLayout = new VerticalLayout(); | |||||
| userSignPad = new SignaturePad(); | |||||
| userSignPad.setBackgroundColor("#FFFFFF"); | |||||
| userSignPad.setHeight("200px"); | |||||
| userSignPad.setPenColor("#000000"); | |||||
| userSignPad.getElement().getStyle().set("border", "1px solid black"); | |||||
| Span tituloUser = new Span("Usuario Interno"); | |||||
| userSignLayout.setSizeFull(); | |||||
| userSignLayout.setSpacing(true); | |||||
| userSignLayout.setSpacing(false); | |||||
| userSignLayout.setAlignItems(Alignment.CENTER); | |||||
| userSignLayout.add(userSignPad, userSignSpan, tituloUser); | |||||
| VerticalLayout smtSignLayout = new VerticalLayout(); | |||||
| smtSignPad = new SignaturePad(); | |||||
| smtSignPad.setHeight("200px"); | |||||
| smtSignPad.setBackgroundColor("#FFFFFF"); | |||||
| smtSignPad.setPenColor("#000000"); | |||||
| smtSignPad.getElement().getStyle().set("border", "1px solid black"); | |||||
| String u = securityService.getAuthenticatedUser(); | |||||
| Span smtSignSpan = new Span(u); | |||||
| Span tituloSMT = new Span("Responsable de Soporte"); | |||||
| smtSignLayout.setSizeFull(); | |||||
| smtSignLayout.setSpacing(true); | |||||
| smtSignLayout.setSpacing(false); | |||||
| smtSignLayout.setAlignItems(Alignment.CENTER); | |||||
| smtSignLayout.add(smtSignPad, smtSignSpan, tituloSMT); | |||||
| VerticalLayout gcialSignLayout = new VerticalLayout(); | |||||
| Image firmaGcia = new Image("images/FirmaGerenteTI.png", "Firma Gerente de Sistemas"); | |||||
| firmaGcia.setHeight("200px"); | |||||
| firmaGcia.setWidthFull(); | |||||
| Span gciatiSignSpan = new Span("Ing. Javier Patiño Martinez"); | |||||
| Span tituloGerente = new Span("Gerente de T.I"); | |||||
| gcialSignLayout.setSizeFull(); | |||||
| gcialSignLayout.setSpacing(false); | |||||
| gcialSignLayout.setAlignItems(Alignment.CENTER); | |||||
| gcialSignLayout.add(firmaGcia, gciatiSignSpan, tituloGerente); | |||||
| firmasLayout.add(userSignLayout, smtSignLayout, gcialSignLayout); | |||||
| firmasLayout.setWidthFull(); | |||||
| firmasLayout.setSpacing(false); | |||||
| firmasLayout.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| } | |||||
| // Metodo para verificar si la firma corresponde a una cadena de firma vacia | |||||
| private boolean esFirmaVacia(String firmaBase64) { | |||||
| String firmaVacia = "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD8CAYAAACSCdTiAAAIbElEQVR4Xu3UAQ0AIAwDQeZfNCPI+Nwc9Lp07rvjCBAgQCApMEY+2atQBAgQ+AJG3iMQIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBAw8n6AAAECYQEjHy5XNAIECBh5P0CAAIGwgJEPlysaAQIEjLwfIECAQFjAyIfLFY0AAQJG3g8QIEAgLGDkw+WKRoAAASPvBwgQIBAWMPLhckUjQICAkfcDBAgQCAsY+XC5ohEgQMDI+wECBAiEBYx8uFzRCBAgYOT9AAECBMICRj5crmgECBBYAuXtOkIWm1QAAAAASUVORK5CYII="; | |||||
| return firmaBase64.equals(firmaVacia); | |||||
| } | |||||
| private void buttons() { | |||||
| VerticalLayout buttonsLayout = new VerticalLayout(); | |||||
| Button btnGuardar = new Button("Guardar", LineAwesomeIcon.SAVE.create()); | |||||
| btnGuardar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| btnGuardar.addThemeVariants(ButtonVariant.LUMO_LARGE); | |||||
| btnGuardar.addClickListener(event -> { | |||||
| if (planAnualActual == null) { | |||||
| Notification.show("No se pudo cargar el Plan Anual. Verifica el ID.", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| } | |||||
| if (planAnualActual != null) { | |||||
| fechaProgramada = planAnualActual.getFechaProgramada(); | |||||
| fechaSeleccionada = fecha.getValue(); | |||||
| boolean mismoMes = fechaSeleccionada != null && | |||||
| fechaSeleccionada.getMonthValue() == fechaProgramada.getMonthValue() && | |||||
| fechaSeleccionada.getYear() == fechaProgramada.getYear(); | |||||
| if (!mismoMes) { | |||||
| Dialog confirmDialog = new Dialog(); | |||||
| Span aviso = new Span("El mantenimiento esta fuera de tiempo, justifique el motivo"); | |||||
| jsutificacion = new TextArea(); | |||||
| jsutificacion.setSizeFull(); | |||||
| Button btnSi = new Button("Guardar",LineAwesomeIcon.SAVE_SOLID.create(), e -> { | |||||
| confirmDialog.close(); | |||||
| guardarMantenimiento(); | |||||
| }); | |||||
| btnSi.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| VerticalLayout layout = new VerticalLayout(aviso, jsutificacion, btnSi); | |||||
| layout.setSizeFull(); | |||||
| layout.setAlignItems(Alignment.CENTER); | |||||
| confirmDialog.add(layout); | |||||
| confirmDialog.open(); | |||||
| } else { | |||||
| guardarMantenimiento(); | |||||
| } | |||||
| } | |||||
| }); | |||||
| buttonsLayout.setSizeFull(); | |||||
| buttonsLayout.add(btnGuardar); | |||||
| buttonsLayout.setAlignItems(Alignment.CENTER); | |||||
| botonesLayout.add(buttonsLayout); | |||||
| botonesLayout.setSizeFull(); | |||||
| //botonesLayout.setAlignItems(Alignment.CENTER); | |||||
| } | |||||
| // METODO PARA ENVIAR CORREOS ELECTRONICOS | |||||
| private void enviarCorreo() { | |||||
| Usuario usuarioSeleccionado = usuario.getValue(); | |||||
| if (usuarioSeleccionado != null && usuarioSeleccionado.getEmail() != null) { | |||||
| String destinatario = usuarioSeleccionado.getEmail(); | |||||
| String asunto = "MANTENIMIENTO DE EQUIPO DE COMPUTO REALIZADO"; | |||||
| String cuerpo = "<html>" + | |||||
| "<body>" + | |||||
| "<img src='cid:image_id'/>"+ | |||||
| "</body>" + | |||||
| "</html>"; | |||||
| String imagePath = "META-INF/resources/images/imgCorreo/correoMantt.png"; | |||||
| emailService.enviarCorreo(destinatario, asunto, cuerpo, imagePath); | |||||
| } else { | |||||
| Notification.show("Por favor selecciona un usuario", 4000, Notification.Position.MIDDLE); | |||||
| } | |||||
| } | |||||
| private void guardarMantenimiento() { | |||||
| TiposMantenimiento tiposMantenimiento = tipoMantt.getValue(); | |||||
| String tipoMantId = tiposMantenimiento != null ? tiposMantenimiento.getTipomantId() : null; | |||||
| String planAnualValue = txtPlananualID.getValue(); | |||||
| String justificacionValue = jsutificacion != null ? jsutificacion.getValue() : null; | |||||
| String reparacionValue = null; | |||||
| DepartamentosModel departamentoSeleccionado = area.getValue(); | |||||
| String departamentoId = departamentoSeleccionado != null ? departamentoSeleccionado.getDepartamentoId().toString() : null; | |||||
| Usuario usuarioSeleccionado = usuario.getValue(); | |||||
| String empleadoId = usuarioSeleccionado != null ? usuarioSeleccionado.getEmpleadoId().toString() : null; | |||||
| String equipoId = txtNombreEquipo.getValue(); | |||||
| String formaSeleccionada = formaGroup.getValue(); | |||||
| String formaMantt = null; | |||||
| if ("Remota".equals(formaSeleccionada)) { | |||||
| formaMantt = "R"; | |||||
| } else if ("Manual".equals(formaSeleccionada)) { | |||||
| formaMantt = "M"; | |||||
| } | |||||
| // Validación de campos obligatorios | |||||
| if (fechaSeleccionada == null || tipoMantId == null || departamentoId == null || empleadoId == null || | |||||
| equipoId == null || equipoId.trim().isEmpty() || formaMantt == null || planAnualValue == null || planAnualValue.trim().isEmpty()) { | |||||
| Notification.show("Por favor, completa todos los campos requeridos", 4000, Notification.Position.MIDDLE); | |||||
| return; | |||||
| } | |||||
| byte[] userSignatureBytes = userSignPad.getImageBase64(); | |||||
| byte[] smtSignatureBytes = smtSignPad.getImageBase64(); | |||||
| //byte[] gciaSignatureBytes = gciatiSignPad.getImageBase64(); | |||||
| String userSignatureBase64 = Base64.getEncoder().encodeToString(userSignatureBytes); | |||||
| String smtSignatureBase64 = Base64.getEncoder().encodeToString(smtSignatureBytes); | |||||
| //String gciaSignatureBase64 = Base64.getEncoder().encodeToString(gciaSignatureBytes); | |||||
| if (esFirmaVacia(userSignatureBase64)) userSignatureBase64 = null; | |||||
| if (esFirmaVacia(smtSignatureBase64)) smtSignatureBase64 = null; | |||||
| //if (esFirmaVacia(gciaSignatureBase64)) gciaSignatureBase64 = null; | |||||
| // Validación de campos de hardware | |||||
| List<Map<String, String>> detallesHardware = new ArrayList<>(); | |||||
| for (HorizontalLayout layout : hardwareLayouts) { | |||||
| ComboBox<TiposHardware> tipoHardware = (ComboBox<TiposHardware>) layout.getComponentAt(0); | |||||
| TextField noSerie = (TextField) layout.getComponentAt(1); | |||||
| TextField modelo = (TextField) layout.getComponentAt(2); | |||||
| TextField placa = (TextField) layout.getComponentAt(3); | |||||
| TiposHardware tipoSeleccionado = tipoHardware.getValue(); | |||||
| if (tipoSeleccionado == null) { | |||||
| Notification.show("Por favor, selecciona un tipo de hardware", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| boolean esOpcional = Arrays.asList("TECLADO", "MOUSE").contains(tipoSeleccionado.getNombreHardware()); | |||||
| String numSerie = noSerie.getValue(); | |||||
| String modeloVal = modelo.getValue(); | |||||
| String placaVal = placa.getValue(); | |||||
| if (!esOpcional && (modeloVal == null || modeloVal.isEmpty() || numSerie == null || numSerie.isEmpty() || placaVal == null || placaVal.isEmpty())) { | |||||
| Notification.show("Por favor, completa todos los campos de hardware.", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| Map<String, String> hw = new HashMap<>(); | |||||
| hw.put("tipoHardwareId", tipoSeleccionado.getTipoHardwareId()); | |||||
| hw.put("numSerie", numSerie); | |||||
| hw.put("modelo", modeloVal); | |||||
| hw.put("placa", placaVal); | |||||
| detallesHardware.add(hw); | |||||
| } | |||||
| Set<String> actualizacionesSeleccionadas = actualizaciones.getSelectedItems(); | |||||
| String otrasActualizaciones = null; | |||||
| if ("Si".equals(masActualizacionesGroup.getValue())) { | |||||
| otrasActualizaciones = txtCuales.getValue(); | |||||
| if (otrasActualizaciones == null || otrasActualizaciones.trim().isEmpty()) { | |||||
| Notification.show("Especifica las otras actualizaciones", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_WARNING); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // Una vez que validamos todos los campos del formulario, procedemos a insertar en BD | |||||
| try { | |||||
| int isInserted = databaseService.insertarMantenimiento(fechaSeleccionada, tipoMantId, departamentoId, empleadoId, formaMantt, equipoId, userSignatureBase64, smtSignatureBase64, planAnualValue, justificacionValue, reparacionValue); | |||||
| if (isInserted <= 0) { | |||||
| Notification.show("Error al guardar el mantenimiento", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| int mantenimientoId = databaseService.getUltimoMantenimientoId(); | |||||
| for (Map<String, String> hw : detallesHardware) { | |||||
| boolean ok = databaseService.insertarHardware( | |||||
| hw.get("tipoHardwareId"), | |||||
| hw.get("numSerie"), | |||||
| hw.get("modelo"), | |||||
| hw.get("placa"), | |||||
| mantenimientoId | |||||
| ); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar detalles del hardware: ", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| for (String act : actualizacionesSeleccionadas) { | |||||
| boolean ok = databaseService.insertActualizacionSeg(act, null, mantenimientoId); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar actualización de seguridad", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| if (otrasActualizaciones != null) { | |||||
| boolean ok = databaseService.insertActualizacionSeg("Otras", otrasActualizaciones, mantenimientoId); | |||||
| if (!ok) { | |||||
| Notification.show("Error al insertar otras actualizaciones", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // === EXITO === | |||||
| Notification.show("¡Mantenimiento guardado exitosamente!", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| try { | |||||
| enviarCorreo(); | |||||
| } catch (Exception e) { | |||||
| Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| // Limpiar campos | |||||
| fecha.clear(); | |||||
| txtPlananualID.clear(); | |||||
| tipoMantt.clear(); | |||||
| area.clear(); | |||||
| usuario.clear(); | |||||
| txtNombreEquipo.clear(); | |||||
| formaGroup.clear(); | |||||
| actualizaciones.clear(); | |||||
| masActualizacionesGroup.clear(); | |||||
| txtCuales.clear(); | |||||
| userSignPad.clear(); | |||||
| smtSignPad.clear(); | |||||
| //gciatiSignPad.clear(); | |||||
| for (HorizontalLayout layout : hardwareLayouts) { | |||||
| ((ComboBox<?>) layout.getComponentAt(0)).clear(); | |||||
| ((TextField) layout.getComponentAt(1)).clear(); | |||||
| ((TextField) layout.getComponentAt(2)).clear(); | |||||
| ((TextField) layout.getComponentAt(3)).clear(); | |||||
| } | |||||
| UI.getCurrent().navigate("/"); | |||||
| } catch (Exception ex) { | |||||
| Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| ex.printStackTrace(); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { | |||||
| String fechaParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("fecha") != null | |||||
| ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("fecha").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| String tipoParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("tipo") != null | |||||
| ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("tipo").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| String idParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id") != null | |||||
| ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("id").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| if (idParam != null) { | |||||
| try { | |||||
| int id = Integer.parseInt(idParam); | |||||
| planAnualActual = databaseService.getPlanAnualPorId(id); | |||||
| } catch (NumberFormatException e) { | |||||
| planAnualActual = null; | |||||
| } | |||||
| } | |||||
| String equipoParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo") != null | |||||
| ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("nomEquipo").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| String deptoParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("departamento") != null | |||||
| ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("departamento").stream().findFirst().orElse(null) | |||||
| : null; | |||||
| if (fechaParam != null) { | |||||
| try { | |||||
| LocalDate fechaActual = LocalDate.parse(fechaParam); | |||||
| this.fecha.setValue(fechaActual); // Establece la fecha en el DatePicker | |||||
| } catch (Exception e) { | |||||
| Notification.show("Error al establecer la fecha: " + e.getMessage(), 3000, Notification.Position.MIDDLE); | |||||
| } | |||||
| } | |||||
| // Cambiamos el valor por el ID | |||||
| if ("1".equals(tipoParam)) { // 1 es para PREVENTIVO | |||||
| TiposMantenimiento preventivo = tipoMantt.getDataProvider() | |||||
| .fetch(new com.vaadin.flow.data.provider.Query<>()) | |||||
| .filter(tipo -> "1".equals(tipo.getTipomantId())) | |||||
| .findFirst() | |||||
| .orElse(null); | |||||
| if (preventivo != null) { | |||||
| tipoMantt.setValue(preventivo); | |||||
| tipoMantt.setReadOnly(true); | |||||
| } | |||||
| } else if ("2".equals(tipoParam)) { // 2 es para CORRECTIVO | |||||
| TiposMantenimiento correctivo = tipoMantt.getDataProvider() | |||||
| .fetch(new com.vaadin.flow.data.provider.Query<>()) | |||||
| .filter(tipo -> "2".equals(tipo.getTipomantId())) | |||||
| .findFirst() | |||||
| .orElse(null); | |||||
| if (correctivo != null) { | |||||
| tipoMantt.setValue(correctivo); | |||||
| tipoMantt.setReadOnly(true); | |||||
| } | |||||
| } | |||||
| // Establecemos el ID desde el plan anual | |||||
| if (idParam != null) { | |||||
| txtPlananualID.setValue(idParam); // Establece el ID en el campo de texto | |||||
| } else { | |||||
| txtPlananualID.setValue("Sin ID"); // O un valor por defecto si no hay ID | |||||
| } | |||||
| // Establecemos el valor del campo de texto Nombre de Equipo con el parametro que viene en la url | |||||
| if (equipoParam != null) { | |||||
| txtNombreEquipo.setValue(equipoParam); | |||||
| } else { | |||||
| txtNombreEquipo.setValue("Sin nombre"); | |||||
| } | |||||
| // Establecemos el campo del departamento con el departamento desde el plan anual | |||||
| if (deptoParam != null) { | |||||
| Optional<DepartamentosModel> departamentoSeleccionado = area.getDataProvider() | |||||
| .fetch(new com.vaadin.flow.data.provider.Query<>()) | |||||
| .filter(departamento -> departamento.getNombre().equals(deptoParam)) | |||||
| .findFirst(); | |||||
| if (departamentoSeleccionado.isPresent()) { | |||||
| area.setValue(departamentoSeleccionado.get()); | |||||
| area.setReadOnly(true); | |||||
| } else { | |||||
| area.setValue(null); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,950 @@ | |||||
| package mx.gob.jumapacelaya.ui; | |||||
| import com.vaadin.flow.component.Component; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.button.Button; | |||||
| import com.vaadin.flow.component.button.ButtonVariant; | |||||
| import com.vaadin.flow.component.checkbox.Checkbox; | |||||
| import com.vaadin.flow.component.checkbox.CheckboxGroup; | |||||
| import com.vaadin.flow.component.checkbox.CheckboxGroupVariant; | |||||
| import com.vaadin.flow.component.combobox.ComboBox; | |||||
| import com.vaadin.flow.component.confirmdialog.ConfirmDialog; | |||||
| import com.vaadin.flow.component.datepicker.DatePicker; | |||||
| import com.vaadin.flow.component.dependency.CssImport; | |||||
| import com.vaadin.flow.component.dialog.Dialog; | |||||
| import com.vaadin.flow.component.formlayout.FormLayout; | |||||
| import com.vaadin.flow.component.grid.Grid; | |||||
| import com.vaadin.flow.component.grid.GridVariant; | |||||
| import com.vaadin.flow.component.grid.HeaderRow; | |||||
| import com.vaadin.flow.component.grid.contextmenu.GridContextMenu; | |||||
| import com.vaadin.flow.component.grid.contextmenu.GridMenuItem; | |||||
| import com.vaadin.flow.component.grid.dataview.GridListDataView; | |||||
| import com.vaadin.flow.component.html.*; | |||||
| import com.vaadin.flow.component.icon.Icon; | |||||
| import com.vaadin.flow.component.icon.VaadinIcon; | |||||
| import com.vaadin.flow.component.notification.Notification; | |||||
| import com.vaadin.flow.component.notification.NotificationVariant; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.component.popover.Popover; | |||||
| import com.vaadin.flow.component.popover.PopoverPosition; | |||||
| import com.vaadin.flow.component.radiobutton.RadioButtonGroup; | |||||
| import com.vaadin.flow.component.textfield.NumberField; | |||||
| import com.vaadin.flow.component.textfield.TextField; | |||||
| import com.vaadin.flow.component.upload.Upload; | |||||
| import com.vaadin.flow.component.upload.receivers.MemoryBuffer; | |||||
| import com.vaadin.flow.data.value.ValueChangeMode; | |||||
| import com.vaadin.flow.function.ValueProvider; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import com.vaadin.flow.server.StreamRegistration; | |||||
| import com.vaadin.flow.server.StreamResource; | |||||
| import jakarta.annotation.security.PermitAll; | |||||
| import mx.gob.jumapacelaya.models.PlanAnual; | |||||
| import mx.gob.jumapacelaya.services.DatabaseService; | |||||
| import mx.gob.jumapacelaya.services.ReportService; | |||||
| import net.sf.jasperreports.engine.JasperFillManager; | |||||
| import net.sf.jasperreports.engine.JasperPrint; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.apache.poi.ss.usermodel.*; | |||||
| import org.springframework.core.env.Environment; | |||||
| import org.springframework.security.core.Authentication; | |||||
| import org.springframework.security.core.context.SecurityContextHolder; | |||||
| import org.vaadin.lineawesome.LineAwesomeIcon; | |||||
| import java.io.*; | |||||
| import java.lang.reflect.Array; | |||||
| import java.sql.Date; | |||||
| import java.time.LocalDate; | |||||
| import java.time.Year; | |||||
| import java.time.format.DateTimeFormatter; | |||||
| import java.util.*; | |||||
| import java.util.function.Consumer; | |||||
| @PermitAll | |||||
| @PageTitle("Plan Anual de Mantenimiento") | |||||
| @Route(value = "/", layout = MainLayout.class) | |||||
| @CssImport("./themes/sistema-mantenimiento/styles.css") | |||||
| public class PlanAnualView extends VerticalLayout { | |||||
| private final Environment env; | |||||
| private final ReportService reportService; | |||||
| H4 titulo = new H4(); | |||||
| H5 titulo1 = new H5(); | |||||
| Button btnInsertar; | |||||
| private byte[] fileContent; | |||||
| VerticalLayout gridLayout = new VerticalLayout(); | |||||
| HorizontalLayout uploadLayout = new HorizontalLayout(); | |||||
| HorizontalLayout filtrosLayout = new HorizontalLayout(); | |||||
| private final DatabaseService databaseService; | |||||
| Grid<PlanAnual> planAnualGrid; | |||||
| Button btnColumns; | |||||
| Button btnImprimirRpt; | |||||
| Button btnAddEquipo; | |||||
| HorizontalLayout btnImprimirLayout; | |||||
| private Popover reportePopover; | |||||
| public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) { | |||||
| this.databaseService = databaseService; | |||||
| this.env = env; | |||||
| this.reportService = reportService; | |||||
| setupHeader(); | |||||
| Grid<PlanAnual> planAnualGrid = setupGrid(); | |||||
| // Notificación de conexión activa | |||||
| String perfil = String.join(",", env.getActiveProfiles()); | |||||
| String url = env.getProperty("db.url"); | |||||
| Notification.show("Conectado a: " + perfil + "\nURL DB: " + url, 5000, Notification.Position.BOTTOM_START); | |||||
| // Obtenemos la lista de items y establecemos un GridListDataView para gestionar | |||||
| // los datos | |||||
| List<PlanAnual> planAnualItems = databaseService.getPlanAnual(); | |||||
| GridListDataView<PlanAnual> dataView = planAnualGrid.setItems(planAnualItems); | |||||
| // Se crea el filtro para el grid. | |||||
| PlanAnualFilter planAnualFilter = new PlanAnualFilter(dataView); | |||||
| planAnualFilter.setExcludeRealizado(true); | |||||
| HeaderRow headerRow = planAnualGrid.appendHeaderRow(); | |||||
| /*headerRow.getCell(planAnualGrid.getColumnByKey("smtColumnKey")) | |||||
| .setComponent(createFilterHeader("S.M.T", planAnualFilter::setSmt));*/ | |||||
| headerRow.getCell(planAnualGrid.getColumnByKey("equipo")) | |||||
| .setComponent(createFilterHeader("Equipo", planAnualFilter::setEquipo)); | |||||
| headerRow.getCell(planAnualGrid.getColumnByKey("departamento")) | |||||
| .setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento)); | |||||
| headerRow.getCell(planAnualGrid.getColumnByKey("mesplaneado")) | |||||
| .setComponent(createFilterHeader("Mes Planeado", planAnualFilter::setMesPlaneado)); | |||||
| // MENU CONTEXTUAL DEL GRID | |||||
| PersonContextMenu contextMenu = new PersonContextMenu(planAnualGrid); | |||||
| // Componente UPLOAD para subir archivos | |||||
| MemoryBuffer buffer = new MemoryBuffer(); | |||||
| Upload upload = new Upload(); | |||||
| upload.setAcceptedFileTypes(".xls", ".xlsx"); | |||||
| upload.setMaxFiles(1); | |||||
| upload.setDropLabel(new com.vaadin.flow.component.html.Span("Arrastra un archivo Excel aquí o selecciona uno")); | |||||
| upload.addSucceededListener(event -> { | |||||
| try { | |||||
| // Almacena el contenido del archivo en un arreglo de bytes | |||||
| try (InputStream inputStream = buffer.getInputStream(); | |||||
| ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { | |||||
| inputStream.transferTo(byteArrayOutputStream); | |||||
| fileContent = byteArrayOutputStream.toByteArray(); | |||||
| } | |||||
| // Validación del archivo cargado | |||||
| List<String> errores = validarExcel(new ByteArrayInputStream(fileContent)); | |||||
| if (!errores.isEmpty()) { | |||||
| // Crear notificación con mensaje de error y sin duración | |||||
| final Notification ntfError = new Notification(); | |||||
| ntfError.setText("Errores en el archivo: " + String.join(", ", errores)); | |||||
| ntfError.setDuration(0); // La notificación no se cerrará automáticamente | |||||
| ntfError.setPosition(Notification.Position.MIDDLE); | |||||
| ntfError.addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| // Texto del mensaje de error | |||||
| Span errorMessage = new Span("Errores en el archivo: " + String.join(", ", errores)); | |||||
| errorMessage.getStyle().set("margin-right", "10px"); | |||||
| // Crear botón de cierre | |||||
| final Button closeButton = new Button(new Icon(VaadinIcon.CLOSE)); | |||||
| closeButton.addClickListener(e -> ntfError.close()); | |||||
| // Agregar el mensaje y el botón de cierre a la notificación | |||||
| HorizontalLayout notificationLayout = new HorizontalLayout(errorMessage, closeButton); | |||||
| ntfError.add(notificationLayout); | |||||
| ntfError.open(); // Abrir la notificación en pantalla | |||||
| // Ocultar el botón de insertar si hay errores | |||||
| btnInsertar.setVisible(false); | |||||
| } else { | |||||
| btnInsertar.setVisible(true); | |||||
| } | |||||
| } catch (IOException e) { | |||||
| Notification.show("Error al leer el archivo: " + e.getMessage()) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| } | |||||
| }); | |||||
| btnInsertar = new Button("Insertar archivo", event -> insertarDatos()); | |||||
| btnInsertar.setVisible(false); | |||||
| gridLayout.add(btnImprimirLayout,planAnualGrid); | |||||
| gridLayout.setSizeFull(); | |||||
| uploadLayout.add(upload, btnInsertar); | |||||
| toggleLayouts(dataView); | |||||
| filtrosLayout.addClassNames("lumo-justify-content-center", "lumo-gap-m", "lumo-padding-s"); | |||||
| filtrosLayout.setWidthFull(); | |||||
| filtrosLayout.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| Button btnPendientes = new Button("Pendientes", VaadinIcon.CLOCK.create()); | |||||
| Button btnRealizados = new Button("Realizados", VaadinIcon.CHECK_CIRCLE.create()); | |||||
| btnPendientes.addClassName("selected-tab"); | |||||
| btnPendientes.addClickListener(e -> { | |||||
| planAnualFilter.setExcludeRealizado(true); | |||||
| btnPendientes.addClassName("selected-tab"); | |||||
| btnRealizados.removeClassName("selected-tab"); | |||||
| }); | |||||
| btnRealizados.addClickListener(e -> { | |||||
| planAnualFilter.setExcludeRealizado(false); | |||||
| btnRealizados.addClassName("selected-tab"); | |||||
| btnPendientes.removeClassName("selected-tab"); | |||||
| }); | |||||
| filtrosLayout.add(btnPendientes, btnRealizados); | |||||
| mostrarPopoverReportes(); | |||||
| this.setPadding(false); | |||||
| this.setMargin(false); | |||||
| this.setSpacing(false); | |||||
| this.setSizeFull(); | |||||
| add(filtrosLayout, gridLayout, uploadLayout); | |||||
| } | |||||
| private void setupHeader() { | |||||
| VerticalLayout headerLayout = new VerticalLayout(); | |||||
| headerLayout.addClassName("plan-anual-header"); | |||||
| titulo.addClassName("plan-anual-titulo"); | |||||
| titulo1.addClassName("plan-anual-titulo1"); | |||||
| titulo.setText("Plan Anual de Mantenimiento Preventivo de Equipo de Computo"); | |||||
| titulo1.setText(Year.now().toString()); | |||||
| TextField nomenclaturaTxt = new TextField(); | |||||
| nomenclaturaTxt.setValue("FR01-PA-7.1.3-02"); | |||||
| nomenclaturaTxt.setReadOnly(true); | |||||
| nomenclaturaTxt.addClassName("nomenclatura-txt"); | |||||
| headerLayout.add(titulo, titulo1); | |||||
| headerLayout.setAlignItems(Alignment.CENTER); | |||||
| add(headerLayout); | |||||
| } | |||||
| private Grid<PlanAnual> setupGrid() { | |||||
| planAnualGrid = new Grid<>(PlanAnual.class, false); | |||||
| planAnualGrid.addColumn((ValueProvider<PlanAnual, Integer>) PlanAnual::getNumero) | |||||
| .setHeader("No.").setSortable(true).setAutoWidth(true).setFrozen(true); | |||||
| // Botón condicional | |||||
| planAnualGrid.addComponentColumn(planAnual -> { | |||||
| String estado = planAnual.getEstado(); | |||||
| Button btn; | |||||
| if ("PENDIENTE".equalsIgnoreCase(estado)) { | |||||
| btn = new Button(new Icon(VaadinIcon.EDIT)); | |||||
| btn.setTooltipText("Realizar mantenimiento"); | |||||
| btn.getStyle().set("color", "#A02142"); | |||||
| btn.addClickListener(event -> { | |||||
| int idPlananual = planAnual.getNumero(); | |||||
| LocalDate fechaSistema = LocalDate.now(); | |||||
| String nomEquipo = planAnual.getNomEquipo(); | |||||
| String departamento = planAnual.getDepartamento(); | |||||
| btn.getUI().ifPresent(ui -> ui.navigate( | |||||
| "mantenimiento?id=" + idPlananual + | |||||
| "&fecha=" + fechaSistema + | |||||
| "&tipo=1" + | |||||
| "&nomEquipo=" + nomEquipo + | |||||
| "&departamento=" + departamento)); | |||||
| }); | |||||
| } else if ("REALIZADO".equalsIgnoreCase(estado)) { | |||||
| btn = new Button(new Icon(VaadinIcon.EYE)); | |||||
| btn.setTooltipText("Ver detalles"); | |||||
| btn.getStyle().set("color", "#A02142"); | |||||
| btn.addClickListener(event -> { | |||||
| int idPlananual = planAnual.getNumero(); | |||||
| btn.getUI().ifPresent(ui -> ui.navigate( | |||||
| "detalles?id=" + idPlananual)); | |||||
| }); | |||||
| } else { | |||||
| btn = new Button("N/A"); | |||||
| btn.setEnabled(false); | |||||
| } | |||||
| return btn; | |||||
| }).setAutoWidth(true).setFrozen(true); | |||||
| planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getNomEquipo) | |||||
| .setHeader("Equipo").setAutoWidth(true).setKey("equipo"); | |||||
| planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getDepartamento) | |||||
| .setHeader("Departamento").setAutoWidth(true).setKey("departamento"); | |||||
| planAnualGrid.addColumn(planAnual -> { | |||||
| String mesPlaneado = planAnual.getMesplaneado(); | |||||
| return mesPlaneado != null ? mesPlaneado.toUpperCase() : "N/A"; | |||||
| }).setHeader("Mes Planeado").setAutoWidth(true).setKey("mesplaneado"); | |||||
| // Fechas formateadas | |||||
| planAnualGrid.addColumn(planAnual -> { | |||||
| LocalDate fecha = planAnual.getFechaProgramada(); | |||||
| return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "No programada"; | |||||
| }).setHeader("Fecha Programada").setAutoWidth(true).setSortable(true).setKey("fechaProgramada"); | |||||
| planAnualGrid.addColumn(planAnual -> { | |||||
| LocalDate fecha = planAnual.getFechaMantenimiento(); | |||||
| return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : ""; | |||||
| }).setHeader("Fecha Realización").setAutoWidth(true).setSortable(true).setKey("fechaMantenimiento"); | |||||
| planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getEstado) | |||||
| .setHeader("Estado").setAutoWidth(true).setKey("estado"); | |||||
| planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSituacion) | |||||
| .setHeader("Situación").setAutoWidth(true).setKey("situacion"); | |||||
| /*planAnualGrid.addColumn((ValueProvider<PlanAnual, String>) PlanAnual::getSmt) | |||||
| .setHeader("S.M.T").setKey("smtColumnKey");*/ | |||||
| // Iconos en columnas booleanas | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor").setKey("monitor"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado").setKey("teclado"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMouse())).setHeader("Mouse").setKey("mouse"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isRegulador())).setHeader("Regulador").setKey("regulador"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isCpu())).setHeader("CPU").setKey("cpu"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isImpresora())).setHeader("Impresora").setKey("impresora"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMiniPrint())).setHeader("MiniPrint").setKey("miniprint"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isLaptop())).setHeader("Laptop").setKey("laptop"); | |||||
| planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isEscaner())).setHeader("Escáner").setKey("escaner"); | |||||
| planAnualGrid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT); | |||||
| planAnualGrid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES); | |||||
| btnColumns = new Button(VaadinIcon.GRID_H.create()); | |||||
| btnColumns.addThemeVariants(ButtonVariant.LUMO_ICON); | |||||
| btnColumns.setAriaLabel("Show/Hide Columns"); | |||||
| btnColumns.setTooltipText("Show/Hide Columns"); | |||||
| btnImprimirRpt = new Button(VaadinIcon.PRINT.create()); | |||||
| btnImprimirRpt.addClickListener(event -> reportePopover.open()); | |||||
| btnImprimirRpt.setTooltipText("Imprimir reporte"); | |||||
| btnAddEquipo = new Button(VaadinIcon.PLUS.create()); | |||||
| btnAddEquipo.addClickListener(event -> addNuevoEquipo()); | |||||
| btnAddEquipo.setTooltipText("Agregar nuevo equipo"); | |||||
| btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo); | |||||
| HorizontalLayout columnSelectorLayout = new HorizontalLayout(); | |||||
| columnSelectorLayout.setAlignItems(Alignment.END); | |||||
| Popover popover = new Popover(); | |||||
| popover.setModal(true); | |||||
| popover.setBackdropVisible(true); | |||||
| popover.setPosition(PopoverPosition.BOTTOM_END); | |||||
| popover.setTarget(btnColumns); | |||||
| Div heading = new Div("Ver/Ocultar columnas"); | |||||
| heading.getStyle().set("font-weight", "600"); | |||||
| heading.getStyle().set("padding", "var(--lumo-space-xs)"); | |||||
| List<String> columns = List.of("equipo", "departamento", "mesplaneado", "fechaProgramada", | |||||
| "fechaMantenimiento", "estado", "situacion", "monitor", "teclado", "mouse", "regulador", | |||||
| "cpu", "impresora", "miniprint", "laptop", "escaner"); | |||||
| CheckboxGroup<String> chkColumns = new CheckboxGroup<>(); | |||||
| chkColumns.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL); | |||||
| chkColumns.setItems(columns); | |||||
| chkColumns.setItemLabelGenerator((item) -> { | |||||
| String label = StringUtils | |||||
| .join(StringUtils.splitByCharacterTypeCamelCase(item), " "); | |||||
| return StringUtils.capitalize(label.toLowerCase()); | |||||
| }); | |||||
| chkColumns.addValueChangeListener((e) -> { | |||||
| columns.forEach((key) -> { | |||||
| Grid.Column<?> col = planAnualGrid.getColumnByKey(key); | |||||
| if (col != null) { | |||||
| col.setVisible(e.getValue().contains(key)); | |||||
| } else { | |||||
| System.out.println("Columna no encontrada para key: " + key); | |||||
| } | |||||
| }); | |||||
| }); | |||||
| Set<String> defaultColumns = Set.of("equipo", "departamento", "mesplaneado", | |||||
| "fechaProgramada", "fechaMantenimiento", "estado", "situacion"); | |||||
| chkColumns.setValue(defaultColumns); | |||||
| popover.add(heading, chkColumns); | |||||
| // Cargar datos | |||||
| planAnualGrid.setItems(databaseService.getPlanAnual()); | |||||
| return planAnualGrid; | |||||
| } | |||||
| /* | |||||
| * (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * SUSTITUIR VALORES BOOLEANOS POR UN ICONO (∩ ͡° ͜ʖ | |||||
| * ͡°)⊃━☆゚. * | |||||
| */ | |||||
| private Icon getIcon(boolean value) { | |||||
| if (value) { | |||||
| return new Icon(VaadinIcon.CHECK_CIRCLE); | |||||
| } else { | |||||
| return new Icon(); | |||||
| } | |||||
| } | |||||
| /* | |||||
| * (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * METODO PARA VALIDAR QUE EL ARCHIOVO TENGA LA ESTRUCTURA | |||||
| * CORRECTA (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * | |||||
| */ | |||||
| private List<String> validarExcel(InputStream inputStream) throws IOException { | |||||
| List<String> errores = new ArrayList<>(); | |||||
| Workbook workbook = WorkbookFactory.create(inputStream); | |||||
| Sheet sheet = workbook.getSheetAt(0); | |||||
| // Lista de nombres de columnas esperados en el encabezado | |||||
| List<String> columnas = Arrays.asList("NOMEQUIPO", "DEPARTAMENTO", "MONITOR", "TECLADO", "MOUSE", "REGULADOR", | |||||
| "CPU", "IMPRESORA", "MINIPRINT", "LAPTOP", "ESCANER", "FECHAPROG", "TECNICO", "ESTADO"); | |||||
| // Obtener la primera fila como encabezado | |||||
| Row headerRow = sheet.getRow(0); | |||||
| if (headerRow != null) { | |||||
| // Validar que cada celda en el encabezado tiene el nombre correcto | |||||
| for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) { | |||||
| Cell cell = headerRow.getCell(i); | |||||
| if (cell != null) { // Verificar si la celda no es null antes de acceder a su valor | |||||
| String columnName = cell.getStringCellValue(); | |||||
| if (!columnas.contains(columnName)) { | |||||
| errores.add("Columna inesperada: " + columnName); | |||||
| } | |||||
| } else { | |||||
| errores.add("Celda vacía en la columna de índice " + i); | |||||
| } | |||||
| } | |||||
| } else { | |||||
| errores.add("La hoja no contiene un encabezado en la primera fila."); | |||||
| } | |||||
| // Verificar si faltan columnas esperadas en el encabezado | |||||
| for (String columnName : columnas) { | |||||
| boolean found = false; | |||||
| if (headerRow != null) { | |||||
| for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) { | |||||
| Cell cell = headerRow.getCell(i); | |||||
| if (cell != null && cell.getStringCellValue().equals(columnName)) { | |||||
| found = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (!found) { | |||||
| errores.add("Falta la columna: " + columnName); | |||||
| } | |||||
| } | |||||
| workbook.close(); | |||||
| return errores; | |||||
| } | |||||
| // Valida que haya un archivo cargado en el UPLOAD y si si, llama al metodo para | |||||
| // insertar el archivo en la base de datos | |||||
| private void insertarDatos() { | |||||
| if (fileContent == null) { | |||||
| Notification.show("Error: No hay archivo cargado.").addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| try (InputStream inputStream = new ByteArrayInputStream(fileContent)) { | |||||
| databaseService.insertarDesdeExcel(inputStream); | |||||
| Notification.show("Archivo insertado correctamente").addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| btnInsertar.setVisible(false); // Ocultar el botón después de la inserción | |||||
| } catch (Exception e) { | |||||
| Notification.show("Error al insertar el archivo: " + e.getMessage()) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| } | |||||
| } | |||||
| private static Component createFilterHeader(String labelText, Consumer<String> filterChangeConsumer) { | |||||
| TextField textField = new TextField(); | |||||
| textField.setPlaceholder("Buscar..."); | |||||
| textField.setValueChangeMode(ValueChangeMode.EAGER); | |||||
| textField.setClearButtonVisible(true); | |||||
| textField.setWidthFull(); | |||||
| textField.addValueChangeListener(event -> filterChangeConsumer.accept(event.getValue())); | |||||
| VerticalLayout layout = new VerticalLayout(textField); | |||||
| layout.setSpacing(false); | |||||
| layout.setPadding(false); | |||||
| return layout; | |||||
| } | |||||
| private static class PlanAnualFilter { | |||||
| private final GridListDataView<PlanAnual> dataView; | |||||
| private String smt; | |||||
| private String equipo; | |||||
| private String departamento; | |||||
| private String mesPlaneado; | |||||
| private boolean excludeRealizado = true; | |||||
| public PlanAnualFilter(GridListDataView<PlanAnual> dataView) { | |||||
| this.dataView = dataView; | |||||
| this.dataView.addFilter(this::test); | |||||
| } | |||||
| public void setSmt(String smt) { | |||||
| this.smt = smt; | |||||
| this.dataView.refreshAll(); | |||||
| } | |||||
| public void setEquipo(String equipo) { | |||||
| this.equipo = equipo; | |||||
| this.dataView.refreshAll(); | |||||
| } | |||||
| public void setDepartamento(String departamento) { | |||||
| this.departamento = departamento; | |||||
| this.dataView.refreshAll(); | |||||
| } | |||||
| public void setMesPlaneado(String mesPlaneado) { | |||||
| this.mesPlaneado = mesPlaneado; | |||||
| this.dataView.refreshAll(); | |||||
| } | |||||
| public void setExcludeRealizado(boolean excludeRealizado) { | |||||
| this.excludeRealizado = excludeRealizado; | |||||
| this.dataView.refreshAll(); | |||||
| } | |||||
| public boolean test(PlanAnual planAnual) { | |||||
| if (planAnual == null) { | |||||
| return false; // Avoid NullPointerException | |||||
| } | |||||
| boolean matchesSmt = matches(planAnual.getSmt(), smt); | |||||
| boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo); | |||||
| boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento); | |||||
| boolean matchesMesPlaneado = matches(planAnual.getMesplaneado(), mesPlaneado); | |||||
| if (excludeRealizado) { | |||||
| // Mostrar solo los pendientes | |||||
| return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado | |||||
| && (planAnual.getEstado() == null || !"REALIZADO".equalsIgnoreCase(planAnual.getEstado())); | |||||
| } else { | |||||
| // Mostrar solo realizados | |||||
| return matchesSmt && matchesEquipo && matchesDepartamento && matchesMesPlaneado | |||||
| && "REALIZADO".equalsIgnoreCase(planAnual.getEstado()); | |||||
| } | |||||
| } | |||||
| private boolean matches(String value, String searchTerm) { | |||||
| return searchTerm == null || searchTerm.isEmpty() | |||||
| || value.toLowerCase().contains(searchTerm.toLowerCase()); | |||||
| } | |||||
| } | |||||
| // Aqui validamos que haya registros en el plan anual y si no hay muestra el | |||||
| // upload para cargar un nuevo plan anual | |||||
| private void toggleLayouts(GridListDataView<PlanAnual> dataView) { | |||||
| boolean hasItems = dataView.getItemCount() > 0; | |||||
| gridLayout.setVisible(hasItems); | |||||
| uploadLayout.setVisible(!hasItems); | |||||
| } | |||||
| private void sacarReporte() { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.setHeaderTitle("Seleccione la fecha de inicio y fin"); | |||||
| DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() | |||||
| .setWeekdays(List.of("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sabado")) | |||||
| .setWeekdaysShort(List.of("Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb")) | |||||
| .setMonthNames(List.of("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")) | |||||
| .setFirstDayOfWeek(1) | |||||
| .setToday("Hoy") | |||||
| .setCancel("Cancelar") | |||||
| .setDateFormat("dd/MM/yyyy"); | |||||
| DatePicker fechaInicio = new DatePicker("Fecha de inicio:"); | |||||
| fechaInicio.setRequired(true); | |||||
| fechaInicio.setI18n(i18n); | |||||
| DatePicker fechaFin = new DatePicker("Fecha de fin:"); | |||||
| fechaFin.setRequired(true); | |||||
| fechaFin.setI18n(i18n); | |||||
| Button btnGenerar = new Button("Generar", VaadinIcon.PRINT.create()); | |||||
| btnGenerar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| btnGenerar.addClickListener(e -> { | |||||
| if (fechaInicio.getValue() == null || fechaFin.getValue() == null) { | |||||
| Notification.show("Por favor, seleccione ambas fechas.", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| LocalDate inicio = fechaInicio.getValue(); | |||||
| LocalDate fin = fechaFin.getValue(); | |||||
| try { | |||||
| // Prepara los parámetros para el reporte | |||||
| Map<String, Object> parametros = new HashMap<>(); | |||||
| parametros.put("FECHAINICIO", java.sql.Date.valueOf(inicio)); | |||||
| parametros.put("FECHAFIN", java.sql.Date.valueOf(fin)); | |||||
| // Genera el PDF | |||||
| byte[] pdf = reportService.generarReporte("mantenimientoFechas", parametros); | |||||
| // Creando el recurso de descarga | |||||
| StreamResource resource = new StreamResource("reporte.pdf", () -> new ByteArrayInputStream(pdf)); | |||||
| /*Anchor downloadLink = new Anchor(resource, "Descargar Reporte"); | |||||
| downloadLink.setTarget("_blank"); | |||||
| downloadLink.setId("descargar-reporte-link"); | |||||
| add(downloadLink); | |||||
| getUI().ifPresent(ui -> | |||||
| ui.getPage().executeJs("document.getElementById('descargar-reporte-link').click();") | |||||
| );*/ | |||||
| StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource); | |||||
| UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')"); | |||||
| } catch (Exception ex) { | |||||
| Notification.show("Error al genrar el reporte: " + ex.getMessage(), 5000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| ex.printStackTrace(); | |||||
| } | |||||
| }); | |||||
| Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); | |||||
| dialog.getFooter().add(btnCancelar); | |||||
| dialog.getFooter().add(btnGenerar); | |||||
| HorizontalLayout fechasLayout = new HorizontalLayout(fechaInicio, fechaFin); | |||||
| dialog.add(fechasLayout); | |||||
| dialog.open(); | |||||
| } | |||||
| private void addNuevoEquipo() { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.setHeaderTitle("Agregar nuevo equipo"); | |||||
| TextField nombreEquipo = new TextField("Nombre equipo:"); | |||||
| TextField area = new TextField("Área:"); | |||||
| DatePicker.DatePickerI18n i18n = new DatePicker.DatePickerI18n() | |||||
| .setWeekdays(List.of("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sabado")) | |||||
| .setWeekdaysShort(List.of("Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb")) | |||||
| .setMonthNames(List.of("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")) | |||||
| .setFirstDayOfWeek(1) | |||||
| .setToday("Hoy") | |||||
| .setCancel("Cancelar") | |||||
| .setDateFormat("dd/MM/yyyy"); | |||||
| DatePicker fechaProgramada = new DatePicker("Fecha programada:"); | |||||
| fechaProgramada.setI18n(i18n); | |||||
| List<String> items = List.of("ENERO", "FEBRERO", "MARZO", "ABRIL", "MAYO", "JUNIO", | |||||
| "JULIO", "AGOSTO", "SEPTIEMBRE", "OCTUBRE", "NOVIEMBRE", "DICIEMBRE"); | |||||
| ComboBox<String> cmbMes = new ComboBox<>("Mes Planeado:"); | |||||
| cmbMes.setItems(items); | |||||
| CheckboxGroup<String> group1 = new CheckboxGroup<>(); | |||||
| group1.setLabel("Seleccione los componentes del equipo"); | |||||
| group1.setItems("MONITOR","TECLADO","MOUSE","REGULADOR"); | |||||
| CheckboxGroup<String> group2 = new CheckboxGroup<>(); | |||||
| group2.setItems("CPU","IMPRESORA","MINIPRINT","LAPTOP","ESCANER"); | |||||
| HorizontalLayout layout1 = new HorizontalLayout(nombreEquipo, area); | |||||
| HorizontalLayout layout2 = new HorizontalLayout(fechaProgramada,cmbMes); | |||||
| VerticalLayout layout3 = new VerticalLayout(group1,group2); | |||||
| layout3.setSpacing(false); | |||||
| Button btnGuardar = new Button("Guardar", LineAwesomeIcon.SAVE_SOLID.create()); | |||||
| btnGuardar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| btnGuardar.addClickListener(e -> { | |||||
| if (nombreEquipo.getValue().isEmpty() || area.getValue().isEmpty() || | |||||
| fechaProgramada.getValue() == null || cmbMes.getValue() == null) { | |||||
| Notification.show("Por favor, complete todos los campos.", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| final Map<String, Integer> MES_ID_MAP = new HashMap<>(); | |||||
| MES_ID_MAP.put("ENERO", 1); | |||||
| MES_ID_MAP.put("FEBRERO", 2); | |||||
| MES_ID_MAP.put("MARZO", 3); | |||||
| MES_ID_MAP.put("ABRIL", 4); | |||||
| MES_ID_MAP.put("MAYO", 5); | |||||
| MES_ID_MAP.put("JUNIO", 6); | |||||
| MES_ID_MAP.put("JULIO", 7); | |||||
| MES_ID_MAP.put("AGOSTO", 8); | |||||
| MES_ID_MAP.put("SEPTIEMBRE", 9); | |||||
| MES_ID_MAP.put("OCTUBRE", 10); | |||||
| MES_ID_MAP.put("NOVIEMBRE", 11); | |||||
| MES_ID_MAP.put("DICIEMBRE", 12); | |||||
| String mesSeleccionado = cmbMes.getValue(); | |||||
| Integer mesId = MES_ID_MAP.get(mesSeleccionado); | |||||
| if (group1.getValue().isEmpty() && group2.getValue().isEmpty()) { | |||||
| Notification.show("Debe seleccionar al menos un componente del equipo.", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| Set<String> seleccionados = new HashSet<>(); | |||||
| seleccionados.addAll(group1.getValue()); | |||||
| seleccionados.addAll(group2.getValue()); | |||||
| boolean monitor = seleccionados.contains("MONITOR"); | |||||
| boolean teclado = seleccionados.contains("TECLADO"); | |||||
| boolean mouse = seleccionados.contains("MOUSE"); | |||||
| boolean regulador = seleccionados.contains("REGULADOR"); | |||||
| boolean cpu = seleccionados.contains("CPU"); | |||||
| boolean impresora = seleccionados.contains("IMPRESORA"); | |||||
| boolean miniprint = seleccionados.contains("MINIPRINT"); | |||||
| boolean laptop = seleccionados.contains("LAPTOP"); | |||||
| boolean escaner = seleccionados.contains("ESCANER"); | |||||
| databaseService.insertarNuevoEquipo( | |||||
| nombreEquipo.getValue().toUpperCase(), | |||||
| area.getValue().toUpperCase(), | |||||
| monitor, | |||||
| teclado, | |||||
| mouse, | |||||
| regulador, | |||||
| cpu, | |||||
| impresora, | |||||
| miniprint, | |||||
| laptop, | |||||
| escaner, | |||||
| java.sql.Date.valueOf(fechaProgramada.getValue()), | |||||
| "", | |||||
| "PENDIENTE", | |||||
| mesId | |||||
| ); | |||||
| Notification.show("Equipo agregado correctamente", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| dialog.close(); | |||||
| // Recargar el grid para mostrar el nuevo equipo | |||||
| planAnualGrid.setItems(databaseService.getPlanAnual()); | |||||
| }); | |||||
| Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); | |||||
| dialog.getFooter().add(btnGuardar); | |||||
| dialog.getFooter().add(btnCancelar); | |||||
| dialog.add(layout1,layout2,layout3); | |||||
| dialog.open(); | |||||
| } | |||||
| private void mostrarPopoverReportes() { | |||||
| reportePopover = new Popover(); | |||||
| reportePopover.setModal(true); | |||||
| reportePopover.setBackdropVisible(true); | |||||
| reportePopover.setPosition(PopoverPosition.BOTTOM_END); | |||||
| reportePopover.setTarget(btnImprimirRpt); | |||||
| Div headding = new Div("Reportes disponibles"); | |||||
| headding.getStyle().set("font-weight", "600"); | |||||
| headding.getStyle().set("padding", "var(--lumo-space-xs)"); | |||||
| VerticalLayout listaRrportes = new VerticalLayout(); | |||||
| //listaRrportes.setSpacing(false); | |||||
| listaRrportes.setPadding(false); | |||||
| Button btnReporteFechas = new Button("Mantenimiento por fechas", VaadinIcon.STAR.create(), e -> { | |||||
| reportePopover.close(); | |||||
| sacarReporte(); | |||||
| }); | |||||
| btnReporteFechas.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE); | |||||
| Button btnListadoMant = new Button("Listado de mantenimientos", VaadinIcon.STAR.create(), e -> { | |||||
| reportePopover.close(); | |||||
| obtenerListadoRpt(); | |||||
| }); | |||||
| btnListadoMant.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE); | |||||
| listaRrportes.add(btnReporteFechas, btnListadoMant); | |||||
| reportePopover.add(headding, listaRrportes); | |||||
| } | |||||
| private void obtenerListadoRpt() { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.setHeaderTitle("Ingresa el peridodo a consultar"); | |||||
| TextField txtMes = new TextField("Mes:"); | |||||
| txtMes.setRequired(true); | |||||
| NumberField txtAnio = new NumberField("Año:"); | |||||
| txtAnio.setRequired(true); | |||||
| HorizontalLayout layout = new HorizontalLayout(txtMes, txtAnio); | |||||
| Button btnGenerar = new Button("Generar", VaadinIcon.PRINT.create()); | |||||
| btnGenerar.addThemeVariants(ButtonVariant.LUMO_PRIMARY); | |||||
| btnGenerar.addClickListener(e -> { | |||||
| String mes = txtMes.getValue().toUpperCase(); | |||||
| Integer anio = txtAnio.getValue() != null ? txtAnio.getValue().intValue() : null; | |||||
| if (mes.isEmpty() || anio == null) { | |||||
| Notification.show("Por favor, completa todos los campos.", 2000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| return; | |||||
| } | |||||
| try { | |||||
| // Preparando los parámetros para el reporte | |||||
| Map<String, Object> parametros = new HashMap<>(); | |||||
| parametros.put("pMES", mes); | |||||
| parametros.put("pANIO", anio); | |||||
| // Generando el PDF | |||||
| byte[] pdf = reportService.generarReporte("listadoMantenimientos", parametros); | |||||
| // Creando el recurso de descarga | |||||
| StreamResource resource = new StreamResource("listado_mantenimientos.pdf", () -> new ByteArrayInputStream(pdf)); | |||||
| /*Anchor downloadLink = new Anchor(resource, "Descargar Reporte"); | |||||
| downloadLink.setTarget("_blank"); | |||||
| downloadLink.setId("descargar-listado-link"); | |||||
| add(downloadLink); | |||||
| getUI().ifPresent(ui -> | |||||
| ui.getPage().executeJs("document.getElementById('descargar-listado-link').click();") | |||||
| );*/ | |||||
| StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry().registerResource(resource); | |||||
| UI.getCurrent().getPage().executeJs("window.open('" + registration.getResourceUri().toString() + "','_blank')"); | |||||
| } catch (Exception ex) { | |||||
| Notification.show("Error al generar el reporte: " + ex.getMessage(), 5000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_ERROR); | |||||
| ex.printStackTrace(); | |||||
| } | |||||
| }); | |||||
| Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); | |||||
| dialog.getFooter().add(btnCancelar, btnGenerar); | |||||
| dialog.add(layout); | |||||
| dialog.open(); | |||||
| } | |||||
| private class PersonContextMenu extends GridContextMenu<PlanAnual> { | |||||
| public PersonContextMenu(Grid<PlanAnual> target) { | |||||
| super(target); | |||||
| addItem("Realizar", e -> e.getItem().ifPresent(planAnual -> { | |||||
| int idPlananual = planAnual.getNumero(); | |||||
| LocalDate fechaSistema = LocalDate.now(); | |||||
| String nomEquipo = planAnual.getNomEquipo(); | |||||
| String departamento = planAnual.getDepartamento(); | |||||
| getUI().ifPresent(ui -> ui.navigate( | |||||
| "mantenimiento?id=" + idPlananual + | |||||
| "&fecha=" + fechaSistema + | |||||
| "&tipo=1" + | |||||
| "&nomEquipo=" + nomEquipo + | |||||
| "&departamento=" + departamento)); | |||||
| })); | |||||
| addItem("Borrar", e -> e.getItem().ifPresent(planAnual -> { | |||||
| eliminarPlanAnual(planAnual); | |||||
| })); | |||||
| add(new Hr()); | |||||
| GridMenuItem<PlanAnual> nomEquipo = addItem("Equipo", | |||||
| e -> e.getItem().ifPresent(planAnual -> { | |||||
| planAnual.getNomEquipo(); | |||||
| })); | |||||
| GridMenuItem<PlanAnual> depto = addItem("Departamento", | |||||
| e -> e.getItem().ifPresent(planAnual -> { | |||||
| planAnual.getDepartamento(); | |||||
| })); | |||||
| setDynamicContentHandler(planAnual -> { | |||||
| if (planAnual == null) | |||||
| return false; | |||||
| nomEquipo.setText(String.format("Equipo: %s", planAnual.getNomEquipo())); | |||||
| depto.setText(String.format("Area: %s", planAnual.getDepartamento())); | |||||
| return true; | |||||
| }); | |||||
| } | |||||
| } | |||||
| private void eliminarPlanAnual(PlanAnual planAnual) { | |||||
| Dialog dialog = new Dialog(); | |||||
| dialog.setHeaderTitle("Eliminar Mantenimiento"); | |||||
| TextField txtMotivo = new TextField("Justifica el motivo de la eliminación"); | |||||
| txtMotivo.setWidthFull(); | |||||
| txtMotivo.setRequired(true); | |||||
| dialog.add( | |||||
| new VerticalLayout( | |||||
| new Span("¿Estás seguro de que deseas eliminar el mantenimiento del equipo: " + planAnual.getNomEquipo()), | |||||
| txtMotivo | |||||
| ) | |||||
| ); | |||||
| Button btnEliminar = new Button("Eliminar", VaadinIcon.TRASH.create(), event -> { | |||||
| String motivo = txtMotivo.getValue(); | |||||
| if (motivo.isEmpty()) { | |||||
| txtMotivo.setErrorMessage("El motivo es requerido."); | |||||
| txtMotivo.setInvalid(true); | |||||
| return; | |||||
| } | |||||
| txtMotivo.setInvalid(false); | |||||
| Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |||||
| String usuarioId = authentication != null ? authentication.getName().toUpperCase() : "DESCONOCIDO"; | |||||
| LocalDate fecha = LocalDate.now(); | |||||
| // Llamar al servicio para insertar la bitácora de eliminación | |||||
| databaseService.insertarBitacoraEliminacion(planAnual.getNumero(), usuarioId, fecha, motivo); | |||||
| // Llamar al servicio para eliminar el plan anual | |||||
| databaseService.eliminarEquipoPlanAnual(planAnual.getNumero()); | |||||
| Notification.show("Equipo eliminado correctamente", 3000, Notification.Position.MIDDLE) | |||||
| .addThemeVariants(NotificationVariant.LUMO_SUCCESS); | |||||
| dialog.close(); | |||||
| UI.getCurrent().getPage().executeJs("setTimeout(() => { location.reload(); }, 2000);"); | |||||
| }); | |||||
| Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close()); | |||||
| HorizontalLayout dialogFooter = new HorizontalLayout(btnEliminar, btnCancelar); | |||||
| dialog.getFooter().add(dialogFooter); | |||||
| dialog.open(); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,106 @@ | |||||
| package mx.gob.jumapacelaya.ui.login; | |||||
| import com.vaadin.flow.component.UI; | |||||
| import com.vaadin.flow.component.html.Image; | |||||
| import com.vaadin.flow.component.login.LoginForm; | |||||
| import com.vaadin.flow.component.login.LoginI18n; | |||||
| import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||||
| import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||||
| import com.vaadin.flow.router.BeforeEnterEvent; | |||||
| import com.vaadin.flow.router.BeforeEnterObserver; | |||||
| import com.vaadin.flow.router.PageTitle; | |||||
| import com.vaadin.flow.router.Route; | |||||
| import com.vaadin.flow.server.auth.AnonymousAllowed; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| @Route("login") | |||||
| @PageTitle("Login") | |||||
| @AnonymousAllowed | |||||
| public class LoginView extends VerticalLayout implements BeforeEnterObserver { | |||||
| private static final Logger log = LoggerFactory.getLogger(LoginView.class); | |||||
| private final LoginForm login = new LoginForm(); | |||||
| // Usuario local para demostracion | |||||
| private final String localUser = "admin"; | |||||
| private final String localPassword = "admin"; | |||||
| public LoginView(){ | |||||
| //Configuracion de la vista | |||||
| addClassName("login"); | |||||
| setSizeFull(); | |||||
| setPadding(false); | |||||
| setMargin(false); | |||||
| // Crear el layout horizontal | |||||
| HorizontalLayout mainLayout = new HorizontalLayout(); | |||||
| mainLayout.setSizeFull(); | |||||
| mainLayout.setPadding(false); | |||||
| mainLayout.setMargin(false); | |||||
| // Configuración de i18n para el formulario de login | |||||
| LoginI18n i18n = LoginI18n.createDefault(); | |||||
| LoginI18n.Form i18nFormulario = i18n.getForm(); | |||||
| i18nFormulario.setTitle("Mantenimiento Preventivo y Correctivo"); | |||||
| i18nFormulario.setUsername("Usuario"); | |||||
| i18nFormulario.setPassword("Contraseña"); | |||||
| i18nFormulario.setSubmit("Iniciar sesión"); | |||||
| i18n.setForm(i18nFormulario); | |||||
| // Configuración de los mensajes de error | |||||
| LoginI18n.ErrorMessage i18nError = i18n.getErrorMessage(); | |||||
| i18nError.setTitle("Credenciales incorrectas"); | |||||
| i18nError.setMessage("Usuario o contraseña incorrectos, verifica tus credenciales"); | |||||
| i18n.setErrorMessage(i18nError); | |||||
| i18n.setAdditionalInformation("Versión 2.0.0 - © 2024 JUMAPACelaya"); | |||||
| // Configuración del formulario de login | |||||
| login.setAction("login"); | |||||
| login.setForgotPasswordButtonVisible(false); | |||||
| login.setI18n(i18n); | |||||
| // Crear un contenedor para el formulario | |||||
| VerticalLayout loginFormContainer = new VerticalLayout(); | |||||
| Image imageLogin = new Image("images/LOGO_24'27.png", "Login"); | |||||
| imageLogin.setWidth("300px"); | |||||
| loginFormContainer.add(imageLogin); | |||||
| loginFormContainer.add(login); | |||||
| loginFormContainer.setSizeUndefined(); | |||||
| loginFormContainer.setPadding(false); | |||||
| loginFormContainer.setMargin(false); | |||||
| loginFormContainer.setAlignItems(Alignment.CENTER); | |||||
| loginFormContainer.setJustifyContentMode(JustifyContentMode.CENTER); | |||||
| loginFormContainer.getElement().getThemeList().add("dark"); | |||||
| // Añadir la imagen y el contenedor del formulario al layout principal | |||||
| mainLayout.add(loginFormContainer); | |||||
| mainLayout.setFlexGrow(1, loginFormContainer); | |||||
| mainLayout.setFlexGrow(2); | |||||
| // Añadir el layout principal a la vista | |||||
| add(mainLayout); | |||||
| } | |||||
| @Override | |||||
| public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { | |||||
| if(beforeEnterEvent.getLocation() | |||||
| .getQueryParameters() | |||||
| .getParameters() | |||||
| .containsKey("error")){ | |||||
| login.setError(true); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,4 @@ | |||||
| #Configuracion de la base de datos | |||||
| db.url=jdbc:mysql://localhost:3307/mantenimientosdb | |||||
| db.user=mantenimientos | |||||
| db.pass=mantenimientos | |||||
| @ -0,0 +1,5 @@ | |||||
| #Configuracion de la base de datos | |||||
| db.url=jdbc:mysql://db:3306/mantenimientosdb | |||||
| #db.url=jdbc:oracle:thin:@//SVRAPPS:1521/XEPDB1 | |||||
| db.user=mantenimientos | |||||
| db.pass=mantenimientos | |||||
| @ -0,0 +1,34 @@ | |||||
| server.port=${PORT:8080} | |||||
| logging.level.org.atmosphere = warn | |||||
| spring.profiles.active=dev | |||||
| # Launch the default browser when starting the application in development mode | |||||
| vaadin.launch-browser=true | |||||
| # To improve the performance during development. | |||||
| # For more information https://vaadin.com/docs/latest/integrations/spring/configuration#special-configuration-parameters | |||||
| vaadin.allowed-packages = com.vaadin,org.vaadin,mx.gob.jumapacelaya, de.f0rce.signaturepad | |||||
| spring.jpa.defer-datasource-initialization = true | |||||
| #Configuracion LDAP | |||||
| spring.ldap.urls=ldap://172.1.0.1:389 | |||||
| spring.ldap.base=DC=JUMAPACELAYA,DC=GOB,DC=MX | |||||
| spring.ldap.username=administrator | |||||
| spring.ldap.password=Dr3na$134%4guA | |||||
| ###################PRODUCTIVO#################### | |||||
| redmine.url=https://proyman.jumapacelaya.gob.mx/ | |||||
| redmine.api_key=69be2a5df9bacce02722f566fdf0731d728a1b86 | |||||
| #Conexion al servidor de correo electronico | |||||
| spring.mail.host=correo.jumapacelaya.gob.mx | |||||
| spring.mail.port=587 | |||||
| spring.mail.username=noreply@jumapacelaya.gob.mx | |||||
| spring.mail.password=Div#13AJum$17 | |||||
| spring.mail.properties.mail.smtp.auth=true | |||||
| spring.mail.properties.mail.smtp.starttls.enable=false | |||||
| spring.mail.properties.mail.smtp.ssl.trust=correo.jumapacelaya.gob.mx | |||||
| @ -0,0 +1,6 @@ | |||||
| ____ _ _ _ __ __ _ _ _ _ | |||||
| / ___|(_)___| |_ ___ _ __ ___ __ _ __| | ___ | \/ | __ _ _ __ | |_ ___ _ __ (_)_ __ ___ (_) ___ _ __ | |_ ___ | |||||
| \___ \| / __| __/ _ \ '_ ` _ \ / _` | / _` |/ _ \ | |\/| |/ _` | '_ \| __/ _ \ '_ \| | '_ ` _ \| |/ _ \ '_ \| __/ _ \ | |||||
| ___) | \__ \ || __/ | | | | | (_| | | (_| | __/ | | | | (_| | | | | || __/ | | | | | | | | | | __/ | | | || (_) | | |||||
| |____/|_|___/\__\___|_| |_| |_|\__,_| \__,_|\___| |_| |_|\__,_|_| |_|\__\___|_| |_|_|_| |_| |_|_|\___|_| |_|\__\___/ | |||||
| @ -0,0 +1,39 @@ | |||||
| // This TypeScript configuration file is generated by vaadin-maven-plugin. | |||||
| // This is needed for TypeScript compiler to compile your TypeScript code in the project. | |||||
| // It is recommended to commit this file to the VCS. | |||||
| // You might want to change the configurations to fit your preferences | |||||
| // For more information about the configurations, please refer to http://www.typescriptlang.org/docs/handbook/tsconfig-json.html | |||||
| { | |||||
| "_version": "9.1", | |||||
| "compilerOptions": { | |||||
| "sourceMap": true, | |||||
| "jsx": "react-jsx", | |||||
| "inlineSources": true, | |||||
| "module": "esNext", | |||||
| "target": "es2020", | |||||
| "moduleResolution": "bundler", | |||||
| "strict": true, | |||||
| "skipLibCheck": true, | |||||
| "noFallthroughCasesInSwitch": true, | |||||
| "noImplicitReturns": true, | |||||
| "noImplicitAny": true, | |||||
| "noImplicitThis": true, | |||||
| "noUnusedLocals": false, | |||||
| "noUnusedParameters": false, | |||||
| "experimentalDecorators": true, | |||||
| "useDefineForClassFields": false, | |||||
| "baseUrl": "src/main/frontend", | |||||
| "paths": { | |||||
| "@vaadin/flow-frontend": ["generated/jar-resources"], | |||||
| "@vaadin/flow-frontend/*": ["generated/jar-resources/*"], | |||||
| "Frontend/*": ["*"] | |||||
| } | |||||
| }, | |||||
| "include": [ | |||||
| "src/main/frontend/**/*", | |||||
| "types.d.ts" | |||||
| ], | |||||
| "exclude": [ | |||||
| "src/main/frontend/generated/jar-resources/**" | |||||
| ] | |||||
| } | |||||
| @ -0,0 +1,17 @@ | |||||
| // This TypeScript modules definition file is generated by vaadin-maven-plugin. | |||||
| // You can not directly import your different static files into TypeScript, | |||||
| // This is needed for TypeScript compiler to declare and export as a TypeScript module. | |||||
| // It is recommended to commit this file to the VCS. | |||||
| // You might want to change the configurations to fit your preferences | |||||
| declare module '*.css?inline' { | |||||
| import type { CSSResultGroup } from 'lit'; | |||||
| const content: CSSResultGroup; | |||||
| export default content; | |||||
| } | |||||
| // Allow any CSS Custom Properties | |||||
| declare module 'csstype' { | |||||
| interface Properties { | |||||
| [index: `--${string}`]: any; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,9 @@ | |||||
| import { UserConfigFn } from 'vite'; | |||||
| import { overrideVaadinConfig } from './vite.generated'; | |||||
| const customConfig: UserConfigFn = (env) => ({ | |||||
| // Here you can add custom Vite parameters | |||||
| // https://vitejs.dev/config/ | |||||
| }); | |||||
| export default overrideVaadinConfig(customConfig); | |||||