commit
ebedfd152f
140 changed files with 140173 additions and 0 deletions
-
4.env
-
2.gitattributes
-
42.gitignore
-
3.mvn/wrapper/maven-wrapper.properties
-
295mvnw
-
189mvnw.cmd
-
125pom.xml
-
32src/main/java/com/adjustment_file_management_system/springboot/AdjustmentFileManagementSystemApplication.java
-
16src/main/java/com/adjustment_file_management_system/springboot/configuration/ApplicationConfiguration.java
-
42src/main/java/com/adjustment_file_management_system/springboot/configuration/AuditorAwareConfiguration.java
-
44src/main/java/com/adjustment_file_management_system/springboot/configuration/CustomAuthenticationProvider.java
-
15src/main/java/com/adjustment_file_management_system/springboot/configuration/FileDataProperties.java
-
64src/main/java/com/adjustment_file_management_system/springboot/configuration/FileDataPropertiesConfiguration.java
-
100src/main/java/com/adjustment_file_management_system/springboot/configuration/LogFolderInitializer.java
-
18src/main/java/com/adjustment_file_management_system/springboot/configuration/LogReadyInitializer.java
-
90src/main/java/com/adjustment_file_management_system/springboot/configuration/SecurityConfiguration.java
-
82src/main/java/com/adjustment_file_management_system/springboot/controller/FileDataController.java
-
44src/main/java/com/adjustment_file_management_system/springboot/controller/HomeController.java
-
22src/main/java/com/adjustment_file_management_system/springboot/mapper/AdvanceTypeMapper.java
-
18src/main/java/com/adjustment_file_management_system/springboot/mapper/AppUserMapper.java
-
127src/main/java/com/adjustment_file_management_system/springboot/mapper/FileDataMapper.java
-
15src/main/java/com/adjustment_file_management_system/springboot/mapper/FundTypeMapper.java
-
13src/main/java/com/adjustment_file_management_system/springboot/mapper/UserRoleMapper.java
-
43src/main/java/com/adjustment_file_management_system/springboot/model/AdvanceType.java
-
52src/main/java/com/adjustment_file_management_system/springboot/model/AppUser.java
-
213src/main/java/com/adjustment_file_management_system/springboot/model/FileData.java
-
43src/main/java/com/adjustment_file_management_system/springboot/model/FundType.java
-
52src/main/java/com/adjustment_file_management_system/springboot/model/UserRole.java
-
18src/main/java/com/adjustment_file_management_system/springboot/repository/AdvanceTypeRepository.java
-
13src/main/java/com/adjustment_file_management_system/springboot/repository/AppUserRepository.java
-
15src/main/java/com/adjustment_file_management_system/springboot/repository/FileDataRepository.java
-
11src/main/java/com/adjustment_file_management_system/springboot/repository/FundTypeRepository.java
-
34src/main/java/com/adjustment_file_management_system/springboot/request_dto/AddFileDataRequestDTO.java
-
18src/main/java/com/adjustment_file_management_system/springboot/request_dto/AdvanceTypeRequestDTO.java
-
17src/main/java/com/adjustment_file_management_system/springboot/request_dto/AppUserRequestDTO.java
-
44src/main/java/com/adjustment_file_management_system/springboot/request_dto/FileDataRequestDTO.java
-
50src/main/java/com/adjustment_file_management_system/springboot/request_dto/UpdateFileDataRequestDTO.java
-
19src/main/java/com/adjustment_file_management_system/springboot/response_dto/AdvanceTypeResponseDTO.java
-
19src/main/java/com/adjustment_file_management_system/springboot/response_dto/AppUserResponseDTO.java
-
46src/main/java/com/adjustment_file_management_system/springboot/response_dto/FileDataResponseDTO.java
-
17src/main/java/com/adjustment_file_management_system/springboot/response_dto/FundTypeResponseDTO.java
-
19src/main/java/com/adjustment_file_management_system/springboot/response_dto/ServiceResponseDTO.java
-
17src/main/java/com/adjustment_file_management_system/springboot/response_dto/UserRoleResponseDTO.java
-
93src/main/java/com/adjustment_file_management_system/springboot/rest_controller/FileDataRestController.java
-
78src/main/java/com/adjustment_file_management_system/springboot/rest_controller/HomeRestController.java
-
606src/main/java/com/adjustment_file_management_system/springboot/service/FileDataService.java
-
119src/main/java/com/adjustment_file_management_system/springboot/service/FolderService.java
-
64src/main/java/com/adjustment_file_management_system/springboot/service/HomeService.java
-
12src/main/resources/META-INF/additional-spring-configuration-metadata.json
-
48src/main/resources/application.properties
-
33src/main/resources/logback-spring.xml
-
11794src/main/resources/static/bootstrap-5.3.2/css/bootstrap.min.css
-
2212src/main/resources/static/bootstrap-5.3.2/js/bootstrap.min.js
-
192src/main/resources/static/css/body-form-styles.css
-
12src/main/resources/static/css/btn-secondary-styles.css
-
98src/main/resources/static/css/datatable-styles.css
-
77src/main/resources/static/css/header-styles.css
-
40src/main/resources/static/css/home-styles.css
-
272src/main/resources/static/css/login-form-styles.css
-
58src/main/resources/static/css/view-file-detail-styles.css
-
60src/main/resources/static/css/view-file-styles.css
-
532src/main/resources/static/datatables-1.13.6/css/dataTables.bootstrap5.min.css
-
80src/main/resources/static/datatables-1.13.6/js/dataTables.bootstrap5.min.js
-
2990src/main/resources/static/datatables-1.13.6/js/jquery.dataTables.min.js
-
248src/main/resources/static/datatables-buttons-2.4.1/css/buttons.bootstrap5.min.css
-
70src/main/resources/static/datatables-buttons-2.4.1/js/buttons.bootstrap5.min.js
-
538src/main/resources/static/datatables-buttons-2.4.1/js/buttons.html5.min.js
-
79src/main/resources/static/datatables-buttons-2.4.1/js/buttons.print.min.js
-
764src/main/resources/static/datatables-buttons-2.4.1/js/dataTables.buttons.min.js
-
793src/main/resources/static/flatpickr-4.6.13/css/flatpickr.min.css
-
1379src/main/resources/static/flatpickr-4.6.13/js/flatpickr.js
-
6995src/main/resources/static/font-awesome-6.5.1/css/all.min.css
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-brands-400.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-brands-400.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-regular-400.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-regular-400.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-solid-900.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-solid-900.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-v4compatibility.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.1/webfonts/fa-v4compatibility.woff2
-
7023src/main/resources/static/font-awesome-6.5.2/css/all.min.css
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-brands-400.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-brands-400.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-regular-400.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-regular-400.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-solid-900.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-solid-900.woff2
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf
-
BINsrc/main/resources/static/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2
-
BINsrc/main/resources/static/header-images/gcc1.png
-
25996src/main/resources/static/html2pdf-0.9.3/js/html2pdf.bundle.min.js
-
3244src/main/resources/static/jquery-3.6.4/js/jquery-3.6.4.min.js
-
77src/main/resources/static/js/add-file-script.js
-
17src/main/resources/static/js/adjust-row-class-script.js
-
20src/main/resources/static/js/fetch-csrf-script.js
-
3src/main/resources/static/js/go-back-script.js
-
31src/main/resources/static/js/login-script.js
-
118src/main/resources/static/js/update-ejv-number-script.js
-
351src/main/resources/static/js/update-file-script.js
-
157src/main/resources/static/js/view-file-detail-script.js
@ -0,0 +1,4 @@ |
|||
DB_URL=jdbc:oracle:thin:@10.1.0.14:1521:chncorp |
|||
DB_USERNAME=fileadjust |
|||
DB_PASSWORD=fileadjust |
|||
FORCE_HTTPS=false |
|||
@ -0,0 +1,2 @@ |
|||
/mvnw text eol=lf |
|||
*.cmd text eol=crlf |
|||
@ -0,0 +1,42 @@ |
|||
HELP.md |
|||
target/ |
|||
.mvn/wrapper/maven-wrapper.jar |
|||
!**/src/main/**/target/ |
|||
!**/src/test/**/target/ |
|||
|
|||
### STS ### |
|||
.apt_generated |
|||
.classpath |
|||
.factorypath |
|||
.project |
|||
.settings |
|||
.springBeans |
|||
.sts4-cache |
|||
|
|||
### IntelliJ IDEA ### |
|||
.idea |
|||
*.iws |
|||
*.iml |
|||
*.ipr |
|||
|
|||
### NetBeans ### |
|||
/nbproject/private/ |
|||
/nbbuild/ |
|||
/dist/ |
|||
/nbdist/ |
|||
/.nb-gradle/ |
|||
build/ |
|||
!**/src/main/**/build/ |
|||
!**/src/test/**/build/ |
|||
|
|||
### VS Code ### |
|||
.vscode/ |
|||
|
|||
### Logs ### |
|||
log/ |
|||
logs/ |
|||
*.log |
|||
|
|||
### File Uploads ### |
|||
uploads/file-data/* |
|||
!uploads/file-data/.gitkeep |
|||
@ -0,0 +1,3 @@ |
|||
wrapperVersion=3.3.4 |
|||
distributionType=only-script |
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip |
|||
@ -0,0 +1,295 @@ |
|||
#!/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. |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
# ---------------------------------------------------------------------------- |
|||
# Apache Maven Wrapper startup batch script, version 3.3.4 |
|||
# |
|||
# Optional ENV vars |
|||
# ----------------- |
|||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source |
|||
# MVNW_REPOURL - repo url base for downloading maven distribution |
|||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
|||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
set -euf |
|||
[ "${MVNW_VERBOSE-}" != debug ] || set -x |
|||
|
|||
# OS specific support. |
|||
native_path() { printf %s\\n "$1"; } |
|||
case "$(uname)" in |
|||
CYGWIN* | MINGW*) |
|||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" |
|||
native_path() { cygpath --path --windows "$1"; } |
|||
;; |
|||
esac |
|||
|
|||
# set JAVACMD and JAVACCMD |
|||
set_java_home() { |
|||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched |
|||
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" |
|||
JAVACCMD="$JAVA_HOME/jre/sh/javac" |
|||
else |
|||
JAVACMD="$JAVA_HOME/bin/java" |
|||
JAVACCMD="$JAVA_HOME/bin/javac" |
|||
|
|||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then |
|||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 |
|||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 |
|||
return 1 |
|||
fi |
|||
fi |
|||
else |
|||
JAVACMD="$( |
|||
'set' +e |
|||
'unset' -f command 2>/dev/null |
|||
'command' -v java |
|||
)" || : |
|||
JAVACCMD="$( |
|||
'set' +e |
|||
'unset' -f command 2>/dev/null |
|||
'command' -v javac |
|||
)" || : |
|||
|
|||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then |
|||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 |
|||
return 1 |
|||
fi |
|||
fi |
|||
} |
|||
|
|||
# hash string like Java String::hashCode |
|||
hash_string() { |
|||
str="${1:-}" h=0 |
|||
while [ -n "$str" ]; do |
|||
char="${str%"${str#?}"}" |
|||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) |
|||
str="${str#?}" |
|||
done |
|||
printf %x\\n $h |
|||
} |
|||
|
|||
verbose() { :; } |
|||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } |
|||
|
|||
die() { |
|||
printf %s\\n "$1" >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
trim() { |
|||
# MWRAPPER-139: |
|||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. |
|||
# Needed for removing poorly interpreted newline sequences when running in more |
|||
# exotic environments such as mingw bash on Windows. |
|||
printf "%s" "${1}" | tr -d '[:space:]' |
|||
} |
|||
|
|||
scriptDir="$(dirname "$0")" |
|||
scriptName="$(basename "$0")" |
|||
|
|||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties |
|||
while IFS="=" read -r key value; do |
|||
case "${key-}" in |
|||
distributionUrl) distributionUrl=$(trim "${value-}") ;; |
|||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; |
|||
esac |
|||
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" |
|||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" |
|||
|
|||
case "${distributionUrl##*/}" in |
|||
maven-mvnd-*bin.*) |
|||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ |
|||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in |
|||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; |
|||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;; |
|||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;; |
|||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;; |
|||
*) |
|||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 |
|||
distributionPlatform=linux-amd64 |
|||
;; |
|||
esac |
|||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" |
|||
;; |
|||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; |
|||
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; |
|||
esac |
|||
|
|||
# apply MVNW_REPOURL and calculate MAVEN_HOME |
|||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
|||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" |
|||
distributionUrlName="${distributionUrl##*/}" |
|||
distributionUrlNameMain="${distributionUrlName%.*}" |
|||
distributionUrlNameMain="${distributionUrlNameMain%-bin}" |
|||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" |
|||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" |
|||
|
|||
exec_maven() { |
|||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : |
|||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" |
|||
} |
|||
|
|||
if [ -d "$MAVEN_HOME" ]; then |
|||
verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
|||
exec_maven "$@" |
|||
fi |
|||
|
|||
case "${distributionUrl-}" in |
|||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; |
|||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; |
|||
esac |
|||
|
|||
# prepare tmp dir |
|||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then |
|||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } |
|||
trap clean HUP INT TERM EXIT |
|||
else |
|||
die "cannot create temp dir" |
|||
fi |
|||
|
|||
mkdir -p -- "${MAVEN_HOME%/*}" |
|||
|
|||
# Download and Install Apache Maven |
|||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
|||
verbose "Downloading from: $distributionUrl" |
|||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
|
|||
# select .zip or .tar.gz |
|||
if ! command -v unzip >/dev/null; then |
|||
distributionUrl="${distributionUrl%.zip}.tar.gz" |
|||
distributionUrlName="${distributionUrl##*/}" |
|||
fi |
|||
|
|||
# verbose opt |
|||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' |
|||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v |
|||
|
|||
# normalize http auth |
|||
case "${MVNW_PASSWORD:+has-password}" in |
|||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
|||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
|||
esac |
|||
|
|||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then |
|||
verbose "Found wget ... using wget" |
|||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" |
|||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then |
|||
verbose "Found curl ... using curl" |
|||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" |
|||
elif set_java_home; then |
|||
verbose "Falling back to use Java to download" |
|||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" |
|||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
cat >"$javaSource" <<-END |
|||
public class Downloader extends java.net.Authenticator |
|||
{ |
|||
protected java.net.PasswordAuthentication getPasswordAuthentication() |
|||
{ |
|||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); |
|||
} |
|||
public static void main( String[] args ) throws Exception |
|||
{ |
|||
setDefault( new Downloader() ); |
|||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); |
|||
} |
|||
} |
|||
END |
|||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java |
|||
verbose " - Compiling Downloader.java ..." |
|||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" |
|||
verbose " - Running Downloader.java ..." |
|||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" |
|||
fi |
|||
|
|||
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
|||
if [ -n "${distributionSha256Sum-}" ]; then |
|||
distributionSha256Result=false |
|||
if [ "$MVN_CMD" = mvnd.sh ]; then |
|||
echo "Checksum validation is not supported for maven-mvnd." >&2 |
|||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
|||
exit 1 |
|||
elif command -v sha256sum >/dev/null; then |
|||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then |
|||
distributionSha256Result=true |
|||
fi |
|||
elif command -v shasum >/dev/null; then |
|||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then |
|||
distributionSha256Result=true |
|||
fi |
|||
else |
|||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 |
|||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
|||
exit 1 |
|||
fi |
|||
if [ $distributionSha256Result = false ]; then |
|||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 |
|||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 |
|||
exit 1 |
|||
fi |
|||
fi |
|||
|
|||
# unzip and move |
|||
if command -v unzip >/dev/null; then |
|||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" |
|||
else |
|||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" |
|||
fi |
|||
|
|||
# Find the actual extracted directory name (handles snapshots where filename != directory name) |
|||
actualDistributionDir="" |
|||
|
|||
# First try the expected directory name (for regular distributions) |
|||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then |
|||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then |
|||
actualDistributionDir="$distributionUrlNameMain" |
|||
fi |
|||
fi |
|||
|
|||
# If not found, search for any directory with the Maven executable (for snapshots) |
|||
if [ -z "$actualDistributionDir" ]; then |
|||
# enable globbing to iterate over items |
|||
set +f |
|||
for dir in "$TMP_DOWNLOAD_DIR"/*; do |
|||
if [ -d "$dir" ]; then |
|||
if [ -f "$dir/bin/$MVN_CMD" ]; then |
|||
actualDistributionDir="$(basename "$dir")" |
|||
break |
|||
fi |
|||
fi |
|||
done |
|||
set -f |
|||
fi |
|||
|
|||
if [ -z "$actualDistributionDir" ]; then |
|||
verbose "Contents of $TMP_DOWNLOAD_DIR:" |
|||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" |
|||
die "Could not find Maven distribution directory in extracted archive" |
|||
fi |
|||
|
|||
verbose "Found extracted Maven distribution directory: $actualDistributionDir" |
|||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" |
|||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" |
|||
|
|||
clean || : |
|||
exec_maven "$@" |
|||
@ -0,0 +1,189 @@ |
|||
<# : batch portion |
|||
@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 Apache Maven Wrapper startup batch script, version 3.3.4 |
|||
@REM |
|||
@REM Optional ENV vars |
|||
@REM MVNW_REPOURL - repo url base for downloading maven distribution |
|||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
|||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output |
|||
@REM ---------------------------------------------------------------------------- |
|||
|
|||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) |
|||
@SET __MVNW_CMD__= |
|||
@SET __MVNW_ERROR__= |
|||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% |
|||
@SET PSModulePath= |
|||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( |
|||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) |
|||
) |
|||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% |
|||
@SET __MVNW_PSMODULEP_SAVE= |
|||
@SET __MVNW_ARG0_NAME__= |
|||
@SET MVNW_USERNAME= |
|||
@SET MVNW_PASSWORD= |
|||
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) |
|||
@echo Cannot start maven from wrapper >&2 && exit /b 1 |
|||
@GOTO :EOF |
|||
: end batch / begin powershell #> |
|||
|
|||
$ErrorActionPreference = "Stop" |
|||
if ($env:MVNW_VERBOSE -eq "true") { |
|||
$VerbosePreference = "Continue" |
|||
} |
|||
|
|||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties |
|||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl |
|||
if (!$distributionUrl) { |
|||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" |
|||
} |
|||
|
|||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { |
|||
"maven-mvnd-*" { |
|||
$USE_MVND = $true |
|||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" |
|||
$MVN_CMD = "mvnd.cmd" |
|||
break |
|||
} |
|||
default { |
|||
$USE_MVND = $false |
|||
$MVN_CMD = $script -replace '^mvnw','mvn' |
|||
break |
|||
} |
|||
} |
|||
|
|||
# apply MVNW_REPOURL and calculate MAVEN_HOME |
|||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
|||
if ($env:MVNW_REPOURL) { |
|||
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } |
|||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" |
|||
} |
|||
$distributionUrlName = $distributionUrl -replace '^.*/','' |
|||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' |
|||
|
|||
$MAVEN_M2_PATH = "$HOME/.m2" |
|||
if ($env:MAVEN_USER_HOME) { |
|||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" |
|||
} |
|||
|
|||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) { |
|||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null |
|||
} |
|||
|
|||
$MAVEN_WRAPPER_DISTS = $null |
|||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { |
|||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" |
|||
} else { |
|||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" |
|||
} |
|||
|
|||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" |
|||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' |
|||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" |
|||
|
|||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { |
|||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
|||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
|||
exit $? |
|||
} |
|||
|
|||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { |
|||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" |
|||
} |
|||
|
|||
# prepare tmp dir |
|||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile |
|||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" |
|||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null |
|||
trap { |
|||
if ($TMP_DOWNLOAD_DIR.Exists) { |
|||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
|||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
|||
} |
|||
} |
|||
|
|||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null |
|||
|
|||
# Download and Install Apache Maven |
|||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
|||
Write-Verbose "Downloading from: $distributionUrl" |
|||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
|||
|
|||
$webclient = New-Object System.Net.WebClient |
|||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { |
|||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) |
|||
} |
|||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
|||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null |
|||
|
|||
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
|||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum |
|||
if ($distributionSha256Sum) { |
|||
if ($USE_MVND) { |
|||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." |
|||
} |
|||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash |
|||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { |
|||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." |
|||
} |
|||
} |
|||
|
|||
# unzip and move |
|||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null |
|||
|
|||
# Find the actual extracted directory name (handles snapshots where filename != directory name) |
|||
$actualDistributionDir = "" |
|||
|
|||
# First try the expected directory name (for regular distributions) |
|||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" |
|||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" |
|||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { |
|||
$actualDistributionDir = $distributionUrlNameMain |
|||
} |
|||
|
|||
# If not found, search for any directory with the Maven executable (for snapshots) |
|||
if (!$actualDistributionDir) { |
|||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { |
|||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD" |
|||
if (Test-Path -Path $testPath -PathType Leaf) { |
|||
$actualDistributionDir = $_.Name |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (!$actualDistributionDir) { |
|||
Write-Error "Could not find Maven distribution directory in extracted archive" |
|||
} |
|||
|
|||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" |
|||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null |
|||
try { |
|||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null |
|||
} catch { |
|||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { |
|||
Write-Error "fail to move MAVEN_HOME" |
|||
} |
|||
} finally { |
|||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
|||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
|||
} |
|||
|
|||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
|||
@ -0,0 +1,125 @@ |
|||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>3.5.9</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>com.adjustment-file-management-system</groupId> |
|||
<artifactId>adjustment-file-management-system</artifactId> |
|||
<version>0.0.1-SNAPSHOT</version> |
|||
<name>adjustment-file-management-system</name> |
|||
<description>Springboot Project For Adjustment File Management System</description> |
|||
<url/> |
|||
<licenses> |
|||
<license/> |
|||
</licenses> |
|||
<developers> |
|||
<developer/> |
|||
</developers> |
|||
<scm> |
|||
<connection/> |
|||
<developerConnection/> |
|||
<tag/> |
|||
<url/> |
|||
</scm> |
|||
<properties> |
|||
<java.version>21</java.version> |
|||
</properties> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-jpa</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-rest</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-thymeleaf</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-validation</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-devtools</artifactId> |
|||
<scope>runtime</scope> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.oracle.database.jdbc</groupId> |
|||
<artifactId>ojdbc11</artifactId> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<optional>true</optional> |
|||
</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-configuration-processor</artifactId> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-security</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.security</groupId> |
|||
<artifactId>spring-security-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>io.github.cdimascio</groupId> |
|||
<artifactId>java-dotenv</artifactId> |
|||
<version>5.2.2</version> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
<finalName>adjustment-file-management-system</finalName> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-compiler-plugin</artifactId> |
|||
<configuration> |
|||
<annotationProcessorPaths> |
|||
<path> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
</path> |
|||
</annotationProcessorPaths> |
|||
</configuration> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
<configuration> |
|||
<excludes> |
|||
<exclude> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
</exclude> |
|||
</excludes> |
|||
</configuration> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
|||
@ -0,0 +1,32 @@ |
|||
package com.adjustment_file_management_system.springboot; |
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; |
|||
|
|||
import com.adjustment_file_management_system.springboot.configuration.LogFolderInitializer; |
|||
import com.adjustment_file_management_system.springboot.configuration.LogReadyInitializer; |
|||
|
|||
import io.github.cdimascio.dotenv.Dotenv; |
|||
import io.github.cdimascio.dotenv.DotenvEntry; |
|||
|
|||
@SpringBootApplication |
|||
@EnableJpaAuditing(auditorAwareRef = "auditorAware") |
|||
public class AdjustmentFileManagementSystemApplication { |
|||
|
|||
static { |
|||
Dotenv dotEnv = Dotenv.configure().ignoreIfMissing().load(); |
|||
for(DotenvEntry entry : dotEnv.entries()) { |
|||
System.setProperty(entry.getKey(), entry.getValue()); |
|||
} |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
SpringApplication app = new SpringApplication(AdjustmentFileManagementSystemApplication.class); |
|||
// Register pre-logging and post-logging listeners |
|||
app.addListeners(new LogFolderInitializer()); // creates logs folder & initial file |
|||
app.addListeners(new LogReadyInitializer()); // logs a startup info message |
|||
app.run(args); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
|||
import org.springframework.security.crypto.password.PasswordEncoder; |
|||
|
|||
@Configuration |
|||
public class ApplicationConfiguration { |
|||
|
|||
@Bean |
|||
PasswordEncoder passwordEncoder() { |
|||
return new BCryptPasswordEncoder(12); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import java.util.Optional; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.data.domain.AuditorAware; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.security.core.context.SecurityContextHolder; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.transaction.annotation.Propagation; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AppUser; |
|||
import com.adjustment_file_management_system.springboot.repository.AppUserRepository; |
|||
|
|||
@Component("auditorAware") |
|||
public class AuditorAwareConfiguration implements AuditorAware<AppUser> { |
|||
|
|||
@Autowired |
|||
private AppUserRepository appUsrRepo; |
|||
|
|||
@Override |
|||
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) |
|||
public Optional<AppUser> getCurrentAuditor() { |
|||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
|||
|
|||
if (authentication == null || !authentication.isAuthenticated()) { |
|||
return Optional.empty(); |
|||
} |
|||
|
|||
// If it's already AppUser, no need to hit DB |
|||
Object principal = authentication.getPrincipal(); |
|||
if (principal instanceof AppUser user) { |
|||
return Optional.of(user); |
|||
} |
|||
|
|||
// Fetch AppUser from DB using username |
|||
String username = authentication.getName(); |
|||
return appUsrRepo.findByUsrName(username); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.authentication.AuthenticationProvider; |
|||
import org.springframework.security.authentication.BadCredentialsException; |
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.security.core.AuthenticationException; |
|||
import org.springframework.security.core.userdetails.UserDetails; |
|||
import org.springframework.security.crypto.password.PasswordEncoder; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.service.HomeService; |
|||
|
|||
@Component |
|||
public class CustomAuthenticationProvider implements AuthenticationProvider { |
|||
|
|||
@Autowired |
|||
private HomeService homeSer; |
|||
|
|||
@Autowired |
|||
private PasswordEncoder passEncode; |
|||
|
|||
@Override |
|||
public Authentication authenticate(Authentication authentication) throws AuthenticationException { |
|||
String username = authentication.getName(); |
|||
String password = authentication.getCredentials().toString(); |
|||
|
|||
UserDetails usrDets = homeSer.loadUserByUsername(username); // throws UsernameNotFoundException if not found |
|||
|
|||
if (!passEncode.matches(password, usrDets.getPassword())) { |
|||
throw new BadCredentialsException("Invalid username or password"); |
|||
} |
|||
|
|||
return new UsernamePasswordAuthenticationToken(usrDets.getUsername(), usrDets.getPassword(), |
|||
usrDets.getAuthorities()); |
|||
} |
|||
|
|||
@Override |
|||
public boolean supports(Class<?> authentication) { |
|||
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
@Component |
|||
@Getter |
|||
@Setter |
|||
@ConfigurationProperties(prefix = "file.data") |
|||
public class FileDataProperties { |
|||
private String uploadDir; |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import java.io.File; |
|||
import java.nio.file.Paths; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.boot.system.ApplicationHome; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|||
|
|||
import jakarta.annotation.PostConstruct; |
|||
import lombok.Getter; |
|||
|
|||
@Configuration |
|||
@Getter |
|||
public class FileDataPropertiesConfiguration implements WebMvcConfigurer { |
|||
|
|||
@Autowired |
|||
private FileDataProperties fileDataProps; |
|||
|
|||
private File uploadDirFile; |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(FileDataPropertiesConfiguration.class); |
|||
|
|||
@PostConstruct |
|||
public void init() { |
|||
try { |
|||
File baseDir; |
|||
ApplicationHome home = new ApplicationHome(FileDataPropertiesConfiguration.class); |
|||
|
|||
if (home.getSource() != null && home.getSource().isFile() && home.getSource().getName().endsWith(".jar")) { |
|||
// Running as a packaged JAR |
|||
baseDir = home.getDir(); |
|||
} else { |
|||
// Running from IDE -> use project root instead of target/classes |
|||
baseDir = new File(System.getProperty("user.dir")); |
|||
} |
|||
|
|||
// Create /images/product relative to baseDir |
|||
uploadDirFile = Paths.get(baseDir.getAbsolutePath(), fileDataProps.getUploadDir()).toFile(); |
|||
|
|||
if (!uploadDirFile.exists()) { |
|||
boolean created = uploadDirFile.mkdirs(); |
|||
if (created) { |
|||
logger.info("Created upload directory at: {}", uploadDirFile.getAbsolutePath()); |
|||
} else { |
|||
logger.error("Failed to create upload directory at: {}", uploadDirFile.getAbsolutePath()); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
logger.error("Exception in ProductImagePropertiesConfiguration.init(): {}", e.getMessage(), e); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void addResourceHandlers(ResourceHandlerRegistry registry) { |
|||
String fullPath = uploadDirFile.toURI().toString(); |
|||
registry.addResourceHandler("uploads/file-data/**").addResourceLocations(fullPath); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,100 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import java.io.File; |
|||
import java.io.FileWriter; |
|||
import java.io.IOException; |
|||
import java.io.PrintWriter; |
|||
import java.time.LocalDateTime; |
|||
import java.time.format.DateTimeFormatter; |
|||
|
|||
import org.springframework.boot.context.event.ApplicationStartingEvent; |
|||
import org.springframework.boot.system.ApplicationHome; |
|||
import org.springframework.context.ApplicationListener; |
|||
import org.springframework.util.ClassUtils; |
|||
|
|||
public class LogFolderInitializer implements ApplicationListener<ApplicationStartingEvent> { |
|||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
|||
|
|||
@Override |
|||
public void onApplicationEvent(ApplicationStartingEvent event) { |
|||
File logFile = null; |
|||
try { |
|||
// Determine safe base folder |
|||
File baseDir = determineBaseFolder(); |
|||
|
|||
// Create logs folder |
|||
File logsDir = new File(baseDir, "logs"); |
|||
if (!logsDir.exists() && !logsDir.mkdirs()) { |
|||
writeError(logsDir, "Failed to create logs folder at: " + logsDir.getAbsolutePath(), null); |
|||
} |
|||
|
|||
// Create initial log file |
|||
logFile = new File(logsDir, "app-logs.txt"); |
|||
if (!logFile.exists()) { |
|||
logFile.createNewFile(); |
|||
} |
|||
|
|||
// Log pre-start messages |
|||
writeInfo(logFile, "Created log file at: " + logFile.getAbsolutePath()); |
|||
writeInfo(logFile, "LOG_ROOT set to: " + logsDir.getAbsolutePath()); |
|||
|
|||
// Set system property for logback-spring.xml |
|||
System.setProperty("LOG_ROOT", logsDir.getAbsolutePath()); |
|||
|
|||
} catch (IOException ioe) { |
|||
writeError(logFile, "Failed to create logs folder/file", ioe); |
|||
} |
|||
} |
|||
|
|||
/** Determine a safe base folder for logs/uploads */ |
|||
private File determineBaseFolder() { |
|||
try { |
|||
boolean devtoolsActive = ClassUtils.isPresent("org.springframework.boot.devtools.restart.RestartLauncher", |
|||
this.getClass().getClassLoader()); |
|||
|
|||
if (devtoolsActive) { |
|||
// IDE development: use user.dir (project root) to avoid DevTools restart loop |
|||
return new File(System.getProperty("user.dir")); |
|||
} else { |
|||
// JAR deployment: use folder containing the JAR |
|||
ApplicationHome home = new ApplicationHome(LogFolderInitializer.class); |
|||
return home.getDir(); |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
// Last resort: use temp directory |
|||
File tmpDir = new File(System.getProperty("java.io.tmpdir")); |
|||
tmpDir.mkdirs(); |
|||
return tmpDir; |
|||
} |
|||
} |
|||
|
|||
private void writeInfo(File logFile, String message) { |
|||
String timestamp = LocalDateTime.now().format(formatter); |
|||
if (logFile != null) { |
|||
try (PrintWriter pw = new PrintWriter(new FileWriter(logFile, true))) { |
|||
pw.println(timestamp + " INFO " + message); |
|||
} catch (IOException e) { |
|||
System.err.println(timestamp + " ERROR Failed to write INFO to log file: " + e.getMessage()); |
|||
} |
|||
} |
|||
System.out.println(timestamp + " INFO " + message); |
|||
} |
|||
|
|||
private void writeError(File logFile, String message, Throwable t) { |
|||
String timestamp = LocalDateTime.now().format(formatter); |
|||
if (logFile != null) { |
|||
try (PrintWriter pw = new PrintWriter(new FileWriter(logFile, true))) { |
|||
pw.println(timestamp + " ERROR " + message); |
|||
if (t != null) |
|||
t.printStackTrace(pw); |
|||
} catch (IOException e) { |
|||
System.err.println(timestamp + " ERROR Failed to write ERROR to log file: " + e.getMessage()); |
|||
} |
|||
} |
|||
System.err.println(timestamp + " ERROR " + message); |
|||
if (t != null) |
|||
t.printStackTrace(System.err); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.boot.context.event.ApplicationReadyEvent; |
|||
import org.springframework.context.ApplicationListener; |
|||
|
|||
public class LogReadyInitializer implements ApplicationListener<ApplicationReadyEvent> { |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(LogReadyInitializer.class); |
|||
|
|||
@Override |
|||
public void onApplicationEvent(ApplicationReadyEvent event) { |
|||
// TODO Auto-generated method stub |
|||
logger.info("Log folder and initial log file are ready at: {}", System.getProperty("LOG_ROOT")); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
package com.adjustment_file_management_system.springboot.configuration; |
|||
|
|||
import static org.springframework.security.config.Customizer.withDefaults; |
|||
|
|||
import java.util.List; |
|||
|
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.security.authentication.AuthenticationManager; |
|||
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.web.AuthenticationEntryPoint; |
|||
import org.springframework.security.web.SecurityFilterChain; |
|||
import org.springframework.security.web.access.AccessDeniedHandler; |
|||
import org.springframework.security.web.csrf.CookieCsrfTokenRepository; |
|||
|
|||
@Configuration |
|||
@EnableWebSecurity |
|||
public class SecurityConfiguration { |
|||
|
|||
private final CustomAuthenticationProvider custAuthProvider; |
|||
|
|||
public SecurityConfiguration(CustomAuthenticationProvider custAuthenProvider) { |
|||
this.custAuthProvider = custAuthenProvider; |
|||
} |
|||
|
|||
@Value("${app.security.force-https}") |
|||
private boolean isForceHttps; |
|||
|
|||
// List of all admin-only endpoints |
|||
private final List<String> adminEndpoints = List.of("/home", "/redirect", "/file/upd-adjust", "/file/add-file", |
|||
"/file/upd-ejv-num", "/file/upd-file", "/file/view-file"); |
|||
|
|||
// --- AUTHENTICATION MANAGER (NO DEPRECATION) --- |
|||
@Bean |
|||
AuthenticationManager authManager(HttpSecurity http) throws Exception { |
|||
return http.getSharedObject(AuthenticationManagerBuilder.class).authenticationProvider(custAuthProvider) |
|||
.build(); |
|||
} |
|||
|
|||
// Return 404 for unauthenticated requests to admin endpoints |
|||
private final AuthenticationEntryPoint notFoundEntryPoint = (req, res, authException) -> { |
|||
if (adminEndpoints.contains(req.getRequestURI())) { |
|||
res.sendError(404); // hide existence |
|||
} else { |
|||
res.sendRedirect("/"); // fallback for login for other endpoints |
|||
} |
|||
}; |
|||
|
|||
// Return 404 for access denied on admin endpoints |
|||
private final AccessDeniedHandler adminNotFoundAccessDeniedHandler = (req, res, accessDeniedException) -> { |
|||
if (adminEndpoints.contains(req.getRequestURI())) { |
|||
res.sendError(404); // hide existence |
|||
} else { |
|||
res.sendRedirect("/"); // fallback for login for other endpoints |
|||
} |
|||
}; |
|||
|
|||
// disable default login form |
|||
@Bean |
|||
SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
|||
// CSRF with Cookie repository for forms + AJAX |
|||
http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())); |
|||
|
|||
// Force HTTPS if enabled |
|||
if (isForceHttps) { |
|||
http.redirectToHttps(withDefaults()); |
|||
} |
|||
|
|||
// Admin-only endpoints and general authorization |
|||
http.authorizeHttpRequests( |
|||
auth -> auth |
|||
.requestMatchers("/home", "/redirect", "/file/upd-adjust", "/file/add-file", |
|||
"/file/upd-ejv-num", "/file/upd-file", "/file/view-file") |
|||
.hasRole("ADMIN").anyRequest().permitAll()); |
|||
|
|||
// Custom access handlers |
|||
http.exceptionHandling(exceptionHandler -> exceptionHandler.authenticationEntryPoint(notFoundEntryPoint) |
|||
.accessDeniedHandler(adminNotFoundAccessDeniedHandler)); |
|||
|
|||
// Custom login and logout |
|||
http.formLogin(form -> form.loginPage("/").failureUrl("/").permitAll()) |
|||
.logout(logout -> logout.logoutUrl("/usr-logout").logoutSuccessUrl("/").invalidateHttpSession(true) |
|||
.clearAuthentication(true).permitAll()); |
|||
|
|||
return http.build(); |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
package com.adjustment_file_management_system.springboot.controller; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.ui.Model; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
|
|||
import com.adjustment_file_management_system.springboot.response_dto.FileDataResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.FundTypeResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.service.FileDataService; |
|||
|
|||
@Controller |
|||
@RequestMapping("/file") |
|||
public class FileDataController { |
|||
|
|||
@Autowired |
|||
private FileDataService fileDataSer; |
|||
|
|||
@GetMapping("/view-file-det") |
|||
public String viewFileDetails(Model model, @RequestParam("file-num") String fileNum) { |
|||
FileDataResponseDTO fileDataResDTO = fileDataSer.getFileDataByFileNum(fileNum); |
|||
model.addAttribute("fileDatum", fileDataResDTO); |
|||
model.addAttribute("curPage", "view-file-det"); |
|||
return "file/view-file-detail"; |
|||
} |
|||
|
|||
@GetMapping("/add-file") |
|||
public String addFile(Model model) { |
|||
List<FundTypeResponseDTO> fundTypeResDTOs = fileDataSer.getAllFundTypes(); |
|||
model.addAttribute("fundTypes", fundTypeResDTOs); |
|||
model.addAttribute("curPage", "add-file"); |
|||
return "file/add-file"; |
|||
} |
|||
|
|||
@GetMapping("/upd-ejv-num") |
|||
public String updEjvNum(Model model) { |
|||
List<Map<String, Object>> fileDatum = fileDataSer.getAllFileData().stream().map(fileData -> { |
|||
Map<String, Object> fileDataMapObj = new HashMap<String, Object>(); |
|||
fileDataMapObj.put("fileNum", fileData.getFileDataNum()); |
|||
boolean asFinalFileStat = (fileData.getAsFinalFilePath() != null |
|||
&& !fileData.getAsFinalFilePath().trim().equalsIgnoreCase("-")); |
|||
boolean ejvNumFileStat = (fileData.getEjvNumFilePath() != null |
|||
&& !fileData.getEjvNumFilePath().trim().equalsIgnoreCase("-")); |
|||
boolean ejvNumStat = (!fileData.getEjvNum().trim().isEmpty() |
|||
&& !fileData.getEjvNum().trim().equalsIgnoreCase("-")); |
|||
fileDataMapObj.put("asFinalFileStat", asFinalFileStat); |
|||
fileDataMapObj.put("ejvNumFileStat", ejvNumFileStat); |
|||
fileDataMapObj.put("ejvNumStat", ejvNumStat); |
|||
fileDataMapObj.put("ejvNum", fileData.getEjvNum()); |
|||
fileDataMapObj.put("ejvNumFile", fileData.getEjvNumFilePath()); |
|||
return fileDataMapObj; |
|||
}).toList(); |
|||
model.addAttribute("curPage", "upd-ejv-num"); |
|||
model.addAttribute("fileDatum", fileDatum); |
|||
return "file/update-ejv-number"; |
|||
} |
|||
|
|||
@GetMapping("/upd-file") |
|||
public String updFile(Model model) { |
|||
List<FileDataResponseDTO> fileDataResDTOs = fileDataSer.getAllFileData(); |
|||
List<FundTypeResponseDTO> fundTypeResDTOs = fileDataSer.getAllFundTypes(); |
|||
model.addAttribute("fundTypes", fundTypeResDTOs); |
|||
model.addAttribute("fileDatum", fileDataResDTOs); |
|||
model.addAttribute("curPage", "upd-file"); |
|||
return "file/update-file"; |
|||
} |
|||
|
|||
@GetMapping("/view-file") |
|||
public String viewFile(Model model) { |
|||
List<FileDataResponseDTO> fileDataResDTOs = fileDataSer.getAllFileData(); |
|||
model.addAttribute("fileDatum", fileDataResDTOs); |
|||
model.addAttribute("curPage", "view-file"); |
|||
return "file/view-file"; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
package com.adjustment_file_management_system.springboot.controller; |
|||
|
|||
import java.util.Map; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.ui.Model; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
|
|||
import com.adjustment_file_management_system.springboot.service.HomeService; |
|||
|
|||
@Controller |
|||
@RequestMapping("/") |
|||
public class HomeController { |
|||
|
|||
@Autowired |
|||
private HomeService homeSer; |
|||
|
|||
@GetMapping("/home") |
|||
public String homePage(Model model) { |
|||
Map<String, Long> stats = homeSer.getFileDataStat(); |
|||
model.addAttribute("curPage", "home"); |
|||
model.addAttribute("stats", stats); |
|||
return "home/home"; |
|||
} |
|||
|
|||
@GetMapping("/redirect") |
|||
public String usrRedirect(@RequestParam("usr-role") String usrRole) { |
|||
|
|||
return switch (usrRole) { |
|||
case "ROLE_ADMIN" -> "redirect:/home"; |
|||
default -> "redirect:/"; // fallback to login page |
|||
}; |
|||
|
|||
} |
|||
|
|||
@GetMapping("/") |
|||
public String loginPage() { |
|||
return "home/login"; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package com.adjustment_file_management_system.springboot.mapper; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AdvanceType; |
|||
import com.adjustment_file_management_system.springboot.request_dto.AdvanceTypeRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.AdvanceTypeResponseDTO; |
|||
|
|||
@Component |
|||
public class AdvanceTypeMapper { |
|||
|
|||
public AdvanceTypeResponseDTO toAdvTypeResDTO(AdvanceType advType) { |
|||
return new AdvanceTypeResponseDTO(advType.getAdvTypeId(), advType.getAdvType()); |
|||
} |
|||
|
|||
public AdvanceType toAdvTypeEnt(AdvanceTypeRequestDTO advTypeReqDTO) { |
|||
AdvanceType advType = new AdvanceType(); |
|||
advType.setAdvType(advTypeReqDTO.getAdvType()); |
|||
return advType; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
package com.adjustment_file_management_system.springboot.mapper; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AppUser; |
|||
import com.adjustment_file_management_system.springboot.response_dto.AppUserResponseDTO; |
|||
|
|||
@Component |
|||
public class AppUserMapper { |
|||
@Autowired |
|||
private UserRoleMapper usrRoleMap; |
|||
|
|||
public AppUserResponseDTO toUsrResDTO(AppUser usr) { |
|||
return new AppUserResponseDTO(usr.getUsrId(), usr.getUsrName(), usrRoleMap.toUsrRoleResDTO(usr.getUsrRole()), |
|||
usr.getUsrPass()); |
|||
} |
|||
} |
|||
@ -0,0 +1,127 @@ |
|||
package com.adjustment_file_management_system.springboot.mapper; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.FileData; |
|||
import com.adjustment_file_management_system.springboot.repository.AdvanceTypeRepository; |
|||
import com.adjustment_file_management_system.springboot.repository.FundTypeRepository; |
|||
import com.adjustment_file_management_system.springboot.request_dto.FileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.FileDataResponseDTO; |
|||
|
|||
@Component |
|||
public class FileDataMapper { |
|||
|
|||
@Autowired |
|||
private AdvanceTypeRepository advTypeRepo; |
|||
|
|||
@Autowired |
|||
private FundTypeRepository fundTypeRepo; |
|||
|
|||
@Autowired |
|||
private FundTypeMapper fundTypeMap; |
|||
|
|||
@Autowired |
|||
private AdvanceTypeMapper advTypeMap; |
|||
|
|||
public FileData toFileDataEnt(FileDataResponseDTO fileDataResDTO) { |
|||
FileData fileData = new FileData(); |
|||
fileData.setAdvType(advTypeRepo.findById(fileDataResDTO.getAdvTypeResDTO().getAdvTypeId()).get()); |
|||
fileData.setAsFileGenDate(fileDataResDTO.getAsFileGenDate()); |
|||
fileData.setAsFilePath(fileDataResDTO.getAsFilePath()); |
|||
fileData.setAsFinalFileGenDate(fileDataResDTO.getAsFinalFileGenDate()); |
|||
fileData.setAsFinalFilePath(fileDataResDTO.getAsFinalFilePath()); |
|||
fileData.setBalAmt(fileDataResDTO.getBalAmt()); |
|||
fileData.setDcFilePath(fileDataResDTO.getDcFilePath()); |
|||
fileData.setEjvNum(fileDataResDTO.getEjvNum()); |
|||
fileData.setEjvNumFileGenDate(fileDataResDTO.getEjvNumFileGenDate()); |
|||
fileData.setEjvNumFilePath(fileDataResDTO.getEjvNumFilePath()); |
|||
fileData.setFiAmt(fileDataResDTO.getFiAmt()); |
|||
fileData.setFiFileGenDate(fileDataResDTO.getFiFileGenDate()); |
|||
fileData.setFiFilePath(fileDataResDTO.getFiFilePath()); |
|||
fileData.setFileRmrk(fileDataResDTO.getFileRmrk()); |
|||
fileData.setFileDataNum(fileDataResDTO.getFileDataNum()); |
|||
fileData.setFileDataId(fileDataResDTO.getFileDataId()); |
|||
fileData.setFinYear(fileDataResDTO.getFinYear()); |
|||
fileData.setFundType(fundTypeRepo.findById(fileDataResDTO.getFundTypeResDTO().getFundTypeId()).get()); |
|||
fileData.setIrFilePath(fileDataResDTO.getIrFilePath()); |
|||
fileData.setPiAmt(fileDataResDTO.getPiAmt()); |
|||
fileData.setPiFileGenDate(fileDataResDTO.getPiFileGenDate()); |
|||
fileData.setPiFilePath(fileDataResDTO.getPiFilePath()); |
|||
fileData.setPoFilePath(fileDataResDTO.getPoFilePath()); |
|||
fileData.setRtgsFilePath(fileDataResDTO.getRtgsFilePath()); |
|||
fileData.setSrFilePath(fileDataResDTO.getSrFilePath()); |
|||
fileData.setTcFileGenDate(fileDataResDTO.getTcFileGenDate()); |
|||
fileData.setTcFilePath(fileDataResDTO.getTcFilePath()); |
|||
fileData.setVendName(fileDataResDTO.getVendName()); |
|||
return fileData; |
|||
} |
|||
|
|||
public FileData toFileDataEnt(FileDataRequestDTO fileDataReqDTO) { |
|||
FileData fileData = new FileData(); |
|||
fileData.setAdvType(advTypeRepo.findById(fileDataReqDTO.getAdvTypeId()).get()); |
|||
fileData.setAsFileGenDate(fileDataReqDTO.getAsFileGenDate()); |
|||
fileData.setAsFilePath(fileDataReqDTO.getAsFilePath()); |
|||
fileData.setAsFinalFileGenDate(fileDataReqDTO.getAsFinalFileGenDate()); |
|||
fileData.setAsFinalFilePath(fileDataReqDTO.getAsFinalFilePath()); |
|||
fileData.setBalAmt(fileDataReqDTO.getBalAmt()); |
|||
fileData.setDcFilePath(fileDataReqDTO.getDcFilePath()); |
|||
fileData.setEjvNum(fileDataReqDTO.getEjvNum()); |
|||
fileData.setEjvNumFilePath(fileDataReqDTO.getEjvNumFilePath()); |
|||
fileData.setFiAmt(fileDataReqDTO.getFiAmt()); |
|||
fileData.setFiFileGenDate(fileDataReqDTO.getFiFileGenDate()); |
|||
fileData.setFiFilePath(fileDataReqDTO.getFiFilePath()); |
|||
fileData.setFileDataNum(fileDataReqDTO.getFileDataNum()); |
|||
fileData.setFileRmrk(fileDataReqDTO.getFileRmrk()); |
|||
fileData.setFinYear(fileDataReqDTO.getFinYear()); |
|||
fileData.setFundType(fundTypeRepo.findById(fileDataReqDTO.getFundTypeId()).get()); |
|||
fileData.setIrFilePath(fileDataReqDTO.getIrFilePath()); |
|||
fileData.setPiAmt(fileDataReqDTO.getPiAmt()); |
|||
fileData.setPiFileGenDate(fileDataReqDTO.getPiFileGenDate()); |
|||
fileData.setPiFilePath(fileDataReqDTO.getPiFilePath()); |
|||
fileData.setPoFilePath(fileDataReqDTO.getPoFilePath()); |
|||
fileData.setRtgsFilePath(fileDataReqDTO.getRtgsFilePath()); |
|||
fileData.setSrFilePath(fileDataReqDTO.getSrFilePath()); |
|||
fileData.setTcFileGenDate(fileDataReqDTO.getTcFileGenDate()); |
|||
fileData.setTcFilePath(fileDataReqDTO.getTcFilePath()); |
|||
fileData.setVendName(fileDataReqDTO.getVendName()); |
|||
fileData.setEjvNumFileGenDate(fileDataReqDTO.getEjvNumFileGenDate()); |
|||
return fileData; |
|||
} |
|||
|
|||
public FileDataResponseDTO toFileDataResDTO(FileData fileData) { |
|||
FileDataResponseDTO fileDataResDTO = new FileDataResponseDTO(); |
|||
fileDataResDTO.setAsFileGenDate(fileData.getAsFileGenDate()); |
|||
fileDataResDTO.setAdvTypeResDTO( |
|||
advTypeMap.toAdvTypeResDTO(advTypeRepo.findById(fileData.getAdvType().getAdvTypeId()).get())); |
|||
fileDataResDTO.setAsFilePath(fileData.getAsFilePath()); |
|||
fileDataResDTO.setAsFinalFileGenDate(fileData.getAsFinalFileGenDate()); |
|||
fileDataResDTO.setAsFinalFilePath(fileData.getAsFinalFilePath()); |
|||
fileDataResDTO.setBalAmt(fileData.getBalAmt()); |
|||
fileDataResDTO.setDcFilePath(fileData.getDcFilePath()); |
|||
fileDataResDTO.setEjvNum(fileData.getEjvNum()); |
|||
fileDataResDTO.setEjvNumFilePath(fileData.getEjvNumFilePath()); |
|||
fileDataResDTO.setFiAmt(fileData.getFiAmt()); |
|||
fileDataResDTO.setFiFileGenDate(fileData.getFiFileGenDate()); |
|||
fileDataResDTO.setFiFilePath(fileData.getFiFilePath()); |
|||
fileDataResDTO.setFileDataId(fileData.getFileDataId()); |
|||
fileDataResDTO.setFileDataNum(fileData.getFileDataNum()); |
|||
fileDataResDTO.setFileRmrk(fileData.getFileRmrk()); |
|||
fileDataResDTO.setFinYear(fileData.getFinYear()); |
|||
fileDataResDTO.setFundTypeResDTO( |
|||
fundTypeMap.toFundTypeResDTO(fundTypeRepo.findById(fileData.getFundType().getFundTypeId()).get())); |
|||
fileDataResDTO.setIrFilePath(fileData.getIrFilePath()); |
|||
fileDataResDTO.setPiAmt(fileData.getPiAmt()); |
|||
fileDataResDTO.setPiFileGenDate(fileData.getPiFileGenDate()); |
|||
fileDataResDTO.setPiFilePath(fileData.getPiFilePath()); |
|||
fileDataResDTO.setPoFilePath(fileData.getPoFilePath()); |
|||
fileDataResDTO.setRtgsFilePath(fileData.getRtgsFilePath()); |
|||
fileDataResDTO.setSrFilePath(fileData.getSrFilePath()); |
|||
fileDataResDTO.setTcFileGenDate(fileData.getTcFileGenDate()); |
|||
fileDataResDTO.setTcFilePath(fileData.getTcFilePath()); |
|||
fileDataResDTO.setVendName(fileData.getVendName()); |
|||
fileDataResDTO.setEjvNumFileGenDate(fileData.getEjvNumFileGenDate()); |
|||
return fileDataResDTO; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.adjustment_file_management_system.springboot.mapper; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.FundType; |
|||
import com.adjustment_file_management_system.springboot.response_dto.FundTypeResponseDTO; |
|||
|
|||
@Component |
|||
public class FundTypeMapper { |
|||
|
|||
public FundTypeResponseDTO toFundTypeResDTO(FundType fundType) { |
|||
return new FundTypeResponseDTO(fundType.getFundTypeId(), fundType.getFundType()); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
package com.adjustment_file_management_system.springboot.mapper; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.UserRole; |
|||
import com.adjustment_file_management_system.springboot.response_dto.UserRoleResponseDTO; |
|||
|
|||
@Component |
|||
public class UserRoleMapper { |
|||
public UserRoleResponseDTO toUsrRoleResDTO(UserRole usrRole) { |
|||
return new UserRoleResponseDTO(usrRole.getUsrRoleId(), usrRole.getUsrRoleName()); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
package com.adjustment_file_management_system.springboot.model; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.GeneratedValue; |
|||
import jakarta.persistence.GenerationType; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.SequenceGenerator; |
|||
import jakarta.persistence.Table; |
|||
import jakarta.validation.constraints.NotBlank; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Entity |
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
//For local DB Server |
|||
/* @Table(name = "tbl_adv_type_det", schema = "GCC") */ |
|||
//For Production DB Server |
|||
@Table(name = "tbl_adv_type_det", schema = "fileadjust") |
|||
public class AdvanceType { |
|||
|
|||
@Id |
|||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "adv_type_seq") |
|||
/* |
|||
* @SequenceGenerator(name = "adv_type_seq", sequenceName = "adv_type_id_seq", |
|||
* allocationSize = 1, schema = "GCC") |
|||
*/ |
|||
@SequenceGenerator(name = "adv_type_seq", sequenceName = "adv_type_id_seq", allocationSize = 1, schema = "fileadjust") |
|||
@Column(name = "adv_type_id", nullable = false, updatable = false) |
|||
private Long advTypeId; |
|||
|
|||
@Column(name = "adv_type", nullable = false) |
|||
@NotBlank |
|||
private String advType; |
|||
|
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
package com.adjustment_file_management_system.springboot.model; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonBackReference; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.GeneratedValue; |
|||
import jakarta.persistence.GenerationType; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.JoinColumn; |
|||
import jakarta.persistence.ManyToOne; |
|||
import jakarta.persistence.SequenceGenerator; |
|||
import jakarta.persistence.Table; |
|||
import jakarta.validation.constraints.NotBlank; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Entity |
|||
@Table(name = "tbl_app_usr_det", schema = "fileadjust") |
|||
/* @Table(name = "tbl_app_usr_det", schema = "gcc") */ |
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true, exclude = { "usrRole", "usrPass" }) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class AppUser { |
|||
@Id |
|||
@Column(name = "usr_id", nullable = false, updatable = false) |
|||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_usr_seq") |
|||
/* |
|||
* @SequenceGenerator(name = "app_usr_seq", sequenceName = "usr_id_seq", |
|||
* allocationSize = 1, schema = "GCC") |
|||
*/ |
|||
@SequenceGenerator(name = "app_usr_seq", sequenceName = "app_usr_id_seq", allocationSize = 1, schema = "fileadjust") |
|||
private Integer usrId; |
|||
|
|||
@Column(name = "usr_name", nullable = false) |
|||
@NotBlank |
|||
private String usrName; |
|||
|
|||
@Column(name = "usr_pass", nullable = false) |
|||
@NotBlank |
|||
private String usrPass; |
|||
|
|||
@ManyToOne |
|||
@JoinColumn(name = "usr_role_id", nullable = false, referencedColumnName = "usr_role_id") |
|||
@JsonBackReference |
|||
private UserRole usrRole; |
|||
} |
|||
@ -0,0 +1,213 @@ |
|||
package com.adjustment_file_management_system.springboot.model; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import org.springframework.data.annotation.CreatedBy; |
|||
import org.springframework.data.annotation.CreatedDate; |
|||
import org.springframework.data.annotation.LastModifiedBy; |
|||
import org.springframework.data.annotation.LastModifiedDate; |
|||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.EntityListeners; |
|||
import jakarta.persistence.FetchType; |
|||
import jakarta.persistence.GeneratedValue; |
|||
import jakarta.persistence.GenerationType; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.JoinColumn; |
|||
import jakarta.persistence.ManyToOne; |
|||
import jakarta.persistence.PrePersist; |
|||
import jakarta.persistence.PreUpdate; |
|||
import jakarta.persistence.SequenceGenerator; |
|||
import jakarta.persistence.Table; |
|||
import jakarta.persistence.Temporal; |
|||
import jakarta.persistence.TemporalType; |
|||
import jakarta.validation.constraints.NotBlank; |
|||
import jakarta.validation.constraints.NotNull; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Entity |
|||
@EntityListeners(AuditingEntityListener.class) |
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true, exclude = { "advType", "fundType", "createdBy", |
|||
"updatedBy" }) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
// For local DB Server |
|||
/* @Table(name = "tbl_file_data_det", schema = "GCC") */ |
|||
// For Production DB Server |
|||
@Table(name = "tbl_file_data_det", schema = "fileadjust") |
|||
public class FileData { |
|||
|
|||
@Id |
|||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "file_data_seq") |
|||
/* |
|||
* @SequenceGenerator(name = "file_data_seq", sequenceName = "file_data_id_seq", |
|||
* allocationSize = 1, schema = "GCC") |
|||
*/ |
|||
@SequenceGenerator(name = "file_data_seq", sequenceName = "file_data_id_seq", allocationSize = 1, schema = "fileadjust") |
|||
@Column(name = "file_data_id", nullable = false, updatable = false) |
|||
private Long fileDataId; |
|||
|
|||
@Column(name = "file_data_num", nullable = false, unique = true) |
|||
@NotBlank |
|||
private String fileDataNum; |
|||
|
|||
@Column(name = "fin_year", nullable = false) |
|||
@NotBlank |
|||
private String finYear; |
|||
|
|||
@Column(name = "as_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String asFilePath; |
|||
|
|||
@Column(name = "as_file_gen_date", nullable = false) |
|||
@Temporal(TemporalType.DATE) |
|||
@NotNull |
|||
private Date asFileGenDate; |
|||
|
|||
@Column(name = "pi_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String piFilePath; |
|||
|
|||
@Column(name = "pi_file_gen_date", nullable = false) |
|||
@Temporal(TemporalType.DATE) |
|||
@NotNull |
|||
private Date piFileGenDate; |
|||
|
|||
@Column(name = "pi_amt", nullable = false) |
|||
@NotNull |
|||
private Double piAmt; |
|||
|
|||
@Column(name = "fi_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String fiFilePath; |
|||
|
|||
@Column(name = "fi_amt", nullable = false) |
|||
@NotNull |
|||
private Double fiAmt; |
|||
|
|||
@Column(name = "fi_file_gen_date", nullable = false) |
|||
@Temporal(TemporalType.DATE) |
|||
@NotNull |
|||
private Date fiFileGenDate; |
|||
|
|||
@Column(name = "bal_amt", nullable = false) |
|||
@NotNull |
|||
private Double balAmt; |
|||
|
|||
@Column(name = "rtgs_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String rtgsFilePath; |
|||
|
|||
@Column(name = "po_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String poFilePath; |
|||
|
|||
@Column(name = "dc_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String dcFilePath; |
|||
|
|||
@Column(name = "sr_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String srFilePath; |
|||
|
|||
@Column(name = "ir_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String irFilePath; |
|||
|
|||
@Column(name = "as_final_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String asFinalFilePath; |
|||
|
|||
@Column(name = "as_final_file_gen_date", nullable = false) |
|||
@Temporal(TemporalType.DATE) |
|||
@NotNull |
|||
private Date asFinalFileGenDate; |
|||
|
|||
@Column(name = "ejv_num", nullable = false) |
|||
@NotBlank |
|||
private String ejvNum; |
|||
|
|||
@Column(name = "ejv_num_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String ejvNumFilePath; |
|||
|
|||
@Column(name = "ejv_num_file_gen_date", nullable = false) |
|||
@NotNull |
|||
@Temporal(TemporalType.DATE) |
|||
private Date ejvNumFileGenDate; |
|||
|
|||
@Column(name = "tc_file_path", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String tcFilePath; |
|||
|
|||
@Column(name = "tc_file_gen_date", nullable = false) |
|||
@Temporal(TemporalType.DATE) |
|||
@NotNull |
|||
private Date tcFileGenDate; |
|||
|
|||
@Column(name = "file_rmrk", nullable = false, length = 1000) |
|||
@NotBlank |
|||
private String fileRmrk; |
|||
|
|||
@ManyToOne(fetch = FetchType.LAZY) |
|||
@JoinColumn(name = "adv_type_id", referencedColumnName = "adv_type_id", nullable = false) |
|||
private AdvanceType advType; |
|||
|
|||
@ManyToOne(fetch = FetchType.LAZY) |
|||
@JoinColumn(name = "fund_type_id", referencedColumnName = "fund_type_id", nullable = false) |
|||
private FundType fundType; |
|||
|
|||
@Column(name = "vend_name", nullable = false) |
|||
@NotBlank |
|||
private String vendName; |
|||
|
|||
@CreatedBy |
|||
@ManyToOne(fetch = FetchType.LAZY) |
|||
@JoinColumn(name = "created_by_usr_id", referencedColumnName = "usr_id", updatable = false, nullable = false) |
|||
private AppUser createdBy; |
|||
|
|||
@LastModifiedBy |
|||
@ManyToOne(fetch = FetchType.LAZY) |
|||
@JoinColumn(name = "updated_by_usr_id", referencedColumnName = "usr_id", nullable = false) |
|||
private AppUser updatedBy; |
|||
|
|||
// User timestamp |
|||
@Temporal(TemporalType.TIMESTAMP) |
|||
@Column(name = "usr_created_timestamp", nullable = false, updatable = false) |
|||
private Date usrCreatedTimestamp; |
|||
|
|||
@Temporal(TemporalType.TIMESTAMP) |
|||
@Column(name = "usr_updated_timestamp", nullable = false) |
|||
private Date usrUpdatedTimestamp; |
|||
|
|||
// DB-managed timestamps |
|||
@CreatedDate |
|||
@Temporal(TemporalType.TIMESTAMP) |
|||
@Column(updatable = false, nullable = false, name = "db_created_timestamp") |
|||
private Date dbCreatedTimestamp; |
|||
|
|||
@LastModifiedDate |
|||
@Temporal(TemporalType.TIMESTAMP) |
|||
@Column(nullable = false, name = "db_updated_timestamp") |
|||
private Date dbUpdatedTimestamp; |
|||
|
|||
@PrePersist |
|||
public void onCreate() { |
|||
this.usrCreatedTimestamp = new Date(); |
|||
this.usrUpdatedTimestamp = new Date(); |
|||
} |
|||
|
|||
@PreUpdate |
|||
public void onUpdate() { |
|||
this.usrUpdatedTimestamp = new Date(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
package com.adjustment_file_management_system.springboot.model; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.GeneratedValue; |
|||
import jakarta.persistence.GenerationType; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.SequenceGenerator; |
|||
import jakarta.persistence.Table; |
|||
import jakarta.validation.constraints.NotBlank; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Entity |
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
//For local DB Server |
|||
/* @Table(name = "tbl_fund_type_det", schema = "GCC") */ |
|||
//For Production DB Server |
|||
@Table(name = "tbl_fund_type_det", schema = "fileadjust") |
|||
public class FundType { |
|||
|
|||
@Id |
|||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fund_type_seq") |
|||
/* |
|||
* @SequenceGenerator(name = "fund_type_seq", sequenceName = "fund_type_id_seq", |
|||
* allocationSize = 1, schema = "GCC") |
|||
*/ |
|||
@SequenceGenerator(name = "fund_type_seq", sequenceName = "fund_type_id_seq", allocationSize = 1, schema = "fileadjust") |
|||
@Column(name = "fund_type_id", nullable = false, updatable = false) |
|||
private Long fundTypeId; |
|||
|
|||
@Column(name = "fund_type", nullable = false) |
|||
@NotBlank |
|||
private String fundType; |
|||
|
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
package com.adjustment_file_management_system.springboot.model; |
|||
|
|||
import java.util.List; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonManagedReference; |
|||
|
|||
import jakarta.persistence.CascadeType; |
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.FetchType; |
|||
import jakarta.persistence.GeneratedValue; |
|||
import jakarta.persistence.GenerationType; |
|||
import jakarta.persistence.Id; |
|||
import jakarta.persistence.OneToMany; |
|||
import jakarta.persistence.SequenceGenerator; |
|||
import jakarta.persistence.Table; |
|||
import jakarta.validation.constraints.NotBlank; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Entity |
|||
@ToString(includeFieldNames = true, doNotUseGetters = true, exclude = { "appUsrs" }) |
|||
@Getter |
|||
@Setter |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
/* @Table(name = "tbl_usr_role_det", schema = "gcc") */ |
|||
@Table(name = "tbl_usr_role_det", schema = "fileadjust") |
|||
public class UserRole { |
|||
|
|||
@Id |
|||
@Column(name = "usr_role_id", nullable = false, updatable = false) |
|||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usr_role_seq") |
|||
/* |
|||
* @SequenceGenerator(name = "usr_role_seq", sequenceName = "usr_role_id_seq", |
|||
* allocationSize = 1, schema = "GCC") |
|||
*/ |
|||
@SequenceGenerator(name = "usr_role_seq", sequenceName = "usr_role_id_seq", allocationSize = 1, schema = "fileadjust") |
|||
private Integer usrRoleId; |
|||
|
|||
@Column(name = "usr_role_name", nullable = false) |
|||
@NotBlank |
|||
private String usrRoleName; |
|||
|
|||
@OneToMany(mappedBy = "usrRole", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) |
|||
@JsonManagedReference |
|||
private List<AppUser> appUsrs; |
|||
|
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
package com.adjustment_file_management_system.springboot.repository; |
|||
|
|||
import java.util.Optional; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.data.repository.query.Param; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AdvanceType; |
|||
|
|||
@Repository |
|||
public interface AdvanceTypeRepository extends JpaRepository<AdvanceType, Long> { |
|||
|
|||
@Query(nativeQuery = true, value = "SELECT * FROM TBL_ADV_TYPE_DET WHERE ADV_TYPE = :advType") |
|||
Optional<AdvanceType> findAdvTypeByAdvType(@Param("advType") String advType); |
|||
|
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
package com.adjustment_file_management_system.springboot.repository; |
|||
|
|||
import java.util.Optional; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AppUser; |
|||
|
|||
@Repository |
|||
public interface AppUserRepository extends JpaRepository<AppUser, Integer> { |
|||
Optional<AppUser> findByUsrName(String usrName); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.adjustment_file_management_system.springboot.repository; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.FileData; |
|||
|
|||
@Repository |
|||
public interface FileDataRepository extends JpaRepository<FileData, Long> { |
|||
|
|||
@Query(value = "SELECT fd FROM FileData fd WHERE fd.fileDataNum = ?1") |
|||
FileData findFileDataByFileDataNum(String fileDataNum); |
|||
|
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
package com.adjustment_file_management_system.springboot.repository; |
|||
|
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.FundType; |
|||
|
|||
@Repository |
|||
public interface FundTypeRepository extends JpaRepository<FundType, Long> { |
|||
|
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
package com.adjustment_file_management_system.springboot.request_dto; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class AddFileDataRequestDTO { |
|||
|
|||
private String fileNum; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date asFileGenDate; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date piFileGenDate; |
|||
private Double piAmt; |
|||
private String fileRmrk; |
|||
private MultipartFile asFile; |
|||
private MultipartFile piFile; |
|||
private String finYear; |
|||
private String vendName; |
|||
private String advType; |
|||
private Long fundTypeId; |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
package com.adjustment_file_management_system.springboot.request_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class AdvanceTypeRequestDTO { |
|||
|
|||
private String advType; |
|||
|
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
package com.adjustment_file_management_system.springboot.request_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class AppUserRequestDTO { |
|||
private String usrName; |
|||
private String usrPass; |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
package com.adjustment_file_management_system.springboot.request_dto; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class FileDataRequestDTO { |
|||
private String fileDataNum; |
|||
private String asFilePath; |
|||
private Date asFileGenDate; |
|||
private String piFilePath; |
|||
private Date piFileGenDate; |
|||
private Double piAmt; |
|||
private String fiFilePath; |
|||
private Double fiAmt; |
|||
private Date fiFileGenDate; |
|||
private Double balAmt; |
|||
private String rtgsFilePath; |
|||
private String poFilePath; |
|||
private String dcFilePath; |
|||
private String srFilePath; |
|||
private String irFilePath; |
|||
private String asFinalFilePath; |
|||
private Date asFinalFileGenDate; |
|||
private String ejvNum; |
|||
private String ejvNumFilePath; |
|||
private String tcFilePath; |
|||
private Date tcFileGenDate; |
|||
private String fileRmrk; |
|||
private String vendName; |
|||
private String finYear; |
|||
private Long advTypeId; |
|||
private Long fundTypeId; |
|||
private Date ejvNumFileGenDate; |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
package com.adjustment_file_management_system.springboot.request_dto; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class UpdateFileDataRequestDTO { |
|||
|
|||
private String fileNum; |
|||
private String fileRmrk; |
|||
private String advType; |
|||
private Long fundTypeId; |
|||
private String vendName; |
|||
private MultipartFile poFile; |
|||
private MultipartFile dcFile; |
|||
private MultipartFile srFile; |
|||
private MultipartFile irFile; |
|||
private MultipartFile rtgsFile; |
|||
private MultipartFile piFile; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date piFileGenDate; |
|||
private Double piAmt; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date asFileGenDate; |
|||
private MultipartFile asFile; |
|||
private MultipartFile fiFile; |
|||
private Double fiAmt; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date fiFileGenDate; |
|||
private MultipartFile asFinalFile; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date asFinalFileGenDate; |
|||
@DateTimeFormat(pattern = "dd-MM-yyyy") |
|||
private Date tcFileGenDate; |
|||
private MultipartFile tcFile; |
|||
private Double balAmt; |
|||
|
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class AdvanceTypeResponseDTO { |
|||
|
|||
private Long advTypeId; |
|||
private String advType; |
|||
|
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true, exclude = { "usrPass" }) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class AppUserResponseDTO { |
|||
private Integer usrId; |
|||
private String usrName; |
|||
private UserRoleResponseDTO usrRole; |
|||
private String usrPass; |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class FileDataResponseDTO { |
|||
private Long fileDataId; |
|||
private String fileDataNum; |
|||
private String asFilePath; |
|||
private Date asFileGenDate; |
|||
private String piFilePath; |
|||
private Date piFileGenDate; |
|||
private Double piAmt; |
|||
private String fiFilePath; |
|||
private Double fiAmt; |
|||
private Date fiFileGenDate; |
|||
private Double balAmt; |
|||
private String rtgsFilePath; |
|||
private String poFilePath; |
|||
private String dcFilePath; |
|||
private String srFilePath; |
|||
private String irFilePath; |
|||
private String asFinalFilePath; |
|||
private Date asFinalFileGenDate; |
|||
private String ejvNum; |
|||
private String ejvNumFilePath; |
|||
private String tcFilePath; |
|||
private Date tcFileGenDate; |
|||
private String fileRmrk; |
|||
private String vendName; |
|||
private String finYear; |
|||
private AdvanceTypeResponseDTO advTypeResDTO; |
|||
private Date ejvNumFileGenDate; |
|||
private FundTypeResponseDTO fundTypeResDTO; |
|||
private Long daysPass; |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(includeFieldNames = true, doNotUseGetters = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class FundTypeResponseDTO { |
|||
private Long fundTypeId; |
|||
private String fundType; |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class ServiceResponseDTO { |
|||
|
|||
private boolean resStat; |
|||
private String res; |
|||
|
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
package com.adjustment_file_management_system.springboot.response_dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import lombok.ToString; |
|||
|
|||
@Getter |
|||
@Setter |
|||
@ToString(doNotUseGetters = true, includeFieldNames = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class UserRoleResponseDTO { |
|||
private Integer usrRoleId; |
|||
private String usrRoleName; |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
package com.adjustment_file_management_system.springboot.rest_controller; |
|||
|
|||
import java.io.IOException; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.text.SimpleDateFormat; |
|||
import java.util.Date; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.propertyeditors.CustomDateEditor; |
|||
import org.springframework.beans.propertyeditors.CustomNumberEditor; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.bind.WebDataBinder; |
|||
import org.springframework.web.bind.annotation.InitBinder; |
|||
import org.springframework.web.bind.annotation.ModelAttribute; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import com.adjustment_file_management_system.springboot.request_dto.AddFileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.request_dto.UpdateFileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.ServiceResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.service.FileDataService; |
|||
|
|||
@RestController |
|||
@RequestMapping("/api/file") |
|||
public class FileDataRestController { |
|||
|
|||
@Autowired |
|||
private FileDataService fileDataSer; |
|||
|
|||
@InitBinder |
|||
public void initBinder(WebDataBinder binder) { |
|||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); |
|||
sdf.setLenient(false); |
|||
// true = allow empty string to be converted to null |
|||
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true)); |
|||
binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true)); |
|||
} |
|||
|
|||
@PostMapping("/view-supp-docs") |
|||
public ResponseEntity<byte[]> viewSuppDocs(@RequestParam("file-type") String fileType, |
|||
@RequestParam("file-path") String filePath, @RequestParam("file-num") String fileNum) { |
|||
try { |
|||
byte[] fileData = fileDataSer.getFileBytes(fileType, filePath, fileNum); |
|||
String fileName = fileDataSer.getFileName(filePath); |
|||
return ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF) |
|||
.header("Content-Disposition", "inline; filename=\"" + fileName + "\"").body(fileData); |
|||
} catch (IllegalArgumentException iae) { |
|||
return ResponseEntity.badRequest().body(iae.getMessage().getBytes(StandardCharsets.UTF_8)); |
|||
} catch (IOException ioe) { |
|||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ioe.getMessage().getBytes(StandardCharsets.UTF_8)); |
|||
} catch (Exception e) { |
|||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) |
|||
.body(e.getMessage().getBytes(StandardCharsets.UTF_8)); |
|||
} |
|||
} |
|||
|
|||
@PostMapping("/add-file") |
|||
public ResponseEntity<ServiceResponseDTO> addFile(@ModelAttribute AddFileDataRequestDTO addFileDataReqDTO) { |
|||
ServiceResponseDTO serResDTO = fileDataSer.addFileData(addFileDataReqDTO); |
|||
if (serResDTO.isResStat()) { |
|||
return ResponseEntity.ok(serResDTO); |
|||
} else { |
|||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(serResDTO); |
|||
} |
|||
} |
|||
|
|||
@PostMapping("/upd-file") |
|||
public ResponseEntity<ServiceResponseDTO> updFile(@ModelAttribute UpdateFileDataRequestDTO updFileDataReqDTO) { |
|||
ServiceResponseDTO serResDTO = fileDataSer.updFileData(updFileDataReqDTO); |
|||
if (serResDTO.isResStat()) { |
|||
return ResponseEntity.ok(serResDTO); |
|||
} else { |
|||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(serResDTO); |
|||
} |
|||
} |
|||
|
|||
@PostMapping("/upd-ejv-num") |
|||
public ResponseEntity<ServiceResponseDTO> updEjvNum(@RequestParam("file-num") String fileNum, |
|||
@RequestParam("ejv-num") String ejvNum, @RequestParam("ejv-num-file") MultipartFile ejvNumFile) { |
|||
ServiceResponseDTO serResDTO = fileDataSer.updEjvNum(fileNum, ejvNumFile, ejvNum); |
|||
if (serResDTO.isResStat()) { |
|||
return ResponseEntity.ok(serResDTO); |
|||
} else { |
|||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(serResDTO); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
package com.adjustment_file_management_system.springboot.rest_controller; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.security.authentication.AuthenticationManager; |
|||
import org.springframework.security.authentication.BadCredentialsException; |
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.security.core.AuthenticationException; |
|||
import org.springframework.security.core.context.SecurityContext; |
|||
import org.springframework.security.core.context.SecurityContextHolder; |
|||
import org.springframework.security.core.userdetails.UsernameNotFoundException; |
|||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; |
|||
import org.springframework.web.bind.annotation.ModelAttribute; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import com.adjustment_file_management_system.springboot.request_dto.AppUserRequestDTO; |
|||
|
|||
import jakarta.servlet.http.HttpServletRequest; |
|||
import jakarta.servlet.http.HttpSession; |
|||
|
|||
@RestController |
|||
@RequestMapping("/api") |
|||
public class HomeRestController { |
|||
|
|||
@Autowired |
|||
private AuthenticationManager authManager; |
|||
|
|||
@PostMapping("/val-app-usr-login") |
|||
public ResponseEntity<?> valUsrLogin(@ModelAttribute AppUserRequestDTO appUsrReqDTO, HttpServletRequest req) { |
|||
Map<String, Object> res = new HashMap<String, Object>(); |
|||
try { |
|||
Authentication auth = authManager.authenticate( |
|||
new UsernamePasswordAuthenticationToken(appUsrReqDTO.getUsrName(), appUsrReqDTO.getUsrPass())); |
|||
|
|||
/** |
|||
* Store authentication in session so Spring Security knows the user is logged |
|||
* in |
|||
**/ |
|||
SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); |
|||
securityContext.setAuthentication(auth); |
|||
SecurityContextHolder.setContext(securityContext); |
|||
|
|||
HttpSession httpSession = req.getSession(true); |
|||
httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext); |
|||
|
|||
// Authentication successful |
|||
res.put("result", true); |
|||
res.put("usrName", auth.getName()); |
|||
res.put("role", auth.getAuthorities()); |
|||
return ResponseEntity.ok(res); |
|||
} catch (AuthenticationException ae) { |
|||
|
|||
// 1️ Username not found (direct) |
|||
if (ae instanceof UsernameNotFoundException) { |
|||
res.put("result", false); |
|||
res.put("error", "User not found"); |
|||
return ResponseEntity.status(404).body(res); |
|||
} |
|||
|
|||
// 2 Wrong password (direct) |
|||
if (ae instanceof BadCredentialsException) { |
|||
res.put("result", false); |
|||
res.put("error", "Invalid username or password"); |
|||
return ResponseEntity.status(401).body(res); |
|||
} |
|||
// 3️ Default fallback |
|||
res.put("result", false); |
|||
res.put("error", "Authentication failed"); |
|||
return ResponseEntity.status(401).body(res); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,606 @@ |
|||
package com.adjustment_file_management_system.springboot.service; |
|||
|
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.time.Instant; |
|||
import java.time.LocalDate; |
|||
import java.time.ZoneId; |
|||
import java.time.format.DateTimeFormatter; |
|||
import java.time.temporal.ChronoUnit; |
|||
import java.util.ArrayList; |
|||
import java.util.Comparator; |
|||
import java.util.Date; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.function.Consumer; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import com.adjustment_file_management_system.springboot.configuration.FileDataPropertiesConfiguration; |
|||
import com.adjustment_file_management_system.springboot.mapper.AdvanceTypeMapper; |
|||
import com.adjustment_file_management_system.springboot.mapper.FileDataMapper; |
|||
import com.adjustment_file_management_system.springboot.mapper.FundTypeMapper; |
|||
import com.adjustment_file_management_system.springboot.repository.AdvanceTypeRepository; |
|||
import com.adjustment_file_management_system.springboot.repository.FileDataRepository; |
|||
import com.adjustment_file_management_system.springboot.repository.FundTypeRepository; |
|||
import com.adjustment_file_management_system.springboot.request_dto.AddFileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.request_dto.AdvanceTypeRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.request_dto.FileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.request_dto.UpdateFileDataRequestDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.AdvanceTypeResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.FileDataResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.FundTypeResponseDTO; |
|||
import com.adjustment_file_management_system.springboot.response_dto.ServiceResponseDTO; |
|||
|
|||
@Service |
|||
public class FileDataService { |
|||
|
|||
@Autowired |
|||
private FileDataRepository fileDataRepo; |
|||
|
|||
@Autowired |
|||
private FolderService folderSer; |
|||
|
|||
@Autowired |
|||
private AdvanceTypeRepository advTypeRepo; |
|||
|
|||
@Autowired |
|||
private FundTypeRepository fundTypeRepo; |
|||
|
|||
@Autowired |
|||
private FundTypeMapper fundTypeMap; |
|||
|
|||
@Autowired |
|||
private FileDataPropertiesConfiguration fileDataPropsConfig; |
|||
|
|||
@Autowired |
|||
private FileDataMapper fileDataMap; |
|||
|
|||
@Autowired |
|||
private AdvanceTypeMapper advTypeMap; |
|||
|
|||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(FileDataService.class); |
|||
|
|||
private static final Date placeHolderDate = new Date(0); |
|||
|
|||
// Clean file if error occurrs while adding file |
|||
private void cleanUpFiles(String... paths) { |
|||
for (String path : paths) { |
|||
folderSer.deleteFileIfExists(path); |
|||
} |
|||
} |
|||
|
|||
// Setting default values for new file |
|||
private void setDefaultFileDataValues(FileDataRequestDTO fileDataReqDTO) { |
|||
fileDataReqDTO.setAsFinalFileGenDate(placeHolderDate); |
|||
fileDataReqDTO.setAsFinalFilePath("-"); |
|||
fileDataReqDTO.setBalAmt(0.0); |
|||
fileDataReqDTO.setDcFilePath("-"); |
|||
fileDataReqDTO.setEjvNum("-"); |
|||
fileDataReqDTO.setEjvNumFilePath("-"); |
|||
fileDataReqDTO.setFiAmt(0.0); |
|||
fileDataReqDTO.setFiFileGenDate(placeHolderDate); |
|||
fileDataReqDTO.setFiFilePath("-"); |
|||
fileDataReqDTO.setPiFilePath("-"); |
|||
fileDataReqDTO.setPoFilePath("-"); |
|||
fileDataReqDTO.setRtgsFilePath("-"); |
|||
fileDataReqDTO.setSrFilePath("-"); |
|||
fileDataReqDTO.setIrFilePath("-"); |
|||
fileDataReqDTO.setTcFileGenDate(placeHolderDate); |
|||
fileDataReqDTO.setTcFilePath("-"); |
|||
fileDataReqDTO.setAsFilePath("-"); |
|||
fileDataReqDTO.setPiFilePath("-"); |
|||
fileDataReqDTO.setEjvNumFileGenDate(placeHolderDate); |
|||
} |
|||
|
|||
/** |
|||
* Helper method for file uploads, tracks uploaded files automatically. |
|||
*/ |
|||
private void handleFileUpload(String fileNum, String type, Date date, MultipartFile file, |
|||
Consumer<String> pathSetter, List<String> uploadedFiles) throws IOException { |
|||
if (file == null || file.isEmpty()) { |
|||
return; |
|||
} |
|||
|
|||
String path = folderSer.saveFile(fileNum, type, date, file); |
|||
pathSetter.accept(path); |
|||
|
|||
// Track uploaded file for cleanup if something goes wrong later |
|||
uploadedFiles.add(path); |
|||
} |
|||
|
|||
/** |
|||
* Utility method for choosing first non-null value. |
|||
*/ |
|||
private <T> T firstNonNull(T a, T b) { |
|||
return (a != null) ? a : b; |
|||
} |
|||
|
|||
// Helper method for date modifying |
|||
public String formatForFlatpickr(Date date) { |
|||
if (date == null) { |
|||
return ""; |
|||
} |
|||
// Convert java.util.Date to LocalDate |
|||
LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); |
|||
if (localDate.equals(LocalDate.of(1970, 1, 1))) { |
|||
return ""; |
|||
} |
|||
return localDate.format(formatter); |
|||
} |
|||
|
|||
/** |
|||
* Helper to update a field if not null |
|||
*/ |
|||
private <T> void updateIfNotNull(Consumer<T> setter, T value) { |
|||
if (value != null) |
|||
setter.accept(value); |
|||
} |
|||
|
|||
/** |
|||
* Helper to update a String field if not blank |
|||
*/ |
|||
private void updateIfNotBlank(Consumer<String> setter, String value) { |
|||
if (value != null && !value.isBlank()) |
|||
setter.accept(value.trim()); |
|||
} |
|||
|
|||
/** |
|||
* Returns the file from Respective File Data Request DTO by type |
|||
*/ |
|||
private MultipartFile getFileByType(Object obj, String type) { |
|||
if (obj instanceof AddFileDataRequestDTO addFileDataReqDTO) { |
|||
return switch (type) { |
|||
case "AS" -> addFileDataReqDTO.getAsFile(); |
|||
case "PI" -> addFileDataReqDTO.getPiFile(); |
|||
default -> null; |
|||
}; |
|||
} else if (obj instanceof UpdateFileDataRequestDTO updFileDataReqDTO) { |
|||
return switch (type) { |
|||
case "AS" -> updFileDataReqDTO.getAsFile(); |
|||
case "PI" -> updFileDataReqDTO.getPiFile(); |
|||
case "FI" -> updFileDataReqDTO.getFiFile(); |
|||
case "AS-Final" -> updFileDataReqDTO.getAsFinalFile(); |
|||
case "TC" -> updFileDataReqDTO.getTcFile(); |
|||
default -> null; |
|||
}; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
// Returns the file name from path |
|||
public String getFileName(String filePath) { |
|||
return Path.of(filePath).getFileName().toString(); |
|||
} |
|||
|
|||
// Calculates the number of days from present till the date of FI uploaded date |
|||
private void calculateDaysPass(FileDataResponseDTO fileDataResDTO) { |
|||
LocalDate fiFileGenDate = ((java.sql.Date) fileDataResDTO.getFiFileGenDate()).toLocalDate(); |
|||
LocalDate ejvNumFileGenDate = ((java.sql.Date) fileDataResDTO.getEjvNumFileGenDate()).toLocalDate(); |
|||
boolean fiFilePresent = !fileDataResDTO.getFiFilePath().equals("-"); |
|||
boolean ejvFilePresent = !fileDataResDTO.getEjvNumFilePath().equals("-"); |
|||
|
|||
if (!fiFileGenDate.equals(LocalDate.of(1970, 1, 1)) && fiFilePresent) { |
|||
long daysPassed; |
|||
if (ejvFilePresent && !ejvNumFileGenDate.equals(LocalDate.of(1970, 1, 1))) { |
|||
daysPassed = ChronoUnit.DAYS.between(fiFileGenDate, ejvNumFileGenDate); |
|||
} else { |
|||
daysPassed = ChronoUnit.DAYS.between(fiFileGenDate, LocalDate.now()); |
|||
} |
|||
fileDataResDTO.setDaysPass(daysPassed); |
|||
} else { |
|||
fileDataResDTO.setDaysPass(0L); |
|||
} |
|||
} |
|||
|
|||
// Extract the starting year from financial year string |
|||
private Integer extractStartYear(String finYear) { |
|||
if (finYear == null || !finYear.contains("-")) { |
|||
return 0; |
|||
} |
|||
try { |
|||
// Extract the part before the dash (e.g., "2020" from "2020-2021") |
|||
return Integer.parseInt(finYear.split("-")[0].trim()); |
|||
} catch (NumberFormatException nfe) { |
|||
nfe.printStackTrace(); |
|||
logger.info("Exception occurred while extracting the financial starting year: {}", nfe.getMessage()); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Extract the ending year from financial year string |
|||
**/ |
|||
private Integer extractEndYear(String finYear) { |
|||
if (finYear == null || !finYear.contains("-")) |
|||
return 0; |
|||
try { |
|||
return Integer.parseInt(finYear.split("-")[1].trim()); |
|||
} catch (NumberFormatException nfe) { |
|||
nfe.printStackTrace(); |
|||
logger.info("Exception occurred while extracting the financial end year: {}", nfe.getMessage()); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
// Reads PDF bytes from the given file path of respective file number if valid |
|||
public byte[] getFileBytes(String fileType, String filePath, String fileNum) throws IOException { |
|||
fileType = fileType.trim(); |
|||
filePath = filePath.trim(); |
|||
fileNum = fileNum.trim(); |
|||
if (!StringUtils.hasText(fileType) || !StringUtils.hasText(filePath)) { |
|||
throw new IllegalArgumentException("Invalid request parameters"); |
|||
} |
|||
|
|||
switch (fileType) { |
|||
case "AS", "PI", "RTGS", "PO", "DC", "SR", "IR", "EJV-Number", "AS-Final", "FI", "TC" -> { |
|||
|
|||
// Remove duplicate prefix from filePath if present |
|||
if (filePath.startsWith("/uploads/file-data/")) { |
|||
filePath = filePath.substring("/uploads/file-data/".length()); |
|||
} else if (filePath.startsWith("uploads/file-data/")) { |
|||
filePath = filePath.substring("uploads/file-data/".length()); |
|||
} |
|||
|
|||
// Resolve relative path inside uploadDir |
|||
File baseDir = fileDataPropsConfig.getUploadDirFile(); |
|||
Path fullPath = Path.of(baseDir.getAbsolutePath(), filePath).normalize(); |
|||
|
|||
if (!Files.exists(fullPath)) { |
|||
throw new IOException("File not found for file number: " + fileNum); |
|||
} |
|||
return Files.readAllBytes(fullPath); |
|||
} |
|||
default -> |
|||
throw new IllegalArgumentException("Unknown file type: " + fileType + " for file number: " + fileNum); |
|||
} |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public FileDataResponseDTO getFileDataByFileNum(String fileNum) { |
|||
FileDataResponseDTO dto = fileDataMap.toFileDataResDTO(fileDataRepo.findFileDataByFileDataNum(fileNum)); |
|||
calculateDaysPass(dto); |
|||
return dto; |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public List<String> getAllFileDataNum() { |
|||
return fileDataRepo.findAll().stream().map(fileData -> fileData.getFileDataNum()).toList(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public List<FileDataResponseDTO> getAllFileData() { |
|||
// Comparator for comparing financial year |
|||
Comparator<FileDataResponseDTO> comparator = Comparator |
|||
.comparing((FileDataResponseDTO dto) -> extractStartYear(dto.getFinYear())) |
|||
.thenComparing(dto -> extractEndYear(dto.getFinYear())); |
|||
|
|||
return fileDataRepo.findAll().stream().map(fileData -> { |
|||
FileDataResponseDTO dto = fileDataMap.toFileDataResDTO(fileData); |
|||
calculateDaysPass(dto); |
|||
return dto; |
|||
}).sorted(comparator).toList(); |
|||
} |
|||
|
|||
@Transactional(rollbackFor = Exception.class) |
|||
public ServiceResponseDTO addFileData(AddFileDataRequestDTO addFileDataReqDTO) { |
|||
List<String> uploadedFiles = new ArrayList<String>(); // Track uploaded file paths |
|||
|
|||
try { |
|||
String fileNum = addFileDataReqDTO.getFileNum().trim(); |
|||
String vendName = (addFileDataReqDTO.getVendName() != null |
|||
&& !addFileDataReqDTO.getVendName().trim().isEmpty()) |
|||
? addFileDataReqDTO.getVendName().trim().toUpperCase() |
|||
: "-"; |
|||
String advTypeName = addFileDataReqDTO.getAdvType().trim().toUpperCase(); |
|||
Double piAmt = addFileDataReqDTO.getPiAmt() != null ? addFileDataReqDTO.getPiAmt() : 0.0; |
|||
Date piFileGenDate = addFileDataReqDTO.getPiFileGenDate() != null ? addFileDataReqDTO.getPiFileGenDate() |
|||
: placeHolderDate; |
|||
Date asFileGenDate = addFileDataReqDTO.getAsFileGenDate() != null ? addFileDataReqDTO.getAsFileGenDate() |
|||
: placeHolderDate; |
|||
|
|||
// 1️. Get or create AdvanceType |
|||
AdvanceTypeResponseDTO advTypeResDTO = advTypeMap |
|||
.toAdvTypeResDTO(advTypeRepo.findAdvTypeByAdvType(advTypeName).orElseGet(() -> { |
|||
AdvanceTypeRequestDTO advTypeReqDTO = new AdvanceTypeRequestDTO(advTypeName); |
|||
return advTypeRepo.save(advTypeMap.toAdvTypeEnt(advTypeReqDTO)); |
|||
})); |
|||
|
|||
// 2️. Prepare DTO |
|||
FileDataRequestDTO fileDataReqDTO = new FileDataRequestDTO(); |
|||
fileDataReqDTO.setAdvTypeId(advTypeResDTO.getAdvTypeId()); |
|||
fileDataReqDTO.setFileDataNum(fileNum); |
|||
fileDataReqDTO.setFileRmrk(addFileDataReqDTO.getFileRmrk().trim()); |
|||
fileDataReqDTO.setFinYear(addFileDataReqDTO.getFinYear().trim()); |
|||
fileDataReqDTO.setFundTypeId(addFileDataReqDTO.getFundTypeId()); |
|||
fileDataReqDTO.setVendName(vendName); |
|||
fileDataReqDTO.setPiAmt(piAmt); |
|||
fileDataReqDTO.setAsFileGenDate(asFileGenDate); |
|||
fileDataReqDTO.setPiFileGenDate(piFileGenDate); |
|||
|
|||
// Set default values |
|||
setDefaultFileDataValues(fileDataReqDTO); |
|||
|
|||
// 3️. Handle file uploads |
|||
Map<String, MultipartFile> files = new HashMap<String, MultipartFile>(); |
|||
if (addFileDataReqDTO.getAsFile() != null) { |
|||
files.put("AS", addFileDataReqDTO.getAsFile()); |
|||
} |
|||
if (addFileDataReqDTO.getPiFile() != null) { |
|||
files.put("PI", addFileDataReqDTO.getPiFile()); |
|||
} |
|||
|
|||
Map<String, Consumer<String>> pathSetters = Map.of("AS", fileDataReqDTO::setAsFilePath, "PI", |
|||
fileDataReqDTO::setPiFilePath); |
|||
|
|||
for (String type : files.keySet()) { |
|||
MultipartFile file = files.get(type); |
|||
// use the dates already set |
|||
handleFileUpload(fileNum, type, "AS".equals(type) ? asFileGenDate : piFileGenDate, file, |
|||
pathSetters.get(type), uploadedFiles); |
|||
} |
|||
|
|||
// 4️. Save to DB |
|||
fileDataRepo.save(fileDataMap.toFileDataEnt(fileDataReqDTO)); |
|||
|
|||
logger.info("File saved with file number: {}", fileNum); |
|||
return new ServiceResponseDTO(true, "File added successfully"); |
|||
|
|||
} catch (IOException ioe) { |
|||
logger.error("Exception occurred in file upload part: {}", ioe.getMessage(), ioe); |
|||
ioe.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, "Failed to add the file. Error in file upload: " + ioe.getMessage()); |
|||
} catch (Exception e) { |
|||
logger.error("Exception occurred: {}", e.getMessage(), e); |
|||
e.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, "Failed to add the file. Error: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
@Transactional(rollbackFor = Exception.class) |
|||
public ServiceResponseDTO updFileData(UpdateFileDataRequestDTO updFileReqDTO) { |
|||
List<String> uploadedFiles = new ArrayList<String>(); // Track uploaded paths |
|||
|
|||
try { |
|||
String fileNum = updFileReqDTO.getFileNum().trim(); |
|||
FileDataResponseDTO fileDataResDTO = fileDataMap |
|||
.toFileDataResDTO(fileDataRepo.findFileDataByFileDataNum(fileNum)); |
|||
String advTypeName = updFileReqDTO.getAdvType().trim().toUpperCase(); |
|||
String reqVendName = updFileReqDTO.getVendName(); |
|||
String vendName = reqVendName != null ? reqVendName.trim().toUpperCase() : "-"; |
|||
|
|||
if (fileDataResDTO == null) { |
|||
return new ServiceResponseDTO(false, "File not found for file number: " + fileNum); |
|||
} |
|||
|
|||
// Get or create AdvanceType |
|||
AdvanceTypeResponseDTO advTypeResDTO = advTypeMap |
|||
.toAdvTypeResDTO(advTypeRepo.findAdvTypeByAdvType(advTypeName).orElseGet(() -> { |
|||
AdvanceTypeRequestDTO advTypeReqDTO = new AdvanceTypeRequestDTO(advTypeName); |
|||
return advTypeRepo.save(advTypeMap.toAdvTypeEnt(advTypeReqDTO)); |
|||
})); |
|||
|
|||
// Update simple fields |
|||
fileDataResDTO.setAdvTypeResDTO(advTypeResDTO); |
|||
fileDataResDTO.setVendName(vendName); |
|||
fileDataResDTO.setFundTypeResDTO( |
|||
fundTypeMap.toFundTypeResDTO(fundTypeRepo.findById(updFileReqDTO.getFundTypeId()).get())); |
|||
updateIfNotBlank(fileDataResDTO::setFileRmrk, updFileReqDTO.getFileRmrk()); |
|||
updateIfNotNull(fileDataResDTO::setPiAmt, updFileReqDTO.getPiAmt()); |
|||
updateIfNotNull(fileDataResDTO::setFiAmt, updFileReqDTO.getFiAmt()); |
|||
updateIfNotNull(fileDataResDTO::setBalAmt, updFileReqDTO.getBalAmt()); |
|||
|
|||
// Simple files (no dates) |
|||
Map<String, MultipartFile> simpleFiles = new HashMap<String, MultipartFile>(); |
|||
if (updFileReqDTO.getPoFile() != null) { |
|||
simpleFiles.put("PO", updFileReqDTO.getPoFile()); |
|||
} |
|||
if (updFileReqDTO.getDcFile() != null) { |
|||
simpleFiles.put("DC", updFileReqDTO.getDcFile()); |
|||
} |
|||
if (updFileReqDTO.getRtgsFile() != null) { |
|||
simpleFiles.put("RTGS", updFileReqDTO.getRtgsFile()); |
|||
} |
|||
if (updFileReqDTO.getSrFile() != null) { |
|||
simpleFiles.put("SR", updFileReqDTO.getSrFile()); |
|||
} |
|||
if (updFileReqDTO.getIrFile() != null) { |
|||
simpleFiles.put("IR", updFileReqDTO.getIrFile()); |
|||
} |
|||
|
|||
Map<String, Consumer<String>> simpleSetters = Map.of("PO", fileDataResDTO::setPoFilePath, "DC", |
|||
fileDataResDTO::setDcFilePath, "RTGS", fileDataResDTO::setRtgsFilePath, "SR", |
|||
fileDataResDTO::setSrFilePath, "IR", fileDataResDTO::setIrFilePath); |
|||
|
|||
// Handle simple files |
|||
for (Map.Entry<String, MultipartFile> entry : simpleFiles.entrySet()) { |
|||
handleFileUpload(fileNum, entry.getKey(), null, entry.getValue(), simpleSetters.get(entry.getKey()), |
|||
uploadedFiles); |
|||
} |
|||
|
|||
// Complex files (with dates) |
|||
Map<String, MultipartFile> complexFiles = new HashMap<String, MultipartFile>(); |
|||
if (updFileReqDTO.getAsFile() != null) { |
|||
complexFiles.put("AS", updFileReqDTO.getAsFile()); |
|||
} |
|||
if (updFileReqDTO.getPiFile() != null) { |
|||
complexFiles.put("PI", updFileReqDTO.getPiFile()); |
|||
} |
|||
if (updFileReqDTO.getFiFile() != null) { |
|||
complexFiles.put("FI", updFileReqDTO.getFiFile()); |
|||
} |
|||
if (updFileReqDTO.getAsFinalFile() != null) { |
|||
complexFiles.put("AS-Final", updFileReqDTO.getAsFinalFile()); |
|||
} |
|||
if (updFileReqDTO.getTcFile() != null) { |
|||
complexFiles.put("TC", updFileReqDTO.getTcFile()); |
|||
} |
|||
|
|||
Map<String, Date> currentDates = new HashMap<String, Date>(); |
|||
if (fileDataResDTO.getAsFileGenDate() != null) { |
|||
currentDates.put("AS", fileDataResDTO.getAsFileGenDate()); |
|||
} |
|||
if (fileDataResDTO.getPiFileGenDate() != null) { |
|||
currentDates.put("PI", fileDataResDTO.getPiFileGenDate()); |
|||
} |
|||
if (fileDataResDTO.getFiFileGenDate() != null) { |
|||
currentDates.put("FI", fileDataResDTO.getFiFileGenDate()); |
|||
} |
|||
if (fileDataResDTO.getAsFinalFileGenDate() != null) { |
|||
currentDates.put("AS-Final", fileDataResDTO.getAsFinalFileGenDate()); |
|||
} |
|||
if (fileDataResDTO.getTcFileGenDate() != null) { |
|||
currentDates.put("TC", fileDataResDTO.getTcFileGenDate()); |
|||
} |
|||
|
|||
Map<String, Date> newDates = new HashMap<String, Date>(); |
|||
if (updFileReqDTO.getAsFileGenDate() != null) { |
|||
newDates.put("AS", updFileReqDTO.getAsFileGenDate()); |
|||
} |
|||
if (updFileReqDTO.getPiFileGenDate() != null) { |
|||
newDates.put("PI", updFileReqDTO.getPiFileGenDate()); |
|||
} |
|||
if (updFileReqDTO.getFiFileGenDate() != null) { |
|||
newDates.put("FI", updFileReqDTO.getFiFileGenDate()); |
|||
} |
|||
if (updFileReqDTO.getAsFinalFileGenDate() != null) { |
|||
newDates.put("AS-Final", updFileReqDTO.getAsFinalFileGenDate()); |
|||
} |
|||
if (updFileReqDTO.getTcFileGenDate() != null) { |
|||
newDates.put("TC", updFileReqDTO.getTcFileGenDate()); |
|||
} |
|||
|
|||
Map<String, Consumer<String>> pathSetters = Map.of("AS", fileDataResDTO::setAsFilePath, "PI", |
|||
fileDataResDTO::setPiFilePath, "FI", fileDataResDTO::setFiFilePath, "AS-Final", |
|||
fileDataResDTO::setAsFinalFilePath, "TC", fileDataResDTO::setTcFilePath); |
|||
|
|||
Map<String, Consumer<Date>> dateSetters = Map.of("AS", fileDataResDTO::setAsFileGenDate, "PI", |
|||
fileDataResDTO::setPiFileGenDate, "FI", fileDataResDTO::setFiFileGenDate, "AS-Final", |
|||
fileDataResDTO::setAsFinalFileGenDate, "TC", fileDataResDTO::setTcFileGenDate); |
|||
|
|||
// Handle complex files |
|||
for (String type : currentDates.keySet()) { |
|||
Date dateToUse = firstNonNull(newDates.get(type), currentDates.get(type)); |
|||
dateSetters.get(type).accept(dateToUse); |
|||
handleFileUpload(fileNum, type, dateToUse, getFileByType(updFileReqDTO, type), pathSetters.get(type), |
|||
uploadedFiles); |
|||
} |
|||
|
|||
// Save updated entity |
|||
fileDataRepo.save(fileDataMap.toFileDataEnt(fileDataResDTO)); |
|||
return new ServiceResponseDTO(true, "File updated successfully."); |
|||
|
|||
} catch (IOException ioe) { |
|||
logger.error("Exception occurred in file upload part: {}", ioe.getMessage(), ioe); |
|||
ioe.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, |
|||
"Failed to update the file. Error in file upload: " + ioe.getMessage()); |
|||
} catch (Exception e) { |
|||
logger.error("Exception occurred: {}", e.getMessage(), e); |
|||
e.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, "Failed to update the file. Error: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
@Transactional(rollbackFor = Exception.class) |
|||
public ServiceResponseDTO updEjvNum(String fileNum, MultipartFile ejvNumFile, String ejvNum) { |
|||
List<String> uploadedFiles = new ArrayList<String>(); // Track uploaded files |
|||
|
|||
try { |
|||
fileNum = fileNum.trim(); |
|||
ejvNum = ejvNum.trim(); |
|||
|
|||
// 1️. Find existing FileData |
|||
FileDataResponseDTO fileDataResDTO = fileDataMap |
|||
.toFileDataResDTO(fileDataRepo.findFileDataByFileDataNum(fileNum)); |
|||
|
|||
if (fileDataResDTO == null) { |
|||
return new ServiceResponseDTO(false, "File not found for file number: " + fileNum); |
|||
} |
|||
|
|||
// 2️. Update fields |
|||
fileDataResDTO.setEjvNum(ejvNum); |
|||
fileDataResDTO.setEjvNumFileGenDate(new Date()); |
|||
|
|||
// 3️. Handle file upload |
|||
if (ejvNumFile != null && !ejvNumFile.isEmpty()) { |
|||
handleFileUpload(fileNum, "EJV-Number", fileDataResDTO.getEjvNumFileGenDate(), ejvNumFile, |
|||
fileDataResDTO::setEjvNumFilePath, uploadedFiles); |
|||
} |
|||
|
|||
// 4️. Save updated entity |
|||
fileDataRepo.save(fileDataMap.toFileDataEnt(fileDataResDTO)); |
|||
|
|||
return new ServiceResponseDTO(true, "Updated the EJV Number successfully."); |
|||
|
|||
} catch (IOException ioe) { |
|||
logger.error("Exception occurred in file upload part: {}", ioe.getMessage(), ioe); |
|||
ioe.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, |
|||
"Failed to update the EJV Number. Error in file upload: " + ioe.getMessage()); |
|||
} catch (Exception e) { |
|||
logger.error("Exception occurred: {}", e.getMessage(), e); |
|||
e.printStackTrace(); |
|||
cleanUpFiles(uploadedFiles.toArray(new String[0])); // Delete all uploaded files |
|||
return new ServiceResponseDTO(false, "Failed to update the EJV Number. Error: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public List<AdvanceTypeResponseDTO> getAllAdvTypes() { |
|||
// TODO Auto-generated method stub |
|||
return advTypeRepo.findAll().stream().map(advTypeMap::toAdvTypeResDTO).toList(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public List<FundTypeResponseDTO> getAllFundTypes() { |
|||
// TODO Auto-generated method stub |
|||
return fundTypeRepo.findAll().stream().map(fundTypeMap::toFundTypeResDTO).toList(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public Long getAllAdjustFileData() { |
|||
return fileDataRepo.findAll().stream() |
|||
.filter(fileDatum -> fileDatum.getEjvNum() != null && fileDatum.getEjvNumFilePath() != null |
|||
&& !fileDatum.getEjvNum().trim().equals("-") |
|||
&& !fileDatum.getEjvNumFilePath().trim().equals("-")) |
|||
.count(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public Long getAllNotAdjustFileData() { |
|||
return fileDataRepo.findAll().stream().filter(fileDatum -> fileDatum.getEjvNum() != null |
|||
&& fileDatum.getEjvNumFilePath() != null |
|||
&& (fileDatum.getEjvNum().trim().equals("-") || fileDatum.getEjvNumFilePath().trim().equals("-"))) |
|||
.count(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public Long getAllItcFileData() { |
|||
return fileDataRepo.findAll().stream().filter(fileDatum -> fileDatum.getFileDataNum() != null |
|||
&& fileDatum.getFileDataNum().toUpperCase().contains("I.T.C")).count(); |
|||
} |
|||
|
|||
@Transactional(readOnly = true) |
|||
public Long getAllEdpFileData() { |
|||
return fileDataRepo.findAll().stream().filter(fileDatum -> fileDatum.getFileDataNum() != null |
|||
&& fileDatum.getFileDataNum().toUpperCase().contains("E.D.P")).count(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,119 @@ |
|||
package com.adjustment_file_management_system.springboot.service; |
|||
|
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.nio.file.Paths; |
|||
import java.util.Calendar; |
|||
import java.util.Date; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import com.adjustment_file_management_system.springboot.configuration.FileDataProperties; |
|||
import com.adjustment_file_management_system.springboot.configuration.FileDataPropertiesConfiguration; |
|||
|
|||
import jakarta.annotation.PostConstruct; |
|||
|
|||
@Service |
|||
public class FolderService { |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(FolderService.class); |
|||
|
|||
@Autowired |
|||
private FileDataPropertiesConfiguration fileDataPropsConfig; |
|||
|
|||
@Autowired |
|||
private FileDataProperties fileDataProps; |
|||
|
|||
private Path fullUploadPath; |
|||
|
|||
@PostConstruct |
|||
public void init() throws IOException { |
|||
// Initialize absolute upload path after config is ready |
|||
fullUploadPath = fileDataPropsConfig.getUploadDirFile().toPath(); |
|||
Files.createDirectories(fullUploadPath); |
|||
} |
|||
|
|||
/** |
|||
* Save uploaded file in a structured directory: |
|||
* uploads/file-data/{fileNum}/{category}/{category-year.extension} |
|||
* |
|||
* @param fileNum File number (e.g., I.T.C.C.NO.C1/240/2024) |
|||
* @param fileType Category (AS, PI, RTGS) |
|||
* @param genDate Generation date for naming (if null, current date is used) |
|||
* @param file The uploaded MultipartFile |
|||
* @return relative path (for DB) |
|||
*/ |
|||
public String saveFile(String fileNum, String fileType, Date genDate, MultipartFile file) throws IOException { |
|||
// Build target directory under the absolute upload path |
|||
Path targetDir = fullUploadPath.resolve(fileNum).resolve(fileType); |
|||
Files.createDirectories(targetDir); |
|||
|
|||
// Extract file extension |
|||
String originalName = file.getOriginalFilename(); |
|||
String extension = ""; |
|||
String baseName = "file"; // Fallback name |
|||
if (originalName != null && originalName.contains(".")) { |
|||
int dotIndex = originalName.lastIndexOf("."); |
|||
if (dotIndex >= 0) { |
|||
extension = originalName.substring(dotIndex); // Includes dot |
|||
baseName = originalName.substring(0, dotIndex); // Name without extension |
|||
} else { |
|||
baseName = originalName; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Sanitize the base name by removing leading/trailing spaces, replacing spaces |
|||
* with underscore and removing special characters except _ and - |
|||
**/ |
|||
baseName = baseName.trim().replaceAll("\\s+", "_").replaceAll("[^a-zA-Z0-9_\\-]", ""); |
|||
|
|||
// Use provided date or fallback to current date |
|||
Calendar cal = Calendar.getInstance(); |
|||
if (genDate != null) { |
|||
cal.setTime(genDate); |
|||
} |
|||
int year = cal.get(Calendar.YEAR); |
|||
|
|||
// Build new filename: originalname-filetype-year.extension |
|||
String newFileName = baseName + "-" + fileType.toLowerCase() + "-" + year + extension; |
|||
|
|||
// Save file |
|||
Path targetPath = targetDir.resolve(newFileName); |
|||
file.transferTo(targetPath.toFile()); |
|||
|
|||
logger.info("Saved file to {}", targetPath.toAbsolutePath()); |
|||
|
|||
// Return relative path to store in DB |
|||
return "/" |
|||
+ Paths.get(fileDataProps.getUploadDir(), fileNum, fileType, newFileName).toString().replace("\\", "/"); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* Utility method to safely delete a file. |
|||
*/ |
|||
public void deleteFileIfExists(String filePath) { |
|||
if (filePath != null && !filePath.equals("-")) { |
|||
try { |
|||
File file = new File(filePath); |
|||
if (file.exists() && file.isFile()) { |
|||
if (file.delete()) { |
|||
logger.info("Deleted orphan file: {}", filePath); |
|||
} else { |
|||
logger.warn("Failed to delete orphan file: {}", filePath); |
|||
} |
|||
} |
|||
} catch (Exception ex) { |
|||
logger.error("Error while deleting file {}: {}", filePath, ex.getMessage(), ex); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
package com.adjustment_file_management_system.springboot.service; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
import java.util.Optional; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.core.userdetails.User; |
|||
import org.springframework.security.core.userdetails.UserDetails; |
|||
import org.springframework.security.core.userdetails.UserDetailsService; |
|||
import org.springframework.security.core.userdetails.UsernameNotFoundException; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import com.adjustment_file_management_system.springboot.model.AppUser; |
|||
import com.adjustment_file_management_system.springboot.repository.AppUserRepository; |
|||
import com.adjustment_file_management_system.springboot.repository.FileDataRepository; |
|||
|
|||
|
|||
@Service |
|||
public class HomeService implements UserDetailsService { |
|||
|
|||
@Autowired |
|||
private AppUserRepository appUsrRepo; |
|||
|
|||
@Autowired |
|||
private FileDataRepository fileDataRepo; |
|||
|
|||
@Autowired |
|||
private FileDataService fileDataSer; |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(HomeService.class); |
|||
|
|||
@Override |
|||
public UserDetails loadUserByUsername(String usrName) throws UsernameNotFoundException { |
|||
logger.info("Loading user: {}", usrName); |
|||
Optional<AppUser> optAppUsr = appUsrRepo.findByUsrName(usrName); |
|||
|
|||
AppUser appUsr = optAppUsr |
|||
.orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + usrName)); |
|||
|
|||
// Uses Bcrypt for password verification |
|||
UserDetails userDetails = User.withUsername(appUsr.getUsrName()).password(appUsr.getUsrPass()) |
|||
.authorities(appUsr.getUsrRole().getUsrRoleName()).build(); |
|||
|
|||
return userDetails; |
|||
} |
|||
|
|||
public Map<String, Long> getFileDataStat() { |
|||
Map<String, Long> fileDatumStat = new HashMap<String, Long>(); |
|||
Long totFileDatum = fileDataRepo.count(); |
|||
Long totAdjustFileDatum = fileDataSer.getAllAdjustFileData(); |
|||
Long totNotAdjustFileDatum = fileDataSer.getAllNotAdjustFileData(); |
|||
Long totItcFileDatum = fileDataSer.getAllItcFileData(); |
|||
Long totEdpFileDatum = fileDataSer.getAllEdpFileData(); |
|||
fileDatumStat.put("totFile", totFileDatum); |
|||
fileDatumStat.put("totAdjustFile", totAdjustFileDatum); |
|||
fileDatumStat.put("totNotAdjustFile", totNotAdjustFileDatum); |
|||
fileDatumStat.put("totItcFile", totItcFileDatum); |
|||
fileDatumStat.put("totEdpFile", totEdpFileDatum); |
|||
return fileDatumStat; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{"properties": [ |
|||
{ |
|||
"name": "file.data.upload-dir", |
|||
"type": "java.lang.String", |
|||
"description": "Folder or Directory where all the uploaded files are stored" |
|||
}, |
|||
{ |
|||
"name": "app.security.force-https", |
|||
"type": "java.lang.String", |
|||
"description": "Enables Forcing of HTTPS for CSRF" |
|||
} |
|||
]} |
|||
@ -0,0 +1,48 @@ |
|||
spring.application.name=adjustment_file_management_system |
|||
server.port=8190 |
|||
server.address=0.0.0.0 |
|||
# 30 minutes |
|||
server.servlet.session.timeout=30m |
|||
|
|||
# =============================== |
|||
# Oracle Database Configuration |
|||
# =============================== |
|||
# Production DB server |
|||
# spring.datasource.url=jdbc:oracle:thin:@10.1.0.14:1521:chncorp |
|||
# spring.datasource.username=fileadjust |
|||
# spring.datasource.password=fileadjust |
|||
spring.datasource.url=${DB_URL} |
|||
spring.datasource.username=${DB_USERNAME} |
|||
spring.datasource.password=${DB_PASSWORD} |
|||
# Local DB server |
|||
# spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/XEPDB1 |
|||
# spring.datasource.username=gcc |
|||
# spring.datasource.password=product |
|||
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver |
|||
|
|||
# =============================== |
|||
# JPA / Hibernate Config |
|||
# =============================== |
|||
# spring.jpa.database-platform=org.hibernate.dialect.OracleDialect |
|||
# spring.jpa.hibernate.ddl-auto=update |
|||
spring.jpa.show-sql=true |
|||
# spring.jpa.properties.hibernate.format_sql=true |
|||
spring.jpa.open-in-view=true |
|||
logging.level.org.hibernate.SQL=DEBUG |
|||
# logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE |
|||
logging.level.org.hibernate.type.descriptor.sql=TRACE |
|||
|
|||
|
|||
# Directory/Folder to store uploaded files (can be used anywhere in the app using @Value or Environment) |
|||
# Relative path inside project root |
|||
file.data.upload-dir=uploads/file-data/ |
|||
|
|||
# Max file size (single file) |
|||
spring.servlet.multipart.max-file-size=100MB |
|||
|
|||
# Max request size (total request size including multiple files) |
|||
spring.servlet.multipart.max-request-size=400MB |
|||
|
|||
# To enable forced HTTPS for CSRF (false for dev/testing and https is disabled, true for production only if https is enabled) |
|||
# (can be used anywhere in the app using @Value or Environment) |
|||
app.security.force-https=${FORCE_HTTPS:false} |
|||
@ -0,0 +1,33 @@ |
|||
<configuration scan="true"> |
|||
|
|||
<!-- Read Spring property LOG_ROOT or default to 'logs' --> |
|||
<springProperty scope="context" name="LOG_DIR" source="LOG_ROOT" defaultValue="logs"/> |
|||
|
|||
<!-- Console Appender --> |
|||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
|||
<encoder> |
|||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) [%thread] %logger - %msg%n</pattern> |
|||
</encoder> |
|||
</appender> |
|||
|
|||
<!-- File Appender with Daily Rolling --> |
|||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender" prudent="true"> |
|||
<!-- Current log File --> |
|||
<file>${LOG_DIR}/app-logs.txt</file> |
|||
<!-- Rolling policy --> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<!-- Log file per day --> |
|||
<fileNamePattern>${LOG_DIR}/app-logs.%d{yyyy-MM-dd}.txt</fileNamePattern> |
|||
</rollingPolicy> |
|||
<encoder> |
|||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger - %msg%n</pattern> |
|||
</encoder> |
|||
</appender> |
|||
|
|||
<!-- Root logger: Log everything --> |
|||
<root level="INFO"> |
|||
<appender-ref ref="CONSOLE" /> |
|||
<appender-ref ref="FILE" /> |
|||
</root> |
|||
|
|||
</configuration> |
|||
11794
src/main/resources/static/bootstrap-5.3.2/css/bootstrap.min.css
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2212
src/main/resources/static/bootstrap-5.3.2/js/bootstrap.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,192 @@ |
|||
body { |
|||
margin: 0; |
|||
padding: 0; |
|||
font-family: Arial, sans-serif; |
|||
background: linear-gradient(45deg, #f6f7fb, #4ca3b3); |
|||
background-repeat: no-repeat; |
|||
} |
|||
|
|||
.form-title { |
|||
text-align: center; |
|||
margin-bottom: 20px; |
|||
font-size: 1.8rem; |
|||
color: #003366; |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
.header-row { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 20px; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.back-button { |
|||
background-color: white; |
|||
border: 2px solid black !important; |
|||
border-radius: 4px; |
|||
padding: 10px 20px; |
|||
border-radius: 5px; |
|||
font-size: 16px; |
|||
position: relative; /* override absolute */ |
|||
color: #005f73; |
|||
cursor: pointer; |
|||
transition: background-color 0.3s, transform 0.2s; |
|||
} |
|||
|
|||
.back-button:hover { |
|||
background: #4ca3b3; |
|||
transform: scale(1.05); |
|||
color: #000000; |
|||
} |
|||
|
|||
.back-to-home-btn { |
|||
background-color: white; |
|||
border: 2px solid black !important; |
|||
border-radius: 4px; |
|||
padding: 10px 20px; |
|||
border-radius: 5px; |
|||
font-size: 16px; |
|||
position: relative; /* override absolute */ |
|||
color: #005f73; |
|||
cursor: pointer; |
|||
transition: background-color 0.3s, transform 0.2s; |
|||
} |
|||
|
|||
.back-to-home-btn:hover { |
|||
background: #4ca3b3; |
|||
transform: scale(1.05); |
|||
color: #000000; |
|||
} |
|||
|
|||
.required { |
|||
color: red; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.container { |
|||
padding: 20px; |
|||
max-width: 1200px; |
|||
margin: 0 auto; |
|||
width: 100%; |
|||
} |
|||
|
|||
h2 { |
|||
color: #0B3954; |
|||
margin-bottom: 30px; |
|||
} |
|||
|
|||
.form-container { |
|||
background: white; |
|||
padding: 30px; |
|||
border-radius: 10px; |
|||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.form-row { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; |
|||
gap: 20px; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.form-group { |
|||
margin-bottom: 20px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.form-group label { |
|||
margin-bottom: 5px; |
|||
font-weight: bold; |
|||
color: #333; |
|||
} |
|||
|
|||
.form-control { |
|||
padding: 8px; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.file-input { |
|||
display: flex; |
|||
gap: 10px; |
|||
} |
|||
|
|||
.file-input button { |
|||
background: #f0f0f0; |
|||
border: none; |
|||
padding: 8px 15px; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.radio-group { |
|||
display: flex; |
|||
gap: 20px; |
|||
} |
|||
|
|||
.radio-option { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 5px; |
|||
} |
|||
|
|||
.submit-btn { |
|||
display: flex; |
|||
justify-content: center; |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.submit-btn input[type="submit"]:disabled { |
|||
background-color: #cccccc; /* grey color */ |
|||
color: #666666; |
|||
cursor: not-allowed; |
|||
} |
|||
|
|||
.submit-btn input[type="submit"] { |
|||
background-color: #005f73; |
|||
color: #fff; |
|||
font-size: 1rem; |
|||
border: none; |
|||
padding: 10px 20px; |
|||
border-radius: 4px; |
|||
cursor: pointer; |
|||
transition: background 0.3s ease; |
|||
} |
|||
|
|||
.submit-btn input[type="submit"]:hover { |
|||
background: #005f05; |
|||
} |
|||
/* Responsive Design for Tablets */ |
|||
@media ( max-width : 768px) { |
|||
.form-row { |
|||
grid-template-columns: 1fr; |
|||
} |
|||
.form-container { |
|||
padding: 20px; |
|||
} |
|||
.form-title { |
|||
font-size: 1.5rem; |
|||
} |
|||
.form-control { |
|||
font-size: 1rem; |
|||
} |
|||
} |
|||
|
|||
/* Responsive Design for Mobile */ |
|||
@media ( max-width : 480px) { |
|||
.form-row { |
|||
grid-template-columns: 1fr; |
|||
} |
|||
.submit-btn input[type="submit"] { |
|||
width: 100%; |
|||
font-size: 1.2rem; |
|||
padding: 12px; |
|||
} |
|||
.form-container { |
|||
padding: 15px; |
|||
} |
|||
.form-title { |
|||
font-size: 1.2rem; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
.btn-secondary { |
|||
background-color: white !important; |
|||
color: black !important; |
|||
border: 2px solid black !important; |
|||
padding: 5px 10px; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.btn-secondary:hover { |
|||
background-color: #6c757d !important; |
|||
color: white !important; |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
#custom-info { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
#custom-length { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 8px; /* Add spacing between dropdown and label */ |
|||
white-space: nowrap; /* Prevent wrapping */ |
|||
} |
|||
|
|||
.dataTables_length label { |
|||
display: flex; |
|||
align-items: center; |
|||
margin: 0; |
|||
gap: 5px; /* Adjust spacing between text and dropdown */ |
|||
} |
|||
|
|||
.dataTables_length select { |
|||
display: inline-block; |
|||
width: auto; /* Ensure dropdown adjusts to content */ |
|||
} |
|||
|
|||
#custom-pagination { |
|||
display: flex; |
|||
justify-content: flex-end; /* Align pagination to the right */ |
|||
align-items: center; |
|||
} |
|||
|
|||
.dataTables_filter { |
|||
display: none; |
|||
} |
|||
|
|||
/* Apply border-radius to the table */ |
|||
.det-table { |
|||
width: 125%; |
|||
border-collapse: separate; |
|||
border-spacing: 0; |
|||
border: 2px solid #f0f0f0; |
|||
margin-top: 20px; |
|||
font-family: Arial, sans-serif; |
|||
font-size: 14px; |
|||
table-layout: auto; |
|||
border-radius: 12px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.det-table th, .det-table td { |
|||
border: 1px solid #e0e0e0; |
|||
padding: 12px; |
|||
text-align: center; |
|||
} |
|||
|
|||
.det-table td.no-word-wrap { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.det-table th { |
|||
background-color: #005f73; |
|||
color: white; |
|||
text-align: center; |
|||
} |
|||
|
|||
.det-table tr:nth-child(even) { |
|||
background-color: #f9f9f9; |
|||
} |
|||
|
|||
.det-table tr:hover { |
|||
background-color: #f1f1f1; |
|||
} |
|||
|
|||
.det-table th, .det-table td { |
|||
text-align: center; |
|||
} |
|||
|
|||
.view-btn { |
|||
background-color: #005f73; |
|||
color: white; |
|||
padding: 5px 10px; |
|||
border: none; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.view-btn:hover { |
|||
background-color: #005f05; |
|||
} |
|||
|
|||
@media (max-width: 767.98px) { |
|||
.btn-group { |
|||
width: 100%; |
|||
justify-content: center; |
|||
} |
|||
.btn-group .btn { |
|||
width: 48%; /* make buttons fill container nicely */ |
|||
margin: 1px; |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
.header { |
|||
background-color: #005f73; |
|||
padding: 10px 20px; |
|||
display: flex; |
|||
align-items: center; |
|||
/* justify-content: space-between; */ |
|||
position: relative; |
|||
color: white; |
|||
} |
|||
|
|||
.header .logo-left img { |
|||
height: 60px; |
|||
width: 60px; |
|||
margin-right: 10px; |
|||
} |
|||
|
|||
.header .title { |
|||
text-align: center; |
|||
/* flex-grow: 1; */ |
|||
position: absolute; |
|||
transform: translateX(-50%); |
|||
left: 50% |
|||
} |
|||
|
|||
.header .title h2 { |
|||
margin: 0; |
|||
font-size: 1.5rem; |
|||
} |
|||
|
|||
.header .logos-right img { |
|||
height: 60px; |
|||
margin-left: 10px; |
|||
} |
|||
|
|||
.header .logo-left { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.header .logo-text { |
|||
display: flex; |
|||
flex-direction: column; |
|||
line-height: 1; |
|||
} |
|||
|
|||
.header .logo-text h2 { |
|||
margin: 0; |
|||
font-size: 0.8rem; |
|||
color: white; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.header .logo-text p { |
|||
margin: 0; |
|||
font-size: 0.5rem; |
|||
color: white; |
|||
} |
|||
|
|||
@media ( max-width : 480px) { |
|||
.header { |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
position: relative; |
|||
} |
|||
.header .logo-left img { |
|||
margin-bottom: 10px; |
|||
} |
|||
.header .logos-right img { |
|||
margin-bottom: 10px; |
|||
} |
|||
.header .title { |
|||
position: static; /* Reset absolute positioning */ |
|||
transform: none; /* Remove the translate effect */ |
|||
margin-top: 10px; |
|||
text-align: center; /* Ensure the text stays centered */ |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
.button-row { |
|||
display: flex; |
|||
justify-content: center; |
|||
gap: 40px; |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.stats { |
|||
color: #005f73; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.custom-button { |
|||
padding: 15px 30px; |
|||
background: white; |
|||
border: 1px solid #ccc; |
|||
border-radius: 10px; |
|||
font-size: 1rem; |
|||
color: #005f73; |
|||
cursor: pointer; |
|||
transition: background-color 0.3s, transform 0.2s; |
|||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.custom-button:hover { |
|||
background: #4ca3b3; |
|||
transform: scale(1.05); |
|||
color: #000000; |
|||
} |
|||
|
|||
.custom-button:active { |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
@media (max-width : 768px) { |
|||
.button-row { |
|||
flex-direction: column; |
|||
gap: 20px; |
|||
} |
|||
} |
|||
@ -0,0 +1,272 @@ |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 100; |
|||
src: url("/poppins-23.0/fonts/devanagari/poppins-v23-devanagari-700.woff2") format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 200; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-200.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 300; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-300.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-regular.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 500; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-500.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 600; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-600.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
src: url("../poppins-23.0/fonts/devanagari/poppins-v23-devanagari-700.woff2") |
|||
format("woff2"); |
|||
} |
|||
|
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 100; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-100.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 200; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-200.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 300; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-300.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-regular.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 500; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-500.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 600; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-600.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
src: url("../poppins-23.0/fonts/latin-ext/poppins-v23-latin-ext-700.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 100; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-100.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 200; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-200.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 300; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-300.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-regular.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 500; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-500.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 600; |
|||
src: url("../poppins-23.0/fonts/latin/poppins-v23-latin-600.woff2") |
|||
format("woff2"); |
|||
} |
|||
@font-face { |
|||
font-family: "Poppins"; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
src: url("/poppins-23.0/fonts/latin/poppins-v23-latin-700.woff2") |
|||
format("woff2"); |
|||
} |
|||
|
|||
* { |
|||
margin: 0; |
|||
border: 0; |
|||
padding: 0; |
|||
box-sizing: border-box; |
|||
font-family: "Poppins", sans-serif; |
|||
} |
|||
|
|||
body { |
|||
background: linear-gradient(45deg, #f6f7fb, #4ca3b3); |
|||
background-repeat: no-repeat; |
|||
min-height: 100vh; |
|||
min-width: 100vw; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100%; |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
div.container { |
|||
background: white; |
|||
min-width: 320px; |
|||
min-height: 33vh; |
|||
padding: 2rem; |
|||
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.2); |
|||
border-radius: 8px; |
|||
} |
|||
|
|||
div h2 { |
|||
font-weight: 600; |
|||
margin-bottom: 2rem; |
|||
position: relative; |
|||
} |
|||
|
|||
.container h3, |
|||
.container h4 { |
|||
text-align: center; |
|||
} |
|||
|
|||
div h2::before { |
|||
content: ""; |
|||
position: absolute; |
|||
height: 4px; |
|||
width: 25px; |
|||
bottom: 3px; |
|||
left: 0; |
|||
border-radius: 8px; |
|||
background: #005f73; |
|||
} |
|||
|
|||
form { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.input-field { |
|||
position: relative; |
|||
margin-bottom: 1.5rem; /* instead of targeting only first-child */ |
|||
} |
|||
|
|||
.input-field .underline::before { |
|||
content: ""; |
|||
position: absolute; |
|||
height: 1px; |
|||
width: 100%; |
|||
bottom: -5px; |
|||
left: 0; |
|||
background: rgba(0, 0, 0, 0.2); |
|||
} |
|||
|
|||
.input-field .underline::after { |
|||
content: ""; |
|||
position: absolute; |
|||
height: 1px; |
|||
width: 100%; |
|||
bottom: -5px; |
|||
left: 0; |
|||
background: linear-gradient(45deg, #8e2de2, #4a00e0); |
|||
transform: scaleX(0); |
|||
transition: all 0.3s ease-in-out; |
|||
transform-origin: left; |
|||
} |
|||
|
|||
.input-field input:focus ~ .underline::after { |
|||
transform: scaleX(1); |
|||
} |
|||
|
|||
.input-field input { |
|||
outline: none; |
|||
font-size: 0.9rem; |
|||
color: rgba(0, 0, 0, 0.7); |
|||
width: 100%; |
|||
} |
|||
|
|||
.input-field input::placeholder { |
|||
color: rgba(0, 0, 0, 0.5); |
|||
} |
|||
|
|||
form input[type="submit"] { |
|||
margin-top: 2rem; |
|||
padding: 0.4rem; |
|||
width: 100%; |
|||
background: #005f73; |
|||
cursor: pointer; |
|||
color: white; |
|||
font-size: 0.9rem; |
|||
font-weight: 300; |
|||
border-radius: 4px; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
form input[type="submit"]:hover { |
|||
letter-spacing: 0.5px; |
|||
background: #005f05; |
|||
} |
|||
|
|||
.small-logo { |
|||
width: 60px; |
|||
height: 60px; |
|||
display: block; |
|||
margin: 0 auto; /* Centers the image */ |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
.table-header { |
|||
background-color: #003366; |
|||
color: white; |
|||
} |
|||
|
|||
.table-bordered th, .table-bordered td { |
|||
border: 1px solid #003366; |
|||
} |
|||
|
|||
/* Make the cell a flex container so its contents are perfectly centered */ |
|||
.table-bordered td.status-cell { |
|||
display: flex; |
|||
align-items: center; /* vertical center */ |
|||
justify-content: center; /* horizontal center */ |
|||
padding: 8px; /* adjust if you want taller rows */ |
|||
vertical-align: middle; /* fallback */ |
|||
} |
|||
|
|||
.status-active, |
|||
.status-expired { |
|||
display: inline-flex; /* let the badge size to content */ |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 6px 12px; /* pill padding */ |
|||
border-radius: 20px; /* pill */ |
|||
font-size: 14px; |
|||
font-weight: 700; |
|||
line-height: 1; |
|||
min-height: 32px; /* ensures nice vertical size */ |
|||
margin: 0; /* remove margins that push it off-center */ |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.fas.fa-eye { |
|||
background-color: white; |
|||
color: black; |
|||
} |
|||
|
|||
.fas.fa-eye:hover { |
|||
color: #6c757d; |
|||
} |
|||
|
|||
.pdf-container { |
|||
width: 100%; |
|||
height: 80vh; /* Responsive height: 80% of viewport height */ |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
canvas { |
|||
width: 100% !important; /* Ensures canvas scales with container */ |
|||
height: auto !important; |
|||
} |
|||
|
|||
@media ( max-width : 768px) { |
|||
.responsive-text { |
|||
font-size: 0.9rem; |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
.table-header { |
|||
background-color: #003366; |
|||
color: white; |
|||
} |
|||
|
|||
.table-bordered th, .table-bordered td { |
|||
border: 1px solid #003366; |
|||
} |
|||
|
|||
/* Make the cell a flex container so its contents are perfectly centered */ |
|||
.table-bordered td.status-cell { |
|||
display: flex; |
|||
align-items: center; /* vertical center */ |
|||
justify-content: center; /* horizontal center */ |
|||
padding: 8px; /* adjust if you want taller rows */ |
|||
vertical-align: middle; /* fallback */ |
|||
} |
|||
|
|||
.status-active, |
|||
.status-expired { |
|||
display: inline-flex; /* let the badge size to content */ |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 6px 12px; /* pill padding */ |
|||
border-radius: 20px; /* pill */ |
|||
font-size: 14px; |
|||
font-weight: 700; |
|||
line-height: 1; |
|||
min-height: 32px; /* ensures nice vertical size */ |
|||
margin: 0; /* remove margins that push it off-center */ |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.pdf-container { |
|||
width: 100%; |
|||
height: 80vh; /* Responsive height: 80% of viewport height */ |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
/* Colors (use contrast-friendly text color) */ |
|||
.status-active { |
|||
background-color: #28a745; |
|||
color: black |
|||
} |
|||
|
|||
.status-expired { |
|||
background-color: #dc3545; |
|||
color: black |
|||
} |
|||
|
|||
canvas { |
|||
width: 100% !important; /* Ensures canvas scales with container */ |
|||
height: auto !important; |
|||
} |
|||
|
|||
@media ( max-width : 768px) { |
|||
.responsive-text { |
|||
font-size: 0.9rem; |
|||
} |
|||
} |
|||
@ -0,0 +1,532 @@ |
|||
:root { |
|||
--dt-row-selected: 13, 110, 253; |
|||
--dt-row-selected-text: 255, 255, 255; |
|||
--dt-row-selected-link: 9, 10, 11; |
|||
--dt-row-stripe: 0, 0, 0; |
|||
--dt-row-hover: 0, 0, 0; |
|||
--dt-column-ordering: 0, 0, 0; |
|||
--dt-html-background: white; |
|||
} |
|||
|
|||
:root.dark { |
|||
--dt-html-background: rgb(33, 37, 41); |
|||
} |
|||
|
|||
table.dataTable td.dt-control { |
|||
text-align: center; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
table.dataTable td.dt-control:before { |
|||
display: inline-block; |
|||
color: rgba(0, 0, 0, 0.5); |
|||
content: "►"; |
|||
} |
|||
|
|||
table.dataTable tr.dt-hasChild td.dt-control:before { |
|||
content: "▼"; |
|||
} |
|||
|
|||
html.dark table.dataTable td.dt-control:before { |
|||
color: rgba(255, 255, 255, 0.5); |
|||
} |
|||
|
|||
html.dark table.dataTable tr.dt-hasChild td.dt-control:before { |
|||
color: rgba(255, 255, 255, 0.5); |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting, |
|||
table.dataTable thead > tr > th.sorting_asc, |
|||
table.dataTable thead > tr > th.sorting_desc, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled, |
|||
table.dataTable thead > tr > th.sorting_desc_disabled, |
|||
table.dataTable thead > tr > td.sorting, |
|||
table.dataTable thead > tr > td.sorting_asc, |
|||
table.dataTable thead > tr > td.sorting_desc, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled { |
|||
cursor: pointer; |
|||
position: relative; |
|||
padding-right: 26px; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting:before, |
|||
table.dataTable thead > tr > th.sorting:after, |
|||
table.dataTable thead > tr > th.sorting_asc:before, |
|||
table.dataTable thead > tr > th.sorting_asc:after, |
|||
table.dataTable thead > tr > th.sorting_desc:before, |
|||
table.dataTable thead > tr > th.sorting_desc:after, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled:before, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled:after, |
|||
table.dataTable thead > tr > th.sorting_desc_disabled:before, |
|||
table.dataTable thead > tr > th.sorting_desc_disabled:after, |
|||
table.dataTable thead > tr > td.sorting:before, |
|||
table.dataTable thead > tr > td.sorting:after, |
|||
table.dataTable thead > tr > td.sorting_asc:before, |
|||
table.dataTable thead > tr > td.sorting_asc:after, |
|||
table.dataTable thead > tr > td.sorting_desc:before, |
|||
table.dataTable thead > tr > td.sorting_desc:after, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled:before, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled:after, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled:before, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled:after { |
|||
position: absolute; |
|||
display: block; |
|||
opacity: 0.125; |
|||
right: 10px; |
|||
line-height: 9px; |
|||
font-size: 0.8em; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting:before, |
|||
table.dataTable thead > tr > th.sorting_asc:before, |
|||
table.dataTable thead > tr > th.sorting_desc:before, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled:before, |
|||
table.dataTable thead > tr > th.sorting_desc_disabled:before, |
|||
table.dataTable thead > tr > td.sorting:before, |
|||
table.dataTable thead > tr > td.sorting_asc:before, |
|||
table.dataTable thead > tr > td.sorting_desc:before, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled:before, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled:before { |
|||
bottom: 50%; |
|||
content: "▲"; |
|||
content: "▲"/""; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting:after, |
|||
table.dataTable thead > tr > th.sorting_asc:after, |
|||
table.dataTable thead > tr > th.sorting_desc:after, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled:after, |
|||
table.dataTable thead > tr > th.sorting_desc_disabled:after, |
|||
table.dataTable thead > tr > td.sorting:after, |
|||
table.dataTable thead > tr > td.sorting_asc:after, |
|||
table.dataTable thead > tr > td.sorting_desc:after, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled:after, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled:after { |
|||
top: 50%; |
|||
content: "▼"; |
|||
content: "▼"/""; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting_asc:before, |
|||
table.dataTable thead > tr > th.sorting_desc:after, |
|||
table.dataTable thead > tr > td.sorting_asc:before, |
|||
table.dataTable thead > tr > td.sorting_desc:after { |
|||
opacity: 0.6; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting_desc_disabled:after, |
|||
table.dataTable thead > tr > th.sorting_asc_disabled:before, |
|||
table.dataTable thead > tr > td.sorting_desc_disabled:after, |
|||
table.dataTable thead > tr > td.sorting_asc_disabled:before { |
|||
display: none; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th:active, |
|||
table.dataTable thead > tr > td:active { |
|||
outline: none; |
|||
} |
|||
|
|||
div.dataTables_scrollBody > table.dataTable > thead > tr > th:before, |
|||
div.dataTables_scrollBody > table.dataTable > thead > tr > th:after, |
|||
div.dataTables_scrollBody > table.dataTable > thead > tr > td:before, |
|||
div.dataTables_scrollBody > table.dataTable > thead > tr > td:after { |
|||
display: none; |
|||
} |
|||
|
|||
div.dataTables_processing { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
width: 200px; |
|||
margin-left: -100px; |
|||
margin-top: -26px; |
|||
text-align: center; |
|||
padding: 2px; |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child { |
|||
position: relative; |
|||
width: 80px; |
|||
height: 15px; |
|||
margin: 1em auto; |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child > div { |
|||
position: absolute; |
|||
top: 0; |
|||
width: 13px; |
|||
height: 13px; |
|||
border-radius: 50%; |
|||
background: rgb(13, 110, 253); |
|||
background: rgb(var(--dt-row-selected)); |
|||
animation-timing-function: cubic-bezier(0, 1, 1, 0); |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child > div:nth-child(1) { |
|||
left: 8px; |
|||
animation: datatables-loader-1 0.6s infinite; |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child > div:nth-child(2) { |
|||
left: 8px; |
|||
animation: datatables-loader-2 0.6s infinite; |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child > div:nth-child(3) { |
|||
left: 32px; |
|||
animation: datatables-loader-2 0.6s infinite; |
|||
} |
|||
|
|||
div.dataTables_processing > div:last-child > div:nth-child(4) { |
|||
left: 56px; |
|||
animation: datatables-loader-3 0.6s infinite; |
|||
} |
|||
|
|||
@keyframes datatables-loader-1 { |
|||
0% { |
|||
transform: scale(0); |
|||
} |
|||
|
|||
100% { |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
@keyframes datatables-loader-3 { |
|||
0% { |
|||
transform: scale(1); |
|||
} |
|||
|
|||
100% { |
|||
transform: scale(0); |
|||
} |
|||
} |
|||
@keyframes datatables-loader-2 { |
|||
0% { |
|||
transform: translate(0, 0); |
|||
} |
|||
|
|||
100% { |
|||
transform: translate(24px, 0); |
|||
} |
|||
} |
|||
table.dataTable.nowrap th, |
|||
table.dataTable.nowrap td { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
table.dataTable th.dt-left, |
|||
table.dataTable td.dt-left { |
|||
text-align: left; |
|||
} |
|||
|
|||
table.dataTable th.dt-center, |
|||
table.dataTable td.dt-center, |
|||
table.dataTable td.dataTables_empty { |
|||
text-align: center; |
|||
} |
|||
|
|||
table.dataTable th.dt-right, |
|||
table.dataTable td.dt-right { |
|||
text-align: right; |
|||
} |
|||
|
|||
table.dataTable th.dt-justify, |
|||
table.dataTable td.dt-justify { |
|||
text-align: justify; |
|||
} |
|||
|
|||
table.dataTable th.dt-nowrap, |
|||
table.dataTable td.dt-nowrap { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
table.dataTable thead th, |
|||
table.dataTable thead td, |
|||
table.dataTable tfoot th, |
|||
table.dataTable tfoot td { |
|||
text-align: left; |
|||
} |
|||
|
|||
table.dataTable thead th.dt-head-left, |
|||
table.dataTable thead td.dt-head-left, |
|||
table.dataTable tfoot th.dt-head-left, |
|||
table.dataTable tfoot td.dt-head-left { |
|||
text-align: left; |
|||
} |
|||
|
|||
table.dataTable thead th.dt-head-center, |
|||
table.dataTable thead td.dt-head-center, |
|||
table.dataTable tfoot th.dt-head-center, |
|||
table.dataTable tfoot td.dt-head-center { |
|||
text-align: center; |
|||
} |
|||
|
|||
table.dataTable thead th.dt-head-right, |
|||
table.dataTable thead td.dt-head-right, |
|||
table.dataTable tfoot th.dt-head-right, |
|||
table.dataTable tfoot td.dt-head-right { |
|||
text-align: right; |
|||
} |
|||
|
|||
table.dataTable thead th.dt-head-justify, |
|||
table.dataTable thead td.dt-head-justify, |
|||
table.dataTable tfoot th.dt-head-justify, |
|||
table.dataTable tfoot td.dt-head-justify { |
|||
text-align: justify; |
|||
} |
|||
|
|||
table.dataTable thead th.dt-head-nowrap, |
|||
table.dataTable thead td.dt-head-nowrap, |
|||
table.dataTable tfoot th.dt-head-nowrap, |
|||
table.dataTable tfoot td.dt-head-nowrap { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
table.dataTable tbody th.dt-body-left, |
|||
table.dataTable tbody td.dt-body-left { |
|||
text-align: left; |
|||
} |
|||
|
|||
table.dataTable tbody th.dt-body-center, |
|||
table.dataTable tbody td.dt-body-center { |
|||
text-align: center; |
|||
} |
|||
|
|||
table.dataTable tbody th.dt-body-right, |
|||
table.dataTable tbody td.dt-body-right { |
|||
text-align: right; |
|||
} |
|||
|
|||
table.dataTable tbody th.dt-body-justify, |
|||
table.dataTable tbody td.dt-body-justify { |
|||
text-align: justify; |
|||
} |
|||
|
|||
table.dataTable tbody th.dt-body-nowrap, |
|||
table.dataTable tbody td.dt-body-nowrap { |
|||
white-space: nowrap; |
|||
} /*! Bootstrap 5 integration for DataTables |
|||
* |
|||
* ©2020 SpryMedia Ltd, all rights reserved. |
|||
* License: MIT datatables.net/license/mit |
|||
*/ |
|||
table.dataTable { |
|||
clear: both; |
|||
margin-top: 6px !important; |
|||
margin-bottom: 6px !important; |
|||
max-width: none !important; |
|||
border-collapse: separate !important; |
|||
border-spacing: 0; |
|||
} |
|||
|
|||
table.dataTable td, |
|||
table.dataTable th { |
|||
-webkit-box-sizing: content-box; |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
table.dataTable td.dataTables_empty, |
|||
table.dataTable th.dataTables_empty { |
|||
text-align: center; |
|||
} |
|||
|
|||
table.dataTable.nowrap th, |
|||
table.dataTable.nowrap td { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
table.dataTable.table-striped > tbody > tr:nth-of-type(2n + 1) > * { |
|||
box-shadow: none; |
|||
} |
|||
|
|||
table.dataTable > tbody > tr { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
table.dataTable > tbody > tr.selected > * { |
|||
box-shadow: inset 0 0 0 9999px rgb(13, 110, 253); |
|||
box-shadow: inset 0 0 0 9999px rgb(var(--dt-row-selected)); |
|||
color: rgb(255, 255, 255); |
|||
color: rgb(var(--dt-row-selected-text)); |
|||
} |
|||
|
|||
table.dataTable > tbody > tr.selected a { |
|||
color: rgb(9, 10, 11); |
|||
color: rgb(var(--dt-row-selected-link)); |
|||
} |
|||
|
|||
table.dataTable.table-striped > tbody > tr.odd > * { |
|||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.05); |
|||
} |
|||
|
|||
table.dataTable.table-striped > tbody > tr.odd.selected > * { |
|||
box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.95); |
|||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.95); |
|||
} |
|||
|
|||
table.dataTable.table-hover > tbody > tr:hover > * { |
|||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.075); |
|||
} |
|||
|
|||
table.dataTable.table-hover > tbody > tr.selected:hover > * { |
|||
box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.975); |
|||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975); |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_length label { |
|||
font-weight: normal; |
|||
text-align: left; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_length select { |
|||
width: auto; |
|||
display: inline-block; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_filter { |
|||
text-align: right; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_filter label { |
|||
font-weight: normal; |
|||
white-space: nowrap; |
|||
text-align: left; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_filter input { |
|||
margin-left: 0.5em; |
|||
display: inline-block; |
|||
width: auto; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_info { |
|||
padding-top: 0.85em; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_paginate { |
|||
margin: 0; |
|||
white-space: nowrap; |
|||
text-align: right; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_paginate ul.pagination { |
|||
margin: 2px 0; |
|||
white-space: nowrap; |
|||
justify-content: flex-end; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dt-row { |
|||
position: relative; |
|||
} |
|||
|
|||
div.dataTables_scrollHead table.dataTable { |
|||
margin-bottom: 0 !important; |
|||
} |
|||
|
|||
div.dataTables_scrollBody > table { |
|||
border-top: none; |
|||
margin-top: 0 !important; |
|||
margin-bottom: 0 !important; |
|||
} |
|||
|
|||
div.dataTables_scrollBody > table > thead .sorting:before, |
|||
div.dataTables_scrollBody > table > thead .sorting_asc:before, |
|||
div.dataTables_scrollBody > table > thead .sorting_desc:before, |
|||
div.dataTables_scrollBody > table > thead .sorting:after, |
|||
div.dataTables_scrollBody > table > thead .sorting_asc:after, |
|||
div.dataTables_scrollBody > table > thead .sorting_desc:after { |
|||
display: none; |
|||
} |
|||
|
|||
div.dataTables_scrollBody > table > tbody tr:first-child th, |
|||
div.dataTables_scrollBody > table > tbody tr:first-child td { |
|||
border-top: none; |
|||
} |
|||
|
|||
div.dataTables_scrollFoot > .dataTables_scrollFootInner { |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
div.dataTables_scrollFoot > .dataTables_scrollFootInner > table { |
|||
margin-top: 0 !important; |
|||
border-top: none; |
|||
} |
|||
|
|||
@media screen and (max-width: 767px) { |
|||
div.dataTables_wrapper div.dataTables_length, |
|||
div.dataTables_wrapper div.dataTables_filter, |
|||
div.dataTables_wrapper div.dataTables_info, |
|||
div.dataTables_wrapper div.dataTables_paginate { |
|||
text-align: center; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_paginate ul.pagination { |
|||
justify-content: center !important; |
|||
} |
|||
} |
|||
|
|||
table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) { |
|||
padding-right: 20px; |
|||
} |
|||
|
|||
table.table-bordered.dataTable { |
|||
border-right-width: 0; |
|||
} |
|||
|
|||
table.table-bordered.dataTable thead tr:first-child th, |
|||
table.table-bordered.dataTable thead tr:first-child td { |
|||
border-top-width: 1px; |
|||
} |
|||
|
|||
table.table-bordered.dataTable th, |
|||
table.table-bordered.dataTable td { |
|||
border-left-width: 0; |
|||
} |
|||
|
|||
table.table-bordered.dataTable th:first-child, |
|||
table.table-bordered.dataTable th:first-child, |
|||
table.table-bordered.dataTable td:first-child, |
|||
table.table-bordered.dataTable td:first-child { |
|||
border-left-width: 1px; |
|||
} |
|||
|
|||
table.table-bordered.dataTable th:last-child, |
|||
table.table-bordered.dataTable th:last-child, |
|||
table.table-bordered.dataTable td:last-child, |
|||
table.table-bordered.dataTable td:last-child { |
|||
border-right-width: 1px; |
|||
} |
|||
|
|||
table.table-bordered.dataTable th, |
|||
table.table-bordered.dataTable td { |
|||
border-bottom-width: 1px; |
|||
} |
|||
|
|||
div.dataTables_scrollHead table.table-bordered { |
|||
border-bottom-width: 0; |
|||
} |
|||
|
|||
div.table-responsive > div.dataTables_wrapper > div.row { |
|||
margin: 0; |
|||
} |
|||
|
|||
div.table-responsive |
|||
> div.dataTables_wrapper |
|||
> div.row |
|||
> div[class^="col-"]:first-child { |
|||
padding-left: 0; |
|||
} |
|||
|
|||
div.table-responsive |
|||
> div.dataTables_wrapper |
|||
> div.row |
|||
> div[class^="col-"]:last-child { |
|||
padding-right: 0; |
|||
} |
|||
|
|||
:root[data-bs-theme="dark"] { |
|||
--dt-row-hover: 255, 255, 255; |
|||
--dt-row-stripe: 255, 255, 255; |
|||
--dt-column-ordering: 255, 255, 255; |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
/*! DataTables Bootstrap 5 integration |
|||
* 2020 SpryMedia Ltd - datatables.net/license |
|||
*/ |
|||
! function(t) { |
|||
var n, r; |
|||
"function" == typeof define && define.amd ? define(["jquery", "datatables.net"], function(e) { |
|||
return t(e, window, document) |
|||
}) : "object" == typeof exports ? (n = require("jquery"), r = function(e, a) { |
|||
a.fn.dataTable || require("datatables.net")(e, a) |
|||
}, "undefined" == typeof window ? module.exports = function(e, a) { |
|||
return e = e || window, a = a || n(e), r(e, a), t(a, 0, e.document) |
|||
} : (r(window, n), module.exports = t(n, window, window.document))) : t(jQuery, window, document) |
|||
}(function(x, e, r, o) { |
|||
"use strict"; |
|||
var i = x.fn.dataTable; |
|||
return x.extend(!0, i.defaults, { |
|||
dom: "<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row dt-row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", |
|||
renderer: "bootstrap" |
|||
}), x.extend(i.ext.classes, { |
|||
sWrapper: "dataTables_wrapper dt-bootstrap5", |
|||
sFilterInput: "form-control form-control-sm", |
|||
sLengthSelect: "form-select form-select-sm", |
|||
sProcessing: "dataTables_processing card", |
|||
sPageButton: "paginate_button page-item" |
|||
}), i.ext.renderer.pageButton.bootstrap = function(d, e, s, a, l, c) { |
|||
function u(e, a) { |
|||
for (var t, n, r = function(e) { |
|||
e.preventDefault(), x(e.currentTarget).hasClass("disabled") || b.page() == e.data.action || b.page(e.data.action).draw("page") |
|||
}, o = 0, i = a.length; o < i; o++) |
|||
if (t = a[o], Array.isArray(t)) u(e, t); |
|||
else { |
|||
switch (f = p = "", t) { |
|||
case "ellipsis": |
|||
p = "…", f = "disabled"; |
|||
break; |
|||
case "first": |
|||
p = g.sFirst, f = t + (0 < l ? "" : " disabled"); |
|||
break; |
|||
case "previous": |
|||
p = g.sPrevious, f = t + (0 < l ? "" : " disabled"); |
|||
break; |
|||
case "next": |
|||
p = g.sNext, f = t + (l < c - 1 ? "" : " disabled"); |
|||
break; |
|||
case "last": |
|||
p = g.sLast, f = t + (l < c - 1 ? "" : " disabled"); |
|||
break; |
|||
default: |
|||
p = t + 1, f = l === t ? "active" : "" |
|||
} |
|||
p && (n = -1 !== f.indexOf("disabled"), n = x("<li>", { |
|||
class: m.sPageButton + " " + f, |
|||
id: 0 === s && "string" == typeof t ? d.sTableId + "_" + t : null |
|||
}).append(x("<a>", { |
|||
href: n ? null : "#", |
|||
"aria-controls": d.sTableId, |
|||
"aria-disabled": n ? "true" : null, |
|||
"aria-label": w[t], |
|||
role: "link", |
|||
"aria-current": "active" === f ? "page" : null, |
|||
"data-dt-idx": t, |
|||
tabindex: n ? -1 : d.iTabIndex, |
|||
class: "page-link" |
|||
}).html(p)).appendTo(e), d.oApi._fnBindAction(n, { |
|||
action: t |
|||
}, r)) |
|||
} |
|||
} |
|||
var p, f, t, b = new i.Api(d), |
|||
m = d.oClasses, |
|||
g = d.oLanguage.oPaginate, |
|||
w = d.oLanguage.oAria.paginate || {}, |
|||
e = x(e); |
|||
try { |
|||
t = e.find(r.activeElement).data("dt-idx") |
|||
} catch (e) { } |
|||
var n = e.children("ul.pagination"); |
|||
n.length ? n.empty() : n = e.html("<ul/>").children("ul").addClass("pagination"), u(n, a), t !== o && e.find("[data-dt-idx=" + t + "]").trigger("focus") |
|||
}, i |
|||
}); |
|||
2990
src/main/resources/static/datatables-1.13.6/js/jquery.dataTables.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,248 @@ |
|||
@keyframes dtb-spinner { |
|||
100% { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
@-o-keyframes dtb-spinner { |
|||
100% { |
|||
-o-transform: rotate(360deg); |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
@-ms-keyframes dtb-spinner { |
|||
100% { |
|||
-ms-transform: rotate(360deg); |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
@-webkit-keyframes dtb-spinner { |
|||
100% { |
|||
-webkit-transform: rotate(360deg); |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
@-moz-keyframes dtb-spinner { |
|||
100% { |
|||
-moz-transform: rotate(360deg); |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
div.dataTables_wrapper { |
|||
position: relative; |
|||
} |
|||
div.dt-buttons { |
|||
position: initial; |
|||
} |
|||
div.dt-buttons .dt-button { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
} |
|||
div.dt-button-info { |
|||
position: fixed; |
|||
top: 50%; |
|||
left: 50%; |
|||
width: 400px; |
|||
margin-top: -100px; |
|||
margin-left: -200px; |
|||
background-color: white; |
|||
border-radius: 0.75em; |
|||
box-shadow: 3px 4px 10px 1px rgba(0, 0, 0, 0.8); |
|||
text-align: center; |
|||
z-index: 2003; |
|||
overflow: hidden; |
|||
} |
|||
div.dt-button-info h2 { |
|||
padding: 2rem 2rem 1rem 2rem; |
|||
margin: 0; |
|||
font-weight: normal; |
|||
} |
|||
div.dt-button-info > div { |
|||
padding: 1em 2em 2em 2em; |
|||
} |
|||
div.dtb-popover-close { |
|||
position: absolute; |
|||
top: 6px; |
|||
right: 6px; |
|||
width: 22px; |
|||
height: 22px; |
|||
text-align: center; |
|||
border-radius: 3px; |
|||
cursor: pointer; |
|||
z-index: 2003; |
|||
} |
|||
button.dtb-hide-drop { |
|||
display: none !important; |
|||
} |
|||
div.dt-button-collection-title { |
|||
text-align: center; |
|||
padding: 0.3em 0 0.5em; |
|||
margin-left: 0.5em; |
|||
margin-right: 0.5em; |
|||
font-size: 0.9em; |
|||
} |
|||
div.dt-button-collection-title:empty { |
|||
display: none; |
|||
} |
|||
span.dt-button-spacer { |
|||
display: inline-block; |
|||
margin: 0.5em; |
|||
white-space: nowrap; |
|||
} |
|||
span.dt-button-spacer.bar { |
|||
border-left: 1px solid rgba(0, 0, 0, 0.3); |
|||
vertical-align: middle; |
|||
padding-left: 0.5em; |
|||
} |
|||
span.dt-button-spacer.bar:empty { |
|||
height: 1em; |
|||
width: 1px; |
|||
padding-left: 0; |
|||
} |
|||
div.dt-button-collection .dt-button-active { |
|||
padding-right: 3em; |
|||
} |
|||
div.dt-button-collection .dt-button-active:after { |
|||
position: absolute; |
|||
top: 50%; |
|||
margin-top: -10px; |
|||
right: 1em; |
|||
display: inline-block; |
|||
content: "✓"; |
|||
color: inherit; |
|||
} |
|||
div.dt-button-collection .dt-button-active.dt-button-split { |
|||
padding-right: 0; |
|||
} |
|||
div.dt-button-collection .dt-button-active.dt-button-split:after { |
|||
display: none; |
|||
} |
|||
div.dt-button-collection .dt-button-active.dt-button-split > *:first-child { |
|||
padding-right: 3em; |
|||
} |
|||
div.dt-button-collection |
|||
.dt-button-active.dt-button-split |
|||
> *:first-child:after { |
|||
position: absolute; |
|||
top: 50%; |
|||
margin-top: -10px; |
|||
right: 1em; |
|||
display: inline-block; |
|||
content: "✓"; |
|||
color: inherit; |
|||
} |
|||
div.dt-button-collection .dt-button-active-a a { |
|||
padding-right: 3em; |
|||
} |
|||
div.dt-button-collection .dt-button-active-a a:after { |
|||
position: absolute; |
|||
right: 1em; |
|||
display: inline-block; |
|||
content: "✓"; |
|||
color: inherit; |
|||
} |
|||
div.dt-button-collection span.dt-button-spacer { |
|||
width: 100%; |
|||
font-size: 0.9em; |
|||
text-align: center; |
|||
margin: 0.5em 0; |
|||
} |
|||
div.dt-button-collection span.dt-button-spacer:empty { |
|||
height: 0; |
|||
width: 100%; |
|||
} |
|||
div.dt-button-collection span.dt-button-spacer.bar { |
|||
border-left: none; |
|||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); |
|||
padding-left: 0; |
|||
} |
|||
html.dark div.dt-button-info { |
|||
background-color: var(--dt-html-background); |
|||
border: 1px solid rgba(255, 255, 255, 0.15); |
|||
} |
|||
div.dt-buttons div.btn-group { |
|||
position: initial; |
|||
} |
|||
div.dt-buttons div.dropdown-menu { |
|||
margin-top: 4px; |
|||
} |
|||
div.dt-buttons div.dropdown-menu .dt-button { |
|||
position: relative; |
|||
} |
|||
div.dt-buttons div.dropdown-menu div.dt-button-split { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
justify-content: flex-start; |
|||
align-content: flex-start; |
|||
align-items: stretch; |
|||
} |
|||
div.dt-buttons div.dropdown-menu div.dt-button-split a:first-child { |
|||
min-width: auto; |
|||
flex: 1 0 50px; |
|||
padding-right: 0; |
|||
} |
|||
div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child { |
|||
min-width: 33px; |
|||
flex: 0; |
|||
background: transparent; |
|||
border: none; |
|||
line-height: 1rem; |
|||
color: var(--bs-dropdown-link-color); |
|||
padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); |
|||
} |
|||
div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child:hover { |
|||
color: var(--bs-dropdown-link-hover-color); |
|||
background-color: var(--bs-dropdown-link-hover-bg); |
|||
} |
|||
div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child:after { |
|||
position: relative; |
|||
left: -3px; |
|||
} |
|||
div.dt-buttons span.dt-button-spacer.empty { |
|||
margin: 1px; |
|||
} |
|||
div.dt-buttons span.dt-button-spacer.bar:empty { |
|||
height: inherit; |
|||
} |
|||
div.dt-buttons .btn.processing { |
|||
color: rgba(0, 0, 0, 0.2); |
|||
} |
|||
div.dt-buttons .btn.processing:after { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
width: 16px; |
|||
height: 16px; |
|||
margin: -8px 0 0 -8px; |
|||
box-sizing: border-box; |
|||
display: block; |
|||
content: " "; |
|||
border: 2px solid rgb(40, 40, 40); |
|||
border-radius: 50%; |
|||
border-left-color: transparent; |
|||
border-right-color: transparent; |
|||
animation: dtb-spinner 1500ms infinite linear; |
|||
-o-animation: dtb-spinner 1500ms infinite linear; |
|||
-ms-animation: dtb-spinner 1500ms infinite linear; |
|||
-webkit-animation: dtb-spinner 1500ms infinite linear; |
|||
-moz-animation: dtb-spinner 1500ms infinite linear; |
|||
} |
|||
div.dt-button-background { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 999; |
|||
} |
|||
@media screen and (max-width: 767px) { |
|||
div.dt-buttons { |
|||
float: none; |
|||
width: 100%; |
|||
text-align: center; |
|||
margin-bottom: 0.5em; |
|||
} |
|||
div.dt-buttons a.btn { |
|||
float: none; |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
/*! Bootstrap integration for DataTables' Buttons |
|||
* © SpryMedia Ltd - datatables.net/license |
|||
*/ |
|||
! function(o) { |
|||
var e, a; |
|||
"function" == typeof define && define.amd ? define(["jquery", "datatables.net-bs5", "datatables.net-buttons"], function(t) { |
|||
return o(t, window, document) |
|||
}) : "object" == typeof exports ? (e = require("jquery"), a = function(t, n) { |
|||
n.fn.dataTable || require("datatables.net-bs5")(t, n), n.fn.dataTable.Buttons || require("datatables.net-buttons")(t, n) |
|||
}, "undefined" == typeof window ? module.exports = function(t, n) { |
|||
return t = t || window, n = n || e(t), a(t, n), o(n, 0, t.document) |
|||
} : (a(window, e), module.exports = o(e, window, window.document))) : o(jQuery, window, document) |
|||
}(function(o, t, n, e) { |
|||
"use strict"; |
|||
var a = o.fn.dataTable; |
|||
return o.extend(!0, a.Buttons.defaults, { |
|||
dom: { |
|||
container: { |
|||
className: "dt-buttons btn-group flex-wrap" |
|||
}, |
|||
button: { |
|||
className: "btn btn-secondary", |
|||
active: "active" |
|||
}, |
|||
collection: { |
|||
action: { |
|||
dropHtml: "" |
|||
}, |
|||
container: { |
|||
tag: "div", |
|||
className: "dropdown-menu dt-button-collection" |
|||
}, |
|||
closeButton: !1, |
|||
button: { |
|||
tag: "a", |
|||
className: "dt-button dropdown-item", |
|||
active: "dt-button-active", |
|||
disabled: "disabled", |
|||
spacer: { |
|||
className: "dropdown-divider", |
|||
tag: "hr" |
|||
} |
|||
} |
|||
}, |
|||
split: { |
|||
action: { |
|||
tag: "a", |
|||
className: "btn btn-secondary dt-button-split-drop-button", |
|||
closeButton: !1 |
|||
}, |
|||
dropdown: { |
|||
tag: "button", |
|||
dropHtml: "", |
|||
className: "btn btn-secondary dt-button-split-drop dropdown-toggle dropdown-toggle-split", |
|||
closeButton: !1, |
|||
align: "split-left", |
|||
splitAlignClass: "dt-button-split-left" |
|||
}, |
|||
wrapper: { |
|||
tag: "div", |
|||
className: "dt-button-split btn-group", |
|||
closeButton: !1 |
|||
} |
|||
} |
|||
}, |
|||
buttonCreated: function(t, n) { |
|||
return t.buttons ? o('<div class="btn-group"/>').append(n) : n |
|||
} |
|||
}), a.ext.buttons.collection.className += " dropdown-toggle", a.ext.buttons.collection.rightAlignClassName = "dropdown-menu-right", a |
|||
}); |
|||
538
src/main/resources/static/datatables-buttons-2.4.1/js/buttons.html5.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,79 @@ |
|||
/*! |
|||
* Print button for Buttons and DataTables. |
|||
* © SpryMedia Ltd - datatables.net/license |
|||
*/ |
|||
! function(n) { |
|||
var o, r; |
|||
"function" == typeof define && define.amd ? define(["jquery", "datatables.net", "datatables.net-buttons"], function(t) { |
|||
return n(t, window, document) |
|||
}) : "object" == typeof exports ? (o = require("jquery"), r = function(t, e) { |
|||
e.fn.dataTable || require("datatables.net")(t, e), e.fn.dataTable.Buttons || require("datatables.net-buttons")(t, e) |
|||
}, "undefined" == typeof window ? module.exports = function(t, e) { |
|||
return t = t || window, e = e || o(t), r(t, e), n(e, t, t.document) |
|||
} : (r(window, o), module.exports = n(o, window, window.document))) : n(jQuery, window, document) |
|||
}(function(m, b, t, p) { |
|||
"use strict"; |
|||
|
|||
function h(t) { |
|||
return n.href = t, -1 === (t = n.host).indexOf("/") && 0 !== n.pathname.indexOf("/") && (t += "/"), n.protocol + "//" + t + n.pathname + n.search |
|||
} |
|||
var e = m.fn.dataTable, |
|||
n = t.createElement("a"); |
|||
return e.ext.buttons.print = { |
|||
className: "buttons-print", |
|||
text: function(t) { |
|||
return t.i18n("buttons.print", "Print") |
|||
}, |
|||
action: function(t, e, n, o) { |
|||
function r(t, e) { |
|||
for (var n = "<tr>", o = 0, r = t.length; o < r; o++) { |
|||
var i = null === t[o] || t[o] === p ? "" : t[o]; |
|||
n += "<" + e + " " + (s[o] ? 'class="' + s[o] + '"' : "") + ">" + i + "</" + e + ">" |
|||
} |
|||
return n + "</tr>" |
|||
} |
|||
var i = e.buttons.exportData(m.extend({ |
|||
decodeEntities: !1 |
|||
}, o.exportOptions)), |
|||
a = e.buttons.exportInfo(o), |
|||
s = e.columns(o.exportOptions.columns).flatten().map(function(t) { |
|||
return e.settings()[0].aoColumns[e.column(t).index()].sClass |
|||
}).toArray(), |
|||
u = '<table class="' + e.table().node().className + '">'; |
|||
o.header && (u += "<thead>" + r(i.header, "th") + "</thead>"), u += "<tbody>"; |
|||
for (var d = 0, c = i.body.length; d < c; d++) u += r(i.body[d], "td"); |
|||
u += "</tbody>", o.footer && i.footer && (u += "<tfoot>" + r(i.footer, "th") + "</tfoot>"), u += "</table>"; |
|||
var l = b.open("", ""); |
|||
if (l) { |
|||
l.document.close(); |
|||
var f = "<title>" + a.title + "</title>"; |
|||
m("style, link").each(function() { |
|||
f += function(t) { |
|||
t = m(t).clone()[0]; |
|||
return "link" === t.nodeName.toLowerCase() && (t.href = h(t.href)), t.outerHTML |
|||
}(this) |
|||
}); |
|||
try { |
|||
l.document.head.innerHTML = f |
|||
} catch (t) { |
|||
m(l.document.head).html(f) |
|||
} |
|||
l.document.body.innerHTML = "<h1>" + a.title + "</h1><div>" + (a.messageTop || "") + "</div>" + u + "<div>" + (a.messageBottom || "") + "</div>", m(l.document.body).addClass("dt-print-view"), m("img", l.document.body).each(function(t, e) { |
|||
e.setAttribute("src", h(e.getAttribute("src"))) |
|||
}), o.customize && o.customize(l, o, e); |
|||
a = function() { |
|||
o.autoPrint && (l.print(), l.close()) |
|||
}; |
|||
navigator.userAgent.match(/Trident\/\d.\d/) ? a() : l.setTimeout(a, 1e3) |
|||
} else e.buttons.info(e.i18n("buttons.printErrorTitle", "Unable to open print view"), e.i18n("buttons.printErrorMsg", "Please allow popups in your browser for this site to be able to view the print view."), 5e3) |
|||
}, |
|||
title: "*", |
|||
messageTop: "*", |
|||
messageBottom: "*", |
|||
exportOptions: {}, |
|||
header: !0, |
|||
footer: !1, |
|||
autoPrint: !0, |
|||
customize: null |
|||
}, e |
|||
}); |
|||
@ -0,0 +1,764 @@ |
|||
/*! Buttons for DataTables 2.4.1 |
|||
* © SpryMedia Ltd - datatables.net/license |
|||
*/ |
|||
! function(e) { |
|||
var o, i; |
|||
"function" == typeof define && define.amd ? define(["jquery", "datatables.net"], function(t) { |
|||
return e(t, window, document) |
|||
}) : "object" == typeof exports ? (o = require("jquery"), i = function(t, n) { |
|||
n.fn.dataTable || require("datatables.net")(t, n) |
|||
}, "undefined" == typeof window ? module.exports = function(t, n) { |
|||
return t = t || window, n = n || o(t), i(t, n), e(n, t, t.document) |
|||
} : (i(window, o), module.exports = e(o, window, window.document))) : e(jQuery, window, document) |
|||
}(function(y, v, x, w) { |
|||
"use strict"; |
|||
var e = y.fn.dataTable, |
|||
o = 0, |
|||
C = 0, |
|||
_ = e.ext.buttons; |
|||
|
|||
function A(t, n, e) { |
|||
y.fn.animate ? t.stop().fadeIn(n, e) : (t.css("display", "block"), e && e.call(t)) |
|||
} |
|||
|
|||
function k(t, n, e) { |
|||
y.fn.animate ? t.stop().fadeOut(n, e) : (t.css("display", "none"), e && e.call(t)) |
|||
} |
|||
|
|||
function B(n, t) { |
|||
if (!(this instanceof B)) return function(t) { |
|||
return new B(t, n).container() |
|||
}; |
|||
!0 === (t = void 0 === t ? {} : t) && (t = {}), Array.isArray(t) && (t = { |
|||
buttons: t |
|||
}), this.c = y.extend(!0, {}, B.defaults, t), t.buttons && (this.c.buttons = t.buttons), this.s = { |
|||
dt: new e.Api(n), |
|||
buttons: [], |
|||
listenKeys: "", |
|||
namespace: "dtb" + o++ |
|||
}, this.dom = { |
|||
container: y("<" + this.c.dom.container.tag + "/>").addClass(this.c.dom.container.className) |
|||
}, this._constructor() |
|||
} |
|||
y.extend(B.prototype, { |
|||
action: function(t, n) { |
|||
t = this._nodeToButton(t); |
|||
return n === w ? t.conf.action : (t.conf.action = n, this) |
|||
}, |
|||
active: function(t, n) { |
|||
var t = this._nodeToButton(t), |
|||
e = this.c.dom.button.active, |
|||
o = y(t.node); |
|||
return t.inCollection && this.c.dom.collection.button && this.c.dom.collection.button.active !== w && (e = this.c.dom.collection.button.active), n === w ? o.hasClass(e) : (o.toggleClass(e, n === w || n), this) |
|||
}, |
|||
add: function(t, n, e) { |
|||
var o = this.s.buttons; |
|||
if ("string" == typeof n) { |
|||
for (var i = n.split("-"), s = this.s, a = 0, r = i.length - 1; a < r; a++) s = s.buttons[+i[a]]; |
|||
o = s.buttons, n = +i[i.length - 1] |
|||
} |
|||
return this._expandButton(o, t, t !== w ? t.split : w, (t === w || t.split === w || 0 === t.split.length) && s !== w, !1, n), e !== w && !0 !== e || this._draw(), this |
|||
}, |
|||
collectionRebuild: function(t, n) { |
|||
var e = this._nodeToButton(t); |
|||
if (n !== w) { |
|||
for (var o = e.buttons.length - 1; 0 <= o; o--) this.remove(e.buttons[o].node); |
|||
for (e.conf.prefixButtons && n.unshift.apply(n, e.conf.prefixButtons), e.conf.postfixButtons && n.push.apply(n, e.conf.postfixButtons), o = 0; o < n.length; o++) { |
|||
var i = n[o]; |
|||
this._expandButton(e.buttons, i, i !== w && i.config !== w && i.config.split !== w, !0, i.parentConf !== w && i.parentConf.split !== w, null, i.parentConf) |
|||
} |
|||
} |
|||
this._draw(e.collection, e.buttons) |
|||
}, |
|||
container: function() { |
|||
return this.dom.container |
|||
}, |
|||
disable: function(t) { |
|||
t = this._nodeToButton(t); |
|||
return y(t.node).addClass(this.c.dom.button.disabled).prop("disabled", !0), this |
|||
}, |
|||
destroy: function() { |
|||
y("body").off("keyup." + this.s.namespace); |
|||
for (var t = this.s.buttons.slice(), n = 0, e = t.length; n < e; n++) this.remove(t[n].node); |
|||
this.dom.container.remove(); |
|||
var o = this.s.dt.settings()[0]; |
|||
for (n = 0, e = o.length; n < e; n++) |
|||
if (o.inst === this) { |
|||
o.splice(n, 1); |
|||
break |
|||
} return this |
|||
}, |
|||
enable: function(t, n) { |
|||
return !1 === n ? this.disable(t) : (n = this._nodeToButton(t), y(n.node).removeClass(this.c.dom.button.disabled).prop("disabled", !1), this) |
|||
}, |
|||
index: function(t, n, e) { |
|||
n || (n = "", e = this.s.buttons); |
|||
for (var o = 0, i = e.length; o < i; o++) { |
|||
var s = e[o].buttons; |
|||
if (e[o].node === t) return n + o; |
|||
if (s && s.length) { |
|||
s = this.index(t, o + "-", s); |
|||
if (null !== s) return s |
|||
} |
|||
} |
|||
return null |
|||
}, |
|||
name: function() { |
|||
return this.c.name |
|||
}, |
|||
node: function(t) { |
|||
return t ? (t = this._nodeToButton(t), y(t.node)) : this.dom.container |
|||
}, |
|||
processing: function(t, n) { |
|||
var e = this.s.dt, |
|||
o = this._nodeToButton(t); |
|||
return n === w ? y(o.node).hasClass("processing") : (y(o.node).toggleClass("processing", n), y(e.table().node()).triggerHandler("buttons-processing.dt", [n, e.button(t), e, y(t), o.conf]), this) |
|||
}, |
|||
remove: function(t) { |
|||
var n = this._nodeToButton(t), |
|||
e = this._nodeToHost(t), |
|||
o = this.s.dt; |
|||
if (n.buttons.length) |
|||
for (var i = n.buttons.length - 1; 0 <= i; i--) this.remove(n.buttons[i].node); |
|||
n.conf.destroying = !0, n.conf.destroy && n.conf.destroy.call(o.button(t), o, y(t), n.conf), this._removeKey(n.conf), y(n.node).remove(); |
|||
o = y.inArray(n, e); |
|||
return e.splice(o, 1), this |
|||
}, |
|||
text: function(t, n) { |
|||
function e(t) { |
|||
return "function" == typeof t ? t(i, s, o.conf) : t |
|||
} |
|||
var o = this._nodeToButton(t), |
|||
t = o.textNode, |
|||
i = this.s.dt, |
|||
s = y(o.node); |
|||
return n === w ? e(o.conf.text) : (o.conf.text = n, t.html(e(n)), this) |
|||
}, |
|||
_constructor: function() { |
|||
var e = this, |
|||
t = this.s.dt, |
|||
o = t.settings()[0], |
|||
n = this.c.buttons; |
|||
o._buttons || (o._buttons = []), o._buttons.push({ |
|||
inst: this, |
|||
name: this.c.name |
|||
}); |
|||
for (var i = 0, s = n.length; i < s; i++) this.add(n[i]); |
|||
t.on("destroy", function(t, n) { |
|||
n === o && e.destroy() |
|||
}), y("body").on("keyup." + this.s.namespace, function(t) { |
|||
var n; |
|||
x.activeElement && x.activeElement !== x.body || (n = String.fromCharCode(t.keyCode).toLowerCase(), -1 !== e.s.listenKeys.toLowerCase().indexOf(n) && e._keypress(n, t)) |
|||
}) |
|||
}, |
|||
_addKey: function(t) { |
|||
t.key && (this.s.listenKeys += (y.isPlainObject(t.key) ? t.key : t).key) |
|||
}, |
|||
_draw: function(t, n) { |
|||
t || (t = this.dom.container, n = this.s.buttons), t.children().detach(); |
|||
for (var e = 0, o = n.length; e < o; e++) t.append(n[e].inserter), t.append(" "), n[e].buttons && n[e].buttons.length && this._draw(n[e].collection, n[e].buttons) |
|||
}, |
|||
_expandButton: function(t, n, e, o, i, s, a) { |
|||
for (var r, l = this.s.dt, c = this.c.dom.collection, u = Array.isArray(n) ? n : [n], d = 0, f = (u = n === w ? Array.isArray(e) ? e : [e] : u).length; d < f; d++) { |
|||
var p = this._resolveExtends(u[d]); |
|||
if (p) |
|||
if (r = !(!p.config || !p.config.split), Array.isArray(p)) this._expandButton(t, p, h !== w && h.conf !== w ? h.conf.split : w, o, a !== w && a.split !== w, s, a); |
|||
else { |
|||
var h = this._buildButton(p, o, p.split !== w || p.config !== w && p.config.split !== w, i); |
|||
if (h) { |
|||
if (s !== w && null !== s ? (t.splice(s, 0, h), s++) : t.push(h), h.conf.buttons && (h.collection = y("<" + c.container.content.tag + "/>"), h.conf._collection = h.collection, y(h.node).append(c.action.dropHtml), this._expandButton(h.buttons, h.conf.buttons, h.conf.split, !r, r, s, h.conf)), h.conf.split) { |
|||
h.collection = y("<" + c.container.tag + "/>"), h.conf._collection = h.collection; |
|||
for (var b = 0; b < h.conf.split.length; b++) { |
|||
var g = h.conf.split[b]; |
|||
"object" == typeof g && (g.parent = a, g.collectionLayout === w && (g.collectionLayout = h.conf.collectionLayout), g.dropup === w && (g.dropup = h.conf.dropup), g.fade === w) && (g.fade = h.conf.fade) |
|||
} |
|||
this._expandButton(h.buttons, h.conf.buttons, h.conf.split, !r, r, s, h.conf) |
|||
} |
|||
h.conf.parent = a, p.init && p.init.call(l.button(h.node), l, y(h.node), p) |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
_buildButton: function(n, t, e, o) { |
|||
function i(t) { |
|||
return "function" == typeof t ? t(u, l, n) : t |
|||
} |
|||
var s, a, r, l, c = this.c.dom, |
|||
u = this.s.dt, |
|||
d = y.extend(!0, {}, c.button); |
|||
if (t && e && c.collection.split ? y.extend(!0, d, c.collection.split.action) : o || t ? y.extend(!0, d, c.collection.button) : e && y.extend(!0, d, c.split.button), n.spacer) return c = y("<" + d.spacer.tag + "/>").addClass("dt-button-spacer " + n.style + " " + d.spacer.className).html(i(n.text)), { |
|||
conf: n, |
|||
node: c, |
|||
inserter: c, |
|||
buttons: [], |
|||
inCollection: t, |
|||
isSplit: e, |
|||
collection: null, |
|||
textNode: c |
|||
}; |
|||
if (n.available && !n.available(u, n) && !n.hasOwnProperty("html")) return !1; |
|||
n.hasOwnProperty("html") ? l = y(n.html) : (a = function(t, n, e, o) { |
|||
o.action.call(n.button(e), t, n, e, o), y(n.table().node()).triggerHandler("buttons-action.dt", [n.button(e), n, e, o]) |
|||
}, c = n.tag || d.tag, r = n.clickBlurs === w || n.clickBlurs, l = y("<" + c + "/>").addClass(d.className).attr("tabindex", this.s.dt.settings()[0].iTabIndex).attr("aria-controls", this.s.dt.table().node().id).on("click.dtb", function(t) { |
|||
t.preventDefault(), !l.hasClass(d.disabled) && n.action && a(t, u, l, n), r && l.trigger("blur") |
|||
}).on("keypress.dtb", function(t) { |
|||
13 === t.keyCode && (t.preventDefault(), !l.hasClass(d.disabled)) && n.action && a(t, u, l, n) |
|||
}), "a" === c.toLowerCase() && l.attr("href", "#"), "button" === c.toLowerCase() && l.attr("type", "button"), s = d.liner.tag ? (c = y("<" + d.liner.tag + "/>").html(i(n.text)).addClass(d.liner.className), "a" === d.liner.tag.toLowerCase() && c.attr("href", "#"), l.append(c), c) : (l.html(i(n.text)), l), !1 === n.enabled && l.addClass(d.disabled), n.className && l.addClass(n.className), n.titleAttr && l.attr("title", i(n.titleAttr)), n.attr && l.attr(n.attr), n.namespace || (n.namespace = ".dt-button-" + C++), n.config !== w && n.config.split && (n.split = n.config.split)); |
|||
var f, p, h, b, g, m, c = this.c.dom.buttonContainer, |
|||
c = c && c.tag ? y("<" + c.tag + "/>").addClass(c.className).append(l) : l; |
|||
return this._addKey(n), this.c.buttonCreated && (c = this.c.buttonCreated(n, c)), e && (p = (f = t ? y.extend(!0, this.c.dom.split, this.c.dom.collection.split) : this.c.dom.split).wrapper, h = y("<" + p.tag + "/>").addClass(p.className).append(l), b = y.extend(n, { |
|||
align: f.dropdown.align, |
|||
attr: { |
|||
"aria-haspopup": "dialog", |
|||
"aria-expanded": !1 |
|||
}, |
|||
className: f.dropdown.className, |
|||
closeButton: !1, |
|||
splitAlignClass: f.dropdown.splitAlignClass, |
|||
text: f.dropdown.text |
|||
}), this._addKey(b), g = function(t, n, e, o) { |
|||
_.split.action.call(n.button(h), t, n, e, o), y(n.table().node()).triggerHandler("buttons-action.dt", [n.button(e), n, e, o]), e.attr("aria-expanded", !0) |
|||
}, m = y('<button class="' + f.dropdown.className + ' dt-button"></button>').html(f.dropdown.dropHtml).on("click.dtb", function(t) { |
|||
t.preventDefault(), t.stopPropagation(), m.hasClass(d.disabled) || g(t, u, m, b), r && m.trigger("blur") |
|||
}).on("keypress.dtb", function(t) { |
|||
13 === t.keyCode && (t.preventDefault(), m.hasClass(d.disabled) || g(t, u, m, b)) |
|||
}), 0 === n.split.length && m.addClass("dtb-hide-drop"), h.append(m).attr(b.attr)), { |
|||
conf: n, |
|||
node: (e ? h : l).get(0), |
|||
inserter: e ? h : c, |
|||
buttons: [], |
|||
inCollection: t, |
|||
isSplit: e, |
|||
inSplit: o, |
|||
collection: null, |
|||
textNode: s |
|||
} |
|||
}, |
|||
_nodeToButton: function(t, n) { |
|||
for (var e = 0, o = (n = n || this.s.buttons).length; e < o; e++) { |
|||
if (n[e].node === t) return n[e]; |
|||
if (n[e].buttons.length) { |
|||
var i = this._nodeToButton(t, n[e].buttons); |
|||
if (i) return i |
|||
} |
|||
} |
|||
}, |
|||
_nodeToHost: function(t, n) { |
|||
for (var e = 0, o = (n = n || this.s.buttons).length; e < o; e++) { |
|||
if (n[e].node === t) return n; |
|||
if (n[e].buttons.length) { |
|||
var i = this._nodeToHost(t, n[e].buttons); |
|||
if (i) return i |
|||
} |
|||
} |
|||
}, |
|||
_keypress: function(s, a) { |
|||
var r; |
|||
a._buttonsHandled || (r = function(t) { |
|||
for (var n, e, o = 0, i = t.length; o < i; o++) n = t[o].conf, e = t[o].node, !n.key || n.key !== s && (!y.isPlainObject(n.key) || n.key.key !== s || n.key.shiftKey && !a.shiftKey || n.key.altKey && !a.altKey || n.key.ctrlKey && !a.ctrlKey || n.key.metaKey && !a.metaKey) || (a._buttonsHandled = !0, y(e).click()), t[o].buttons.length && r(t[o].buttons) |
|||
})(this.s.buttons) |
|||
}, |
|||
_removeKey: function(t) { |
|||
var n; |
|||
t.key && (t = (y.isPlainObject(t.key) ? t.key : t).key, n = this.s.listenKeys.split(""), t = y.inArray(t, n), n.splice(t, 1), this.s.listenKeys = n.join("")) |
|||
}, |
|||
_resolveExtends: function(e) { |
|||
function t(t) { |
|||
for (var n = 0; !y.isPlainObject(t) && !Array.isArray(t);) { |
|||
if (t === w) return; |
|||
if ("function" == typeof t) { |
|||
if (!(t = t.call(i, s, e))) return !1 |
|||
} else if ("string" == typeof t) { |
|||
if (!_[t]) return { |
|||
html: t |
|||
}; |
|||
t = _[t] |
|||
} |
|||
if (30 < ++n) throw "Buttons: Too many iterations" |
|||
} |
|||
return Array.isArray(t) ? t : y.extend({}, t) |
|||
} |
|||
var n, o, i = this, |
|||
s = this.s.dt; |
|||
for (e = t(e); e && e.extend;) { |
|||
if (!_[e.extend]) throw "Cannot extend unknown button type: " + e.extend; |
|||
var a = t(_[e.extend]); |
|||
if (Array.isArray(a)) return a; |
|||
if (!a) return !1; |
|||
var r = a.className; |
|||
e.config !== w && a.config !== w && (e.config = y.extend({}, a.config, e.config)), e = y.extend({}, a, e), r && e.className !== r && (e.className = r + " " + e.className), e.extend = a.extend |
|||
} |
|||
var l = e.postfixButtons; |
|||
if (l) |
|||
for (e.buttons || (e.buttons = []), n = 0, o = l.length; n < o; n++) e.buttons.push(l[n]); |
|||
var c = e.prefixButtons; |
|||
if (c) |
|||
for (e.buttons || (e.buttons = []), n = 0, o = c.length; n < o; n++) e.buttons.splice(n, 0, c[n]); |
|||
return e |
|||
}, |
|||
_popover: function(o, t, n, e) { |
|||
function i() { |
|||
h = !0, k(y(g), b.fade, function() { |
|||
y(this).detach() |
|||
}), y(f.buttons('[aria-haspopup="dialog"][aria-expanded="true"]').nodes()).attr("aria-expanded", "false"), y("div.dt-button-background").off("click.dtb-collection"), B.background(!1, b.backgroundClassName, b.fade, m), y(v).off("resize.resize.dtb-collection"), y("body").off(".dtb-collection"), f.off("buttons-action.b-internal"), f.off("destroy") |
|||
} |
|||
var s, a, r, l, c, u, d, f = t, |
|||
p = this.c, |
|||
h = !1, |
|||
b = y.extend({ |
|||
align: "button-left", |
|||
autoClose: !1, |
|||
background: !0, |
|||
backgroundClassName: "dt-button-background", |
|||
closeButton: !0, |
|||
containerClassName: p.dom.collection.container.className, |
|||
contentClassName: p.dom.collection.container.content.className, |
|||
collectionLayout: "", |
|||
collectionTitle: "", |
|||
dropup: !1, |
|||
fade: 400, |
|||
popoverTitle: "", |
|||
rightAlignClassName: "dt-button-right", |
|||
tag: p.dom.collection.container.tag |
|||
}, n), |
|||
g = b.tag + "." + b.containerClassName.replace(/ /g, "."), |
|||
m = t.node(); |
|||
!1 === o ? i() : ((p = y(f.buttons('[aria-haspopup="dialog"][aria-expanded="true"]').nodes())).length && (m.closest(g).length && (m = p.eq(0)), i()), n = y(".dt-button", o).length, p = "", 3 === n ? p = "dtb-b3" : 2 === n ? p = "dtb-b2" : 1 === n && (p = "dtb-b1"), s = y("<" + b.tag + "/>").addClass(b.containerClassName).addClass(b.collectionLayout).addClass(b.splitAlignClass).addClass(p).css("display", "none").attr({ |
|||
"aria-modal": !0, |
|||
role: "dialog" |
|||
}), o = y(o).addClass(b.contentClassName).attr("role", "menu").appendTo(s), m.attr("aria-expanded", "true"), m.parents("body")[0] !== x.body && (m = x.body.lastChild), b.popoverTitle ? s.prepend('<div class="dt-button-collection-title">' + b.popoverTitle + "</div>") : b.collectionTitle && s.prepend('<div class="dt-button-collection-title">' + b.collectionTitle + "</div>"), b.closeButton && s.prepend('<div class="dtb-popover-close">×</div>').addClass("dtb-collection-closeable"), A(s.insertAfter(m), b.fade), n = y(t.table().container()), d = s.css("position"), "container" !== b.span && "dt-container" !== b.align || (m = m.parent(), s.css("width", n.width())), "absolute" === d ? (p = y(m[0].offsetParent), t = m.position(), n = m.offset(), a = p.offset(), r = p.position(), l = v.getComputedStyle(p[0]), a.height = p.outerHeight(), a.width = p.width() + parseFloat(l.paddingLeft), a.right = a.left + a.width, a.bottom = a.top + a.height, p = t.top + m.outerHeight(), c = t.left, s.css({ |
|||
top: p, |
|||
left: c |
|||
}), l = v.getComputedStyle(s[0]), (u = s.offset()).height = s.outerHeight(), u.width = s.outerWidth(), u.right = u.left + u.width, u.bottom = u.top + u.height, u.marginTop = parseFloat(l.marginTop), u.marginBottom = parseFloat(l.marginBottom), b.dropup && (p = t.top - u.height - u.marginTop - u.marginBottom), "button-right" !== b.align && !s.hasClass(b.rightAlignClassName) || (c = t.left - u.width + m.outerWidth()), "dt-container" !== b.align && "container" !== b.align || (c = c < t.left ? -t.left : c) + u.width > a.width && (c = a.width - u.width), r.left + c + u.width > y(v).width() && (c = y(v).width() - u.width - r.left), n.left + c < 0 && (c = -n.left), r.top + p + u.height > y(v).height() + y(v).scrollTop() && (p = t.top - u.height - u.marginTop - u.marginBottom), r.top + p < y(v).scrollTop() && (p = t.top + m.outerHeight()), s.css({ |
|||
top: p, |
|||
left: c |
|||
})) : ((d = function() { |
|||
var t = y(v).height() / 2, |
|||
n = s.height() / 2; |
|||
s.css("marginTop", -1 * (n = t < n ? t : n)) |
|||
})(), y(v).on("resize.dtb-collection", function() { |
|||
d() |
|||
})), b.background && B.background(!0, b.backgroundClassName, b.fade, b.backgroundHost || m), y("div.dt-button-background").on("click.dtb-collection", function() { }), b.autoClose && setTimeout(function() { |
|||
f.on("buttons-action.b-internal", function(t, n, e, o) { |
|||
o[0] !== m[0] && i() |
|||
}) |
|||
}, 0), y(s).trigger("buttons-popover.dt"), f.on("destroy", i), setTimeout(function() { |
|||
h = !1, y("body").on("click.dtb-collection", function(t) { |
|||
var n, e; |
|||
!h && (n = y.fn.addBack ? "addBack" : "andSelf", e = y(t.target).parent()[0], !y(t.target).parents()[n]().filter(o).length && !y(e).hasClass("dt-buttons") || y(t.target).hasClass("dt-button-background")) && i() |
|||
}).on("keyup.dtb-collection", function(t) { |
|||
27 === t.keyCode && i() |
|||
}).on("keydown.dtb-collection", function(t) { |
|||
var n = y("a, button", o), |
|||
e = x.activeElement; |
|||
9 === t.keyCode && (-1 === n.index(e) ? (n.first().focus(), t.preventDefault()) : t.shiftKey ? e === n[0] && (n.last().focus(), t.preventDefault()) : e === n.last()[0] && (n.first().focus(), t.preventDefault())) |
|||
}) |
|||
}, 0)) |
|||
} |
|||
}), B.background = function(t, n, e, o) { |
|||
e === w && (e = 400), o = o || x.body, t ? A(y("<div/>").addClass(n).css("display", "none").insertAfter(o), e) : k(y("div." + n), e, function() { |
|||
y(this).removeClass(n).remove() |
|||
}) |
|||
}, B.instanceSelector = function(t, i) { |
|||
var s, a, r; |
|||
return t === w || null === t ? y.map(i, function(t) { |
|||
return t.inst |
|||
}) : (s = [], a = y.map(i, function(t) { |
|||
return t.name |
|||
}), (r = function(t) { |
|||
var n; |
|||
if (Array.isArray(t)) |
|||
for (var e = 0, o = t.length; e < o; e++) r(t[e]); |
|||
else "string" == typeof t ? -1 !== t.indexOf(",") ? r(t.split(",")) : -1 !== (n = y.inArray(t.trim(), a)) && s.push(i[n].inst) : "number" == typeof t ? s.push(i[t].inst) : "object" == typeof t && s.push(t) |
|||
})(t), s) |
|||
}, B.buttonSelector = function(t, n) { |
|||
for (var c = [], u = function(t, n, e) { |
|||
for (var o, i, s = 0, a = n.length; s < a; s++)(o = n[s]) && (t.push({ |
|||
node: o.node, |
|||
name: o.conf.name, |
|||
idx: i = e !== w ? e + s : s + "" |
|||
}), o.buttons) && u(t, o.buttons, i + "-") |
|||
}, d = function(t, n) { |
|||
var e = [], |
|||
o = (u(e, n.s.buttons), y.map(e, function(t) { |
|||
return t.node |
|||
})); |
|||
if (Array.isArray(t) || t instanceof y) |
|||
for (s = 0, a = t.length; s < a; s++) d(t[s], n); |
|||
else if (null === t || t === w || "*" === t) |
|||
for (s = 0, a = e.length; s < a; s++) c.push({ |
|||
inst: n, |
|||
node: e[s].node |
|||
}); |
|||
else if ("number" == typeof t) n.s.buttons[t] && c.push({ |
|||
inst: n, |
|||
node: n.s.buttons[t].node |
|||
}); |
|||
else if ("string" == typeof t) |
|||
if (-1 !== t.indexOf(",")) |
|||
for (var i = t.split(","), s = 0, a = i.length; s < a; s++) d(i[s].trim(), n); |
|||
else if (t.match(/^\d+(\-\d+)*$/)) { |
|||
var r = y.map(e, function(t) { |
|||
return t.idx |
|||
}); |
|||
c.push({ |
|||
inst: n, |
|||
node: e[y.inArray(t, r)].node |
|||
}) |
|||
} else if (-1 !== t.indexOf(":name")) { |
|||
var l = t.replace(":name", ""); |
|||
for (s = 0, a = e.length; s < a; s++) e[s].name === l && c.push({ |
|||
inst: n, |
|||
node: e[s].node |
|||
}) |
|||
} else y(o).filter(t).each(function() { |
|||
c.push({ |
|||
inst: n, |
|||
node: this |
|||
}) |
|||
}); |
|||
else "object" == typeof t && t.nodeName && -1 !== (r = y.inArray(t, o)) && c.push({ |
|||
inst: n, |
|||
node: o[r] |
|||
}) |
|||
}, e = 0, o = t.length; e < o; e++) { |
|||
var i = t[e]; |
|||
d(n, i) |
|||
} |
|||
return c |
|||
}, B.stripData = function(t, n) { |
|||
return "string" == typeof t && (t = (t = t.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")).replace(/<!\-\-.*?\-\->/g, ""), n && !n.stripHtml || (t = t.replace(/<[^>]*>/g, "")), n && !n.trim || (t = t.replace(/^\s+|\s+$/g, "")), n && !n.stripNewlines || (t = t.replace(/\n/g, " ")), !n || n.decodeEntities) && (l.innerHTML = t, t = l.value), t |
|||
}, B.defaults = { |
|||
buttons: ["copy", "excel", "csv", "pdf", "print"], |
|||
name: "main", |
|||
tabIndex: 0, |
|||
dom: { |
|||
container: { |
|||
tag: "div", |
|||
className: "dt-buttons" |
|||
}, |
|||
collection: { |
|||
action: { |
|||
dropHtml: '<span class="dt-button-down-arrow">▼</span>' |
|||
}, |
|||
container: { |
|||
className: "dt-button-collection", |
|||
content: { |
|||
className: "", |
|||
tag: "div" |
|||
}, |
|||
tag: "div" |
|||
} |
|||
}, |
|||
button: { |
|||
tag: "button", |
|||
className: "dt-button", |
|||
active: "dt-button-active", |
|||
disabled: "disabled", |
|||
spacer: { |
|||
className: "dt-button-spacer", |
|||
tag: "span" |
|||
}, |
|||
liner: { |
|||
tag: "span", |
|||
className: "" |
|||
} |
|||
}, |
|||
split: { |
|||
action: { |
|||
className: "dt-button-split-drop-button dt-button", |
|||
tag: "button" |
|||
}, |
|||
dropdown: { |
|||
align: "split-right", |
|||
className: "dt-button-split-drop", |
|||
dropHtml: '<span class="dt-button-down-arrow">▼</span>', |
|||
splitAlignClass: "dt-button-split-left", |
|||
tag: "button" |
|||
}, |
|||
wrapper: { |
|||
className: "dt-button-split", |
|||
tag: "div" |
|||
} |
|||
} |
|||
} |
|||
}, y.extend(_, { |
|||
collection: { |
|||
text: function(t) { |
|||
return t.i18n("buttons.collection", "Collection") |
|||
}, |
|||
className: "buttons-collection", |
|||
closeButton: !(B.version = "2.4.1"), |
|||
init: function(t, n, e) { |
|||
n.attr("aria-expanded", !1) |
|||
}, |
|||
action: function(t, n, e, o) { |
|||
o._collection.parents("body").length ? this.popover(!1, o) : this.popover(o._collection, o), "keypress" === t.type && y("a, button", o._collection).eq(0).focus() |
|||
}, |
|||
attr: { |
|||
"aria-haspopup": "dialog" |
|||
} |
|||
}, |
|||
split: { |
|||
text: function(t) { |
|||
return t.i18n("buttons.split", "Split") |
|||
}, |
|||
className: "buttons-split", |
|||
closeButton: !1, |
|||
init: function(t, n, e) { |
|||
return n.attr("aria-expanded", !1) |
|||
}, |
|||
action: function(t, n, e, o) { |
|||
this.popover(o._collection, o) |
|||
}, |
|||
attr: { |
|||
"aria-haspopup": "dialog" |
|||
} |
|||
}, |
|||
copy: function(t, n) { |
|||
if (_.copyHtml5) return "copyHtml5" |
|||
}, |
|||
csv: function(t, n) { |
|||
if (_.csvHtml5 && _.csvHtml5.available(t, n)) return "csvHtml5" |
|||
}, |
|||
excel: function(t, n) { |
|||
if (_.excelHtml5 && _.excelHtml5.available(t, n)) return "excelHtml5" |
|||
}, |
|||
pdf: function(t, n) { |
|||
if (_.pdfHtml5 && _.pdfHtml5.available(t, n)) return "pdfHtml5" |
|||
}, |
|||
pageLength: function(t) { |
|||
var n = t.settings()[0].aLengthMenu, |
|||
e = [], |
|||
o = []; |
|||
if (Array.isArray(n[0])) e = n[0], o = n[1]; |
|||
else |
|||
for (var i = 0; i < n.length; i++) { |
|||
var s = n[i]; |
|||
y.isPlainObject(s) ? (e.push(s.value), o.push(s.label)) : (e.push(s), o.push(s)) |
|||
} |
|||
return { |
|||
extend: "collection", |
|||
text: function(t) { |
|||
return t.i18n("buttons.pageLength", { |
|||
"-1": "Show all rows", |
|||
_: "Show %d rows" |
|||
}, t.page.len()) |
|||
}, |
|||
className: "buttons-page-length", |
|||
autoClose: !0, |
|||
buttons: y.map(e, function(s, t) { |
|||
return { |
|||
text: o[t], |
|||
className: "button-page-length", |
|||
action: function(t, n) { |
|||
n.page.len(s).draw() |
|||
}, |
|||
init: function(t, n, e) { |
|||
function o() { |
|||
i.active(t.page.len() === s) |
|||
} |
|||
var i = this; |
|||
t.on("length.dt" + e.namespace, o), o() |
|||
}, |
|||
destroy: function(t, n, e) { |
|||
t.off("length.dt" + e.namespace) |
|||
} |
|||
} |
|||
}), |
|||
init: function(t, n, e) { |
|||
var o = this; |
|||
t.on("length.dt" + e.namespace, function() { |
|||
o.text(e.text) |
|||
}) |
|||
}, |
|||
destroy: function(t, n, e) { |
|||
t.off("length.dt" + e.namespace) |
|||
} |
|||
} |
|||
}, |
|||
spacer: { |
|||
style: "empty", |
|||
spacer: !0, |
|||
text: function(t) { |
|||
return t.i18n("buttons.spacer", "") |
|||
} |
|||
} |
|||
}), e.Api.register("buttons()", function(n, e) { |
|||
e === w && (e = n, n = w), this.selector.buttonGroup = n; |
|||
var t = this.iterator(!0, "table", function(t) { |
|||
if (t._buttons) return B.buttonSelector(B.instanceSelector(n, t._buttons), e) |
|||
}, !0); |
|||
return t._groupSelector = n, t |
|||
}), e.Api.register("button()", function(t, n) { |
|||
t = this.buttons(t, n); |
|||
return 1 < t.length && t.splice(1, t.length), t |
|||
}), e.Api.registerPlural("buttons().active()", "button().active()", function(n) { |
|||
return n === w ? this.map(function(t) { |
|||
return t.inst.active(t.node) |
|||
}) : this.each(function(t) { |
|||
t.inst.active(t.node, n) |
|||
}) |
|||
}), e.Api.registerPlural("buttons().action()", "button().action()", function(n) { |
|||
return n === w ? this.map(function(t) { |
|||
return t.inst.action(t.node) |
|||
}) : this.each(function(t) { |
|||
t.inst.action(t.node, n) |
|||
}) |
|||
}), e.Api.registerPlural("buttons().collectionRebuild()", "button().collectionRebuild()", function(e) { |
|||
return this.each(function(t) { |
|||
for (var n = 0; n < e.length; n++) "object" == typeof e[n] && (e[n].parentConf = t); |
|||
t.inst.collectionRebuild(t.node, e) |
|||
}) |
|||
}), e.Api.register(["buttons().enable()", "button().enable()"], function(n) { |
|||
return this.each(function(t) { |
|||
t.inst.enable(t.node, n) |
|||
}) |
|||
}), e.Api.register(["buttons().disable()", "button().disable()"], function() { |
|||
return this.each(function(t) { |
|||
t.inst.disable(t.node) |
|||
}) |
|||
}), e.Api.register("button().index()", function() { |
|||
var n = null; |
|||
return this.each(function(t) { |
|||
t = t.inst.index(t.node); |
|||
null !== t && (n = t) |
|||
}), n |
|||
}), e.Api.registerPlural("buttons().nodes()", "button().node()", function() { |
|||
var n = y(); |
|||
return y(this.each(function(t) { |
|||
n = n.add(t.inst.node(t.node)) |
|||
})), n |
|||
}), e.Api.registerPlural("buttons().processing()", "button().processing()", function(n) { |
|||
return n === w ? this.map(function(t) { |
|||
return t.inst.processing(t.node) |
|||
}) : this.each(function(t) { |
|||
t.inst.processing(t.node, n) |
|||
}) |
|||
}), e.Api.registerPlural("buttons().text()", "button().text()", function(n) { |
|||
return n === w ? this.map(function(t) { |
|||
return t.inst.text(t.node) |
|||
}) : this.each(function(t) { |
|||
t.inst.text(t.node, n) |
|||
}) |
|||
}), e.Api.registerPlural("buttons().trigger()", "button().trigger()", function() { |
|||
return this.each(function(t) { |
|||
t.inst.node(t.node).trigger("click") |
|||
}) |
|||
}), e.Api.register("button().popover()", function(n, e) { |
|||
return this.map(function(t) { |
|||
return t.inst._popover(n, this.button(this[0].node), e) |
|||
}) |
|||
}), e.Api.register("buttons().containers()", function() { |
|||
var i = y(), |
|||
s = this._groupSelector; |
|||
return this.iterator(!0, "table", function(t) { |
|||
if (t._buttons) |
|||
for (var n = B.instanceSelector(s, t._buttons), e = 0, o = n.length; e < o; e++) i = i.add(n[e].container()) |
|||
}), i |
|||
}), e.Api.register("buttons().container()", function() { |
|||
return this.containers().eq(0) |
|||
}), e.Api.register("button().add()", function(t, n, e) { |
|||
var o = this.context; |
|||
return o.length && (o = B.instanceSelector(this._groupSelector, o[0]._buttons)).length && o[0].add(n, t, e), this.button(this._groupSelector, t) |
|||
}), e.Api.register("buttons().destroy()", function() { |
|||
return this.pluck("inst").unique().each(function(t) { |
|||
t.destroy() |
|||
}), this |
|||
}), e.Api.registerPlural("buttons().remove()", "buttons().remove()", function() { |
|||
return this.each(function(t) { |
|||
t.inst.remove(t.node) |
|||
}), this |
|||
}), e.Api.register("buttons.info()", function(t, n, e) { |
|||
var o = this; |
|||
return !1 === t ? (this.off("destroy.btn-info"), k(y("#datatables_buttons_info"), 400, function() { |
|||
y(this).remove() |
|||
}), clearTimeout(i), i = null) : (i && clearTimeout(i), y("#datatables_buttons_info").length && y("#datatables_buttons_info").remove(), t = t ? "<h2>" + t + "</h2>" : "", A(y('<div id="datatables_buttons_info" class="dt-button-info"/>').html(t).append(y("<div/>")["string" == typeof n ? "html" : "append"](n)).css("display", "none").appendTo("body")), e !== w && 0 !== e && (i = setTimeout(function() { |
|||
o.buttons.info(!1) |
|||
}, e)), this.on("destroy.btn-info", function() { |
|||
o.buttons.info(!1) |
|||
})), this |
|||
}), e.Api.register("buttons.exportData()", function(t) { |
|||
if (this.context.length) return c(new e.Api(this.context[0]), t) |
|||
}), e.Api.register("buttons.exportInfo()", function(t) { |
|||
return { |
|||
filename: n(t = t || {}), |
|||
title: a(t), |
|||
messageTop: r(this, t.message || t.messageTop, "top"), |
|||
messageBottom: r(this, t.messageBottom, "bottom") |
|||
} |
|||
}); |
|||
var i, n = function(t) { |
|||
var n; |
|||
return (n = "function" == typeof (n = "*" === t.filename && "*" !== t.title && t.title !== w && null !== t.title && "" !== t.title ? t.title : t.filename) ? n() : n) === w || null === n ? null : (n = (n = -1 !== n.indexOf("*") ? n.replace("*", y("head > title").text()).trim() : n).replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "")) + (s(t.extension) || "") |
|||
}, |
|||
s = function(t) { |
|||
return null === t || t === w ? null : "function" == typeof t ? t() : t |
|||
}, |
|||
a = function(t) { |
|||
t = s(t.title); |
|||
return null === t ? null : -1 !== t.indexOf("*") ? t.replace("*", y("head > title").text() || "Exported data") : t |
|||
}, |
|||
r = function(t, n, e) { |
|||
n = s(n); |
|||
return null === n ? null : (t = y("caption", t.table().container()).eq(0), "*" === n ? t.css("caption-side") !== e ? null : t.length ? t.text() : "" : n) |
|||
}, |
|||
l = y("<textarea/>")[0], |
|||
c = function(e, t) { |
|||
for (var o = y.extend(!0, {}, { |
|||
rows: null, |
|||
columns: "", |
|||
modifier: { |
|||
search: "applied", |
|||
order: "applied" |
|||
}, |
|||
orthogonal: "display", |
|||
stripHtml: !0, |
|||
stripNewlines: !0, |
|||
decodeEntities: !0, |
|||
trim: !0, |
|||
format: { |
|||
header: function(t) { |
|||
return B.stripData(t, o) |
|||
}, |
|||
footer: function(t) { |
|||
return B.stripData(t, o) |
|||
}, |
|||
body: function(t) { |
|||
return B.stripData(t, o) |
|||
} |
|||
}, |
|||
customizeData: null |
|||
}, t), t = e.columns(o.columns).indexes().map(function(t) { |
|||
var n = e.column(t).header(); |
|||
return o.format.header(n.innerHTML, t, n) |
|||
}).toArray(), n = e.table().footer() ? e.columns(o.columns).indexes().map(function(t) { |
|||
var n = e.column(t).footer(); |
|||
return o.format.footer(n ? n.innerHTML : "", t, n) |
|||
}).toArray() : null, i = y.extend({}, o.modifier), i = (e.select && "function" == typeof e.select.info && i.selected === w && e.rows(o.rows, y.extend({ |
|||
selected: !0 |
|||
}, i)).any() && y.extend(i, { |
|||
selected: !0 |
|||
}), e.rows(o.rows, i).indexes().toArray()), i = e.cells(i, o.columns), s = i.render(o.orthogonal).toArray(), a = i.nodes().toArray(), r = t.length, l = [], c = 0, u = 0, d = 0 < r ? s.length / r : 0; u < d; u++) { |
|||
for (var f = [r], p = 0; p < r; p++) f[p] = o.format.body(s[c], u, p, a[c]), c++; |
|||
l[u] = f |
|||
} |
|||
i = { |
|||
header: t, |
|||
footer: n, |
|||
body: l |
|||
}; |
|||
return o.customizeData && o.customizeData(i), i |
|||
}; |
|||
|
|||
function t(t, n) { |
|||
t = new e.Api(t), n = n || t.init().buttons || e.defaults.buttons; |
|||
return new B(t, n).container() |
|||
} |
|||
return y.fn.dataTable.Buttons = B, y.fn.DataTable.Buttons = B, y(x).on("init.dt plugin-init.dt", function(t, n) { |
|||
"dt" === t.namespace && (t = n.oInit.buttons || e.defaults.buttons) && !n._buttons && new B(n, t).container() |
|||
}), e.ext.feature.push({ |
|||
fnInit: t, |
|||
cFeature: "B" |
|||
}), e.ext.features && e.ext.features.register("buttons", t), e |
|||
}); |
|||
@ -0,0 +1,793 @@ |
|||
.flatpickr-calendar { |
|||
background: transparent; |
|||
opacity: 0; |
|||
display: none; |
|||
text-align: center; |
|||
visibility: hidden; |
|||
padding: 0; |
|||
-webkit-animation: none; |
|||
animation: none; |
|||
direction: ltr; |
|||
border: 0; |
|||
font-size: 14px; |
|||
line-height: 24px; |
|||
border-radius: 5px; |
|||
position: absolute; |
|||
width: 307.875px; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
-ms-touch-action: manipulation; |
|||
touch-action: manipulation; |
|||
background: #fff; |
|||
-webkit-box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, |
|||
0 -1px 0 #e6e6e6, 0 3px 13px rgba(0, 0, 0, 0.08); |
|||
box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, |
|||
0 -1px 0 #e6e6e6, 0 3px 13px rgba(0, 0, 0, 0.08); |
|||
} |
|||
.flatpickr-calendar.open, |
|||
.flatpickr-calendar.inline { |
|||
opacity: 1; |
|||
max-height: 640px; |
|||
visibility: visible; |
|||
} |
|||
.flatpickr-calendar.open { |
|||
display: inline-block; |
|||
z-index: 99999; |
|||
} |
|||
.flatpickr-calendar.animate.open { |
|||
-webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); |
|||
animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); |
|||
} |
|||
.flatpickr-calendar.inline { |
|||
display: block; |
|||
position: relative; |
|||
top: 2px; |
|||
} |
|||
.flatpickr-calendar.static { |
|||
position: absolute; |
|||
top: calc(100% + 2px); |
|||
} |
|||
.flatpickr-calendar.static.open { |
|||
z-index: 999; |
|||
display: block; |
|||
} |
|||
.flatpickr-calendar.multiMonth |
|||
.flatpickr-days |
|||
.dayContainer:nth-child(n + 1) |
|||
.flatpickr-day.inRange:nth-child(7n + 7) { |
|||
-webkit-box-shadow: none !important; |
|||
box-shadow: none !important; |
|||
} |
|||
.flatpickr-calendar.multiMonth |
|||
.flatpickr-days |
|||
.dayContainer:nth-child(n + 2) |
|||
.flatpickr-day.inRange:nth-child(7n + 1) { |
|||
-webkit-box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6; |
|||
box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6; |
|||
} |
|||
.flatpickr-calendar .hasWeeks .dayContainer, |
|||
.flatpickr-calendar .hasTime .dayContainer { |
|||
border-bottom: 0; |
|||
border-bottom-right-radius: 0; |
|||
border-bottom-left-radius: 0; |
|||
} |
|||
.flatpickr-calendar .hasWeeks .dayContainer { |
|||
border-left: 0; |
|||
} |
|||
.flatpickr-calendar.hasTime .flatpickr-time { |
|||
height: 40px; |
|||
border-top: 1px solid #e6e6e6; |
|||
} |
|||
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time { |
|||
height: auto; |
|||
} |
|||
.flatpickr-calendar:before, |
|||
.flatpickr-calendar:after { |
|||
position: absolute; |
|||
display: block; |
|||
pointer-events: none; |
|||
border: solid transparent; |
|||
content: ""; |
|||
height: 0; |
|||
width: 0; |
|||
left: 22px; |
|||
} |
|||
.flatpickr-calendar.rightMost:before, |
|||
.flatpickr-calendar.arrowRight:before, |
|||
.flatpickr-calendar.rightMost:after, |
|||
.flatpickr-calendar.arrowRight:after { |
|||
left: auto; |
|||
right: 22px; |
|||
} |
|||
.flatpickr-calendar.arrowCenter:before, |
|||
.flatpickr-calendar.arrowCenter:after { |
|||
left: 50%; |
|||
right: 50%; |
|||
} |
|||
.flatpickr-calendar:before { |
|||
border-width: 5px; |
|||
margin: 0 -5px; |
|||
} |
|||
.flatpickr-calendar:after { |
|||
border-width: 4px; |
|||
margin: 0 -4px; |
|||
} |
|||
.flatpickr-calendar.arrowTop:before, |
|||
.flatpickr-calendar.arrowTop:after { |
|||
bottom: 100%; |
|||
} |
|||
.flatpickr-calendar.arrowTop:before { |
|||
border-bottom-color: #e6e6e6; |
|||
} |
|||
.flatpickr-calendar.arrowTop:after { |
|||
border-bottom-color: #fff; |
|||
} |
|||
.flatpickr-calendar.arrowBottom:before, |
|||
.flatpickr-calendar.arrowBottom:after { |
|||
top: 100%; |
|||
} |
|||
.flatpickr-calendar.arrowBottom:before { |
|||
border-top-color: #e6e6e6; |
|||
} |
|||
.flatpickr-calendar.arrowBottom:after { |
|||
border-top-color: #fff; |
|||
} |
|||
.flatpickr-calendar:focus { |
|||
outline: 0; |
|||
} |
|||
.flatpickr-wrapper { |
|||
position: relative; |
|||
display: inline-block; |
|||
} |
|||
.flatpickr-months { |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
} |
|||
.flatpickr-months .flatpickr-month { |
|||
background: transparent; |
|||
color: rgba(0, 0, 0, 0.9); |
|||
fill: rgba(0, 0, 0, 0.9); |
|||
height: 34px; |
|||
line-height: 1; |
|||
text-align: center; |
|||
position: relative; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
overflow: hidden; |
|||
-webkit-box-flex: 1; |
|||
-webkit-flex: 1; |
|||
-ms-flex: 1; |
|||
flex: 1; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month, |
|||
.flatpickr-months .flatpickr-next-month { |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
text-decoration: none; |
|||
cursor: pointer; |
|||
position: absolute; |
|||
top: 0; |
|||
height: 34px; |
|||
padding: 10px; |
|||
z-index: 3; |
|||
color: rgba(0, 0, 0, 0.9); |
|||
fill: rgba(0, 0, 0, 0.9); |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month.flatpickr-disabled, |
|||
.flatpickr-months .flatpickr-next-month.flatpickr-disabled { |
|||
display: none; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month i, |
|||
.flatpickr-months .flatpickr-next-month i { |
|||
position: relative; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month, |
|||
.flatpickr-months .flatpickr-next-month.flatpickr-prev-month { |
|||
/* |
|||
/*rtl:begin:ignore*/ |
|||
left: 0; /* |
|||
/*rtl:end:ignore*/ |
|||
} /* |
|||
/*rtl:begin:ignore*/ |
|||
/* |
|||
/*rtl:end:ignore*/ |
|||
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month, |
|||
.flatpickr-months .flatpickr-next-month.flatpickr-next-month { |
|||
/* |
|||
/*rtl:begin:ignore*/ |
|||
right: 0; /* |
|||
/*rtl:end:ignore*/ |
|||
} /* |
|||
/*rtl:begin:ignore*/ |
|||
/* |
|||
/*rtl:end:ignore*/ |
|||
.flatpickr-months .flatpickr-prev-month:hover, |
|||
.flatpickr-months .flatpickr-next-month:hover { |
|||
color: #959ea9; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month:hover svg, |
|||
.flatpickr-months .flatpickr-next-month:hover svg { |
|||
fill: #f64747; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month svg, |
|||
.flatpickr-months .flatpickr-next-month svg { |
|||
width: 14px; |
|||
height: 14px; |
|||
} |
|||
.flatpickr-months .flatpickr-prev-month svg path, |
|||
.flatpickr-months .flatpickr-next-month svg path { |
|||
-webkit-transition: fill 0.1s; |
|||
transition: fill 0.1s; |
|||
fill: inherit; |
|||
} |
|||
.numInputWrapper { |
|||
position: relative; |
|||
height: auto; |
|||
} |
|||
.numInputWrapper input, |
|||
.numInputWrapper span { |
|||
display: inline-block; |
|||
} |
|||
.numInputWrapper input { |
|||
width: 100%; |
|||
} |
|||
.numInputWrapper input::-ms-clear { |
|||
display: none; |
|||
} |
|||
.numInputWrapper input::-webkit-outer-spin-button, |
|||
.numInputWrapper input::-webkit-inner-spin-button { |
|||
margin: 0; |
|||
-webkit-appearance: none; |
|||
} |
|||
.numInputWrapper span { |
|||
position: absolute; |
|||
right: 0; |
|||
width: 14px; |
|||
padding: 0 4px 0 2px; |
|||
height: 50%; |
|||
line-height: 50%; |
|||
opacity: 0; |
|||
cursor: pointer; |
|||
border: 1px solid rgba(57, 57, 57, 0.15); |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
} |
|||
.numInputWrapper span:hover { |
|||
background: rgba(0, 0, 0, 0.1); |
|||
} |
|||
.numInputWrapper span:active { |
|||
background: rgba(0, 0, 0, 0.2); |
|||
} |
|||
.numInputWrapper span:after { |
|||
display: block; |
|||
content: ""; |
|||
position: absolute; |
|||
} |
|||
.numInputWrapper span.arrowUp { |
|||
top: 0; |
|||
border-bottom: 0; |
|||
} |
|||
.numInputWrapper span.arrowUp:after { |
|||
border-left: 4px solid transparent; |
|||
border-right: 4px solid transparent; |
|||
border-bottom: 4px solid rgba(57, 57, 57, 0.6); |
|||
top: 26%; |
|||
} |
|||
.numInputWrapper span.arrowDown { |
|||
top: 50%; |
|||
} |
|||
.numInputWrapper span.arrowDown:after { |
|||
border-left: 4px solid transparent; |
|||
border-right: 4px solid transparent; |
|||
border-top: 4px solid rgba(57, 57, 57, 0.6); |
|||
top: 40%; |
|||
} |
|||
.numInputWrapper span svg { |
|||
width: inherit; |
|||
height: auto; |
|||
} |
|||
.numInputWrapper span svg path { |
|||
fill: rgba(0, 0, 0, 0.5); |
|||
} |
|||
.numInputWrapper:hover { |
|||
background: rgba(0, 0, 0, 0.05); |
|||
} |
|||
.numInputWrapper:hover span { |
|||
opacity: 1; |
|||
} |
|||
.flatpickr-current-month { |
|||
font-size: 135%; |
|||
line-height: inherit; |
|||
font-weight: 300; |
|||
color: inherit; |
|||
position: absolute; |
|||
width: 75%; |
|||
left: 12.5%; |
|||
padding: 7.48px 0 0 0; |
|||
line-height: 1; |
|||
height: 34px; |
|||
display: inline-block; |
|||
text-align: center; |
|||
-webkit-transform: translate3d(0, 0, 0); |
|||
transform: translate3d(0, 0, 0); |
|||
} |
|||
.flatpickr-current-month span.cur-month { |
|||
font-family: inherit; |
|||
font-weight: 700; |
|||
color: inherit; |
|||
display: inline-block; |
|||
margin-left: 0.5ch; |
|||
padding: 0; |
|||
} |
|||
.flatpickr-current-month span.cur-month:hover { |
|||
background: rgba(0, 0, 0, 0.05); |
|||
} |
|||
.flatpickr-current-month .numInputWrapper { |
|||
width: 6ch; |
|||
width: 7ch\0; |
|||
display: inline-block; |
|||
} |
|||
.flatpickr-current-month .numInputWrapper span.arrowUp:after { |
|||
border-bottom-color: rgba(0, 0, 0, 0.9); |
|||
} |
|||
.flatpickr-current-month .numInputWrapper span.arrowDown:after { |
|||
border-top-color: rgba(0, 0, 0, 0.9); |
|||
} |
|||
.flatpickr-current-month input.cur-year { |
|||
background: transparent; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
color: inherit; |
|||
cursor: text; |
|||
padding: 0 0 0 0.5ch; |
|||
margin: 0; |
|||
display: inline-block; |
|||
font-size: inherit; |
|||
font-family: inherit; |
|||
font-weight: 300; |
|||
line-height: inherit; |
|||
height: auto; |
|||
border: 0; |
|||
border-radius: 0; |
|||
vertical-align: initial; |
|||
-webkit-appearance: textfield; |
|||
-moz-appearance: textfield; |
|||
appearance: textfield; |
|||
} |
|||
.flatpickr-current-month input.cur-year:focus { |
|||
outline: 0; |
|||
} |
|||
.flatpickr-current-month input.cur-year[disabled], |
|||
.flatpickr-current-month input.cur-year[disabled]:hover { |
|||
font-size: 100%; |
|||
color: rgba(0, 0, 0, 0.5); |
|||
background: transparent; |
|||
pointer-events: none; |
|||
} |
|||
.flatpickr-current-month .flatpickr-monthDropdown-months { |
|||
appearance: menulist; |
|||
background: transparent; |
|||
border: none; |
|||
border-radius: 0; |
|||
box-sizing: border-box; |
|||
color: inherit; |
|||
cursor: pointer; |
|||
font-size: inherit; |
|||
font-family: inherit; |
|||
font-weight: 300; |
|||
height: auto; |
|||
line-height: inherit; |
|||
margin: -1px 0 0 0; |
|||
outline: none; |
|||
padding: 0 0 0 0.5ch; |
|||
position: relative; |
|||
vertical-align: initial; |
|||
-webkit-box-sizing: border-box; |
|||
-webkit-appearance: menulist; |
|||
-moz-appearance: menulist; |
|||
width: auto; |
|||
} |
|||
.flatpickr-current-month .flatpickr-monthDropdown-months:focus, |
|||
.flatpickr-current-month .flatpickr-monthDropdown-months:active { |
|||
outline: none; |
|||
} |
|||
.flatpickr-current-month .flatpickr-monthDropdown-months:hover { |
|||
background: rgba(0, 0, 0, 0.05); |
|||
} |
|||
.flatpickr-current-month |
|||
.flatpickr-monthDropdown-months |
|||
.flatpickr-monthDropdown-month { |
|||
background-color: transparent; |
|||
outline: none; |
|||
padding: 0; |
|||
} |
|||
.flatpickr-weekdays { |
|||
background: transparent; |
|||
text-align: center; |
|||
overflow: hidden; |
|||
width: 100%; |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
-webkit-box-align: center; |
|||
-webkit-align-items: center; |
|||
-ms-flex-align: center; |
|||
align-items: center; |
|||
height: 28px; |
|||
} |
|||
.flatpickr-weekdays .flatpickr-weekdaycontainer { |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
-webkit-box-flex: 1; |
|||
-webkit-flex: 1; |
|||
-ms-flex: 1; |
|||
flex: 1; |
|||
} |
|||
span.flatpickr-weekday { |
|||
cursor: default; |
|||
font-size: 90%; |
|||
background: transparent; |
|||
color: rgba(0, 0, 0, 0.54); |
|||
line-height: 1; |
|||
margin: 0; |
|||
text-align: center; |
|||
display: block; |
|||
-webkit-box-flex: 1; |
|||
-webkit-flex: 1; |
|||
-ms-flex: 1; |
|||
flex: 1; |
|||
font-weight: bolder; |
|||
} |
|||
.dayContainer, |
|||
.flatpickr-weeks { |
|||
padding: 1px 0 0 0; |
|||
} |
|||
.flatpickr-days { |
|||
position: relative; |
|||
overflow: hidden; |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
-webkit-box-align: start; |
|||
-webkit-align-items: flex-start; |
|||
-ms-flex-align: start; |
|||
align-items: flex-start; |
|||
width: 307.875px; |
|||
} |
|||
.flatpickr-days:focus { |
|||
outline: 0; |
|||
} |
|||
.dayContainer { |
|||
padding: 0; |
|||
outline: 0; |
|||
text-align: left; |
|||
width: 307.875px; |
|||
min-width: 307.875px; |
|||
max-width: 307.875px; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
display: inline-block; |
|||
display: -ms-flexbox; |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: flex; |
|||
-webkit-flex-wrap: wrap; |
|||
flex-wrap: wrap; |
|||
-ms-flex-wrap: wrap; |
|||
-ms-flex-pack: justify; |
|||
-webkit-justify-content: space-around; |
|||
justify-content: space-around; |
|||
-webkit-transform: translate3d(0, 0, 0); |
|||
transform: translate3d(0, 0, 0); |
|||
opacity: 1; |
|||
} |
|||
.dayContainer + .dayContainer { |
|||
-webkit-box-shadow: -1px 0 0 #e6e6e6; |
|||
box-shadow: -1px 0 0 #e6e6e6; |
|||
} |
|||
.flatpickr-day { |
|||
background: none; |
|||
border: 1px solid transparent; |
|||
border-radius: 150px; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
color: #393939; |
|||
cursor: pointer; |
|||
font-weight: 400; |
|||
width: 14.2857143%; |
|||
-webkit-flex-basis: 14.2857143%; |
|||
-ms-flex-preferred-size: 14.2857143%; |
|||
flex-basis: 14.2857143%; |
|||
max-width: 39px; |
|||
height: 39px; |
|||
line-height: 39px; |
|||
margin: 0; |
|||
display: inline-block; |
|||
position: relative; |
|||
-webkit-box-pack: center; |
|||
-webkit-justify-content: center; |
|||
-ms-flex-pack: center; |
|||
justify-content: center; |
|||
text-align: center; |
|||
} |
|||
.flatpickr-day.inRange, |
|||
.flatpickr-day.prevMonthDay.inRange, |
|||
.flatpickr-day.nextMonthDay.inRange, |
|||
.flatpickr-day.today.inRange, |
|||
.flatpickr-day.prevMonthDay.today.inRange, |
|||
.flatpickr-day.nextMonthDay.today.inRange, |
|||
.flatpickr-day:hover, |
|||
.flatpickr-day.prevMonthDay:hover, |
|||
.flatpickr-day.nextMonthDay:hover, |
|||
.flatpickr-day:focus, |
|||
.flatpickr-day.prevMonthDay:focus, |
|||
.flatpickr-day.nextMonthDay:focus { |
|||
cursor: pointer; |
|||
outline: 0; |
|||
background: #e6e6e6; |
|||
border-color: #e6e6e6; |
|||
} |
|||
.flatpickr-day.today { |
|||
border-color: #959ea9; |
|||
} |
|||
.flatpickr-day.today:hover, |
|||
.flatpickr-day.today:focus { |
|||
border-color: #959ea9; |
|||
background: #959ea9; |
|||
color: #fff; |
|||
} |
|||
.flatpickr-day.selected, |
|||
.flatpickr-day.startRange, |
|||
.flatpickr-day.endRange, |
|||
.flatpickr-day.selected.inRange, |
|||
.flatpickr-day.startRange.inRange, |
|||
.flatpickr-day.endRange.inRange, |
|||
.flatpickr-day.selected:focus, |
|||
.flatpickr-day.startRange:focus, |
|||
.flatpickr-day.endRange:focus, |
|||
.flatpickr-day.selected:hover, |
|||
.flatpickr-day.startRange:hover, |
|||
.flatpickr-day.endRange:hover, |
|||
.flatpickr-day.selected.prevMonthDay, |
|||
.flatpickr-day.startRange.prevMonthDay, |
|||
.flatpickr-day.endRange.prevMonthDay, |
|||
.flatpickr-day.selected.nextMonthDay, |
|||
.flatpickr-day.startRange.nextMonthDay, |
|||
.flatpickr-day.endRange.nextMonthDay { |
|||
background: #569ff7; |
|||
-webkit-box-shadow: none; |
|||
box-shadow: none; |
|||
color: #fff; |
|||
border-color: #569ff7; |
|||
} |
|||
.flatpickr-day.selected.startRange, |
|||
.flatpickr-day.startRange.startRange, |
|||
.flatpickr-day.endRange.startRange { |
|||
border-radius: 50px 0 0 50px; |
|||
} |
|||
.flatpickr-day.selected.endRange, |
|||
.flatpickr-day.startRange.endRange, |
|||
.flatpickr-day.endRange.endRange { |
|||
border-radius: 0 50px 50px 0; |
|||
} |
|||
.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n + 1)), |
|||
.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n + 1)), |
|||
.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n + 1)) { |
|||
-webkit-box-shadow: -10px 0 0 #569ff7; |
|||
box-shadow: -10px 0 0 #569ff7; |
|||
} |
|||
.flatpickr-day.selected.startRange.endRange, |
|||
.flatpickr-day.startRange.startRange.endRange, |
|||
.flatpickr-day.endRange.startRange.endRange { |
|||
border-radius: 50px; |
|||
} |
|||
.flatpickr-day.inRange { |
|||
border-radius: 0; |
|||
-webkit-box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6; |
|||
box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6; |
|||
} |
|||
.flatpickr-day.flatpickr-disabled, |
|||
.flatpickr-day.flatpickr-disabled:hover, |
|||
.flatpickr-day.prevMonthDay, |
|||
.flatpickr-day.nextMonthDay, |
|||
.flatpickr-day.notAllowed, |
|||
.flatpickr-day.notAllowed.prevMonthDay, |
|||
.flatpickr-day.notAllowed.nextMonthDay { |
|||
color: rgba(57, 57, 57, 0.3); |
|||
background: transparent; |
|||
border-color: transparent; |
|||
cursor: default; |
|||
} |
|||
.flatpickr-day.flatpickr-disabled, |
|||
.flatpickr-day.flatpickr-disabled:hover { |
|||
cursor: not-allowed; |
|||
color: rgba(57, 57, 57, 0.1); |
|||
} |
|||
.flatpickr-day.week.selected { |
|||
border-radius: 0; |
|||
-webkit-box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7; |
|||
box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7; |
|||
} |
|||
.flatpickr-day.hidden { |
|||
visibility: hidden; |
|||
} |
|||
.rangeMode .flatpickr-day { |
|||
margin-top: 1px; |
|||
} |
|||
.flatpickr-weekwrapper { |
|||
float: left; |
|||
} |
|||
.flatpickr-weekwrapper .flatpickr-weeks { |
|||
padding: 0 12px; |
|||
-webkit-box-shadow: 1px 0 0 #e6e6e6; |
|||
box-shadow: 1px 0 0 #e6e6e6; |
|||
} |
|||
.flatpickr-weekwrapper .flatpickr-weekday { |
|||
float: none; |
|||
width: 100%; |
|||
line-height: 28px; |
|||
} |
|||
.flatpickr-weekwrapper span.flatpickr-day, |
|||
.flatpickr-weekwrapper span.flatpickr-day:hover { |
|||
display: block; |
|||
width: 100%; |
|||
max-width: none; |
|||
color: rgba(57, 57, 57, 0.3); |
|||
background: transparent; |
|||
cursor: default; |
|||
border: none; |
|||
} |
|||
.flatpickr-innerContainer { |
|||
display: block; |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
overflow: hidden; |
|||
} |
|||
.flatpickr-rContainer { |
|||
display: inline-block; |
|||
padding: 0; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
} |
|||
.flatpickr-time { |
|||
text-align: center; |
|||
outline: 0; |
|||
display: block; |
|||
height: 0; |
|||
line-height: 40px; |
|||
max-height: 40px; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
overflow: hidden; |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: -ms-flexbox; |
|||
display: flex; |
|||
} |
|||
.flatpickr-time:after { |
|||
content: ""; |
|||
display: table; |
|||
clear: both; |
|||
} |
|||
.flatpickr-time .numInputWrapper { |
|||
-webkit-box-flex: 1; |
|||
-webkit-flex: 1; |
|||
-ms-flex: 1; |
|||
flex: 1; |
|||
width: 40%; |
|||
height: 40px; |
|||
float: left; |
|||
} |
|||
.flatpickr-time .numInputWrapper span.arrowUp:after { |
|||
border-bottom-color: #393939; |
|||
} |
|||
.flatpickr-time .numInputWrapper span.arrowDown:after { |
|||
border-top-color: #393939; |
|||
} |
|||
.flatpickr-time.hasSeconds .numInputWrapper { |
|||
width: 26%; |
|||
} |
|||
.flatpickr-time.time24hr .numInputWrapper { |
|||
width: 49%; |
|||
} |
|||
.flatpickr-time input { |
|||
background: transparent; |
|||
-webkit-box-shadow: none; |
|||
box-shadow: none; |
|||
border: 0; |
|||
border-radius: 0; |
|||
text-align: center; |
|||
margin: 0; |
|||
padding: 0; |
|||
height: inherit; |
|||
line-height: inherit; |
|||
color: #393939; |
|||
font-size: 14px; |
|||
position: relative; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
-webkit-appearance: textfield; |
|||
-moz-appearance: textfield; |
|||
appearance: textfield; |
|||
} |
|||
.flatpickr-time input.flatpickr-hour { |
|||
font-weight: bold; |
|||
} |
|||
.flatpickr-time input.flatpickr-minute, |
|||
.flatpickr-time input.flatpickr-second { |
|||
font-weight: 400; |
|||
} |
|||
.flatpickr-time input:focus { |
|||
outline: 0; |
|||
border: 0; |
|||
} |
|||
.flatpickr-time .flatpickr-time-separator, |
|||
.flatpickr-time .flatpickr-am-pm { |
|||
height: inherit; |
|||
float: left; |
|||
line-height: inherit; |
|||
color: #393939; |
|||
font-weight: bold; |
|||
width: 2%; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
-webkit-align-self: center; |
|||
-ms-flex-item-align: center; |
|||
align-self: center; |
|||
} |
|||
.flatpickr-time .flatpickr-am-pm { |
|||
outline: 0; |
|||
width: 18%; |
|||
cursor: pointer; |
|||
text-align: center; |
|||
font-weight: 400; |
|||
} |
|||
.flatpickr-time input:hover, |
|||
.flatpickr-time .flatpickr-am-pm:hover, |
|||
.flatpickr-time input:focus, |
|||
.flatpickr-time .flatpickr-am-pm:focus { |
|||
background: #eee; |
|||
} |
|||
.flatpickr-input[readonly] { |
|||
cursor: pointer; |
|||
} |
|||
@-webkit-keyframes fpFadeInDown { |
|||
from { |
|||
opacity: 0; |
|||
-webkit-transform: translate3d(0, -20px, 0); |
|||
transform: translate3d(0, -20px, 0); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
-webkit-transform: translate3d(0, 0, 0); |
|||
transform: translate3d(0, 0, 0); |
|||
} |
|||
} |
|||
@keyframes fpFadeInDown { |
|||
from { |
|||
opacity: 0; |
|||
-webkit-transform: translate3d(0, -20px, 0); |
|||
transform: translate3d(0, -20px, 0); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
-webkit-transform: translate3d(0, 0, 0); |
|||
transform: translate3d(0, 0, 0); |
|||
} |
|||
} |
|||
1379
src/main/resources/static/flatpickr-4.6.13/js/flatpickr.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
6995
src/main/resources/static/font-awesome-6.5.1/css/all.min.css
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
7023
src/main/resources/static/font-awesome-6.5.2/css/all.min.css
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
|
After Width: 325 | Height: 435 | Size: 204 KiB |
25996
src/main/resources/static/html2pdf-0.9.3/js/html2pdf.bundle.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3244
src/main/resources/static/jquery-3.6.4/js/jquery-3.6.4.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,77 @@ |
|||
// Initialize date pickers
|
|||
["asFileGenDate", "piFileGenDate"].forEach(id => { |
|||
flatpickr("#" + id, { |
|||
dateFormat: "d-m-Y", |
|||
enableTime: false, |
|||
noCalendar: false, |
|||
allowInput: true |
|||
}); |
|||
}); |
|||
|
|||
document.addEventListener("DOMContentLoaded", function() { |
|||
const form = document.getElementById("frm-file-det"); |
|||
|
|||
// Listen for advance type changes
|
|||
const advTypeInput = document.getElementById("advType"); |
|||
const vendNameContainer = document.getElementById("vend-name"); |
|||
|
|||
advTypeInput.addEventListener("input", function() { |
|||
// Force uppercase
|
|||
this.value = this.value.toUpperCase(); |
|||
|
|||
const enteredText = this.value.trim(); |
|||
|
|||
// If user types "senior system manager"
|
|||
if (enteredText.toLowerCase() === "senior system manager".toLowerCase()) { |
|||
vendNameContainer.innerHTML = `
|
|||
<label for="vendName">Vendor Name : <span class="required">*</span></label> |
|||
<input type="text" id="vendName" name="vendName" class="form-control" |
|||
placeholder="Enter Vendor Name" required autocomplete="on"> |
|||
`;
|
|||
} else { |
|||
// Clear when not "SSM"
|
|||
vendNameContainer.innerHTML = ""; |
|||
} |
|||
}); |
|||
|
|||
// Existing form submission logic...
|
|||
form.addEventListener("submit", function(e) { |
|||
e.preventDefault(); // Prevent default form submission
|
|||
|
|||
const formData = new FormData(form); |
|||
|
|||
fetch(form.getAttribute("action"), { |
|||
method: "POST", |
|||
body: formData |
|||
}) |
|||
.then(response => { |
|||
if (!response.ok) { |
|||
throw new Error("Network response was not ok: " + response.statusText); |
|||
} |
|||
return response.json(); |
|||
}) |
|||
.then(data => { |
|||
if (data.resStat) { |
|||
alert("Success: " + data.res); |
|||
form.reset(); |
|||
|
|||
// Reset flatpickr
|
|||
if (flatpickr) { |
|||
["#asFileGenDate", "#piFileGenDate"].forEach(selector => { |
|||
const fp = document.querySelector(selector)?._flatpickr; |
|||
if (fp) fp.clear(); |
|||
}); |
|||
} |
|||
|
|||
// Reset dynamic vendor field
|
|||
vendNameContainer.innerHTML = ""; |
|||
} else { |
|||
alert("Failed: " + data.res); |
|||
} |
|||
}) |
|||
.catch(error => { |
|||
console.error("Error submitting file:", error); |
|||
alert("Error submitting file. Please try again."); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,17 @@ |
|||
function adjustRowClass() { |
|||
let row = document.getElementById("fileRow"); |
|||
let row2 = document.getElementById("fileRow2"); |
|||
let row3 = document.getElementById("fileRow3"); |
|||
let row4 = document.getElementById("fileRow4"); |
|||
if (window.innerWidth < 768) { |
|||
row.classList.remove("d-flex", "justify-content-between", "text-center"); |
|||
row2.classList.remove("d-flex", "justify-content-between", "text-center"); |
|||
row3.classList.remove("d-flex", "justify-content-between", "text-center"); |
|||
row4.classList.remove("d-flex", "justify-content-between", "text-center"); |
|||
} else { |
|||
row.classList.add("d-flex", "justify-content-between", "text-center"); |
|||
row2.classList.add("d-flex", "justify-content-between", "text-center"); |
|||
row3.classList.add("d-flex", "justify-content-between", "text-center"); |
|||
row4.classList.add("d-flex", "justify-content-between", "text-center"); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
const csrfToken = document.querySelector('meta[name="_csrf"]').content; |
|||
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content; |
|||
|
|||
// Save original fetch
|
|||
const originalFetch = window.fetch; |
|||
|
|||
window.fetch = (url, options = {}) => { |
|||
// Default method is GET if not provided
|
|||
const method = (options.method || "GET").toUpperCase(); |
|||
|
|||
// Only attach CSRF for unsafe methods
|
|||
if (["POST", "PUT", "DELETE", "PATCH"].includes(method)) { |
|||
options.headers = { |
|||
...options.headers, |
|||
[csrfHeader]: csrfToken |
|||
}; |
|||
} |
|||
|
|||
return originalFetch(url, options); |
|||
}; |
|||
@ -0,0 +1,3 @@ |
|||
function goBack() { |
|||
window.history.back(); |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
document.getElementById("frm-usr-login-det").addEventListener("submit", function(event) { |
|||
event.preventDefault(); // prevent normal form submission
|
|||
|
|||
const formData = new FormData(this); |
|||
|
|||
fetch('/api/val-app-usr-login', { |
|||
method: 'POST', |
|||
body: formData |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
if (data.result) { |
|||
// Extract first role authority (user only has 1 role)
|
|||
let userRole = data.role && data.role.length > 0 ? data.role[0].authority : null; |
|||
|
|||
if (userRole) { |
|||
// Redirect using the role name instead of ID
|
|||
alert("Login Success"); |
|||
window.location.href = "/redirect?usr-role=" + encodeURIComponent(userRole); |
|||
} else { |
|||
alert("No role found for this user!"); |
|||
} |
|||
} else { |
|||
alert(data.error || "Login failed"); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
console.error("Error during login:", err); |
|||
}); |
|||
|
|||
}); |
|||
@ -0,0 +1,118 @@ |
|||
document.addEventListener("DOMContentLoaded", function() { |
|||
const fileNumInput = document.getElementById("file-num"); |
|||
const dataList = document.getElementById("file-num-list"); |
|||
const asFinalFileStatInput = document.getElementById("as-final-file-stat"); |
|||
const ejvNumFileInput = document.getElementById("ejv-num-file"); |
|||
const ejvNumInput = document.getElementById("ejv-num"); |
|||
const submitBtn = document.querySelector(".submit-btn input[type='submit']"); |
|||
const form = document.getElementById("frm-file-det"); |
|||
|
|||
// Disable EJV-related inputs & submit initially
|
|||
ejvNumFileInput.disabled = true; |
|||
ejvNumInput.disabled = true; |
|||
|
|||
fileNumInput.addEventListener("input", function() { |
|||
// Find matching option from datalist
|
|||
const selectedOption = Array.from(dataList.options).find( |
|||
option => option.value === fileNumInput.value |
|||
); |
|||
|
|||
if (!selectedOption) { |
|||
// No valid selection (user typed arbitrary text)
|
|||
asFinalFileStatInput.value = ""; |
|||
ejvNumInput.value = ""; |
|||
ejvNumFileInput.value = ""; |
|||
document.getElementById("selected-ejv-num-file-name").textContent = ""; |
|||
ejvNumInput.disabled = true; |
|||
ejvNumFileInput.disabled = true; |
|||
submitBtn.disabled = true; |
|||
return; |
|||
} |
|||
|
|||
const asFinalStat = selectedOption.dataset.asFinalFileStat; |
|||
const ejvFileStat = selectedOption.dataset.ejvNumFileStat; |
|||
const ejvNumStat = selectedOption.dataset.ejvNum; |
|||
let ejvNumValue = selectedOption.dataset.ejvNumInput || ""; |
|||
if (ejvNumValue === "-") ejvNumValue = ""; |
|||
const ejvNumFileValue = selectedOption.dataset.ejvNumFileInput || ""; |
|||
|
|||
// Show Adjustment Order status
|
|||
if (asFinalStat === "true") { |
|||
asFinalFileStatInput.value = "Yes"; |
|||
} else if (asFinalStat === "false") { |
|||
asFinalFileStatInput.value = "No"; |
|||
} else { |
|||
asFinalFileStatInput.value = ""; |
|||
} |
|||
|
|||
// Always show span with EJV number
|
|||
document.getElementById("selected-ejv-num-file-name").textContent = |
|||
ejvNumFileValue && ejvNumFileValue !== "-" |
|||
? "Uploaded file: " + ejvNumFileValue.split("/").pop() |
|||
: "Uploaded file: N/A"; |
|||
|
|||
ejvNumInput.style.display = "inline"; |
|||
ejvNumFileInput.style.display = "inline"; |
|||
|
|||
// Handle enable/disable logic
|
|||
if (asFinalStat === "true" && (ejvFileStat === "true" || ejvNumStat === "true")) { |
|||
// Already updated → disabled
|
|||
ejvNumInput.value = ejvNumValue; |
|||
ejvNumInput.disabled = true; |
|||
ejvNumFileInput.disabled = true; |
|||
submitBtn.disabled = true; |
|||
} else if (asFinalStat === "true" && (ejvFileStat !== "true" || ejvNumStat !== "true")) { |
|||
// Not updated yet → enabled
|
|||
ejvNumInput.value = ejvNumValue; |
|||
ejvNumInput.disabled = false; |
|||
ejvNumFileInput.disabled = false; |
|||
submitBtn.disabled = false; |
|||
} else if (asFinalStat !== "true") { |
|||
// Adjustment Order not uploaded → disabled
|
|||
ejvNumInput.value = ejvNumValue; |
|||
ejvNumInput.disabled = true; |
|||
ejvNumFileInput.disabled = true; |
|||
submitBtn.disabled = true; |
|||
} |
|||
}); |
|||
|
|||
// Handle form submit with fetch
|
|||
form.addEventListener("submit", function(e) { |
|||
e.preventDefault(); // prevent default page reload
|
|||
|
|||
const selectedOption = Array.from(dataList.options).find( |
|||
option => option.value === fileNumInput.value |
|||
); |
|||
if (!selectedOption) { |
|||
alert("Please select a valid file number from the list."); |
|||
return; |
|||
} |
|||
|
|||
const formData = new FormData(); |
|||
formData.append("file-num", fileNumInput.value); |
|||
formData.append("ejv-num", ejvNumInput.value); |
|||
formData.append("ejv-num-file", ejvNumFileInput.files[0]); |
|||
|
|||
fetch("/api/file/upd-ejv-num", { |
|||
method: "POST", |
|||
body: formData |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
if (data.resStat) { |
|||
alert(data.res); |
|||
form.reset(); |
|||
asFinalFileStatInput.value = ""; |
|||
ejvNumFileInput.disabled = true; |
|||
ejvNumInput.disabled = true; |
|||
submitBtn.disabled = true; |
|||
} else { |
|||
alert(data.res); |
|||
} |
|||
}) |
|||
.catch(error => { |
|||
console.error("Error:", error); |
|||
alert("Something went wrong while updating EJV."); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,351 @@ |
|||
document.addEventListener("DOMContentLoaded", function() { |
|||
|
|||
// ========== COMMON HELPERS ==========
|
|||
function getFileName(path) { |
|||
let fileSpan = "Uploaded file: "; |
|||
return (!path || path === '-' ? fileSpan + "N/A" : fileSpan + path.split(/[/\\]/).pop()); |
|||
} |
|||
|
|||
function formatDateForInput(dateStr) { |
|||
if (!dateStr || dateStr === '-' || dateStr === '1970-01-01') return ''; |
|||
const parts = dateStr.split('-'); // ["2024","09","09"]
|
|||
return `${parts[2]}-${parts[1]}-${parts[0]}`; // "09-09-2024"
|
|||
} |
|||
|
|||
// Debounce helper
|
|||
function debounce(func, delay) { |
|||
let timer; |
|||
return function(...args) { |
|||
clearTimeout(timer); |
|||
timer = setTimeout(() => func.apply(this, args), delay); |
|||
}; |
|||
} |
|||
|
|||
// ========== PART 1: AS/PI FILE SECTION (update-file-script.js logic) ==========
|
|||
["asFileGenDate", "piFileGenDate"].forEach(id => { |
|||
flatpickr("#" + id, { |
|||
dateFormat: "d-m-Y", |
|||
enableTime: false, |
|||
noCalendar: false, |
|||
allowInput: true |
|||
}); |
|||
}); |
|||
|
|||
const fileNumSelect = document.getElementById("fileNum"); |
|||
|
|||
const fileInputs = { |
|||
rtgsFile: 'selected-rtgs-file-name', |
|||
poFile: 'selected-po-file-name', |
|||
dcFile: 'selected-dc-file-name', |
|||
srFile: 'selected-sr-file-name', |
|||
irFile: 'selected-ir-file-name', |
|||
asFile: 'selected-as-file-name', |
|||
piFile: 'selected-pi-file-name', |
|||
asFileGenDate: null, |
|||
piFileGenDate: null, |
|||
piAmt: null, |
|||
fileRmrk: null, |
|||
advType: null, |
|||
vendName: null, |
|||
fundTypeId: null |
|||
}; |
|||
|
|||
function setInputsState(enabledIds = [], preserveValues = []) { |
|||
Object.keys(fileInputs).forEach(id => { |
|||
const input = document.getElementById(id); |
|||
const spanId = fileInputs[id]; |
|||
const span = spanId ? document.getElementById(spanId) : null; |
|||
|
|||
if (input) input.disabled = !enabledIds.includes(id); |
|||
|
|||
if (span) { |
|||
if (enabledIds.includes(id) || preserveValues.includes(id)) { |
|||
span.style.display = "inline"; |
|||
} else { |
|||
span.style.display = "none"; |
|||
if (!preserveValues.includes(id)) span.textContent = ""; |
|||
} |
|||
} |
|||
|
|||
if (!enabledIds.includes(id) && input && !preserveValues.includes(id)) { |
|||
input.value = ""; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
const list = document.getElementById("fileNumList"); |
|||
|
|||
const handleFileSelection = () => { |
|||
if (!fileNumSelect.value) { |
|||
setInputsState([]); |
|||
handleFIPanel(null); |
|||
return; |
|||
} |
|||
|
|||
// Find matching datalist option
|
|||
const selectedOption = Array.from(list.options).find(opt => opt.value === fileNumSelect.value); |
|||
|
|||
if (!selectedOption) { |
|||
setInputsState([]); |
|||
handleFIPanel(null); |
|||
return; |
|||
} |
|||
|
|||
const ejvNum = selectedOption.dataset.ejv; |
|||
const ejvPath = selectedOption.dataset.ejvPath; |
|||
const hasEJV = ejvNum && ejvNum !== '-' && ejvPath && ejvPath !== '-'; |
|||
|
|||
if (hasEJV) { |
|||
setInputsState(['fileRmrk'], ['piAmt', 'piFileGenDate', 'asFileGenDate', 'vendName', 'advType', 'fundTypeId']); |
|||
} else { |
|||
setInputsState(Object.keys(fileInputs)); |
|||
} |
|||
|
|||
document.getElementById("piAmt").value = selectedOption.dataset.piAmt || ''; |
|||
document.getElementById("advType").value = selectedOption.dataset.advType || ''; |
|||
document.getElementById("vendName").value = selectedOption.dataset.vendName || ''; |
|||
document.getElementById("asFileGenDate").value = formatDateForInput(selectedOption.dataset.asFileGenDate); |
|||
document.getElementById("piFileGenDate").value = formatDateForInput(selectedOption.dataset.piFileGenDate); |
|||
document.getElementById("fileRmrk").value = selectedOption.dataset.remarks || ''; |
|||
|
|||
const fundTypeSelect = document.getElementById("fundTypeId"); |
|||
const fundType = selectedOption.dataset.fundType || ''; |
|||
if (fundTypeSelect) { |
|||
fundTypeSelect.value = fundType; |
|||
} |
|||
|
|||
Object.keys(fileInputs).forEach(id => { |
|||
if (!['asFileGenDate', 'piFileGenDate', 'piAmt', 'fileRmrk', 'vendName', 'advType', 'fundTypeId'].includes(id)) { |
|||
const spanId = fileInputs[id]; |
|||
const span = spanId ? document.getElementById(spanId) : null; |
|||
const filePath = selectedOption.dataset[id] || ''; |
|||
if (span) { |
|||
span.style.display = "inline"; |
|||
span.textContent = getFileName(filePath); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
handleFIPanel(selectedOption, hasEJV); |
|||
}; |
|||
|
|||
// Wrap it with debounce (300ms delay)
|
|||
const debouncedHandle = debounce(handleFileSelection, 300); |
|||
|
|||
// Attach event listener
|
|||
fileNumSelect.addEventListener("input", debouncedHandle); |
|||
fileNumSelect.addEventListener("change", debouncedHandle); // optional, for safety
|
|||
|
|||
// ========== PART 2: FI / AS FINAL / TC SECTION (add-update-adjustment-script.js logic) ==========
|
|||
const piAmtInput = document.getElementById("piAmt"); |
|||
const fiFileGenDate = document.getElementById("fiFileGenDate"); |
|||
const fiAmtInput = document.getElementById("fiAmt"); |
|||
const balAmtInput = document.getElementById("balAmt"); |
|||
const asFinalFileGenDate = document.getElementById("asFinalFileGenDate"); |
|||
const tcFileGenDate = document.getElementById("tcFileGenDate"); |
|||
const submitBtn = document.querySelector(".submit-btn input[type='submit']"); |
|||
|
|||
const fiSectionInputs = ["fiFileGenDate", "fiFile", "fiAmt", "asFinalFile", "asFinalFileGenDate", "tcFileGenDate", "tcFile"]; |
|||
const fiSpans = ["selected-fi-file-name", "selected-as-final-file-name", "selected-tc-file-name"]; |
|||
|
|||
// Disable initially
|
|||
fiSectionInputs.forEach(id => { |
|||
const el = document.getElementById(id); |
|||
if (el) el.disabled = true; |
|||
}); |
|||
|
|||
// Initialize Flatpickr
|
|||
const fpFI = flatpickr(fiFileGenDate, { dateFormat: "d-m-Y", maxDate: "today", allowInput: true }); |
|||
const fpAS = flatpickr(asFinalFileGenDate, { dateFormat: "d-m-Y", maxDate: "today", allowInput: true }); |
|||
const fpTC = flatpickr(tcFileGenDate, { dateFormat: "d-m-Y", maxDate: "today", allowInput: true }); |
|||
|
|||
function handleFIPanel(selected, hasEJV = false) { |
|||
if (!selected) { |
|||
fiSectionInputs.forEach(id => document.getElementById(id).disabled = true); |
|||
if (submitBtn) submitBtn.disabled = true; |
|||
fiSpans.forEach(id => document.getElementById(id).textContent = ""); |
|||
if (fpFI) fpFI.clear(); |
|||
if (fpAS) fpAS.clear(); |
|||
if (fpTC) fpTC.clear(); |
|||
if (typeof piAmtInput !== "undefined" && piAmtInput) piAmtInput.value = ""; |
|||
if (typeof fiAmtInput !== "undefined" && fiAmtInput) fiAmtInput.value = ""; |
|||
if (typeof balAmtInput !== "undefined" && balAmtInput) balAmtInput.value = 0; |
|||
return; |
|||
} |
|||
|
|||
const ejvStat = selected.getAttribute("data-ejv-stat") === "true"; |
|||
const ejvFileStat = selected.getAttribute("data-ejv-file-stat") === "true"; |
|||
|
|||
// Fill data
|
|||
piAmtInput.value = parseFloat(selected.getAttribute("data-pi-amt") || 0) || 0; |
|||
fiAmtInput.value = selected.getAttribute("data-fi-amt") || ""; |
|||
balAmtInput.value = 0; |
|||
|
|||
// Trigger balance calculation when fiAmt is auto-filled
|
|||
fiAmtInput.dispatchEvent(new Event("input")); |
|||
|
|||
const files = { |
|||
"selected-fi-file-name": selected.getAttribute("data-fi-file"), |
|||
"selected-as-final-file-name": selected.getAttribute("data-as-final-file"), |
|||
"selected-tc-file-name": selected.getAttribute("data-tc-file") |
|||
}; |
|||
Object.entries(files).forEach(([spanId, path]) => { |
|||
document.getElementById(spanId).textContent = getFileName(path); |
|||
}); |
|||
|
|||
// Dates
|
|||
const fiVal = formatDateForInput(selected.getAttribute("data-fi-file-gen-date")); |
|||
const asVal = formatDateForInput(selected.getAttribute("data-as-final-file-gen-date")); |
|||
const tcVal = formatDateForInput(selected.getAttribute("data-tc-file-gen-date")); |
|||
|
|||
if (fiVal) fpFI.setDate(fiVal, true, "d-m-Y"); else fpFI.clear(); |
|||
if (asVal) fpAS.setDate(asVal, true, "d-m-Y"); else fpAS.clear(); |
|||
if (tcVal) fpTC.setDate(tcVal, true, "d-m-Y"); else fpTC.clear(); |
|||
|
|||
// Dependencies
|
|||
const piGenRaw = selected.getAttribute("data-pi-file-gen-date"); |
|||
if (piGenRaw && piGenRaw !== "-" && piGenRaw !== "1970-01-01") { |
|||
const [y, m, d] = piGenRaw.split("-"); // Fixed: y,m,d
|
|||
fpFI.set("minDate", new Date(y, m - 1, d)); |
|||
} else { |
|||
fpFI.set("minDate", null); |
|||
} |
|||
|
|||
if (fiVal) { |
|||
const [d, m, y] = fiVal.split("-"); |
|||
const fiDateObj = new Date(y, m - 1, d); |
|||
fpAS.set("minDate", fiDateObj); |
|||
fpTC.set("minDate", fiDateObj); |
|||
} else { |
|||
fpAS.set("minDate", null); |
|||
fpTC.set("minDate", null); |
|||
} |
|||
|
|||
// Enable/disable section
|
|||
if (hasEJV || ejvStat || ejvFileStat) { |
|||
fiSectionInputs.forEach(id => { |
|||
const el = document.getElementById(id); |
|||
if (el) el.disabled = true; |
|||
}); |
|||
// Allow submit if remarks are enabled (e.g., when hasEJV is true)
|
|||
if (submitBtn) submitBtn.disabled = !document.getElementById("fileRmrk")?.disabled ? false : true; |
|||
} else { |
|||
fiSectionInputs.forEach(id => { |
|||
const el = document.getElementById(id); |
|||
if (el) el.disabled = false; |
|||
}); |
|||
if (submitBtn) submitBtn.disabled = false; |
|||
} |
|||
} |
|||
|
|||
// Update AS/TC minDate when FI date changes manually
|
|||
if (fiFileGenDate) { |
|||
fiFileGenDate.addEventListener("change", function() { |
|||
const fiDate = this.value; |
|||
if (fiDate) { |
|||
const [d, m, y] = fiDate.split("-"); |
|||
const fiDateObj = new Date(y, m - 1, d); |
|||
fpAS.set("minDate", fiDateObj); |
|||
fpTC.set("minDate", fiDateObj); |
|||
} else { |
|||
fpAS.set("minDate", null); |
|||
fpTC.set("minDate", null); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// Balance calculation
|
|||
const calculateBalance = debounce(() => { |
|||
const piAmt = parseFloat(piAmtInput.value || 0); |
|||
const fiAmtRaw = fiAmtInput.value.trim(); |
|||
balAmtInput.value = fiAmtRaw ? Math.max(piAmt - parseFloat(fiAmtRaw), 0) : ""; |
|||
}, 500); |
|||
fiAmtInput.addEventListener("input", calculateBalance); |
|||
|
|||
// ----- Unified Form Submission (merged from update-file-script.js + add-update-adjustment-script.js) -----
|
|||
const form = document.getElementById("frm-file-det"); |
|||
form.addEventListener("submit", function(event) { |
|||
event.preventDefault(); |
|||
|
|||
const formData = new FormData(form); |
|||
|
|||
// ensure disabled inputs (advType, fundTypeId, etc.) are sent
|
|||
["advType", "fundTypeId"].forEach(id => { |
|||
const el = document.getElementById(id); |
|||
if (el && !formData.has(id)) { |
|||
formData.append(id, el.value || ""); |
|||
} |
|||
}); |
|||
|
|||
// Include balance amount if it exists
|
|||
if (typeof balAmtInput !== "undefined" && balAmtInput) { |
|||
formData.append("balAmt", balAmtInput.value || ""); |
|||
} |
|||
|
|||
fetch(form.getAttribute("action"), { |
|||
method: form.getAttribute("method") || "POST", |
|||
body: formData |
|||
}) |
|||
.then(res => res.ok ? res.json() : Promise.reject("Network response not ok")) |
|||
.then(data => { |
|||
if (data.resStat) { |
|||
alert(data.res || "Form submitted successfully!"); |
|||
|
|||
// Reset the form and UI
|
|||
form.reset(); |
|||
|
|||
// Reset AS/PI section
|
|||
const asFileGenDateEl = document.getElementById("asFileGenDate"); |
|||
const piFileGenDateEl = document.getElementById("piFileGenDate"); |
|||
const fundTypeSelect = document.getElementById("fundTypeId"); |
|||
|
|||
if (fundTypeSelect) { |
|||
fundTypeSelect.value = ""; |
|||
fundTypeSelect.disabled = false; |
|||
} |
|||
if (asFileGenDateEl) asFileGenDateEl.value = ""; |
|||
if (piFileGenDateEl) piFileGenDateEl.value = ""; |
|||
if (document.getElementById("fileRmrk")) document.getElementById("fileRmrk").value = ""; |
|||
|
|||
// Reset FI/AS Final/TC section
|
|||
if (typeof piAmtInput !== "undefined" && piAmtInput) piAmtInput.value = 0; |
|||
if (typeof balAmtInput !== "undefined" && balAmtInput) balAmtInput.value = 0; |
|||
if (typeof fiAmtInput !== "undefined" && fiAmtInput) fiAmtInput.value = ""; |
|||
|
|||
if (typeof fileNameSpans !== "undefined") { |
|||
fileNameSpans.forEach(id => { |
|||
const span = document.getElementById(id); |
|||
if (span) span.textContent = ""; |
|||
}); |
|||
} |
|||
|
|||
// Clear Flatpickr pickers if available
|
|||
if (typeof fpFI !== "undefined" && fpFI) { |
|||
fpFI.clear(); |
|||
fpFI.set("minDate", null); |
|||
} |
|||
if (typeof fpAS !== "undefined" && fpAS) { |
|||
fpAS.clear(); |
|||
fpAS.set("minDate", null); |
|||
} |
|||
if (typeof fpTC !== "undefined" && fpTC) { |
|||
fpTC.clear(); |
|||
fpTC.set("minDate", null); |
|||
} |
|||
|
|||
fileNumSelect.selectedIndex = 0; |
|||
fileNumSelect.dispatchEvent(new Event('change')); |
|||
console.log("Response:", data); |
|||
} else { |
|||
alert("Submission failed: " + (data.res || "Unknown error")); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
console.error("Error submitting form:", err); |
|||
alert("Error submitting form. Check console for details."); |
|||
}); |
|||
}); |
|||
|
|||
// Initial trigger
|
|||
fileNumSelect.dispatchEvent(new Event('change')); |
|||
}); |
|||
@ -0,0 +1,157 @@ |
|||
// Function to view Supporting Document in modal
|
|||
function viewFileInModal(fileNum, fileType, filePath) { |
|||
var pdfModal = new bootstrap.Modal(document.getElementById('pdf-modal')); |
|||
var modalTitle = document.getElementById('pdf-modal-label'); |
|||
var pdfContainer = document.getElementById('pdf-container'); |
|||
pdfContainer.innerHTML = ''; // Clear previous pages
|
|||
|
|||
var decodedFilePath = decodeURIComponent(filePath); |
|||
var fileName = decodedFilePath.split(/[\\/]/).pop(); |
|||
modalTitle.textContent = fileType + " File (" + fileName + ")"; |
|||
|
|||
/*var userId = document.getElementById('hid_user_id').value;*/ |
|||
|
|||
var params = new URLSearchParams(); |
|||
params.append('file-type', fileType); |
|||
params.append('file-path', decodedFilePath); |
|||
/*params.append('user_id', userId);*/ |
|||
params.append('file-num', fileNum); // matches data-file-num
|
|||
|
|||
fetch('/api/file/view-supp-docs', { // Controller endpoint
|
|||
method: 'POST', |
|||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
|||
body: params.toString() |
|||
}).then(function(response) { |
|||
if (!response.ok) { |
|||
throw new Error('Failed to fetch PDF: ' + response.statusText); |
|||
} |
|||
return response.arrayBuffer(); |
|||
}).then(function(pdfData) { |
|||
var blob = new Blob([pdfData], { type: 'application/pdf' }); |
|||
var blobUrl = URL.createObjectURL(blob); |
|||
|
|||
// Set download link
|
|||
var downloadBtn = document.getElementById('download-pdf-btn'); |
|||
downloadBtn.href = blobUrl; |
|||
downloadBtn.download = fileName; |
|||
|
|||
return pdfjsLib.getDocument({ data: pdfData }).promise; |
|||
}).then(function(pdf) { |
|||
let renderPage = function(pageNum) { |
|||
return pdf.getPage(pageNum).then(function(page) { |
|||
var viewport = page.getViewport({ scale: 1.5 }); |
|||
var canvas = document.createElement('canvas'); |
|||
canvas.classList.add('mb-3'); |
|||
var ctx = canvas.getContext('2d'); |
|||
canvas.height = viewport.height; |
|||
canvas.width = viewport.width; |
|||
|
|||
var renderContext = { canvasContext: ctx, viewport: viewport }; |
|||
pdfContainer.appendChild(canvas); |
|||
return page.render(renderContext).promise; |
|||
}); |
|||
}; |
|||
|
|||
// Render all pages sequentially
|
|||
let sequence = Promise.resolve(); |
|||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) { |
|||
sequence = sequence.then(() => renderPage(pageNum)); |
|||
} |
|||
|
|||
return sequence; |
|||
}).then(function() { |
|||
pdfModal.show(); |
|||
}).catch(function(error) { |
|||
alert('Error loading PDF: ' + error.message); |
|||
}); |
|||
} |
|||
|
|||
$(document).ready(function() { |
|||
|
|||
// Initialize DataTable
|
|||
var table = $('#file-data-det-tbl').DataTable({ |
|||
paging: true, |
|||
searching: true, |
|||
ordering: true, |
|||
lengthChange: true, |
|||
pageLength: 10, |
|||
language: { |
|||
emptyTable: "No data available", |
|||
lengthMenu: "Display _MENU_ records per page", |
|||
info: "Showing _START_ to _END_ of _TOTAL_ entries", |
|||
infoEmpty: "No records to show", |
|||
infoFiltered: "(filtered from _MAX_ total records)" |
|||
}, |
|||
columnDefs: [ |
|||
{ |
|||
orderable: false, |
|||
targets: 0, // S.No column
|
|||
render: function(data, type, row, meta) { |
|||
return meta.row + 1; |
|||
} |
|||
} |
|||
], |
|||
buttons: [ |
|||
{ |
|||
extend: 'excelHtml5', |
|||
title: "File Details", |
|||
filename: "File Details", |
|||
exportOptions: { |
|||
columns: ':visible:not(:eq(11))' // exclude 12th column
|
|||
} |
|||
}, |
|||
'pdfHtml5' |
|||
] |
|||
}); |
|||
|
|||
// Move DataTable controls to custom container
|
|||
$('#custom-pagination').html($('.dataTables_paginate')); |
|||
$('#custom-info').html($('.dataTables_info')); |
|||
$('#custom-length').html($('.dataTables_length')); |
|||
|
|||
// Custom export buttons
|
|||
$('#export-excel').on('click', function() { |
|||
table.button('.buttons-excel').trigger(); |
|||
}); |
|||
|
|||
$('#export-pdf').on('click', function() { |
|||
var originalLength = table.page.len(); |
|||
table.one('draw', function() { |
|||
var tableClone = $('#file-det-tbl').clone(); |
|||
tableClone.removeClass('dataTable'); |
|||
tableClone.find('thead, tbody, tfoot').removeAttr('style'); |
|||
|
|||
// Remove "Supporting Documents" column (13th col = index 12)
|
|||
tableClone.find('tr').each(function() { |
|||
$(this).find('th:eq(12), td:eq(12)').remove(); |
|||
}); |
|||
|
|||
var pdfContainer = $('#pdf-print-container'); |
|||
pdfContainer.html('<h2 style="text-align:center;">File Details</h2>'); |
|||
pdfContainer.append(tableClone).css({ display: 'block', padding: '20px' }); |
|||
|
|||
tableClone.css({ width: '100%', borderCollapse: 'collapse' }); |
|||
tableClone.find('th, td').css( |
|||
{ |
|||
border: '1px solid #ccc', |
|||
padding: '5px', |
|||
fontSize: '10px', |
|||
textAlign: 'left', |
|||
verticalAlign: 'top' |
|||
}); |
|||
tableClone.find('tr').css({ pageBreakInside: 'avoid', breakInside: 'avoid', webkitBreakInside: 'avoid' }); |
|||
|
|||
html2pdf().set({ |
|||
margin: 0.5, |
|||
filename: 'File Details.pdf', |
|||
image: { type: 'jpeg', quality: 0.98 }, |
|||
html2canvas: { scale: 2, useCORS: true }, |
|||
jsPDF: { unit: 'in', format: 'a3', orientation: 'landscape' } |
|||
}).from(pdfContainer[0]).save().then(function() { |
|||
table.page.len(originalLength).draw(); |
|||
pdfContainer.hide(); |
|||
}); |
|||
}); |
|||
table.page.len(-1).draw(); // show all rows for PDF
|
|||
}); |
|||
}); |
|||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue