Browse Source

initial commit

master
KaNi-04 2 months ago
commit
5b8f676f92
  1. 28
      HELP.md
  2. 295
      mvnw
  3. 189
      mvnw.cmd
  4. 74
      pom.xml
  5. 13
      src/main/java/com/gcc/pospostdata/PospostdataApplication.java
  6. 58
      src/main/java/com/gcc/pospostdata/configuration/DataSourceConfig.java
  7. 53
      src/main/java/com/gcc/pospostdata/controller/POSDataController.java
  8. 38
      src/main/java/com/gcc/pospostdata/service/DateTimeUtil.java
  9. 753
      src/main/java/com/gcc/pospostdata/service/POSDataService.java
  10. 3
      src/main/resources/application-local.properties
  11. 3
      src/main/resources/application-production.properties
  12. 17
      src/main/resources/application.properties
  13. 13
      src/test/java/com/gcc/pospostdata/PospostdataApplicationTests.java

28
HELP.md

@ -0,0 +1,28 @@
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/4.1.0/maven-plugin)
* [Create an OCI image](https://docs.spring.io/spring-boot/4.1.0/maven-plugin/build-image.html)
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/4.1.0/reference/using/devtools.html)
* [Spring Web](https://docs.spring.io/spring-boot/4.1.0/reference/web/servlet.html)
* [Spring Data JDBC](https://docs.spring.io/spring-boot/4.1.0/reference/data/sql.html#data.sql.jdbc)
### Guides
The following guides illustrate how to use some features concretely:
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
* [Using Spring Data JDBC](https://github.com/spring-projects/spring-data-examples/tree/main/jdbc/basics)
* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/)
### Maven Parent overrides
Due to Maven's design, elements are inherited from the parent POM to the project POM.
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

295
mvnw

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

189
mvnw.cmd

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

74
pom.xml

@ -0,0 +1,74 @@
<?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>4.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gcc</groupId>
<artifactId>pospostdata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name/>
<description/>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

13
src/main/java/com/gcc/pospostdata/PospostdataApplication.java

@ -0,0 +1,13 @@
package com.gcc.pospostdata;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PospostdataApplication {
public static void main(String[] args) {
SpringApplication.run(PospostdataApplication.class, args);
}
}

58
src/main/java/com/gcc/pospostdata/configuration/DataSourceConfig.java

@ -0,0 +1,58 @@
package com.gcc.pospostdata.configuration;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
// private static String host = "localhost:3306";
// private static String dbpassword = "root";
// AWS
private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306";
private static String dbpassword = "gcc-facial-password";
@Bean(name = "mysqlPenaltyDataSource")
public DataSource mysqlPenaltyDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_penalty_pos");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
return dataSource;
}
@Bean(name = "mysqlPOSDataSource")
public DataSource mysqlPOSDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/erp_pos_data");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
return dataSource;
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager posTransactionManager(
@Qualifier("mysqlPOSDataSource") DataSource posDataSource) {
return new DataSourceTransactionManager(posDataSource);
}
@Bean(name = "penaltyTransactionManager")
public PlatformTransactionManager penaltyTransactionManager(
@Qualifier("mysqlPenaltyDataSource") DataSource penaltyDataSource) {
return new DataSourceTransactionManager(penaltyDataSource);
}
}

53
src/main/java/com/gcc/pospostdata/controller/POSDataController.java

@ -0,0 +1,53 @@
package com.gcc.pospostdata.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.gcc.pospostdata.service.POSDataService;
@RequestMapping("/gccpospostdata/api")
@RestController("apiPOSpostdataRest")
public class POSDataController {
@Autowired
POSDataService posDataService;
@PostMapping("/storeBankTransaction")
public List<?> storeBankTransaction(@RequestBody Map<String, Object> transactionData) {
return posDataService.storeBankTransaction(transactionData);
}
@PostMapping("/storeFailedBankTransaction")
public List<?> storeFailedBankTransaction(@RequestBody Map<String, Object> transactionData) {
return posDataService.storeFailedBankTransaction(transactionData);
}
@PostMapping(value = "/storeOfflineTransaction")
public List<?> generateOfflineChallan(@RequestParam MultiValueMap<String, String> formData,
@RequestParam(value = "transactionResponseStatus", required = false) String transactionResponseStatus,
@RequestParam(value = "bankName", required = false) String bankName,
@RequestParam(value = "transactionAmount", required = false) String transactionAmount,
@RequestParam(value = "txnDate", required = false) String txnDate,
@RequestParam(value = "txnTime", required = false) String txnTime,
@RequestParam(value = "branchname", required = false) String branchname,
@RequestParam(value = "extraInfo", required = false) String extraInfo,
@RequestParam(value = "extraInfo2", required = false) String extraInfo2,
@RequestParam(value = "extraInfo3", required = false) String extraInfo3,
@RequestParam(value = "txnMode", required = false) String txnMode,
@RequestParam(value = "txnId", required = false) String txnId,
@RequestParam(value = "file", required = false) MultipartFile file) {
return posDataService.storeOfflineTransaction(formData, transactionResponseStatus, bankName,
transactionAmount, txnDate, txnTime, branchname, extraInfo, extraInfo2, extraInfo3, txnMode, txnId,
file);
}
}

38
src/main/java/com/gcc/pospostdata/service/DateTimeUtil.java

@ -0,0 +1,38 @@
package com.gcc.pospostdata.service;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
public class DateTimeUtil {
public static String getCurrentDateTime() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyyHHmmss");
LocalDateTime now = LocalDateTime.now();
return now.format(formatter);
}
public static String getCurrentYear() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
LocalDateTime now = LocalDateTime.now();
return now.format(formatter);
}
public static String getCurrentMonth() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM");
LocalDateTime now = LocalDateTime.now();
return now.format(formatter);
}
public static String getCurrentDay() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd");
LocalDateTime now = LocalDateTime.now();
return now.format(formatter);
}
public static String getCurrentDateTimeMysql() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
return now.format(formatter);
}
}

753
src/main/java/com/gcc/pospostdata/service/POSDataService.java

@ -0,0 +1,753 @@
package com.gcc.pospostdata.service;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import tools.jackson.databind.ObjectMapper;
@Service
public class POSDataService {
private JdbcTemplate jdbcPOSDataTemplate;
private final Environment environment;
private String fileBaseUrl;
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final int STRING_LENGTH = 15;
private static final Random RANDOM = new SecureRandom();
@Autowired
public void setDataSource(@Qualifier("mysqlPOSDataSource") DataSource posDataSource) {
this.jdbcPOSDataTemplate = new JdbcTemplate(posDataSource);
}
@Autowired
public POSDataService(Environment environment) {
this.environment = environment;
this.fileBaseUrl = environment.getProperty("fileBaseUrl");
}
public static String generateRandomString() {
StringBuilder result = new StringBuilder(STRING_LENGTH);
for (int i = 0; i < STRING_LENGTH; i++) {
result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length())));
}
return result.toString();
}
// Function to convert date string from dd-MM-yyyy to yyyy-MM-dd
public static String convertDateFormat(String inputDate, int add) {
// Check if the inputDate is not null or blank
if (inputDate != null && !inputDate.isBlank()) {
try {
// Define the input and output date formats
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// Parse the input date string to LocalDate
LocalDate date = LocalDate.parse(inputDate, inputFormatter);
// Add the specified number of days to the date if 'add' is greater than 0
if (add > 0) {
date = date.plusDays(add);
}
// Format the date to the new format
return date.format(outputFormatter);
} catch (DateTimeParseException e) {
// Handle the case where the input date is invalid
System.out.println("Invalid date format: " + inputDate);
return "";
}
} else {
return "";
}
}
private byte[] compressImage(BufferedImage image, float quality) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(imageOutputStream);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
writer.write(null, new javax.imageio.IIOImage(image, null, null), param);
writer.dispose();
imageOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
public String fileUpload(String name, String id, MultipartFile file) {
int lastInsertId = 0;
// Set the file path where you want to save it
String uploadDirectory = environment.getProperty("file.upload.directory");
String serviceFolderName = environment.getProperty("penalty_foldername");
var year = DateTimeUtil.getCurrentYear();
var month = DateTimeUtil.getCurrentMonth();
uploadDirectory = uploadDirectory + serviceFolderName + "pos/" + year + "/" + month + "/";
try {
// Create directory if it doesn't exist
Path directoryPath = Paths.get(uploadDirectory);
if (!Files.exists(directoryPath)) {
Files.createDirectories(directoryPath);
}
// Datetime string
String datetimetxt = DateTimeUtil.getCurrentDateTime();
// File name
String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename();
fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename
String filePath = uploadDirectory + "/" + fileName;
String filepath_txt = "/" + serviceFolderName + "pos/" + year + "/" + month + "/" + fileName;
// Create a new Path object
Path path = Paths.get(filePath);
// Get the bytes of the file
byte[] bytes = file.getBytes();
// Compress the image
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality
// Write the bytes to the file
Files.write(path, bytes);
System.out.println(filePath);
return filepath_txt;
} catch (IOException e) {
e.printStackTrace();
return "Failed to save file " + file.getOriginalFilename();
}
}
private String safeStr(Map<String, Object> map, String key) {
Object val = map.get(key);
return val != null ? val.toString() : null;
}
private Integer safeInt(Map<String, Object> map, String key) {
Object val = map.get(key);
if (val == null)
return null;
if (val instanceof Number)
return ((Number) val).intValue();
try {
return Integer.parseInt(val.toString());
} catch (NumberFormatException e) {
return null;
}
}
private Long safeLong(Map<String, Object> map, String key) {
Object val = map.get(key);
if (val == null)
return null;
if (val instanceof Number)
return ((Number) val).longValue();
try {
return Long.parseLong(val.toString());
} catch (NumberFormatException e) {
return null;
}
}
private Double safeDouble(Map<String, Object> map, String key) {
Object val = map.get(key);
if (val == null)
return null;
if (val instanceof Number)
return ((Number) val).doubleValue();
try {
return Double.parseDouble(val.toString());
} catch (NumberFormatException e) {
return null;
}
}
private Boolean safeBool(Map<String, Object> map, String key) {
Object val = map.get(key);
if (val == null)
return null;
if (val instanceof Boolean)
return (Boolean) val;
return Boolean.parseBoolean(val.toString());
}
@Transactional
@SuppressWarnings("unchecked")
public List<Map<String, Object>> storeBankTransaction(Map<String, Object> transactionData) {
Map<String, Object> response = new HashMap<>();
try {
// Convert raw request to JSON string for response_json column
ObjectMapper objectMapper = new ObjectMapper();
String responseJson = objectMapper.writeValueAsString(transactionData);
// Extract nested sections
Map<String, Object> detail = (Map<String, Object>) transactionData.get("Detail");
Map<String, Object> header = (Map<String, Object>) transactionData.get("Header");
Map<String, Object> resp = (Map<String, Object>) transactionData.get("Response");
if (detail == null || header == null || resp == null) {
response.put("status", 400);
response.put("message", "Invalid payload: Detail, Header, and Response sections are required.");
return Collections.singletonList(response);
}
// --- Detail fields ---
String acquirerName = safeStr(detail, "AcquirerName");
Integer acquiringBankCode = safeInt(detail, "AcquiringBankCode");
Double amountProcessed = safeDouble(detail, "AmountProcessed");
String approvalCode = safeStr(detail, "ApprovalCode");
Long authAmoutPaise = safeLong(detail, "AuthAmoutPaise");
Integer batchNumber = safeInt(detail, "BatchNumber");
String billingRefNo = safeStr(detail, "BillingRefNo");
String cardNumber = safeStr(detail, "CardNumber");
String cardType = safeStr(detail, "CardType");
String hostResponse = safeStr(detail, "HostResponse");
Integer invoiceNumber = safeInt(detail, "InvoiceNumber");
Integer loyaltyPointsAwarded = safeInt(detail, "LoyaltyPointsAwarded");
String merchantAddress = safeStr(detail, "MerchantAddress");
String merchantCity = safeStr(detail, "MerchantCity");
String merchantId = safeStr(detail, "MerchantId");
String merchantName = safeStr(detail, "MerchantName");
Long plutusTransactionLogId = safeLong(detail, "PlutusTransactionLogID");
String plutusVersion = safeStr(detail, "PlutusVersion");
Integer printCardholderName = safeInt(detail, "PrintCardholderName");
String remark = safeStr(detail, "Remark");
String retrievalReferenceNumber = safeStr(detail, "RetrievalReferenceNumber");
String terminalId = safeStr(detail, "TerminalId");
String transactionDate = safeStr(detail, "TransactionDate");
String transactionTime = safeStr(detail, "TransactionTime");
Integer transactionType = safeInt(detail, "TransactionType");
Boolean isTransitMode = safeBool(detail, "isTransitMode");
// --- Header fields ---
String applicationId = safeStr(header, "ApplicationId");
Integer methodId = safeInt(header, "MethodId");
Long userId = safeLong(header, "UserId");
String versionNo = safeStr(header, "VersionNo");
Long clientId = safeLong(header, "ClientId");
String deviceSn = safeStr(header, "DeviceSN");
// --- Response fields ---
String appVersion = safeStr(resp, "AppVersion");
String parameterJson = safeStr(resp, "ParameterJson");
Integer responseCode = safeInt(resp, "ResponseCode");
String responseMsg = safeStr(resp, "ResponseMsg");
// Shared final for both inserts
final String f_responseJson = responseJson;
// Step 1: Insert raw JSON into payment_response table
String paymentResponseSql = "INSERT INTO payment_response (response_json) VALUES (?)";
KeyHolder paymentResponseKeyHolder = new GeneratedKeyHolder();
jdbcPOSDataTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(paymentResponseSql, new String[] { "id" });
ps.setString(1, f_responseJson);
return ps;
}
}, paymentResponseKeyHolder);
// Step 2: Insert parsed fields into bank_transactions table
String sqlQuery = "INSERT INTO bank_transactions ("
+ "response_json, "
// Detail
+ "acquirer_name, acquiring_bank_code, amount_processed, approval_code, auth_amout_paise, "
+ "batch_number, billing_ref_no, card_number, card_type, host_response, invoice_number, "
+ "loyalty_points_awarded, merchant_address, merchant_city, merchant_id, merchant_name, "
+ "plutus_transaction_log_id, plutus_version, print_cardholder_name, remark, "
+ "retrieval_reference_number, terminal_id, transaction_date, transaction_time, "
+ "transaction_type, is_transit_mode, "
// Header
+ "application_id, method_id, user_id, version_no, client_id, device_sn, "
// Response
+ "app_version, parameter_json, response_code, response_msg"
+ ") VALUES ("
+ "?, "
+ "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?"
+ ")";
KeyHolder keyHolder = new GeneratedKeyHolder();
// Capture finals for lambda (f_responseJson already declared above)
final String f_acquirerName = acquirerName;
final Integer f_acquiringBankCode = acquiringBankCode;
final Double f_amountProcessed = amountProcessed;
final String f_approvalCode = approvalCode;
final Long f_authAmoutPaise = authAmoutPaise;
final Integer f_batchNumber = batchNumber;
final String f_billingRefNo = billingRefNo;
final String f_cardNumber = cardNumber;
final String f_cardType = cardType;
final String f_hostResponse = hostResponse;
final Integer f_invoiceNumber = invoiceNumber;
final Integer f_loyaltyPointsAwarded = loyaltyPointsAwarded;
final String f_merchantAddress = merchantAddress;
final String f_merchantCity = merchantCity;
final String f_merchantId = merchantId;
final String f_merchantName = merchantName;
final Long f_plutusTransactionLogId = plutusTransactionLogId;
final String f_plutusVersion = plutusVersion;
final Integer f_printCardholderName = printCardholderName;
final String f_remark = remark;
final String f_retrievalReferenceNumber = retrievalReferenceNumber;
final String f_terminalId = terminalId;
final String f_transactionDate = transactionDate;
final String f_transactionTime = transactionTime;
final Integer f_transactionType = transactionType;
final Boolean f_isTransitMode = isTransitMode;
final String f_applicationId = applicationId;
final Integer f_methodId = methodId;
final Long f_userId = userId;
final String f_versionNo = versionNo;
final Long f_clientId = clientId;
final String f_deviceSn = deviceSn;
final String f_appVersion = appVersion;
final String f_parameterJson = parameterJson;
final Integer f_responseCode = responseCode;
final String f_responseMsg = responseMsg;
int affectedRows = jdbcPOSDataTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "id" });
int i = 1;
ps.setString(i++, f_responseJson);
// Detail
ps.setString(i++, f_acquirerName);
if (f_acquiringBankCode != null)
ps.setInt(i++, f_acquiringBankCode);
else
ps.setNull(i++, Types.INTEGER);
if (f_amountProcessed != null)
ps.setDouble(i++, f_amountProcessed);
else
ps.setNull(i++, Types.DECIMAL);
ps.setString(i++, f_approvalCode);
if (f_authAmoutPaise != null)
ps.setLong(i++, f_authAmoutPaise);
else
ps.setNull(i++, Types.BIGINT);
if (f_batchNumber != null)
ps.setInt(i++, f_batchNumber);
else
ps.setNull(i++, Types.INTEGER);
ps.setString(i++, f_billingRefNo);
ps.setString(i++, f_cardNumber);
ps.setString(i++, f_cardType);
ps.setString(i++, f_hostResponse);
if (f_invoiceNumber != null)
ps.setInt(i++, f_invoiceNumber);
else
ps.setNull(i++, Types.INTEGER);
if (f_loyaltyPointsAwarded != null)
ps.setInt(i++, f_loyaltyPointsAwarded);
else
ps.setNull(i++, Types.INTEGER);
ps.setString(i++, f_merchantAddress);
ps.setString(i++, f_merchantCity);
ps.setString(i++, f_merchantId);
ps.setString(i++, f_merchantName);
if (f_plutusTransactionLogId != null)
ps.setLong(i++, f_plutusTransactionLogId);
else
ps.setNull(i++, Types.BIGINT);
ps.setString(i++, f_plutusVersion);
if (f_printCardholderName != null)
ps.setInt(i++, f_printCardholderName);
else
ps.setNull(i++, Types.TINYINT);
ps.setString(i++, f_remark);
ps.setString(i++, f_retrievalReferenceNumber);
ps.setString(i++, f_terminalId);
ps.setString(i++, f_transactionDate);
ps.setString(i++, f_transactionTime);
if (f_transactionType != null)
ps.setInt(i++, f_transactionType);
else
ps.setNull(i++, Types.INTEGER);
if (f_isTransitMode != null)
ps.setBoolean(i++, f_isTransitMode);
else
ps.setNull(i++, Types.BOOLEAN);
// Header
ps.setString(i++, f_applicationId);
if (f_methodId != null)
ps.setInt(i++, f_methodId);
else
ps.setNull(i++, Types.INTEGER);
if (f_userId != null)
ps.setLong(i++, f_userId);
else
ps.setNull(i++, Types.BIGINT);
ps.setString(i++, f_versionNo);
if (f_clientId != null)
ps.setLong(i++, f_clientId);
else
ps.setNull(i++, Types.BIGINT);
ps.setString(i++, f_deviceSn);
// Response
ps.setString(i++, f_appVersion);
ps.setString(i++, f_parameterJson);
if (f_responseCode != null)
ps.setInt(i++, f_responseCode);
else
ps.setNull(i++, Types.INTEGER);
ps.setString(i++, f_responseMsg);
return ps;
}
}, keyHolder);
if (affectedRows > 0) {
Number generatedId = keyHolder.getKey();
long insertedId = (generatedId != null) ? generatedId.longValue() : 0;
// Fetch and return the inserted record
// String selectSql = "SELECT * FROM bank_transactions WHERE id = ? LIMIT 1";
// List<Map<String, Object>> result =
// jdbcPOSDataTemplate.queryForList(selectSql, insertedId);
response.put("status", 200);
response.put("message", "Transaction stored successfully!");
// response.put("data", result.isEmpty() ? null : result.get(0));
} else {
response.put("status", 201);
response.put("message", "Failed to store the transaction.");
response.put("data", null);
}
} catch (DataAccessException e) {
response.put("status", 500);
response.put("message", "Database error while storing transaction.");
response.put("error", e.getMessage());
e.printStackTrace();
} catch (Exception e) {
response.put("status", 500);
response.put("message", "Unexpected error while processing transaction.");
response.put("error", e.getMessage());
e.printStackTrace();
}
return Collections.singletonList(response);
}
@Transactional
public List<Map<String, Object>> storeFailedBankTransaction(Map<String, Object> transactionData) {
Map<String, Object> response = new HashMap<>();
int lastInsertId = 0;
// Extract data from the JSON object
String transactionResponseStatus = (String) transactionData.get("transactionResponseStatus");
// Check if the transaction was successful
if ("Transaction cancelled".equalsIgnoreCase(transactionResponseStatus)) {
String mid = (String) transactionData.get("mid");
String tid = (String) transactionData.get("tid");
String txnId = (String) transactionData.get("txnId");
// Fetch nested transaction response data
Map<String, Object> txnResponseData = (Map<String, Object>) transactionData.get("txnResponseData");
String bankName = (String) txnResponseData.get("bankName");
String batchNumber = (String) txnResponseData.get("batchNumber");
String transactionTitle = (String) txnResponseData.get("transactionTitle");
String txnAID = (String) txnResponseData.get("txnAID");
String txnApprCode = (String) txnResponseData.get("txnApprCode");
String txnCardNo = (String) txnResponseData.get("txnCardNo");
String txnCardType = (String) txnResponseData.get("txnCardType");
String txnDate = (String) txnResponseData.get("txnDate");
String txnInvoice = (String) txnResponseData.get("txnInvoice");
String txnMode = (String) txnResponseData.get("txnMode");
String txnRefNo = (String) txnResponseData.get("txnRefNo");
String txnTC = (String) txnResponseData.get("txnTC");
String txnTSI = (String) txnResponseData.get("txnTSI");
String txnTVR = (String) txnResponseData.get("txnTVR");
String txnTime = (String) txnResponseData.get("txnTime");
// Convert transaction amount properly
// Double transactionAmount = Double.valueOf((String)
// txnResponseData.get("transactionAmount"));
// Get the transactionAmount from txnResponseData
String transactionAmountStr = (String) txnResponseData.get("transactionAmount");
// Check if the transactionAmount is not null and not empty before converting
Double transactionAmountTemp = null;
if (transactionAmountStr != null && !transactionAmountStr.trim().isEmpty()) {
try {
// Convert the valid string to a Double
transactionAmountTemp = Double.valueOf(transactionAmountStr);
} catch (NumberFormatException e) {
// Handle the case where the string cannot be parsed to a Double // Log the
// error or throw a custom exception
System.out.println("Error: Unable to parse transactionAmount to Double. " + e.getMessage());
transactionAmountTemp = 0.0; // Set to a default value or handle as needed
}
} else {
// Handle the case where transactionAmount is empty or null
transactionAmountTemp = 0.0; // Default value or handle as needed
}
Double transactionAmount = transactionAmountTemp;
String sqlQuery = "INSERT INTO bank_failed_transactions (mid, tid, txnId, bankName, batchNumber, transactionAmount, "
+ "transactionTitle, txnAID, txnApprCode, txnCardNo, txnCardType, txnDate, txnInvoice, txnMode, txnRefNo, "
+ "txnTC, txnTSI, txnTVR, txnTime) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
try {
int affectedRows = jdbcPOSDataTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "id" });
ps.setString(1, mid);
ps.setString(2, tid);
ps.setString(3, txnId);
ps.setString(4, bankName);
ps.setString(5, batchNumber);
ps.setDouble(6, transactionAmount);
ps.setString(7, transactionTitle);
ps.setString(8, txnAID);
ps.setString(9, txnApprCode);
ps.setString(10, txnCardNo);
ps.setString(11, txnCardType);
ps.setString(12, txnDate);
ps.setString(13, txnInvoice);
ps.setString(14, txnMode);
ps.setString(15, txnRefNo);
ps.setString(16, txnTC);
ps.setString(17, txnTSI);
ps.setString(18, txnTVR);
ps.setString(19, txnTime);
return ps;
}
}, keyHolder);
if (affectedRows > 0) {
Number generatedId = keyHolder.getKey();
lastInsertId = (generatedId != null) ? generatedId.intValue() : 0;
// updatePaymentStatus(txnId, transactionResponseStatus);
// Fetch inserted data for response, joining `penalty_challan` and
// `bank_transactions`
// String sqlQuery_joined = "SELECT pc.category_id, CONCAT('" + fileBaseUrl
// + "/gccofficialapp/files', pc.image) as imageurl, "
// + "pc.latitude, pc.longitude, pc.zone, pc.ward, pc.challan_by, "
// + "pc.violator_name, pc.violator_phone, pc.ton, pc.fine_amount, pc.orderid,
// pc.status, "
// + "bt.mid, bt.tid, bt.txnId, bt.bankName, bt.batchNumber,
// bt.transactionAmount, bt.transactionTitle, "
// + "bt.txnCardNo, bt.txnDate, bt.txnInvoice, bt.txnMode, bt.txnRefNo "
// + "FROM penalty_challan pc "
// + "LEFT JOIN bank_transactions bt ON pc.orderid = bt.txnId "
// + "WHERE pc.isactive = 1 AND pc.isdelete = 0 AND bt.txnId = ? LIMIT 1";
// System.out.println(sqlQuery_joined);
// // Execute the query
// List<Map<String, Object>> result =
// jdbcPOSDataTemplate.queryForList(sqlQuery_joined, txnId);
response.put("status", 200);
response.put("message", "Transaction stored successfully!");
// response.put("data", result);
} else {
response.put("status", 201);
response.put("message", "Failed to store the transaction.");
response.put("data", "");
}
} catch (DataAccessException e) {
response.put("status", 500);
response.put("message", "Database error while storing transaction.");
response.put("error", e.getMessage());
e.printStackTrace(); // This will give you more detail in logs
}
} else {
response.put("status", 400);
response.put("message", "Transaction failed or invalid status.");
}
return Collections.singletonList(response);
}
public String updatePaymentStatus(String orderid, String status) {
String sqlQuery = "UPDATE penalty_challan SET status = ? WHERE orderid = ? LIMIT 1";
jdbcPOSDataTemplate.update(sqlQuery, status, orderid);
return "success";
}
@Transactional
public List<Map<String, Object>> storeOfflineTransaction(
MultiValueMap<String, String> formData,
String transactionResponseStatus,
String bankName,
String transactionAmount,
String txnDate,
String txnTime,
String branchname,
String extraInfo,
String extraInfo2,
String extraInfo3,
String txnMode,
String txnId,
MultipartFile file) {
Map<String, Object> response = new HashMap<>();
int lastInsertId = 0;
String orderid = generateRandomString();
String image = fileUpload("offline", extraInfo, file);
// Convert transaction amount properly
Double transactionAmount_d = Double.valueOf(transactionAmount); // Corrected line
String sqlQuery = "INSERT INTO `bank_transactions`(`transactionResponseStatus`, `bankName`, `transactionAmount`, "
+ "`txnDate`, `txnTime`, `branchname`,`extraInfo`,`extraInfo2`, `extraInfo3`,`txnMode`, `txnId`,`file`) "
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
try {
int affectedRows = jdbcPOSDataTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "id" });
ps.setString(1, transactionResponseStatus);
ps.setString(2, bankName);
ps.setString(3, transactionAmount);
ps.setString(4, txnDate);
ps.setString(5, txnTime);
ps.setString(6, branchname);
ps.setString(7, extraInfo);
ps.setString(8, extraInfo2);
ps.setString(9, extraInfo3);
ps.setString(10, txnMode);
ps.setString(11, txnId);
ps.setString(12, image);
return ps;
}
}, keyHolder);
if (affectedRows > 0) {
Number generatedId = keyHolder.getKey();
lastInsertId = (generatedId != null) ? generatedId.intValue() : 0;
updatePaymentStatus(txnId, transactionResponseStatus);
// Fetch inserted data for response, joining `penalty_challan` and
// `bank_transactions`
// String sqlQuery_joined = "SELECT pc.category_id, CONCAT('" + fileBaseUrl
// + "/gccofficialapp/files', pc.image) as imageurl, "
// + "pc.latitude, pc.longitude, pc.zone, pc.ward, pc.challan_by, "
// + "pc.violator_name, pc.violator_phone, pc.ton, pc.fine_amount, pc.orderid,
// pc.status, "
// + "bt.mid, bt.tid, bt.txnId, bt.bankName, bt.batchNumber,
// bt.transactionAmount, bt.transactionTitle, "
// + "bt.txnCardNo, bt.txnDate, bt.txnInvoice, bt.txnMode, bt.txnRefNo, "
// + "bt.branchname, bt.extraInfo, bt.extraInfo2, bt.extraInfo3, CONCAT('" +
// fileBaseUrl
// + "/gccofficialapp/files', bt.file) as offlineimageurl "
// + "FROM penalty_challan pc "
// + "LEFT JOIN bank_transactions bt ON pc.orderid = bt.txnId "
// + "WHERE pc.isactive = 1 AND pc.isdelete = 0 AND bt.id = ? LIMIT 1";
// System.out.println(sqlQuery_joined);
// // Execute the query
// List<Map<String, Object>> result =
// jdbcPOSDataTemplate.queryForList(sqlQuery_joined, lastInsertId);
// response.put("insertid", lastInsertId);
response.put("status", 200);
response.put("message", "A new Penalty (Chellan) was generated successfully!");
// response.put("orderid", orderid);
// response.put("data", result);
System.out.println("Transaction stored successfully!");
} else {
response.put("status", 201);
response.put("message", "Failed to store the transaction.");
response.put("data", "");
}
} catch (DataAccessException e) {
System.out.println("Data Access Exception:");
Throwable rootCause = e.getMostSpecificCause();
if (rootCause instanceof SQLException) {
SQLException sqlException = (SQLException) rootCause;
System.out.println("SQL State: " + sqlException.getSQLState());
System.out.println("Error Code: " + sqlException.getErrorCode());
System.out.println("Message: " + sqlException.getMessage());
response.put("status", 500);
response.put("message", "Database error while storing transaction.");
response.put("error", e.getMessage());
} else {
System.out.println("Message: " + rootCause.getMessage());
response.put("status", 400);
response.put("message", "Transaction failed or invalid status.");
}
}
return Collections.singletonList(response);
}
}

3
src/main/resources/application-local.properties

@ -0,0 +1,3 @@
assets.base-url=/assets/
fileBaseUrl=http://localhost:8067

3
src/main/resources/application-production.properties

@ -0,0 +1,3 @@
assets.base-url=/gccofficialapp/assets/
fileBaseUrl=https://gccservices.in

17
src/main/resources/application.properties

@ -0,0 +1,17 @@
spring.application.name=pospostdata
# spring.profiles.active=local
spring.profiles.active=production
# Enable live reload (default is true)
spring.devtools.livereload.enabled=true
# Enable restart (default is true)
spring.devtools.restart.enabled=true
# HTTP Server
server.port = 8087
file.upload.directory=${user.dir}/gcc_mobile_service_uploads/
penalty_foldername = penalty_activity/

13
src/test/java/com/gcc/pospostdata/PospostdataApplicationTests.java

@ -0,0 +1,13 @@
package com.gcc.pospostdata;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class PospostdataApplicationTests {
@Test
void contextLoads() {
}
}
Loading…
Cancel
Save