From 49c50b94b28daba9bad6c15b89de259dd1cd97a3 Mon Sep 17 00:00:00 2001 From: KaNi-04 <136799210+KaNi-04@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:31:10 +0530 Subject: [PATCH] Whatsapp Governance - Rest API Services - Initial Commit --- .gitignore | 33 + mvnw | 259 +++ mvnw.cmd | 149 ++ pom.xml | 94 ++ .../RestapiservicesApplication.java | 13 + .../controller/BirthApiController.java | 885 ++++++++++ .../ChildNameInclusionController.java | 121 ++ .../controller/DeathApiController.java | 440 +++++ .../service/BirthCertificateService.java | 1095 +++++++++++++ .../service/ChildNameInclusionService.java | 420 +++++ .../service/DeathCertificateService.java | 789 +++++++++ .../cdwaste/controller/ApiController.java | 244 +++ .../controller/DropDownApiController.java | 157 ++ .../cdwaste/service/DropDownService.java | 70 + .../cdwaste/service/RequestService.java | 354 ++++ .../cdwaste/util/ApiResponseUtil.java | 44 + .../cdwaste/util/DateTimeUtil.java | 35 + .../configuration/PaymentConfig.java | 96 ++ .../controller/ReportController.java | 95 ++ .../controller/communityHallController.java | 992 +++++++++++ .../dto/PaymentWebhookPayload.java | 198 +++ .../communityHall/dto/TransactionData.java | 83 + .../dto/TransactionRefundResponse.java | 73 + .../service/CHPaymentService.java | 536 ++++++ .../communityHall/service/ReportService.java | 162 ++ .../service/WhatsappMsgServiceImpl.java | 41 + .../service/communityHallService.java | 864 ++++++++++ .../communityHall/util/EncryptionUtils.java | 63 + .../util/TransactionNumberGenerator.java | 37 + .../configuration/AppConfig.java | 64 + .../configuration/DataSourceConfig.java | 201 +++ .../coworkspace/constants/AppConstants.java | 11 + .../coworkspace/controller/ApiResponse.java | 49 + .../controller/CoworkspaceApiController.java | 389 +++++ .../exception/GlobalExceptionHandler.java | 44 + .../exception/NoSlotAvailable.java | 7 + .../service/AmountConfigService.java | 38 + .../coworkspace/service/CalendarService.java | 33 + .../service/CoworkspaceApiService.java | 1447 +++++++++++++++++ .../coworkspace/service/PaymentService.java | 193 +++ .../coworkspace/service/SMSService.java | 69 + .../coworkspace/service/WhatsAppService.java | 102 ++ .../controller/CrsLogsApiController.java | 264 +++ .../crslogs/service/CrsLogsService.java | 80 + .../controller/FeedbackController.java | 127 ++ .../feedback/service/FeedbackService.java | 125 ++ .../controller/LocationController.java | 108 ++ .../controller/NearByController.java | 94 ++ .../nearbyservices/service/NearByService.java | 633 +++++++ .../constants/AppConstants.java | 11 + .../controller/PetController.java | 76 + .../PetRegistrationApiController.java | 757 +++++++++ .../controller/SMSController.java | 32 + .../service/PetRegistrationApiService.java | 949 +++++++++++ .../service/PetSMSService.java | 603 +++++++ .../petregistration/util/ApiResponseUtil.java | 46 + .../petregistration/util/DateTimeUtil.java | 35 + .../controller/PropertyTaxOtpController.java | 324 ++++ .../service/PropertyTaxOtpService.java | 313 ++++ .../controller/ServicePdfController.java | 126 ++ .../service/ServicePdfService.java | 47 + .../swimmingpool/constants/AppConfig.java | 59 + .../swimmingpool/constants/AppConstants.java | 14 + .../controller/PoolApiController.java | 380 +++++ .../controller/SwimmingPoolApiController.java | 485 ++++++ .../swimmingpool/service/PoolService.java | 525 ++++++ .../service/SwimmingPoolService.java | 778 +++++++++ .../swimmingpool/util/ApiResponse.java | 49 + .../BuildingApprovalApiController.java | 42 + .../service/BuildingApprovalService.java | 53 + .../configuration/VPHPaymentConfig.java | 96 ++ .../controller/VPHHallController.java | 992 +++++++++++ .../dto/PaymentWebhookPayload.java | 198 +++ .../dto/TransactionData.java | 83 + .../dto/TransactionRefundResponse.java | 73 + .../service/VPHPaymentService.java | 536 ++++++ .../service/WhatsappMsgService.java | 41 + .../service/victoriaHallService.java | 849 ++++++++++ .../util/VPHEncryptionUtils.java | 63 + .../util/VPHTransactionNumberGenerator.java | 37 + src/main/resources/application-dev.properties | 36 + .../resources/application-prod.properties | 46 + src/main/resources/application.properties | 3 + src/main/resources/paymentConfig.properties | 15 + 84 files changed, 21292 insertions(+) create mode 100644 .gitignore create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/com/gcc/restapiservices/RestapiservicesApplication.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/controller/BirthApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/controller/ChildNameInclusionController.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/controller/DeathApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/service/BirthCertificateService.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/service/ChildNameInclusionService.java create mode 100644 src/main/java/com/gcc/restapiservices/birthanddeath/service/DeathCertificateService.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/controller/ApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/controller/DropDownApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/service/DropDownService.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/service/RequestService.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/util/ApiResponseUtil.java create mode 100644 src/main/java/com/gcc/restapiservices/cdwaste/util/DateTimeUtil.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/configuration/PaymentConfig.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/controller/ReportController.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/controller/communityHallController.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/dto/PaymentWebhookPayload.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionData.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionRefundResponse.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/service/CHPaymentService.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/service/ReportService.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/service/WhatsappMsgServiceImpl.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/service/communityHallService.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/util/EncryptionUtils.java create mode 100644 src/main/java/com/gcc/restapiservices/communityHall/util/TransactionNumberGenerator.java create mode 100644 src/main/java/com/gcc/restapiservices/configuration/AppConfig.java create mode 100644 src/main/java/com/gcc/restapiservices/configuration/DataSourceConfig.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/constants/AppConstants.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/controller/ApiResponse.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/controller/CoworkspaceApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/exception/NoSlotAvailable.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/AmountConfigService.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/CalendarService.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/CoworkspaceApiService.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/PaymentService.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/SMSService.java create mode 100644 src/main/java/com/gcc/restapiservices/coworkspace/service/WhatsAppService.java create mode 100644 src/main/java/com/gcc/restapiservices/crslogs/controller/CrsLogsApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/crslogs/service/CrsLogsService.java create mode 100644 src/main/java/com/gcc/restapiservices/feedback/controller/FeedbackController.java create mode 100644 src/main/java/com/gcc/restapiservices/feedback/service/FeedbackService.java create mode 100644 src/main/java/com/gcc/restapiservices/nearbyservices/controller/LocationController.java create mode 100644 src/main/java/com/gcc/restapiservices/nearbyservices/controller/NearByController.java create mode 100644 src/main/java/com/gcc/restapiservices/nearbyservices/service/NearByService.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/constants/AppConstants.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/controller/PetController.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/controller/PetRegistrationApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/controller/SMSController.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/service/PetRegistrationApiService.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/service/PetSMSService.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/util/ApiResponseUtil.java create mode 100644 src/main/java/com/gcc/restapiservices/petregistration/util/DateTimeUtil.java create mode 100644 src/main/java/com/gcc/restapiservices/propertytax/controller/PropertyTaxOtpController.java create mode 100644 src/main/java/com/gcc/restapiservices/propertytax/service/PropertyTaxOtpService.java create mode 100644 src/main/java/com/gcc/restapiservices/servicesPdf/controller/ServicePdfController.java create mode 100644 src/main/java/com/gcc/restapiservices/servicesPdf/service/ServicePdfService.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConfig.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConstants.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/controller/PoolApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/controller/SwimmingPoolApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/service/PoolService.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/service/SwimmingPoolService.java create mode 100644 src/main/java/com/gcc/restapiservices/swimmingpool/util/ApiResponse.java create mode 100644 src/main/java/com/gcc/restapiservices/townplanning/controller/BuildingApprovalApiController.java create mode 100644 src/main/java/com/gcc/restapiservices/townplanning/service/BuildingApprovalService.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/configuration/VPHPaymentConfig.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/controller/VPHHallController.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/PaymentWebhookPayload.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionData.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionRefundResponse.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/VPHPaymentService.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/WhatsappMsgService.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/victoriaHallService.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHEncryptionUtils.java create mode 100644 src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHTransactionNumberGenerator.java create mode 100644 src/main/resources/application-dev.properties create mode 100644 src/main/resources/application-prod.properties create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/paymentConfig.properties diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +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/ diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..19529dd --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/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.2 +# +# 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:]' +} + +# 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 <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.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${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -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 +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,149 @@ +<# : 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.2 +@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-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/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_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::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 +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -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" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f2550a5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.4 + + + com.gcc + restapiservices + + restapiservices + GCC restapiservices + + + + + + + + + + + + + + + 17 + + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + com.oracle.database.jdbc + ojdbc8 + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.apache.commons + commons-lang3 + 3.14.0 + + + com.razorpay + razorpay-java + 1.4.3 + + + com.google.code.gson + gson + 2.10.1 + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/RestapiservicesApplication.java b/src/main/java/com/gcc/restapiservices/RestapiservicesApplication.java new file mode 100644 index 0000000..d49c98f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/RestapiservicesApplication.java @@ -0,0 +1,13 @@ +package com.gcc.restapiservices; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class RestapiservicesApplication { + + public static void main(String[] args) { + SpringApplication.run(RestapiservicesApplication.class, args); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/controller/BirthApiController.java b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/BirthApiController.java new file mode 100644 index 0000000..2b78d40 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/BirthApiController.java @@ -0,0 +1,885 @@ +package com.gcc.restapiservices.birthanddeath.controller; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +// import com.gcc.restapiservices.birthanddeath.service.BirthCertificateService; +import com.gcc.restapiservices.configuration.AppConfig; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@RequestMapping("/gccrestservices/api/birth-certificate") +@RestController +public class BirthApiController { + +// @Autowired +// private BirthCertificateService birthCertificateService; + + @Autowired + private AppConfig appConfig; + +// // old from local db +// @PostMapping("/by-registration") +// public ResponseEntity getByRegistration(@RequestParam("registration_number") String regNo) { +// try { + +// // Validate presence +// if (regNo == null || regNo.trim().isEmpty()) { +// Map error = new LinkedHashMap<>(); +// error.put("status", "invalid_request"); +// error.put("message", "Registration number is required"); +// error.put("status_code", 400); +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); +// } + +// String formattedRegNo = regNo.trim().toUpperCase(); + +// // Map result = +// // birthCertificateService.getByRegistrationNumber(regNo); +// Map result = birthCertificateService.getBirthByRegistrationNumber(formattedRegNo); + + + +// if (result.containsKey("certificate_details")) { +// // Check for empty pdf_url and set message if needed +// Object pdfUrl = result.get("pdf_url"); +// if (pdfUrl == null || pdfUrl.toString().isEmpty()) { +// result.put("message", "Awaiting for eSign"); +// } else { +// result.put("message", "Record fetched successfully"); +// } +// result.put("status", "success"); +// result.put("status_code", 200); +// return ResponseEntity.ok(result); +// } else { +// return ResponseEntity.ok(result); +// } + + +// } catch (EmptyResultDataAccessException ex) { +// Map response = new LinkedHashMap<>(); +// response.put("status", "not_found"); +// response.put("message", +// "no data found for given registration number.Please ensure registration number is exactly as on the certificate."); +// response.put("status_code", 404); +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// Map error = new LinkedHashMap<>(); +// error.put("status", "error"); +// error.put("message", "An unexpected error occurred " + ex); +// error.put("status_code", 500); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } +// } + +// @PostMapping("/by-mobile") +// public ResponseEntity getByMobile(@RequestParam(value = "mobile_number") String mobile) { +// try { +// // Validate presence +// if (mobile == null || mobile.trim().isEmpty()) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_request", "message", +// "Mobile number is required", "status_code", 400)); +// } + +// mobile = mobile.trim(); + +// // Validate format: 10 digits +// if (!mobile.matches("^\\d{10}$")) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "Invalid mobile number format. Expected: 10-digit number", "status_code", 400)); +// } + +// // List> results = +// // birthCertificateService.getByMobile(mobile); + +// List> results = birthCertificateService.getBirthByMobile(mobile); + +// //System.out.println("results mobile " + results); + +// if (results.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("status", "not_found", "message", +// "No records found for the given mobile number or some other district", "status_code", 404)); +// } + +// // Inject status and status_code into each record +// List> finalResults = new ArrayList<>(); +// for (Map record : results) { +// if(record.get("pdf_url") == null || record.get("pdf_url").toString().isEmpty()) { +// record.put("message", "Awaiting for eSign"); +// } else { +// record.put("message", "Record fetched successfully"); +// } +// record.put("status", "success"); +// record.put("status_code", 200); +// finalResults.add(record); +// } + +// return ResponseEntity.ok(finalResults); + +// } catch (Exception ex) { +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + +// @PostMapping("/by-details") +// public ResponseEntity getBirthDetailsMysql(@RequestParam(name = "incident_date") String dob, +// @RequestParam(name = "gender") String gender, @RequestParam(name = "father_name") String fatherName, +// @RequestParam(name = "mother_name") String motherName, +// @RequestParam(required = false, name = "child_name") String childName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate +// List missing = new ArrayList<>(); +// if (dob == null || dob.trim().isEmpty()) +// missing.add("birth_date"); +// if (fatherName == null || fatherName.trim().isEmpty()) +// missing.add("father_name"); +// if (motherName == null || motherName.trim().isEmpty()) +// missing.add("mother_name"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// String formattedDob; + +// // ✅ Format gender like "Male"/"Female" to "M"/"F" +// String formattedGender = formatGender(gender); + +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + +// LocalDate incidentDate = LocalDate.parse(dob.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// formattedDob = LocalDate.parse(dob.trim(), inputFormat).format(oracleFormat); +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { +// // System.out.println("DOB : " + formattedDob); +// // System.out.println("Father : " + fatherName); +// // System.out.println("Mother : " + motherName); +// // System.out.println("Gender : " + formattedGender); +// // System.out.println("Child : " + (childName != null ? childName : "[EMPTY]")); + +// Map result = birthCertificateService.getByDetailsOracleOldAndNew(formattedDob, fatherName, +// motherName, childName, formattedGender); + +// if (result == null || result.isEmpty() || "not_found".equals(result.get("status"))) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404)); +// } + +// result.put("status_code", 200); +// result.put("message", "Record fetched successfully"); +// return ResponseEntity.ok(result); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + + /* ///////////////// otp configuration ///////////////////// */ + + @GetMapping(value = "/sendOTP") + public String sendOtp(HttpServletRequest request, @RequestParam String mobile) { + + // Create an ObjectMapper instance + ObjectMapper objectMapper = new ObjectMapper(); + + Map response = new HashMap<>(); + + String MobileNo = mobile; + System.out.print("\n MobileNo---:" + mobile); + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + + System.out.print("\n otp---:" + otp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); + LocalDateTime now = LocalDateTime.now(); + System.out.println(dtf.format(now)); + + String generatedToken = "Welcome to GCC! Your OTP for Birth and Death Certificate login is " + otp; + String key = "pfTEYN6H"; + String urlString = appConfig.getGetOtpUrl() + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + generatedToken + "&entityid=1401572690000011081&templateid=1407174687453240990"; + System.out.print("\n urlString---: " + urlString); + String bodyMessage = ""; + + if (mobile == null || mobile.trim().isEmpty()) { + throw new IllegalArgumentException("Mobile number is required"); + } + + // Validate mobile number is exactly 10 digits + if (!mobile.matches("\\d{10}")) { + throw new IllegalArgumentException("Mobile number must be exactly 10 digits"); + } + + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + // Add mobileNo and otp to the response JSON + jsonResponse.put("MobileNo", MobileNo); + jsonResponse.put("otp", otp); + + bodyMessage = jsonResponse.toString(); + System.out.println("\n bodyMessage" + bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: " + e); + bodyMessage = "Error"; + } + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + return bodyMessage; + + } + + // Helper method for 400 error +// private ResponseEntity> badRequest(String message) { +// Map error = new LinkedHashMap<>(); +// error.put("status", "invalid_request"); +// error.put("message", message); +// error.put("status_code", 400); +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); +// } + +// public static String formatGender(String gender) { +// if (gender == null) +// return null; + +// gender = gender.trim().toLowerCase(); + +// if (gender.equals("male")) { +// return "M"; +// } else if (gender.equals("female")) { +// return "F"; +// } else { +// // Fallback: capitalize first letter only +// return gender.substring(0, 1).toUpperCase() + gender.substring(1); +// } +// } + +// /// dizo + +// // Child Name Inclusion Send OTP + +// @PostMapping("/ciotp") +// public ResponseEntity sendCiOtp(@RequestParam("MOB") String MOB, +// @RequestParam(value = "ServiceID", defaultValue = "CI") String ServiceID) { + +// ObjectMapper mapper = new ObjectMapper(); + +// try { +// // 🔒 Validate mobile number +// if (MOB == null || MOB.trim().isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter the Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!MOB.matches("\\d{10}")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter a valid 10-digit Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // ✅ Prepare JSON payload for service +// ObjectNode payload = mapper.createObjectNode(); +// payload.put("MOB", MOB); + +// // ✅ Call service +// JsonNode externalResponse = birthCertificateService.sendCiOtp(ServiceID, payload.toString()); + +// // ❌ Handle missing OTP +// if (externalResponse == null || !externalResponse.has("OTP")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Failed to send OTP"); +// error.put("Mobile", MOB); +// error.put("ResultStatus", "False"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } + +// // ✅ Success response +// ObjectNode success = mapper.createObjectNode(); +// success.put("Message", "Sending Success"); +// success.put("Mobile", MOB); +// success.put("OTP", externalResponse.get("OTP").asText()); +// success.put("ResultStatus", "True"); + +// return ResponseEntity.ok(success); + +// } catch (Exception e) { +// e.printStackTrace(); +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Server Error"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } +// } + +// // Child Name Inclusion Register + +// @PostMapping("/ciRegisterData") +// public ResponseEntity ciRegisterData(@RequestParam String MOB, @RequestParam String OTP, +// @RequestParam String REGNO, @RequestParam(required = false, defaultValue = "CI") String ISBD) { + +// ObjectMapper mapper = new ObjectMapper(); + +// try { +// // 🔒 Validate mobile number +// if (MOB == null || MOB.trim().isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter the Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!MOB.matches("\\d{10}")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter a valid 10-digit Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // 🔒 Validate OTP +// if (OTP == null || OTP.trim().isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter OTP"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // 🔒 Validate REGNO +// if (REGNO == null || REGNO.trim().isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter REG No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // ✅ Create SetInput payload +// ObjectNode payload = mapper.createObjectNode(); +// payload.put("MOB", MOB); +// payload.put("OTP", OTP); +// payload.put("REGNO", REGNO); +// payload.put("ISBD", ISBD); // optional + +// // ✅ Call external service +// JsonNode externalResponse = birthCertificateService.CiRegisterData("CI", payload.toString()); + +// // ❌ Handle failure +// if (externalResponse == null || !externalResponse.has("ResultStatus") +// || !"True".equalsIgnoreCase(externalResponse.get("ResultStatus").asText())) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Failed to fetch birth certificate data"); +// error.put("Mobile", MOB); +// error.put("ResultStatus", "False"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } + +// // ✅ Add default DeclarationForm value to the response +// if (externalResponse instanceof ObjectNode) { +// ((ObjectNode) externalResponse).put("DeclarationForm", +// "https://chennaicorporation.gov.in/images/Name%20Declaration%20Form.pdf"); +// } + +// return ResponseEntity.ok(externalResponse); + +// } catch (Exception e) { +// e.printStackTrace(); +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Server Error"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } +// } + +// // Child Name Inclusion Name Added To submit + +// @PostMapping("/saveCiName") +// public ResponseEntity saveCiName(@RequestParam String MOB, @RequestParam String REGNO, +// @RequestParam String ISBD, @RequestParam String PAR_ID, @RequestParam String PAR_DCL, +// @RequestParam("AFFT_LTR") MultipartFile afftLtrFile, +// @RequestParam("PAR_ID_SIGN") MultipartFile paridsignFile, +// @RequestParam("PAR_DCL_SIGN") MultipartFile pardecsignFile, @RequestParam("DOB_Doc") MultipartFile dobFile, +// // @RequestParam("ANY_Doc") MultipartFile anyotherFile, +// @RequestParam String DOB, @RequestParam String CHILD_NAME) { + +// ObjectMapper mapper = new ObjectMapper(); + +// try { +// // Validate mobile number + +// if (MOB == null || MOB.trim().isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter the Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!MOB.matches("\\d{10}")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Enter a valid 10-digit Mobile No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate REGNO +// if (REGNO == null || REGNO.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please fill the REG No"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate PAR_ID +// if (PAR_ID == null || PAR_ID.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please fill the PAR_ID"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate PAR_DCL +// if (PAR_DCL == null || PAR_DCL.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please fill the PAR_DCL"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate DOB +// if (DOB == null || DOB.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please fill the DOB"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate CHILD_NAME +// if (CHILD_NAME == null || CHILD_NAME.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please fill the CHILD_NAME"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// // Validate AFFT_LTR and convert PDF file to Base64 +// if (afftLtrFile == null || afftLtrFile.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please upload AFFIDAVIT LETTER File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!afftLtrFile.getOriginalFilename().toLowerCase().endsWith(".pdf")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Only PDF file is allowed for AFFIDAVIT LETTER File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// byte[] fileBytes = afftLtrFile.getBytes(); +// String afftLtrBase64 = Base64.getEncoder().encodeToString(fileBytes); + +// // Validate PAR_ID_SIGN and convert PDF file to Base64 +// if (paridsignFile == null || paridsignFile.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please upload PARENT ID SIGN File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!paridsignFile.getOriginalFilename().toLowerCase().endsWith(".pdf")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Only PDF file is allowed for PARENT ID SIGN File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// byte[] paridfileBytes = paridsignFile.getBytes(); +// String paridsignBase64 = Base64.getEncoder().encodeToString(paridfileBytes); + +// // Validate PAR_DCL_SIGN and convert PDF file to Base64 +// if (pardecsignFile == null || pardecsignFile.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please upload PARENT DECLARATION SIGN File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!pardecsignFile.getOriginalFilename().toLowerCase().endsWith(".pdf")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Only PDF file is allowed for PARENT DECLARATION SIGN File"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// byte[] pardclfileBytes = pardecsignFile.getBytes(); +// String pardclsignBase64 = Base64.getEncoder().encodeToString(pardclfileBytes); + +// // Validate DOB_Doc and convert PDF file to Base64 +// if (dobFile == null || dobFile.isEmpty()) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Please upload DOB CERTIFICATE"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// if (!dobFile.getOriginalFilename().toLowerCase().endsWith(".pdf")) { +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Only PDF file is allowed for DOB CERTIFICATE"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.badRequest().body(error); +// } + +// byte[] dobfileBytes = dobFile.getBytes(); +// String dobBase64 = Base64.getEncoder().encodeToString(dobfileBytes); + +// // Validate ANY_Doc and convert PDF file to Base64 +// // if (anyotherFile == null || anyotherFile.isEmpty() ) { +// // ObjectNode error = mapper.createObjectNode(); +// // error.put("Message", "Please upload ANY OTHER DOCUMENT File"); +// // error.put("ResultStatus", "False"); +// // return ResponseEntity.badRequest().body(error); +// // } +// // +// // if (!anyotherFile.getOriginalFilename().toLowerCase().endsWith(".pdf")) { +// // ObjectNode error = mapper.createObjectNode(); +// // error.put("Message", "Only PDF file is allowed for ANY OTHER DOCUMENT File"); +// // error.put("ResultStatus", "False"); +// // return ResponseEntity.badRequest().body(error); +// // } +// // +// // byte[] anyotherfileBytes = anyotherFile.getBytes(); +// // String anyotherBase64 = Base64.getEncoder().encodeToString(anyotherfileBytes); + +// // Construct SetInput JSON +// ObjectNode payload = mapper.createObjectNode(); +// payload.put("MOB", MOB); +// payload.put("REGNO", REGNO); +// payload.put("ISBD", ISBD); +// payload.put("PAR_ID", PAR_ID); +// payload.put("PAR_DCL", PAR_DCL); +// payload.put("AFFT_LTR", afftLtrBase64); +// payload.put("PAR_ID_SIGN", paridsignBase64); +// payload.put("PAR_DCL_SIGN", pardclsignBase64); +// payload.put("DOB_Doc", dobBase64); +// // payload.put("ANY_Doc", anyotherBase64); +// payload.put("DOB", DOB); +// payload.put("CHILD_NAME", CHILD_NAME); + +// // Send to external service +// JsonNode externalResponse = birthCertificateService.saveCiName(payload); + +// // Prepare cleaned response +// ObjectNode cleanResponse = mapper.createObjectNode(); +// cleanResponse.put("Message", externalResponse.path("Message").asText()); +// cleanResponse.put("Mobile", externalResponse.path("Mobile").asText()); +// cleanResponse.put("ResultStatus", externalResponse.path("ResultStatus").asText()); + +// return ResponseEntity.ok(cleanResponse); + +// } catch (Exception e) { +// e.printStackTrace(); +// ObjectNode error = mapper.createObjectNode(); +// error.put("Message", "Server Error"); +// error.put("ResultStatus", "False"); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } +// } + +// // added by hariprasath + +// @PostMapping("/by-detailsnew") +// public ResponseEntity getBirthDetailsMysqlnew(@RequestParam(name = "incident_date") String dob, +// @RequestParam(name = "gender") String gender, @RequestParam(name = "father_name") String fatherName, +// @RequestParam(name = "mother_name") String motherName, +// @RequestParam(required = false, name = "child_name") String childName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate +// List missing = new ArrayList<>(); +// if (dob == null || dob.trim().isEmpty()) +// missing.add("incident_date"); +// if (fatherName == null || fatherName.trim().isEmpty()) +// missing.add("father_name"); +// if (motherName == null || motherName.trim().isEmpty()) +// missing.add("mother_name"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// String formattedDob; + +// String formattedGender = formatGender(gender); + +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + +// LocalDate incidentDate = LocalDate.parse(dob.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// formattedDob = LocalDate.parse(dob.trim(), inputFormat).format(oracleFormat); +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { + +// Map result = birthCertificateService.getByNewDetailsOracleOldAndNew(formattedDob, +// fatherName, motherName, childName, formattedGender); + +// if (result == null || result.isEmpty() || "not_found".equals(result.get("status"))) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); +// } + +// //System.out.println("result===="+result); +// Object certDetailsObj = result.get("certificate_details"); +// if (certDetailsObj instanceof List) { +// List certDetailsList = (List) certDetailsObj; +// for (Object certObj : certDetailsList) { +// if (certObj instanceof Map) { +// Map certMap = (Map) certObj; +// Object pdfUrlObj = certMap.get("pdf_url"); +// if (pdfUrlObj == null || pdfUrlObj.toString().trim().isEmpty()) { +// certMap.put("message", "Awaiting for eSign"); +// } else { +// certMap.put("message", "Record fetched successfully"); +// } +// } +// } +// } +// result.put("status_code", 200); +// return ResponseEntity.ok(result); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + + + + +// // added by yoganandhan for web crslogs + +// @PostMapping("/by-detailsnewforWeb") +// public ResponseEntity getBirthDetailsMysqlnewforWeb(@RequestParam(name = "incident_date") String dob, +// @RequestParam(name = "gender") String gender, @RequestParam(required = false,name = "father_name") String fatherName, +// @RequestParam(required = false, name = "mother_name") String motherName, +// @RequestParam(required = false, name = "child_name") String childName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate +// List missing = new ArrayList<>(); +// if (dob == null || dob.trim().isEmpty()) +// missing.add("incident_date"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// String formattedDob; + +// String formattedGender = formatGender(gender); + +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + +// LocalDate incidentDate = LocalDate.parse(dob.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// formattedDob = LocalDate.parse(dob.trim(), inputFormat).format(oracleFormat); +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { + +// Map result = birthCertificateService.getByNewDetailsOracleOldAndNewForWeb(formattedDob, +// fatherName, motherName, childName, formattedGender); + +// if (result == null || result.isEmpty() || "not_found".equals(result.get("status"))) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); +// } + +// //System.out.println("result===="+result); +// Object certDetailsObj = result.get("certificate_details"); +// if (certDetailsObj instanceof List) { +// List certDetailsList = (List) certDetailsObj; +// for (Object certObj : certDetailsList) { +// if (certObj instanceof Map) { +// Map certMap = (Map) certObj; +// Object pdfUrlObj = certMap.get("pdf_url"); +// if (pdfUrlObj == null || pdfUrlObj.toString().trim().isEmpty()) { +// certMap.put("message", "Awaiting for eSign"); +// } else { +// certMap.put("message", "Record fetched successfully"); +// } +// } +// } +// } +// result.put("status_code", 200); +// return ResponseEntity.ok(result); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + + +// //add by yogi for all adoption child details to get + +// @GetMapping("/alladoptionbirthdetails") +// public ResponseEntity> getAllAdoptionBirthDetails() { +// List> result = birthCertificateService.getAllAdoptionBirthDetails(); + +// if (result.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND) +// .body(Map.of( +// "status", "not_found", +// "message", "No adoption birth records found.", +// "status_code", 404 +// )); +// } + +// return ResponseEntity.ok(Map.of( +// "status", "success", +// "count", result.size(), +// "data", result +// )); +// } + + + +// @GetMapping("/getolddetails") +// public ResponseEntity> getoldDetails(String dob, String gender) { +// // Pass the date of death to the service +// List> result = birthCertificateService.getOldBirthDetails(dob,gender); + +// if (result.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND) +// .body(Map.of( +// "status", "not_found", +// "message", "No death records found for the given date.", +// "status_code", 404 +// )); +// } + +// return ResponseEntity.ok(Map.of( +// "status", "success", +// "count", result.size(), +// "data", result +// )); +// } + + + +// @GetMapping("/getolddetailsstatic") +// public ResponseEntity> getOldBirthDetailsStatic() { +// // Pass the date of death to the service +// Map result = birthCertificateService.getOldBirthDetailsStatic(); + +// if (result.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND) +// .body(Map.of( +// "status", "not_found", +// "message", "No death records found for the given date.", +// "status_code", 404 +// )); +// } + +// return ResponseEntity.ok(Map.of( +// "status", "success", +// "count", result.size(), +// "data", result +// )); +// } + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/controller/ChildNameInclusionController.java b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/ChildNameInclusionController.java new file mode 100644 index 0000000..aa7c01d --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/ChildNameInclusionController.java @@ -0,0 +1,121 @@ +// package com.gcc.restapiservices.birthanddeath.controller; + +// import com.gcc.restapiservices.birthanddeath.service.ChildNameInclusionService; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.http.ResponseEntity; +// import org.springframework.web.bind.annotation.*; +// import org.springframework.web.multipart.MultipartFile; +// import java.io.IOException; +// import java.nio.file.Files; +// import java.nio.file.Path; +// import java.nio.file.Paths; +// import java.nio.file.StandardCopyOption; +// import java.util.HashMap; +// import java.util.List; +// import java.util.Map; + +// @RequestMapping("/gccrestservices/api/childnameinclusion") +// @RestController +// public class ChildNameInclusionController { +// private ChildNameInclusionService childNameInclusionService; + +// @Autowired +// public ChildNameInclusionController(ChildNameInclusionService childNameInclusionService) { +// this.childNameInclusionService = childNameInclusionService; +// } + +// @GetMapping("/getByRegNo") +// public Map getByRegNo(@RequestParam String regNo, @RequestParam String mobile) { +// return childNameInclusionService.getByRegNo(regNo, mobile); +// } + +// @GetMapping("/getDetailsByMobNo") +// public Map getDetailsByMobNo(@RequestParam String mobile){ +// return childNameInclusionService.getDetailsByMobNo(mobile); +// } + + + +// // @PostMapping("/save") +// // public ResponseEntity> saveBirthDeath( +// // @RequestParam Map formFields, +// // @RequestParam("fle_par_dcl") MultipartFile fleParDcl, +// // @RequestParam("fle_par_id") MultipartFile fleParId, +// // @RequestParam("fle_afft_ltr") MultipartFile fleAfftLtr, +// // @RequestParam("fle_dob") MultipartFile fleDob +// // ) { +// // Map response = new HashMap<>(); +// // try { +// // // ✅ Required text fields +// // String[] requiredTextFields = { +// // "reg_no", "isBD", "txt_mob", "rd_birth_corr", "m_child" +// // }; +// // for (String field : requiredTextFields) { +// // if (!formFields.containsKey(field) || formFields.get(field).trim().isEmpty()) { +// // response.put("statusCode", 400); +// // response.put("message", "Missing or empty required field: " + field); +// // return ResponseEntity.badRequest().body(response); +// // } +// // } +// // +// // // ✅ Validate files +// // checkFileRequired(fleParDcl, "fle_par_dcl"); +// // checkFileRequired(fleParId, "fle_par_id"); +// // checkFileRequired(fleAfftLtr, "fle_afft_ltr"); +// // checkFileRequired(fleDob, "fle_dob"); +// // +// // // ✅ Build files map for service +// // Map filesMap = new HashMap<>(); +// // filesMap.put("fle_par_dcl", fleParDcl); +// // filesMap.put("fle_par_id", fleParId); +// // filesMap.put("fle_afft_ltr", fleAfftLtr); +// // filesMap.put("fle_dob", fleDob); +// // +// // // ✅ Call service with BOTH parameters +// // String ackNo = childNameInclusionService.saveChildNameInclusion(formFields, filesMap); +// // +// // response.put("statusCode", 200); +// // response.put("message", "Your request for birth child name inclusion has been received successfully"); +// // response.put("acknowledgementNumber", ackNo); +// // return ResponseEntity.ok(response); +// // +// // } catch (IOException e) { +// // response.put("statusCode", 400); +// // response.put("message", "File saving error: " + e.getMessage()); +// // return ResponseEntity.badRequest().body(response); +// // } catch (IllegalArgumentException e) { +// // response.put("statusCode", 400); +// // response.put("message", e.getMessage()); +// // return ResponseEntity.badRequest().body(response); +// // } catch (Exception e) { +// // response.put("statusCode", 500); +// // response.put("message", "Server error: " + e.getMessage()); +// // return ResponseEntity.status(500).body(response); +// // } +// // } +// // +// // private void checkFileRequired(MultipartFile file, String name) { +// // if (file == null || file.isEmpty()) { +// // throw new IllegalArgumentException("Missing required file: " + name); +// // } +// // } +// // +// // +// // +// // +// // +// // private String saveFileLocally(MultipartFile file, String regNo) throws IOException { +// // String uploadDir = System.getProperty("user.dir") + "/uploads/" + regNo; +// // Files.createDirectories(Paths.get(uploadDir)); +// // +// // String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename(); +// // Path filePath = Paths.get(uploadDir, fileName); +// // +// // Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); +// // +// // // returning relative path for DB storage +// // return "/uploads/" + regNo + "/" + fileName; +// // } + +// } diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/controller/DeathApiController.java b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/DeathApiController.java new file mode 100644 index 0000000..002090e --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/controller/DeathApiController.java @@ -0,0 +1,440 @@ +// package com.gcc.restapiservices.birthanddeath.controller; + +// import java.time.LocalDate; +// import java.time.format.DateTimeFormatter; +// import java.time.format.DateTimeParseException; +// import java.util.ArrayList; +// import java.util.LinkedHashMap; +// import java.util.List; +// import java.util.Map; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.dao.EmptyResultDataAccessException; +// import org.springframework.http.HttpStatus; +// import org.springframework.http.ResponseEntity; +// import org.springframework.web.bind.annotation.GetMapping; +// 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 com.gcc.restapiservices.birthanddeath.service.DeathCertificateService; + +// @RequestMapping("/gccrestservices/api/death-certificate") +// @RestController +// public class DeathApiController { + +// @Autowired +// private DeathCertificateService deathCertificateService; + +// @PostMapping("/by-registration") +// public ResponseEntity getByRegistration(@RequestParam("registration_number") String regNo) { +// try { + +// // Validate presence +// if (regNo == null || regNo.trim().isEmpty()) { +// Map error = new LinkedHashMap<>(); +// error.put("status", "invalid_request"); +// error.put("message", "Registration number is required"); +// error.put("status_code", 400); +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); +// } + +// // Map result = +// // deathCertificateService.getByRegistrationNumber(regNo); + +// String formattedRegNo = regNo.trim().toUpperCase(); + +// Map result = deathCertificateService.getDeathByRegistrationNumber(formattedRegNo); + +// // Inject status and status code into response +// if (result.containsKey("certificate_details")) { +// Object pdfUrl = result.get("pdf_url"); +// if (pdfUrl == null || pdfUrl.toString().isEmpty()) { +// result.put("message", "Awaiting for eSign"); +// } else { +// result.put("message", "Record fetched successfully"); +// } +// result.put("status", "success"); +// result.put("status_code", 200); +// //result.put("message", "Record fetched successfully"); +// return ResponseEntity.ok(result); +// } else { +// return ResponseEntity.ok(result); +// } + +// } catch (EmptyResultDataAccessException ex) { +// Map response = new LinkedHashMap<>(); +// response.put("status", "not_found"); +// response.put("message", "no data found for given registration number"); +// response.put("status_code", 404); +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + +// } catch (Exception ex) { +// Map error = new LinkedHashMap<>(); +// error.put("status", "error"); +// error.put("message", "An unexpected error occurred " + ex); +// error.put("status_code", 500); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); +// } +// } + +// @PostMapping("/by-mobile") +// public ResponseEntity getByMobile(@RequestParam(value = "mobile_number") String mobile) { +// try { +// // Validate presence +// if (mobile == null || mobile.trim().isEmpty()) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_request", "message", +// "Mobile number is required", "status_code", 400)); +// } + +// mobile = mobile.trim(); + +// // Validate format: 10 digits +// if (!mobile.matches("^\\d{10}$")) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "Invalid mobile number format. Expected: 10-digit number", "status_code", 400)); +// } + +// List> results = deathCertificateService.getByMobile(mobile); + +// // List> results = +// // deathCertificateService.getDeathByMobile(mobile.trim()); + +// if (results.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("status", "not_found", "message", +// "No records found for the given mobile number", "status_code", 404)); +// } + +// // Inject status and status_code into each record +// List> finalResults = new ArrayList<>(); +// for (Map record : results) { +// if(record.get("pdf_url") == null || record.get("pdf_url").toString().isEmpty()) { +// record.put("message", "Awaiting for eSign"); +// } else { +// record.put("message", "Record fetched successfully"); +// } +// record.put("status", "success"); +// record.put("status_code", 200); +// finalResults.add(record); +// } + +// return ResponseEntity.ok(finalResults); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + +// // oracle working + +// @PostMapping("/by-details") +// public ResponseEntity getDeathDetailsOracle(@RequestParam(name = "incident_date") String dod, +// @RequestParam(name = "gender") String gender, @RequestParam(name = "father_name") String fatherName, +// @RequestParam(name = "mother_name") String motherName, +// @RequestParam(required = false, name = "person_name") String personName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate required fields +// List missing = new ArrayList<>(); +// if (dod == null || dod.trim().isEmpty()) +// missing.add("death_date"); +// if (fatherName == null || fatherName.trim().isEmpty()) +// missing.add("father_name"); +// if (motherName == null || motherName.trim().isEmpty()) +// missing.add("mother_name"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// // ✅ Format gender like "Male"/"Female" to "M"/"F" +// String formattedGender = formatGender(gender); + +// // ✅ Format DoD to dd-MM-yyyy for Oracle +// String formattedDod; +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); +// formattedDod = LocalDate.parse(dod.trim(), inputFormat).format(oracleFormat); +// LocalDate incidentDate = LocalDate.parse(dod.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { +// // System.out.println("📥 DOD : " + formattedDod); +// // System.out.println("📥 Father : " + fatherName); +// // System.out.println("📥 Mother : " + motherName); +// // System.out.println("📥 Gender : " + formattedGender); +// // System.out.println("📥 Person : " + (personName != null ? personName : "[EMPTY]")); + +// Map result = deathCertificateService.getByDetailsOracleOldAndNewForDeath(formattedDod, +// fatherName, motherName, personName, formattedGender); + +// if (result.isEmpty() || "not_found".equals(result.get("status"))) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404)); +// } + +// result.put("status_code", 200); +// result.put("message", "Record fetched successfully"); +// return ResponseEntity.ok(result); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + +// // Helper method for 400 error +// private ResponseEntity> badRequest(String message) { +// Map error = new LinkedHashMap<>(); +// error.put("status", "invalid_request"); +// error.put("message", message); +// error.put("status_code", 400); +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); +// } + +// public static String formatGender(String gender) { +// if (gender == null) +// return null; + +// gender = gender.trim().toLowerCase(); + +// if (gender.equals("male")) { +// return "M"; +// } else if (gender.equals("female")) { +// return "F"; +// } else { +// // Fallback: capitalize first letter +// return gender.substring(0, 1).toUpperCase() + gender.substring(1); +// } +// } + +// // added by hariprasath + +// @PostMapping("/by-detailsnew") +// public ResponseEntity getDeathDetailsOraclenew(@RequestParam(name = "incident_date") String dod, +// @RequestParam(name = "gender") String gender, @RequestParam(name = "father_name") String fatherName, +// @RequestParam(name = "mother_name") String motherName, +// @RequestParam(required = false, name = "person_name") String personName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate required fields +// List missing = new ArrayList<>(); +// if (dod == null || dod.trim().isEmpty()) +// missing.add("incident_date"); +// if (fatherName == null || fatherName.trim().isEmpty()) +// missing.add("father_name"); +// if (motherName == null || motherName.trim().isEmpty()) +// missing.add("mother_name"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// // ✅ Format gender like "Male"/"Female" to "M"/"F" +// String formattedGender = formatGender(gender); + +// // ✅ Format DoD to dd-MM-yyyy for Oracle +// String formattedDod; +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); +// formattedDod = LocalDate.parse(dod.trim(), inputFormat).format(oracleFormat); +// LocalDate incidentDate = LocalDate.parse(dod.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { + +// Map result = deathCertificateService.getBynewDetailsOracleOldAndNewForDeath(formattedDod, +// fatherName, motherName, personName, formattedGender); + +// if (result.isEmpty() || "not_found".equals(result.get("status"))) { +// // return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of( +// // "status", "not_found", +// // "message", "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// // "status_code", 404 +// // )); +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); +// } + +// Object certDetailsObj = result.get("certificate_details"); +// if (certDetailsObj instanceof List) { +// List certDetailsList = (List) certDetailsObj; +// for (Object certObj : certDetailsList) { +// if (certObj instanceof Map) { +// Map certMap = (Map) certObj; +// Object pdfUrlObj = certMap.get("pdf_url"); +// if (pdfUrlObj == null || pdfUrlObj.toString().trim().isEmpty()) { +// certMap.put("message", "Awaiting for eSign"); +// } else { +// certMap.put("message", "Record fetched successfully"); +// } +// } +// } +// } +// result.put("status_code", 200); +// //result.put("message", "Record fetched successfully"); +// return ResponseEntity.ok(result); + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + + + +// // added by yogi for web crslogs + +// @PostMapping("/by-detailsnewforWeb") +// public ResponseEntity getDeathDetailsOraclenewforWeb(@RequestParam(name = "incident_date") String dod, +// @RequestParam(name = "gender") String gender, @RequestParam(required = false,name = "father_name") String fatherName, +// @RequestParam(required = false, name = "mother_name") String motherName, +// @RequestParam(required = false, name = "person_name") String personName) { + +// Map error = new LinkedHashMap<>(); + +// // Validate required fields +// List missing = new ArrayList<>(); +// if (dod == null || dod.trim().isEmpty()) +// missing.add("incident_date"); +// if (gender == null || gender.trim().isEmpty()) +// missing.add("gender"); + +// if (!missing.isEmpty()) { +// error.put("status", "invalid_request"); +// error.put("message", "Missing required fields: " + String.join(", ", missing)); +// error.put("status_code", 400); +// return ResponseEntity.badRequest().body(error); +// } + +// // ✅ Format gender like "Male"/"Female" to "M"/"F" +// String formattedGender = formatGender(gender); + +// // ✅ Format DoD to dd-MM-yyyy for Oracle +// String formattedDod; +// try { +// DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); +// DateTimeFormatter oracleFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); +// formattedDod = LocalDate.parse(dod.trim(), inputFormat).format(oracleFormat); +// LocalDate incidentDate = LocalDate.parse(dod.trim(), inputFormat); +// LocalDate today = LocalDate.now(); + +// if (incidentDate.isAfter(today)) { +// return ResponseEntity.badRequest().body(Map.of("status", "future_date_not_allowed", "message", +// "incident_date cannot be a future date", "status_code", 400)); +// } + +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("status", "invalid_format", "message", +// "incident_date must be in yyyy-MM-dd format", "status_code", 400)); +// } + +// try { + +// Map result = deathCertificateService.getBynewDetailsOracleOldAndNewForWeb(formattedDod, +// fatherName, motherName, personName, formattedGender); + +// if (result.isEmpty() || "not_found".equals(result.get("status"))) { +// // return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of( +// // "status", "not_found", +// // "message", "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// // "status_code", 404 +// // )); +// return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); +// } + +// //System.out.println(" " + dod + " " + fatherName + " " + motherName + " " + personName); +// //System.out.println("deathdetails:" + result); + +// Object certDetailsObj = result.get("certificate_details"); +// if (certDetailsObj instanceof List) { +// List certDetailsList = (List) certDetailsObj; +// for (Object certObj : certDetailsList) { +// if (certObj instanceof Map) { +// Map certMap = (Map) certObj; +// Object pdfUrlObj = certMap.get("pdf_url"); +// if (pdfUrlObj == null || pdfUrlObj.toString().trim().isEmpty()) { +// certMap.put("message", "Awaiting for eSign"); +// } else { +// certMap.put("message", "Record fetched successfully"); +// } +// } +// } +// } + +// //System.out.println("deathdetailscontroller:" + result); +// result.put("status_code", 200); +// //result.put("message", "Record fetched successfully"); +// return ResponseEntity.ok(result); + + +// } catch (Exception ex) { +// ex.printStackTrace(); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("status", "error", "message", +// "An unexpected error occurred: " + ex.getMessage(), "status_code", 500)); +// } +// } + +// // old details for testing + +// @GetMapping("/getolddetails") +// public ResponseEntity> getoldDetails(String dod, String gender) { +// // Pass the date of death to the service +// List> result = deathCertificateService.getOldDeathDetails(dod,gender); + +// if (result.isEmpty()) { +// return ResponseEntity.status(HttpStatus.NOT_FOUND) +// .body(Map.of( +// "status", "not_found", +// "message", "No death records found for the given date.", +// "status_code", 404 +// )); +// } + +// return ResponseEntity.ok(Map.of( +// "status", "success", +// "count", result.size(), +// "data", result +// )); +// } + +// } \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/service/BirthCertificateService.java b/src/main/java/com/gcc/restapiservices/birthanddeath/service/BirthCertificateService.java new file mode 100644 index 0000000..7466cca --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/service/BirthCertificateService.java @@ -0,0 +1,1095 @@ +// package com.gcc.restapiservices.birthanddeath.service; + +// import java.net.URI; +// import java.net.URLEncoder; +// import java.nio.charset.StandardCharsets; +// import java.time.LocalDate; +// import java.time.ZoneId; +// import java.time.format.DateTimeFormatter; +// import java.util.ArrayList; +// import java.util.Comparator; +// import java.util.LinkedHashMap; +// import java.util.List; +// import java.util.Map; +// import java.util.Objects; + +// import javax.sql.DataSource; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.beans.factory.annotation.Qualifier; +// import org.springframework.dao.EmptyResultDataAccessException; +// import org.springframework.http.HttpEntity; +// import org.springframework.http.HttpHeaders; +// import org.springframework.http.MediaType; +// import org.springframework.http.ResponseEntity; +// import org.springframework.jdbc.core.JdbcTemplate; +// import org.springframework.stereotype.Service; +// import org.springframework.util.LinkedMultiValueMap; +// import org.springframework.util.MultiValueMap; +// import org.springframework.web.client.RestTemplate; +// import org.springframework.web.util.UriComponentsBuilder; + +// import com.fasterxml.jackson.databind.JsonNode; +// import com.fasterxml.jackson.databind.ObjectMapper; + +// @Service +// public class BirthCertificateService { + +// private JdbcTemplate jdbcTemplate; + +// // birth and death testing db connection +// // @Autowired +// // public void setDataSource(@Qualifier("oracleDataSourceItCell") DataSource dataSource) { +// // this.jdbcTemplate = new JdbcTemplate(dataSource); +// // } + +// private final RestTemplate restTemplate; + +// public BirthCertificateService(@Qualifier("sslBypassRestTemplate") RestTemplate restTemplate) { +// this.restTemplate = restTemplate; +// } + +// // birth and death new live db connection +// @Autowired +// @Qualifier("oracleBirthNewDataSourceItCell") +// private DataSource newBirthDataSource; + +// // //birth and death old live db connection +// @Autowired +// @Qualifier("oracleBirthOldDataSourceItCell") +// private DataSource oldBirthDataSource; + +// // old local db +// private static final String SELECT_FIELDS = """ +// regno, child_name, dob, gender, father_name, mother_name, english_url +// """; + +// public Map getByRegistrationNumber(String regNo) { +// String sql = "SELECT " + SELECT_FIELDS + " FROM birth_certificates WHERE regno = ?"; + +// return formatResult(jdbcTemplate.queryForMap(sql, regNo)); + +// } + +// // records from live db field names and tables + +// //private static final String eSign_CERTIFICATE_URL_PREFIX = "https://chennaicorporation.gov.in/online-civic-services/birthCertificateCRS.do?do=BirthCertificate®istrationNumber="; +// private static final String eSign_CERTIFICATE_URL_PREFIX = "http://gccapp.chennaicorporation.gov.in/birth_death_tn/CORPBIRTHTAMIL/esign/"; +// private static final String CERTIFICATE_URL_PREFIX = "http://gccapp.chennaicorporation.gov.in/birth_death_tn/CORPBIRTHTAMIL/GccBirthCertAvail.jsp?RegNo="; + +// private static final String OLD_CERTIFICATE_URL_PREFIX="https://chennaicorporation.gov.in/online-civic-services/birthCertificate.do?do=BirthCertificate®istrationNumber="; +// private static final String CRS_CERTIFICATE_URL_PREFIX="https://chennaicorporation.gov.in/online-civic-services/birthCertificateCRS.do?do=BirthCertificate®istrationNumber="; + + + +// private static final String BIRTH_SELECT_FIELDS = """ +// REGISTRATION_NUMBER AS regno, DATE_OF_BIRTH AS dob, SEX AS gender, +// FATHER_NAME AS father_name, MOTHER_NAME AS mother_name,CHILD_NAME as child_name, '' AS english_url +// """; + + +// // live db for birth regno + +// // public Map getBirthByRegistrationNumber(String regNo) { +// // JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// // JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // // Query new schema +// // String newSql = """ +// // SELECT +// // bd.REGISTRATION_NUMBER AS regno, +// // TO_CHAR(bd.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// // TO_CHAR(bd.created_date , 'DD-MM-YYYY') AS created_date, +// // bd.SEX AS gender, +// // bd.FATHER_NAME AS father_name, +// // bd.MOTHER_NAME AS mother_name, +// // bd.CHILD_NAME AS child_name, +// // CASE +// // WHEN (bd.verified_dt >= TO_DATE('2019-06-19', 'YYYY-MM-DD') +// // OR bd.registration_date >= TO_DATE('2019-06-01', 'YYYY-MM-DD')) THEN 1 +// // ELSE 0 +// // END AS reg_val, +// // NVL(bec.status, 'NA') AS status, +// // bec.cert_file +// // FROM tbl_birth_details bd +// // LEFT JOIN tbl_birth_esign_cert bec +// // ON bec.reg_no = bd.REGISTRATION_NUMBER +// // WHERE bd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// // AND bd.REGISTRATION_NUMBER = ? +// // AND ROWNUM = 1 +// // """; + +// // List> newResults = newJdbc.queryForList(newSql, regNo); +// // if (!newResults.isEmpty()) { +// // return formatResult(newResults.get(0)); +// // } + +// // // Query old schema if not found in new +// // String oldSql = """ +// // SELECT +// // bdo.REGISTRATION_NUMBER AS regno, +// // TO_CHAR(bdo.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// // TO_CHAR(bdo.created_date , 'DD-MM-YYYY') AS created_date, +// // bdo.SEX AS gender, +// // bdo.FATHER_NAME AS father_name, +// // bdo.MOTHER_NAME AS mother_name, +// // bdo.CHILD_NAME AS child_name, +// // CASE +// // WHEN (bdo.verified_dt < TO_DATE('2019-06-19', 'YYYY-MM-DD')) THEN 1 +// // ELSE 0 +// // END AS reg_val, +// // NVL(beco.status, 'NA') AS status, +// // beco.cert_file +// // FROM tbl_birth_details bdo +// // LEFT JOIN tbl_birth_esign_cert beco +// // ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// // OR beco.reg_no = 'GCC_B_' || bdo.REGISTRATION_NUMBER) +// // WHERE bdo.REGISTRATION_NUMBER = ? +// // AND ROWNUM = 1 +// // """; + +// // List> oldResults = oldJdbc.queryForList(oldSql, regNo); +// // if (!oldResults.isEmpty()) { +// // return formatResult(oldResults.get(0)); +// // } + +// // // return Map.of("status", "not_found", "message", "No record found for the +// // // given registration number"); + +// // Map notFound = new LinkedHashMap<>(); +// // notFound.put("status", "not_found"); +// // notFound.put("message", +// // "No record found for the given registration number.Please ensure registration number is exactly as on the certificate."); +// // notFound.put("status_code", 404); +// // return notFound; +// // } + + +// // live db for birth regno with adoption union +// public Map getBirthByRegistrationNumber(String regNo) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // ---------- NEW TABLE + ADOPTION UNION ---------- +// String newSql = """ +// SELECT * FROM ( +// -- Regular Birth Details +// SELECT +// bd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bd.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bd.created_date , 'DD-MM-YYYY') AS created_date, +// bd.SEX AS gender, +// bd.FATHER_NAME AS father_name, +// bd.MOTHER_NAME AS mother_name, +// bd.CHILD_NAME AS child_name, +// CASE +// WHEN (bd.verified_dt >= TO_DATE('2019-06-19', 'YYYY-MM-DD') +// OR bd.registration_date >= TO_DATE('2019-06-01', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_birth_details bd +// LEFT JOIN tbl_birth_esign_cert bec +// ON bec.reg_no = bd.REGISTRATION_NUMBER +// WHERE bd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND bd.REGISTRATION_NUMBER = ? + +// UNION ALL + +// -- Adoption Birth Details +// SELECT +// A.REGISTRATION_NUMBER AS regno, +// TO_CHAR(A.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(A.created_date , 'DD-MM-YYYY') AS created_date, +// A.SEX AS gender, +// NVL(A.ADPT_FATHER_NAME,' ') AS father_name, +// NVL(A.ADPT_MOTHER_NAME,' ') AS mother_name, +// NVL(A.ADPT_CHILDNAME,' ') AS child_name, +// CASE +// WHEN (A.MODIFIED_DATE >= TO_DATE('2019-06-19','YYYY-MM-DD') +// OR A.REGISTRATION_DATE >= TO_DATE('2019-06-01','YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(B.status,'NA') AS status, +// B.cert_file +// FROM TBL_ADPT_BIRTH_DETAILS A +// LEFT JOIN TBL_BIRTH_ESIGN_CERT B +// ON A.REGISTRATION_NUMBER = B.reg_no +// WHERE A.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND A.REGISTRATION_NUMBER = ? +// ) +// WHERE ROWNUM = 1 +// """; + +// List> newResults = newJdbc.queryForList(newSql, regNo, regNo); +// if (!newResults.isEmpty()) { +// return formatResult(newResults.get(0)); +// } + +// // ---------- OLD TABLE ---------- +// String oldSql = """ +// SELECT +// bdo.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bdo.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bdo.created_date , 'DD-MM-YYYY') AS created_date, +// bdo.SEX AS gender, +// bdo.FATHER_NAME AS father_name, +// bdo.MOTHER_NAME AS mother_name, +// bdo.CHILD_NAME AS child_name, +// CASE +// WHEN (bdo.verified_dt < TO_DATE('2019-06-19', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status, 'NA') AS status, +// beco.cert_file +// FROM tbl_birth_details bdo +// LEFT JOIN tbl_birth_esign_cert beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_B_' || bdo.REGISTRATION_NUMBER) +// WHERE bdo.REGISTRATION_NUMBER = ? +// AND ROWNUM = 1 +// """; + +// List> oldResults = oldJdbc.queryForList(oldSql, regNo); +// if (!oldResults.isEmpty()) { +// return formatResult(oldResults.get(0)); +// } + +// Map notFound = new LinkedHashMap<>(); +// notFound.put("status", "not_found"); +// notFound.put("message", +// "No record found for the given registration number. Please ensure registration number is exactly as on the certificate."); +// notFound.put("status_code", 404); +// return notFound; +// } + + + + +// // oracle live db birth +// public List> getBirthByMobile(String mobile) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// String sql = """ +// SELECT +// bd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bd.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bd.created_date , 'DD-MM-YYYY') AS created_date, +// bd.SEX AS gender, +// bd.FATHER_NAME AS father_name, +// bd.MOTHER_NAME AS mother_name, +// bd.CHILD_NAME AS child_name, +// CASE +// WHEN (bd.verified_dt >= TO_DATE('2019-06-19', 'YYYY-MM-DD') +// OR bd.registration_date >= TO_DATE('2019-06-01', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_birth_details bd +// LEFT JOIN tbl_birth_esign_cert bec ON bec.reg_no = bd.REGISTRATION_NUMBER +// WHERE bd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND bd.FATH_MOB_NO = ? OR bd.MOTH_MOB_NO = ? +// """; + +// List> results = newJdbc.queryForList(sql, mobile, mobile); +// return results.stream().map(this::formatResult).toList(); +// } + + +// // live db for birth +// public Map getByDetailsOracleOldAndNew(String dob, String father, String mother, String child, +// String gender) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// String upperFather = father.toUpperCase().trim(); +// String upperMother = mother.toUpperCase().trim(); +// String upperGender = gender.toUpperCase().trim(); +// String upperChild = (child != null && !child.trim().isEmpty()) ? child.toUpperCase().trim() : null; +// String trimmedDob = (dob != null && !dob.trim().isEmpty()) ? dob.trim() : null; + +// // ---------- NEW ---------- +// StringBuilder newSql = new StringBuilder(""" +// SELECT * FROM ( +// SELECT +// bd.REGISTRATION_NUMBER AS regno, +// bd.DATE_OF_BIRTH AS dob, +// bd.SEX AS gender, +// bd.FATHER_NAME AS father_name, +// bd.MOTHER_NAME AS mother_name, +// bd.CHILD_NAME AS child_name, +// CASE +// WHEN (bd.verified_dt >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR bd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_birth_details bd +// LEFT JOIN tbl_birth_esign_cert bec ON bec.reg_no = bd.REGISTRATION_NUMBER +// WHERE TRIM(UPPER(bd.FATHER_NAME)) = ? +// AND TRIM(UPPER(bd.MOTHER_NAME)) = ? +// AND TRIM(UPPER(bd.SEX)) = ? +// """); + +// List newParams = new ArrayList<>(List.of(upperFather, upperMother, upperGender)); + +// if (upperChild != null) { +// newSql.append(" AND TRIM(UPPER(bd.CHILD_NAME)) = ? "); +// newParams.add(upperChild); +// } + +// if (trimmedDob != null) { +// newSql.append(" AND TRUNC(bd.DATE_OF_BIRTH) = TO_DATE(?, 'DD-MM-YYYY') "); +// newParams.add(trimmedDob); +// } + +// newSql.append(") WHERE ROWNUM = 1"); + +// try { +// Map newResult = newJdbc.queryForMap(newSql.toString(), newParams.toArray()); +// return formatResult(newResult); +// } catch (EmptyResultDataAccessException e) { +// // Continue to old source +// } catch (Exception e) { +// throw new RuntimeException("Error querying new birth table", e); +// } + +// // ---------- OLD ---------- +// StringBuilder oldSql = new StringBuilder(""" +// SELECT * FROM ( +// SELECT +// bdo.REGISTRATION_NUMBER AS regno, +// bdo.DATE_OF_BIRTH AS dob, +// bdo.SEX AS gender, +// bdo.FATHER_NAME AS father_name, +// bdo.MOTHER_NAME AS mother_name, +// bdo.CHILD_NAME AS child_name, +// CASE +// WHEN (bdo.verified_dt < TO_DATE('19-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status, 'NA') AS status, +// beco.cert_file +// FROM tbl_birth_details bdo +// LEFT JOIN tbl_birth_esign_cert beco ON beco.reg_no = bdo.REGISTRATION_NUMBER +// WHERE TRIM(UPPER(bdo.FATHER_NAME)) = ? +// AND TRIM(UPPER(bdo.MOTHER_NAME)) = ? +// AND TRIM(UPPER(bdo.SEX)) = ? +// """); + +// List oldParams = new ArrayList<>(List.of(upperFather, upperMother, upperGender)); + +// if (upperChild != null) { +// oldSql.append(" AND TRIM(UPPER(bdo.CHILD_NAME)) = ? "); +// oldParams.add(upperChild); +// } + +// if (trimmedDob != null) { +// oldSql.append(" AND TRUNC(bdo.DATE_OF_BIRTH) = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(trimmedDob); +// } + +// oldSql.append(") WHERE ROWNUM = 1"); + +// try { +// Map oldResult = oldJdbc.queryForMap(oldSql.toString(), oldParams.toArray()); +// return formatResult(oldResult); +// } catch (EmptyResultDataAccessException e) { +// return Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } catch (Exception e) { +// // Return "not_found" with message instead of throwing exception +// return Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } +// } + + +// // oracle +// private Map formatResult(Map row) { + +// // System.out.println("row="+row); + +// Map response = new LinkedHashMap<>(); +// response.put("status", "success"); + +// Map birthresponse = new LinkedHashMap<>(); +// // birthresponse.put("name", row.get("child_name")); + +// birthresponse.put("regno", row.get("regno") != null ? row.get("regno").toString() : ""); +// birthresponse.put("name", row.get("child_name") != null ? row.get("child_name").toString() : ""); +// birthresponse.put("dob", row.get("dob")!= null ? row.get("dob").toString() : "" ); + + +// String gender = row.get("gender") != null ? row.get("gender").toString().trim().toUpperCase() : ""; +// if ("M".equals(gender)) { +// birthresponse.put("gender", "Male"); +// } else if ("F".equals(gender)) { +// birthresponse.put("gender", "FeMale"); +// } else if( "G".equals(gender)) { +// birthresponse.put("gender", "Transgender"); +// }else { +// birthresponse.put("gender", "other"); +// } + + +// birthresponse.put("father_name", row.get("father_name")); +// birthresponse.put("mother_name", row.get("mother_name")); +// response.put("certificate_details", birthresponse); + + +// String regNo = row.get("regno") != null ? row.get("regno").toString() : ""; +// //System.out.println("regNo " + regNo); + +// Integer regVal = row.get("reg_val") instanceof Number ? ((Number) row.get("reg_val")).intValue() : 0; +// String status = String.valueOf(row.getOrDefault("status", "NA")); +// String certFile = row.get("cert_file") != null ? row.get("cert_file").toString() : ""; +// String createdDateStr = (row.get("created_date") != null) ? row.get("created_date").toString().trim() : ""; + +// // System.out.println("certFile="+certFile); + +// // Build PDF URL if valid +// String pdfUrl = ""; +// if ("S".equalsIgnoreCase(status) ) { +// pdfUrl = eSign_CERTIFICATE_URL_PREFIX + certFile; +// } +// else if ("P".equalsIgnoreCase(status)) { +// pdfUrl = ""; + +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isBefore(LocalDate.of(2012, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = ""; // newer pending — no link +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// } +// else { + +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isAfter(LocalDate.of(2018, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// } + +// response.put("pdf_url", pdfUrl); +// if (pdfUrl == null || pdfUrl.isEmpty()) { +// response.put("message", "Awaiting for eSign"); +// } +// return response; +// } + + + +// // dizo + +// // Child Name Inclusion Send OTP + +// public JsonNode sendCiOtp(String serviceId, String setInput) { +// try { +// setInput = setInput.trim(); +// String encodedInput = URLEncoder.encode(setInput, StandardCharsets.UTF_8.toString()); + +// URI uri = UriComponentsBuilder.fromHttpUrl("https://10.1.0.7/gcc/mob-child-name/SendOTP.jsp") +// .queryParam("ServiceID", serviceId).queryParam("SetInput", encodedInput).build(true).toUri(); + +// String response = restTemplate.getForObject(uri, String.class); +// return new ObjectMapper().readTree(response); + +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } + +// //Child Name Inclusion Register + +// public JsonNode CiRegisterData(String serviceId, String setInput) { +// try { +// setInput = setInput.trim(); +// String encodedInput = URLEncoder.encode(setInput, StandardCharsets.UTF_8.toString()); + +// URI uri = UriComponentsBuilder.fromHttpUrl("https://10.1.0.7/gcc/mob-child-name/BDView.jsp") +// .queryParam("ServiceID", serviceId).queryParam("SetInput", encodedInput).build(true).toUri(); + +// String response = restTemplate.getForObject(uri, String.class); +// return new ObjectMapper().readTree(response); + +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } + +// // Child Name Inclusion Name Added To submit + +// public JsonNode saveCiName(JsonNode payload) { +// try { +// String url = "https://10.1.0.7/gcc/mob-child-name/BDSave.jsp"; + +// System.out.println("payload..." + payload); + +// // Create form data (key=value format) +// MultiValueMap formData = new LinkedMultiValueMap<>(); +// formData.add("ServiceID", "CI"); +// formData.add("SetInput", payload.toString()); + +// HttpHeaders headers = new HttpHeaders(); +// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + +// HttpEntity> request = new HttpEntity<>(formData, headers); +// ResponseEntity response = restTemplate.postForEntity(url, request, String.class); + +// ObjectMapper mapper = new ObjectMapper(); +// return mapper.readTree(response.getBody()); + +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } + +// // added by hariprasath + +// public Map getByNewDetailsOracleOldAndNew(String dob, String father, String mother, String child, +// String gender) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// String upperFather = father.toUpperCase().trim(); +// String upperMother = mother.toUpperCase().trim(); +// String upperGender = gender.toUpperCase().trim(); +// String upperChild = (child != null && !child.trim().isEmpty()) ? child.toUpperCase().trim() : null; +// String trimmedDob = (dob != null && !dob.trim().isEmpty()) ? dob.trim() : null; + +// // ---------- NEW ---------- +// StringBuilder newSql = new StringBuilder(""" +// SELECT +// bd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bd.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bd.created_date , 'DD-MM-YYYY') AS created_date, +// bd.SEX AS gender, +// bd.FATHER_NAME AS father_name, +// bd.MOTHER_NAME AS mother_name, +// bd.CHILD_NAME AS child_name, +// CASE +// WHEN (bd.verified_dt >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR bd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_birth_details bd +// LEFT JOIN tbl_birth_esign_cert bec ON bec.reg_no = bd.REGISTRATION_NUMBER +// WHERE bd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(bd.SEX)) = ? +// AND UPPER(bd.FATHER_NAME) LIKE ? +// AND UPPER(bd.MOTHER_NAME) LIKE ? +// """); + +// List newParams = new ArrayList<>(); +// newParams.add(upperGender.trim().toUpperCase()); +// newParams.add("%" + upperFather.trim().toUpperCase() + "%"); +// newParams.add("%" + upperMother.trim().toUpperCase() + "%"); + +// if (upperChild != null) { +// newSql.append(" AND UPPER(bd.CHILD_NAME) LIKE ? "); +// newParams.add("%" + upperChild.trim().toUpperCase() + "%"); +// } + +// if (trimmedDob != null) { +// newSql.append(" AND bd.DATE_OF_BIRTH = TO_DATE(?, 'DD-MM-YYYY') "); +// newParams.add(trimmedDob); +// } + +// try { +// List> newResult = newJdbc.queryForList(newSql.toString(), newParams.toArray()); +// if (!newResult.isEmpty()) { +// return newdetailsformatResult(newResult); +// } +// } catch (EmptyResultDataAccessException e) { +// // Continue to old source +// } catch (Exception e) { +// throw new RuntimeException("Error querying new birth table", e); +// } + +// // ---------- OLD ---------- + +// StringBuilder oldSql = new StringBuilder(""" +// SELECT +// bdo.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bdo.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bdo.created_date , 'DD-MM-YYYY') AS created_date, +// bdo.SEX AS gender, +// bdo.FATHER_NAME AS father_name, +// bdo.MOTHER_NAME AS mother_name, +// bdo.CHILD_NAME AS child_name, +// CASE +// WHEN (bdo.verified_dt < TO_DATE('19-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status, 'NA') AS status, +// beco.cert_file +// FROM tbl_birth_details bdo +// LEFT JOIN tbl_birth_esign_cert beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_B_' || bdo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(bdo.SEX)) = ? +// AND UPPER(bdo.FATHER_NAME) LIKE ? +// AND UPPER(bdo.MOTHER_NAME) LIKE ? +// """); + +// List oldParams = new ArrayList<>(); +// oldParams.add(upperGender.trim().toUpperCase()); +// oldParams.add("%" + upperFather.trim().toUpperCase() + "%"); +// oldParams.add("%" + upperMother.trim().toUpperCase() + "%"); + +// if (upperChild != null && !upperChild.isBlank()) { +// oldSql.append(" AND UPPER(bdo.CHILD_NAME) LIKE ? "); +// oldParams.add("%" + upperChild.trim().toUpperCase() + "%"); +// } + +// if (trimmedDob != null && !trimmedDob.isBlank()) { +// oldSql.append(" AND bdo.DATE_OF_BIRTH = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(trimmedDob); +// } + +// try { +// List> oldResult = oldJdbc.queryForList(oldSql.toString(), oldParams.toArray()); +// if (!oldResult.isEmpty()) { +// return newdetailsformatResult(oldResult); +// } +// } catch (EmptyResultDataAccessException e) { +// e.printStackTrace(); +// return Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } catch (Exception e) { +// e.printStackTrace(); +// // Return "not_found" with message instead of throwing exception +// return Map.of("status", "not_found", "message", "No matching birth certificate found.", "status_code", 404); +// } + +// return Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } + + + +// private Map newdetailsformatResult(List> rows) { + +// //System.out.println("rows="+rows); + +// if (rows == null || rows.isEmpty()) { +// return Map.of("status", "not_found", "message", +// "No matching birth certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } + +// Map response = new LinkedHashMap<>(); +// response.put("status", "success"); + +// List> certificateDetailsList = new ArrayList<>(); + +// for (Map row : rows) { +// Map birthresponse = new LinkedHashMap<>(); + +// birthresponse.put("regno", row.get("regno") != null ? row.get("regno").toString() : ""); +// birthresponse.put("name", row.get("child_name") != null ? row.get("child_name").toString() : " "); + + +// birthresponse.put("dob", row.get("dob")); + +// //System.out.println("dob="+row.get("dob")); + +// birthresponse.put("verified_date",row.get("verified_date") != null ? row.get("verified_date").toString().trim() : ""); +// birthresponse.put("created_date",row.get("created_date") != null ? row.get("created_date").toString().trim() : ""); +// String createdDateStr = (row.get("created_date") != null) ? row.get("created_date").toString().trim() : ""; + +// //System.out.println("verified_date="+row.get("verified_date")); +// // ---- Gender ---- +// String gender = row.get("gender") != null ? row.get("gender").toString().trim().toUpperCase() : ""; +// if ("M".equals(gender)) { +// birthresponse.put("gender", "Male"); +// } else if ("F".equals(gender)) { +// birthresponse.put("gender", "Female"); +// } else if ("G".equals(gender)) { +// birthresponse.put("gender", "Transgender"); +// } else { +// birthresponse.put("gender", "other"); // fallback if unknown value +// } + +// birthresponse.put("father_name", row.get("father_name")); +// birthresponse.put("mother_name", row.get("mother_name")); +// birthresponse.put("status",row.get("status")); +// // ---- Build PDF URL ---- +// String regNo = row.get("regno") != null ? row.get("regno").toString() : ""; +// Integer regVal = row.get("reg_val") instanceof Number ? ((Number) row.get("reg_val")).intValue() : 0; +// String status = String.valueOf(row.getOrDefault("status", "NA")); +// String certFile = row.get("cert_file") != null ? row.get("cert_file").toString() : ""; + +// // System.out.println("certFile="+certFile); + +// String pdfUrl = ""; + +// if ("S".equalsIgnoreCase(status)) { +// // ✅ eSign URL for successful certificates +// pdfUrl = eSign_CERTIFICATE_URL_PREFIX + certFile; + +// } else if ("P".equalsIgnoreCase(status)) { +// // ✅ Pending certificates + +// // this condition for before 2012 old pending certificate link if status is "P" +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isBefore(LocalDate.of(2012, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = ""; // newer pending — no link +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } + +// } else { +// // ✅ Other statuses +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isAfter(LocalDate.of(2018, 1, 1))) { +// //pdfUrl = CRS_CERTIFICATE_URL_PREFIX + regNo; +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// } + +// birthresponse.put("pdf_url", pdfUrl); + +// // add this row to the list +// certificateDetailsList.add(birthresponse); + +// } + +// response.put("certificate_details", certificateDetailsList); +// return response; +// } + + + +// //added by yogi for web crslogs updated with combined records to fetch + +// public Map getByNewDetailsOracleOldAndNewForWeb( +// String dob, String father, String mother, String child, String gender) { + +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // ---------- Input normalization ---------- +// String upperFather = (father != null && !father.isBlank()) ? father.trim().toUpperCase() : ""; +// String upperMother = (mother != null && !mother.isBlank()) ? mother.trim().toUpperCase() : ""; +// String upperGender = (gender != null && !gender.isBlank()) ? gender.trim().toUpperCase() : ""; +// String upperChild = (child != null && !child.isBlank()) ? child.trim().toUpperCase() : null; +// String trimmedDob = (dob != null && !dob.trim().isEmpty()) ? dob.trim() : null; + +// // ---------- Combined result list ---------- +// List> combinedResults = new ArrayList<>(); + +// // ---------- NEW + ADOPTION UNION ---------- +// StringBuilder newSql = new StringBuilder(""" +// SELECT * FROM ( +// -- Regular Birth Details +// SELECT +// bd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bd.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(bd.created_date , 'DD-MM-YYYY') AS created_date, +// bd.SEX AS gender, +// bd.FATHER_NAME AS father_name, +// bd.MOTHER_NAME AS mother_name, +// bd.CHILD_NAME AS child_name, +// CASE +// WHEN (bd.verified_dt >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR bd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_birth_details bd +// LEFT JOIN tbl_birth_esign_cert bec +// ON bec.reg_no = bd.REGISTRATION_NUMBER +// WHERE bd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(bd.SEX)) = ? +// AND UPPER(bd.FATHER_NAME) LIKE ? +// AND UPPER(bd.MOTHER_NAME) LIKE ? +// """); + +// List params = new ArrayList<>(); +// params.add(upperGender); +// params.add("%" + upperFather + "%"); +// params.add("%" + upperMother + "%"); + +// if (upperChild != null) { +// newSql.append(" AND UPPER(bd.CHILD_NAME) LIKE ? "); +// params.add("%" + upperChild + "%"); +// } +// if (trimmedDob != null) { +// newSql.append(" AND bd.DATE_OF_BIRTH = TO_DATE(?, 'DD-MM-YYYY') "); +// params.add(trimmedDob); +// } + +// // ---------- Adoption Table UNION ---------- +// newSql.append(""" +// UNION ALL +// SELECT +// A.REGISTRATION_NUMBER AS regno, +// TO_CHAR(A.DATE_OF_BIRTH , 'DD-MM-YYYY') AS dob, +// TO_CHAR(A.created_date , 'DD-MM-YYYY') AS created_date, +// A.SEX AS gender, +// NVL(A.ADPT_FATHER_NAME,' ') AS father_name, +// NVL(A.ADPT_MOTHER_NAME,' ') AS mother_name, +// NVL(A.ADPT_CHILDNAME,' ') AS child_name, +// CASE +// WHEN (A.MODIFIED_DATE >= TO_DATE('19-06-2019','DD-MM-YYYY') +// OR A.REGISTRATION_DATE >= TO_DATE('01-06-2019','DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(B.status,'NA') AS status, +// B.cert_file +// FROM TBL_ADPT_BIRTH_DETAILS A +// LEFT JOIN TBL_BIRTH_ESIGN_CERT B +// ON A.REGISTRATION_NUMBER = B.reg_no +// WHERE A.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(A.SEX)) = ? +// AND UPPER(NVL(A.ADPT_FATHER_NAME,' ')) LIKE ? +// AND UPPER(NVL(A.ADPT_MOTHER_NAME,' ')) LIKE ? +// """); + +// params.add(upperGender); +// params.add("%" + upperFather + "%"); +// params.add("%" + upperMother + "%"); + +// if (trimmedDob != null) { +// newSql.append(" AND TRUNC(A.DATE_OF_BIRTH) = TO_DATE(?, 'DD-MM-YYYY') "); +// params.add(trimmedDob); +// } + +// newSql.append(" ) ORDER BY father_name "); + +// // ---------- Execute NEW DB Query ---------- +// try { +// List> newResult = newJdbc.queryForList(newSql.toString(), params.toArray()); +// if (!newResult.isEmpty()) { +// combinedResults.addAll(newResult); +// } +// } catch (Exception e) { +// System.err.println("⚠️ Error querying NEW DB: " ); +// } + +// // ---------- OLD TABLE ---------- +// StringBuilder oldSql = new StringBuilder(""" +// SELECT +// Z.ZONE_CODE || '-' || Z.ZONE_NAME AS zone_name, +// Y.DIVISION_NAME AS division_name, +// bdo.hospital_id, +// TO_CHAR(bdo.verified_dt, 'dd-mm-yyyy') as verified_date, +// TO_CHAR(bdo.created_date, 'dd-mm-yyyy') as created_date, +// TO_CHAR(bdo.DATE_OF_BIRTH, 'DD-MM-YYYY') AS dob, +// bdo.SEX AS gender, +// NVL(bdo.CHILD_NAME,' ') AS child_name, +// NVL(bdo.FATHER_NAME,' ') AS father_name, +// NVL(bdo.MOTHER_NAME,' ') AS mother_name, +// CASE bdo.birth_place +// WHEN 1 THEN 'HOSPITAL' +// WHEN 2 THEN 'HOME' +// ELSE 'OTHERS' +// END AS birth_place, +// bdo.REGISTRATION_NUMBER AS regno, +// bdo.place_of_birth_add1, +// CASE +// WHEN bdo.verified_dt < TO_DATE('19-06-2019', 'DD-MM-YYYY') THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status,'NA') AS status, +// beco.cert_file +// FROM TBL_BIRTH_DETAILS bdo +// JOIN TBL_ZONE Z ON bdo.ZONE_ID = Z.ZONE_ID +// JOIN TBL_DIVISION Y ON bdo.DIVISON_ID = Y.DIVISON_ID +// LEFT JOIN TBL_BIRTH_ESIGN_CERT beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_B_' || bdo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(bdo.SEX)) = ? +// AND UPPER(bdo.FATHER_NAME) LIKE ? +// AND UPPER(bdo.MOTHER_NAME) LIKE ? +// """); + +// List oldParams = new ArrayList<>(); +// oldParams.add(upperGender); +// oldParams.add("%" + upperFather + "%"); +// oldParams.add("%" + upperMother + "%"); + +// if (upperChild != null) { +// oldSql.append(" AND UPPER(bdo.CHILD_NAME) LIKE ? "); +// oldParams.add("%" + upperChild + "%"); +// } +// if (trimmedDob != null) { +// oldSql.append(" AND bdo.DATE_OF_BIRTH = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(trimmedDob); +// } + +// oldSql.append(" ORDER BY bdo.FATHER_NAME "); + + + +// // ---------- Execute OLD DB Query ---------- +// try { +// List> oldResult = oldJdbc.queryForList(oldSql.toString(), oldParams.toArray()); + +// if (!oldResult.isEmpty()) { +// combinedResults.addAll(oldResult); +// } +// } catch (Exception e) { +// System.err.println("⚠️ Error querying OLD DB: " ); +// } + +// // ---------- Combine and Return ---------- +// if (!combinedResults.isEmpty()) { +// combinedResults.sort(Comparator.comparing(m -> String.valueOf(m.get("father_name")))); +// return newdetailsformatResult(combinedResults); +// } + +// return Map.of( +// "status", "not_found", +// "message", "No matching birth or adoption certificate found.", +// "status_code", 404 +// ); +// } + + + + +// public Map getOldBirthDetailsStatic() { +// // Create a JdbcTemplate for the old Oracle DB +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // SQL Query (exactly your static example) +// String sql = """ +// SELECT +// bdo.REGISTRATION_NUMBER AS regno, +// Y.DIVISION_NAME AS division_name, +// bdo.hospital_id, +// bdo.date_of_birth AS date_of_birth, +// bdo.SEX AS sex, +// CASE +// WHEN bdo.verified_dt < TO_DATE('19-06-2019', 'DD-MM-YYYY') THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status, 'NA') AS status, +// beco.cert_file +// FROM TBL_BIRTH_DETAILS bdo +// JOIN TBL_ZONE Z ON bdo.ZONE_ID = Z.ZONE_ID +// JOIN TBL_DIVISION Y ON bdo.DIVISON_ID = Y.DIVISON_ID +// LEFT JOIN TBL_BIRTH_ESIGN_CERT beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_B_' || bdo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(bdo.SEX)) = 'F' +// AND TRUNC(bdo.DATE_OF_BIRTH) = TO_DATE('16-03-1994', 'DD-MM-YYYY') +// """; + +// try { +// // Execute and fetch results +// List> results = oldJdbc.queryForList(sql); + +// if (!results.isEmpty()) { +// // Return formatted response +// return Map.of( +// "status", "success", +// "count", results.size(), +// "data", results +// ); +// } else { +// return Map.of( +// "status", "not_found", +// "message", "No records found in old DB." +// ); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// return Map.of( +// "status", "error", +// "message", "Error querying old Oracle DB: " + e.getMessage() +// ); +// } +// } + + +// public List> getAllAdoptionBirthDetails() { + +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// String sql = """ +// SELECT +// A.REGISTRATION_NUMBER AS regno, +// TO_CHAR(A.DATE_OF_BIRTH, 'yyyy-mm-dd') AS dob, +// A.SEX AS gender, +// NVL(A.ADPT_FATHER_NAME, ' ') AS father_name, +// NVL(A.ADPT_MOTHER_NAME, ' ') AS mother_name, +// NVL(A.ADPT_CHILDNAME, ' ') AS child_name, +// A.ZONE_ID, +// A.DIVISION_ID, +// A.CREATED_DATE, +// A.MODIFIED_DATE, +// A.REGISTRATION_DATE, +// NVL(B.status, 'NA') AS status, +// B.cert_file +// FROM TBL_ADPT_BIRTH_DETAILS A +// LEFT JOIN TBL_BIRTH_ESIGN_CERT B +// ON A.REGISTRATION_NUMBER = B.reg_no +// ORDER BY A.ADPT_FATHER_NAME +// """; + +// return newJdbc.queryForList(sql); +// } + + + +// public List> getOldBirthDetails(String dob, String gender) { +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// String sql = """ +// SELECT +// REGISTRATION_NUMBER, +// TO_CHAR(DATE_OF_BIRTH, 'DD-MM-YYYY') AS dob, +// SEX AS gender +// FROM TBL_BIRTH_DETAILS +// WHERE TRIM(UPPER(SEX)) = ? +// AND TRUNC(DATE_OF_BIRTH) = TO_DATE(?, 'DD-MM-YYYY') +// """; + +// return oldJdbc.queryForList(sql, gender.toUpperCase(), dob); +// } + + +// } \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/service/ChildNameInclusionService.java b/src/main/java/com/gcc/restapiservices/birthanddeath/service/ChildNameInclusionService.java new file mode 100644 index 0000000..f9be042 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/service/ChildNameInclusionService.java @@ -0,0 +1,420 @@ +// package com.gcc.restapiservices.birthanddeath.service; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.beans.factory.annotation.Qualifier; +// import org.springframework.dao.DataAccessException; +// import org.springframework.jdbc.core.JdbcTemplate; +// import org.springframework.stereotype.Service; +// import org.springframework.web.multipart.MultipartFile; + +// import javax.sql.DataSource; +// 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.nio.file.StandardCopyOption; +// import java.util.HashMap; +// import java.util.List; +// import java.util.Map; + +// @Service +// public class ChildNameInclusionService { +// private JdbcTemplate jdbcTemplate; + +// @Autowired +// public ChildNameInclusionService(JdbcTemplate jdbcTemplate) { +// this.jdbcTemplate = jdbcTemplate; +// } + + + + + +// // private final RestTemplate restTemplate; + +// // public ChildNameInclusionService(@Qualifier("sslBypassRestTemplate") RestTemplate restTemplate) { +// // this.restTemplate = restTemplate; +// // } + +// //birth and death new live db connection +// @Autowired +// @Qualifier("oracleBirthNewDataSourceItCell") +// private DataSource newBirthDataSource; + +// //birth and death old live db connection +// @Autowired +// @Qualifier("oracleBirthOldDataSourceItCell") +// private DataSource oldBirthDataSource; + + +// public Map getByRegNo(String regNo, String mobile) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); +// Map response = new HashMap<>(); +// Map result = new HashMap<>(); +// if (regNo.isEmpty() || regNo == null) { +// result.put("Message", "Please provide Registration Number"); +// response.put("Response", result); +// return response; +// } +// String newSql = "Select case when ceil (months_between(sysdate,date_of_birth)/12)>=5 then 1 else 0 end age_5," + +// " (select zone_code||'-'||zone_name from tbl_zone z where z.zone_id=x.zone_id) zone_name, " + +// " (select division_name from tbl_division d where d.divison_id=x.divison_id) division_name, " + +// " to_char(DATE_OF_BIRTH,'dd/mm/yyyy') DATE_OF_BIRTH , TO_CHAR(CREATED_DATE,'DD/MM/RRRR') CREATED_DATE, NVL(SEX,' ') SEX ," + +// " nvl(CHILD_NAME,' ') CHILD_NAME , nvl(FATHER_NAME,' ') FATHER_NAME , nvl(MOTHER_NAME,' ') MOTHER_NAME, nvl(FATH_MOB_NO, ' ') FATH_MOB_NO, nvl(MOTH_MOB_NO, ' ') MOTH_MOB_NO, " + +// " nvl(X.PERMANENT_ADDRESS1,' ') ||' '|| nvl(X.PERMANENT_ADDRESS2,' ') ||' '|| " + +// " case when nvl(X.PERMANENT_ADDRESS3,'NULL') not like 'NULL%' then X.PERMANENT_ADDRESS3 else ' ' end ||' '|| replace( " + +// " (CASE WHEN trim(X.PERMTBLDGNO) IS NOT NULL THEN X.PERMTBLDGNO ||', ' ELSE ' ' END || " + +// " CASE WHEN trim(X.PERMTHOUSENO) IS NOT NULL THEN X.PERMTHOUSENO ||', ' ELSE ' 'END || " + +// "CASE WHEN INSTR(X.PERMTADDR1,'_')>=0 THEN SUBSTR(X.PERMTADDR1,1,INSTR(X.PERMTADDR1,'_')-1)||', ' ELSE X.PERMTADDR1||', ' END|| " + +// " CASE WHEN nvl(X.PERMTVLG,'NL') not in ('NL','NULL_NULL') THEN X.PERMTVLG ||', ' ELSE '' END || " + +// " CASE WHEN INSTR(X.PERMTADDR1,'_')>=0 THEN SUBSTR(X.PERMTADDR1,INSTR(X.PERMTADDR1,'_')+1)||', ' ELSE X.PERMTADDR1||', ' END || " + +// " CASE WHEN INSTR(X.PERMTSUBDIST,'_')>0 THEN SUBSTR(X.PERMTSUBDIST,1,INSTR(X.PERMTSUBDIST,'_')-1) ELSE X.PERMTSUBDIST END ||', '|| " + +// " CASE WHEN INSTR(X.PERMTDIST,'_')>0 THEN SUBSTR(X.PERMTDIST,1,INSTR(X.PERMTDIST,'_')-1) ELSE X.PERMTDIST END ||', '|| " + +// " CASE WHEN X.PERMTSTATE IS NOT NULL THEN X.PERMTSTATE ELSE ' ' END || " + +// " CASE WHEN TO_CHAR(X.PERMTPIN) IS NOT NULL THEN '-'||X.PERMTPIN ||' ' ELSE ' 'END),', ', ', ') || " + +// " case nvl(X.PERMANENT_PIN,'0') when '0' then ' ' else ' '||X.PERMANENT_PIN end PERM_ADDR, " + +// " CASE WHEN X.PARENTBLDGNO IS NOT NULL THEN X.PARENTBLDGNO||', ' ELSE ' ' END || " + +// " CASE WHEN X.PARENTHOUSENO IS NOT NULL THEN X.PARENTHOUSENO||', ' ELSE ' ' END || " + +// " CASE WHEN nvl(X.PARENTADDRESS,'_') not in ('_','NULL_NULL') THEN nvl(substr(X.PARENTADDRESS,1,instr(X.PARENTADDRESS,'_')-1),' ') ||' , ' ELSE ' ' END || " + +// " CASE WHEN X.PARENTVLG IS NOT NULL THEN X.PARENTVLG||', ' ELSE ' ' END || " + +// " CASE WHEN nvl(X.PARENTADDRESS,'_') not in ('_','NULL_NULL') THEN nvl(substr(X.PARENTADDRESS,instr(X.PARENTADDRESS,'_')+1),' ') ||' , ' ELSE ' ' END || " + +// " CASE WHEN INSTR(X.PARENTSUBDIST,'_') >0 THEN SUBSTR(X.PARENTSUBDIST,1,INSTR(X.PARENTSUBDIST,'_')-1 ) ELSE X.PARENTSUBDIST END ||', '||" + +// " CASE WHEN INSTR(X.PARENTDIST,'_') >0 THEN SUBSTR(X.PARENTDIST,1,INSTR(X.PARENTDIST,'_')-1 ) ELSE X.PARENTDIST END ||', '|| " + +// " CASE WHEN X.PARENTSTATE IS NOT NULL AND X.PARENTSTATE IN ('1','2') THEN X.PARENTSTATE ELSE X.PARENTSTATE END || " + +// " nvl(X.CURRENT_ADDRESS1,' ') ||' '||nvl(X.CURRENT_ADDRESS2,' ') ||' '||nvl(X.CURRENT_ADDRESS3,' ') ||' '|| nvl(X.cnt_name,' ') ||' '|| " + +// " CASE WHEN PARENTPIN IS NOT NULL THEN '- '|| PARENTPIN ELSE ' ' END currentAddress ," + +// " CASE WHEN BIRTH_PLACE !=1 THEN " + +// " BIRTH_PLACE||' '||PLACE_OF_BIRTH_ADD1||' '||PLACE_OF_BIRTH_ADD2||' '||PLACE_OF_BIRTH_ADD3||' '||PLACE_OF_BIRTH_PIN " + +// " ELSE " + +// " (SELECT HOSPITAL_NAME||chr(13) ||HOSPITAL_ADDRESS1||' '||HOSPITAL_ADDRESS2||' ' ||HOSPITAL_ADDRESS3||' '||HOSPITAL_PIN " + +// " FROM TBL_HOSPITAL H WHERE H.HOSPITAL_ID=X.HOSPITAL_ID) END PLACE_BIRTH ,'COC' COC " + +// " from TBL_BIRTH_DETAILS X where registration_number= ? and child_name is null " + +// " and zone_id between 501 and 515 "; + +// String oldSql = "Select case when ceil (months_between(sysdate,date_of_birth)/12)>=5 then 1 else 0 end age_5," + +// " (select zone_code||'-'||zone_name from tbl_zone z where z.zone_id=x.zone_id) zone_name, " + +// " (select division_name from tbl_division d where d.divison_id=x.divison_id) division_name, " + +// " to_char(DATE_OF_BIRTH,'dd/mm/yyyy') DATE_OF_BIRTH , TO_CHAR(CREATED_DATE,'DD/MM/RRRR') CREATED_DATE, NVL(SEX,' ') SEX ," + +// " nvl(CHILD_NAME,' ') CHILD_NAME , nvl(FATHER_NAME,' ') FATHER_NAME , nvl(MOTHER_NAME,' ') MOTHER_NAME, registration_number, " + +// " nvl(PERMANENT_ADDRESS1,' ') ||'
'||nvl(PERMANENT_ADDRESS2,' ')||'
' || " + +// " nvl(PERMANENT_ADDRESS3,' ')||'-' || PERMANENT_PIN PERM_ADDR, " + +// " " + +// " nvl(CURRENT_ADDRESS1,' ') ||'
'||nvl(CURRENT_ADDRESS2,' ')||'
' || " + +// " nvl(CURRENT_ADDRESS3,' ')||'-' || CURRENT_PIN PERM_ADDR, " + +// " " + +// " CASE WHEN BIRTH_PLACE !=1 THEN " + +// " BIRTH_PLACE||' '||PLACE_OF_BIRTH_ADD1||' '||PLACE_OF_BIRTH_ADD2||' '||PLACE_OF_BIRTH_ADD3||' '||PLACE_OF_BIRTH_PIN " + +// " ELSE " + +// " (SELECT HOSPITAL_NAME||chr(13) ||HOSPITAL_ADDRESS1||' '||HOSPITAL_ADDRESS2||' ' ||HOSPITAL_ADDRESS3||' '||HOSPITAL_PIN " + +// " FROM TBL_HOSPITAL H WHERE H.HOSPITAL_ID=X.HOSPITAL_ID) END PLACE_BIRTH ,'COC' COC " + +// " from TBL_BIRTH_DETAILS X where registration_number= ? and " + +// " zone_id between 54 and 68 and child_name is null "; + +// try { +// System.out.println("check 12"); +// List> newResults = newJdbc.queryForList(newSql, regNo); +// System.out.println("check 11"); +// // System.out.println("mob no.."+newResults.get("FATH_MOB_NO")+"\n"+newResults.get("MOTH_MOB_NO")+"\nsize:"+newResults.size()); +// if (!newResults.isEmpty()) { +// System.out.println("check 1"); +// String father = (newResults.get(0).get("FATH_MOB_NO") != null && !newResults.get(0).get("FATH_MOB_NO").toString().trim().isEmpty()) +// ? newResults.get(0).get("FATH_MOB_NO").toString().trim() +// : ""; +// String mother = (newResults.get(0).get("MOTH_MOB_NO") != null && !newResults.get(0).get("MOTH_MOB_NO").toString().trim().isEmpty()) +// ? newResults.get(0).get("MOTH_MOB_NO").toString().trim() +// : ""; + +// if (mobile.equalsIgnoreCase(father) || mobile.equalsIgnoreCase(mother) || father.isEmpty() || mother.isEmpty()) { +// result.put("Status", "Sucess"); +// result.put("Status Code", 200); +// result.put("Message", "Child Data fetched successfully"); +// result.put("Data", newResults); +// response.put("Response", result); +// return response; +// } else { +// result.put("Message", "Kindly check through your registered mobile number"); +// response.put("Response", result); +// return response; +// } + +// } +// List> oldResults = oldJdbc.queryForList(oldSql, regNo); +// // List> oldResults = oldJdbc.queryForList(oldSql); +// if (!oldResults.isEmpty()) { +// result.put("Status", "Sucess"); +// result.put("Status Code", 200); +// result.put("Message", "Child Data fetched successfully"); +// result.put("Data", oldResults); +// response.put("Response", result); +// return response; +// } +// if (newResults.isEmpty() && oldResults.isEmpty()) { +// result.put("Status", "Not Found"); +// result.put("Message", "Child Data Not Found"); +// result.put("Status Code", 404); +// response.put("Response", result); +// return response; +// } +// } catch (Exception e) { +// e.printStackTrace(); +// result.put("Status", "Error"); +// result.put("Message", "Error in fetching Child Data :" + e); +// result.put("Status Code", 500); +// response.put("Response", result); +// } +// return response; +// } + +// public Map getDetailsByMobNo(String mobile) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); +// Map response = new HashMap<>(); +// Map result = new HashMap<>(); +// if (mobile.isEmpty() || mobile == null) { +// result.put("Message", "Please provide Registration Number"); +// response.put("Response", result); +// return response; +// } +// String newSql = "Select case when ceil (months_between(sysdate,date_of_birth)/12)>=5 then 1 else 0 end age_5," + +// " (select zone_code||'-'||zone_name from tbl_zone z where z.zone_id=x.zone_id) zone_name, " + +// " (select division_name from tbl_division d where d.divison_id=x.divison_id) division_name, " + +// " to_char(DATE_OF_BIRTH,'dd/mm/yyyy') DATE_OF_BIRTH , TO_CHAR(CREATED_DATE,'DD/MM/RRRR') CREATED_DATE, NVL(SEX,' ') SEX ," + +// " nvl(CHILD_NAME,' ') CHILD_NAME , nvl(FATHER_NAME,' ') FATHER_NAME , nvl(MOTHER_NAME,' ') MOTHER_NAME, nvl(FATH_MOB_NO, ' ') FATH_MOB_NO, nvl(MOTH_MOB_NO, ' ') MOTH_MOB_NO, " + +// " nvl(X.PERMANENT_ADDRESS1,' ') ||' '|| nvl(X.PERMANENT_ADDRESS2,' ') ||' '|| " + +// " case when nvl(X.PERMANENT_ADDRESS3,'NULL') not like 'NULL%' then X.PERMANENT_ADDRESS3 else ' ' end ||' '|| replace( " + +// " (CASE WHEN trim(X.PERMTBLDGNO) IS NOT NULL THEN X.PERMTBLDGNO ||', ' ELSE ' ' END || " + +// " CASE WHEN trim(X.PERMTHOUSENO) IS NOT NULL THEN X.PERMTHOUSENO ||', ' ELSE ' 'END || " + +// " CASE WHEN INSTR(X.PERMTADDR1,'_')>=0 THEN SUBSTR(X.PERMTADDR1,1,INSTR(X.PERMTADDR1,'_')-1)||', ' ELSE X.PERMTADDR1||', ' END|| " + +// " CASE WHEN nvl(X.PERMTVLG,'NL') not in ('NL','NULL_NULL') THEN X.PERMTVLG ||', ' ELSE '' END || " + +// " CASE WHEN INSTR(X.PERMTADDR1,'_')>=0 THEN SUBSTR(X.PERMTADDR1,INSTR(X.PERMTADDR1,'_')+1)||', ' ELSE X.PERMTADDR1||', ' END || " + +// " CASE WHEN INSTR(X.PERMTSUBDIST,'_')>0 THEN SUBSTR(X.PERMTSUBDIST,1,INSTR(X.PERMTSUBDIST,'_')-1) ELSE X.PERMTSUBDIST END ||', '|| " + +// " CASE WHEN INSTR(X.PERMTDIST,'_')>0 THEN SUBSTR(X.PERMTDIST,1,INSTR(X.PERMTDIST,'_')-1) ELSE X.PERMTDIST END ||', '|| " + +// " CASE WHEN X.PERMTSTATE IS NOT NULL THEN X.PERMTSTATE ELSE ' ' END || " + +// " CASE WHEN TO_CHAR(X.PERMTPIN) IS NOT NULL THEN '-'||X.PERMTPIN ||' ' ELSE ' 'END),', ', ', ') || " + +// " case nvl(X.PERMANENT_PIN,'0') when '0' then ' ' else ' '||X.PERMANENT_PIN end PERM_ADDR, " + +// " " + +// " CASE WHEN X.PARENTBLDGNO IS NOT NULL THEN X.PARENTBLDGNO||', ' ELSE ' ' END || " + +// " CASE WHEN X.PARENTHOUSENO IS NOT NULL THEN X.PARENTHOUSENO||', ' ELSE ' ' END || " + +// " CASE WHEN nvl(X.PARENTADDRESS,'_') not in ('_','NULL_NULL') THEN nvl(substr(X.PARENTADDRESS,1,instr(X.PARENTADDRESS,'_')-1),' ') ||' , ' ELSE ' ' END || " + +// " CASE WHEN X.PARENTVLG IS NOT NULL THEN X.PARENTVLG||', ' ELSE ' ' END || " + +// " CASE WHEN nvl(X.PARENTADDRESS,'_') not in ('_','NULL_NULL') THEN nvl(substr(X.PARENTADDRESS,instr(X.PARENTADDRESS,'_')+1),' ') ||' , ' ELSE ' ' END || " + +// " CASE WHEN INSTR(X.PARENTSUBDIST,'_') >0 THEN SUBSTR(X.PARENTSUBDIST,1,INSTR(X.PARENTSUBDIST,'_')-1 ) ELSE X.PARENTSUBDIST END ||', '||" + +// " CASE WHEN INSTR(X.PARENTDIST,'_') >0 THEN SUBSTR(X.PARENTDIST,1,INSTR(X.PARENTDIST,'_')-1 ) ELSE X.PARENTDIST END ||', '|| " + +// " CASE WHEN X.PARENTSTATE IS NOT NULL AND X.PARENTSTATE IN ('1','2') THEN X.PARENTSTATE ELSE X.PARENTSTATE END || " + +// " nvl(X.CURRENT_ADDRESS1,' ') ||' '||nvl(X.CURRENT_ADDRESS2,' ') ||' '||nvl(X.CURRENT_ADDRESS3,' ') ||' '|| nvl(X.cnt_name,' ') ||' '|| " + +// " CASE WHEN PARENTPIN IS NOT NULL THEN '- '|| PARENTPIN ELSE ' ' END currentAddress ," + +// " " + +// " " + +// " CASE WHEN BIRTH_PLACE !=1 THEN " + +// " BIRTH_PLACE||' '||PLACE_OF_BIRTH_ADD1||' '||PLACE_OF_BIRTH_ADD2||' '||PLACE_OF_BIRTH_ADD3||' '||PLACE_OF_BIRTH_PIN " + +// " ELSE " + +// " (SELECT HOSPITAL_NAME||chr(13) ||HOSPITAL_ADDRESS1||' '||HOSPITAL_ADDRESS2||' ' ||HOSPITAL_ADDRESS3||' '||HOSPITAL_PIN " + +// " FROM TBL_HOSPITAL H WHERE H.HOSPITAL_ID=X.HOSPITAL_ID) END PLACE_BIRTH ,'COC' COC " + +// " from TBL_BIRTH_DETAILS X where child_name is null and (FATH_MOB_NO= ? OR MOTH_MOB_NO = ?) " + +// " and zone_id between 501 and 515 "; +// try { +// List> newResults = newJdbc.queryForList(newSql, mobile, mobile); +// if (!newResults.isEmpty()) { +// result.put("Status", "Sucess"); +// result.put("Status Code", 200); +// result.put("Message", "Child Data fetched successfully"); +// result.put("Data", newResults); +// response.put("Response", result); +// } else { +// result.put("Status", "Not Found"); +// result.put("Message", "Child Data Not Found"); +// result.put("Status Code", 404); +// response.put("Response", result); +// } +// } catch (DataAccessException e) { +// e.printStackTrace(); +// result.put("Status", "Error"); +// result.put("Message", "Error in fetching Child Data :" + e); +// result.put("Status Code", 500); +// response.put("Response", result); +// } +// return response; +// } + + + +// // public String saveChildNameInclusion(Map formFields, +// // Map files) throws IOException { +// // +// // JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// // +// // // 1. Get sequence values +// // Map seqData = newJdbc.queryForMap( +// // "SELECT birth_death_tn.file_seq.NEXTVAL AS stg_id, birth_death_tn.id.NEXTVAL AS id FROM dual" +// // ); +// // String stagId = seqData.get("stg_id").toString(); +// // String sId = seqData.get("id").toString(); +// // +// // // 2. Handle file uploads +// // if (files != null) { +// // for (Map.Entry entry : files.entrySet()) { +// // MultipartFile file = entry.getValue(); +// // if (!file.isEmpty()) { +// // if (file.getSize() > MAX_FILE_SIZE) { +// // throw new IOException("File size exceeds 4MB: " + entry.getKey()); +// // } +// // String originalFileName = file.getOriginalFilename(); +// // String ext = originalFileName.substring(originalFileName.lastIndexOf(".") + 1).toLowerCase(); +// // if (!ext.equals("jpg") && !ext.equals("jpeg") && !ext.equals("pdf")) { +// // throw new IOException("Invalid file type for: " + entry.getKey()); +// // } +// // String newFileName = stagId + "_" + originalFileName; +// // File dest = new File(FILE_PATH, newFileName); +// // file.transferTo(dest); +// // formFields.put(entry.getKey(), newFileName); +// // } +// // } +// // } +// // +// // // 3. Insert into main table +// // String insertCtzn = """ +// // INSERT INTO birth_death_tn.tbl_birth_death_corr_ctzn +// // (id, reg_no, isBD, txt_mob, s_user_id, cr_date, ack_no, status, rd_birth_corr) +// // VALUES (?, ?, ?, ?, ?, SYSDATE, NULL, 'P', ?) +// // """; +// // newJdbc.update(insertCtzn, +// // sId, +// // formFields.get("reg_no"), +// // formFields.get("isBD"), +// // formFields.get("txt_mob"), +// // "0", +// // formFields.get("rd_birth_corr") +// // ); +// // +// // // 4. Insert into birth correction table +// // String insertBirth = """ +// // INSERT INTO birth_death_tn.tbl_birth_corr_fle +// // (id, fle_par_dcl, fle_par_id, fle_afft_ltr, fle_dob, m_child) +// // VALUES (?, ?, ?, ?, ?, ?) +// // """; +// // newJdbc.update(insertBirth, +// // sId, +// // formFields.get("fle_par_dcl"), +// // formFields.get("fle_par_id"), +// // formFields.get("fle_afft_ltr"), +// // formFields.get("fle_dob"), +// // formFields.get("m_child") +// // ); +// // +// // // 5. Generate and update acknowledgement number +// // String ackNo = "P/" + formFields.get("isBD") + "/" + sId; +// // newJdbc.update( +// // "UPDATE birth_death_tn.tbl_birth_death_corr_ctzn SET ack_no=? WHERE id=?", +// // ackNo, sId +// // ); +// // +// // return ackNo; +// // } + + + +// // +// // public String saveChildNameInclusion(Map formFields, +// // Map files) throws IOException { +// // +// // JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// // +// // // 1. Get sequence values +// // Map seqData = newJdbc.queryForMap( +// // "SELECT birth_death_tn.file_seq.NEXTVAL AS stg_id, birth_death_tn.id.NEXTVAL AS id FROM dual" +// // ); +// // String stagId = seqData.get("stg_id").toString(); +// // String sId = seqData.get("id").toString(); +// // +// // // 2. Folder mapping for each file field +// // Map folderMapping = Map.of( +// // "fle_par_dcl", "parentDeclarations", +// // "fle_par_id", "parentIDs", +// // "fle_afft_ltr", "affidavitLetters", +// // "fle_dob", "dobProofs" +// // ); +// // +// // // 3. Handle file uploads +// // if (files != null) { +// // for (Map.Entry entry : files.entrySet()) { +// // MultipartFile file = entry.getValue(); +// // String fieldName = entry.getKey(); +// // +// // if (!file.isEmpty()) { +// // if (file.getSize() > MAX_FILE_SIZE) { +// // throw new IOException("File size exceeds 4MB: " + fieldName); +// // } +// // +// // String originalFileName = file.getOriginalFilename(); +// // String ext = originalFileName.substring(originalFileName.lastIndexOf(".") + 1).toLowerCase(); +// // if (!ext.equals("jpg") && !ext.equals("jpeg") && !ext.equals("pdf")) { +// // throw new IOException("Invalid file type for: " + fieldName); +// // } +// // +// // // Determine folder for the file +// // String folderName = folderMapping.getOrDefault(fieldName, "misc"); +// // String uploadDir = System.getProperty("user.dir") + "/uploads/childname/" + folderName; +// // Files.createDirectories(Paths.get(uploadDir)); +// // +// // // Create new file name +// // String newFileName = stagId + "_" + originalFileName; +// // Path filePath = Paths.get(uploadDir, newFileName); +// // +// // // Save file locally +// // Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); +// // +// // // Store relative path in DB +// // String relativePath = "/uploads/childname/" + folderName + "/" + newFileName; +// // formFields.put(fieldName, relativePath); +// // } +// // } +// // } +// // +// // // 4. Insert into main table +// //// String insertCtzn = """ +// //// INSERT INTO tbl_birth_death_corr_ctzn +// //// (id, reg_no, isbd, mob, s_user_id, cdate, ack_no, status, corr) +// //// VALUES (tbl_birth_death_corr_ctzn_seq.NEXTVAL, ?, ?, ?, ?, SYSDATE, NULL, 'P', ?) +// ////"""; +// //// +// //// newJdbc.update(insertCtzn, +// //// formFields.get("reg_no"), // reg_no +// //// formFields.get("isbd"), // isbd +// //// formFields.get("mob"), // mob +// //// "0", // s_user_id +// //// formFields.get("corr") // corr +// //// ); +// // +// // +// // +// // +// // // 5. Insert into birth correction table +// // String insertBirth = """ +// // INSERT INTO tbl_birth_corr_fle +// // (id, fle_par_dcl, fle_par_id, fle_afft_ltr, fle_dob, m_child) +// // VALUES (?, ?, ?, ?, ?, ?) +// // """; +// // newJdbc.update(insertBirth, +// // sId, +// // formFields.get("fle_par_dcl"), +// // formFields.get("fle_par_id"), +// // formFields.get("fle_afft_ltr"), +// // formFields.get("fle_dob"), +// // formFields.get("m_child") +// // ); +// // +// // // 6. Generate and update acknowledgement number +// // String ackNo = "P/" + formFields.get("isBD") + "/" + sId; +// // newJdbc.update( +// // "UPDATE birth_death_tn.tbl_birth_death_corr_ctzn SET ack_no=? WHERE id=?", +// // ackNo, sId +// // ); +// // +// // return ackNo; +// // } + + + +// } diff --git a/src/main/java/com/gcc/restapiservices/birthanddeath/service/DeathCertificateService.java b/src/main/java/com/gcc/restapiservices/birthanddeath/service/DeathCertificateService.java new file mode 100644 index 0000000..f00a492 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/birthanddeath/service/DeathCertificateService.java @@ -0,0 +1,789 @@ +// package com.gcc.restapiservices.birthanddeath.service; + +// import java.time.LocalDate; +// import java.time.ZoneId; +// import java.time.format.DateTimeFormatter; +// import java.util.ArrayList; +// import java.util.Comparator; +// import java.util.LinkedHashMap; +// import java.util.List; +// import java.util.Map; + +// import javax.sql.DataSource; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.beans.factory.annotation.Qualifier; +// import org.springframework.dao.EmptyResultDataAccessException; +// import org.springframework.http.HttpStatus; +// import org.springframework.http.ResponseEntity; +// import org.springframework.jdbc.core.JdbcTemplate; +// import org.springframework.stereotype.Service; +// import org.springframework.web.bind.annotation.GetMapping; + +// @Service +// public class DeathCertificateService { + +// private JdbcTemplate jdbcTemplate; + +// // MYSQL CONNECTION +// // @Autowired +// // public void setDataSource(@Qualifier("mysqlGccRestServicesDataSource") DataSource dataSource) { +// // this.jdbcTemplate = new JdbcTemplate(dataSource); +// // } + +// // ORACLE CONNECTION +// // @Autowired +// // public void setDataSource(@Qualifier("oracleDataSourceItCell") DataSource dataSource) { +// // this.jdbcTemplate = new JdbcTemplate(dataSource); +// // } + +// @Autowired +// @Qualifier("oracleBirthNewDataSourceItCell") +// private DataSource newBirthDataSource; + +// @Autowired +// @Qualifier("oracleBirthOldDataSourceItCell") +// private DataSource oldBirthDataSource; + +// // old local db + +// private static final String SELECT_FIELDS = """ +// regno, person_name, dod, gender, father_name, mother_name, english_url +// """; + +// public Map getByRegistrationNumber(String regNo) { +// String sql = "SELECT " + SELECT_FIELDS + " FROM death_certificates WHERE regno = ?"; +// return formatResult(jdbcTemplate.queryForMap(sql, regNo)); +// } + +// // records from live db field names and tables + +// private static final String DEATH_SELECT_FIELDS = """ +// REGISTRATION_NUMBER AS regno, DATE_OF_DEATH AS dod, SEX AS gender, +// FATHER_NAME AS father_name, MOTHER_NAME AS mother_name, PERSON_NAME AS person_name, '' AS english_url +// """; + +// private static final String eSign_CERTIFICATE_URL_PREFIX = "http://gccapp.chennaicorporation.gov.in/birth_death_tn/CORPBIRTHTAMIL/esign/"; +// private static final String CERTIFICATE_URL_PREFIX = "http://gccapp.chennaicorporation.gov.in/birth_death_tn/CORPBIRTHTAMIL/GccDeathCertAvail.jsp?RegNo="; +// private static final String OLD_CERTIFICATE_URL_PREFIX="https://chennaicorporation.gov.in/online-civic-services/deathCertificate.do?do=DeathCertificate®istrationNumber="; + +// private static final String CRS_CERTIFICATE_URL_PREFIX="https://chennaicorporation.gov.in/online-civic-services/deathCertificateCRS.do?do=DeathCertificate®istrationNumber="; + + + +// public Map getDeathByRegistrationNumber(String regNo) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // Query new schema +// String newSql = """ +// SELECT +// dd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(dd.DATE_OF_DEATH , 'DD-MM-YYYY') AS dod, +// TO_CHAR(dd.created_date , 'DD-MM-YYYY') AS created_date, +// dd.SEX AS gender, +// dd.FATHER_NAME AS father_name, +// dd.MOTHER_NAME AS mother_name, +// dd.PERSON_NAME AS person_name, +// CASE +// WHEN (dd.verified_date >= TO_DATE('2019-06-19', 'YYYY-MM-DD') +// OR dd.registration_date >= TO_DATE('2019-06-01', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_death_details dd +// LEFT JOIN tbl_birth_esign_cert bec ON bec.reg_no = dd.REGISTRATION_NUMBER +// WHERE dd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND dd.REGISTRATION_NUMBER = ? +// AND ROWNUM = 1 +// """; + +// List> newResults = newJdbc.queryForList(newSql, regNo); +// if (!newResults.isEmpty()) { +// return formatResult(newResults.get(0)); +// } + +// // Query old schema if not found in new +// String oldSql = """ +// SELECT +// ddo.REGISTRATION_NUMBER AS regno, +// TO_CHAR(ddo.DATE_OF_DEATH, 'DD-MM-YYYY') AS dod, +// TO_CHAR(ddo.created_date , 'DD-MM-YYYY') AS created_date, +// ddo.SEX AS gender, +// ddo.FATHER_NAME AS father_name, +// ddo.MOTHER_NAME AS mother_name, +// ddo.PERSON_NAME AS person_name, +// CASE +// WHEN (ddo.verified_date < TO_DATE('2019-06-19', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(beco.status, 'NA') AS status, +// beco.cert_file +// FROM tbl_death_details ddo +// LEFT JOIN tbl_birth_esign_cert beco +// ON (beco.reg_no = ddo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_D_' || ddo.REGISTRATION_NUMBER) +// WHERE ddo.REGISTRATION_NUMBER = ? +// AND ROWNUM = 1 +// """; + +// List> oldResults = oldJdbc.queryForList(oldSql, regNo); +// if (!oldResults.isEmpty()) { +// return formatResult(oldResults.get(0)); +// } + +// // return Map.of("status", "not_found", "message", "No record found for the +// // given registration number"); + +// Map notFound = new LinkedHashMap<>(); +// notFound.put("status", "not_found"); +// notFound.put("message", +// "No record found for the given registration number.Please ensure registration number is exactly as on the certificate."); +// notFound.put("status_code", 404); +// return notFound; +// } + +// // + +// // public List> getDeathByMobile(String mobile) { +// // String sql = "SELECT " + DEATH_SELECT_FIELDS + +// // " FROM tbl_death_details WHERE FATH_MOB_NO = ? OR MOTH_MOB_NO = ? " ; +// // List> results = jdbcTemplate.queryForList(sql, mobile, mobile); +// // return results.stream().map(this::formatResult).toList(); +// // } + +// public List> getByMobile(String mobile) { +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// String sql = """ +// SELECT +// dd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(dd.DATE_OF_DEATH , 'DD-MM-YYYY') AS dod, +// TO_CHAR(dd.created_date , 'DD-MM-YYYY') AS created_date, +// dd.SEX AS gender, +// dd.FATHER_NAME AS father_name, +// dd.MOTHER_NAME AS mother_name, +// dd.PERSON_NAME AS person_name, +// CASE +// WHEN (dd.verified_date >= TO_DATE('2019-06-19', 'YYYY-MM-DD') +// OR dd.registration_date >= TO_DATE('2019-06-01', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(bec.status, 'NA') AS status, +// bec.cert_file +// FROM tbl_death_details dd +// LEFT JOIN tbl_birth_esign_cert bec ON bec.reg_no = dd.REGISTRATION_NUMBER +// WHERE dd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND dd.FATH_MOB_NO = ? OR dd.MOTH_MOB_NO = ? +// """; + +// List> results = newJdbc.queryForList(sql, mobile, mobile); +// return results.stream().map(this::formatResult).toList(); +// } + + + +// public Map getByDetailsOracleOldAndNewForDeath(String dod, String father, String mother, +// String person, String gender) { + +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); +// // Prepare query and params for NEW data +// StringBuilder newSql = new StringBuilder(""" +// SELECT +// dd.REGISTRATION_NUMBER AS regno, +// dd.DATE_OF_DEATH AS dod, +// dd.SEX AS gender, +// dd.FATHER_NAME AS father_name, +// dd.MOTHER_NAME AS mother_name, +// dd.PERSON_NAME AS person_name, +// CASE +// WHEN (dd.verified_date >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR dd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(dec.status, 'NA') AS status, +// dec.cert_file +// FROM tbl_death_details dd +// LEFT JOIN tbl_birth_esign_cert dec ON dec.reg_no = dd.REGISTRATION_NUMBER +// WHERE dd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(dd.FATHER_NAME)) = ? +// AND TRIM(UPPER(dd.MOTHER_NAME)) = ? +// AND TRIM(UPPER(dd.SEX)) = ? +// """); + +// List newParams = new ArrayList<>(); +// newParams.add(father.toUpperCase().trim()); +// newParams.add(mother.toUpperCase().trim()); +// newParams.add(gender.toUpperCase().trim()); + +// if (person != null && !person.trim().isEmpty()) { +// newSql.append(" AND TRIM(UPPER(dd.PERSON_NAME)) = ? "); +// newParams.add(person.toUpperCase().trim()); +// } + +// if (dod != null && !dod.trim().isEmpty()) { +// newSql.append(" AND TRUNC(dd.DATE_OF_DEATH) = TO_DATE(?, 'DD-MM-YYYY') "); +// newParams.add(dod.trim()); +// } + +// newSql.append(" AND ROWNUM = 1"); + +// // Try fetching from NEW data +// try { +// Map result = newJdbc.queryForMap(newSql.toString(), newParams.toArray()); +// return formatResult(result); +// } catch (EmptyResultDataAccessException e) { +// // Fallback to OLD data +// } + +// // Prepare query and params for OLD data +// StringBuilder oldSql = new StringBuilder(""" +// SELECT +// ddo.REGISTRATION_NUMBER AS regno, +// ddo.DATE_OF_DEATH AS dod, +// ddo.SEX AS gender, +// ddo.FATHER_NAME AS father_name, +// ddo.MOTHER_NAME AS mother_name, +// ddo.PERSON_NAME AS person_name, +// CASE +// WHEN (ddo.verified_date < TO_DATE('2019-06-19', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(deco.status, 'NA') AS status, +// deco.cert_file +// FROM tbl_death_details ddo +// LEFT JOIN tbl_birth_esign_cert deco ON deco.reg_no = ddo.REGISTRATION_NUMBER +// WHERE TRIM(UPPER(ddo.FATHER_NAME)) = ? +// AND TRIM(UPPER(ddo.MOTHER_NAME)) = ? +// AND TRIM(UPPER(ddo.SEX)) = ? +// """); + +// List oldParams = new ArrayList<>(); +// oldParams.add(father.toUpperCase().trim()); +// oldParams.add(mother.toUpperCase().trim()); +// oldParams.add(gender.toUpperCase().trim()); + +// if (person != null && !person.trim().isEmpty()) { +// oldSql.append(" AND TRIM(UPPER(ddo.PERSON_NAME)) = ? "); +// oldParams.add(person.toUpperCase().trim()); +// } + +// if (dod != null && !dod.trim().isEmpty()) { +// oldSql.append(" AND TRUNC(ddo.DATE_OF_DEATH) = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(dod.trim()); +// } + +// oldSql.append(" AND ROWNUM = 1"); + +// try { +// Map result = oldJdbc.queryForMap(oldSql.toString(), oldParams.toArray()); +// return formatResult(result); +// } catch (EmptyResultDataAccessException e) { +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } catch (Exception e) { +// // Return "not_found" with message instead of throwing exception +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } +// } + + +// // oracle +// private Map formatResult(Map row) { +// Map response = new LinkedHashMap<>(); +// response.put("status", "success"); + +// // System.out.println("row="+row); + +// Map deathresponse = new LinkedHashMap<>(); +// // birthresponse.put("name", row.get("child_name")); + +// deathresponse.put("regno", row.get("regno") != null ? row.get("regno").toString() : ""); + +// deathresponse.put("name", row.get("person_name") != null ? row.get("person_name").toString() : " "); +// deathresponse.put("dod", row.get("dod")!= null ? row.get("dod").toString() : "" ); + +// String gender = row.get("gender") != null ? row.get("gender").toString().trim().toUpperCase() : ""; +// if ("M".equals(gender)) { +// deathresponse.put("gender", "Male"); +// } else if ("F".equals(gender)) { +// deathresponse.put("gender", "FeMale"); +// } else if( "G".equals(gender)) { +// deathresponse.put("gender", "Transgender"); +// }else { +// deathresponse.put("gender", "other"); +// } + +// deathresponse.put("father_name", row.get("father_name")); +// deathresponse.put("mother_name", row.get("mother_name")); +// response.put("certificate_details", deathresponse); + + +// String regNo = row.get("regno") != null ? row.get("regno").toString() : ""; +// //System.out.println("regNo " + regNo); + +// Integer regVal = row.get("reg_val") instanceof Number ? ((Number) row.get("reg_val")).intValue() : 0; +// String status = String.valueOf(row.getOrDefault("status", "NA")); +// String certFile = row.get("cert_file") != null ? row.get("cert_file").toString() : ""; +// String createdDateStr = (row.get("created_date") != null) ? row.get("created_date").toString().trim() : ""; + +// //System.out.println("certFile=" + certFile); + +// // Build PDF URL if valid +// String pdfUrl = ""; +// if ("S".equalsIgnoreCase(status)) { +// pdfUrl = eSign_CERTIFICATE_URL_PREFIX + certFile; +// } +// else if ("P".equalsIgnoreCase(status)) { +// pdfUrl = ""; +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isBefore(LocalDate.of(2012, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = ""; // newer pending — no link +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// } +// else { +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isAfter(LocalDate.of(2018, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// } + +// response.put("pdf_url", pdfUrl); +// if (pdfUrl == null || pdfUrl.isEmpty()) { +// response.put("message", "Awaiting for eSign"); +// } +// return response; +// } + + + +// // added by hariprasath + +// public Map getBynewDetailsOracleOldAndNewForDeath(String dod, String father, String mother, +// String person, String gender) { + +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); +// // Prepare query and params for NEW data +// StringBuilder newSql = new StringBuilder(""" +// SELECT +// dd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(dd.DATE_OF_DEATH , 'DD-MM-YYYY') AS dod, +// TO_CHAR(dd.created_date , 'DD-MM-YYYY') AS created_date, +// dd.SEX AS gender, +// dd.FATHER_NAME AS father_name, +// dd.MOTHER_NAME AS mother_name, +// dd.PERSON_NAME AS person_name, +// CASE +// WHEN (dd.verified_date >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR dd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(dec.status, 'NA') AS status, +// dec.cert_file +// FROM tbl_death_details dd +// LEFT JOIN tbl_birth_esign_cert dec ON dec.reg_no = dd.REGISTRATION_NUMBER +// WHERE dd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(dd.SEX)) = ? +// AND UPPER(dd.FATHER_NAME) LIKE ? +// AND UPPER(dd.MOTHER_NAME) LIKE ? +// """); + +// List newParams = new ArrayList<>(); +// newParams.add(gender.toUpperCase().trim()); +// newParams.add("%" + father.toUpperCase().trim() + "%"); +// newParams.add("%" + mother.toUpperCase().trim() + "%"); + +// if (person != null && !person.trim().isEmpty()) { +// newSql.append(" AND UPPER(dd.PERSON_NAME) LIKE ? "); +// newParams.add("%" + person.toUpperCase().trim() + "%"); +// } + +// if (dod != null && !dod.trim().isEmpty()) { +// newSql.append(" AND dd.DATE_OF_DEATH = TO_DATE(?, 'DD-MM-YYYY') "); +// newParams.add(dod.trim()); +// } + +// // Try fetching from NEW data +// try { +// List> result = newJdbc.queryForList(newSql.toString(), newParams.toArray()); +// if (!result.isEmpty()) { +// return formatResultnew(result); +// } +// } catch (EmptyResultDataAccessException e) { +// // Fallback to OLD data +// } + +// // Prepare query and params for OLD data +// StringBuilder oldSql = new StringBuilder(""" +// SELECT +// ddo.REGISTRATION_NUMBER AS regno, +// TO_CHAR(ddo.DATE_OF_DEATH , 'DD-MM-YYYY') AS dod, +// TO_CHAR(ddo.created_date , 'DD-MM-YYYY') AS created_date, +// ddo.FATHER_NAME AS father_name, +// ddo.MOTHER_NAME AS mother_name, +// ddo.PERSON_NAME AS person_name, +// CASE +// WHEN (ddo.verified_date < TO_DATE('2019-06-19', 'YYYY-MM-DD')) THEN 1 +// ELSE 0 +// END AS reg_val, +// NVL(deco.status, 'NA') AS status, +// deco.cert_file +// FROM tbl_death_details ddo +// LEFT JOIN tbl_birth_esign_cert deco +// ON (deco.reg_no = ddo.REGISTRATION_NUMBER +// OR deco.reg_no = 'GCC_D_' || ddo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(ddo.SEX)) = ? +// AND UPPER(ddo.FATHER_NAME) LIKE ? +// AND UPPER(ddo.MOTHER_NAME) LIKE ? +// """); + +// List oldParams = new ArrayList<>(); +// oldParams.add(gender.toUpperCase().trim()); +// oldParams.add("%" + father.toUpperCase().trim() + "%"); +// oldParams.add("%" + mother.toUpperCase().trim() + "%"); + +// if (person != null && !person.trim().isEmpty()) { +// oldSql.append(" AND UPPER(ddo.PERSON_NAME) LIKE ? "); +// oldParams.add("%" + person.toUpperCase().trim() + "%"); + +// } + +// if (dod != null && !dod.trim().isEmpty()) { +// oldSql.append(" AND ddo.DATE_OF_DEATH = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(dod.trim()); +// } + +// // oldSql.append(" AND ROWNUM = 1"); + +// try { +// List> result = oldJdbc.queryForList(oldSql.toString(), oldParams.toArray()); +// if (!result.isEmpty()) { +// return formatResultnew(result); +// } +// } catch (EmptyResultDataAccessException e) { +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } catch (Exception e) { +// // Return "not_found" with message instead of throwing exception +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } + + + +// private Map formatResultnew(List> rows) { + +// //System.out.println("row1="+rows); + +// if (rows == null || rows.isEmpty()) { +// return Map.of("status", "not_found", "message", +// "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404); +// } + +// Map response = new LinkedHashMap<>(); +// response.put("status", "success"); + +// List> certificateDetailsList = new ArrayList<>(); + +// for (Map row : rows) { +// Map deathresponse = new LinkedHashMap<>(); + +// deathresponse.put("regno", row.get("regno") != null ? row.get("regno").toString() : ""); +// deathresponse.put("name", row.get("person_name") != null ? row.get("person_name").toString() : " "); +// deathresponse.put("dod", row.get("dod")); +// // ---- Gender ---- +// String gender = row.get("gender") != null ? row.get("gender").toString().trim().toUpperCase() : ""; +// if ("M".equals(gender)) { +// deathresponse.put("gender", "Male"); +// } else if ("F".equals(gender)) { +// deathresponse.put("gender", "Female"); +// } else if( "G".equals(gender)) { +// deathresponse.put("gender", "Transgender"); +// }else { +// deathresponse.put("gender", "other"); +// } + +// deathresponse.put("father_name", row.get("father_name")); +// deathresponse.put("mother_name", row.get("mother_name")); +// deathresponse.put("status",row.get("status")); + +// String regNo = row.get("regno") != null ? row.get("regno").toString() : ""; +// //System.out.println("regNo " + regNo); + +// Integer regVal = row.get("reg_val") instanceof Number ? ((Number) row.get("reg_val")).intValue() : 0; +// String status = String.valueOf(row.getOrDefault("status", "NA")); +// String certFile = row.get("cert_file") != null ? row.get("cert_file").toString() : ""; +// String createdDateStr = (row.get("created_date") != null) ? row.get("created_date").toString().trim() : ""; + +// //System.out.println("certFile=" + certFile); + +// // Build PDF URL if valid +// String pdfUrl =""; +// if ("S".equalsIgnoreCase(status)) { +// pdfUrl = eSign_CERTIFICATE_URL_PREFIX + certFile; +// } +// else if ("P".equalsIgnoreCase(status)) { + +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isBefore(LocalDate.of(2012, 1, 1))) { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = ""; // newer pending — no link +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } +// }else { + +// if (!createdDateStr.isEmpty()) { +// try { +// LocalDate createdDate = LocalDate.parse(createdDateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); +// if (createdDate.isAfter(LocalDate.of(2018, 1, 1))) { +// //pdfUrl = CRS_CERTIFICATE_URL_PREFIX + regNo; +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } else { +// pdfUrl = OLD_CERTIFICATE_URL_PREFIX + regNo; +// } +// } catch (Exception e) { +// pdfUrl = ""; // fallback +// } +// } + +// } + +// deathresponse.put("pdf_url", pdfUrl); + +// // add this row to the list +// certificateDetailsList.add(deathresponse); +// } + +// response.put("certificate_details", certificateDetailsList); +// return response; +// } + + + +// // added by yogi for web + +// public Map getBynewDetailsOracleOldAndNewForWeb( +// String dod, String father, String mother, String person, String gender) { + +// JdbcTemplate newJdbc = new JdbcTemplate(newBirthDataSource); +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// // Normalize inputs +// String upperFather = (father != null && !father.isBlank()) ? father.trim().toUpperCase() : ""; +// String upperMother = (mother != null && !mother.isBlank()) ? mother.trim().toUpperCase() : ""; +// String upperGender = (gender != null && !gender.isBlank()) ? gender.trim().toUpperCase() : ""; +// String upperPerson = (person != null && !person.isBlank()) ? person.trim().toUpperCase() : ""; +// String trimmedDod = (dod != null && !dod.trim().isEmpty()) ? dod.trim() : null; + +// // ---------- Combined result list ---------- +// List> combinedResults = new ArrayList<>(); +// // ---------- NEW ---------- +// StringBuilder newSql = new StringBuilder(""" +// SELECT +// dd.REGISTRATION_NUMBER AS regno, +// TO_CHAR(dd.DATE_OF_DEATH, 'DD-MM-YYYY') AS dod, +// TO_CHAR(dd.created_date , 'DD-MM-YYYY') AS created_date, +// dd.SEX AS gender, +// NVL(dd.FATHER_NAME,' ') AS father_name, +// NVL(dd.MOTHER_NAME,' ') AS mother_name, +// NVL(dd.PERSON_NAME,' ') AS person_name, +// CASE +// WHEN (dd.verified_date >= TO_DATE('19-06-2019', 'DD-MM-YYYY') +// OR dd.registration_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY') +// OR dd.created_date >= TO_DATE('01-06-2019', 'DD-MM-YYYY')) +// THEN 1 ELSE 0 +// END AS reg_val, +// NVL(dec.status,'NA') AS status, +// dec.cert_file +// FROM tbl_death_details dd +// LEFT JOIN tbl_birth_esign_cert dec +// ON dec.reg_no = dd.REGISTRATION_NUMBER +// WHERE dd.ZONE_ID IN (501,502,503,504,505,506,507,508,509,510,511,512,513,514,515) +// AND TRIM(UPPER(dd.SEX)) = ? +// """); + +// List params = new ArrayList<>(); +// params.add(upperGender); + +// if (!upperFather.isEmpty()) { +// newSql.append(" AND UPPER(dd.FATHER_NAME) LIKE ? "); +// params.add("%" + upperFather + "%"); +// } +// if (!upperMother.isEmpty()) { +// newSql.append(" AND UPPER(dd.MOTHER_NAME) LIKE ? "); +// params.add("%" + upperMother + "%"); +// } +// if (!upperPerson.isEmpty()) { +// newSql.append(" AND UPPER(dd.PERSON_NAME) LIKE ? "); +// params.add("%" + upperPerson + "%"); +// } +// if (trimmedDod != null) { +// newSql.append(" AND TRUNC(dd.DATE_OF_DEATH) = TO_DATE(?, 'DD-MM-YYYY') "); +// params.add(trimmedDod); +// } + +// newSql.append(" ORDER BY dd.PERSON_NAME "); + +// try { +// //System.out.println("New SQL => " + newSql); +// //System.out.println("Params => " + params); +// List> newresult = newJdbc.queryForList(newSql.toString(), params.toArray()); +// if (!newresult.isEmpty()) { +// // return formatResultnew(result); +// combinedResults.addAll(newresult); +// } +// } catch (Exception e) { +// throw new RuntimeException("Error querying new death table", e); +// } + +// // ---------- OLD ---------- +// StringBuilder oldSql = new StringBuilder(""" +// SELECT +// bdo.REGISTRATION_NUMBER AS regno, +// TO_CHAR(bdo.DATE_OF_DEATH, 'DD-MM-YYYY') AS dod, +// TO_CHAR(bdo.created_date , 'DD-MM-YYYY') AS created_date, +// bdo.SEX AS gender, +// NVL(bdo.FATHER_NAME,' ') AS father_name, +// NVL(bdo.MOTHER_NAME,' ') AS mother_name, +// NVL(bdo.PERSON_NAME,' ') AS person_name, +// CASE +// WHEN bdo.verified_date < TO_DATE('19-06-2019', 'DD-MM-YYYY') +// THEN 1 ELSE 0 +// END AS reg_val, +// NVL(beco.status,'NA') AS status, +// beco.cert_file, +// Z.ZONE_CODE || '-' || Z.ZONE_NAME AS zone_name, +// Y.DIVISION_NAME AS division_name, +// bdo.hospital_id +// FROM TBL_DEATH_DETAILS bdo +// JOIN TBL_ZONE Z ON bdo.ZONE_ID = Z.ZONE_ID +// JOIN TBL_DIVISION Y ON bdo.DIVISON_ID = Y.DIVISON_ID +// LEFT JOIN TBL_BIRTH_ESIGN_CERT beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_D_' || bdo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(bdo.SEX)) = ? +// """); + +// List oldParams = new ArrayList<>(); +// oldParams.add(upperGender); + +// if (!upperFather.isEmpty()) { +// oldSql.append(" AND UPPER(bdo.FATHER_NAME) LIKE ? "); +// oldParams.add("%" + upperFather + "%"); +// } +// if (!upperMother.isEmpty()) { +// oldSql.append(" AND UPPER(bdo.MOTHER_NAME) LIKE ? "); +// oldParams.add("%" + upperMother + "%"); +// } +// if (!upperPerson.isEmpty()) { +// oldSql.append(" AND UPPER(bdo.PERSON_NAME) LIKE ? "); +// oldParams.add("%" + upperPerson + "%"); +// } +// if (trimmedDod != null) { +// oldSql.append(" AND bdo.DATE_OF_DEATH = TO_DATE(?, 'DD-MM-YYYY') "); +// oldParams.add(trimmedDod); +// } + +// oldSql.append(" ORDER BY bdo.PERSON_NAME "); + +// try { +// //System.out.println("Old SQL => " + oldSql); +// //System.out.println("Params => " + oldParams); +// List> oldResult = oldJdbc.queryForList(oldSql.toString(), oldParams.toArray()); +// if (!oldResult.isEmpty()) { +// //return formatResultnew(oldResult); +// combinedResults.addAll(oldResult); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } + +// if(!combinedResults.isEmpty()){ +// combinedResults.sort(Comparator.comparing(m -> String.valueOf(m.get("person_name")))); +// return formatResultnew(combinedResults); +// } + +// return Map.of( +// "status", "not_found", +// "message", "No matching death certificate found. Please ensure names and date are exactly as on the certificate.", +// "status_code", 404 +// ); +// } + + +// public List> getOldDeathDetails(String dod, String gender) { +// JdbcTemplate oldJdbc = new JdbcTemplate(oldBirthDataSource); + +// String sql = """ +// SELECT +// Z.ZONE_CODE || '-' || Z.ZONE_NAME AS zone_name, +// Y.DIVISION_NAME AS division_name, +// bdo.hospital_id, +// TO_CHAR(bdo.DATE_OF_DEATH, 'yyyy-mm-dd') AS date_of_death, +// bdo.SEX AS sex, +// NVL(bdo.PERSON_NAME,' ') AS person_name, +// bdo.REGISTRATION_NUMBER AS regno, +// CASE +// WHEN bdo.verified_date < TO_DATE('19-06-2019', 'DD-MM-YYYY') THEN 1 +// ELSE 0 +// END AS reg_val, +// beco.status AS status, +// beco.cert_file +// FROM TBL_DEATH_DETAILS bdo +// JOIN TBL_ZONE Z ON bdo.ZONE_ID = Z.ZONE_ID +// JOIN TBL_DIVISION Y ON bdo.DIVISON_ID = Y.DIVISON_ID +// LEFT JOIN TBL_BIRTH_ESIGN_CERT beco +// ON (beco.reg_no = bdo.REGISTRATION_NUMBER +// OR beco.reg_no = 'GCC_D_' || bdo.REGISTRATION_NUMBER) +// WHERE TRIM(UPPER(bdo.SEX)) = ? +// AND TRUNC(bdo.DATE_OF_DEATH) = TO_DATE(?, 'DD-MM-YYYY') +// ORDER BY bdo.PERSON_NAME +// """; + +// //System.out.println("Executing SQL:\n" + sql); +// //System.out.println("Parameters - gender: " + gender + ", dod: " + dod); + +// // Pass parameters to query +// List> result = oldJdbc.queryForList(sql, gender.toUpperCase(), dod); + +// //System.out.println("Result size: " + result.size()); + +// return result; +// } + + +// } \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/controller/ApiController.java b/src/main/java/com/gcc/restapiservices/cdwaste/controller/ApiController.java new file mode 100644 index 0000000..2d597ac --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/controller/ApiController.java @@ -0,0 +1,244 @@ +package com.gcc.restapiservices.cdwaste.controller; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.gcc.restapiservices.cdwaste.service.RequestService; +import com.gcc.restapiservices.cdwaste.util.ApiResponseUtil; +import com.gcc.restapiservices.configuration.AppConfig; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@RestController +@RequestMapping("/gccrestservices/dumpregistration/api") + +public class ApiController { + + @Autowired + private RequestService requestService ; + + + @Autowired + private AppConfig appConfig; + + + @PostMapping("/savedetails") + public ResponseEntity saveWasteCollection( + @RequestParam("name") String name, + @RequestParam("mobileNumber") String mobileNumber, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("doorNumber") String doorNumber, + @RequestParam("streetName") String streetName, + @RequestParam("area") String area, + @RequestParam("city") String city, + @RequestParam("pincode") String pincode, + @RequestParam("wasteType") String wasteType, + @RequestParam("wasteQuantity") String wasteQuantity, + @RequestParam("vehicleType") String vehicleType, + @RequestParam(value = "dumpLocation", required = false,defaultValue = "100") String dumpLocation, + @RequestParam("dump") MultipartFile wasteImage) { + + try { + int waste_Type = Integer.parseInt(wasteType); + int waste_Quantity = Integer.parseInt(wasteQuantity); + int vehicle_Type = Integer.parseInt(vehicleType); + int dump_Location = Integer.parseInt(dumpLocation); + + + String refId = requestService.saveWasteCollection(name, mobileNumber, zone, ward, doorNumber, streetName, area, city, + pincode, waste_Type, waste_Quantity, vehicle_Type, dump_Location, wasteImage); + + if ("error".equalsIgnoreCase(refId)) { + return ApiResponseUtil.error("Something went wrong while saving", HttpStatus.INTERNAL_SERVER_ERROR); + } + + Map data = new HashMap<>(); + data.put("referenceId", refId); + + return ApiResponseUtil.success(data, "Waste collection request saved successfully"); + + } catch (Exception e) { + e.printStackTrace(); + return ApiResponseUtil.error("Error saving data: " + e.getMessage(), HttpStatus.BAD_REQUEST); + } + + } + + + + + @GetMapping(value = "/sendOTP") + public String sendOtp(HttpServletRequest request, @RequestParam String mobile) { + + // Create an ObjectMapper instance + //ObjectMapper objectMapper = new ObjectMapper(); + + // Check if mobile number is already registered + //List registrations = wasteregistrationrepo.findByMobileNo(mobile); + + // Create a response map + Map response = new HashMap<>(); + +// if (registrations.isEmpty()) { +// // If mobile number is not registered +// response.put("status", "NOT_REGISTERED"); +// response.put("mobile", mobile); // Return the mobile number +// try { +// return objectMapper.writeValueAsString(response); // Use the instance to convert map to JSON string +// } catch (Exception e) { +// // Handle JSON conversion error +// return "{\"status\": \"ERROR\", \"message\": \"Could not convert response to JSON.\"}"; +// } +// } + + + String MobileNo=mobile; + System.out.print("\n MobileNo---:"+mobile); + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + +// int otp= 22222; + System.out.print("\n otp---:"+otp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); + LocalDateTime now = LocalDateTime.now(); + System.out.println(dtf.format(now)); + //String generatedToken = "Welcome to GCC! Your OTP for C%26D waste collectors Registration process is "+otp; + + //String generatedToken = "Welcome to GCC "+otp+" is your OTP for gcc QR System"; + + String generatedToken = "Welcome to GCC! Your OTP for C and D waste collectors Registration process is " + otp; +// String key="qxg4mklD"; + String key="pfTEYN6H"; + String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407172967243483268"; + + + //String urlString = "https://tmegov.onex-aura.com/api/sms?from=GCCCRP&key=pfTEYN6H&sender=GCCCRP&to=9360777472&body=Welcome%20to%20GCC!%20Your%20OTP%20for%20C%26D%20waste%20collectors%20Registration%20process%20is%20"+otp+"&entityid=1401572690000011081&templateid=1407172959127552127"; + //String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407168250479102852"; +// String urlString=appConfig.getGetOtpUrl()+"user=GCCtrans&authkey=92kOC1RBGBIws&sender=GCCCRP&mobile="+MobileNo+"&text="+generatedToken+"&rpt=1&summary=1&output=json&entityid=1401572690000011081&templateid=1407168250479102852"; + System.out.print("\n urlString---: "+urlString); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + // Using Jackson ObjectMapper to parse the response JSON + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + // Add mobileNo and otp to the response JSON + jsonResponse.put("MobileNo", MobileNo); + jsonResponse.put("otp", otp); + + // Convert the updated JSON object back to string + bodyMessage = jsonResponse.toString(); +// bodyMessage=Response; + System.out.println("\n bodyMessage"+bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: "+e); + bodyMessage = "Error"; + } + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + return bodyMessage; + + } + + + + @GetMapping(value = "/verifyOTP") + public String verifyOtp(HttpServletRequest request, @RequestParam String otp) { + HttpSession session = request.getSession(); + try { + Integer session_otp = (Integer) session.getAttribute("otp"); + System.out.println("session_otp---:" + session_otp); + Integer entered_otp = Integer.parseInt(otp); + + if (session_otp != null && session_otp.equals(entered_otp)) { + System.out.println("Entered OTP Correct"); + session.setAttribute("verifiedotp", "success"); + return "Success"; + } else { + System.out.println("Incorrect OTP. Please enter correct OTPs."); + session.setAttribute("verifiedotp", "error"); + return "Error"; + } + } catch (NumberFormatException e) { + System.out.println("Invalid OTP format: " + otp); + return "Error"; + } catch (Exception e) { + System.out.println("Error verifying OTP: " + e.getMessage()); + return "Error"; + } + } + + + + // get the request details by mobile number + + @GetMapping("/requestlistbymobileno") + public ResponseEntity getRequestDetailsByMobileNo(@RequestParam String mobileNo) { + try { + List> responseList = requestService.getRequestDetailsList(mobileNo); + + if (responseList == null || responseList.isEmpty()) { + return ApiResponseUtil.notFound("No requests found for this mobile number."); + } + + return ApiResponseUtil.success(responseList, "Request list fetched successfully."); + } catch (Exception e) { + e.printStackTrace(); + return ApiResponseUtil.error("Failed to fetch data: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + // get the request details by ref-id + + @GetMapping("/requestlistbyrefid") + public ResponseEntity getRequestDetailsByRefId(@RequestParam String refId) { + try { + List> responseList = requestService.getRequestDetailsListByRefId(refId); + + if (responseList == null || responseList.isEmpty()) { + return ApiResponseUtil.notFound("No requests found for this Ref ID."); + } + + return ApiResponseUtil.success(responseList, "Request list fetched successfully."); + } catch (Exception e) { + e.printStackTrace(); + return ApiResponseUtil.error("Failed to fetch data: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + + + + + + + + +} diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/controller/DropDownApiController.java b/src/main/java/com/gcc/restapiservices/cdwaste/controller/DropDownApiController.java new file mode 100644 index 0000000..21d36b1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/controller/DropDownApiController.java @@ -0,0 +1,157 @@ +package com.gcc.restapiservices.cdwaste.controller; + + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.gcc.restapiservices.cdwaste.service.DropDownService; +import com.gcc.restapiservices.cdwaste.util.ApiResponseUtil; + +@RestController +@RequestMapping("/gccrestservices/dropdown/api") +public class DropDownApiController { + + @Autowired + + private DropDownService dropDownService; + + @GetMapping("/wastetypes") + public ResponseEntity getwastetypes() { + + List> result = dropDownService.getwastetypes(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + @GetMapping("/wastequantity") + public ResponseEntity getwastequantity() { + + List> result = dropDownService.getwastequantity(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + @GetMapping("/locations") + public ResponseEntity getlocations(@RequestParam("quantityId") int quantityId) { + + List> result = dropDownService.getlocations(quantityId); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + @GetMapping("/vehicletypes") + public ResponseEntity getvehicletypes(@RequestParam("quantityId") int quantityId) { + + List> result = dropDownService.getvehicletypes(quantityId); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + @GetMapping("/wastecollectionscharges") + public ResponseEntity>> getwastecolectionscharges() { + + List> result = dropDownService.getwastecolectionscharges(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + + @GetMapping("/zone") + public ResponseEntity>> getallzone() { + + List> result = dropDownService.getZonesList(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + @GetMapping("/wardbyzone") + public ResponseEntity>> getwardbyzone(@RequestParam int zoneId) { + + List> result = dropDownService.getWardListByZone(zoneId); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + + + +} diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/service/DropDownService.java b/src/main/java/com/gcc/restapiservices/cdwaste/service/DropDownService.java new file mode 100644 index 0000000..d7d0811 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/service/DropDownService.java @@ -0,0 +1,70 @@ +package com.gcc.restapiservices.cdwaste.service; + +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + + +@Service +public class DropDownService { + + @Autowired + public void setDataSource(@Qualifier("mysqlCdWasteDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + + private JdbcTemplate jdbcTemplate; + + + public List> getwastetypes() { + String sql = " SELECT id,waste_type FROM waste_type_master where is_active = 1 AND is_delete=0 " ; + return jdbcTemplate.queryForList(sql); + } + + + + public List> getwastequantity() { + String sql = " SELECT id,quantity FROM quantity_master where is_active = 1 AND is_delete = 0 " ; + return jdbcTemplate.queryForList(sql); + } + + + + public List> getlocations(int quantityId) { + String sql = "SELECT id,location FROM dumping_location where quantity_id = ? "; + return jdbcTemplate.queryForList(sql, quantityId); + } + + + + public List> getvehicletypes(int quantityId) { + String sql = "SELECT id,vehicle_name FROM vehicle_master where quantity_id = ? "; + return jdbcTemplate.queryForList(sql,quantityId); + } + + + public List> getwastecolectionscharges() { + String sql = "SELECT id,amount_type,amount FROM waste_collection_charges where is_active = 1 AND is_delete = 0 "; + return jdbcTemplate.queryForList(sql); + } + + + + public List> getZonesList() { + String sql = " SELECT id,zone_name from zones where is_active = 1 "; + return jdbcTemplate.queryForList(sql); + } + + public List> getWardListByZone(int zoneId) { + String sql = "SELECT id, ward_name FROM wards WHERE zone_id = ? AND is_active = 1 AND is_delete = 0 "; + return jdbcTemplate.queryForList(sql, zoneId); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/service/RequestService.java b/src/main/java/com/gcc/restapiservices/cdwaste/service/RequestService.java new file mode 100644 index 0000000..26fea1a --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/service/RequestService.java @@ -0,0 +1,354 @@ +package com.gcc.restapiservices.cdwaste.service; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.Random; + +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.core.io.ByteArrayResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.cdwaste.util.DateTimeUtil; +import com.gcc.restapiservices.configuration.AppConfig; + +@Service +public class RequestService { + + @Autowired + private Environment environment; + + @Autowired + private AppConfig appConfig; + + @Autowired + public void setDataSource(@Qualifier("mysqlCdWasteDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private JdbcTemplate jdbcTemplate; + + private String fileBaseUrl; + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + public RequestService(RestTemplate restTemplate, AppConfig appConfig, ObjectMapper objectMapper, + Environment environment) { + this.restTemplate = restTemplate; + this.appConfig = appConfig; + this.environment = environment; + this.objectMapper = objectMapper; + this.fileBaseUrl = environment.getProperty("fileBaseUrl"); + } + + @Autowired + private final ObjectMapper objectMapper; + + @Autowired + private RestTemplate restTemplate; + + public String saveWasteCollection(String name, String mobileNumber, String zone, String ward, String doorNumber, + String streetName, String area, String city, String pincode, int wasteType, int wasteQuantity, + int vehicleType, int dumpLocation, MultipartFile wasteImage) throws IOException { + + String paymentstatus = "PENDING"; + + String uploadImgUrl = null; + + int isMobile = 2; + + String sql = "INSERT INTO waste_collectors_request " + + "(name, mobile_no, zone, ward, door_number,street_name,area,city,pincode,waste_type_id, waste_quantity_id, vehicle_id, payment_status, upload_image_url,dump_location_id,is_mobile) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?,?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int result = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, name); + ps.setString(2, mobileNumber); + ps.setString(3, zone); + ps.setString(4, ward); + ps.setString(5, doorNumber); + ps.setString(6, streetName); + ps.setString(7, area); + ps.setString(8, city); + ps.setString(9, pincode); + ps.setInt(10, wasteType); + ps.setInt(11, wasteQuantity); + + ps.setInt(12, vehicleType); + ps.setString(13, paymentstatus); + ps.setString(14, null); // placeholder for image URL + + // 👇 move this logic inside the lambda + if (vehicleType != 1 && dumpLocation > 0) { + ps.setInt(15, dumpLocation); + } else { + ps.setInt(15, 100); // Default value + } + + ps.setInt(16, isMobile); + return ps; + }, keyHolder); + + if (result > 0) { + int generatedId = keyHolder.getKey().intValue(); + String prefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + String refId = prefix + generatedId; + + // Save the file and build the file path (relative or just file name) + if (wasteImage != null && !wasteImage.isEmpty()) { + + uploadImgUrl = saveFile(wasteImage); + + System.out.println("uploadImgUrl...." + uploadImgUrl); + + // Update the upload_image_url column + String updateSql = "UPDATE waste_collectors_request SET upload_image_url = ? WHERE id = ?"; + jdbcTemplate.update(updateSql, uploadImgUrl, generatedId); + } + + // Update reference ID (assuming it's another column in the same table) + if (updaterefId(refId, generatedId)) { + sendrequestraisedWhatsappMessage(refId, mobileNumber); + + } + + System.out.println("wasteQuantity" + wasteQuantity); + System.out.println("vehicleId" + vehicleType); + System.out.println("result" + result); + + if ((wasteQuantity == 1 || wasteQuantity == 2) && (vehicleType == 1 || vehicleType == 4) && result > 0) { + + String fullAddress = doorNumber + "," + streetName + "," + area + "," + city + "," + pincode; + System.out.println("fullAddress" + fullAddress); + callGccWasteApi(zone, ward, fullAddress, refId, wasteQuantity, wasteType, wasteImage); + System.out.println("hiiii"); + + } + return refId; + } + + return "error"; + } + + public void callGccWasteApi(String zone, String ward, String fulladdress, String refId, int wasteQuantity, + int wasteType, MultipartFile dump) { + System.out.println("inside the method"); + + String url = "https://gccservices.in/gccofficialapp/c_dwaste/api/saveUserWaste"; + + MultiValueMap body = new LinkedMultiValueMap<>(); + + String tonage = ""; + if (wasteQuantity == 1) { + tonage = "Less Than 1 Ton"; + } else if (wasteQuantity == 2) { + tonage = "1 Ton to 20 Ton"; + } else { + tonage = "Unknown Tonage"; + } + + body.add("zone", zone); + body.add("ward", ward); + body.add("address", fulladdress); + body.add("ref_id", refId); + System.out.println("tonage....." + tonage); + body.add("tonage", tonage); + body.add("wastetype", wasteType); + + try { + ByteArrayResource fileAsResource = new ByteArrayResource(dump.getBytes()) { + @Override + public String getFilename() { + return dump.getOriginalFilename(); // Provide a file name + } + }; + + body.add("file", fileAsResource); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); + + System.out.println("GCC API response: " + response.getBody()); + + } catch (Exception e) { + System.err.println("GCC API error: " + e.getMessage()); + e.printStackTrace(); + } + } + + private boolean updaterefId(String refId, int generatedId) { + String sql = "update waste_collectors_request set refid = ? where id = ?"; + int result = jdbcTemplate.update(sql, refId, generatedId); + if (result > 0) { + return true; + } + return false; + } + + public void sendrequestraisedWhatsappMessage(String refId, String mobileNumber) { + try { + + String apiUrl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + + mobileNumber + + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Thank+you%21+Your+request+has+been+successfully+submitted.%0ARequest+Id+%3A+" + + refId + + "&isTemplate=true&header=C%26D+Waste+Collection+Request+Registered&footer=Greater+Chennai+Corporation"; + + System.out.println("WhatsApp API URL: " + apiUrl); // Optional debug + // smsService.sendMsg(apiUrl); + sendMsg(apiUrl); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public String sendMsg(String msgUrl) { + System.out.println("Whatsapp URL :-" + msgUrl); + + String response = ""; + try { + HttpURLConnection connection = null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public String saveFeedbackImage(String SMS_Url) { + System.out.println("SMS URL:- " + SMS_Url); + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(SMS_Url, String.class); + return response; + } + + public String saveFile(MultipartFile file) throws IOException { + + String order_copy_url = ""; + // type_folder = "works/"+type_folder; + // Handle file upload if a file is provided + if (file == null || file.isEmpty()) { + return order_copy_url; + } + + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("dump_directory"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + // var date =DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + "/" + serviceFolderName + "/" + year + "/" + month; + + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + String fileName = datetimetxt + "" + generateRandomStringForFile(10) + "_" + file.getOriginalFilename(); + // Construct the file path + String filepath = uploadDirectory + "/" + fileName; + String filepath_txt = "/" + serviceFolderName + "/" + year + "/" + month + "/" + fileName; + Path path = Paths.get(filepath); + + // Ensure the directory exists + Files.createDirectories(path.getParent()); + + // Write the file to the specified path + Files.write(path, file.getBytes()); + + // Set the order_copy_url to the relative file path for storing in DB + order_copy_url = filepath_txt; + + return order_copy_url; + } + + public static String generateRandomStringForFile(int String_Lenth) { + StringBuilder result = new StringBuilder(String_Lenth); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public List> getRequestDetailsList(String mobileNo) { + StringBuilder query = new StringBuilder("SELECT " + + "wcr.name, wcr.mobile_no, wcr.zone, wcr.ward, wtm.waste_type, wcr.payment_status, wcr.refid, " + + "wcr.actual_weight, wcr.payment_type, wcr.processing_charge, " + + "wcr.waste_collection_charge, wcr.total_charge, wcr.payment_mobile_no, wcr.door_number, wcr.street_name, " + + "wcr.area, wcr.city, wcr.pincode, " + "CONCAT(' " + fileBaseUrl + + "/gcc/files', wcr.upload_image_url) AS upload_image_url, " + + "DATE_FORMAT(wcr.cdate, '%d-%m-%Y') AS request_date, " + "vm.vehicle_name, " + "qm.quantity, " + + "dl.location " + "FROM waste_collectors_request wcr " + + "LEFT JOIN vehicle_master vm ON wcr.vehicle_id = vm.id " + + "LEFT JOIN dumping_location dl ON wcr.dump_location_id = dl.id " + + "LEFT JOIN waste_type_master wtm ON wcr.waste_type_id = wtm.id " + + "LEFT JOIN quantity_master qm ON wcr.waste_quantity_id = qm.id " + "WHERE wcr.mobile_no = ? "); + + return jdbcTemplate.queryForList(query.toString(), mobileNo); + } + + public List> getRequestDetailsListByRefId(String refId) { + StringBuilder query = new StringBuilder("SELECT " + + "wcr.name, wcr.mobile_no, wcr.zone, wcr.ward, wtm.waste_type, wcr.payment_status, wcr.refid, " + + "wcr.actual_weight, wcr.payment_type, wcr.processing_charge, " + + "wcr.waste_collection_charge, wcr.total_charge, wcr.payment_mobile_no, wcr.door_number, wcr.street_name, " + + "wcr.area, wcr.city, wcr.pincode, " + "vm.vehicle_name, " + "qm.quantity, " + "dl.location, " + + "CONCAT(' " + fileBaseUrl + "/gcc/files', wcr.upload_image_url) AS upload_image_url, " + + "DATE_FORMAT(wcr.cdate, '%d-%m-%Y') AS request_date " + "FROM waste_collectors_request wcr " + + "LEFT JOIN vehicle_master vm ON wcr.vehicle_id = vm.id " + + "LEFT JOIN dumping_location dl ON wcr.dump_location_id = dl.id " + + "LEFT JOIN waste_type_master wtm ON wcr.waste_type_id = wtm.id " + + "LEFT JOIN quantity_master qm ON wcr.waste_quantity_id = qm.id " + "WHERE wcr.refid = ? "); + + return jdbcTemplate.queryForList(query.toString(), refId); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/util/ApiResponseUtil.java b/src/main/java/com/gcc/restapiservices/cdwaste/util/ApiResponseUtil.java new file mode 100644 index 0000000..71df660 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/util/ApiResponseUtil.java @@ -0,0 +1,44 @@ +package com.gcc.restapiservices.cdwaste.util; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +public class ApiResponseUtil { + + public static ResponseEntity>> success(Object data, String message) { + return buildResponse(true, HttpStatus.OK, message, data); + } + + public static ResponseEntity>> notFound(String message) { + return buildResponse(false, HttpStatus.NOT_FOUND, message, Collections.emptyList()); + } + + public static ResponseEntity>> error(String message, HttpStatus status) { + return buildResponse(false, status, message, null); + } + + + + public static ResponseEntity>> buildResponse( + boolean statusFlag, + HttpStatus httpStatus, + String message, + Object data + ) { + Map response = new LinkedHashMap<>(); + response.put("status", statusFlag); + response.put("code", httpStatus.value()); + response.put("message", message); + response.put("data", data); + + List> responseList = Collections.singletonList(response); + return ResponseEntity.status(httpStatus).body(responseList); + } + +} + diff --git a/src/main/java/com/gcc/restapiservices/cdwaste/util/DateTimeUtil.java b/src/main/java/com/gcc/restapiservices/cdwaste/util/DateTimeUtil.java new file mode 100644 index 0000000..c7403a1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/cdwaste/util/DateTimeUtil.java @@ -0,0 +1,35 @@ +package com.gcc.restapiservices.cdwaste.util; + +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); + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/configuration/PaymentConfig.java b/src/main/java/com/gcc/restapiservices/communityHall/configuration/PaymentConfig.java new file mode 100644 index 0000000..0fccb01 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/configuration/PaymentConfig.java @@ -0,0 +1,96 @@ +package com.gcc.restapiservices.communityHall.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@Configuration +@PropertySource("classpath:paymentConfig.properties") +public class PaymentConfig { + + @Value("${payment.worldline.merchantId}") + private String merchantId; + + @Value("${payment.worldline.encryptionKey}") + private String encryptionKey; + + @Value("${payment.worldline.encryptionIV}") + private String encryptionIV; + + @Value("${payment.worldline.schemeCode}") + private String schemeCode; + + @Value("${payment.worldline.merchantName}") + private String merchantName; + + @Value("${payment.worldline.transactionSuccessCode}") + private String transactionSuccessCode; + + @Value("${payment.worldline.refundSuccessCode}") + private String refundSuccessCode; + + + public String getMerchantId() { + return merchantId; + } + + public void setMerchantId(String merchantId) { + this.merchantId = merchantId; + } + + public String getEncryptionKey() { + return encryptionKey; + } + public byte[] getEncryptionKeyByte() { + return encryptionKey.getBytes(); + } + + public void setEncryptionKey(String encryptionKey) { + this.encryptionKey = encryptionKey; + } + + public String getEncryptionIV() { + return encryptionIV; + } + + public byte[] getEncryptionIVByte() { + return encryptionIV.getBytes(); + } + + public void setEncryptionIV(String encryptionIV) { + this.encryptionIV = encryptionIV; + } + + public String getSchemeCode() { + return schemeCode; + } + + public void setSchemeCode(String schemeCode) { + this.schemeCode = schemeCode; + } + + public String getMerchantName() { + return merchantName; + } + + public void setMerchantName(String merchantName) { + this.merchantName = merchantName; + } + + public String getTransactionSuccessCode() { + return transactionSuccessCode; + } + + public void setTransactionSuccessCode(String transactionSuccessCode) { + this.transactionSuccessCode = transactionSuccessCode; + } + + public String getRefundSuccessCode() { + return refundSuccessCode; + } + + public void setRefundSuccessCode(String refundSuccessCode) { + this.refundSuccessCode = refundSuccessCode; + }} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/controller/ReportController.java b/src/main/java/com/gcc/restapiservices/communityHall/controller/ReportController.java new file mode 100644 index 0000000..35c5539 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/controller/ReportController.java @@ -0,0 +1,95 @@ +package com.gcc.restapiservices.communityHall.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.communityHall.service.ReportService; +import com.gcc.restapiservices.communityHall.service.communityHallService; +import jakarta.servlet.http.HttpSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Controller +@RequestMapping("/gccrestservices/communityhall/api") +public class ReportController { + + @Autowired + private communityHallService bookingService; + + @Autowired + private ReportService reportService; + + @GetMapping("/report") + public ResponseEntity getReport() { + return ResponseEntity.ok("Report"); + } + + + // New REST endpoints for the three services using ReportService + + @GetMapping("/zone-wise-booking-data") + public ResponseEntity getZoneWiseBookingData( + @RequestParam(name = "fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String fromDate, + @RequestParam(name = "toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String toDate) { + try { + List> result = reportService.getZoneWiseBookingData(fromDate, toDate); + if (result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found for the specified date range"); + } + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Error retrieving zone-wise booking data: " + e.getMessage()); + } + } + + @GetMapping("/hall-details-by-zone") + public ResponseEntity getHallDetailsByZoneAndDate( + @RequestParam(name = "fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String fromDate, + @RequestParam(name = "toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String toDate, + @RequestParam(name = "zone") String zone) { + try { + if (zone == null || zone.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Zone parameter is required"); + } + + List> result = reportService.getHallDetailsByZoneAndDate(fromDate, toDate, zone); + if (result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No hall details found for zone: " + zone + " in the specified date range"); + } + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Error retrieving hall details by zone: " + e.getMessage()); + } + } + + @GetMapping("/hall-specific-data") + public ResponseEntity getHallSpecificData( + @RequestParam(name = "fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String fromDate, + @RequestParam(name = "toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String toDate, + @RequestParam(name = "zone", required = false) String zone, + @RequestParam(name = "hallId", required = false) Integer hallId) { + try { + List> result = reportService.getHallSpecificData(fromDate, toDate, zone, hallId); + if (result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No counter-wise booking data found for the specified criteria"); + } + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Error retrieving counter-wise booking data: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/communityHall/controller/communityHallController.java b/src/main/java/com/gcc/restapiservices/communityHall/controller/communityHallController.java new file mode 100644 index 0000000..b381f14 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/controller/communityHallController.java @@ -0,0 +1,992 @@ +package com.gcc.restapiservices.communityHall.controller; + +import com.gcc.restapiservices.communityHall.dto.PaymentWebhookPayload; +import com.gcc.restapiservices.communityHall.service.CHPaymentService; +import com.gcc.restapiservices.communityHall.service.communityHallService; +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.coworkspace.controller.ApiResponse; + +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.dao.EmptyResultDataAccessException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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 java.security.NoSuchAlgorithmException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Random; + +@RestController +@RequestMapping("/gccrestservices/communityhall/api") +public class communityHallController { + + @Autowired + private CHPaymentService chPaymentService; + + @Autowired + private communityHallService hallService; + @Autowired + private AppConfig appConfig; + + @GetMapping("/getHallList") + public List> getHallList() { + List> hallList = new ArrayList>(); + hallList = hallService.getHallList(); + + if (hallList.isEmpty()) { + return hallList; + } + return hallList; + } + + @GetMapping("/getReasonMaster") + public ResponseEntity getReasonMaster() { + try { + List> result = hallService.getReasonMaster(); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found"); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getDocumentsByReasonId") + public ResponseEntity getDocumentsByReasonId(@RequestParam(value = "reasonId", required = false) Long reasonId) { + if (reasonId == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "reasonId is required"); + errorResponse.put("message", "Missing required parameter for reasonId"); + return ResponseEntity.badRequest().body(errorResponse); + } + try { + List> result = hallService.getDocumentsByReasonId(reasonId); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found for reasonId: " + reasonId); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getRelationTypes") + public ResponseEntity getRelationTypes() { + try { + List> result = hallService.getRelationTypesAsMap(); + + if (result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found"); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getUserDetails") + public ResponseEntity getUserDetails(@RequestParam(value = "Mobilenumber", required = false) Long Mobilenumber) {// @RequestParam(value + // = + // "mobileNumber", + // required + // = + // false) + // Long + // mobileNumber, + if (Mobilenumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + // Check if mobile number is 10 digits + String mobileStr = String.valueOf(Mobilenumber); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + try { + List> result = hallService.getUserDetails(Mobilenumber); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No data found for Mobilenumber: " + Mobilenumber); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/calculatehallamount") + public ResponseEntity> getHallDetailsConcession( + @RequestParam(value = "numDays", required = false) Integer numDays, + @RequestParam(value = "startPeriod", required = false) String startPeriod, + @RequestParam(value = "endPeriod", required = false) String endPeriod, + @RequestParam(value = "reasonforBooking", required = false) String reasonforBooking, + @RequestParam(value = "hallId", required = false) Integer hallId) { + + // Validation for required parameters + if (numDays == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Number of days is required"); + errorResponse.put("message", "Please provide the numDays parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (startPeriod == null || startPeriod.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Start period is required"); + errorResponse.put("message", "Please provide the startPeriod parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + if (!startPeriod.equals("1") && !startPeriod.equals("2")) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Invalid startPeriod"); + errorResponse.put("message", "startPeriod must be either '1' or '2'"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (endPeriod == null || endPeriod.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "End period is required"); + errorResponse.put("message", "Please provide the endPeriod parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + if (!endPeriod.equals("1") && !endPeriod.equals("2")) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Invalid endPeriod"); + errorResponse.put("message", "endPeriod must be either '1' or '2'"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (reasonforBooking == null || reasonforBooking.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Reason for booking is required"); + errorResponse.put("message", "Please provide the reasonforBooking parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (hallId == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Hall ID is required"); + errorResponse.put("message", "Please provide the hallId parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + Map hallDetails = hallService.getHallDetailsById(hallId); + + if (hallDetails == null) { + return ResponseEntity.status(404).body(Map.of("message", "Incorrect HallID")); + } + System.out.println("hallDetails..." + hallDetails); + + Map concession = hallService.getHallConcessionByHallId(hallId); + System.out.println("concession....." + concession); + + Boolean isSGEObj = (Boolean) hallDetails.get("is_sge"); + Boolean isCGEObj = (Boolean) hallDetails.get("is_cge"); + + boolean isSGE = isSGEObj != null && isSGEObj; + boolean isCGE = isCGEObj != null && isCGEObj; + + double fullDayAmount = toDouble(hallDetails.get("full_day_rent")); + double halfDayAmount = toDouble(hallDetails.get("half_day_rent")); + double depositAmount = toDouble(hallDetails.get("deposit_amount")); + double gstRate = toDouble(hallDetails.get("gst")); + System.out.println("tete"); + System.out.println(depositAmount); + + Map response = new HashMap<>(); + double amount = calculateAmount(numDays, startPeriod, endPeriod, fullDayAmount, halfDayAmount); + double totalDepositAmount = calculateDepositAmount(numDays, startPeriod, endPeriod, depositAmount); + double totalAmount = 0; + double discountAmount = 0; + + response.put("reasonforBooking", reasonforBooking); + + if (!isSGE) { + double gst = round(amount * gstRate / 100.0); + totalAmount = round(amount + gst + totalDepositAmount); + response.put("discount", 0); + response.put("amount", round(amount)); + response.put("totalAmount", totalAmount); + response.put("depositAmount", round(totalDepositAmount)); + response.put("gst", gst); + response.put("discountAmount", round(amount)); + } else if ("SGE".equalsIgnoreCase(reasonforBooking) && concession != null) { + double fullCleaning = toDouble(concession.get("fullday_cleaningcharges")); + double fullPA = toDouble(concession.get("fullday_pasystem")); + double fullEB = toDouble(concession.get("fullday_ebcharges")); + double halfCleaning = toDouble(concession.get("halfday_cleaningcharges")); + double halfPA = toDouble(concession.get("halfday_pasystem")); + double halfEB = toDouble(concession.get("halfday_ebcharges")); + + double fullAdd = fullCleaning + fullPA + fullEB; + double halfAdd = halfCleaning + halfPA + halfEB; + double addCharges = calculateAmount(numDays, startPeriod, endPeriod, fullAdd, halfAdd); + double sgeDiscount = toDouble(hallDetails.get("sge_discount")); + double fullRent = toDouble(concession.get("fulldayhallamount")); + double halfRent = toDouble(concession.get("halfdayhallamount")); + + double gst = round(addCharges * gstRate / 100.0); + totalAmount = round(addCharges + totalDepositAmount + gst); + discountAmount = round((fullRent * sgeDiscount) / 100.0); + + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("fulldayhallAmount", round(fullRent)); + response.put("halfdayhallAmount", round(halfRent)); + response.put("discount", sgeDiscount); + response.put("rentAmount", 0); + response.put("additionalCharges", round(addCharges)); + response.put("netAmount", round(addCharges)); + response.put("gst", gst); + response.put("depositAmount", round(totalDepositAmount)); + response.put("totalAmount", totalAmount); + response.put("discountAmount", discountAmount); + } else if ("CGE".equalsIgnoreCase(reasonforBooking) && concession != null) { + double fullCleaning = toDouble(concession.get("fullday_cleaningcharges")); + double fullPA = toDouble(concession.get("fullday_pasystem")); + double fullEB = toDouble(concession.get("fullday_ebcharges")); + double halfCleaning = toDouble(concession.get("halfday_cleaningcharges")); + double halfPA = toDouble(concession.get("halfday_pasystem")); + double halfEB = toDouble(concession.get("halfday_ebcharges")); + + double fullAdd = fullCleaning + fullPA + fullEB; + double halfAdd = halfCleaning + halfPA + halfEB; + double addCharges = calculateAmount(numDays, startPeriod, endPeriod, fullAdd, halfAdd); + double cgeDiscount = toDouble(hallDetails.get("cge_discount")); + + double rentAmount = round((amount * cgeDiscount) / 100.0); + double netAmount = round(rentAmount + addCharges); + double gst = round(netAmount * gstRate / 100.0); + totalAmount = round(netAmount + gst + totalDepositAmount); + + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("fulldayhallAmount", round(fullDayAmount)); + response.put("halfdayhallAmount", round(halfDayAmount)); + response.put("discount", cgeDiscount); + response.put("rentAmount", rentAmount); + response.put("additionalCharges", round(addCharges)); + response.put("netAmount", netAmount); + response.put("gst", gst); + response.put("depositAmount", round(totalDepositAmount)); + response.put("totalAmount", totalAmount); + response.put("discountAmount", round(discountAmount)); + } else { + double gstValue = round(gstRate * amount / 100.0); + totalAmount = round(amount + gstValue + totalDepositAmount); + response.put("discount", 0); + response.put("amount", round(amount)); + response.put("totalAmount", totalAmount); + response.put("depositAmount", round(totalDepositAmount)); + response.put("gst", gstValue); + response.put("discountAmount", round(amount)); + } + response.put("numDays", numDays); + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("reasonforBooking", reasonforBooking); + response.put("hallId", hallId); + + return ResponseEntity.ok(response); + } + + // Helper to safely convert Object to double + private double toDouble(Object value) { + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + return 0.0; + } + + // Helper to round to 2 decimal places + private double round(double value) { + return Math.round(value * 100.0) / 100.0; + } + + public double calculateAmount(double numDays, String startPeriod, String endPeriod, double fullDayAmount, + double halfDayAmount) { + double amount = 0; + + // If there is only one day + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + amount = halfDayAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + amount = halfDayAmount; + } else { + amount = numDays; + } + } else { + // For multiple days + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount * numDays; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 1) + halfDayAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 1) + halfDayAmount; + } else if ("2".equals(startPeriod) && "1".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 2) + halfDayAmount * 2; + } else { + amount = numDays; + } + } + + return amount; + } + + public double calculateDepositAmount(double numDays, String startPeriod, String endPeriod, double depositAmount) { + double damount = 0; + + // If there is only one day + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount; + } else { + damount = numDays; + } + } else { + // For multiple days + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount * numDays; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount * (numDays - 1) + depositAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount * (numDays - 1) + depositAmount; + } else if ("2".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount * (numDays - 2) + depositAmount; + } else { + damount = numDays; + } + } + + return damount; + } + + /* + * @GetMapping("/checkMobileExits") public String checkMobileExits(@RequestParam + * (value = "Mobilenumber", required = false) long Mobilenumber) { + * // @RequestParam(value = "mobileNumber", required = false) Long mobileNumber, + * + * try { + * + * // Validate mobile number has exactly 10 digits String mobileStr = + * String.valueOf(Mobilenumber); if (mobileStr.length() != 10) { return + * "Invalid mobile number. Must be exactly 10 digits."; } return + * !hallService.checkMobileExits(Mobilenumber).isEmpty() ? "Already Registered" + * : "Allow to Register"; } catch (Exception e) { return "error"; } } + */ + @GetMapping("/checkMobileExits") + public ResponseEntity checkMobileExits( + @RequestParam(value = "Mobilenumber", required = false) Long Mobilenumber) { + + if (Mobilenumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + try { + String mobileStr = String.valueOf(Mobilenumber); + if (mobileStr.length() != 10) { + return ResponseEntity.badRequest().body("Invalid mobile number. Must be exactly 10 digits."); + } + + boolean exists = !hallService.checkMobileExits(Mobilenumber).isEmpty(); + return ResponseEntity.ok(exists ? "Already Registered" : "Allow to Register"); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal server error"); + } + } + + // otp + @GetMapping(value = "/sendOTP") + public String sendOtp(HttpServletRequest request, @RequestParam String mobile) { + + // Validate mobile number has exactly 10 digits + if (mobile == null || mobile.trim().isEmpty()) { + return "Mobile number is required."; + } + + String mobileTrimmed = mobile.trim(); + if (mobileTrimmed.length() != 10) { + return "Invalid mobile number. Must be exactly 10 digits."; + } + + String MobileNo = mobile; + System.out.print("\n MobileNo---:" + mobile); + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + +// int otp= 22222; + System.out.print("\n otp---:" + otp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); + LocalDateTime now = LocalDateTime.now(); + System.out.println(dtf.format(now)); + + String generatedToken = "Welcome to GCC! Your OTP for GCC Community Centre is " + otp; + String key = "pfTEYN6H"; + String urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + mobile + + "&from=GCCCRP&body=Welcome to GCC! Your OTP for GCC Community Centre booking is " + otp + + "&entityid=1401572690000011081&templateid=1407172346444550398"; + + System.out.print("\n urlString---: " + urlString); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + jsonResponse.put("MobileNo", MobileNo); + jsonResponse.put("otp", otp); + + bodyMessage = jsonResponse.toString(); + System.out.println("\n bodyMessage" + bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: " + e); + bodyMessage = "Error"; + } + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + return bodyMessage; + + } + + @GetMapping("/verifyEmployee") + public ResponseEntity verifyEmployee(@RequestParam String userType, + @RequestParam(value = "EmployeeID", required = false) String EmployeeID) { + if (EmployeeID == null || EmployeeID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'EmployeeID' parameter"); + } + + if (!"GCC EMPLOYEE".equalsIgnoreCase(userType)) { + return ResponseEntity.badRequest().body("Invalid userType for Employee verification."); + } + + if (EmployeeID == null || EmployeeID.isBlank()) { + return ResponseEntity.badRequest().body("Employee ID is required for GCC EMPLOYEE."); + } + + List> existingEmployeeUsers = hallService.checkEmployeeExits(EmployeeID); + if (existingEmployeeUsers != null && !existingEmployeeUsers.isEmpty()) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Employee number already registered"); + } + + try { + String responseBody = getEmployeeResponse(EmployeeID); + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(responseBody); + boolean resultStatus = rootNode.path("ResultStatus").asBoolean(); + + if (!resultStatus) { + return ResponseEntity.badRequest().body("Invalid employee ID."); + } + + return ResponseEntity.ok(rootNode); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Employee verification failed."); + } + } + + @GetMapping("/verifyPensioner") + public ResponseEntity verifyPensioner(@RequestParam String userType, + @RequestParam(value = "PensionerID", required = false) String PensionerID) { + + if (PensionerID == null || PensionerID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'PensionerID' parameter"); + } + + if (!"GCC PENSIONER".equalsIgnoreCase(userType)) { + return ResponseEntity.badRequest().body("Invalid userType for Pensioner verification."); + } + + if (PensionerID == null || PensionerID.isBlank()) { + return ResponseEntity.badRequest().body("Pensioner ID is required for GCC PENSIONER."); + } + + List> existingEmployeeUsers = hallService.checkPenionerExits(PensionerID); + if (existingEmployeeUsers != null && !existingEmployeeUsers.isEmpty()) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Pensioner number already registered"); + } + + try { + String responseBody = getPensionerResponse(PensionerID); + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(responseBody); + boolean resultStatus = rootNode.path("ResultStatus").asBoolean(); + + if (!resultStatus) { + return ResponseEntity.badRequest().body("Invalid pensioner ID."); + } + + return ResponseEntity.ok(rootNode); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Pensioner verification failed."); + } + } + + @PostMapping("/register") + public ResponseEntity registerUser(@RequestParam(value = "userType", required = false) String userType, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "mobileNumber", required = false) Long mobileNumber, + @RequestParam(value = "aadharNumber", required = false) String aadharNumber, + @RequestParam(required = false) MultipartFile profilePhoto, @RequestParam(required = false) String emailId, + @RequestParam(value = "doorNo", required = false) String doorNo, + @RequestParam(value = "street", required = false) String street, + @RequestParam(value = "area", required = false) String area, + @RequestParam(value = "location", required = false) String location, + @RequestParam(value = "pincode", required = false) String pincode, + @RequestParam(required = false) String PensionerID, + @RequestParam(required = false) String PensionerDepartment, + @RequestParam(required = false) String EmployeeID, + @RequestParam(required = false) String EmployeeDepartment) { + + try { + + if (userType == null || userType.trim().isEmpty()) { + return ResponseEntity.badRequest().body("User type is required."); + } + + if (name == null || name.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Name is required."); + } + + if (mobileNumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + if (aadharNumber == null || aadharNumber.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Aadhar number is required."); + } + + if (doorNo == null || doorNo.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Door number is required."); + } + + if (street == null || street.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Street is required."); + } + + if (area == null || area.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Area is required."); + } + + if (location == null || location.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Location is required."); + } + + if (pincode == null || pincode.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Pincode is required."); + } + + // Additional validations for specific user types + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + if (PensionerID == null || PensionerID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Pensioner ID is required for GCC PENSIONER user type."); + } + if (PensionerID.length() != 6) { + + return ResponseEntity.badRequest().body("Invalid PensionerID. Must be exactly 6 digits.."); + } + if (PensionerDepartment == null || PensionerDepartment.trim().isEmpty()) { + return ResponseEntity.badRequest() + .body("Pensioner Department is required for GCC PENSIONER user type."); + } + } + + if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + if (EmployeeID == null || EmployeeID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Employee ID is required for GCC EMPLOYEE user type."); + } + if (EmployeeID.length() != 6) { + + return ResponseEntity.badRequest().body("Invalid EmployeeID. Must be exactly 6 digits.."); + } + + if (EmployeeDepartment == null || EmployeeDepartment.trim().isEmpty()) { + return ResponseEntity.badRequest() + .body("Employee Department is required for GCC EMPLOYEE user type."); + } + } + + // Format validations + if (String.valueOf(mobileNumber).length() != 10) { + return ResponseEntity.badRequest().body("Mobile number must be exactly 10 digits."); + } + + if (pincode.length() != 6) { + return ResponseEntity.badRequest().body("Pincode must be exactly 6 digits."); + } + + if (emailId != null && !emailId.isBlank()) { + String emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.com$"; + if (!emailId.matches(emailRegex)) { + return ResponseEntity.badRequest().body("Invalid email ID."); + } + } + + if (aadharNumber.length() != 12) { + return ResponseEntity.badRequest().body("Aadhar number must be exactly 12 digits."); + } + + // Mobile number check only for PUBLIC users + if ("PUBLIC".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkMobileExits(mobileNumber); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Mobile number already registered"); + } + } + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkPenionerExits(PensionerID); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Pensioner number already registered "); + } + } + if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkEmployeeExits(EmployeeID); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Employee number already registered"); + } + } + + // Register all user types + hallService.registerUser(userType, name, mobileNumber, aadharNumber, profilePhoto, emailId, doorNo, street, + area, location, pincode, PensionerID, PensionerDepartment, EmployeeID, EmployeeDepartment); + + // return ResponseEntity.ok("Pending."); + // Return different success messages based on user type + String successMessage; + if ("PUBLIC".equalsIgnoreCase(userType)) { + successMessage = "Welcome to GCC, Your User Registration for booking Community Centre is successful."; + } else if ("GCC PENSIONER".equalsIgnoreCase(userType) || "COUNCILLOR".equalsIgnoreCase(userType) + || "GCC EMPLOYEE".equalsIgnoreCase(userType)) { + successMessage = "Welcome to GCC, Your User Registration request for booking Community Centre is submitted successfully."; + } else { + successMessage = "Welcome to GCC, your registration is successful."; + } + return ResponseEntity.ok(successMessage); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Registration failed."); + } + } + + private String getPensionerResponse(String pensionerId) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/external/mobileservice?serviceId=getPensionerDetailsList&pensionerId=" + + pensionerId; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + String responseBody = responseEntity.getBody(); + System.out.println("response.. " + responseBody); + return responseBody; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private String getEmployeeResponse(String employeeId) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/external/mobileservice?serviceId=getEmployeeDetail&EmployeeID=" + + employeeId; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + String responseBody = responseEntity.getBody(); + System.out.println("Employee API response: " + responseBody); + return responseBody; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @GetMapping("/verifyCounsellor") + public ResponseEntity checkCounsellorMobileExits( + @RequestParam(value = "mobileNo", required = false) Long mobileNo) {// @RequestParam(value = "mobileNumber", + // required = false) Long mobileNumber, + if (mobileNo == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + String mobileStr = String.valueOf(mobileNo); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + + try { + // Validate input + if (mobileNo == null || mobileNo.toString().trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'mobileNo' parameter."); + } + + // Search for counsellor using mobile1 or mobile2 + List> counsellorList = hallService.findCounsellorByMobile(mobileNo); + + if (counsellorList == null || counsellorList.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Counsellor mobile number not found."); + } + + Map counsellor = counsellorList.get(0); + String mobile1 = String.valueOf(counsellor.get("mobile1")); + String mobile2 = String.valueOf(counsellor.get("mobile2")); + + // Check if either number is already used in Users table + boolean isMobile1Used = !hallService.checkMobileExits(Long.parseLong(mobile1)).isEmpty(); + boolean isMobile2Used = !hallService.checkMobileExits(Long.parseLong(mobile2)).isEmpty(); + + if (isMobile1Used || isMobile2Used) { + return ResponseEntity.status(HttpStatus.CONFLICT) + .body("One of the counsellor's mobile numbers is already used."); + } + + return ResponseEntity.ok(counsellor.get("name").toString()); + + } catch (NumberFormatException e) { + return ResponseEntity.badRequest().body("Invalid mobile number format."); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Mobile number verification failed."); + } + } + + // acknowledgment + /* + * @GetMapping("/acknowledgement") public ResponseEntity> + * getBookingDetails(@RequestParam(value = "bookingId", required = false) int + * bookingId) { Map bookingDetails = + * hallService.getBookingDetailsById(bookingId); return + * ResponseEntity.ok(bookingDetails); } + */ + @GetMapping("/acknowledgement") + public ResponseEntity getBookingDetails(@RequestParam(value = "bookingId", required = false) Integer bookingId) { + if (bookingId == null) { + return ResponseEntity.badRequest().body("Booking ID is required."); + } + + try { + Map bookingDetails = hallService.getBookingDetailsById(bookingId); + + return ResponseEntity.ok(bookingDetails); + + } catch (EmptyResultDataAccessException ex) { + // No booking found + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No booking found for bookingId"); + } catch (Exception e) { + // Any other error + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + //mobile + /* + * @GetMapping("/viewhistory") public ResponseEntity> + * getBookingsByMobile( + * + * @RequestParam("mobileNumber") Long mobileNumber) { + * + * + * Map response = new HashMap<>(); + * + * // Step 1: Check if user exists List> userResult = + * hallService.checkMobileExits(mobileNumber); + * + * if (userResult.isEmpty()) { response.put("status", "NOT_FOUND"); + * response.put("message", "No user found with the given mobile number"); return + * ResponseEntity.ok(response); } + * + * // Step 2: If exists → Call service List> bookings = + * hallService.getBookingsByMobile(mobileNumber); + * + * response.put("status", "SUCCESS"); + * + * response.put("mobile_no", mobileNumber); response.put("bookings", bookings); + * + * return ResponseEntity.ok(response); } + */ + @GetMapping("/viewhistory") + public ResponseEntity getBookingsByMobile( + @RequestParam(value = "mobileNumber", required = false) Long mobileNumber) { + if (mobileNumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + // Check if mobile number is exactly 10 digits + String mobileStr = String.valueOf(mobileNumber); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + + try { + // Step 1: Check if user exists + List> userResult = hallService.checkMobileExits(mobileNumber); + if (userResult.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No user found with the given mobile number "); + } + + // Step 2: Get bookings + List> bookings = hallService.getBookingsByMobile(mobileNumber); + if (bookings == null || bookings.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No bookings found for mobile number: " + mobileNumber); + } + + // Success response + Map response = new HashMap<>(); + response.put("status", "SUCCESS"); + response.put("mobile_no", mobileNumber); + response.put("bookings", bookings); + + return ResponseEntity.ok(response); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @PostMapping(path = "/saveTheRequest2", consumes = {"multipart/form-data"}) + public ResponseEntity saveTheBookingDetails2(HttpServletRequest request) { + try { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map bookingDetails = splitFormData(multipartRequest); + Map saveBookingDetails = hallService.saveBookingDetails(bookingDetails); + + return ResponseEntity.ok(new ApiResponse("success", "Booking details saved successfully", + saveBookingDetails, HttpStatus.OK.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to save booking details " + e.getMessage(), null, + HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + public Map splitFormData(MultipartHttpServletRequest multipartRequest) { + Map formData = new HashMap<>(); + + // Iterate through the request parameters + Enumeration parameterNames = multipartRequest.getParameterNames(); + while (parameterNames.hasMoreElements()) { + String paramName = parameterNames.nextElement(); + String paramValues = multipartRequest.getParameter(paramName); + formData.put(paramName, paramValues); + } + + // Iterate through the request parts (files) + try { + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entry : fileMap.entrySet()) { + MultipartFile file = entry.getValue(); + if (!file.isEmpty()) { + formData.put(entry.getKey(), file); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return formData; + } + + @PostMapping("/payment-request") + public ResponseEntity startPayment(@RequestParam int bookingId) { + try { + Map paymentDetails = hallService.startPayment(bookingId); + + return ResponseEntity.ok(new ApiResponse("success", "Payment request initiated successfully", + paymentDetails, HttpStatus.OK.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to initiate payment request: " + e.getMessage(), null, + HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @PostMapping("/payment-response") + public ResponseEntity paymentResponse(@RequestParam String orderId, @RequestBody PaymentWebhookPayload payload) { + try { + ResponseEntity result = chPaymentService.processPaymentResponse(orderId, payload); + + return ResponseEntity + .ok(new ApiResponse("success", "Payment processed successfully", result, HttpStatus.OK.value())); + + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return ResponseEntity.badRequest().body(new ApiResponse("error", "Invalid request: " + e.getMessage(), null, + HttpStatus.BAD_REQUEST.value())); + + } catch (EmptyResultDataAccessException e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse("error", + "No payment record found for Order ID: " + orderId, null, HttpStatus.NOT_FOUND.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ApiResponse("error", + "Failed to Process the Payment: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @GetMapping("/checkSlot") + public ResponseEntity> checkSlotAvailability( + @RequestParam int hallId, + @RequestParam String startDate, + @RequestParam String endDate, + @RequestParam int startingSlot, // 1 = morning, 2 = evening + @RequestParam int endingSlot // 1 = morning, 2 = evening + ) { + Map result = hallService.checkSlotAvailability(hallId, startDate, endDate, startingSlot, endingSlot); + return ResponseEntity.ok(result); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/dto/PaymentWebhookPayload.java b/src/main/java/com/gcc/restapiservices/communityHall/dto/PaymentWebhookPayload.java new file mode 100644 index 0000000..5d8fc5f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/dto/PaymentWebhookPayload.java @@ -0,0 +1,198 @@ +package com.gcc.restapiservices.communityHall.dto; + +import java.math.BigDecimal; + +public class PaymentWebhookPayload { + private String reference_id; + private Currency currency; + private Amount paymentAmount; + private Transaction transaction; + + public String getReference_id() { + return reference_id; + } + + public void setReference_id(String reference_id) { + this.reference_id = reference_id; + } + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public Amount getPaymentAmount() { + return paymentAmount; + } + + public void setPaymentAmount(Amount paymentAmount) { + this.paymentAmount = paymentAmount; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + public static class Currency { + private String reference_id; + private Amount amount; + private String currency; + private Transaction transaction; + + public String getReference_id() { + return reference_id; + } + + public void setReference_id(String reference_id) { + this.reference_id = reference_id; + } + + public Amount getAmount() { + return amount; + } + + public void setAmount(Amount amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + } + + public static class Amount { + private double value; + private double offset; + + public double getValue() { + return value; + } + + public void setValue(double value) { + this.value = value; + } + + public double getOffset() { + return offset; + } + + public void setOffset(double offset) { + this.offset = offset; + } + } + + public static class Transaction { + private String id; + private String pg_transaction_id; + private String type; + private String status; + private long created_timestamp; + private long updated_timestamp; + private Amount amount; + private String currency; + private Method method; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPg_transaction_id() { + return pg_transaction_id; + } + + public void setPg_transaction_id(String pg_transaction_id) { + this.pg_transaction_id = pg_transaction_id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public long getCreated_timestamp() { + return created_timestamp; + } + + public void setCreated_timestamp(long created_timestamp) { + this.created_timestamp = created_timestamp; + } + + public long getUpdated_timestamp() { + return updated_timestamp; + } + + public void setUpdated_timestamp(long updated_timestamp) { + this.updated_timestamp = updated_timestamp; + } + + public Amount getAmount() { + return amount; + } + + public void setAmount(Amount amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + } + + public static class Method { + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionData.java b/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionData.java new file mode 100644 index 0000000..651be51 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionData.java @@ -0,0 +1,83 @@ +package com.gcc.restapiservices.communityHall.dto; + +public class TransactionData { + private Merchant merchant = new Merchant(); + private Transaction transaction = new Transaction(); + + public Merchant getMerchant() { + return merchant; + } + + public Transaction getTransaction() { + return transaction; + } + + public static class Merchant { + private String identifier; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + } + + public static class Transaction { + private String amount; + private String identifier; + private String dateTime; + private String requestType; + private String token; + private String reference; + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public String getRequestType() { + return requestType; + } + + public void setRequestType(String requestType) { + this.requestType = requestType; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getReference() { + return reference; + } + + public void setReference(String reference) { + this.reference = reference; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionRefundResponse.java b/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionRefundResponse.java new file mode 100644 index 0000000..c78952b --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/dto/TransactionRefundResponse.java @@ -0,0 +1,73 @@ +package com.gcc.restapiservices.communityHall.dto; + +public class TransactionRefundResponse { + private String merchantTransactionIdentifier; + private PaymentMethod paymentMethod; + + public String getMerchantTransactionIdentifier() { + return merchantTransactionIdentifier; + } + + public void setMerchantTransactionIdentifier(String merchantTransactionIdentifier) { + this.merchantTransactionIdentifier = merchantTransactionIdentifier; + } + + public PaymentMethod getPaymentMethod() { + return paymentMethod; + } + + public void setPaymentMethod(PaymentMethod paymentMethod) { + this.paymentMethod = paymentMethod; + } + + public static class PaymentMethod { + private PaymentTransaction paymentTransaction; + + public PaymentTransaction getPaymentTransaction() { + return paymentTransaction; + } + + public void setPaymentTransaction(PaymentTransaction paymentTransaction) { + this.paymentTransaction = paymentTransaction; + } + } + + public static class PaymentTransaction { + private String statusCode; + private String amount; + private String balanceAmount; + private String refundIdentifier; + + public String getStatusCode() { + return statusCode; + } + + public void setStatusCode(String statusCode) { + this.statusCode = statusCode; + } + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getBalanceAmount() { + return balanceAmount; + } + + public void setBalanceAmount(String balanceAmount) { + this.balanceAmount = balanceAmount; + } + + public String getRefundIdentifier() { + return refundIdentifier; + } + + public void setRefundIdentifier(String refundIdentifier) { + this.refundIdentifier = refundIdentifier; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/service/CHPaymentService.java b/src/main/java/com/gcc/restapiservices/communityHall/service/CHPaymentService.java new file mode 100644 index 0000000..f0483f1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/service/CHPaymentService.java @@ -0,0 +1,536 @@ +package com.gcc.restapiservices.communityHall.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.communityHall.configuration.PaymentConfig; +import com.gcc.restapiservices.communityHall.dto.PaymentWebhookPayload; +import com.gcc.restapiservices.communityHall.dto.TransactionData; +import com.gcc.restapiservices.communityHall.dto.TransactionRefundResponse; +import com.gcc.restapiservices.communityHall.util.EncryptionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.client.RestTemplate; +import java.util.HashMap; + +import javax.sql.DataSource; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Service +public class CHPaymentService { + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private PaymentConfig paymentConfig; + + @Autowired + private WhatsappMsgServiceImpl whatsappMsgServiceImpl; + + @Autowired + private EncryptionUtils encryptionUtils; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public void setDataSource(@Qualifier("mysqlCommunityHallDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Transactional("mysqlCommunityHallTransactionManager") + public ResponseEntity processPaymentResponse( + @RequestParam String OrderId, + @RequestBody PaymentWebhookPayload payload) throws Exception { + + Map result = new HashMap<>(); + + String transactionId = OrderId; + String pgTxnId = payload.getTransaction().getPg_transaction_id(); + String status = payload.getTransaction().getStatus(); + double amount = payload.getTransaction().getAmount().getValue() / 100.0; + String dateTime = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") + .withZone(ZoneId.of("Asia/Kolkata")) + .format(Instant.ofEpochSecond(payload.getTransaction().getCreated_timestamp())); + + Map txn; + try { + txn = jdbcTemplate.queryForMap( + "SELECT * FROM transaction_response WHERE txansaction_id = ? AND status_code ='temp' ", + transactionId); + } catch (EmptyResultDataAccessException e) { + result.put("status", "error"); + result.put("message", "Transaction not found or already processed."); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); + } + + int bookingId = (int) txn.get("booking_id"); + int hallId = (int) txn.get("hall_id"); + String userId = (String) txn.get("user_id"); + + jdbcTemplate.update( + "UPDATE transaction_response SET tpsl_txn_id = ?, amount = ?, date = ?, status_code = ?, response = ?, " + + + "booking_id = ?, hall_id = ?, user_id = ? WHERE txansaction_id = ?", + pgTxnId, String.valueOf(amount), dateTime, status, + objectMapper.writeValueAsString(payload), bookingId, hallId, userId, transactionId); + + Map booking; + try { + booking = jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?", bookingId); + } catch (EmptyResultDataAccessException e) { + result.put("status", "error"); + result.put("message", "Booking not found."); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); + } + + double expectedAmount = booking.get("amount_received") != null + ? ((Number) booking.get("amount_received")).doubleValue() + : 0.0; + + jdbcTemplate.update("INSERT INTO payments " + + " (transaction_id, amount_received, payment_status, cdate, booking_details_booking_id) " + + " VALUES (?, ?, ?, ?, ?)", transactionId, amount, "Not Completed", new Date(), + bookingId); + + if (expectedAmount != amount) { + updatePaymentStatus(transactionId, "Failed"); + // bookingFailure(bookingId, 1); + result.put("status", "error"); + result.put("message", "Amount mismatch. Payment failed."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + if ("success".equalsIgnoreCase(status)) { + updatePaymentStatus(transactionId, "Success"); + confirmBooking(bookingId); + + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + + bookingId; + result.put("status", "success"); + result.put("message", "Payment processed successfully."); + result.put("acknowledgement_url", acknowledgementUrl); + return ResponseEntity.ok(result); + } else { + updatePaymentStatus(transactionId, "Failed"); + result.put("status", "error"); + result.put("message", "Payment failed."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + } + + public void updatePaymentStatus(String transactionId, String status) { + jdbcTemplate.update("UPDATE payments SET payment_status = ? WHERE transaction_id = ?", status, transactionId); + } + + @Transactional(value = "mysqlCommunityHallTransactionManager", propagation = Propagation.REQUIRES_NEW) + public void bookingFailure(int bookingId, int flag) { + String comment = flag == 1 ? "Booking Not Confirmed" + : "Slot occupied by other user, Amount paid will be refunded."; + jdbcTemplate.update("UPDATE booking_details SET booking_status = 'REFUNDED', comments = ? WHERE booking_id = ?", + comment, bookingId); + /* + * String refundStatus = booking.get("refund_status").toString(); + * if (!("COMPLETED".equalsIgnoreCase(refundStatus)) && + * !("CLOSED".equalsIgnoreCase(refundStatus))) { + * refundTheAmount(bookingId, Integer.parseInt(userId)); + * } + */ + } + + @Transactional("mysqlCommunityHallTransactionManager") + public String confirmBooking(int bookingId) { + Map booking = jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?", + bookingId); + try { + int hallId = (int) booking.get("hall_details_hall_id"); + LocalDate startDate = LocalDate.parse((String) booking.get("start_date")); + LocalDate endDate = LocalDate.parse((String) booking.get("end_date")); + int startSlot = (int) booking.get("starting_slot"); + int endSlot = (int) booking.get("ending_slot"); + double noOfDays = booking.get("no_of_days") != null ? (double) booking.get("no_of_days") : 1.0; + + // int i = 0; + // for (LocalDate date = startDate; !date.isAfter(endDate); date = + // date.plusDays(1)) { + // String checkSql = "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id + // = ?"; + // List> existing = jdbcTemplate.queryForList(checkSql, + // date, hallId); + + // if (!existing.isEmpty()) { + // Map cal = existing.get(0); + // if ((boolean) cal.get("is_blocked")) throw new RuntimeException("GCC Blocked + // Date"); + // boolean morningBooked = (boolean) cal.get("morning_slot"); + // boolean eveningBooked = (boolean) cal.get("evening_slot"); + // if ((date.equals(startDate) && startSlot == 1 && morningBooked) || + // (date.equals(startDate) && startSlot == 2 && eveningBooked) || + // (date.equals(endDate) && endSlot == 1 && morningBooked) || + // (date.equals(endDate) && endSlot == 2 && eveningBooked)) { + // throw new RuntimeException("Slot already booked or partially occupied"); + // } + // updateCalendarWithBooking(date, bookingId, hallId, startDate, endDate, + // startSlot, endSlot, i); + // } else { + // insertCalendarWithBooking(date, bookingId, hallId, startDate, endDate, + // startSlot, endSlot, i); + // } + // i++; + // } + + int i = 0; + for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { + + String checkSql = "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?"; + List> existing = jdbcTemplate.queryForList(checkSql, date, hallId); + + if (!existing.isEmpty()) { + Map cal = existing.get(0); + if ((boolean) cal.get("is_blocked")) + throw new RuntimeException("GCC Blocked Date"); + + boolean morningBooked = (boolean) cal.get("morning_slot"); + boolean eveningBooked = (boolean) cal.get("evening_slot"); + int isBooked = (int) cal.get("is_booked"); + String bookingId1 = (String) cal.get("booking_id_1"); + String bookingId2 = (String) cal.get("booking_id_2"); + + // ====== Validation ====== + if ((date.equals(startDate) && startSlot == 1 && morningBooked) || + (date.equals(startDate) && startSlot == 2 && eveningBooked) || + (date.equals(endDate) && endSlot == 1 && morningBooked) || + (date.equals(endDate) && endSlot == 2 && eveningBooked) || + (morningBooked && eveningBooked)) { + throw new RuntimeException("Slot already booked or partially occupied"); + } + + // ====== Update slots ====== + if (date.equals(startDate)) { + if (startSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + if (!date.equals(endDate) || (startDate.equals(endDate) && endSlot == 2)) { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else if (date.equals(endDate)) { + if (endSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + if (endSlot == 2) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } + } + } else { + morningBooked = true; + eveningBooked = true; + bookingId1 = String.valueOf(bookingId); + bookingId2 = String.valueOf(bookingId); + isBooked += 2; + } + + // ====== Run UPDATE ====== + String updateSql = "UPDATE booking_calendar " + + "SET morning_slot=?, evening_slot=?, is_booked=?, booking_id_1=?, booking_id_2=? " + + "WHERE bdate=? AND hall_id=?"; + jdbcTemplate.update(updateSql, + morningBooked, eveningBooked, isBooked, bookingId1, bookingId2, + date, hallId); + + } else { + // ====== Insert new row ====== + boolean morningBooked = false; + boolean eveningBooked = false; + boolean isDelete = false; + boolean isBlocked = false; + int isBooked = 0; + String bookingId1 = null, bookingId2 = null; + + if (date.equals(startDate)) { + if (startSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + if (!date.equals(endDate) || (startDate.equals(endDate) && endSlot == 2)) { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else if (date.equals(endDate)) { + if (endSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + if (endSlot == 2) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } + } + } else { + morningBooked = true; + eveningBooked = true; + bookingId1 = String.valueOf(bookingId); + bookingId2 = String.valueOf(bookingId); + isBooked += 2; + } + + String uniqueId = date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId; + + System.out.println("uniqueId...."+uniqueId+"\n hallId: "+hallId+"\n morningBooked: "+morningBooked+ + "\n eveningBooked: "+eveningBooked+"\n isBooked: "+isBooked+"\n bookingId1: "+bookingId1+"\n bookingId2: "+bookingId2); + + String insertSql = "INSERT INTO booking_calendar " + + "(bdate, hall_id, morning_slot, evening_slot, is_booked, booking_id_1, booking_id_2, is_active, unique_id, is_delete, is_blocked) " + +"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertSql,date, hallId, morningBooked, eveningBooked, isBooked,bookingId1, bookingId2, true, uniqueId, isDelete, isBlocked); + } + i++; + } + + String reason = (String) booking.get("reason"); + String reasonCode = fetchReasonCode(reason); + + String status = "APPROVED"; + String comments = "Booking Confirmed Successfully"; + if (reasonCode != null && !reasonCode.trim().isEmpty()) { + if (List.of("CGE", "CAO", "SGE").contains(reasonCode)) { + status = "WAITING_FOR_NOC"; + comments = "Waiting For NOC Documents"; + } + } + + jdbcTemplate.update("UPDATE booking_details SET booking_status = ?, comments = ? WHERE booking_id = ?", + status, comments, bookingId); + + sendConfirmationMessages(bookingId, booking); + return comments; + } catch (Exception e) { + e.printStackTrace(); + // bookingFailure(bookingId, 2); + return "redirect:/communityhall/user/acknowledgement?bookingId=" + bookingId; + } + } + + private void updateCalendarWithBooking(LocalDate date, int bookingId, int hallId, LocalDate startDate, + LocalDate endDate, int startSlot, int endSlot, int i) { + String updateSql = "UPDATE booking_calendar SET morning_slot = ?, evening_slot = ?, booking_id_1 = ?, booking_id_2 = ?, is_booked = is_booked + ? WHERE bdate = ? AND hall_id = ?"; + boolean isMorning = true; + boolean isEvening = true; + int increment = 2; + jdbcTemplate.update(updateSql, isMorning, isEvening, bookingId, bookingId, increment, date, hallId); + } + + private void insertCalendarWithBooking(LocalDate date, int bookingId, int hallId, LocalDate startDate, + LocalDate endDate, int startSlot, int endSlot, int i) { + String uniqueId = date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId; + String insertSql = "INSERT INTO booking_calendar (bdate, hall_id, is_active, is_booked, is_delete, morning_slot, evening_slot, booking_id_1, booking_id_2, is_blocked, unique_id) VALUES (?, ?, true, ?, false, ?, ?, ?, ?, false, ?)"; + jdbcTemplate.update(insertSql, date, hallId, 2, true, true, bookingId, bookingId, uniqueId); + } + + private String fetchReasonCode(String reason) { + try { + String sql = "SELECT reasoncode FROM reason_master WHERE reason = ?"; + return jdbcTemplate.queryForObject(sql, String.class, reason); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + + private String sendConfirmationMessages(int bookingId, Map booking) { + System.out.println("confirmation message calling.."); + try { + String bookingconfirmationmsg, urlString, whatsupmsg; + String reason = booking.get("reason").toString(); + String reasonCode = fetchReasonCode(reason); + String bookingDate = booking.get("booking_date").toString(); + String startDate = booking.get("start_date").toString(); + + int userId = Integer.parseInt(booking.get("users_user_id").toString()); + + Map userData = jdbcTemplate.queryForMap("SELECT * FROM users WHERE user_id = ? ", userId); + String userMobNo = userData.get("mobile_no").toString(); + + if (reasonCode != null && !reasonCode.trim().isEmpty()) { + if (reasonCode.equals("CGE") || reasonCode.equals("CAO") || reasonCode.equals("SGE")) { + + updateBookingStatus(bookingId, "WAITING_FOR_NOC", "Waiting For NOC Documents"); + + bookingconfirmationmsg = "Your booking ID " + bookingId + " on " + bookingDate + + " has been confirmed successfully. Thanks for using GCC Community Hall Booking System."; + + urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + userMobNo + + "&from=GCCCRP&body=" + bookingconfirmationmsg + + "&entityid=1401572690000011081&templateid=1407172346459428987"; + + whatsupmsg = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + +userMobNo + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+booking+with+ID+" + +bookingId + "+on+" + bookingDate+ "+has+been+successfully+confirmed.+%0AThanks+for+using+GCC+Community+Hall+Booking+System."; + + whatsappMsgServiceImpl.sendMsg(whatsupmsg); + whatsappMsgServiceImpl.sendSMS(urlString); + return "Waiting For NOC Documents"; + + } else { + updateBookingStatus(bookingId, "APPROVED", "Booking Confirmed Successfully"); + + bookingconfirmationmsg = "Your booking ID " + bookingId + " on " + startDate + + " has been confirmed successfully. Thanks for using GCC Community Hall Booking System."; + + urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + userMobNo + + "&from=GCCCRP&body=" + bookingconfirmationmsg + + "&entityid=1401572690000011081&templateid=1407172346459428987"; + + whatsupmsg = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + + + userMobNo + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+booking+with+ID+" + + + bookingId + "+on+" + startDate + + "+has+been+successfully+confirmed.+%0AThanks+for+using+GCC+Community+Hall+Booking+System."; + + whatsappMsgServiceImpl.sendMsg(whatsupmsg); + whatsappMsgServiceImpl.sendSMS(urlString); + return "Booking confirmed successfully"; + } + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + return "Incorrect booking data"; + } + + /* + * public String refundTheAmount(int bookingId, int userId) { + * try { + * + * // get mobile no using userId --> need to add + * Map txn = jdbcTemplate. + * queryForMap("SELECT * FROM transaction_response WHERE booking_id = ? AND status_code = ? ORDER BY id DESC LIMIT 1" + * , bookingId, paymentConfig.getTransactionSuccessCode()); + * String amount = (String) txn.get("amount"); + * String txnDate = ((String) txn.get("date")).split(" ")[0]; + * String tpslTxnId = (String) txn.get("tpsl_txn_id"); + * + * TransactionData payload = new TransactionData(); + * payload.getMerchant().setIdentifier(paymentConfig.getMerchantId()); + * payload.getTransaction().setAmount(amount); + * payload.getTransaction().setIdentifier(""); + * payload.getTransaction().setDateTime(txnDate); + * payload.getTransaction().setRequestType("R"); + * payload.getTransaction().setToken(""); + * payload.getTransaction().setReference(tpslTxnId); + * + * String json = objectMapper.writeValueAsString(payload); + * String encrypted = encryptionUtils.encryptHxRefund(json); + * + * String url = "https://www.tpsl-india.in/PaymentGateway/merchant2.pg/" + + * paymentConfig.getMerchantId(); + * ResponseEntity response = new RestTemplate().postForEntity(url, + * encrypted, String.class); + * String decrypted = encryptionUtils.decryptHxTRefund(response.getBody()); + * + * TransactionRefundResponse refundRes = objectMapper.readValue(decrypted, + * TransactionRefundResponse.class); + * String refundStatusCode = + * refundRes.getPaymentMethod().getPaymentTransaction().getStatusCode(); + * String refundTxnId = refundRes.getMerchantTransactionIdentifier(); + * String refundIdentifier = + * refundRes.getPaymentMethod().getPaymentTransaction().getRefundIdentifier(); + * String refundedAmount = + * refundRes.getPaymentMethod().getPaymentTransaction().getAmount(); + * String balanceAmount = + * refundRes.getPaymentMethod().getPaymentTransaction().getBalanceAmount(); + * + * jdbcTemplate. + * update("INSERT INTO refund_response (booking_id, user_id, response, status_code, txansaction_id, amount, balace_amount, date) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" + * , bookingId, userId, decrypted, refundStatusCode, refundTxnId, + * refundedAmount, balanceAmount, LocalDate.now()); + * + * Map booking = + * jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?" + * , bookingId); + * + * jdbcTemplate. + * update("INSERT INTO refund_transaction (amount_refunded, cdate, booking_details_booking_id, refund_identifier, refund_status, transaction_id) VALUES (?, ?, ?, ?, ?, ?)" + * , Double.parseDouble(refundedAmount), new Date(), bookingId, + * refundIdentifier, refundStatusCode, refundTxnId); + * + * if (refundStatusCode.equals(paymentConfig.getRefundSuccessCode())) { + * jdbcTemplate. + * update("UPDATE booking_details SET refund_status = 'COMPLETED' WHERE booking_id = ?" + * , bookingId); + * + * long mobile = (long) booking.get("users_user_id"); + * double amt = Double.parseDouble(refundedAmount); + * whatsappMsgServiceImpl.sendSMS(buildSMSUrl(mobile, amt, bookingId)); + * whatsappMsgServiceImpl.sendMsg(buildWhatsAppUrl(mobile, amt, bookingId)); + * return "Refunded"; + * } + * + * return "Error"; + * } catch (Exception e) { + * e.printStackTrace(); + * return "error"; + * } + * } + */ + + private String buildSMSUrl(long mobile, double amt, int bookingId) { + return "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + mobile + + "&from=GCCCRP&body=Your refund amount of Rs. " + amt + " for Booking ID " + bookingId + + " has been initiated."; + } + + private String buildWhatsAppUrl(long mobile, double amt, int bookingId) { + return "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + mobile + + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+refund+of+Rs.+" + amt + + "+for+Booking+ID+" + bookingId + "+has+been+initiated."; + } + + public void updateBookingStatus(int bookingId, String bookingStatus, String comments) { + String updateSql = "update booking_details set booking_status =?, comments= ? WHERE booking_id = ?"; + jdbcTemplate.update(updateSql, bookingStatus, comments, bookingId); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/service/ReportService.java b/src/main/java/com/gcc/restapiservices/communityHall/service/ReportService.java new file mode 100644 index 0000000..80d0896 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/service/ReportService.java @@ -0,0 +1,162 @@ +package com.gcc.restapiservices.communityHall.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.stream.Collectors; + +@Service +public class ReportService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlCommunityHallliveDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + // Zone-wise booking data from date to date + public List> getZoneWiseBookingData(String fromDate, String toDate) { + String sql = "SELECT hd.zone, " + + "COUNT(DISTINCT hd.hall_id) AS hall_count, " + + "SUM(CASE WHEN bd.booking_type = 'ONLINE' AND bd.counter_id IS NULL THEN 1 ELSE 0 END) AS online_bookings, " + + "SUM(CASE WHEN bd.booking_type = 'ONLINE' AND bd.counter_id IS NOT NULL THEN 1 ELSE 0 END) AS counter_bookings, " + + "COUNT(bd.booking_id) AS total_bookings " + + "FROM hall_details hd " + + "LEFT JOIN booking_details bd ON hd.hall_id = bd.hall_details_hall_id " + + "AND DATE(bd.booking_date) BETWEEN ? AND ? " + + "AND bd.booking_status NOT IN ('PENDING','GCC_UNBLOCKED','REFUNDED','GCC_BLOCKED') " + + "AND bd.booking_type IS NOT NULL " + + "GROUP BY hd.zone " + + "ORDER BY hd.zone"; + + List> result = jdbcTemplate.queryForList(sql, fromDate, toDate); + + // Transform to the desired JSON format + List> jsonResult = new ArrayList<>(); + + for (Map row : result) { + Map zoneData = new HashMap<>(); + zoneData.put("Zone", row.get("zone")); + zoneData.put("Hall Count", row.get("hall_count")); + zoneData.put("Online Bookings", row.get("online_bookings")); + zoneData.put("Counter Bookings", row.get("counter_bookings")); + zoneData.put("Total Bookings", row.get("total_bookings")); + + jsonResult.add(zoneData); + } + + return jsonResult; + } + + // Helper method to get zone labels + private String getZoneLabel(String zoneNumber) { + switch (zoneNumber) { + case "01": return "Zone 1 - Tondiarpet"; + case "02": return "Zone 2 - Royapuram"; + case "03": return "Zone 3 - Thiru Vi Ka Nagar"; + case "04": return "Zone 4 - Ambattur"; + case "05": return "Zone 5 - Anna Nagar"; + case "06": return "Zone 6 - Teynampet"; + case "07": return "Zone 7 - Kodambakkam"; + case "08": return "Zone 8 - Valasaravakkam"; + case "09": return "Zone 9 - Alandur"; + case "10": return "Zone 10 - Adyar"; + case "11": return "Zone 11 - Perungudi"; + case "12": return "Zone 12 - Sholinganallur"; + case "13": return "Zone 13 - Thiruvottiyur"; + case "14": return "Zone 14 - Manali"; + case "15": return "Zone 15 - Madhavaram"; + default: return "Zone " + zoneNumber; + } + } + + // From date to date zone for hall details + public List> getHallDetailsByZoneAndDate(String fromDate, String toDate, String zone) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT hd.hall_id, hd.hall_name, "); + sql.append("SUM(CASE WHEN bd.booking_type = 'ONLINE' AND bd.counter_id IS NULL THEN 1 ELSE 0 END) AS online_bookings, "); + sql.append("SUM(CASE WHEN bd.booking_type = 'ONLINE' AND bd.counter_id IS NOT NULL THEN 1 ELSE 0 END) AS counter_bookings, "); + sql.append("COUNT(bd.booking_id) AS total_bookings "); + sql.append("FROM hall_details hd "); + sql.append("LEFT JOIN booking_details bd ON hd.hall_id = bd.hall_details_hall_id "); + sql.append("AND DATE(bd.booking_date) BETWEEN ? AND ? "); + sql.append("AND bd.booking_status NOT IN ('PENDING','GCC_UNBLOCKED','REFUNDED','GCC_BLOCKED') " + + "AND bd.booking_type IS NOT NULL "); + sql.append("WHERE hd.zone = ? "); + sql.append("GROUP BY hd.hall_id, hd.hall_name "); + sql.append("ORDER BY hd.hall_name"); + + List> result = jdbcTemplate.queryForList(sql.toString(), fromDate, toDate, zone); + + // Transform to the desired JSON format with only requested fields + List> jsonResult = new ArrayList<>(); + + for (Map row : result) { + Map hallData = new HashMap<>(); + hallData.put("Hall Name", row.get("hall_name")); + hallData.put("Hall ID", row.get("hall_id")); + hallData.put("Online Booking Count", row.get("online_bookings")); + hallData.put("Counter Booking Count", row.get("counter_bookings")); + hallData.put("Total Count", row.get("total_bookings")); + + jsonResult.add(hallData); + } + + return jsonResult; + } + + // From date to date zone hall ID specific data + public List> getHallSpecificData(String fromDate, String toDate, String zone, Integer hallId) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT "); + sql.append("bd.counter_id, bd.hall_details_hall_id, "); + sql.append("COUNT(bd.booking_id) AS booking_count "); + sql.append("FROM booking_details bd "); + sql.append("INNER JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id "); + sql.append("WHERE DATE(bd.booking_date) BETWEEN ? AND ? "); + sql.append("AND bd.booking_status NOT IN ('PENDING','GCC_UNBLOCKED','REFUNDED','GCC_BLOCKED') "); + sql.append("AND bd.booking_type IS NOT NULL "); + sql.append("AND bd.counter_id IS NOT NULL "); + + List params = new ArrayList<>(); + params.add(fromDate); + params.add(toDate); + + if (zone != null && !zone.trim().isEmpty()) { + sql.append("AND hd.zone = ? "); + params.add(zone); + } + + if (hallId != null) { + sql.append("AND hd.hall_id = ? "); + params.add(hallId); + } + + sql.append("GROUP BY bd.counter_id, bd.hall_details_hall_id "); + sql.append("ORDER BY bd.counter_id"); + + List> result = jdbcTemplate.queryForList(sql.toString(), params.toArray()); + + // Transform to the desired JSON format + List> jsonResult = new ArrayList<>(); + + for (Map row : result) { + Map counterData = new HashMap<>(); + counterData.put("Counter ID", row.get("counter_id")); + counterData.put("Hall ID", row.get("hall_details_hall_id")); + counterData.put("Booking Count", row.get("booking_count")); + + jsonResult.add(counterData); + } + + return jsonResult; + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/service/WhatsappMsgServiceImpl.java b/src/main/java/com/gcc/restapiservices/communityHall/service/WhatsappMsgServiceImpl.java new file mode 100644 index 0000000..95096fc --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/service/WhatsappMsgServiceImpl.java @@ -0,0 +1,41 @@ +package com.gcc.restapiservices.communityHall.service; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.net.HttpURLConnection; +import java.net.URL; + +@Service +public class WhatsappMsgServiceImpl { + + public String sendMsg(String msgUrl) { + System.out.println("Whatsapp URL :-" + msgUrl); + + String response = ""; + try { + HttpURLConnection connection = null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public String sendSMS(String SMS_Url) { + System.out.println("SMS URL:- " + SMS_Url); + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(SMS_Url, String.class); + return response; + } +} + diff --git a/src/main/java/com/gcc/restapiservices/communityHall/service/communityHallService.java b/src/main/java/com/gcc/restapiservices/communityHall/service/communityHallService.java new file mode 100644 index 0000000..a7d5ba8 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/service/communityHallService.java @@ -0,0 +1,864 @@ + +package com.gcc.restapiservices.communityHall.service; + +import com.gcc.restapiservices.communityHall.configuration.PaymentConfig; +import com.gcc.restapiservices.communityHall.util.TransactionNumberGenerator; +import com.gcc.restapiservices.configuration.AppConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +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.web.bind.annotation.RequestParam; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Random; + +import com.gcc.restapiservices.configuration.AppConfig; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + +@Service + +public class communityHallService { + private JdbcTemplate jdbcTemplate; + @Autowired + private AppConfig appConfig; + @Autowired + private Environment environment; + + @Autowired + private PaymentConfig paymentConfig; + + @Autowired + private TransactionNumberGenerator transactionNumberGenerator; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Value("${file.upload.directory.communityhall}") + private String uploadDirectory; + + @Value("${file.fullpath.communityhall}") + private String serverPath; + + @Autowired + public void setDataSource(@Qualifier("mysqlCommunityHallDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + public List> getHallList() { + return jdbcTemplate.queryForList("SELECT * FROM hall_details WHERE is_active = 1 order by hall_name asc"); + } + + public List> getReasonMaster() { + String sql = "SELECT reason_id,reason,maxdays,reasoncode FROM reason_master"; + return jdbcTemplate.queryForList(sql); + } + + public List> getDocumentsByReasonId(Long reasonId) { + String sql = "SELECT doc_field_name,field_name FROM reason_document_master WHERE reason_id = ?"; + return jdbcTemplate.queryForList(sql, reasonId); + } + + public List> getRelationTypesAsMap() { + List> relationList = new ArrayList<>(); + + String[] relations = {"Self", "Son", "Daughter", "Granddaughter", "Grandson", "Brother", "Sister"}; + + for (String rel : relations) { + Map map = new HashMap<>(); + map.put("relation_name", rel); + map.put("value", rel); + relationList.add(map); + } + + return relationList; + } + + public List> getUserDetails(Long Mobilenumber) { + String sql = "SELECT name,email,mobile_no,doorno,area,location,pin_code,user_status,usertype,profilephoto FROM users WHERE mobile_no = ?"; + return jdbcTemplate.queryForList(sql, Mobilenumber); + } + + public Map getHallDetailsById(int hallId) { + String sql = "SELECT * FROM hall_details WHERE hall_id = ?"; + List> result = jdbcTemplate.queryForList(sql, hallId); + + if (result.isEmpty()) { + return null; // or Collections.emptyMap() if you prefer + } + + return result.get(0); + } + + public Map getHallConcessionByHallId(int hallId) { + String sql = "SELECT * FROM hall_details_concession WHERE hall_id = ?"; + List> result = jdbcTemplate.queryForList(sql, hallId); + + if (result.isEmpty()) { + return null; // or Collections.emptyMap() + } + + return result.get(0); // ✅ safe return of first result + } + + public List> checkMobileExits(Long Mobilenumber) { + String sql = "SELECT * FROM users WHERE mobile_no = ?"; + return jdbcTemplate.queryForList(sql, Mobilenumber); + } + + public List> checkEmployeeExits(String EmployeeID) { + String sql = "SELECT * FROM users WHERE government_id= ?"; + return jdbcTemplate.queryForList(sql, EmployeeID); + } + + /* + * public Map getBookingDetailsById(int bookingId) { String sql + * = "SELECT " + + * "bd.booking_id, bd.booking_date, bd.start_date, bd.end_date, bd.comments, bd.booking_status, " + * + + * "bd.starting_slot, bd.ending_slot, bd.no_of_days, bd.reason, bd.gst, bd.deposit_amount, " + * + "bd.hall_amount, bd.amount_received AS booking_amount_received, " + + * "u.name, u.usertype, u.mobile_no, u.email, " + + * "hd.zone, hd.division, hd.hall_incharge_name, hd.hall_incharge_no, hd.hall_name, " + * + "CONCAT_WS(', ', hd.street, hd.area, hd.pin_code) AS address, " + + * "p.transaction_id, p.payment_status, p.amount_received AS payment_amount_received " + * + "FROM booking_details bd " + + * "INNER JOIN users u ON bd.users_user_id = u.user_id " + + * "INNER JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + + * "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + + * "WHERE bd.booking_id = ?"; + * + * return jdbcTemplate.queryForMap(sql, bookingId); } + */ + public Map getBookingDetailsById(int bookingId) { + String sql = "SELECT " + + "bd.booking_id, DATE_FORMAT(bd.booking_date, '%d-%m-%Y') AS booking_date, " + + " DATE_FORMAT(bd.start_date, '%d-%m-%Y') AS start_date, " + + " DATE_FORMAT(bd.end_date, '%d-%m-%Y') AS end_date, " + + " bd.comments, bd.booking_status, " + + "bd.starting_slot, bd.ending_slot, bd.no_of_days, bd.reason, bd.gst, bd.deposit_amount, " + + "bd.hall_amount, bd.amount_received AS total_amount, " + "u.name, u.usertype, u.mobile_no, u.email, " + + "hd.zone, hd.division, hd.hall_incharge_name as caretaker_name, hd.hall_incharge_no as caretaker_mobileno, hd.hall_name, " + + "CONCAT_WS(', ', hd.street, hd.area, hd.pin_code) AS hall_address, " + + "p.transaction_id, p.payment_status, p.amount_received AS payment_amount_received " + + "FROM booking_details bd " + "INNER JOIN users u ON bd.users_user_id = u.user_id " + + "INNER JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + + "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + "WHERE bd.booking_id = ?"; + + Map result = jdbcTemplate.queryForMap(sql, bookingId); + + // Add the acknowledgement URL to the result + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + bookingId; + result.put("acknowledgement_url", acknowledgementUrl); + + return result; + } + + // pdf + + /* + * public List> getBookingsByMobile(Long mobileNumber) { + * String sql = + * "SELECT bd.booking_id, bd.booking_date, bd.start_date, bd.end_date, " + + * "bd.starting_slot, bd.ending_slot, bd.reason, bd.booking_status, " + + * "p.payment_status AS payment_status " + + * "FROM testcommunityhall.booking_details bd " + + * "INNER JOIN testcommunityhall.users u ON bd.users_user_id = u.user_id " + + * "INNER JOIN testcommunityhall.payments p ON bd.booking_id = p.booking_details_booking_id " + * + "WHERE u.mobile_no = ? " + "AND bd.booking_status NOT IN ('PENDING')"; + * + * return jdbcTemplate.queryForList(sql, mobileNumber); } + */ + public List> getBookingsByMobile(Long mobileNumber) { + String sql = "SELECT bd.booking_id , DATE_FORMAT(bd.booking_date, '%d-%m-%Y') AS booking_date," + + " DATE_FORMAT(bd.start_date, '%d-%m-%Y') AS start_date," + + " DATE_FORMAT(bd.end_date, '%d-%m-%Y') AS end_date, " + + "bd.starting_slot, bd.ending_slot, bd.reason, bd.booking_status, " + + "p.payment_status AS payment_status " + "FROM booking_details bd " + + "INNER JOIN users u ON bd.users_user_id = u.user_id " + + "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + + "WHERE u.mobile_no = ? " + "AND bd.booking_status NOT IN ('PENDING')"; + + List> bookings = jdbcTemplate.queryForList(sql, mobileNumber); + + // Add acknowledgement URL to each booking + for (Map booking : bookings) { + Object bookingId = booking.get("booking_id"); + if (bookingId != null) { + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + + bookingId; + booking.put("acknowledgement_url", acknowledgementUrl); + } + } + + return bookings; + } + + public List> checkPenionerExits(String PensionerID) { + String sql = "SELECT * FROM users WHERE government_id= ?"; + return jdbcTemplate.queryForList(sql, PensionerID); + } + + // + public List> findCounsellorByMobile(long mobileNo) { + String sql = "SELECT * FROM counsellor_details WHERE mobile1 = ? OR mobile2 = ?"; + return jdbcTemplate.queryForList(sql, mobileNo, mobileNo); + } + + public void registerUser(String userType, String name, long mobileNumber, String aadharNumber, + MultipartFile profilePhoto, String emailId, String doorNo, String street, String area, String location, + String pincode, String pensionerID, String pensionerDepartment, String employeeID, + String employeeDepartment) throws IOException { + + String uploadPhotoUrl = null; + if (profilePhoto != null && !profilePhoto.isEmpty()) { + uploadPhotoUrl = saveFile(profilePhoto); + } + + // Default values for government_id and department + String governmentId = null; + String department = null; + + String userstatus = "APPROVED"; + + // Logic for conditional insertion based on userType + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + + governmentId = pensionerID; + department = pensionerDepartment; + userstatus = "PENDING"; + } else if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + governmentId = employeeID; + department = employeeDepartment; + userstatus = "PENDING"; + } + + String sql = "INSERT INTO users (usertype, name, mobile_no, aadhar_number, profilephoto, email, " + + "doorno, street, area, location, pin_code, government_id, department,user_status) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)"; + + jdbcTemplate.update(sql, userType, name, mobileNumber, aadharNumber, uploadPhotoUrl, emailId, doorNo, street, + area, location, pincode, governmentId, department, userstatus); + } + + public String saveFile(MultipartFile file) throws IOException { + String order_copy_url = ""; + + // Handle file upload if a file is provided + if (file == null || file.isEmpty()) { + return order_copy_url; + } + + // Get the base upload directory from properties + String uploadDirectory = environment.getProperty("file.upload.directory"); // e.g., /opt/myapp/uploads + + // Define the subdirectory structure + String serviceFolderName = "images/userPhoto"; // You can also get from properties if needed + + // Build the full folder path + String fullUploadPath = uploadDirectory + File.separator + serviceFolderName; + Path directoryPath = Paths.get(fullUploadPath); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Generate unique file name + // String datetimetxt = DateTimeUtil.getCurrentDateTime(); + String fileName = generateRandomStringForFile(10) + "_" + file.getOriginalFilename(); + + // Physical file path + Path filePath = directoryPath.resolve(fileName); + + // Write the file to the physical path + Files.write(filePath, file.getBytes()); + + // Relative path for storing in DB + String filepath_txt = "/" + serviceFolderName + "/" + fileName; + + return filepath_txt; + } + + public static String generateRandomStringForFile(int String_Lenth) { + StringBuilder result = new StringBuilder(String_Lenth); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + + } + + @Transactional("mysqlCommunityHallTransactionManager") + public Map saveBookingDetails(Map formData) { + Map hs = new HashMap<>(); + + Map userMaster = jdbcTemplate.queryForMap("SELECT * FROM users WHERE mobile_no = ?", + (formData.get("mobNo").toString())); + + Integer userId = (Integer) userMaster.get("user_id"); + + Map reasonMaster = jdbcTemplate.queryForMap("SELECT * FROM reason_master WHERE reason_id = ?", + Integer.parseInt(formData.get("reasonId").toString())); + + Map hallDetails = jdbcTemplate.queryForMap("SELECT * FROM hall_details WHERE hall_id = ?", + Integer.parseInt(formData.get("hallId").toString())); + + // Fetch User + Map user = jdbcTemplate.queryForMap("SELECT * FROM users WHERE user_id = ?", userId); + + String bookingId = formData.get("bookingId").toString(); + Map bookingDetails = null; + + if (bookingId != null && bookingId.equals("0")) { + } else { + List> bookings = jdbcTemplate + .queryForList("SELECT * FROM booking_details WHERE booking_id = ?", Integer.parseInt(bookingId)); + if (!bookings.isEmpty()) { + bookingDetails = bookings.get(0); + jdbcTemplate.update("DELETE FROM booking_documents WHERE booking_id = ?", Integer.parseInt(bookingId)); + } + } + + if (user != null) { + String startDate = formData.get("startDate").toString(); + String endDate = formData.get("endDate").toString(); + String relation = formData.get("relation").toString(); + double days = Double.parseDouble(formData.get("days").toString()); + int daysrange = Integer.parseInt(formData.get("daysrange").toString()); + String usertype = user.get("usertype").toString(); + String reason = reasonMaster.get("reason").toString(); + int startingSlot = Integer.parseInt(formData.get("startingSlot").toString()); + int endingSlot = Integer.parseInt(formData.get("endingSlot").toString()); + String startingSlot_txt = formData.get("startingSlot").toString(); + String endingSlot_txt = formData.get("endingSlot").toString(); + + Map discountrange = jdbcTemplate + .queryForMap("SELECT * FROM discount_range WHERE usertype = ?", usertype); + float discount = Float.parseFloat(discountrange.get("discount_range").toString()); + + double hallAmount = calcHallAmountJdbc(hallDetails, daysrange, startingSlot, endingSlot); + hs.put("actualhallamount", hallAmount); + + double depositeamount = Double.parseDouble(hallDetails.get("deposit_amount").toString()); + double halfDepositAmount = Double.parseDouble(hallDetails.get("half_deposit_amount").toString()); + double Totaldepositeamount = calculateDepositAmountJdbc(daysrange, startingSlot_txt, endingSlot_txt, + depositeamount, halfDepositAmount); + depositeamount = Totaldepositeamount; + + double discountAmount = 0; + double gstAmount = 0.00; + String reasoncode = reasonMaster.get("reasoncode") != null ? reasonMaster.get("reasoncode").toString() : ""; + hs.put("reasoncode", reasoncode); + + /*Map governmentevents = jdbcTemplate.queryForMap( + "SELECT * FROM hall_details_concession WHERE hall_id = ?", + Integer.parseInt(hallDetails.get("hall_id").toString()));*/ + + List> rows = jdbcTemplate.queryForList( + "SELECT * FROM hall_details_concession WHERE hall_id = ?", + Integer.parseInt(hallDetails.get("hall_id").toString()) + ); + + Map governmentevents = rows.isEmpty() + ? Collections.emptyMap() // or null, your call + : rows.get(0); + + if (reasoncode.equals("SGE")) { + if (startingSlot == 1 && endingSlot == 2) { + discountAmount = (Double.parseDouble(governmentevents.get("fulldayhallamount").toString()) + * Double.parseDouble(hallDetails.get("sgediscount").toString())) / 100; + hallAmount = Double.parseDouble(governmentevents.get("fulldayhallamount").toString()); + hs.put("discount", hallDetails.get("sgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("full_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("fulldaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("fulldayebcharges").toString()); + double additionalcharges = cleaningCharges + PASystem + EB; + gstAmount = Math.round(additionalcharges * Double.parseDouble(hallDetails.get("gst").toString())) + / 100.0; + double depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + double totalAmount = additionalcharges + gstAmount + depositAmount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, additionalcharges, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } else { + hallAmount = Double.parseDouble(governmentevents.get("halfdayhallamount").toString()); + discountAmount = (hallAmount * Double.parseDouble(hallDetails.get("sgediscount").toString())) / 100; + hs.put("discount", hallDetails.get("sgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("halfdaycleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("halfdaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("halfdayebcharges").toString()); + double additionalcharges = cleaningCharges + PASystem + EB; + gstAmount = Math.round(additionalcharges * Double.parseDouble(hallDetails.get("gst").toString())) + / 100.0; + double depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + double totalAmount = additionalcharges + gstAmount + depositAmount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, additionalcharges, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } else if (reasoncode.equals("CGE")) { + double rentAmount, netAmount, depositAmount, totalAmount, truncatedTotalAmount, additionalcharges; + if (startingSlot == 1 && endingSlot == 2) { + discountAmount = (Double.parseDouble(hallDetails.get("full_day_rent").toString()) + * Double.parseDouble(hallDetails.get("cgediscount").toString())) / 100; + hallAmount = Double.parseDouble(hallDetails.get("full_day_rent").toString()); + hs.put("discount", hallDetails.get("cgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("full_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("fulldaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("fulldayebcharges").toString()); + additionalcharges = cleaningCharges + PASystem + EB; + rentAmount = hallAmount - discountAmount; + netAmount = rentAmount + additionalcharges; + gstAmount = Math.round(netAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + totalAmount = netAmount + gstAmount + depositAmount; + truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("rentAmount", rentAmount); + hs.put("gstAmount", gstAmount); + hs.put("netAmount", netAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, netAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } else { + discountAmount = (Double.parseDouble(hallDetails.get("half_day_rent").toString()) + * Double.parseDouble(hallDetails.get("cge_discount").toString())) / 100; + hallAmount = Double.parseDouble(hallDetails.get("half_day_rent").toString()); + hs.put("discount", hallDetails.get("cgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("half_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("halfdaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("halfdayebcharges").toString()); + additionalcharges = cleaningCharges + PASystem + EB; + rentAmount = hallAmount - discountAmount; + netAmount = rentAmount + additionalcharges; + gstAmount = Math.round(netAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + totalAmount = netAmount + gstAmount + depositAmount; + truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("rentAmount", rentAmount); + hs.put("gstAmount", gstAmount); + hs.put("netAmount", netAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, netAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } else { + + if (usertype.equals("COUNCILLOR") || usertype.equals("PENSIONER") || usertype.equals("GCC_EMPLOYEE") + || usertype.equals("PUBLIC")) { + discountAmount = (hallAmount * discount) / 100; + hallAmount = hallAmount - discountAmount; + gstAmount = Math.round(hallAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + double totalAmount = hallAmount + gstAmount + depositeamount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, hallAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } + + System.out.println("bookingId...." + bookingId); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate start = LocalDate.parse(startDate, formatter); + LocalDate end = LocalDate.parse(endDate, formatter); + int hallId = Integer.parseInt(hallDetails.get("hall_id").toString()); + int i = 0; + for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) { + Map bookingCalendar = null; + List> calList = jdbcTemplate.queryForList( + "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?", date.toString(), hallId); + if (!calList.isEmpty()) + bookingCalendar = calList.get(0); + + if (bookingCalendar != null) { + boolean morningSlot = Boolean.TRUE.equals(bookingCalendar.get("morning_slot")); + boolean eveningSlot = Boolean.TRUE.equals(bookingCalendar.get("evening_slot")); + if ((date.equals(start) && startingSlot == 1 && morningSlot) + || (date.equals(start) && startingSlot == 2 && eveningSlot) + || (date.equals(end) && endingSlot == 1 && morningSlot) + || (date.equals(end) && endingSlot == 2 && eveningSlot)) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (morningSlot && eveningSlot) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (!date.equals(end) && i != 0 && i != Math.round(days - 1) + && (morningSlot || eveningSlot)) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (date.equals(end) && endingSlot == 2 && morningSlot && i != 0 + && i == Math.round(days - 1)) { + return Collections.singletonMap("status", "slotOccupied"); + } + } + i++; + } + + List> reasonDocMaster = jdbcTemplate.queryForList( + "SELECT * FROM reason_document_master WHERE reason_id = ?", + Integer.parseInt(formData.get("reasonId").toString())); + List> uploadedDocs = new ArrayList<>(); + for (Map rm : reasonDocMaster) { + Map docMap = new HashMap<>(); + String fieldName = ""; + String value = ""; + String fileName = ""; + String fileUrl = ""; + String filePath = ""; + if (Boolean.TRUE.equals(rm.get("add_text_field"))) { + fieldName = rm.get("field_name").toString(); + value = formData.get(fieldName).toString(); + jdbcTemplate.update( + "INSERT INTO booking_documents (booking_details_booking_id, booking_label, name) VALUES (?, ?, ?)", + Integer.parseInt(bookingId), fieldName, value); + docMap.put("booking_label", fieldName); + docMap.put("name", value); + } + if (Boolean.TRUE.equals(rm.get("add_document_field"))) { + String docFieldName = rm.get("doc_field_name").toString(); + MultipartFile file = (MultipartFile) formData.get(docFieldName); + fileName = bookingId + "_" + file.getOriginalFilename(); + fileUrl = serverPath + "images/" + reason + "/" + fileName; + filePath = uploadDirectory + "/" + reason + "/" + fileName; + + // Create directory if it doesn't exist + File directory = new File(uploadDirectory + "/" + reason); + if (!directory.exists()) { + directory.mkdirs(); // Creates parent directories if needed + } + + docMap.put("documentName", file.getOriginalFilename()); + docMap.put("documentType", file.getContentType()); + docMap.put("bookingDocUrl", fileUrl); + + // Save file to disk + try (FileOutputStream fos = new FileOutputStream(filePath)) { + byte[] bytes = file.getBytes(); + fos.write(bytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + + jdbcTemplate.update( + "INSERT INTO booking_documents (booking_details_booking_id, booking_doc_url, document_name, document_type, booking_label, name) VALUES (?, ?, ?, ?, ?, ?)", + Integer.parseInt(bookingId), fileUrl, file.getOriginalFilename(), file.getContentType(), + fieldName, value); + } + uploadedDocs.add(docMap); + } + + hs.put("bookingId", bookingId); + hs.put("hallName", hallDetails.get("hall_name")); + hs.put("NoOfDay", days); + hs.put("startDate", startDate); + hs.put("endDate", endDate); + hs.put("startingSlot", startingSlot); + hs.put("endingSlot", endingSlot); + hs.put("hallAmount", hallAmount); + hs.put("gst", gstAmount); + hs.put("depositAmount", depositeamount); + hs.put("username", user.get("name")); + hs.put("userId", user.get("user_id")); + hs.put("mobileNo", user.get("mobile_no")); + hs.put("userType", user.get("usertype")); + hs.put("reason", reason); + hs.put("bookingId", bookingId); + hs.put("uploadedDocs", uploadedDocs); + } + + return hs; + } + + private double calcHallAmountJdbc(Map hallDetails, int daysrange, int startPeriod, int endPeriod) { + double fullDayRent = Double.parseDouble(hallDetails.get("full_day_rent").toString()); + double halfDayRent = Double.parseDouble(hallDetails.get("half_day_rent").toString()); + if (daysrange == 1) { + if (startPeriod == 1 && endPeriod == 2) + return fullDayRent; + else if (startPeriod == 1 && endPeriod == 1) + return halfDayRent; + else if (startPeriod == 2 && endPeriod == 2) + return halfDayRent; + else if (startPeriod == 2 && endPeriod == 1) + return fullDayRent; + } else { + if (startPeriod == 1 && endPeriod == 2) + return fullDayRent * daysrange; + else if (startPeriod == 1 && endPeriod == 1) + return fullDayRent * (daysrange - 1) + halfDayRent; + else if (startPeriod == 2 && endPeriod == 2) + return fullDayRent * (daysrange - 1) + halfDayRent; + else if (startPeriod == 2 && endPeriod == 1) + return fullDayRent * (daysrange - 2) + halfDayRent * 2; + } + return 0; + } + + private double calculateDepositAmountJdbc(double numDays, String startPeriod, String endPeriod, + double depositAmount, double HalfDepositAmount) { + double damount = 0; + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount; + else if ("1".equals(startPeriod) && "1".equals(endPeriod)) + damount = HalfDepositAmount; + else if ("2".equals(startPeriod) && "2".equals(endPeriod)) + damount = HalfDepositAmount; + else + damount = numDays; + } else { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount * numDays; + else if ("1".equals(startPeriod) && "1".equals(endPeriod)) + damount = depositAmount * (numDays - 1) + HalfDepositAmount; + else if ("2".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount * (numDays - 1) + HalfDepositAmount; + else if ("2".equals(startPeriod) && "1".equals(endPeriod)) + damount = depositAmount * (numDays - 2) + depositAmount; + else + damount = numDays; + } + return damount; + } + + private String insertOrUpdateBookingDetailsJdbc(JdbcTemplate jdbcTemplate, String bookingId, + Map user, Map hallDetails, String startDate, String endDate, double days, + int startingSlot, int endingSlot, double depositAmount, double hallAmount, double gst, double totalAmount, + String reason, String relation, String refundStatus, String comments, String bookingType) { + + if (bookingId == null || bookingId.equals("0")) { + // Insert with KeyHolder + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement( + "INSERT INTO booking_details (users_user_id, hall_details_hall_id, start_date, end_date, no_of_days, starting_slot, ending_slot, deposit_amount, hall_amount, gst, amount_received, reason, refund_status, comments, booking_type, relationship, booking_date, schedule_count, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + Statement.RETURN_GENERATED_KEYS); + ps.setObject(1, user.get("user_id")); + ps.setObject(2, hallDetails.get("hall_id")); + ps.setString(3, startDate); + ps.setString(4, endDate); + ps.setDouble(5, days); + ps.setInt(6, startingSlot); + ps.setInt(7, endingSlot); + ps.setDouble(8, depositAmount); + ps.setDouble(9, hallAmount); + ps.setDouble(10, gst); + ps.setDouble(11, totalAmount); + ps.setString(12, reason); + ps.setString(13, refundStatus); + ps.setString(14, comments); + ps.setString(15, bookingType); + ps.setString(16, relation); + ps.setString(17, java.time.LocalDate.now().toString()); + ps.setInt(18, 0); + ps.setInt(19, 2); + return ps; + }, keyHolder); + + Number generatedId = keyHolder.getKey(); + return generatedId != null ? generatedId.toString() : null; + } else { + // Update + jdbcTemplate.update( + "UPDATE booking_details SET users_user_id=?, hall_details_hall_id=?, start_date=?, end_date=?, no_of_days=?, starting_slot=?, ending_slot=?, deposit_amount=?, hall_amount=?, gst=?, amount_received=?, reason=?, refund_status=?, comments=?, booking_type=?, relationship=?, booking_date=?, schedule_count=? WHERE booking_id=?", + user.get("user_id"), hallDetails.get("hall_id"), startDate, endDate, days, startingSlot, endingSlot, + depositAmount, hallAmount, gst, totalAmount, reason, refundStatus, comments, bookingType, relation, + java.time.LocalDate.now().toString(), 0, Integer.parseInt(bookingId)); + return bookingId; + } + } + + public HashMap startPayment(int bookingId) { + HashMap hs = new HashMap<>(); + + String bookingSql = "SELECT b.amount_received, b.users_user_id, b.hall_details_hall_id, " + + " u.user_id, u.mobile_no, u.email " + " FROM booking_details b " + + " JOIN users u ON b.users_user_id = u.user_id " + " WHERE b.booking_id = ?"; + + try { + Map data = jdbcTemplate.queryForMap(bookingSql, bookingId); + + double amountReceived = (double) data.get("amount_received"); + int UserId = (int) data.get("user_id"); + long mobileNo = (long) data.get("mobile_no"); + String email = (String) data.get("email"); + int hallId = (int) data.get("hall_details_hall_id"); + + String txnId = "CHB" + transactionNumberGenerator.generateTransactionNumber() + + String.format("%05d", UserId); + + String totalAmt = String.valueOf(amountReceived); + + String insertSql = "INSERT INTO transaction_response (txansaction_id, hall_id, user_id, status_code, booking_id) " + + " VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertSql, txnId, hallId, String.valueOf(UserId), "temp", bookingId); + + String merchantId = paymentConfig.getMerchantId(); + String consumerId = String.format("%05d", UserId); + String encryptedToken = getToken(merchantId + "|", txnId + "|", totalAmt + "|", "|", consumerId + "|", + mobileNo + "|", email + "|", "|", "|", "|", "|", "|", "|", "|", "|", "|", + paymentConfig.getEncryptionKey()); + + hs.put("txansactionId", txnId); + hs.put("token", encryptedToken); + hs.put("amount", totalAmt); + /* + * hs.put("merchantId", merchantId); hs.put("consumerMobileNo", mobileNo); + * hs.put("consumerEmailId", email); hs.put("consumerId", consumerId); + * hs.put("error", false); + */ + + } catch (EmptyResultDataAccessException | NoSuchAlgorithmException e) { + hs.put("error", true); + hs.put("message", "Invalid booking ID or no user data found. "); + e.printStackTrace(); + } + + return hs; + } + + public String getToken(String merchantId, String txnId, String totalAmt, String accountNo, String consumerId, + String consumerMobileNo, String consumerEmailId, String debitStartDate, String debitEndDate, + String maxAmount, String amountType, String frequency, String cardNumber, String expMonth, String expYear, + String cvvCode, String salt) throws NoSuchAlgorithmException { + String token = merchantId + txnId + totalAmt + accountNo + consumerId + consumerMobileNo + consumerEmailId + + debitStartDate + debitEndDate + maxAmount + amountType + frequency + cardNumber + expMonth + expYear + + cvvCode + salt; + + return generateToken(token); + } + + public String generateToken(String token) throws NoSuchAlgorithmException { + // System.out.println("Token:-" + token); + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(token.getBytes()); + + byte[] bytes = md.digest(); + + BigInteger bigInt = new BigInteger(1, bytes); + String encryptedtoken = bigInt.toString(16); + + while (encryptedtoken.length() < 128) { + encryptedtoken = "0" + encryptedtoken; + } + // System.out.println("Encryption :- " + encryptedtoken); + return encryptedtoken; + } + + public Map checkSlotAvailability(int hallId, String startDate, String endDate, int startingSlot, int endingSlot) { + + // Validate slot numbers + if (startingSlot < 1 || startingSlot > 2 || endingSlot < 1 || endingSlot > 2) { + throw new IllegalArgumentException("Slot values must be 1 (morning) or 2 (evening)."); + } + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate start; + LocalDate end; + + try { + start = LocalDate.parse(startDate, formatter); + end = LocalDate.parse(endDate, formatter); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid date format. Use yyyy-MM-dd."); + } + + if (end.isBefore(start)) { + throw new IllegalArgumentException("End date cannot be before start date."); + } + + long days = java.time.temporal.ChronoUnit.DAYS.between(start, end) + 1; + int i = 0; + + try { + for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) { + + List> calList = jdbcTemplate.queryForList( + "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?", + date.toString(), hallId + ); + + if (!calList.isEmpty()) { + Map bookingCalendar = calList.get(0); + + boolean morningSlot = Boolean.TRUE.equals(bookingCalendar.get("morning_slot")); + boolean eveningSlot = Boolean.TRUE.equals(bookingCalendar.get("evening_slot")); + + if ((date.equals(start) && startingSlot == 1 && morningSlot) + || (date.equals(start) && startingSlot == 2 && eveningSlot) + || (date.equals(end) && endingSlot == 1 && morningSlot) + || (date.equals(end) && endingSlot == 2 && eveningSlot)) { + return Map.of("status", "slotOccupied"); + } else if (morningSlot && eveningSlot) { + return Map.of("status", "slotOccupied"); + } else if (!date.equals(end) && i != 0 && i != Math.round(days - 1) + && (morningSlot || eveningSlot)) { + return Map.of("status", "slotOccupied"); + } else if (date.equals(end) && endingSlot == 2 && morningSlot && i != 0 + && i == Math.round(days - 1)) { + return Map.of("status", "slotOccupied"); + } + } + i++; + } + } catch (DataAccessException e) { + e.printStackTrace(); + throw new RuntimeException("Database error occurred while checking slot availability."); + } + + return Map.of("status", "slotAvailable"); + } +} diff --git a/src/main/java/com/gcc/restapiservices/communityHall/util/EncryptionUtils.java b/src/main/java/com/gcc/restapiservices/communityHall/util/EncryptionUtils.java new file mode 100644 index 0000000..bd4be2b --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/util/EncryptionUtils.java @@ -0,0 +1,63 @@ +package com.gcc.restapiservices.communityHall.util; + +import com.gcc.restapiservices.communityHall.configuration.PaymentConfig; +import org.apache.commons.codec.binary.Hex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +@Component +public class EncryptionUtils { + + @Autowired + private PaymentConfig paymentConfig; + + public String encryptHxRefund(String text) throws Exception { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec keySpec = new SecretKeySpec(this.paymentConfig.getEncryptionKeyByte(), "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(this.paymentConfig.getEncryptionIVByte()); + cipher.init(1, keySpec, ivSpec); + byte[] results = cipher.doFinal(text.getBytes("UTF-8")); + String hxencstr = ToHexStrRefund(results); + return hxencstr; + } + + public String ToHexStrRefund(byte[] dataBuf) { + String hxstr = null; + Hex hx = new Hex(); + hxstr = new String(hx.encode(dataBuf)); + return hxstr; + } + + public String decryptHxTRefund(String hxstrr) throws Exception { + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + + SecretKeySpec keySpec = new SecretKeySpec(this.paymentConfig.getEncryptionKeyByte(), "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(this.paymentConfig.getEncryptionIVByte()); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + + byte[] decbytes = FromHexStr(hxstrr); + + byte[] results = cipher.doFinal(decbytes); + return new String(results, "UTF-8").trim(); + } + + public byte[] FromHexStr(String hxStr) { + byte[] charArray = hxStr.getBytes(); + byte[] bufstr = null; + Hex hxx = new Hex(); + + try { + bufstr = hxx.decode(charArray); + } catch (Exception e) { + e.printStackTrace(); + } + + return bufstr; + } +} + diff --git a/src/main/java/com/gcc/restapiservices/communityHall/util/TransactionNumberGenerator.java b/src/main/java/com/gcc/restapiservices/communityHall/util/TransactionNumberGenerator.java new file mode 100644 index 0000000..eaf7d50 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/communityHall/util/TransactionNumberGenerator.java @@ -0,0 +1,37 @@ +package com.gcc.restapiservices.communityHall.util; + +import org.springframework.stereotype.Service; + +import java.util.Random; + +@Service +public class TransactionNumberGenerator { + + public String generateTransactionNumber() { + // Define the length of the transaction number + int length = 12; + + // Define characters to be used in the transaction number + String characters = "0123456789"; + + // Create a StringBuilder to store the transaction number + StringBuilder sb = new StringBuilder(); + + // Create an instance of Random class + Random random = new Random(); + + // Generate the transaction number + for (int i = 0; i < length; i++) { + // Generate a random index within the range of characters + int randomIndex = random.nextInt(characters.length()); + + // Append the character at the random index to the transaction number + sb.append(characters.charAt(randomIndex)); + } + + + // Convert StringBuilder to String and return + return sb.toString(); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/configuration/AppConfig.java b/src/main/java/com/gcc/restapiservices/configuration/AppConfig.java new file mode 100644 index 0000000..206c623 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/configuration/AppConfig.java @@ -0,0 +1,64 @@ +package com.gcc.restapiservices.configuration; + + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + + +@Component +@ConfigurationProperties(prefix = "app") +public class AppConfig { + + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + private String title; + private String baseUrl; + private String getOtpUrl; + private String erpUrl; + + // @Value("${payment.razorpay.my_key_id}") private String keyId; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getGetOtpUrl() { + return getOtpUrl; + } + + public void setGetOtpUrl(String getOtpUrl) { + this.getOtpUrl = getOtpUrl; + } + + public String getErpUrl() { + return erpUrl; + } + + public void setErpUrl(String erpUrl) { + this.erpUrl = erpUrl; + } + + /* + * public String getKeyId() { return keyId; } + * + * public void setKeyId(String keyId) { this.keyId = keyId; } + */ +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/configuration/DataSourceConfig.java b/src/main/java/com/gcc/restapiservices/configuration/DataSourceConfig.java new file mode 100644 index 0000000..60c9ae1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/configuration/DataSourceConfig.java @@ -0,0 +1,201 @@ +package com.gcc.restapiservices.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.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.client.RestTemplate; + +@Configuration +@EnableTransactionManagement +public class DataSourceConfig { + + // live aws connection + private static final String awshost = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; + private static final String awspassword = "gcc-facial-password"; + + // local + // private static final String awshost = "localhost"; + // private static final String awspassword = "root"; + + @Bean(name = "mysqlCdWasteDataSource") + public DataSource mysqlCdWasteDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/gcc_c_d_waste_web"); + dataSource.setPassword(awspassword); + dataSource.setUsername("root"); + return dataSource; + } + + // @Bean(name = "mysqlCdWasteDataSource") + // public DataSource mysqlCdWasteDataSource() { + // DriverManagerDataSource dataSource = new DriverManagerDataSource(); + // dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + // dataSource.setUrl("jdbc:mysql://" + host + "/dumpwastecollector"); + // dataSource.setUsername("root"); + // dataSource.setPassword(dbpassword); + // return dataSource; + // } + + // local crs logs + // @Bean(name = "mysqlCrsLogsDataSource") + // public DataSource mysqlCrsLogsAwsDataSource() { + // DriverManagerDataSource dataSource = new DriverManagerDataSource(); + // dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + // dataSource.setUrl("jdbc:mysql://" + host + "/crs_logs"); + // dataSource.setUsername("root"); + // dataSource.setPassword(dbpassword); + // return dataSource; + // } + + // crs log from live yogi + + @Bean(name = "mysqlCrsLogsDataSource") + public DataSource mysqlCrsLogsAwsDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/crs_logs"); + dataSource.setPassword(awspassword); + dataSource.setUsername("root"); + + return dataSource; + } + + // feedback + @Bean(name = "mysqlFeedbackDataSource") + public DataSource mysqlFeedbackDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/feedback_service"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + // dataSource.setUrl("jdbc:mysql://" + host + "/feedback_service"); + // dataSource.setUsername("root"); + // dataSource.setPassword(dbpassword); + return dataSource; + } + + @Bean(name = "mysqlCommunityHallDataSource") + public DataSource mysqlCommunityHallDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/communityhall_live"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlCoworkspaceRestServicesDataSource") + public DataSource mysqlCoworkspaceRestServicesDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/coworkingspace"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + // Swimmingpool + @Bean(name = "mysqlSwimmingpoolDataSource") + public DataSource mysqlSwimmingpoolDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/swimmingpool"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlServicespdfDataSource") + public DataSource mysqlServicespdfDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/gcc_rest_services"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlVictoriaHallDataSource") + public DataSource mysqlVictoriaHallDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/victoriahallbooking_test"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlVictoriaHallTransactionManager") + public PlatformTransactionManager mysqlVictoriaHallTransactionManager( + @Qualifier("mysqlVictoriaHallDataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "mysqlCommunityHallTransactionManager") + public PlatformTransactionManager mysqlCommunityHallTransactionManager( + @Qualifier("mysqlCommunityHallDataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "coworkspaceTransactionManager") + public PlatformTransactionManager coworkspaceTransactionManager( + @Qualifier("mysqlCoworkspaceRestServicesDataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "mysqlGccRestServicesTransactionManager") + public PlatformTransactionManager mysqlGccRestServicesTransactionManager( + @Qualifier("mysqlGccRestServicesDataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "servicesPdfJdbcTemplate") + public JdbcTemplate servicesPdfJdbcTemplate(@Qualifier("mysqlServicespdfDataSource") DataSource dataSource) { + return new JdbcTemplate(dataSource); + } + + // @Bean(name = "PetRegistrationdJbcTemplate") + // public JdbcTemplate PetRegistrationdJbcTemplate(@Qualifier("mysqlPetRegistrationRestServicesDataSource") DataSource dataSource) { + // return new JdbcTemplate(dataSource); + // } + + @Bean(name = "mysqlCommunityHallliveDataSource") + public DataSource mysqlCommunityHallliveDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/communityhall_live"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlGccRestServicesDataSource") + public DataSource mysqlGccRestServicesDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/gcc_rest_services"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + + @Bean(name = "mysqlPetRegistrationRestServicesDataSource") + public DataSource mysqlPetRegistrationRestServicesDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + awshost + "/gcc_pets"); + dataSource.setUsername("root"); + dataSource.setPassword(awspassword); + return dataSource; + } + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/constants/AppConstants.java b/src/main/java/com/gcc/restapiservices/coworkspace/constants/AppConstants.java new file mode 100644 index 0000000..83498ab --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/constants/AppConstants.java @@ -0,0 +1,11 @@ +package com.gcc.restapiservices.coworkspace.constants; + +public final class AppConstants { +// public static String key_id="rzp_live_ySI5Ns54Y7qOcJ"; +// public static String key_secret="Nwf1TjhUtaskof8vePkRR8Sb"; + + + //uncomment for testing payment + public static String key_id="rzp_test_tDkHFEqWXmuEi8"; + public static String key_secret="cBQUjMcKZ4J6vmOKSyNZ92py"; +} diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/controller/ApiResponse.java b/src/main/java/com/gcc/restapiservices/coworkspace/controller/ApiResponse.java new file mode 100644 index 0000000..45207bb --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/controller/ApiResponse.java @@ -0,0 +1,49 @@ +package com.gcc.restapiservices.coworkspace.controller; + +public class ApiResponse { + private String status; + private String message; + private Object data; + private int statusCode; + + // Constructor + public ApiResponse(String status, String message, Object data, int statusCode) { + this.status = status; + this.message = message; + this.data = data; + this.statusCode = statusCode; + } + + // Getters and Setters + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/controller/CoworkspaceApiController.java b/src/main/java/com/gcc/restapiservices/coworkspace/controller/CoworkspaceApiController.java new file mode 100644 index 0000000..fd123ac --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/controller/CoworkspaceApiController.java @@ -0,0 +1,389 @@ +package com.gcc.restapiservices.coworkspace.controller; + +import com.gcc.restapiservices.coworkspace.constants.AppConstants; +import com.gcc.restapiservices.coworkspace.service.CoworkspaceApiService; +import com.gcc.restapiservices.coworkspace.service.PaymentService; +import com.razorpay.Order; +import com.razorpay.RazorpayClient; +import com.razorpay.RazorpayException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.*; + + +@RestController +@RequestMapping("/gccrestservices/api/coworkspace") +public class CoworkspaceApiController { + + @Autowired + CoworkspaceApiService coworkspaceApiService; + + @Autowired + PaymentService paymentService; + + + // Endpoint for getting categories + @GetMapping("/getBuildings") + public ResponseEntity getBuildings() { + try { + System.out.println("Inside getBuildings"); + return ResponseEntity.ok(new ApiResponse("success", "Buildings retrieved successfully", coworkspaceApiService.getBuildings(), HttpStatus.OK.value())); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Failed to retrieve Buildings", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + @GetMapping("/getBuildingsbybid") + public ResponseEntity getBuildingsbybid(@RequestParam("bid") int bid) { + try { + System.out.println("Inside getBuildingsbybid"); + return ResponseEntity.ok(new ApiResponse("success", "Buildingsbybid retrieved successfully", coworkspaceApiService.getBuildingsbybid(bid), HttpStatus.OK.value())); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Failed to retrieve Buildingsbybid", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + + // Endpoint for getting categories + @GetMapping("/getcategory") + public ResponseEntity getcategory() { + try { + System.out.println("Inside getcategory"); + return ResponseEntity.ok(new ApiResponse("success", "Categories retrieved successfully", coworkspaceApiService.getcat(), HttpStatus.OK.value())); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Failed to retrieve categories", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + + @GetMapping("/getCategoriesByBid") +public ResponseEntity getCategoriesByBid(@RequestParam("bid") int bid) { + try { + return ResponseEntity.ok(new ApiResponse( + "success", + "Categories retrieved successfully", + coworkspaceApiService.getcat(bid), + HttpStatus.OK.value() + )); + } catch (Exception e) { + return new ResponseEntity<>( + new ApiResponse("error", "Failed to retrieve categories by bid", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } +} + + + // Endpoint for fetching slots by category ID + @GetMapping("/slots-by-category") + public ResponseEntity getSlotsByCategory(@RequestParam("cid") int cid) { + try { + return ResponseEntity.ok(new ApiResponse("success", "Slots retrieved successfully", coworkspaceApiService.getSlotsByCategoryId(cid), HttpStatus.OK.value())); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Failed to retrieve slots", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @GetMapping("/slots-by-displaycategory") + public ResponseEntity getSlotsByCategoryIdWithDisplayName(@RequestParam("cid") int cid) { + try { + System.out.println("Fetching slots for category ID: " + cid); + List> slots = coworkspaceApiService.getSlotsByCategoryIdWithDisplayName(cid); + + if (slots == null || slots.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(new ApiResponse("error", "No slots found for category ID: " + cid, null, HttpStatus.NOT_FOUND.value())); + } + + return ResponseEntity.ok(new ApiResponse("success", "Slots retrieved successfully", slots, HttpStatus.OK.value())); + } catch (Exception e) { + e.printStackTrace(); // Log full stack trace for debugging + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to retrieve slots: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + // Endpoint for checking slot availability + @GetMapping("/checkSlotAvailability") + public ResponseEntity checkSlotAvailability( + @RequestParam("buildId") int buildId, + @RequestParam("catId") int catId, + @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, + @RequestParam("subId") Integer subId, + @RequestParam(value = "noOfPeople", required = false) Integer noOfPeople, + @RequestParam(value = "slotId", required = false) Integer slotId) { + + // buildId=1; + + try { + Map response = coworkspaceApiService.checkSlotAvailability(buildId, catId, date,subId ,noOfPeople, slotId); + + if (response.isEmpty()) { + return new ResponseEntity<>(new ApiResponse("error", "No slot availability data found", null, HttpStatus.NOT_FOUND.value()), HttpStatus.NOT_FOUND); + } + return ResponseEntity.ok(new ApiResponse("success", "Slot availability checked successfully", response, HttpStatus.OK.value())); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + // Endpoint for saving temp booking +// @PostMapping("/saveInTemp") +// public ResponseEntity saveTempBooking(@RequestParam("catId") int catId, +// @RequestParam("buildId") int buildId, +// @RequestParam("subId") int subId, +// @RequestParam("noOfPeople") int noOfPeople, +// @RequestParam("fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate, +// @RequestParam("toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate, +// @RequestParam("userName") String userName, +// @RequestParam("userMobile") long userMobile, +// @RequestParam("slots") List slots) { +// +// try { +// Map tempBooking = coworkspaceApiService.saveTempBooking(userName, userMobile, slots, fromDate, toDate, noOfPeople, catId, buildId, subId); +// if (tempBooking == null || tempBooking.isEmpty()) { +// return new ResponseEntity<>(new ApiResponse("error", "Failed to save booking", null, HttpStatus.BAD_REQUEST.value()), HttpStatus.BAD_REQUEST); +// } +// return ResponseEntity.ok(new ApiResponse("success", "Booking saved temporarily", tempBooking, HttpStatus.OK.value())); +// } catch (Exception e) { +// return new ResponseEntity<>(new ApiResponse("error", "Error occurred while saving booking", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); +// } +// } + + + @PostMapping("/saveInTemp") + public ResponseEntity saveTempBooking(@RequestParam("catId") int catId, + @RequestParam("buildId") int buildId, + @RequestParam("subId") int subId, + @RequestParam("noOfPeople") int noOfPeople, + @RequestParam("fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate, + @RequestParam("toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate, + @RequestParam("userName") String userName, + @RequestParam("userMobile") long userMobile, + @RequestParam("slots") List slots) { + + try { + // 🛑 Validation: fromDate should not be after toDate + if (fromDate.isAfter(toDate)) { + return ResponseEntity.badRequest().body( + new ApiResponse("error", "From date cannot be after To date", null, HttpStatus.BAD_REQUEST.value())); + } + + // buildId=1; + + // ⚠️ Validation: at least one slot is required + if (slots == null || slots.isEmpty()) { + return ResponseEntity.badRequest().body( + new ApiResponse("error", "At least one slot must be selected", null, HttpStatus.BAD_REQUEST.value())); + } + + Map tempBooking = coworkspaceApiService.saveTempBooking( + userName, userMobile, slots, fromDate, toDate, noOfPeople, catId, buildId, subId); + + if (tempBooking == null || tempBooking.isEmpty()) { + return new ResponseEntity<>( + new ApiResponse("error", "Failed to save booking", null, HttpStatus.BAD_REQUEST.value()), + HttpStatus.BAD_REQUEST); + } + + return ResponseEntity.ok( + new ApiResponse("success", "Booking saved temporarily", tempBooking, HttpStatus.OK.value())); + + } catch (Exception e) { + return new ResponseEntity<>( + new ApiResponse("error", "Error occurred while saving booking", null, HttpStatus.INTERNAL_SERVER_ERROR.value()), + HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + // Endpoint for creating an order (Razorpay) + @PostMapping(value="/create_order") + public ResponseEntity create_order(HttpServletRequest request, @RequestParam("id") int tempid) throws RazorpayException { + try { + Map tempBookingInfo = coworkspaceApiService.getTempBookingByTempId(tempid); + + if (tempBookingInfo != null && !tempBookingInfo.isEmpty()) { + String tempbookid = tempBookingInfo.get("tempbookid").toString(); + String amount = tempBookingInfo.get("amount").toString(); + double amountDouble = 0.0; + + try { + amountDouble = Double.parseDouble(amount); + } catch (NumberFormatException e) { + return new ResponseEntity<>(new ApiResponse("error", "Invalid amount format", null, HttpStatus.BAD_REQUEST.value()), HttpStatus.BAD_REQUEST); + } + + // Razorpay order creation + var client = new RazorpayClient(AppConstants.key_id, AppConstants.key_secret); + JSONObject options = new JSONObject(); + options.put("amount", amountDouble * 100); + options.put("currency", "INR"); + Order od = client.orders.create(options); + paymentService.saveorderLog(od.get("id").toString(), od.toString(), tempbookid); + + return ResponseEntity.ok(new ApiResponse("success", "Order created successfully", od.toJson().toMap(), HttpStatus.OK.value())); + } else { + return new ResponseEntity<>(new ApiResponse("error", "No data found for tempid: " + tempid, null, HttpStatus.NOT_FOUND.value()), HttpStatus.NOT_FOUND); + } + } catch (RazorpayException e) { + return new ResponseEntity<>(new ApiResponse("error", "Razorpay error: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Unexpected error: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + @PostMapping("/Confirm") + public ResponseEntity confirmBookingViaWhatsApp( + @RequestParam("id") String tempId, + @RequestParam(value = "source", defaultValue = "2") int source, + @RequestParam(value = "orderId", required = true) String orderId, + @RequestBody Map paymentResponse + ) { + return coworkspaceApiService.processPaymentConfirmation(tempId, source, orderId, paymentResponse); + } + + //sanjay + @GetMapping(value = "/sendOTP") + public ResponseEntity sendOtp(HttpServletRequest request, @RequestParam String mobileNo) { + // Basic mobile number validation + if (mobileNo == null || mobileNo.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Error: Mobile number cannot be empty."); + } + + if (!mobileNo.matches("^[6-9]\\d{9}$")) { + return ResponseEntity.badRequest().body("Error: Invalid mobile number format. It should be 10 digits starting with 6-9."); + } + + // Check if mobile number exists in DB + List bookingDetailsList = coworkspaceApiService.findByMobileNo(Long.parseLong(mobileNo)); + if (bookingDetailsList == null || bookingDetailsList.isEmpty()) { + return ResponseEntity.badRequest().body("Error: This number is not registered."); + } + + // Generate OTP + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + System.out.println("Generated OTP: " + otp); + + // Send SMS + String bodyMessage = coworkspaceApiService.sendOTPNsms(mobileNo, otp + ""); + + // Store OTP in session + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + session.setAttribute("mobileNo", mobileNo); + + return ResponseEntity.ok(bodyMessage); + } + + + + @GetMapping("/booking-history") + public ResponseEntity getBookingHistory(@RequestParam("mobile") long mobile) { + try { + System.out.println("API Called: /booking-history?mobile=" + mobile); + + List> rawData = coworkspaceApiService.getBookingHistoryByMobile(mobile); + + if (rawData.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(new ApiResponse("error", "No booking history found", null, HttpStatus.NOT_FOUND.value())); + } + + // Group data by booking_id + Map> groupedData = new LinkedHashMap<>(); + + for (Map row : rawData) { + Long bookingId = ((Number) row.get("booking_id")).longValue(); + + if (!groupedData.containsKey(bookingId)) { + Map booking = new LinkedHashMap<>(); + booking.put("booking_id", bookingId); + booking.put("from_date", row.get("from_date")); + booking.put("to_date", row.get("to_date")); + booking.put("booking_date", row.get("booking_date")); + booking.put("user_name", row.get("user_name")); + booking.put("mobile", row.get("mobile")); + booking.put("amount", row.get("amount")); + booking.put("payment_status", row.get("payment_status")); + booking.put("no_of_person", row.get("no_of_person")); + booking.put("building_name", row.get("building_name")); + booking.put("category_name", row.get("category_name")); + booking.put("category_display_name", row.get("category_display_name")); + booking.put("status", row.get("status")); + booking.put("slots", new ArrayList>()); + groupedData.put(bookingId, booking); + } + + // Add slot info + List> slots = (List>) groupedData.get(bookingId).get("slots"); + Map slot = new HashMap<>(); + slot.put("slotid", row.get("slotid")); + slot.put("slot_name", row.get("slot_name")); + slot.put("checkin", row.get("checkin")); + slot.put("checkout", row.get("checkout")); + slots.add(slot); + } + + return ResponseEntity.ok(new ApiResponse( + "success", + "Booking history retrieved successfully", + new ArrayList<>(groupedData.values()), + HttpStatus.OK.value() + )); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to retrieve booking history: " + e.getMessage(), null, + HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @GetMapping("/slots-by-subcategory") + public ResponseEntity getSlotsBySubCategory(@RequestParam("scid") int scid) { + try { + List> slots = coworkspaceApiService.getSlotsBySubCategoryId(scid); + if (slots.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(new ApiResponse("error", "No slots found for subcategory ID: " + scid, null, HttpStatus.NOT_FOUND.value())); + } + return ResponseEntity.ok(new ApiResponse("success", "Slots retrieved successfully", slots, HttpStatus.OK.value())); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to retrieve slots: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @GetMapping("/getsubcategorymaster") + public ResponseEntity getsubcategorymaster(@RequestParam("cid")int cid){ + + try { + List> getsubcategorymaster=coworkspaceApiService.getsubcategorymaster(cid); + if (getsubcategorymaster.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(new ApiResponse("error", "No subcategorymaster found for subcategory ID: " + getsubcategorymaster, null, HttpStatus.NOT_FOUND.value())); + } + return ResponseEntity.ok(new ApiResponse("success", "subcategorymaster retrieved successfully", getsubcategorymaster, HttpStatus.OK.value())); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to retrieve subcategorymaster: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/exception/GlobalExceptionHandler.java b/src/main/java/com/gcc/restapiservices/coworkspace/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..fb81433 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/exception/GlobalExceptionHandler.java @@ -0,0 +1,44 @@ +package com.gcc.restapiservices.coworkspace.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +@ControllerAdvice +public class GlobalExceptionHandler { + +// @ExceptionHandler(IllegalArgumentException.class) +// public ResponseEntity handleIllegalArgument(IllegalArgumentException ex) { +// Map error = new HashMap<>(); +// error.put("timestamp", LocalDateTime.now()); +// error.put("status", 400); +// error.put("error", "Bad Request"); +// error.put("message", ex.getMessage()); +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); +// } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleAll(Exception ex) { + Map error = new HashMap<>(); + error.put("timestamp", LocalDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + error.put("status", 500); + error.put("error", "Internal Server Error"); + error.put("message", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); + } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity handleIllegalArgument(IllegalArgumentException ex) { + Map error = new HashMap<>(); + error.put("timestamp", LocalDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + error.put("status", HttpStatus.BAD_REQUEST.value()); + error.put("error", "Bad Request"); + error.put("message", ex.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); + } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/exception/NoSlotAvailable.java b/src/main/java/com/gcc/restapiservices/coworkspace/exception/NoSlotAvailable.java new file mode 100644 index 0000000..dff6a1f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/exception/NoSlotAvailable.java @@ -0,0 +1,7 @@ +package com.gcc.restapiservices.coworkspace.exception; + +public class NoSlotAvailable extends RuntimeException{ + public NoSlotAvailable(String msg){ + super(msg); + } +} diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/AmountConfigService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/AmountConfigService.java new file mode 100644 index 0000000..a102cf2 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/AmountConfigService.java @@ -0,0 +1,38 @@ +package com.gcc.restapiservices.coworkspace.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.Map; + +@Service +public class AmountConfigService { + + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlCoworkspaceRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + + public Map getAmountBySlotid(int slotid) { + String sql = """ + SELECT * FROM amount_config WHERE slotid = ? + AND isactive = 1 AND isdelete = 0 + """; + try { + Map result = jdbcTemplate.queryForMap(sql, slotid); + return result; + }catch (Exception e){ + return null; + } + + // Check if the result is null and return an empty map if so + } + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/CalendarService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/CalendarService.java new file mode 100644 index 0000000..ac39070 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/CalendarService.java @@ -0,0 +1,33 @@ +package com.gcc.restapiservices.coworkspace.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; + +@Service +public class CalendarService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlCoworkspaceRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + public List> getCalendarBasedOnSubCatId(int scid) { + String sql = "select * from slots where scid = ? AND (`isactive`=1 AND `isdelete`=0)"; + System.err.println(sql+scid); + return jdbcTemplate.queryForList(sql, scid); + + } + + public String getSlotText(String slotID) { + String sql = "SELECT name FROM slots WHERE slotid = ? AND isactive = 1 AND isdelete = 0"; + return jdbcTemplate.queryForObject(sql, new Object[]{slotID}, String.class); + } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/CoworkspaceApiService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/CoworkspaceApiService.java new file mode 100644 index 0000000..11e515c --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/CoworkspaceApiService.java @@ -0,0 +1,1447 @@ +package com.gcc.restapiservices.coworkspace.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.coworkspace.controller.ApiResponse; +import com.gcc.restapiservices.coworkspace.exception.NoSlotAvailable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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 javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; +import java.math.BigDecimal; + +@Service + +public class CoworkspaceApiService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlCoworkspaceRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Autowired + AmountConfigService amountConfigService; + + @Autowired + PaymentService paymentService; + + @Autowired + WhatsAppService whatsAppService; + + @Autowired + CalendarService calendarService; + + @Autowired + AppConfig appConfig; + + private final String key = "pfTEYN6H"; + + + + public List> getBuildings() { + System.out.println("CHECK 1"); + + String sql = """ + SELECT + b.bid, + b.name AS building_name, + b.address AS building_address, + c.cid, + c.name AS category_name, + c.display_name AS category_display_name, + c.timing AS category_timing + FROM buildings b + LEFT JOIN category c + ON b.bid = c.bid + AND c.isdelete = 0 + WHERE b.isdelete = 0 + ORDER BY b.bid ASC, c.cid ASC + """; + + System.out.println("CHECK 2"); + + List> rows = jdbcTemplate.queryForList(sql); + + // ✅ Group by bid + Map> grouped = new LinkedHashMap<>(); + + for (Map row : rows) { + Integer bid = (Integer) row.get("bid"); + Map building = grouped.get(bid); + + if (building == null) { + // Create new building object + building = new LinkedHashMap<>(); + building.put("bid", bid); + building.put("building_name", row.get("building_name")); + building.put("building_address", row.get("building_address")); + building.put("categories", new ArrayList>()); + grouped.put(bid, building); + } + + // ✅ Add category if available + if (row.get("cid") != null) { + Map category = new LinkedHashMap<>(); + category.put("cid", row.get("cid")); + category.put("category_name", row.get("category_name")); + category.put("category_display_name", row.get("category_display_name")); + category.put("category_timing", row.get("category_timing")); + + ((List>) building.get("categories")).add(category); + } + } + + // ✅ Convert to List + List> buildings = new ArrayList<>(grouped.values()); + + // ✅ Sort buildings by bid ascending (just in case) + buildings.sort(Comparator.comparingInt(b -> (Integer) b.get("bid"))); + + // ✅ Sort categories for each building by cid ascending + for (Map building : buildings) { + List> categories = (List>) building.get("categories"); + categories.sort(Comparator.comparingInt(c -> (Integer) c.get("cid"))); + } + + return buildings; +} + + + + + + + + // public List> getBuildingsbybid(int bid) { + // System.out.println("CHECK 1"); + // String sql = "select * from buildings where bid = ? "; + // System.out.println("CHECK 2"); + // return jdbcTemplate.queryForList(sql,bid); + // } + + + public List> getBuildingsbybid(int bid) { + System.out.println("CHECK 1"); + + String sql = """ + SELECT + b.bid, + b.name AS building_name, + c.cid, + c.name AS category_name, + c.display_name AS category_display_name, + c.timing AS category_timing + FROM buildings b + LEFT JOIN category c + ON b.bid = c.bid AND c.isdelete = 0 + WHERE b.isdelete = 0 + AND b.bid = ? + ORDER BY c.orderby ASC + """; + + System.out.println("CHECK 2: Running SQL for bid=" + bid); + + List> rows = jdbcTemplate.queryForList(sql, bid); + System.out.println("✅ Query executed, row count: " + rows.size()); + + if (rows.isEmpty()) return Collections.emptyList(); + + // ✅ We only expect one building (filtered by bid) + Map building = new LinkedHashMap<>(); + List> categoriesList = new ArrayList<>(); + + // Temporary category map to group subcategories + Map> categoryMap = new LinkedHashMap<>(); + + for (Map row : rows) { + if (building.isEmpty()) { + // Fill building details only once + building.put("bid", row.get("bid")); + building.put("building_name", row.get("building_name")); + } + + Integer cid = (Integer) row.get("cid"); + if (cid != null) { + Map category = categoryMap.get(cid); + if (category == null) { + category = new LinkedHashMap<>(); + category.put("cid", cid); + category.put("category_name", row.get("category_name")); + category.put("category_display_name", row.get("category_display_name")); + category.put("category_timing", row.get("category_timing")); + categoryMap.put(cid, category); + } + + + } + } + + // ✅ Add all categories (with subcategories) to building + building.put("categories", new ArrayList<>(categoryMap.values())); + + // Return as a single-element list for consistency with your API response format + return List.of(building); +} + + + + + + + + public List> getcat() { + System.out.println("CHECK 1"); + String sql = "select cid,display_name from category"; + System.out.println("CHECK 2"); + return jdbcTemplate.queryForList(sql); + } + + + + + public List> getcat(int bid) { + System.out.println("CHECK 1: Fetching categories for bid = " + bid); + + String sql = """ + SELECT + c.cid, + c.display_name, + c.name AS category_name + FROM category c + INNER JOIN buildings b + ON b.bid = c.bid + WHERE c.isdelete = 0 + AND b.isdelete = 0 + AND b.bid = ? + ORDER BY c.orderby ASC + """; + + System.out.println("CHECK 2: Running SQL..."); + + try { + List> result = jdbcTemplate.queryForList(sql, bid); + System.out.println("✅ Query executed, categories found: " + result.size()); + return result; + } catch (Exception e) { + System.err.println("❌ SQL Error: " + e.getMessage()); + e.printStackTrace(); + throw e; // Let controller handle the exception + } +} + + public ResponseEntity processPaymentConfirmation(String tempid, int source, String orderId, + Map paymentResponse) { + try { + System.out.println("inside process"); + System.out.println("Payment Response: " + paymentResponse); + + // Validate orderId is not null or empty + if (orderId == null || orderId.trim().isEmpty()) { + return ResponseEntity.badRequest().body(Map.of( + "message", "Order ID is required and cannot be null or empty", + "error", "Missing required parameter: orderId")); + } + + int id = Integer.parseInt(tempid); + Map tempBooking = getTempBookingByTempId(id); + + if (tempBooking == null || tempBooking.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("message", "No booking found for id: " + tempid)); + } + + // Extract reference_id from the new payment response format + String referenceId = null; + if (paymentResponse.containsKey("reference_id")) { + referenceId = paymentResponse.get("reference_id").toString(); + } + + // Handle both old and new payment response structures + Map transaction = null; + String extractedOrderId = null; + String paymentId = null; + String status = null; + int amount = 0; + + // Debug: Print the structure to understand it better + System.out.println("Payment Response Keys: " + paymentResponse.keySet()); + + // Check if transaction is directly in paymentResponse (old structure) + if (paymentResponse.containsKey("transaction")) { + transaction = (Map) paymentResponse.get("transaction"); + System.out.println("Found transaction directly: " + transaction); + } else if (paymentResponse.containsKey("currency")) { + // New structure with nested transaction + Map currency = (Map) paymentResponse.get("currency"); + System.out.println("Currency keys: " + currency.keySet()); + if (currency.containsKey("transaction")) { + transaction = (Map) currency.get("transaction"); + System.out.println("Found transaction in currency: " + transaction); + } + } + + if (transaction != null) { + System.out.println("Transaction keys: " + transaction.keySet()); + // Extract payment details from transaction + paymentId = transaction.get("pg_transaction_id") != null + ? transaction.get("pg_transaction_id").toString() + : null; + status = transaction.get("status") != null ? transaction.get("status").toString() : null; + + Map amountObj = (Map) transaction.get("amount"); + if (amountObj != null && amountObj.get("value") != null) { + amount = (int) amountObj.get("value"); + } + + System.out.println( + "Parsed values - paymentId: " + paymentId + ", status: " + status + ", amount: " + amount); + } else { + System.out.println("No transaction found in payment response"); + } + + // Use the provided orderId parameter directly + String finalOrderId = orderId; + + // Validate required fields from payment response + if (paymentId == null || status == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("message", "Invalid payment response structure"); + errorResponse.put("error", + "Missing required transaction fields. Found - paymentId: " + paymentId + ", status: " + status); + errorResponse.put("paymentResponse", paymentResponse); + return ResponseEntity.badRequest().body(errorResponse); + } + + // Save raw order info in log + ObjectMapper mapper = new ObjectMapper(); + String fullResponse = mapper.writeValueAsString(paymentResponse); + paymentService.saveorderLog(finalOrderId, fullResponse, tempid); + System.out.println("after saveorder"); + + if ("failed".equalsIgnoreCase(status)) { + return ResponseEntity.ok(Map.of( + "message", "Your payment failed. Please try again later.", + "status", "failed")); + } + + // Save payment with reference_id + String amountString = (amount / 100.0) + ""; + + System.out.println("PaymentService instance: " + paymentService); + System.out.println("Saving payment with details:"); + System.out.println("- Amount: " + amountString); + System.out.println("- Payment ID: " + paymentId); + System.out.println("- Order ID: " + finalOrderId); + System.out.println("- Status: " + status); + System.out.println("- Mobile: " + tempBooking.get("mobile").toString()); + System.out.println("- Reference ID: " + referenceId); + + int pid = paymentService.savePayment( + amountString, + paymentId, + finalOrderId, + status, + "0", + tempBooking.get("mobile").toString(), + referenceId); + + System.out.println("Payment saved with ID: " + pid); + + if (pid == 0) { + System.out.println("❌ Payment save failed - returned 0"); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + "message", "Payment save failed", + "error", "Payment could not be saved to database")); + } + + System.out.println("after save "); + + // Save final booking + int bookingId = saveBooking(id, pid, source); + + return ResponseEntity.ok(Map.of( + "message", + "https://gccservices.in/muthalvarpadaippagam/bookingQRCode?booking_id=" + + bookingId, + "bookingId", bookingId, + "status", "success")); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + "message", "Something went wrong during booking confirmation", + "error", e.getMessage())); + } + } + + // public List> getSlotsByCategoryId(int cid) { + // String sql = "SELECT \n" + + // " c.cid AS category_id,\n" + + // " c.name AS category_name,\n" + + // " sc.scid AS subcategory_id,\n" + + // " sc.name AS subcategory_name,\n" + + // " s.slotid,\n" + + // " s.name AS slot_name,\n" + + // " s.start_time,\n" + + // " s.end_time,\n" + + // " s.orderby\n" + + // " FROM \n" + + // " category c\n" + + // " JOIN \n" + + // " subcategory sc ON c.cid = sc.cid\n" + + // " JOIN \n" + + // " slots s ON sc.scid = s.scid\n" + + // " WHERE \n" + + // " c.cid = ? AND c.isactive = 1 AND c.isdelete = 0 \n" + + // " AND sc.isactive = 1 AND sc.isdelete = 0 \n" + + // " AND s.isactive = 1 AND s.isdelete = 0\n" + + // " ORDER BY \n" + + // " sc.orderby, s.orderby"; + + // return jdbcTemplate.queryForList(sql, cid); + // } + + public List> getSlotsByCategoryId(int cid) { + String sql = "SELECT \n" + + " c.cid AS category_id,\n" + + " c.name AS category_name,\n" + + " sc.scid AS subcategory_id,\n" + + " sc.name AS subcategory_name,\n" + + " s.slotid,\n" + + " s.name AS slot_name,\n" + + " s.start_time,\n" + + " s.end_time,\n" + + " s.orderby\n" + + " FROM \n" + + " category c\n" + + " JOIN \n" + + " subcategory sc ON c.cid = sc.cid\n" + + " JOIN \n" + + " slots s ON sc.scid = s.scid\n" + + " WHERE \n" + + " c.cid = ? AND c.isactive = 1 AND c.isdelete = 0 \n" + + " AND sc.isactive = 1 AND sc.isdelete = 0 \n" + + " AND s.isactive = 1 AND s.isdelete = 0\n" + + " ORDER BY \n" + + " sc.orderby, s.orderby"; + + List> allSlots = jdbcTemplate.queryForList(sql, cid); + + // Filter out slots that have already passed based on current time + List> availableSlots = new ArrayList<>(); + LocalTime currentTime = LocalTime.now(); + + System.out.println("Current time: " + currentTime + " - Filtering slots for category ID: " + cid); + + for (Map slot : allSlots) { + String endTimeStr = (String) slot.get("end_time"); + String slotName = (String) slot.get("slot_name"); + + if (endTimeStr != null && !endTimeStr.trim().isEmpty()) { + try { + // Parse the end time (assuming format like "09:30", "13:30", etc.) + LocalTime slotEndTime = LocalTime.parse(endTimeStr); + + // Only include slots that haven't ended yet (current time < slot end time) + if (currentTime.isBefore(slotEndTime)) { + availableSlots.add(slot); + System.out.println("✅ Including slot: " + slotName + " (ends at " + slotEndTime + ")"); + } else { + System.out.println( + "❌ Excluding slot: " + slotName + " (ends at " + slotEndTime + " - already ended)"); + } + } catch (Exception e) { + // If parsing fails, include the slot (better to show than hide due to parsing + // error) + System.err.println("⚠️ Error parsing slot end time: " + endTimeStr + " for slot: " + slotName + + " - including slot anyway"); + availableSlots.add(slot); + } + } else { + // If no end time, include the slot + System.out.println("⚠️ No end time found for slot: " + slotName + " - including slot anyway"); + availableSlots.add(slot); + } + } + + System.out.println("Total slots: " + allSlots.size() + ", Available slots: " + availableSlots.size()); + return availableSlots; + } + + public List> getSlotsByCategoryIdWithDisplayName(int cid) { + String sql = "SELECT " + + "c.cid AS category_id, " + + "c.name AS category_name, " + + "sc.scid AS subcategory_id, " + + "sc.name AS subcategory_name, " + + // Safe handling for display_name (if column missing, default to subcategory + // name) + "COALESCE(sc.display_name, sc.name) AS subcategory_display_name, " + + "s.slotid, " + + "s.name AS slot_name, " + + "s.start_time, " + + "s.end_time, " + + "s.orderby " + + "FROM category c " + + "JOIN subcategory sc ON c.cid = sc.cid " + + "JOIN slots s ON sc.scid = s.scid " + + "WHERE c.cid = ? " + + "AND c.isactive = 1 AND c.isdelete = 0 " + + "AND sc.isactive = 1 AND sc.isdelete = 0 " + + "AND s.isactive = 1 AND s.isdelete = 0 " + + "ORDER BY sc.orderby, s.orderby"; + + try { + return jdbcTemplate.queryForList(sql, cid); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Database error while fetching slots: " + e.getMessage()); + } + } + + public Map checkSlotAvailability(int buildId, int catId, LocalDate date, int subId, + Integer noOfPeople, Integer slotId) { + Map response = new HashMap<>(); + + // Only validate slotId if it's provided + if (slotId != null) { + if (!isSlotAllowedForCategory(slotId, catId)) { + throw new IllegalArgumentException("Invalid slot ID " + slotId + " for category ID " + catId); + } + String slotName = getSlotName(slotId); + response.put("slotName", slotName); + } + + if (!isSubcategoryAllowedForCategory(subId, catId)) { + throw new IllegalArgumentException("Subcategory ID " + subId + " is not valid for Category ID " + catId); + } + + // Get calendar data for the date + slot (if slotId is provided) or for all + // slots (if slotId is null) + Map calendarInfo = new HashMap<>(); + if (slotId != null) { + calendarInfo = getCalendarBySlotId(buildId, catId, date, slotId); + } else { + // When slotId is not provided, get data for all slots in the category + //calendarInfo = getCalendarByCategory(buildId, catId, date, subId); + calendarInfo = getCalendarAvilByCategory(buildId, catId, date, subId); + + } + + if (calendarInfo.isEmpty()) { + response.put("message", "📅 No booking record found for the given date and slot."); + response.put("available", true); // Optional: assume available if no record + response.put("filledSeats", 0); + } else { + // If we have slot details (category-wide check), add them to response + if (calendarInfo.containsKey("slotDetails")) { + response.put("slotDetails", calendarInfo.get("slotDetails")); + } + } + + // Get total capacity + Map capacityInfo2 = getCapacity(subId, catId); + int limit = Integer.parseInt(capacityInfo2.getOrDefault("capacity", "0").toString()); + + int filled = Integer.parseInt(calendarInfo.getOrDefault("filed", "0").toString()); + + // Calculate available seats + int availableSeats = Math.max(0, limit - filled); + + boolean available = filled < limit; + + response.put("totalCapacity", limit); + response.put("filledSeats", filled); + response.put("availableSeats", availableSeats); + response.put("available", available); + + if (noOfPeople != null) { + // Check if requested number of people can be accommodated + boolean canAccommodate = (filled + noOfPeople) <= limit; + response.put("canAccommodate", canAccommodate); + response.put("requestedPeople", noOfPeople); + + if (!canAccommodate) { + response.put("message", + "Cannot accommodate " + noOfPeople + " people. Only " + availableSeats + " seats available."); + } else { + response.put("message", + "Can accommodate " + noOfPeople + " people. " + availableSeats + " seats available."); + } + } else { + if (slotId != null) { + response.put("message", "📊 Current availability: " + availableSeats + " seats available out of " + + limit + " total capacity."); + } else { + response.put("message", "📊 Category-wide availability: " + availableSeats + " seats available out of " + + limit + + " total capacity across all slots. Check slotDetails for individual slot information."); + } + } + + return response; + } + + + + public Map getCalendarBySlotId(int bid, int cid, LocalDate Bdate, int slotId) { + String sql; + Object[] params; + + if (cid == 2 && (slotId == 6 || slotId == 7)) { + // Special case for category 2 with slots 6 or 7 - sum multiple slots + sql = "SELECT SUM(bcount) AS filed, bdate FROM calendar WHERE bdate = ? AND cid = ? AND bid = ? AND slotId IN (?,8,9) GROUP BY bdate"; + params = new Object[]{Bdate, cid, bid, slotId}; + } else { + // For all other cases, sum all bookings for the specific slot to handle + //multiple people bookings + sql = "SELECT SUM(bcount) AS filed, bdate FROM calendar WHERE bdate = ? AND cid = ? AND bid = ? AND slotId = ? GROUP BY bdate"; + params = new Object[]{Bdate, cid, bid, slotId}; + } + + // added by yogi this below condition + // if (cid == 2) { + // if (slotId == 6 || slotId == 7) { + // // Special case for category 2 with slots 6 or 7 - sum multiple slots + + // sql = "SELECT SUM(bcount) AS filed, bdate FROM calendar WHERE bdate = ? AND cid = ? AND bid = ? AND slotId IN (?,8,9) GROUP BY bdate"; + + + // } else { + + // sql = "select sum(bcount) as filed, bdate " + // + "from calendar where (bdate = ? and cid = ? and bid = ?) or (0=?) " + // + "group by bdate"; + + // } + // params = new Object[] { Bdate, cid, bid, slotId }; + + // } else { + // // For all other cases, sum all bookings for the specific slot to handle + // // multiple people bookings + // sql = "SELECT SUM(bcount) AS filed, bdate FROM calendar WHERE bdate = ? AND cid = ? AND bid = ? AND slotId = ? GROUP BY bdate"; + // params = new Object[] { Bdate, cid, bid, slotId }; + // } + + System.out.println("Executing calendar SQL for specific slot: " + sql); + + List> result = jdbcTemplate.query(sql, (rs, rowNum) -> { + Map map = new HashMap<>(); + // Handle BigDecimal to Integer conversion safely + Object filedObj = rs.getObject("filed"); + if (filedObj instanceof BigDecimal) { + map.put("filed", ((BigDecimal) filedObj).intValue()); + } else if (filedObj instanceof Number) { + map.put("filed", ((Number) filedObj).intValue()); + } else { + map.put("filed", 0); + } + map.put("bdate", rs.getDate("bdate").toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + return map; + }, params); + + return result.isEmpty() ? Collections.emptyMap() : result.get(0); + } + +// added by balaji sir + public Map getCalendarAvilByCategory(int bid, int cid, LocalDate date, int subId) { + Map capacityInfo = getCapacity(subId, cid); + int totalCapacity = Integer.parseInt(capacityInfo.getOrDefault("capacity", "0").toString()); + + int avl_check = totalCapacity; + + Map response = new HashMap<>(); + if(subId==4){ + LocalDate start = date; + List dateList = new ArrayList<>(); + + // Loop for 30 days (including start date) + for (int i = 0; i < 30; i++) { + LocalDate nextDate = start.plusDays(i); + Map response_map = getCalendarByCategory(bid, cid, nextDate, subId); + response_map.put("data", response_map); + //System.out.println("1 avl_check ON " +nextDate + " = "+ avl_check); + response=response_map; + //System.err.println(response); + // Extract availableSeats from response_map + if (response_map != null && response_map.containsKey("data")) { + Map data = (Map) response_map.get("data"); +//System.out.println("2 avl_check ON " +nextDate + " = "+ avl_check); + // Check slotDetails inside data + if (data != null && data.containsKey("slotDetails")) { + //System.out.println("3 avl_check ON " +nextDate + " = "+ avl_check); + List> slotDetails = (List>) data.get("slotDetails"); + + if (!slotDetails.isEmpty()) { + //System.out.println("4 avl_check ON " +nextDate + " = "+ avl_check); + Map slot = slotDetails.get(0); + Object availableSeats = slot.get("availableSeats"); + Object available = slot.get("available"); + if(available!=null && (boolean)available){ + if(avl_check > Integer.parseInt(availableSeats.toString())){ + avl_check=Integer.parseInt(availableSeats.toString()); + } + //System.out.println("avl_check ON " +nextDate + " = "+ avl_check); + } + else{ + return response_map; + } + } + else{ + return response_map; + } + } + } + + } + // return response; + } + else{ + return getCalendarByCategory(bid, cid, date, subId); + } + + return modifyAvailableSeats(response, totalCapacity, avl_check); + } + + //added by balaji sir + public Map modifyAvailableSeats(Map response, int totalCapacity, int newAvailableSeats) { + // Get the "data" map + Map data = (Map) response.get("data"); + if (data == null) return response; + + // Update availableSeats in the main data + data.put("availableSeats", newAvailableSeats); + + // Get the slotDetails list + List> slotDetails = (List>) data.get("slotDetails"); + if (slotDetails != null && !slotDetails.isEmpty()) { + // Update availableSeats inside each slot + for (Map slot : slotDetails) { + slot.put("availableSeats", newAvailableSeats); + slot.put("filledSeats", (totalCapacity-newAvailableSeats)); + } + } + + // Put updated data back (not strictly needed since it's by reference) + response.put("data", data); + + return response; +} + + // added by balaji sir + public Map getCalendarByCategory(int bid, int cid, LocalDate date, int subId) { + + String sql="SELECT * FROM slots WHERE scid = ? AND isactive = 1 AND isdelete = 0"; + List> slots = jdbcTemplate.queryForList(sql, subId); + String cal; + + Map capacityInfo = getCapacity(subId, cid); + int totalCapacity = Integer.parseInt(capacityInfo.getOrDefault("capacity", "0").toString()); + int totalFilled = 0; + + List> slotDetails = new ArrayList<>(); + + if(cid==2){ + //if(subId==2){ + for(Map slot : slots){ + int slotId = (Integer) slot.get("slotid"); + if(slotId==6 || slotId==7){ + cal = "SELECT COALESCE((sum(bcount)-sum(absent_count)),0) as booked FROM calendar WHERE bdate = ? AND cid = ? AND slotId IN (?,8,9)"; + }else{ + cal = "SELECT COALESCE((sum(bcount)-sum(absent_count)),0) as booked FROM calendar WHERE (bdate = ? AND cid = ?) or (0=?)"; + } + List> avlsql = jdbcTemplate.queryForList(cal, date, cid, slotId); + + int slotAvailable = 0; + if (!avlsql.isEmpty() && avlsql.get(0).get("booked") != null) { + slotAvailable = totalCapacity - Integer.parseInt(avlsql.get(0).get("booked").toString()); + //System.out.println(date + "=" + slotAvailable + " = "+ totalCapacity + " = " + avlsql.get(0).get("booked")); + } else { + slotAvailable = totalCapacity; + } + if(slotAvailable<0){ + slotAvailable=0; + } + int slotFilled = Integer.parseInt(avlsql.get(0).get("booked").toString()); + + // Add slot details with total capacity + Map slotInfo = new HashMap<>(); + slotInfo.put("slotId", slotId); + slotInfo.put("slotName", slot.get("name")); + slotInfo.put("filledSeats", slotFilled); + slotInfo.put("capacity", totalCapacity); // Use total capacity, not divided + slotInfo.put("availableSeats", slotAvailable); + slotInfo.put("available", slotAvailable>0); + totalFilled += slotFilled; + + slotDetails.add(slotInfo); + + } + //} + } + else{ + for(Map slot : slots){ + int slotId = (Integer) slot.get("slotid"); + cal = "SELECT COALESCE(sum(bcount),0) as booked FROM calendar WHERE bdate = ? AND cid = ? AND slotId = ?"; + List> avlsql = jdbcTemplate.queryForList(cal, date, cid, slotId); + + int slotAvailable = 0; + int slotFilled = 0; + if (!avlsql.isEmpty() && avlsql.get(0).get("booked") != null) { + slotAvailable = totalCapacity - Integer.parseInt(avlsql.get(0).get("booked").toString()); + slotFilled = Integer.parseInt(avlsql.get(0).get("booked").toString()); + } else { + slotAvailable = totalCapacity; + slotFilled = 0; + } + + // Add slot details with total capacity + Map slotInfo = new HashMap<>(); + slotInfo.put("slotId", slotId); + slotInfo.put("slotName", slot.get("name")); + slotInfo.put("filledSeats", slotFilled); + slotInfo.put("capacity", totalCapacity); // Use total capacity, not divided + slotInfo.put("availableSeats", slotAvailable); + slotInfo.put("available", slotAvailable>0); + totalFilled += slotFilled; + slotDetails.add(slotInfo); + } + } + + Map result = new HashMap<>(); + result.put("filed", totalFilled); + result.put("bdate", date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + result.put("slotDetails", slotDetails); + result.put("totalCapacity", totalCapacity); + + return result; + +} + +// old added by vishnu + public Map getCalendarByCategory2(int bid, int cid, LocalDate date, int subId) { + // Get all slots for this subcategory to understand the time structure + String slotSql = "SELECT s.slotid, s.name AS slot_name FROM slots s " + + "JOIN subcategory sc ON s.scid = sc.scid " + + "WHERE sc.scid = ? AND sc.cid = ? AND s.isactive = 1 AND s.isdelete = 0 " + + "ORDER BY s.orderby"; + + List> allSlots = jdbcTemplate.queryForList(slotSql, subId, cid); + + // Get calendar data for all slots on this date with SUM to handle multiple + // bookings per slot + String calendarSql = "SELECT c.slotid, SUM(c.bcount) AS bcount, s.name AS slot_name " + + "FROM calendar c " + + "JOIN slots s ON c.slotid = s.slotid " + + "WHERE c.bdate = ? AND c.cid = ? AND c.bid = ? " + + "AND c.slotid IN (SELECT s2.slotid FROM slots s2 " + + "JOIN subcategory sc2 ON s2.scid = sc2.scid " + + "WHERE sc2.scid = ? AND sc2.cid = ?) " + + "GROUP BY c.slotid, s.name"; + + List> calendarData = jdbcTemplate.queryForList(calendarSql, date, cid, bid, subId, cid); + + // Get total capacity for the subcategory + Map capacityInfo = getCapacity(subId, cid); + int totalCapacity = Integer.parseInt(capacityInfo.getOrDefault("capacity", "0").toString()); + + // Create a map to store slot-wise data + Map result = new HashMap<>(); + int totalFilled = 0; + List> slotDetails = new ArrayList<>(); + + // Process each slot - show total capacity for each slot, not divided capacity + for (Map slot : allSlots) { + int slotId = (Integer) slot.get("slotid"); + String slotName = (String) slot.get("slot_name"); + + // Find if this slot has any bookings + int slotFilled = 0; + for (Map cal : calendarData) { + if (cal.get("slotid").equals(slotId)) { + // Handle BigDecimal to Integer conversion safely + Object bcountObj = cal.get("bcount"); + if (bcountObj instanceof BigDecimal) { + slotFilled = ((BigDecimal) bcountObj).intValue(); + } else if (bcountObj instanceof Number) { + slotFilled = ((Number) bcountObj).intValue(); + } else { + slotFilled = 0; + } + break; + } + } + + totalFilled += slotFilled; + + // Calculate available seats for this slot using total capacity (not divided) + int slotAvailable = Math.max(0, totalCapacity - slotFilled); + + // Add slot details with total capacity + Map slotInfo = new HashMap<>(); + slotInfo.put("slotId", slotId); + slotInfo.put("slotName", slotName); + slotInfo.put("filledSeats", slotFilled); + slotInfo.put("capacity", totalCapacity); // Use total capacity, not divided + slotInfo.put("availableSeats", slotAvailable); + slotInfo.put("available", slotFilled < totalCapacity); + slotDetails.add(slotInfo); + } + + result.put("filed", totalFilled); + result.put("bdate", date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + result.put("slotDetails", slotDetails); + result.put("totalCapacity", totalCapacity); + + System.out.println("Executing calendar SQL for category with slot breakdown: " + calendarSql); + + return result; + } + + public Map getCapacity(int sId, int catId) { + String sql = "SELECT limits, capacity FROM subcategory WHERE scid = ? AND cid = ?"; + System.out.println("Executing: " + sql + " with scid=" + sId + ", cid=" + catId); + try { + return jdbcTemplate.queryForMap(sql, sId, catId); + } catch (org.springframework.dao.EmptyResultDataAccessException e) { + throw new IllegalArgumentException( + "❌ Capacity not configured for subcategory ID " + sId + " and category ID " + catId); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("🚨 Unexpected error while fetching capacity: " + e.getMessage()); + } + } + + // helper function to identify slot + public boolean isSlotAllowedForCategory(int slotId, int catId) { + String sql = "SELECT COUNT(*) FROM slots s JOIN subcategory sub ON s.scid = sub.scid " + + "WHERE s.slotid = ? AND sub.cid = ? AND s.isactive = 1 AND s.isdelete = 0"; + Integer count = jdbcTemplate.queryForObject(sql, Integer.class, slotId, catId); + if (count == null || count == 0) { + throw new IllegalArgumentException("❌ Slot ID " + slotId + " is not valid for Category ID " + catId); + } + return true; + } + + public boolean isSubcategoryAllowedForCategory(int subId, int catId) { + String sql = "SELECT COUNT(*) FROM subcategory WHERE scid = ? AND cid = ? AND isactive = 1 AND isdelete = 0"; + Integer count = jdbcTemplate.queryForObject(sql, Integer.class, subId, catId); + return count != null && count > 0; + } + + public String getSlotName(int slotId) { + String sql = "SELECT name FROM slots WHERE slotid = ?"; + try { + return jdbcTemplate.queryForObject(sql, String.class, slotId); + } catch (Exception e) { + return "Slot ID " + slotId; + } + } + + public Map saveTempBooking(String userName, long userMobile, + List slots, LocalDate fromDate, LocalDate toDate, + int noOfPeople, int catId, int buildId, int subId) { + + List btnDates = getDatesBetween(fromDate, toDate); + double amount = 0; + int tempBookingId = 0; + if (!btnDates.isEmpty()) { + for (Integer slot : slots) { + Map amt = amountConfigService.getAmountBySlotid(slot); + System.out.println(slot + "============================>" + amt); + if (amt != null && !amt.isEmpty()) { + if (catId != 3) { + amount = amount + (Double.parseDouble(amt.get("amount") + "") * noOfPeople); + } else { + amount = amount + (Double.parseDouble(amt.get("amount") + "") * 1); + } + for (LocalDate date : btnDates) { + if (checkSlotAvailability(buildId, catId, date, subId, noOfPeople, slot).isEmpty()) { + // return null; + throw new NoSlotAvailable("Slot not available"); + } + } + } else { + throw new NoSlotAvailable("Sry!! Amount Not Configured"); + } + } + } + String Tslot = slots.stream().map(String::valueOf).collect(Collectors.joining(",")); + System.out.println(Tslot); + + tempBookingId = saveTempBookingDetails(userName, userMobile, + Tslot, fromDate, toDate, noOfPeople, catId, buildId, subId, amount); + + Map temp = new HashMap<>(); + temp.put("tempBookId", tempBookingId); + temp.put("userName", userName); + temp.put("userMobile", userMobile); + temp.put("slotIds", Tslot); + temp.put("fromDate", fromDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + temp.put("toDate", toDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))); + temp.put("noOfPeople", noOfPeople); + temp.put("catId", catId); + temp.put("buildId", buildId); + temp.put("subId", subId); + temp.put("amount", amount); + + return temp; + + } + + public static List getDatesBetween(LocalDate fromDate, LocalDate toDate) { + List dates = new ArrayList<>(); + + LocalDate currentDate = fromDate; + while (!currentDate.isAfter(toDate)) { + dates.add(currentDate); + currentDate = currentDate.plusDays(1); + } + + return dates; + } + + public int saveTempBookingDetails(String userName, long userMobile, + String Tslot, LocalDate fromDate, LocalDate toDate, + int noOfPeople, int catId, int buildId, int subId, double amount) { + // Join the slots with commas + + String sqlQuery = "INSERT INTO temp_booking (user_name, mobile, slotids, from_date, to_date, no_of_person, amount, cid, bid, sid) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "tempbookid" }); + ps.setString(1, userName); + ps.setString(2, userMobile + ""); + ps.setString(3, Tslot); + ps.setString(4, fromDate.toString()); + ps.setString(5, toDate.toString()); + ps.setString(6, noOfPeople + ""); + ps.setString(7, amount + ""); + ps.setString(8, catId + ""); + ps.setString(9, buildId + ""); + ps.setString(10, subId + ""); + return ps; + } + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + return (generatedId != null) ? generatedId.intValue() : 0; + } + } 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()); + // return 0; + } else { + System.out.println("Message: " + rootCause.getMessage()); + // return 0; + } + } + + return 0; + + } + + public Map getTempBookingByTempId(int tempbookid) { + String sql = "SELECT * FROM temp_booking where tempbookid = ?"; + return jdbcTemplate.queryForMap(sql, tempbookid); + } + + @Transactional("coworkspaceTransactionManager") + public int saveBooking(int tempbookid, int pid, int source) { + System.out.println("Inside save booking.."); + + Map tempBooking = getTempBookingByTempId(tempbookid); + System.out.println(tempBooking); + + List> result = null; + Map response = new HashMap<>(); + int bookingId = 0; + + String sqlQuery = "INSERT INTO booking (user_name, mobile, slotids, from_date, to_date, no_of_person, amount, cid, bid, sid, source) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + String user_name = tempBooking.get("user_name").toString(); + String mobile = tempBooking.get("mobile").toString(); + String slotIds = tempBooking.get("slotids").toString(); + String from_date = tempBooking.get("from_date").toString(); + String to_date = tempBooking.get("to_date").toString(); + String no_of_person = tempBooking.get("no_of_person").toString(); + String amount = tempBooking.get("amount").toString(); + String cid = tempBooking.get("cid").toString(); + String bid = tempBooking.get("bid").toString(); + String sid = tempBooking.get("sid").toString(); + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "booking_id" }); + ps.setString(1, user_name); + ps.setString(2, mobile); + ps.setString(3, slotIds); + ps.setString(4, from_date); + ps.setString(5, to_date); + ps.setString(6, no_of_person); + ps.setString(7, amount); + ps.setString(8, cid); + ps.setString(9, bid); + ps.setString(10, sid); + ps.setString(11, source + ""); + return ps; + } + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + bookingId = (generatedId != null) ? generatedId.intValue() : 0; + + paymentService.updateBookingIdInPayment( + tempBooking.get("mobile").toString(), + bookingId + "", pid + ""); + saveInBookingInCalendar(bookingId, + tempBooking.get("from_date").toString(), + tempBooking.get("to_date").toString(), + tempBooking.get("no_of_person").toString(), + tempBooking.get("slotids").toString(), + tempBooking.get("bid").toString(), + tempBooking.get("cid").toString(), + tempBooking.get("sid").toString()); + + sendMessage(user_name, mobile, slotIds, from_date, to_date, no_of_person, amount, cid, bid, sid, + bookingId + ""); // Sending Message to public + + return bookingId; + } else { + return 10; + } + + } 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()); + return 0; + } else { + System.out.println("Message: " + rootCause.getMessage()); + return 0; + } + } + } + + public void saveInBookingInCalendar(int bookingId, String fromDat, String toDat, String persons, String slotIds, + String bid, String cid, String sid) { + LocalDate fromDate = LocalDate.parse(fromDat); + LocalDate toDate = LocalDate.parse(toDat); + int noOfPeople = Integer.parseInt(persons); + int buildId = Integer.parseInt(bid); + int catId = Integer.parseInt(cid); + int subId = Integer.parseInt(sid); + + List slots = Arrays.stream(slotIds.split(",")) + .map(Integer::parseInt) // Convert to integer + .toList(); + + List btnDates = getDatesBetween(fromDate, toDate); + double amount = 0; + if (!btnDates.isEmpty()) { + for (Integer slot : slots) { + + for (LocalDate date : btnDates) { + if (checkSlotAvailability(buildId, catId, date, subId, noOfPeople, slot).isEmpty()) { + throw new NoSlotAvailable("Slot Occupied"); + } else { + saveInCalendar(buildId, catId, slot, bookingId, date, noOfPeople); + } + } + + } + System.out.println("successfully saved in calendar"); + updateBookingStatus(bookingId, "success"); + } + + } + + public int saveInCalendar(int bid, int cid, int slotId, int bookId, LocalDate bDate, int noOfPeople) { + + List> result = null; + Map response = new HashMap<>(); + int calendarId = 0; + + String sqlQuery = "insert into calendar(bid,cid,slotid,bookingid,bdate,bcount) values(?,?,?,?,?,?);"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[] { "calid" }); + ps.setString(1, bid + ""); + ps.setString(2, cid + ""); + ps.setString(3, slotId + ""); + ps.setString(4, bookId + ""); + ps.setString(5, bDate.toString()); + ps.setString(6, noOfPeople + ""); + + return ps; + } + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + calendarId = (generatedId != null) ? generatedId.intValue() : 0; + return calendarId; + } else { + return 10; + } + } 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()); + return 0; + } else { + System.out.println("Message: " + rootCause.getMessage()); + return 0; + } + } + } + + public int updateBookingStatus(int bookingId, String bookingStatus) { + // SQL UPDATE query with placeholders + String sql = "UPDATE booking SET booking_status = ? WHERE booking_id = ?"; + + try { + // Execute the update query and return the number of rows affected + int rowsAffected = jdbcTemplate.update(sql, bookingStatus, bookingId); + + if (rowsAffected > 0) { + System.out.println("Booking status updated successfully for booking_id: " + bookingId); + } else { + System.out.println("No booking found with booking_id: " + bookingId); + } + + return rowsAffected; + } catch (DataAccessException e) { + System.err.println("Error while updating booking status: " + e.getMessage()); + return 0; // Return 0 in case of an error + } + } + + public void sendMessage(String user_name, String mobile, String slotIds, String from_date, String to_date, + String no_of_person, String amount, String cid, String bid, String sid, String bookingId) { + + String slottxt = ""; + slottxt = calendarService.getSlotText(slotIds); + slottxt = slottxt.replace(" ", "%20"); + + // System.out.println("cid :"+cid); + // System.out.println("sid :"+sid); + + if (cid.equals("1")) { + whatsAppService.sendELearnNmsg(mobile, no_of_person, from_date, slottxt, amount, bookingId); + whatsAppService.sendTLearnNmsg(mobile, no_of_person, from_date, slottxt, amount, bookingId); + } else if (cid.equals("2")) { + if (sid.equals("4")) { + whatsAppService.sendEMonthDeskspaceNmsg(mobile, no_of_person, from_date, to_date, slottxt, amount, + bookingId); + whatsAppService.sendTMonthDeskspaceNmsg(mobile, no_of_person, from_date, to_date, slottxt, amount, + bookingId); + } else { + whatsAppService.sendEDeskspaceNmsg(mobile, no_of_person, from_date, slottxt, amount, bookingId); + whatsAppService.sendTDeskspaceNmsg(mobile, no_of_person, from_date, slottxt, amount, bookingId); + } + } else if (cid.equals("3")) { + whatsAppService.sendEConfeNmsg(mobile, from_date, slottxt, amount, bookingId); + whatsAppService.sendTConfeNmsg(mobile, from_date, slottxt, amount, bookingId); + } + } + + // sanjay code start + public List> findByMobileNo(long mobileNo) { + String sqlQuery = "SELECT booking_id FROM booking WHERE mobile = ?"; + System.out.println(mobileNo); + return jdbcTemplate.queryForList(sqlQuery, mobileNo); + } + + public String sendOTPNsms(String MobileNo, String msg) { + String generatedToken = "Welcome to Muthalvar Padaippagam, The OTP for your booking is " + msg + " - GCC"; + String urlString = appConfig.getGetOtpUrl() + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + generatedToken + "&entityid=1401572690000011081&templateid=1407173027593091895"; + // return whatsappMsgService.sendSMS(urlString); + return whatsAppService.sendSMS(urlString, MobileNo, msg); + } + + public List> getBookingHistoryByMobile(long mobile) { + String sql = "SELECT " + + "bd.booking_id, " + + "DATE_FORMAT(bd.from_date, '%d-%m-%Y') AS from_date, " + + "DATE_FORMAT(bd.to_date, '%d-%m-%Y') AS to_date, " + + "DATE_FORMAT(bd.cdate, '%d-%m-%Y') AS booking_date, " + + "bd.user_name, bd.mobile, bd.amount,bd.booking_status as payment_status, bd.no_of_person, " + + "bd.slotids, bu.name AS building_name, " + + "c.name AS category_name, c.display_name AS category_display_name, " + + "CASE " + + " WHEN bd.to_date < CURDATE() THEN 'Completed' " + + " WHEN bd.from_date > CURDATE() THEN 'Upcoming' " + + " ELSE 'Ongoing' " + + "END AS status, " + + "st.slotid, st.name AS slot_name, " + + "SUBSTRING_INDEX(st.name, ' to ', 1) AS checkin, " + + "SUBSTRING_INDEX(st.name, ' to ', -1) AS checkout " + + "FROM booking bd " + + "LEFT JOIN buildings bu ON bd.bid = bu.bid " + + "JOIN category c ON bd.cid = c.cid " + + "JOIN slots st ON FIND_IN_SET(st.slotid, bd.slotids) " + + "WHERE bd.mobile = ? " + + "ORDER BY bd.from_date DESC"; + + try { + System.out.println("Executing booking history query for mobile: " + mobile); + System.out.println("Connected DB URL: " + + jdbcTemplate.getDataSource().getConnection().getMetaData().getURL()); + + return jdbcTemplate.queryForList(sql, mobile); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Error fetching booking history: " + e.getMessage()); + } + } + + public List> getSlotsBySubCategoryId(int scid) { + String sql = "SELECT " + + "c.cid AS category_id, " + + "c.name AS category_name, " + + "sc.scid AS subcategory_id, " + + "sc.name AS subcategory_name, " + + "sc.display_name AS subcategory_display_name, " + + "s.slotid, " + + "s.name AS slot_name, " + + "s.start_time, " + + "s.end_time, " + + "s.orderby " + + "FROM category c " + + "JOIN subcategory sc ON c.cid = sc.cid " + + "JOIN slots s ON sc.scid = s.scid " + + "WHERE sc.scid = ? " + + "AND c.isactive = 1 AND c.isdelete = 0 " + + "AND sc.isactive = 1 AND sc.isdelete = 0 " + + "AND s.isactive = 1 AND s.isdelete = 0 " + + "ORDER BY s.orderby"; + + return jdbcTemplate.queryForList(sql, scid); + } + + // public List> getSlotsBySubCategoryId(int scid) { + // String sql = "SELECT " + + // "c.cid AS category_id, " + + // "c.name AS category_name, " + + // "sc.scid AS subcategory_id, " + + // "sc.name AS subcategory_name, " + + // "sc.display_name AS subcategory_display_name, " + + // "s.slotid, " + + // "s.name AS slot_name, " + + // "s.start_time, " + + // "s.end_time, " + + // "s.orderby " + + // "FROM category c " + + // "JOIN subcategory sc ON c.cid = sc.cid " + + // "JOIN slots s ON sc.scid = s.scid " + + // "WHERE sc.scid = ? " + + // "AND c.isactive = 1 AND c.isdelete = 0 " + + // "AND sc.isactive = 1 AND sc.isdelete = 0 " + + // "AND s.isactive = 1 AND s.isdelete = 0 " + + // "ORDER BY s.orderby"; + + // List> allSlots = jdbcTemplate.queryForList(sql, scid); + + // // Filter out slots that have already passed based on current time + // List> availableSlots = new ArrayList<>(); + // LocalTime currentTime = LocalTime.now(); + + // System.out.println("Current time: " + currentTime + " - Filtering slots for + // subcategory ID: " + scid); + + // for (Map slot : allSlots) { + // String startTimeStr = (String) slot.get("start_time"); + // String slotName = (String) slot.get("slot_name"); + + // if (startTimeStr != null && !startTimeStr.trim().isEmpty()) { + // try { + // // Parse the start time (assuming format like "06:00", "14:00", etc.) + // LocalTime slotStartTime = LocalTime.parse(startTimeStr); + + // // Only include slots that haven't started yet (current time < slot start + // time) + // if (currentTime.isBefore(slotStartTime)) { + // availableSlots.add(slot); + // System.out.println("✅ Including slot: " + slotName + " (starts at " + + // slotStartTime + ")"); + // } else { + // System.out.println("❌ Excluding slot: " + slotName + " (starts at " + + // slotStartTime + " - already passed)"); + // } + // } catch (Exception e) { + // // If parsing fails, include the slot (better to show than hide due to + // parsing error) + // System.err.println("⚠️ Error parsing slot start time: " + startTimeStr + " + // for slot: " + slotName + " - including slot anyway"); + // availableSlots.add(slot); + // } + // } else { + // // If no start time, include the slot + // System.out.println("⚠️ No start time found for slot: " + slotName + " - + // including slot anyway"); + // availableSlots.add(slot); + // } + // } + + // System.out.println("Total slots: " + allSlots.size() + ", Available slots: " + // + availableSlots.size()); + // return availableSlots; + // } + + public List> getsubcategorymaster(int cid) { + String sql = "SELECT scid,display_name FROM coworkingspace.subcategory where cid=?"; + return jdbcTemplate.queryForList(sql, cid); + } + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/PaymentService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/PaymentService.java new file mode 100644 index 0000000..e2d2798 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/PaymentService.java @@ -0,0 +1,193 @@ +package com.gcc.restapiservices.coworkspace.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +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 javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; + +@Service +public class PaymentService { + + @Autowired + public void setDataSource(@Qualifier("mysqlCoworkspaceRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + System.out.println("🔵 PaymentService JdbcTemplate initialized with dataSource: " + dataSource); + } + + + private JdbcTemplate jdbcTemplate; + @Transactional("coworkspaceTransactionManager") + public int savePayment( String totalAmount, + String payment_id, + String payment_orderid, + String payment_status, + String bookingId, + String mobile_no, + String whatsUpRefId + ){ + + System.out.println("🔵 PaymentService.savePayment called with:"); + System.out.println("- totalAmount: " + totalAmount); + System.out.println("- payment_id: " + payment_id); + System.out.println("- payment_orderid: " + payment_orderid); + System.out.println("- payment_status: " + payment_status); + System.out.println("- bookingId: " + bookingId); + System.out.println("- mobile_no: " + mobile_no); + System.out.println("- whatsUpRefId: " + whatsUpRefId); + System.out.println("- paymentdate: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + int lastInsertId = 0; + + String sqlQuery = "INSERT INTO `payment`(`amount`, `mobno`, `order_id`, `payment_id`, `payment_status`, `paymentdate`, `booking_id`, `whats_up_refid`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + System.out.println("🔵 SQL Query: " + sqlQuery); + System.out.println("🔵 JdbcTemplate instance: " + jdbcTemplate); + + if (jdbcTemplate == null) { + System.out.println("❌ JdbcTemplate is null! Cannot save payment."); + return 0; + } + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); + ps.setString(1, totalAmount); + ps.setString(2, mobile_no); + ps.setString(3, payment_orderid); + ps.setString(4, payment_id); + ps.setString(5, payment_status); + ps.setString(6, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + ps.setString(7, bookingId); + ps.setString(8, whatsUpRefId); + return ps; + } + }, keyHolder); + + System.out.println("🔵 Affected rows: " + affectedRows); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + lastInsertId = (generatedId != null) ? generatedId.intValue() : 0; + System.out.println("🔵 Generated ID: " + lastInsertId); + return lastInsertId; + } else { + System.out.println("❌ Error on payment save - no rows affected!"); + return 0; + } + } catch (DataAccessException e) { + System.out.println("❌ Data Access Exception in savePayment:"); + e.printStackTrace(); + 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()); + } else { + System.out.println("Message: " + rootCause.getMessage()); + } + return 0; + } catch (Exception e) { + System.out.println("❌ General Exception in savePayment:"); + e.printStackTrace(); + return 0; + } + } + + + public int saveorderLog(String order_id, String order_info, String temp_booking_id) { + System.out.println("inside order log"); + if (order_id == null || temp_booking_id == null) { + System.out.println("❌ Missing required fields. Order ID: " + order_id + ", Temp Book ID: " + temp_booking_id); + return 0; + } + + String sqlQuery = "INSERT INTO `order_log`(`order_id`, `order_info`, `temp_booking_id`) VALUES (?,?,?)"; + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); + ps.setString(1, order_id); + ps.setString(2, order_info); + ps.setString(3, temp_booking_id); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + return (generatedId != null) ? generatedId.intValue() : 0; + } else { + System.out.println("❌ Failed to insert into order_log."); + return 0; + } + } catch (Exception e) { + System.out.println("🚨 Exception during insert to order_log: " + e.getMessage()); + e.printStackTrace(); + return 0; + } + } + + + @Transactional("coworkspaceTransactionManager") + public int updateBookingIdInPayment(String mobile_no,String bookingId,String payment_id) { + System.out.println("inside update payment "); + String sqlQuery = "UPDATE `payment` SET `mobno` = ?, `booking_id` = ? WHERE `id` = ?"; + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery); + ps.setString(1, mobile_no); // Set the new mobile number + ps.setString(2, bookingId); // Set the new booking ID + ps.setString(3, payment_id); // Use the payment ID to locate the record to update + return ps; + } + }); + + if (affectedRows > 0) { + System.out.println("Record updated successfully!"); + return 1; // Or return some relevant status + } else { + System.out.println("Error on updating record!"); + return 0; + } + } 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()); + } else { + System.out.println("Message: " + rootCause.getMessage()); + } + return 0; + } + } + + public Map getPaymentById(int pid){ + String sqlQuery="select * from payment where id = ?"; + return jdbcTemplate.queryForMap(sqlQuery,pid); + } +} diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/SMSService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/SMSService.java new file mode 100644 index 0000000..813c33a --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/SMSService.java @@ -0,0 +1,69 @@ +package com.gcc.restapiservices.coworkspace.service; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.net.HttpURLConnection; +import java.net.URL; + +@Service +public class SMSService { + + + + public String sendMsg(String msgUrl) { + System.out.println("Whatsapp URL :-"+msgUrl); + + String response =""; + try{ + HttpURLConnection connection =null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response=responseCode+""; + System.out.println("Response Code: " + responseCode); + + }catch (Exception e){ + e.printStackTrace(); + } + + return response; + } + + public String sendSMS( String SMS_Url, String mobileNo, String otp) { + + System.out.println("SMS URL:- "+ SMS_Url); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(SMS_Url, String.class); + + // Using Jackson ObjectMapper to parse the response JSON + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + // Add mobileNo and otp to the response JSON + jsonResponse.put("MobileNo", mobileNo); + jsonResponse.put("otp", otp); + + // Convert the updated JSON object back to string + bodyMessage = jsonResponse.toString(); +// bodyMessage=Response; + System.out.println("\n bodyMessage"+bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: "+e); + bodyMessage = "Error"; + } + + return bodyMessage; + } +} diff --git a/src/main/java/com/gcc/restapiservices/coworkspace/service/WhatsAppService.java b/src/main/java/com/gcc/restapiservices/coworkspace/service/WhatsAppService.java new file mode 100644 index 0000000..46121d4 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/coworkspace/service/WhatsAppService.java @@ -0,0 +1,102 @@ +package com.gcc.restapiservices.coworkspace.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class WhatsAppService { + + @Autowired + private SMSService whatsappMsgService; + + String password = "h2YjFNcJ"; + + public String sendOTP(String mobileNo, String msg) { + String msgContent ="https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+mobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Welcome+to+Mudhalvar+Padaipagam%2C+%0A%0AThe+OTP+for+your+booking+is+"+msg+"%2A"; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendELearnNmsg(String MobileNo, String noOfPerson, String bdate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron%2C%0AWelcome+to+Muthalvar+Padaippagam%F0%9F%99%8F++%0A%0AYou+have+booked+our+Learning+Centre+for+%2A"+noOfPerson+"%2A+number+of+persons+on+%2A"+bdate+"%2A+at+%0Atime+slot+%2A"+slot+"%2A+.%0A%0APayment+for+the+booking+is+%2ARs.+"+amount+"%2A+received.+%0A%0APlease+show+your+QR+Code+at+Reception+Desk+for+accessing+Muthalvar+Padaippagam.%0A%0AHave+a+Nice+Day%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendTLearnNmsg(String MobileNo, String noOfPerson, String bdate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81+%F0%9F%99%8F++%0A%0A%E0%AE%A4%E0%AE%BE%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%95%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AE%B2%E0%AF%8D+%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%88++%2A"+noOfPerson+"%2A+%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%A3%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88+%E0%AE%A8%E0%AE%AA%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81++%2A"+bdate+"%2A+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AF%81++%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+%2A"+slot+"%2A+%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.+.%0A%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9++%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82.+"+amount+"%2A+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.%0A%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%B1%E0%AF%88%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.%0A%0A%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AF+%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AE%BE%E0%AE%AF%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendEDeskspaceNmsg(String MobileNo, String noOfPerson, String bdate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron%2C%0AWelcome+to+Muthalvar+Padaippagam%F0%9F%99%8F++%0A%0AYou+have+booked+our+Desk+space+for+%2A"+noOfPerson+"%2A+number+of+persons+on+%2A"+bdate+"%2A+at+time+slot+%2A"+slot+"%2A+.%0A%0APayment+for+the+booking+is+%2ARs.+"+amount+"%2A+received.+%0A%0APlease+show+your+QR+Code+at+Reception+Desk+for+accessing+Muthalvar+Padaippagam.%0A%0AHave+a+Nice+Day%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendTDeskspaceNmsg(String MobileNo, String noOfPerson, String bdate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81%F0%9F%99%8F++%0A%0A%E0%AE%A4%E0%AE%BE%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%AE%E0%AF%87%E0%AE%9A%E0%AF%88+%E0%AE%87%E0%AE%9F%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+%2A"+noOfPerson+"%2A+%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%A3%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88+%E0%AE%A8%E0%AE%AA%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+%2A"+bdate+"%2A+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AF%81+%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+%2A"+slot+"%2A+%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.%0A%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9++%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82.+"+amount+"%2A+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.+%0A%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%B1%E0%AF%88%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%0A%0A%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AF+%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AE%BE%E0%AE%AF%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendEMonthDeskspaceNmsg(String MobileNo, String noOfPerson, String bFromdate,String bTodate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron%2C%0AWelcome+to+Muthalvar+Padaippagam%F0%9F%99%8F++%0A%0AYou+have+booked+our+Desk+space+for+%2A"+noOfPerson+"%2A+number+of+persons+for+30+days+from+%2A"+bFromdate+"+to+"+bTodate+"%2A+at+time+slot+%2A"+slot+"%2A.%0A%0APayment+for+the+booking+is+%2ARs.+"+amount+"%2A+received.+%0A%0APlease+show+your+QR+Code+at+Reception+Desk+for+accessing+Muthalvar+Padaippagam.%0A%0AHave+a+Nice+Day%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendTMonthDeskspaceNmsg(String MobileNo, String noOfPerson, String bfromDate,String btoDate, String slot, String amount, String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to="+MobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81+%F0%9F%99%8F++%0A%0A%E0%AE%A4%E0%AE%BE%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%AE%E0%AF%87%E0%AE%9A%E0%AF%88+%E0%AE%87%E0%AE%9F%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%88+%2A"+noOfPerson+"%2A+%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%A3%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88+%E0%AE%A8%E0%AE%AA%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+30+%E0%AE%A8%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%2A"+bfromDate+"+%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D+"+btoDate+"%2A+%E0%AE%B5%E0%AE%B0%E0%AF%88+%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+%2A"+slot+"%2A+%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.%0A%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9++%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82.+"+amount+"%2A+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.%0A%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%B1%E0%AF%88%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%0A%0A%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AF+%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AE%BE%E0%AE%AF%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendEConfeNmsg(String mobileNo, String bdate, String slot, String amount,String bookingId) { + String msgContent= "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to="+mobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron%2C%0AWelcome+to+Muthalvar+Padaippagam%F0%9F%99%8F++%0A%0AYou+have+booked+our+Conference+Hall+on+%2A"+bdate+"%2A+at+time+slot+%2A"+slot+"%2A+.%0A%0APayment+for+the+booking+is+%2ARs.+"+amount+"%2A+received.+%0A%0APlease+show+your+QR+Code+at+Reception+Desk+for+accessing+Muthalvar+Padaippagam.%0A%0AHave+a+Nice+Day%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + System.out.println(msgContent); + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendTConfeNmsg(String mobileNo, String bdate, String slot, String amount,String bookingId) { + String msgContent = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to="+mobileNo+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81+%F0%9F%99%8F++%0A%0A%E0%AE%A4%E0%AE%BE%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%95%E0%AE%B2%E0%AE%A8%E0%AF%8D%E0%AE%A4%E0%AE%BE%E0%AE%AF%E0%AF%8D%E0%AE%B5%E0%AF%81+%E0%AE%85%E0%AE%B0%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+%2A"+bdate+"%2A+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AF%81++%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+%2A"+slot+"%2A+%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.+%0A%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9++%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82.+"+amount+"%2A+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.+%0A%0A%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D%E0%AE%B5%E0%AE%B0%E0%AF%8D+%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%95%E0%AE%AE%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%B1%E0%AF%88%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%0A%0A%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AF+%E0%AE%A8%E0%AE%BE%E0%AE%B3%E0%AE%BE%E0%AE%AF%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D%F0%9F%98%8A&isTemplate=true&buttonUrlParam=muthalvarpadaippagam%2FbookingQRCode%3Fbooking_id%3D"+bookingId; + return whatsappMsgService.sendMsg(msgContent); + } + + public String sendSMS( String SMS_Url, String mobileNo, String otp) { + + System.out.println("SMS URL:- "+ SMS_Url); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(SMS_Url, String.class); + + // Using Jackson ObjectMapper to parse the response JSON + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + // Add mobileNo and otp to the response JSON + jsonResponse.put("MobileNo", mobileNo); + jsonResponse.put("otp", otp); + + // Convert the updated JSON object back to string + bodyMessage = jsonResponse.toString(); +// bodyMessage=Response; + System.out.println("\n bodyMessage"+bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: "+e); + bodyMessage = "Error"; + } + + return bodyMessage; + } + + +} diff --git a/src/main/java/com/gcc/restapiservices/crslogs/controller/CrsLogsApiController.java b/src/main/java/com/gcc/restapiservices/crslogs/controller/CrsLogsApiController.java new file mode 100644 index 0000000..7c245c1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/crslogs/controller/CrsLogsApiController.java @@ -0,0 +1,264 @@ +package com.gcc.restapiservices.crslogs.controller; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Random; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.client.RestTemplate; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.crslogs.service.CrsLogsService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@RestController +@RequestMapping("/gccrestservices/crslogs/api") +public class CrsLogsApiController { + + + @Autowired + private CrsLogsService crsLogsService; + + @Autowired + private AppConfig appConfig; + + +// @PostMapping("/saveCrsCertificateLogs") +// public ResponseEntity saveCrsCertificateLogs(HttpServletRequest request, +// @RequestParam String regNo, +// @RequestParam String eventDate, +// @RequestParam String Url, +// @RequestParam String service, +// @RequestParam(required = false) String application_flag, +// @RequestParam(required = false) String mobile_number) { +// +// // Set default value if not passed +// if (application_flag == null || application_flag.trim().isEmpty()) { +// application_flag = "whatsapp"; +// } +// +// return crsLogsService.saveCrsCertificateLogs(regNo, eventDate, Url, service, application_flag, mobile_number); +// } + + + + @PostMapping("/saveCrsCertificateLogs") + public ResponseEntity> saveCrsCertificateLogs( + HttpServletRequest request, + @RequestParam String regNo, + @RequestParam String eventDate, + @RequestParam String Url, + @RequestParam String service, + @RequestParam(required = false) String application_flag, + @RequestParam(required = false) String mobile_number) { + + Map response = new LinkedHashMap<>(); + + try { + // Validate required fields + if (regNo == null || regNo.trim().isEmpty()) { + return badRequest("regNo is required"); + } + if (eventDate == null || eventDate.trim().isEmpty()) { + return badRequest("eventDate is required"); + } + if (Url == null || Url.trim().isEmpty()) { + return badRequest("Url is required"); + } + if (service == null || service.trim().isEmpty()) { + return badRequest("service is required"); + } + + // Default application_flag if not provided + if (application_flag == null || application_flag.trim().isEmpty()) { + application_flag = "whatsapp"; + } + + int count = crsLogsService.saveCrsCertificateLogs( + regNo.trim(), eventDate.trim(), Url.trim(), service.trim(), + application_flag.trim(), mobile_number != null ? mobile_number.trim() : null + ); + + if (count > 0) { + response.put("status", true); + response.put("message", "Details saved successfully"); + response.put("status_code", 200); + return ResponseEntity.ok(response); + } else { + response.put("status", false); + response.put("message", "Failed to save details"); + response.put("status_code", 500); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + + } catch (Exception ex) { + response.put("status", false); + response.put("message", "An unexpected error occurred: " + ex.getMessage()); + response.put("status_code", 500); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + private ResponseEntity> badRequest(String message) { + Map error = new LinkedHashMap<>(); + error.put("status", false); + error.put("message", message); + error.put("status_code", 400); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); + } + + + + + +/*///////////////// otp configuration /////////////////////*/ + +// @GetMapping(value = "/sendOTP") +// public String sendOtp(HttpServletRequest request, @RequestParam String mobile) { +// +// // Create an ObjectMapper instance +// ObjectMapper objectMapper = new ObjectMapper(); +// +// Map response = new HashMap<>(); +// +// String MobileNo=mobile; +// System.out.print("\n MobileNo---:"+mobile); +// Random rand = new Random(); +// int otp = rand.nextInt(90000) + 10000; +// +// //int otp= 22222; +// System.out.print("\n otp---:"+otp); +// DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); +// LocalDateTime now = LocalDateTime.now(); +// System.out.println(dtf.format(now)); +// //String generatedToken = "Welcome to GCC! Your OTP for C%26D waste collectors Registration process is "+otp; +// +// //String generatedToken = "Welcome to GCC "+otp+" is your OTP for gcc QR System"; +// +// String generatedToken = "Welcome to GCC! Your OTP for Birth and Death Certificate login is " + otp; +// //String generatedToken = "Welcome to GCC! Your OTP for C and D waste collectors Registration process is " + otp; +//// String key="qxg4mklD"; +// String key="pfTEYN6H"; +// String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407174687453240990"; +// +// +// //String urlString = "https://tmegov.onex-aura.com/api/sms?from=GCCCRP&key=pfTEYN6H&sender=GCCCRP&to=9360777472&body=Welcome%20to%20GCC!%20Your%20OTP%20for%20C%26D%20waste%20collectors%20Registration%20process%20is%20"+otp+"&entityid=1401572690000011081&templateid=1407172959127552127"; +// //String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407168250479102852"; +//// String urlString=appConfig.getGetOtpUrl()+"user=GCCtrans&authkey=92kOC1RBGBIws&sender=GCCCRP&mobile="+MobileNo+"&text="+generatedToken+"&rpt=1&summary=1&output=json&entityid=1401572690000011081&templateid=1407168250479102852"; +// System.out.print("\n urlString---: "+urlString); +// String bodyMessage = ""; +// +// +// if (mobile == null || mobile.trim().isEmpty()) { +// throw new IllegalArgumentException("Mobile number is required"); +// } +// +// // Validate mobile number is exactly 10 digits +// if (!mobile.matches("\\d{10}")) { +// throw new IllegalArgumentException("Mobile number must be exactly 10 digits"); +// } +// +// try { +// RestTemplate restTemplate = new RestTemplate(); +// String Response = restTemplate.getForObject(urlString, String.class); +// +// // Step 1: Ensure user is registered +// int userId = crsLogsService.ensureUserExists(mobile); +// System.out.println("\n User ID (existing or new): " + userId); +// +// ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); +// +// // Add mobileNo and otp to the response JSON +// jsonResponse.put("MobileNo", MobileNo); +// jsonResponse.put("otp", otp); +// +// +// bodyMessage= jsonResponse.toString(); +// System.out.println("\n bodyMessage"+bodyMessage); +// +// System.out.println("OTP sent successfully!"); +// +// } catch (Exception e) { +// e.printStackTrace(); +// System.out.println("ERROR---: " + e.getMessage()); +// bodyMessage = "Error"; +// } +// HttpSession session = request.getSession(); +// session.setAttribute("otp", otp); +// return bodyMessage; +// +// } + + + @GetMapping(value = "/sendOTP") + public ResponseEntity> sendOtp(HttpServletRequest request, + @RequestParam String mobile) { + Map response = new HashMap<>(); + + try { + if (mobile == null || mobile.trim().isEmpty()) { + response.put("status", false); + response.put("message", "Mobile number is required"); + response.put("status_code", HttpStatus.BAD_REQUEST.value()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + if (!mobile.matches("\\d{10}")) { + response.put("status", false); + response.put("message", "Mobile number must be exactly 10 digits"); + response.put("status_code", HttpStatus.BAD_REQUEST.value()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + String generatedToken = "Welcome to GCC! Your OTP for Birth and Death Certificate login is " + otp; + + String key = "pfTEYN6H"; + String urlString = appConfig.getGetOtpUrl() + + "from=GCCCRP&key=" + key + + "&sender=GCCCRP&to=" + mobile + + "&body=" + generatedToken + + "&entityid=1401572690000011081&templateid=1407174687453240990"; + + RestTemplate restTemplate = new RestTemplate(); + String smsResponse = restTemplate.getForObject(urlString, String.class); + + int userId = crsLogsService.ensureUserExists(mobile); + System.out.println("\n User ID (existing or new): " + userId); + + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + + response.put("MobileNo", mobile); + response.put("otp", otp); + response.put("message", "OTP sent successfully"); + response.put("status", HttpStatus.OK.value()); + + return ResponseEntity.ok(response); + + } catch (Exception e) { + e.printStackTrace(); + response.put("status", false); + response.put("message", "Error while sending OTP: " + e.getMessage()); + response.put("status_code", HttpStatus.INTERNAL_SERVER_ERROR.value()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + +} diff --git a/src/main/java/com/gcc/restapiservices/crslogs/service/CrsLogsService.java b/src/main/java/com/gcc/restapiservices/crslogs/service/CrsLogsService.java new file mode 100644 index 0000000..95c0502 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/crslogs/service/CrsLogsService.java @@ -0,0 +1,80 @@ +package com.gcc.restapiservices.crslogs.service; + +import java.util.List; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Service +public class CrsLogsService { + + + private JdbcTemplate jdbcTemplate; + + + @Autowired + public void setDataSource(@Qualifier("mysqlCrsLogsDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + + + +// public ResponseEntity saveCrsCertificateLogs(String regNo, String eventDate, String url, String service, String application_flag, String mobile_number) { +// String sql = "INSERT INTO certificate_logs (regno, event_date, english_url, service, application_flag, mobile_number) VALUES (?, ?, ?, ?, ?, ?)"; +// Integer count = jdbcTemplate.update(sql, regNo, eventDate, url, service, application_flag, mobile_number); +// return count != null && count > 0 ? ResponseEntity.ok(count) : ResponseEntity.notFound().build(); +// } + +// public int saveCrsCertificateLogs(String regNo, String eventDate, String url, String service, String application_flag, String mobile_number) { +// String sql = "INSERT INTO certificate_logs (regno, event_date, english_url, service, application_flag, user_mobile) VALUES (?, ?, ?, ?, ?, ?)"; +// +// try { +// return jdbcTemplate.update(sql, regNo, eventDate, url, service, application_flag, mobile_number); +// } catch (Exception e) { +// System.err.println("SQL Error: " + e.getMessage()); +// throw e; // rethrow to let controller handle it +// } +// } + + + public int saveCrsCertificateLogs(String regNo, String eventDate, String url, String service, + String application_flag, String mobile_number) { + try { + Integer userId = null; + if (mobile_number != null && !mobile_number.trim().isEmpty()) { + userId = ensureUserExists(mobile_number.trim()); + } + + String sql = "INSERT INTO certificate_logs (regno, event_date, english_url, service, application_flag, user_id,user_mobile) " + + "VALUES (?, ?, ?, ?, ?, ?,?)"; + + return jdbcTemplate.update(sql, regNo, eventDate, url, service, application_flag, userId,mobile_number); + } catch (Exception e) { + System.err.println("SQL Error: " + e.getMessage()); + throw e; + } + } + + + + public int ensureUserExists(String mobile) { + String checkUserSql = "SELECT user_id FROM users WHERE user_mobile = ? "; + String insertUserSql = "INSERT INTO users (user_name, user_address, user_mobile) VALUES (?, ?, ?)"; + + List result = jdbcTemplate.query(checkUserSql, (rs, rowNum) -> rs.getInt("user_id"), mobile); + + if (result.isEmpty()) { + jdbcTemplate.update(insertUserSql, "-", "-", mobile); + } + + // Always return the user id + return jdbcTemplate.queryForObject(checkUserSql, Integer.class, mobile); + } + + +} diff --git a/src/main/java/com/gcc/restapiservices/feedback/controller/FeedbackController.java b/src/main/java/com/gcc/restapiservices/feedback/controller/FeedbackController.java new file mode 100644 index 0000000..0437c34 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/feedback/controller/FeedbackController.java @@ -0,0 +1,127 @@ +package com.gcc.restapiservices.feedback.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.gcc.restapiservices.cdwaste.util.ApiResponseUtil; +import com.gcc.restapiservices.feedback.service.FeedbackService; + +@RestController +@RequestMapping("/gccrestservices/feedback/api") +public class FeedbackController { + + @Autowired + private FeedbackService feedbackService; + + @GetMapping("/getMasterServiceList") + public ResponseEntity getMasterService() { + List> result = feedbackService.getMasterService(); + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + return ApiResponseUtil.success(result, "Data found"); + } + +// @GetMapping("/getSubServiceList") +// public ResponseEntity getSubServiceList(@RequestParam String serviceId) { +// int sId = 0; +// +// if (serviceId.isEmpty() ||serviceId == null) { +// return ApiResponseUtil.error("Please enter valid serviceId", HttpStatus.BAD_REQUEST); +// } +// else { +// sId = Integer.parseInt(serviceId); +// } +// +// List> result = feedbackService.getSubServiceList(sId); +// if (result.isEmpty()) { +// return ApiResponseUtil.notFound("No data found"); +// } +// return ApiResponseUtil.success(result, "Data found"); +// } + + @GetMapping("/getSubServiceList") + public ResponseEntity getSubServiceList(@RequestParam(required = false) String serviceId) { + if (serviceId == null || serviceId.trim().isEmpty()) { + return ApiResponseUtil.error("Please enter valid serviceId", HttpStatus.BAD_REQUEST); + } + + int sId; + try { + sId = Integer.parseInt(serviceId); + } catch (NumberFormatException e) { + return ApiResponseUtil.error("Invalid serviceId format", HttpStatus.BAD_REQUEST); + } + + // Restricted service IDs (no subservice available) + List restrictedIds = Arrays.asList(7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21); + if (restrictedIds.contains(sId)) { + return ApiResponseUtil.error("No subservice available for this serviceId", HttpStatus.NOT_FOUND); + } + + List> result = feedbackService.getSubServiceList(sId); + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } + + + @PostMapping("/saveFeedback") + public ResponseEntity saveFeedbackDetails(@RequestParam String userName, + @RequestParam String mobno, + @RequestParam String categoryId, + @RequestParam (required =false) String subCategoryId, + @RequestParam String remarks, + @RequestParam(required = false) MultipartFile feedbackImage) { + + String imgPath=""; + int cid =0; + int subid =0; + + + try { + + if (userName.isEmpty() || userName == null) { + return ApiResponseUtil.error("Please enter valid user name", HttpStatus.BAD_REQUEST); + } + if (mobno == null || !mobno.matches("\\d{10}")) { + return ApiResponseUtil.error("Please enter a valid 10-digit mobile number", HttpStatus.BAD_REQUEST); + } + if (categoryId.isEmpty()||categoryId == null) { + return ApiResponseUtil.error("Invalid category selected", HttpStatus.BAD_REQUEST); + }else { + cid = Integer.parseInt(categoryId); + } + if (!subCategoryId.isEmpty()&& subCategoryId != null) { + subid = Integer.parseInt(subCategoryId); + } + if (remarks == null || remarks.trim().isEmpty()) { + return ApiResponseUtil.error("Remarks cannot be empty", HttpStatus.BAD_REQUEST); + } + + if(!feedbackImage.isEmpty()){ + imgPath = feedbackService.saveFeedbackImage(feedbackImage); + } + + return feedbackService.saveFeedbackDetails(userName, mobno, cid, subid, remarks, imgPath); + + } catch (Exception e) { + e.printStackTrace(); + return ApiResponseUtil.error("Something went wrong: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } +} diff --git a/src/main/java/com/gcc/restapiservices/feedback/service/FeedbackService.java b/src/main/java/com/gcc/restapiservices/feedback/service/FeedbackService.java new file mode 100644 index 0000000..e234b11 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/feedback/service/FeedbackService.java @@ -0,0 +1,125 @@ +package com.gcc.restapiservices.feedback.service; + +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.PreparedStatement; +import java.util.List; +import java.util.Map; +import java.util.Random; + +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.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.gcc.restapiservices.cdwaste.util.ApiResponseUtil; +import com.gcc.restapiservices.cdwaste.util.DateTimeUtil; + +@Service +public class FeedbackService { + + @Autowired + private Environment environment; + + @Autowired + public void setDataSource(@Qualifier("mysqlFeedbackDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private JdbcTemplate jdbcTemplate; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + public List> getMasterService() { + String sql = "Select * from master_service where is_active =1"; + return jdbcTemplate.queryForList(sql); + + } + + public List> getSubServiceList(int serviceId) { + String sql = "Select * from sub_service where master_id =? and is_active =1"; + return jdbcTemplate.queryForList(sql, serviceId); + } + + public String saveFeedbackImage(MultipartFile FeedbackImage) throws IOException { + + String img_url = ""; + if (FeedbackImage == null || FeedbackImage.isEmpty()) { + return img_url; + } + + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("feedback_directory"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + + uploadDirectory = uploadDirectory + "/" + serviceFolderName + "/" + year + "/" + month; + + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + String fileName = datetimetxt + "" + generateRandomStringForFile(10) + "_" + + FeedbackImage.getOriginalFilename(); + + String filepath = uploadDirectory + "/" + fileName; + String filepath_txt = "/" + serviceFolderName + "/" + year + "/" + month + "/" + fileName; + Path path = Paths.get(filepath); + + Files.createDirectories(path.getParent()); + + Files.write(path, FeedbackImage.getBytes()); + + img_url = filepath_txt; + + return img_url; + } + + public static String generateRandomStringForFile(int String_Lenth) { + StringBuilder result = new StringBuilder(String_Lenth); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public ResponseEntity saveFeedbackDetails(String userName, String mobno, int categoryId, int subCategoryId, + String remarks, + String imgPath) { + + String sql = "INSERT INTO feedback_details (user_name, mobile_no, service_id, subservice_id, remarks, img_path) " + + "VALUES (?, ?, ?, ?, ?, ?)"; + + int rowsAffected = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql); + ps.setString(1, userName.trim()); + ps.setString(2, mobno.trim()); + ps.setInt(3, categoryId); + ps.setInt(4, subCategoryId); + ps.setString(5, remarks.trim()); + ps.setString(6, imgPath); + return ps; + }); + + if (rowsAffected > 0) { + return ApiResponseUtil.success( null,"Feedback submitted successfully"); + } else { + return ApiResponseUtil.error("Failed to save feedback. Please try again", null); + } + + } + +} diff --git a/src/main/java/com/gcc/restapiservices/nearbyservices/controller/LocationController.java b/src/main/java/com/gcc/restapiservices/nearbyservices/controller/LocationController.java new file mode 100644 index 0000000..faced88 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/nearbyservices/controller/LocationController.java @@ -0,0 +1,108 @@ +package com.gcc.restapiservices.nearbyservices.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; + + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; + +@RestController +@RequestMapping("/gccrestservices/api/location") +public class LocationController { + + @Value("${google.api.key}") + private String googleApiKey; + + @Value("${gis.api.url}") + private String gisApiUrl; + + private final RestTemplate restTemplate = new RestTemplate(); + + @GetMapping("/getDetails") + public ResponseEntity getLocationDetails(@RequestParam String address) { + try { + if (address == null || address.trim().isEmpty()) { + return ResponseEntity.badRequest().body(Collections.singletonMap("error", "Address is required")); + } + + String searchUrl = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json" + + "?input=" + URLEncoder.encode(address, StandardCharsets.UTF_8) + + "&inputtype=textquery" + + "&fields=geometry" + + "&key=" + googleApiKey; + + Map searchResponse = restTemplate.getForObject(searchUrl, Map.class); + if (searchResponse == null || !"OK".equals(searchResponse.get("status"))) { + return ResponseEntity.badRequest() + .body(Collections.singletonMap("error", "Invalid address or Google Places API error")); + } + + List> candidates = (List>) searchResponse.get("candidates"); + if (candidates == null || candidates.isEmpty()) { + return ResponseEntity.badRequest() + .body(Collections.singletonMap("error", "No location found for the given address")); + } + + Map firstCandidate = candidates.get(0); + Map geometry = (Map) firstCandidate.get("geometry"); + Map location = (Map) geometry.get("location"); + + double latitude = Math.floor((double) location.get("lat") * 1_000_000.0) / 1_000_000.0; + double longitude = Math.floor((double) location.get("lng") * 1_000_000.0) / 1_000_000.0; + + // String geometryJson = String.format( + // "{\"x\":%f,\"y\":%f,\"spatialReference\":{\"wkid\":4326}}", + // longitude, latitude); + + // String gisUrl = + // "https://gisgcc.chennaicorporation.gov.in/server/rest/services/GCCDepts/EDPMobile2025/FeatureServer/0/query"; + + // String params = "f=json" + // + "&geometry=" + URLEncoder.encode(geometryJson, StandardCharsets.UTF_8) + // + "&geometryType=esriGeometryPoint" + // + "&inSR=4326" + // + "&spatialRel=esriSpatialRelIntersects" + // + "&distance=25" + // + "&units=esriSRUnit_Meter" + // + "&outFields=region,new_zone,new_ward,road_id,road_name,gis_id,type" + // + "&returnGeometry=false"; + + // HttpHeaders headers = new HttpHeaders(); + // headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + // HttpEntity request = new HttpEntity<>(params, headers); + + // Map gisMap = restTemplate.postForObject(gisUrl, request, + // Map.class); + + // if (gisMap == null) { + // return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE) + // .body(Collections.singletonMap("error", "Empty GIS response")); + // } + // if (gisMap.containsKey("error")) { + // return ResponseEntity.badRequest().body(gisMap.get("error")); + // } + + // List> gisResponse = + // (List>) gisMap.getOrDefault("features", + // Collections.emptyList()); + + Map response = new LinkedHashMap<>(); + response.put("latitude", latitude); + response.put("longitude", longitude); + response.put("address", address); + // response.put("gis_data", gisResponse); + + return ResponseEntity.ok(response); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Collections.singletonMap("error", "Server error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/nearbyservices/controller/NearByController.java b/src/main/java/com/gcc/restapiservices/nearbyservices/controller/NearByController.java new file mode 100644 index 0000000..ad6cb59 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/nearbyservices/controller/NearByController.java @@ -0,0 +1,94 @@ +package com.gcc.restapiservices.nearbyservices.controller; + +import java.util.HashMap; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import java.util.Map; + + +import com.gcc.restapiservices.nearbyservices.service.NearByService; +import org.json.JSONArray; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + + +@RequestMapping("/gccrestservices/api/nearbyservices") +@RestController +public class NearByController { + private NearByService nearByService; + @Autowired + public NearByController(NearByService nearByService) { + this.nearByService = nearByService; + } + +// @GetMapping("/toilets") +// public ResponseEntity> getToilets(@RequestParam(value = "lat") String lat, +// @RequestParam(value = "lng") String lng){ +// Map result = new HashMap<>(); +// try { +// //String url1="https://chennaicorporation.gov.in/gcc/citizen-details/location-service/mob_ser_toilet.jsp?ServiceID=GetToilet&SetInput={citizenzone:"+""+",citizendivision:"+""+",lat:"+lat+",longt:"+lng+"}"; +// String inputJson = String.format("{\"citizenzone\":\"\",\"citizendivision\":\"\",\"lat\":\"%s\",\"longt\":\"%s\"}", lat, lng); +// String encodedJson = URLEncoder.encode(inputJson, StandardCharsets.UTF_8); +// String urlString = "https://chennaicorporation.gov.in/gcc/citizen-details/location-service/mob_ser_toilet.jsp?ServiceID=GetToilet&SetInput=" + encodedJson; +// System.out.println(urlString); +// +// +// URL url = new URL(urlString); +// URLConnection urlcon=url.openConnection(); +// InputStream stream=urlcon.getInputStream(); +// StringBuilder responseBuilder = new StringBuilder(); +// int i; +// while((i=stream.read())!=-1){ +// responseBuilder.append((char) i); +// } +// stream.close(); +// +// // Clean and extract actual JSON part +// String rawResponse = responseBuilder.toString().trim(); +// System.out.println("rawResponse="+rawResponse); +// // Get JSON object +// JSONObject responseJson = new JSONObject(rawResponse); +// +// // Check if TOILETS exists and is not empty +// if (responseJson.has("TOILETS")) { +// JSONArray toiletsArray = responseJson.getJSONArray("TOILETS"); +// +// if (toiletsArray.length() == 0) { +// result.put("Message", "No Data Found"); +// result.put("Data", new JSONObject()); // or result.put("Data", Collections.emptyMap()); +// } else { +// result.put("Message", "Success"); +// result.put("Data", responseJson.toMap()); // Convert full response JSON to Map +// } +// } else { +// result.put("Message", "TOILETS key missing"); +// result.put("Data", new JSONObject()); +// } +// +// +// +// } +// catch (Exception e) { +// e.printStackTrace(); +// result.put("Message", "Error"); +// } +// return ResponseEntity.ok(result); +// } + + @PostMapping(value = "/details") + public Map getServiceDetails(@RequestParam(value = "lat") String lat, + @RequestParam(value = "lng") String lng, + @RequestParam(value = "service") String service) { + return nearByService.getPropertyList(lat, lng, service); + } + @PostMapping(value = "/services") + public Map getServices() { + return nearByService.getServices(); + } +} diff --git a/src/main/java/com/gcc/restapiservices/nearbyservices/service/NearByService.java b/src/main/java/com/gcc/restapiservices/nearbyservices/service/NearByService.java new file mode 100644 index 0000000..64ddb32 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/nearbyservices/service/NearByService.java @@ -0,0 +1,633 @@ +package com.gcc.restapiservices.nearbyservices.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; +import org.springframework.http.ResponseEntity; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class NearByService { + private JdbcTemplate mysqlJdbcTemplate; + private JdbcTemplate communityJdbcTemplate; + + @Autowired + public void setMysqlDataSource(@Qualifier("mysqlServicespdfDataSource") DataSource mysqlDataSource) { + this.mysqlJdbcTemplate = new JdbcTemplate(mysqlDataSource); + } + @Autowired + public void setDataSource(@Qualifier("mysqlCommunityHallDataSource") DataSource dataSource) { + this.communityJdbcTemplate = new JdbcTemplate(dataSource); + } + + // @Transactional("mysqlNearByServicesfDataSource") + public Map getPropertyList(String lat, String lng, String service) { + Map response = new HashMap<>(); + Map result = new HashMap<>(); + if(service.equalsIgnoreCase("Burial Ground")){ + result = getburialGround(lat,lng); + } else if(service.equalsIgnoreCase("Amma Unavagam")){ + result = getammaUnavagam(lat,lng); + } else if(service.equalsIgnoreCase("Bus Shelter")) { + result = getbusShelter(lat,lng); + } else if(service.equalsIgnoreCase("Toilets")) { + result = gettoilets(lat,lng); + } else if(service.equalsIgnoreCase("School")) { + result = getschools(lat,lng); + } else if(service.equalsIgnoreCase("Community Center")) { + result = getCommunityCenter(lat,lng); + } else if(service.equalsIgnoreCase("UPHC") || service.equalsIgnoreCase("UCHC")) { + result = getUphcUchc(lat,lng,service); + } + response.put("Response", result); + return response; + } + + private Map getCommunityCenter(String lat, String lng) { + Map result = new HashMap<>(); + String sql = "SELECT hd.hall_name, " + + " hd.zone, " + + " hd.division, " + + " hd.door_no, " + + " hd.street, " + + " hd.area, " + + " hd.city, " + + " hd.pin_code, " + + " hd.parking_capacity, " + + " hd.seating_capacity, " + + " hd.half_day_rent, " + + " hd.full_day_rent, " + + " hd.half_deposit_amount, " + + " hd.deposit_amount, " + + " hd.eb_cost_per_unit, " + + " hd.gst, " + + " hd.latitude, " + + " hd.longitude " + + " FROM hall_details hd WHERE (hd.is_active=1) AND " + + " ((6371008.8 * acos( ROUND(cos(radians(?)) * cos(radians(hd.latitude)) * cos(radians(hd.longitude) - radians(?)) + " + + " sin(radians(?)) * sin(radians(hd.latitude)), 9) )) < 1000)"; + try{ + List> data = communityJdbcTemplate.queryForList(sql, lat, lng, lat); + if (!data.isEmpty()) { + result.put("Community Center", data); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Community Center List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "Community Center Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + e.printStackTrace(); + result.put("Status", "Error"); + result.put("Message", "Error in fetching Community Center list :" + e); + result.put("Status Code", 500); + } + return result; + } + + private Map getUphcUchc(String lat, String lng, String service) { + Map result = new HashMap<>(); + String sql = "SELECT " + + " uc.zone, " + + " uc.ward, " + + " uc.uc_name, " + + " uc.address, " + + " uc.mail_id, " + + " uc.contact, " + + " uc.contact_name, " + + " uc.contact_number, " + + " uc.special_facilities, " + + " uc.latitude, " + + " uc.longitude " + + " FROM uphc_uchc uc WHERE (uc.is_active=1 AND uc.is_delete=0 AND uc.type=?) AND " + + " ((6371008.8 * acos( ROUND(cos(radians(?)) * cos(radians(uc.latitude)) * cos(radians(uc.longitude) - radians(?)) + " + + " sin(radians(?)) * sin(radians(uc.latitude)), 9) )) < 1000)"; + try{ + List> data = mysqlJdbcTemplate.queryForList(sql, service, lat, lng, lat); + if (!data.isEmpty()) { + result.put(service, data); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", service+" List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", service+" Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching "+service+" list :" + e); + result.put("Status Code", 500); + } + return result; + } + + private Map getschools(String lat, String lng) { + Map result = new HashMap<>(); + List> data1 = new ArrayList<>(); + String urlString="https://gccservices.in/gccofficialapp/api/gcceducation/getSchoolList?latitude="+lat+"&longitude="+lng; + + try{ + List> dataList = geturldata(urlString); + + if (!dataList.isEmpty()) { + for(Map i:dataList) { + Map data = new HashMap<>(); + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("division") != null && !i.get("division").toString().trim().isEmpty()) + ? i.get("division").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; + String udise = (i.get("udise") != null && !i.get("udise").toString().trim().isEmpty()) + ? i.get("udise").toString().trim() + : ""; + String school_name = (i.get("school_name") != null && !i.get("school_name").toString().trim().isEmpty()) + ? i.get("school_name").toString().trim() + : ""; + String school_address = (i.get("address") != null && !i.get("address").toString().trim().isEmpty()) + ? i.get("address").toString().trim() + : ""; + String category = (i.get("category_type") != null && !i.get("category_type").toString().trim().isEmpty()) + ? i.get("category_type").toString().trim() + : ""; + String hm_name = (i.get("hm_name") != null && !i.get("hm_name").toString().trim().isEmpty()) + ? i.get("hm_name").toString().trim() + : ""; + String hm_mobile = (i.get("hm_phone_number") != null && !i.get("hm_phone_number").toString().trim().isEmpty()) + ? i.get("hm_phone_number").toString().trim() + : ""; + + data.put("Zone", zone); + data.put("Ward", ward); + data.put("Latitude", latitude); + data.put("Longitude", longitude); + data.put("UDISE", udise); + data.put("School Name", school_name); + data.put("School Address", school_address); + data.put("Category", category); + data.put("HM_Name", hm_name); + data.put("HM_Mobile", hm_mobile); + data1.add(data); + } + result.put("Bus Shelter", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "School List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "School List Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Bus School List :" + e); + result.put("Status Code", 500); + } + return result; + } + + private Map gettoilets(String lat, String lng) { + Map result = new HashMap<>(); + List> data1 = new ArrayList<>(); + String urlString = "https://gccservices.in/gccofficialapp/api/toilets/toiletlistRest?latitude=" + lat + "&longitude=" + lng; + String urlString1 = "https://gccservices.in/gccofficialapp/api/privatetoilets/toiletlistRest?latitude=" + lat + "&longitude=" + lng; + try { + + List> dataList = geturldata(urlString); + List> dataList1 = geturldata(urlString1); + // GCC Toilet + if (!dataList.isEmpty()) { + for (Map i : dataList) { + Map data = new HashMap<>(); + + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("ward") != null && !i.get("ward").toString().trim().isEmpty()) + ? i.get("ward").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; + String street_name = (i.get("name") != null && !i.get("name").toString().trim().isEmpty()) + ? i.get("name").toString().trim() + : ""; + String area = (i.get("locality") != null && !i.get("locality").toString().trim().isEmpty()) + ? i.get("locality").toString().trim() + : ""; + + + String locality = ""; + String model = ""; + data.put("Zone", zone); + data.put("Ward", ward); + data.put("Latitude", latitude); + data.put("Longitude", longitude); + data.put("Area", area); + data.put("Street Name", street_name); +// data.put("Locality", locality); +// data.put("Model", model); + data1.add(data); + + } + result.put("GCC Toilet", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "GCC Toilet List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "GCC Toilet Not Found"); + result.put("Status Code", 404); + } + // Private Toilet + if (!dataList1.isEmpty()) { + for (Map i : dataList) { + Map data = new HashMap<>(); + + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("ward") != null && !i.get("ward").toString().trim().isEmpty()) + ? i.get("ward").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; +// String area = (i.get("locality") != null && !i.get("locality").toString().trim().isEmpty()) +// ? i.get("locality").toString().trim() +// : ""; + String street_name = (i.get("pct_name") != null && !i.get("pct_name").toString().trim().isEmpty()) + ? i.get("pct_name").toString().trim() + : ""; + + String locality = ""; + String model = ""; + String area = ""; + data.put("Zone", zone); + data.put("Ward", ward); + data.put("Latitude", latitude); + data.put("Longitude", longitude); + // data.put("Area", area); + data.put("Street Name", street_name); +// data.put("Locality", locality); +// data.put("Model", model); + data1.add(data); + + } + result.put("Private Toilet", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Private Toilet List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "Private Toilet Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Toilet list :" + e); + result.put("Status Code", 500); + } + return result; + } + private Map getbusShelter(String lat, String lng) { + Map result = new HashMap<>(); + List> data1 = new ArrayList<>(); + String urlString="https://gccservices.in/gccofficialapp/api/busshelter/getBusShelterList?latitude="+lat+"&longitude="+lng; + + try{ + List> dataList = geturldata(urlString); + + if (!dataList.isEmpty()) { + for(Map i:dataList) { + Map data = new HashMap<>(); + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("ward") != null && !i.get("ward").toString().trim().isEmpty()) + ? i.get("ward").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; + String area = (i.get("area") != null && !i.get("area").toString().trim().isEmpty()) + ? i.get("area").toString().trim() + : ""; + String road = (i.get("road") != null && !i.get("road").toString().trim().isEmpty()) + ? i.get("road").toString().trim() + : ""; + String name = ""; + data.put("Zone", zone); + data.put("Ward", ward); + data.put("Latitude", latitude); + data.put("Longitude", longitude); + data.put("Area", area); + data.put("Road", road); + //data.put("Name", name); + data1.add(data); + } + result.put("Bus Shelter", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Bus Shelter List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "Bus Shelter Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Bus Shelter list :" + e); + result.put("Status Code", 500); + } + return result; + } + + private Map getammaUnavagam(String lat, String lng) { + Map result = new HashMap<>(); + String sql = "SELECT " + + " am.zone, " + + " am.ward, " + + " am.address, " + + " am.breakfast, " + + " am.lunch, " + + " am.dinner, " + + " am. open_time, " + + " am. close_time, " + + " am.latitude, " + + " am.longitude " + + " FROM ammaunavagam am WHERE (am.is_active=1 AND am.is_delete=0) AND " + + " ((6371008.8 * acos( ROUND(cos(radians(?)) * cos(radians(am.latitude)) * cos(radians(am.longitude) - radians(?)) + " + + " sin(radians(?)) * sin(radians(am.latitude)), 9) )) < 1000)"; + try{ + List> data = mysqlJdbcTemplate.queryForList(sql, lat, lng, lat); + List> data1 = new ArrayList<>(); + if (!data.isEmpty()) { + for (Map i:data) { + Map check = new HashMap<>(); + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("ward") != null && !i.get("ward").toString().trim().isEmpty()) + ? i.get("ward").toString().trim() + : ""; + String address = (i.get("address") != null && !i.get("address").toString().trim().isEmpty()) + ? i.get("address").toString().trim() + : ""; + String breakfast = (i.get("breakfast") != null && !i.get("breakfast").toString().trim().isEmpty()) + ? i.get("breakfast").toString().trim() + : ""; + String lunch = (i.get("lunch") != null && !i.get("lunch").toString().trim().isEmpty()) + ? i.get("lunch").toString().trim() + : ""; + String dinner = (i.get("dinner") != null && !i.get("dinner").toString().trim().isEmpty()) + ? i.get("dinner").toString().trim() + : ""; + String open_time = (i.get("open_time") != null && !i.get("open_time").toString().trim().isEmpty()) + ? i.get("open_time").toString().trim() + : ""; + String close_time = (i.get("close_time") != null && !i.get("close_time").toString().trim().isEmpty()) + ? i.get("close_time").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; + + if(!zone.isEmpty() || !zone.isBlank()) { + check.put("zone", zone); + } + if(!ward.isEmpty() || !ward.isBlank()) { + check.put("ward", ward); + } + if(!address.isEmpty() || !address.isBlank()) { + check.put("address", address); + } + if(!breakfast.isEmpty() || !breakfast.isBlank()) { + check.put("burial_name", breakfast); + } + if(!lunch.isEmpty() || !lunch.isBlank()) { + check.put("burial_name", lunch); + } + if(!dinner.isEmpty() || !dinner.isBlank()) { + check.put("burial_name", dinner); + } + if(!open_time.isEmpty() || !open_time.isBlank()) { + check.put("open_time", open_time); + } + if(!close_time.isEmpty() || !close_time.isBlank()) { + check.put("close_time", close_time); + } + if(!latitude.isEmpty() || !latitude.isBlank()) { + check.put("latitude", latitude); + } + if(!longitude.isEmpty() || !longitude.isBlank()) { + check.put("longitude", longitude); + } + + data1.add(check); + } + result.put("Amma Unavagam", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Amma Unavagam List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "Amma Unavagam Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Amma Unavagam list :" + e); + result.put("Status Code", 500); + } + return result; + } + + private Map getburialGround(String lat, String lng) { + Map result = new HashMap<>(); + String sql = "SELECT " + + " bg.zone, " + + " bg.ward, " + + " bg.burial_name, " + + " bg.address, " + + " bg.open_time, " + + " bg.close_time, " + + " bg.latitude, " + + " bg.longitude " + + " FROM burial_ground bg WHERE (bg.is_active=1 AND bg.is_delete=0) AND " + + " ((6371008.8 * acos( ROUND(cos(radians(?)) * cos(radians(bg.latitude)) * cos(radians(bg.longitude) - radians(?)) + " + + " sin(radians(?)) * sin(radians(bg.latitude)), 9) )) < 1000)"; + + + + + try{ + List> data = mysqlJdbcTemplate.queryForList(sql, lat, lng, lat); + List> data1 = new ArrayList<>(); + if (!data.isEmpty()) { + for (Map i:data) { + Map check = new HashMap<>(); + String zone = (i.get("zone") != null && !i.get("zone").toString().trim().isEmpty()) + ? i.get("zone").toString().trim() + : ""; + String ward = (i.get("ward") != null && !i.get("ward").toString().trim().isEmpty()) + ? i.get("ward").toString().trim() + : ""; + String burial_name = (i.get("burial_name") != null && !i.get("burial_name").toString().trim().isEmpty()) + ? i.get("burial_name").toString().trim() + : ""; + String address = (i.get("address") != null && !i.get("address").toString().trim().isEmpty()) + ? i.get("address").toString().trim() + : ""; + String open_time = (i.get("open_time") != null && !i.get("open_time").toString().trim().isEmpty()) + ? i.get("open_time").toString().trim() + : ""; + String close_time = (i.get("close_time") != null && !i.get("close_time").toString().trim().isEmpty()) + ? i.get("close_time").toString().trim() + : ""; + String latitude = (i.get("latitude") != null && !i.get("latitude").toString().trim().isEmpty()) + ? i.get("latitude").toString().trim() + : ""; + String longitude = (i.get("longitude") != null && !i.get("longitude").toString().trim().isEmpty()) + ? i.get("longitude").toString().trim() + : ""; + if(!zone.isEmpty() || !zone.isBlank()) { + check.put("zone", zone); + } + if(!ward.isEmpty() || !ward.isBlank()) { + check.put("ward", ward); + } + if(!burial_name.isEmpty() || !burial_name.isBlank()) { + check.put("burial_name", burial_name); + } + if(!address.isEmpty() || !address.isBlank()) { + check.put("address", address); + } + if(!open_time.isEmpty() || !open_time.isBlank()) { + check.put("open_time", open_time); + } + if(!close_time.isEmpty() || !close_time.isBlank()) { + check.put("close_time", close_time); + } + if(!latitude.isEmpty() || !latitude.isBlank()) { + check.put("latitude", latitude); + } + if(!longitude.isEmpty() || !longitude.isBlank()) { + check.put("longitude", longitude); + } + data1.add(check); + } + result.put("Burial Ground", data1); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Burial Ground List fetched successfully"); + + } else { + result.put("Status", "Not Found"); + result.put("Message", "Burial Ground Not Found"); + result.put("Status Code", 404); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Burial Ground list :" + e); + result.put("Status Code", 500); + } + return result; + } + + public List> geturldata(String urlString) { + + RestTemplate restTemplate = new RestTemplate(); + List> details = null; + + ResponseEntity response = restTemplate.getForEntity(urlString, String.class); + String rawResponse = response.getBody(); + + ObjectMapper objectMapper = new ObjectMapper(); + try { + List> responseList = objectMapper.readValue(rawResponse, List.class); + + if (!responseList.isEmpty()) { + Map firstItem = responseList.get(0); + details = (List>) firstItem.get("data"); + } + + System.out.println("details === " + details); + + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + return details; + + } + + public Map getServices() { + Map response = new HashMap<>(); + Map result = new HashMap<>(); + String sql = "SELECT service_type FROM service_master ORDER BY execution_order"; + try { + List> data = mysqlJdbcTemplate.queryForList(sql); + if (!data.isEmpty()) { + result.put("Service List", data); + result.put("Status", "Sucess"); + result.put("Status Code", 200); + result.put("Message", "Service List fetched successfully"); + response.put("Response", result); + } else { + result.put("Status", "Not Found"); + result.put("Message", "Service List Not Found"); + result.put("Status Code", 404); + response.put("Response", result); + } + } catch (Exception e) { + result.put("Status", "Error"); + result.put("Message", "Error in fetching Service list :" + e); + result.put("Status Code", 500); + response.put("Response", result); + } + + return response; + } +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/constants/AppConstants.java b/src/main/java/com/gcc/restapiservices/petregistration/constants/AppConstants.java new file mode 100644 index 0000000..ef1ae4f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/constants/AppConstants.java @@ -0,0 +1,11 @@ +package com.gcc.restapiservices.petregistration.constants; + +public final class AppConstants { + //public static String key_id="rzp_live_ySI5Ns54Y7qOcJ"; + // public static String key_secret="Nwf1TjhUtaskof8vePkRR8Sb"; + + + //uncomment for testing payment + public static String key_id="rzp_test_tDkHFEqWXmuEi8"; + public static String key_secret="cBQUjMcKZ4J6vmOKSyNZ92py"; +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/controller/PetController.java b/src/main/java/com/gcc/restapiservices/petregistration/controller/PetController.java new file mode 100644 index 0000000..c07b04d --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/controller/PetController.java @@ -0,0 +1,76 @@ +package com.gcc.restapiservices.petregistration.controller; + +import com.gcc.restapiservices.petregistration.service.PetRegistrationApiService; +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.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Controller +@RequestMapping("/gccrestservices/petregistration") +public class PetController { + + + @Autowired + private PetRegistrationApiService petRegistrationApiService; + + @GetMapping("/getlicense/{id}") + public String viewLicense(Model model, @PathVariable("id") int id, @RequestParam(required =false) String mobileNo) { + System.out.println("mobileNo"+mobileNo); + model.addAttribute("title","license"); + + int uniqueid = id; + Map lic =petRegistrationApiService.getbylicensemobnoanduniqueId(mobileNo, uniqueid); + Map own =petRegistrationApiService.getOwnerDetailsbymobile(mobileNo); + Map pet =petRegistrationApiService.getbymobnoanduniqueId(mobileNo, uniqueid); + System.out.println(lic); + System.out.println(own); + System.out.println(pet); + model.addAttribute("lic",lic); + model.addAttribute("own",own); + model.addAttribute("pet",pet); + SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); + Calendar c = Calendar.getInstance(); + LocalDateTime licenseDateTime = (LocalDateTime) lic.get("date"); + Date licenseDate = Date.from(licenseDateTime.atZone(ZoneId.systemDefault()).toInstant()); + c.setTime(licenseDate); + //c.setTime(lic.getDate()); + String issuedate=dateFormat.format(c.getTime()); + model.addAttribute("issue",issuedate); + c.add(Calendar.YEAR, 1); + c.add(Calendar.DATE, -1); + String dateInString=dateFormat.format(c.getTime()); + model.addAttribute("valid",dateInString); + + Date date1; + + return "owners/petlicense"; + } + + /* @GetMapping("/downloadLicense") + public String dowmloadLicense(Model model) { + + return "owners/downloadlic"; + }*/ + + @GetMapping("/downloadLicense") + public String dowmloadLicense(Model model, @RequestParam("id") int id, @RequestParam(required =true) String mobileNo) { + System.out.println("Download License called......."); + model.addAttribute("mobileNo", mobileNo); + model.addAttribute("id", id); + model.addAttribute("name", "downloadLic"); + return "owners/downloadlic"; + } + + } diff --git a/src/main/java/com/gcc/restapiservices/petregistration/controller/PetRegistrationApiController.java b/src/main/java/com/gcc/restapiservices/petregistration/controller/PetRegistrationApiController.java new file mode 100644 index 0000000..3334b13 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/controller/PetRegistrationApiController.java @@ -0,0 +1,757 @@ +package com.gcc.restapiservices.petregistration.controller; + +import java.time.LocalDate; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.petregistration.constants.AppConstants; +import com.gcc.restapiservices.petregistration.service.PetRegistrationApiService; +import com.gcc.restapiservices.petregistration.util.ApiResponseUtil; +import com.gcc.restapiservices.swimmingpool.util.ApiResponse; +import com.razorpay.Order; +import com.razorpay.RazorpayClient; +import com.razorpay.RazorpayException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +@RestController +@RequestMapping("/gccrestservices/petregistration/api") + +public class PetRegistrationApiController { + + @Autowired + private PetRegistrationApiService petRegistrationApiService; + + @Autowired + private AppConfig appConfig; + + @GetMapping("/breed") + public ResponseEntity getBreedList(@RequestParam int type) { + + List> result = petRegistrationApiService.getBreedList(type); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // get owner details + + @GetMapping("/ownerinfo") + public ResponseEntity getOwnerDetails(@RequestParam String mobile) { + + List> result = petRegistrationApiService.getOwnerDetails(mobile); + try { + + // Check if mobile is missing or blank + if (mobile == null || mobile.trim().isEmpty()) { + return ApiResponseUtil.error("Mobile number is required", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!mobile.matches("\\d{10}")) { + return ApiResponseUtil.error("Mobile number must be exactly 10 digits", HttpStatus.BAD_REQUEST); + } + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // get pet type + @GetMapping("/pettypes") + public ResponseEntity getPetTypes() { + + List> result = petRegistrationApiService.getTypeOfPets(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // get pet type + @GetMapping("/allyears") + public ResponseEntity getAllYears() { + + List> result = petRegistrationApiService.getAllYears(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // get pet type + @GetMapping("/allmonths") + public ResponseEntity getAllMonths() { + + List> result = petRegistrationApiService.getAllMonths(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + @GetMapping("/userexistornot") + public ResponseEntity userExistOrNot(@RequestParam String mobilenum) { + try { + + // Check if mobile is missing or blank + if (mobilenum == null || mobilenum.trim().isEmpty()) { + return ApiResponseUtil.error("Mobile number is required", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!mobilenum.matches("\\d{10}")) { + return ApiResponseUtil.error("Mobile number must be exactly 10 digits", HttpStatus.BAD_REQUEST); + } + + boolean result = petRegistrationApiService.isPhoneRegistered(mobilenum); + System.out.println("result: " + result); + + String message = result ? "Mobile number already registered" : "Mobile number not registered"; + + return ApiResponseUtil.success(result, message); + + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + // save new owner registration + + @PostMapping("/pet-owner/register") + public ResponseEntity savePinDetails(HttpServletRequest request, + @RequestParam(required = false) String title, + @RequestParam(required = false) String username, + @RequestParam(required = false) String doornumber, + @RequestParam(required = false) String street, + @RequestParam(required = false) String area, + @RequestParam(required = false) String city, + @RequestParam(required = false) String pincode, + @RequestParam(required = false) String zone, + @RequestParam(required = false) String ward, + @RequestParam(required = false) String phone, + @RequestParam(required = false) String email, + @RequestParam(required = false) String pin) { + + List missingFields = new ArrayList<>(); + if (title == null || title.trim().isEmpty()) + missingFields.add("title"); + if (username == null || username.trim().isEmpty()) + missingFields.add("username"); + if (doornumber == null || doornumber.trim().isEmpty()) + missingFields.add("doornumber"); + if (street == null || street.trim().isEmpty()) + missingFields.add("street"); + if (area == null || area.trim().isEmpty()) + missingFields.add("area"); + if (city == null || city.trim().isEmpty()) + missingFields.add("city"); + if (pincode == null || pincode.trim().isEmpty()) + missingFields.add("pincode"); + if (zone == null || zone.trim().isEmpty()) + missingFields.add("zone"); + if (ward == null || ward.trim().isEmpty()) + missingFields.add("ward"); + if (phone == null || phone.trim().isEmpty()) + missingFields.add("phone"); + if (email == null || email.trim().isEmpty()) + missingFields.add("email"); + if (pin == null || pin.trim().isEmpty()) + missingFields.add("pin"); + + if (!missingFields.isEmpty()) { + return ApiResponseUtil.invalidRequest("Missing required fields: " + String.join(", ", missingFields)); + } + + try { + + // Check if mobile is missing or blank + if (phone == null || phone.trim().isEmpty()) { + return ApiResponseUtil.error("Mobile number is required", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!phone.matches("\\d{10}")) { + return ApiResponseUtil.error("Mobile number must be exactly 10 digits", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!pincode.matches("\\d{6}")) { + return ApiResponseUtil.error("Pincode must be exactly 6 digits", HttpStatus.BAD_REQUEST); + } + + // Validate email if provided + if (email != null && !email.isBlank()) { + String emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.com$"; + if (!email.matches(emailRegex)) { + return ApiResponseUtil.error("Invalid email id", HttpStatus.BAD_REQUEST); + } + } + + // Check if mobile is not 10 digits + if (!pincode.matches("\\d{6}")) { + return ApiResponseUtil.error("Pincode must be exactly 6 digits", HttpStatus.BAD_REQUEST); + } + // pin validation + + if (!pin.matches("\\d{4}")) { + return ApiResponseUtil.error("pin must be 4 digits only", HttpStatus.BAD_REQUEST); + } + + return petRegistrationApiService.insertPetOwner( + title, username, doornumber, street, area, city, pincode, zone, ward, phone, email, pin); + } catch (Exception ex) { + return ApiResponseUtil.error("Internal server error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @PostMapping("/saveregistrationdetails") + public ResponseEntity saveRegistrationDetails( + @RequestParam(required = false) String petname, + @RequestParam(required = false) String species, + @RequestParam(required = false) String breed, + @RequestParam(required = false) String identification_mark, + @RequestParam(required = false) String petcolor, + @RequestParam(required = false) String gender, + @RequestParam(required = false) String age_year, + @RequestParam(required = false) String months, + @RequestParam(required = false) String is_sterilized, + @RequestParam(required = false) String is_adopted_street, + @RequestParam(required = false) String is_rabies_vaccination, + @RequestParam(required = false) String arv_date, + @RequestParam(required = false) String lastdate_of_deworming, + @RequestParam(required = false) String other_vaccination, + @RequestParam(required = false) String previous_licenseNo, + @RequestParam(required = false) String consultant_name, + @RequestParam(required = false) String council_number, + @RequestParam(required = false) String mobilenum, + @RequestParam(required = false) MultipartFile applicantphoto, + @RequestParam(required = false) MultipartFile addressproof, + @RequestParam(required = false) MultipartFile petphoto, + @RequestParam(required = false) MultipartFile rabiesvacCertificate) { + + LocalDate today = LocalDate.now(); + String registerdate = today.toString(); + + List missingFields = new ArrayList<>(); + + if (petname == null || petname.trim().isEmpty()) + missingFields.add("petname"); + if (species == null || species.trim().isEmpty()) + missingFields.add("species"); + if (breed == null || breed.trim().isEmpty()) + missingFields.add("breed"); + // if (identification_mark == null || identification_mark.trim().isEmpty()) + // missingFields.add("identification_mark"); optional + if (petcolor == null || petcolor.trim().isEmpty()) + missingFields.add("petcolor"); + if (gender == null || gender.trim().isEmpty()) + missingFields.add("gender"); + if (age_year == null || age_year.trim().isEmpty()) + missingFields.add("age_year"); + if (months == null || months.trim().isEmpty()) + missingFields.add("months"); + if (is_sterilized == null || is_sterilized.trim().isEmpty()) + missingFields.add("is_sterilized"); + if (is_adopted_street == null || is_adopted_street.trim().isEmpty()) + missingFields.add("is_adopted_street"); + if (is_rabies_vaccination == null || is_rabies_vaccination.trim().isEmpty()) + missingFields.add("is_rabies_vaccination"); + if (arv_date == null || arv_date.trim().isEmpty()) + missingFields.add("arv_date"); + // if (lastdate_of_deworming == null || lastdate_of_deworming.trim().isEmpty()) + // missingFields.add("lastdate_of_deworming"); optional + // if (other_vaccination == null || other_vaccination.trim().isEmpty()) + // missingFields.add("other_vaccination"); optional + // if (previous_licenseNo == null || previous_licenseNo.trim().isEmpty()) + // missingFields.add("previous_licenseNo"); optional + // if (consultant_name == null || consultant_name.trim().isEmpty()) + // missingFields.add("consultant_name"); optional + // if (council_number == null || council_number.trim().isEmpty()) + // missingFields.add("council_number"); optional + if (mobilenum == null || mobilenum.trim().isEmpty()) + missingFields.add("mobilenum"); + + if (applicantphoto == null || applicantphoto.isEmpty()) + missingFields.add("applicantphoto"); + if (addressproof == null || addressproof.isEmpty()) + missingFields.add("addressproof"); + if (petphoto == null || petphoto.isEmpty()) + missingFields.add("petphoto"); + if (rabiesvacCertificate == null || rabiesvacCertificate.isEmpty()) + missingFields.add("rabiesvacCertificate"); + + if (!missingFields.isEmpty()) { + return ApiResponseUtil.invalidRequest("Missing required fields: " + String.join(", ", missingFields)); + } + + try { + // Save to DB + String saveStatus = petRegistrationApiService.saveAllRegistrationDetails(petname, species, breed, + identification_mark, petcolor, gender, age_year, months, + is_sterilized, is_adopted_street, is_rabies_vaccination, + arv_date, lastdate_of_deworming, other_vaccination, previous_licenseNo, consultant_name, + council_number, mobilenum, + applicantphoto, addressproof, petphoto, rabiesvacCertificate, registerdate); + + Map response = new HashMap<>(); + + System.out.println("saveStatus " + saveStatus); + + // Check if mobile is missing or blank + if (mobilenum == null || mobilenum.trim().isEmpty()) { + return ApiResponseUtil.error("Mobile number is required", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!mobilenum.matches("\\d{10}")) { + return ApiResponseUtil.error("Mobile number must be exactly 10 digits", HttpStatus.BAD_REQUEST); + } + + if (is_rabies_vaccination != null && !is_rabies_vaccination.isBlank() + && is_rabies_vaccination.equalsIgnoreCase("Yes")) { + // Continue registration + } else { + return ApiResponseUtil.error( + "You can't register a pet without Rabies Vaccination. Please select 'Yes' only.", + HttpStatus.BAD_REQUEST); + } + + // Define the date format used in the request (adjust as needed) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + + if (arv_date != null && !arv_date.isBlank()) { + LocalDate arvDate = LocalDate.parse(arv_date.trim(), formatter); + if (arvDate.isAfter(LocalDate.now())) { + return ApiResponseUtil.error("ARV date cannot be in the future", HttpStatus.BAD_REQUEST); + } + } + + if (lastdate_of_deworming != null && !lastdate_of_deworming.isBlank()) { + LocalDate dewormDate = LocalDate.parse(lastdate_of_deworming.trim(), formatter); + if (dewormDate.isAfter(LocalDate.now())) { + return ApiResponseUtil.error("Deworming date cannot be in the future", HttpStatus.BAD_REQUEST); + } + } + + int yearsInt = 0; + int monthsInt = 0; + + try { + if (age_year != null && !age_year.isBlank()) { + yearsInt = Integer.parseInt(age_year.trim()); + } + if (months != null && !months.isBlank()) { + monthsInt = Integer.parseInt(months.trim()); + } + + if (yearsInt <= 0 && monthsInt <= 0) { + return ApiResponseUtil.error("Pet age must be at least 1 month (either in years or months)", + HttpStatus.BAD_REQUEST); + } + } catch (NumberFormatException e) { + return ApiResponseUtil.error("Invalid value for age_year or months. Both must be numbers.", + HttpStatus.BAD_REQUEST); + } + + if (saveStatus == null || saveStatus.isEmpty() || saveStatus.contains("error")) { + + response.put("status", false); + response.put("message", saveStatus); + response.put("description", "Failed to save the details"); + return ResponseEntity.ok(response); + } else { + response.put("status", true); + response.put("message", "success"); + response.put("description", "Details were saved successfully"); + response.put("petId", saveStatus); + } + + // Add uniqueid to response + + return ResponseEntity.ok(response); + + } catch (Exception ex) { + return ApiResponseUtil.error("Internal server error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + // getpetdetails + + // get pet type + @GetMapping("/getpetdetails") + public ResponseEntity getPetDetails(@RequestParam String mobilenum) { + try { + + // Check if mobile is missing or blank + if (mobilenum == null || mobilenum.trim().isEmpty()) { + return ApiResponseUtil.error("Mobile number is required", HttpStatus.BAD_REQUEST); + } + + // Check if mobile is not 10 digits + if (!mobilenum.matches("\\d{10}")) { + return ApiResponseUtil.error("Mobile number must be exactly 10 digits", HttpStatus.BAD_REQUEST); + } + + List> results = petRegistrationApiService.getPetRegistrationDetailsbyMobile(mobilenum); + + // if (results == null || results.isEmpty()) { + // return ResponseEntity.status(HttpStatus.NOT_FOUND) + // .body("No Registration Data for mobile number: " + mobilenum); + // } + + if (results == null || results.isEmpty()) { + return ApiResponseUtil.error("No PET Registration Details for mobile number ", HttpStatus.BAD_REQUEST); + } + + return ApiResponseUtil.success(results, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // renewal the pet certificate + @PostMapping("/updateARVDetails") + public ResponseEntity updateARVDetails( + @RequestParam("uniqueid") String uniqueid, + @RequestParam("arvdate") String arvdate, + @RequestParam("rabiesvacCertificate") MultipartFile rabiesvacCertificate) { + try { + if (uniqueid == null || uniqueid.trim().isEmpty()) { + return ApiResponseUtil.error("Unique ID is required", HttpStatus.BAD_REQUEST); + } + + if (arvdate == null || arvdate.trim().isEmpty()) { + return ApiResponseUtil.error("ARV date is required", HttpStatus.BAD_REQUEST); + } + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + + LocalDate arvDate; + try { + arvDate = LocalDate.parse(arvdate.trim(), formatter); + } catch (DateTimeParseException e) { + return ApiResponseUtil.error("Invalid date format. Please use dd-MM-yyyy", HttpStatus.BAD_REQUEST); + } + + // if (arvDate.isAfter(LocalDate.now())) { + // return ApiResponseUtil.error("ARV date cannot be in the future", + // HttpStatus.BAD_REQUEST); + // } + + if (rabiesvacCertificate == null || rabiesvacCertificate.isEmpty()) { + return ApiResponseUtil.error("Rabies vaccination certificate is required", HttpStatus.BAD_REQUEST); + } + + String result = petRegistrationApiService.updateARVAndRabiesCertificate(uniqueid, arvdate, + rabiesvacCertificate); + + if ("success".equalsIgnoreCase(result)) { + return ApiResponseUtil.success(null, "Details updated successfully"); + } else if (result.startsWith("Renewal allowed only after:")) { + return ApiResponseUtil.error(result, HttpStatus.BAD_REQUEST); + } else if (result.startsWith("No license validity")) { + return ApiResponseUtil.error(result, HttpStatus.NOT_FOUND); + } else if (result.startsWith("Invalid ARV date format")) { + return ApiResponseUtil.error(result, HttpStatus.BAD_REQUEST); + } else { + return ApiResponseUtil.error(result, HttpStatus.INTERNAL_SERVER_ERROR); + } + + // if ("success".equalsIgnoreCase(result)) { + // return ApiResponseUtil.success(null, "Details updated successfully"); + // } else { + // return ApiResponseUtil.error(result, HttpStatus.NOT_FOUND); + // } + + } catch (Exception e) { + return ApiResponseUtil.error("Exception: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + // @PostMapping("/create_order") + // public ResponseEntity createOrder(@RequestParam String petId) throws RazorpayException { + + // try { + // Map petDetail = petRegistrationApiService.getpetdetails(petId); + + // int petStatus = 0; + // // Check if petDetail is empty + // if (!petDetail.isEmpty()) { + // petStatus = (int) petDetail.get("status"); + // } + + // if (petStatus != 2 && petStatus != 4) { + // return new ResponseEntity<>( + // new ApiResponse("error", "PET request must be accepted by the officer to proceed with payment.", + // null, HttpStatus.BAD_REQUEST.value()), + // HttpStatus.BAD_REQUEST); + // } + + // System.out.println("key ID :-----" + appConfig.getKeyId()); + // int pet_id = Integer.parseInt(petId); + + // double amount = Double.parseDouble("50"); + + // // To enable testing mode in appConstants if required for testing & development + // var client = new RazorpayClient(AppConstants.key_id, AppConstants.key_secret); + // JSONObject options = new JSONObject(); + // options.put("amount", amount * 100); + // options.put("currency", "INR"); + // // options.put("receipt","Pet_ID/"+pet_id); + // Order od = client.orders.create(options); + // petRegistrationApiService.saveorderLog(od.get("id").toString(), od.toString(), pet_id); + // System.out.println(od); + // return ResponseEntity.ok(new ApiResponse("success", "Order created successfully", od.toJson().toMap(), + // HttpStatus.OK.value())); + // } catch (NumberFormatException ex) { + // throw new RuntimeException(ex); + // } catch (RazorpayException e) { + // return new ResponseEntity<>(new ApiResponse("error", "Razorpay error: " + e.getMessage(), null, + // HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + // } catch (EmptyResultDataAccessException ex) { + // return new ResponseEntity<>( + // new ApiResponse("error", "PET request must be accepted by the officer to proceed with payment.", + // null, HttpStatus.BAD_REQUEST.value()), + // HttpStatus.BAD_REQUEST); + // } catch (Exception e) { + // return new ResponseEntity<>(new ApiResponse("error", "Unexpected error: " + e.getMessage(), null, + // HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + // } + // } + + @PostMapping("/Confirm") + public ResponseEntity confirmPayment( + @RequestParam("petId") String petId, + @RequestParam(name = "source", defaultValue = "0") String source, + @RequestParam("mobno") String mobno, + @RequestParam(value = "orderId", required = true) String orderId, + @RequestBody Map paymentResponse) { + + try { + // Validate orderId is not null or empty + if (orderId == null || orderId.trim().isEmpty()) { + return ResponseEntity.badRequest().body(Map.of( + "message", "Order ID is required and cannot be null or empty", + "error", "Missing required parameter: orderId")); + } + + System.out.println("Controller Testing................."); + return petRegistrationApiService.processPaymentConfirmation(petId, source, mobno, orderId, paymentResponse); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment", "error", e.getMessage())); + } + } + + // get zones + + @GetMapping("/getZones") + public ResponseEntity getZones() { + + List> result = petRegistrationApiService.getZones(); + try { + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + // get Ward by zoneid + + @GetMapping("/getWardByZoneId") + public ResponseEntity getWardByZoneId(@RequestParam String zoneid) { + + List> result = petRegistrationApiService.getWardByZoneId(zoneid); + try { + + // Check if mobile is missing or blank + if (zoneid == null || zoneid.trim().isEmpty()) { + return ApiResponseUtil.error("ZoneId is required", HttpStatus.BAD_REQUEST); + } + + if (result.isEmpty()) { + return ApiResponseUtil.notFound("No data found"); + } + + return ApiResponseUtil.success(result, "Data found"); + } catch (Exception e) { + return ApiResponseUtil.error("Internal server error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + @GetMapping(value = "/sendOTP") + public String sendOtp(HttpServletRequest request, @RequestParam String mobileNo) { + + Map response = new HashMap<>(); + + String MobileNo = mobileNo; + System.out.print("\n MobileNo---:" + mobileNo); + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + + System.out.print("\n otp---:" + otp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); + LocalDateTime now = LocalDateTime.now(); + System.out.println(dtf.format(now)); + + String generatedToken = "Welcome to GCC " + otp + " is your OTP for gcc QR System"; + + String key = "pfTEYN6H"; + String urlString = appConfig.getGetOtpUrl() + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + generatedToken + "&entityid=1401572690000011081&templateid=1407168250479102852"; + + System.out.print("\n urlString---: " + urlString); + String bodyMessage = ""; + + if (mobileNo == null || mobileNo.trim().isEmpty()) { + throw new IllegalArgumentException("Mobile number is required"); + } + + // Validate mobile number is exactly 10 digits + if (!mobileNo.matches("\\d{10}")) { + throw new IllegalArgumentException("Mobile number must be exactly 10 digits"); + } + + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + // Using Jackson ObjectMapper to parse the response JSON + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + // Add mobileNo and otp to the response JSON + jsonResponse.put("MobileNo", MobileNo); + jsonResponse.put("otp", otp); + + // Convert the updated JSON object back to string + bodyMessage = jsonResponse.toString(); + // bodyMessage=Response; + System.out.println("\n bodyMessage" + bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: " + e); + bodyMessage = "Error"; + } + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + return bodyMessage; + + } + + // get licensedetails api + @GetMapping("/getLicenseDetails") + public ResponseEntity getLicenseDetailsByMobileNo( + @RequestParam(value = "licenseno", required = false) String licenseno) { + if (licenseno == null || licenseno.isEmpty()) { + return ApiResponseUtil.invalidRequest("license number is required."); + } + + try { + + List> licenseDetails = petRegistrationApiService.getLicenseListByMobNo(licenseno); + if (licenseDetails == null || licenseDetails.isEmpty()) { + return ApiResponseUtil.notFound("No bookings found for licenseno: " + licenseno); + } + + // Success response + Map response = new HashMap<>(); + response.put("status", "SUCCESS"); + response.put("statuscode", "200"); + response.put("licenseDetails", licenseDetails); + + return ResponseEntity.ok(response); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + + @GetMapping("/getCountByMobileNo") + public ResponseEntity getCountByMobileNo(String mobileno) { + + int mobileCount = petRegistrationApiService.getCountByMobileNo(mobileno); + + System.out.println("mobileCount: " + mobileCount); + if(mobileCount>=3) { + return ApiResponseUtil.success(mobileCount, "Already you reached the license limit (Max 3 pets)"); + }else { + return ApiResponseUtil.success(mobileCount, "You can proceed with the license registration"); + } + } + + +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/controller/SMSController.java b/src/main/java/com/gcc/restapiservices/petregistration/controller/SMSController.java new file mode 100644 index 0000000..1e50c96 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/controller/SMSController.java @@ -0,0 +1,32 @@ +package com.gcc.restapiservices.petregistration.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import com.gcc.restapiservices.petregistration.service.PetSMSService; + +@RestController +@RequestMapping("/gccrestservices/api/sms") +public class SMSController { + + @Autowired + private PetSMSService smsService; + + @PostMapping("/send") + public String sendMessage( + @RequestParam String channel, // WHATSAPP or SMS + @RequestParam int scenarioId, + @RequestParam String var1, // name + @RequestParam(required = false) String var2, // refId / OTP + @RequestParam(required = false) String var3, // link/status + @RequestParam String mobileNumber) { + if ("SMS".equals(channel)) { + return smsService.sendMessage(scenarioId, var1, var2, var3, mobileNumber); + } else if ("WHATSAPP".equals(channel)) { + return smsService.sendWhatsappMessage(scenarioId, var1, var2, var3, mobileNumber); + } else { + return "Invalid channel input"; + } + + } +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/service/PetRegistrationApiService.java b/src/main/java/com/gcc/restapiservices/petregistration/service/PetRegistrationApiService.java new file mode 100644 index 0000000..f1c2daf --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/service/PetRegistrationApiService.java @@ -0,0 +1,949 @@ +package com.gcc.restapiservices.petregistration.service; + +import java.awt.image.BufferedImage; +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.PreparedStatement; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.HashMap; + +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.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.petregistration.util.ApiResponseUtil; +import com.gcc.restapiservices.cdwaste.util.DateTimeUtil;; + +@Service +public class PetRegistrationApiService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlPetRegistrationRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private final Environment environment; + + private String fileBaseUrl; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + private static final int STRING_LENGTH = 15; + + private static final Random RANDOM = new SecureRandom(); + + + public PetRegistrationApiService(Environment environment) { + this.environment = environment; + this.fileBaseUrl = environment.getProperty("fileBaseUrl"); + + } + + //breed list + public List> getBreedList(int type) { + String sql = " SELECT id,breed FROM breed where type= ? "; + return jdbcTemplate.queryForList(sql, type); + } + + + //mobile number registered or not + public boolean isPhoneRegistered(String mobilenum) { + String sql = "SELECT COUNT(*) FROM pet_owner WHERE phone = ?"; + Integer count = jdbcTemplate.queryForObject(sql, Integer.class, mobilenum); + return count != null && count > 0; + } + + + + // owner registration + public ResponseEntity insertPetOwner( + String title, String username, String doornumber, String street, String area, + String city, String pincode, String zone, String ward, String phone, + String email, String pin) { + + // Check if phone number already exists + String checkSql = "SELECT COUNT(*) FROM pet_owner WHERE phone = ?"; + Integer count = jdbcTemplate.queryForObject(checkSql, new Object[]{phone}, Integer.class); + + if (count != null && count > 0) { + return ApiResponseUtil.buildResponse(false, HttpStatus.CONFLICT, + "This mobile number is already registered.", null); + } + + + Date cdate = new Date(); + + // Insert into pet_owner (without pin) + String insertPetOwnerSql = """ + INSERT INTO pet_owner (title, fname, doornumber, street, area, city, pincode, zone, ward, phone, email,cdate) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?) + """; + + int rows1 = jdbcTemplate.update(insertPetOwnerSql, + title, username, doornumber, street, area, city, pincode, zone, ward, phone, email, cdate); + + // Insert into login_details (with pin) + String insertLoginSql = """ + INSERT INTO login_detail (mobileno, pin, usertype, zone) + VALUES (?, ?, ?, ?) + """; + + int rows2 = jdbcTemplate.update(insertLoginSql, phone, pin, "user", zone); + + if (rows1 > 0 && rows2 > 0) { + return ApiResponseUtil.success(Map.of("phone", phone), "Registered successfully"); + } else { + return ApiResponseUtil.error("Failed to register", HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + + // get owner details + public List> getOwnerDetails(String mobile) { + String sql = "select id, " + + " area, cdate, city, " + + " doornumber, email, " + + " fname as username, " + + " phone, pincode, street, " + + " title, ward, zone " + + " from pet_owner where phone = ? "; + return jdbcTemplate.queryForList(sql, mobile); + } + + + //get type of pet + public List> getTypeOfPets() { + String petsql = "select * from type"; + return jdbcTemplate.queryForList(petsql); + } + + + public List> getAllYears() { + String yearsql = "select * from year order by id asc"; + return jdbcTemplate.queryForList(yearsql); + } + + + public List> getAllMonths() { + String monthsql = "select * from month order by id asc"; + return jdbcTemplate.queryForList(monthsql); + } + + + public String saveAllRegistrationDetails(String petname, String species, String breed, String identification_mark, + String petcolor, String gender, String age_year, String months, + String is_sterilized, String is_adopted_street, String is_rabies_vaccination, + String arv_date, String lastdate_of_deworming, String other_vaccination, + String previous_licenseNo, String consultant_name, String council_number, String mobilenum, + MultipartFile applicantphoto, MultipartFile addressproof, + MultipartFile petphoto, MultipartFile rabiesvacCertificate,String registerdate) { + + // Convert age to string format like "2.3" where 2 = years and 3 = months + String computedAge; + + String source="2"; + try { + String yearPart = (age_year != null && !age_year.isEmpty()) ? age_year.trim() : "0"; + String monthPart = (months != null && !months.isEmpty()) ? months.trim() : "0"; + + // Validate numeric input + Integer.parseInt(yearPart); + Integer.parseInt(monthPart); + + computedAge = yearPart + "." + monthPart; + } catch (NumberFormatException e) { + e.printStackTrace(); + return "error: invalid age input"; + } + + // Declare as final after computation + final String finalAge = computedAge; + +// // Step 1: Fetch zone from pet_owner using mobile number +// String zoneFetched = null; +// try { +// zoneFetched = jdbcTemplate.queryForObject( +// "SELECT zone FROM pet_owner WHERE phone = ?", +// new Object[]{mobilenum}, +// String.class +// ); +// } catch (Exception e) { +// e.printStackTrace(); +// return "error: unable to fetch zone from pet_owner"; +// } +// +// final String zone = zoneFetched; + + + // Step 1: Fetch zone from pet_owner using mobile number + String zoneFetched = null; + try { + List zones = jdbcTemplate.query( + "SELECT zone FROM pet_owner WHERE phone = ? ", + new Object[]{mobilenum}, + (rs, rowNum) -> rs.getString("zone") + ); + + + if (zones.isEmpty()) { + return "error: mobile number not found in pet_owner"; + } + + zoneFetched = zones.get(0); + } catch (Exception e) { + e.printStackTrace(); + return "error: database error while fetching zone"; + } + + final String zone = zoneFetched; + + + + String sql = "INSERT INTO petdetails (" + + "petname, species, breed, identificationmark, petcolor, gender, age, " + + "sterilized, stray, vaccinated, arvdate, dewormdate, othervac, " + + "previoslicense_no, veterinary_consultant, tnvcno, mobilenum,zone,status,registerdate,source) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?)"; + + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + //String finalAge = age; + + int result = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); + ps.setString(1, petname); + ps.setString(2, species); + ps.setString(3, breed); + ps.setString(4, identification_mark); + ps.setString(5, petcolor); + ps.setString(6, gender); + ps.setString(7, finalAge); + ps.setString(8, is_sterilized); + ps.setString(9, is_adopted_street); + ps.setString(10, is_rabies_vaccination); + ps.setString(11, arv_date); + ps.setString(12, lastdate_of_deworming); + ps.setString(13, other_vaccination); + ps.setString(14, previous_licenseNo); + ps.setString(15, consultant_name); + ps.setString(16, council_number); + ps.setString(17, mobilenum); + ps.setString(18, zone); + ps.setInt(19, 0); + ps.setString(20,registerdate); + ps.setString(21,source); + return ps; + }, keyHolder); + + + if (result > 0 && keyHolder.getKey() != null) { + Number petId = keyHolder.getKey(); + + // 4. Get uniqueid using petId + String uniqueId; + try { + uniqueId = jdbcTemplate.queryForObject( + "SELECT uniqueid FROM petdetails WHERE uniqueid = ?", + new Object[]{petId}, + String.class + ); + } catch (Exception e) { + e.printStackTrace(); + return "error: unable to fetch uniqueid after insert"; + } + + // File upload and metadata + String applicantOriginalName = applicantphoto != null ? applicantphoto.getOriginalFilename() : ""; + String applicantMimeType = applicantphoto != null ? applicantphoto.getContentType() : ""; + String applicantPath = applicantphoto != null ? fileUpload(applicantphoto, "applicant_photo") : ""; + + String addressOriginalName = addressproof != null ? addressproof.getOriginalFilename() : ""; + String addressMimeType = addressproof != null ? addressproof.getContentType() : ""; + String addressPath = addressproof != null ? fileUpload(addressproof, "address_proof") : ""; + + String petOriginalName = petphoto != null ? petphoto.getOriginalFilename() : ""; + String petMimeType = petphoto != null ? petphoto.getContentType() : ""; + String petPath = petphoto != null ? fileUpload(petphoto, "pet_photo") : ""; + + String rabiesOriginalName = rabiesvacCertificate != null ? rabiesvacCertificate.getOriginalFilename() : ""; + String rabiesMimeType = rabiesvacCertificate != null ? rabiesvacCertificate.getContentType() : ""; + String rabiesPath = rabiesvacCertificate != null ? fileUpload(rabiesvacCertificate, "rabies_certificate") : ""; + + // Insert into pet_support_doc + String docSql = "INSERT INTO pet_support_doc (" + + "petdetails_uniqueid, address_file_name, address_file_type, address_proof_url, " + + "applicant_file_name, applicant_file_type, applicant_photo_url, " + + "pet_file_name, pet_file_type, pet_photo_url, " + + "rabies_file_name, rabies_file_type, rabies_certificate_url) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + jdbcTemplate.update(docSql, + uniqueId, + addressOriginalName, addressMimeType, addressPath, + applicantOriginalName, applicantMimeType, applicantPath, + petOriginalName, petMimeType, petPath, + rabiesOriginalName, rabiesMimeType, rabiesPath + ); + + return uniqueId; + + //return String.valueOf(petId); + + } + + + } catch (Exception e) { + e.printStackTrace(); + } + + return "error"; + } + + + //generate randomstring + + 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(); + } + + + 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(); + } + + + //fileupload + + public String fileUpload(MultipartFile file, String docType) { + if (file == null || file.isEmpty()) { + return ""; + } + + try { + // Get base upload directory from application.properties + String baseDir = environment.getProperty("file.upload.directory"); + + // Decide folder based on document type + String folderName; + switch (docType) { + case "applicant_photo": + folderName = "applicantPhotos"; + break; + case "address_proof": + folderName = "addressProofs"; + break; + case "pet_photo": + folderName = "petPhotos"; + break; + case "rabies_certificate": + folderName = "rabiesCertificates"; + break; + default: + folderName = "/others"; + } + + // Add year/month subfolders + String year = DateTimeUtil.getCurrentYear(); + String month = DateTimeUtil.getCurrentMonth(); + String fullDirPath = baseDir + "/" + folderName; + + // Ensure directory exists + Path directoryPath = Paths.get(fullDirPath); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Generate safe and unique file name + String timestamp = DateTimeUtil.getCurrentDateTime(); // like 20250715143210 + String originalFileName = file.getOriginalFilename(); + String fileName = docType + "_" + timestamp + "_" + originalFileName.replaceAll("\\s+", ""); + Path filePath = Paths.get(fullDirPath, fileName); + + // Compress image and write to disk + BufferedImage image = ImageIO.read(file.getInputStream()); + byte[] compressedBytes = compressImage(image, 0.5f); // 50% quality + Files.write(filePath, compressedBytes); + + // Return relative path for DB + return fileBaseUrl +"/gccrestservices/files/" + folderName + "/" + fileName; + + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + + + public List> getPetRegistrationDetailsbyMobile(String mobilenum) { + String sql = + "SELECT " + + " pd.uniqueid, " + + " pd.tnvcno, " + + " pd.veterinary_consultant, " + + " pd.age, " + + " pd.arvdate, " + + " pd.breed, " + + " pd.dewormdate, " + + " pd.gender, " + + " pd.identificationmark, " + + " pd.mobilenum, " + + " pd.other_breed, " + + " pd.othervac, " + + " pd.petcolor, " + + " pd.petname, " + + " pd.previoslicense_no, " + + " DATE_FORMAT(pd.registerdate, '%d-%m-%Y') AS registerdate, " + + " pd.species, " + + " pd.sterilized, " + + " pd.stray, " + + " pd.updatedby, " + + " pd.vaccinated, " + + " pd.zone, " + + + " psd.address_proof_url, " + + " psd.applicant_photo_url, " + + " psd.pet_photo_url, " + + " psd.rabies_certificate_url, " + + + // Status mapping as flags + " CASE WHEN pd.status = 0 THEN 'in_progress' " + + " WHEN pd.status = 1 THEN 'pending_for_payment' " + + " WHEN pd.status = 2 THEN 'license_issued' " + + " WHEN pd.status = 3 THEN 'rejected' " + + " WHEN pd.status = 4 THEN 'expired' ELSE 'UNKNOWN' " + + + " END AS status " + + + "FROM petdetails pd " + + "JOIN pet_support_doc psd ON pd.uniqueid = psd.petdetails_uniqueid " + + "WHERE pd.mobilenum = ?"; + + List> results= jdbcTemplate.queryForList(sql, mobilenum); + for (Map result : results) { + Object petId = result.get("uniqueid"); + Object mobile = result.get("mobilenum"); + + if (petId != null && mobile != null) { + String licenseUrl = "https://gccservices.chennaicorporation.gov.in/gccrestservices/petregistration/downloadLicense" + + "?name=downloadLic" + + "&id=" + petId + + "&mobileNo=" + mobile; + result.put("licenseUrl", licenseUrl); + } + } + return results; + } + + + + public String updateARVAndRabiesCertificate( + String uniqueid, + String arvDateStr, + MultipartFile rabiesvacCertificate + ) { + try { + // Parse arvDate + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate arvDate = LocalDate.parse(arvDateStr.trim(), formatter); + + // Step 1: Fetch previous license validity date + String fetchValiditySql = "SELECT pl.validity FROM pet_license pl " + + "JOIN petdetails pd ON pd.uniqueid = pl.uniqueid " + + "WHERE pd.uniqueid = ?"; + + LocalDate validityDate = jdbcTemplate.queryForObject(fetchValiditySql, new Object[]{uniqueid}, + (rs, rowNum) -> { + String validityStr = rs.getString("validity"); // e.g., "29-07-2026" + DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + return LocalDate.parse(validityStr, inputFormat); + }); + + + // Step 2: Check if the renewal is allowed + LocalDate allowedRenewalDate = validityDate.plusYears(1); + if (arvDate.isBefore(allowedRenewalDate)) { + return "Renewal allowed only after: " + allowedRenewalDate.toString(); + } + + // Step 3: Extract file metadata + String rabiesOriginalName = rabiesvacCertificate != null ? rabiesvacCertificate.getOriginalFilename() : ""; + String rabiesMimeType = rabiesvacCertificate != null ? rabiesvacCertificate.getContentType() : ""; + String rabiesPath = rabiesvacCertificate != null ? fileUpload(rabiesvacCertificate, "rabiesCertificates") : ""; + + // Step 4: Perform update + String updateSql = "UPDATE petdetails pd " + + "JOIN pet_support_doc psd ON pd.uniqueid = psd.pet_doc_id " + + "SET pd.arvdate = ?, " + + "psd.rabies_file_name = ?, " + + "psd.rabies_file_type = ?, " + + "psd.rabies_certificate_url = ? " + + "WHERE pd.uniqueid = ?"; + + int updated = jdbcTemplate.update(updateSql, + arvDateStr, + rabiesOriginalName, + rabiesMimeType, + rabiesPath, + uniqueid + ); + + return updated > 0 ? "success" : "No record found for uniqueid: " + uniqueid; + + } catch (EmptyResultDataAccessException e) { + return "No license validity found for this unique ID"; + } catch (DateTimeParseException e) { + return "Invalid ARV date format. Please use yyyy-MM-dd"; + } catch (Exception e) { + e.printStackTrace(); + return "Error while updating: " + e.getMessage(); + } + } + + + +// public String updateARVAndRabiesCertificate( +// String uniqueid, +// String arvDate, +// MultipartFile rabiesvacCertificate +// ) { +// try { +// // Extract rabies certificate file metadata +// String rabiesOriginalName = rabiesvacCertificate != null ? rabiesvacCertificate.getOriginalFilename() : ""; +// String rabiesMimeType = rabiesvacCertificate != null ? rabiesvacCertificate.getContentType() : ""; +// String rabiesPath = rabiesvacCertificate != null ? fileUpload(rabiesvacCertificate, "rabiesCertificates") : ""; +// +// // SQL query to update both tables using join +// String sql = +// "UPDATE petdetails pd " + +// "JOIN pet_support_doc psd ON pd.uniqueid = psd.pet_doc_id " + +// "SET pd.arvdate = ?, " + +// "psd.rabies_file_name = ?, " + +// "psd.rabies_file_type = ?, " + +// "psd.rabies_certificate_url = ? " + +// "WHERE pd.uniqueid = ?"; +// +// int updated = jdbcTemplate.update(sql, +// arvDate, +// rabiesOriginalName, +// rabiesMimeType, +// rabiesPath, +// uniqueid +// ); +// +// if (updated > 0) { +// return "success"; +// } else { +// return "No record found for uniqueid: " + uniqueid; +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// return "Error while updating: " + e.getMessage(); +// } +// } + + + public int saveorderLog(String id, String orderInfo, int petId) { + if (id == null || petId == 0) { + System.out.println("❌ Missing required fields. Order ID: " + id + ", Temp Book ID: " + petId); + return 0; + } + + String sqlQuery = "INSERT INTO orderslogs(order_id, order_info, uniqueid) VALUES (?,?,?)"; + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); + ps.setString(1, id); + ps.setString(2, orderInfo); + ps.setInt(3, petId); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + return (generatedId != null) ? generatedId.intValue() : 0; + } else { + System.out.println("❌ Failed to insert into order_log."); + return 0; + } + } catch (Exception e) { + System.out.println("🚨 Exception during insert to order_log: " + e.getMessage()); + e.printStackTrace(); + return 0; + } + } + + public List> getZones() { + String zonesql = "select id,zone_name from zone_master"; + return jdbcTemplate.queryForList(zonesql); + } + + + public List> getWardByZoneId(String zoneid) { + String wardsql = "select id,ward_name,zone_id from ward_master where zone_id = ?"; + return jdbcTemplate.queryForList(wardsql, zoneid); + } + + + public ResponseEntity processPaymentConfirmation(String petId, String source, String mobno, String orderId, Map paymentResponse) { + + System.out.println("petId:--"+petId); + System.out.println("Payment Response: " + paymentResponse); + System.out.println("OrderId from parameter: " + orderId); + + int uniqueid = Integer.parseInt(petId); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + LocalDateTime now = LocalDateTime.now(); + + Double amount = 50.0; + + try { + // Debug: Print the structure to understand it better + System.out.println("Payment Response Keys: " + paymentResponse.keySet()); + + // Handle the new nested payment response structure + Map transaction = null; + String paymentId = null; + String status = null; + + // Check if transaction is directly in paymentResponse + if (paymentResponse.containsKey("transaction")) { + transaction = (Map) paymentResponse.get("transaction"); + System.out.println("Found transaction directly: " + transaction); + } else if (paymentResponse.containsKey("currency")) { + // New structure with nested transaction inside currency + Map currency = (Map) paymentResponse.get("currency"); + System.out.println("Currency keys: " + currency.keySet()); + if (currency.containsKey("transaction")) { + transaction = (Map) currency.get("transaction"); + System.out.println("Found transaction in currency: " + transaction); + } + } + + if (transaction != null) { + System.out.println("Transaction keys: " + transaction.keySet()); + // Extract payment details from transaction with null checks + paymentId = transaction.get("pg_transaction_id") != null ? transaction.get("pg_transaction_id").toString() : null; + status = transaction.get("status") != null ? transaction.get("status").toString() : null; + + System.out.println("Parsed values - paymentId: " + paymentId + ", status: " + status); + } else { + System.out.println("No transaction found in payment response"); + } + + // Use the provided orderId parameter directly (not from payment response) + String finalOrderId = orderId; + + // Validate required fields from payment response + if (paymentId == null || status == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("message", "Invalid payment response structure"); + errorResponse.put("error", "Missing required transaction fields. Found - paymentId: " + paymentId + ", status: " + status); + errorResponse.put("paymentResponse", paymentResponse); + return ResponseEntity.badRequest().body(errorResponse); + } + + savePaymentResponse(finalOrderId, paymentId, status, paymentResponse, uniqueid); + + if ("failed".equalsIgnoreCase(status)) { + // Convert entire response map to JSON string + ObjectMapper mapper = new ObjectMapper(); + String fullResponseJson = mapper.writeValueAsString(paymentResponse); + + // Save to DB (assuming you have a method) + saveFailedTransaction(finalOrderId, paymentId, status, fullResponseJson, uniqueid); + + return ResponseEntity.ok(Map.of( + "message", "Your payment failed. Please try again." + )); + } else if ("success".equalsIgnoreCase(status)) { + + int s = Integer.parseInt(source) ; + + int result = savePaymentInfo(mobno, uniqueid, paymentId, status, dtf.format(now), finalOrderId, amount, s); + + System.out.println("result...result"+result); + + if (result > 0) { + String licNo = savePetLicense(uniqueid, Long.parseLong(mobno)); + System.out.println("Service Testing........."); + return ResponseEntity.ok(Map.of( + "message", "Your payment was successful " + + + )); + } + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment")); + } + + } catch (Exception ex) { + ex.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment", "error", ex.getMessage())); + + } + + + return ResponseEntity.ok(Map.of("msg", "updated")); + } + + public void savePaymentResponse(String orderId, String payId, String status, + Map paymentResponse, int uniqueId) { + + String sql = "INSERT INTO payment_response (order_id, payment_id, payment_status, response, uniqueId) " + + "VALUES (?, ?, ?, ?, ?)"; + + try { + String jsonResponse = objectMapper.writeValueAsString(paymentResponse); + jdbcTemplate.update(sql, orderId, payId, status, jsonResponse, uniqueId); + } catch (Exception e) { + e.printStackTrace(); // log or rethrow as needed + } + } + + public void saveFailedTransaction(String orderId, String paymentId, String status, String fullJsonResponse, int uniqueId) { + String sql = "INSERT INTO payment_failed_response (order_id, payment_id, payment_status, response, uniqueId) " + + "VALUES (?, ?, ?, ?, ?)"; + + jdbcTemplate.update(sql, orderId, paymentId, status, fullJsonResponse, uniqueId); + } + + public int savePaymentInfo(String mobno, int uniqueid, String payId, String status, String format, String orderId, Double amount, int source) { + String sql = "INSERT INTO payment (amount, mobno, order_id, payment_id, payment_status, paymentdate, uniqueid) " + + "VALUES (?, ?, ?, ?, ?, ?, ?)"; + + int count = jdbcTemplate.update(sql, amount, mobno, orderId, payId, status, format, uniqueid); + + return count; + } + + public String savePetLicense(int uniqueid, long mobno) { + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + String issueDate = dateFormat.format(c.getTime()); + c.add(Calendar.YEAR, 1); + c.add(Calendar.DATE, -1); + String validityDate = dateFormat.format(c.getTime()); + + Map ownerDetails = getOwnerDetailsByMobNo(mobno); + int year = LocalDate.now().getYear(); + + // int z = (int) ownerDetails.get("zone"); + int z = Integer.parseInt(ownerDetails.get("zone").toString()); + + System.out.println("zone..."+z); + // Generate license number + String licenseNo = year + "/" + String.format("%02d", z) + "/" + String.format("%05d", uniqueid); + + Map existingLicenses = checkLincenseExistsByMobNoAndUniqueid(mobno, uniqueid); + + if (!existingLicenses.isEmpty()) { + addOldPetLic(existingLicenses); + // Renewal case - update existing license + String updateSql = "UPDATE pet_license SET license_no = ?, date = ?, validity = ? WHERE phone = ? AND uniqueid = ?"; + jdbcTemplate.update(updateSql, licenseNo, new java.sql.Date(date.getTime()), validityDate, mobno, uniqueid); + } else { + // New license case - insert + String insertSql = "INSERT INTO pet_license (license_no, phone, uniqueid, date, validity) VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertSql, licenseNo, mobno, uniqueid, new java.sql.Date(date.getTime()), validityDate); + } + + // Update pet status + System.out.println("before update pet status"+mobno+"\n"+uniqueid); + updatePetStatus(mobno, uniqueid, 2); + + return licenseNo; + } + + private Map getOwnerDetailsByMobNo(long mobno) { + String query = "SELECT * FROM pet_owner WHERE phone = ?"; + try { + return jdbcTemplate.queryForMap(query, mobno); + } catch (EmptyResultDataAccessException e) { + return Collections.emptyMap(); + } + } + + private Map checkLincenseExistsByMobNoAndUniqueid(long mobno, int uniqueid) { + // Check if license already exists + String checkSql = "SELECT * FROM pet_license WHERE phone = ? AND uniqueid = ?"; +// Map existingLicenses = jdbcTemplate.queryForMap(checkSql, mobno, uniqueid); +// return existingLicenses; + try { + return jdbcTemplate.queryForMap(checkSql, mobno, uniqueid); + } catch (EmptyResultDataAccessException e) { + return Collections.emptyMap(); + } + + } + + private void addOldPetLic(Map existingLicenses) { + + LocalDateTime localDateTime = (LocalDateTime) existingLicenses.get("date"); + Timestamp timestamp = Timestamp.valueOf(localDateTime); + + + String licenseNo = (String) existingLicenses.get("license_no"); + long mobno = (long) existingLicenses.get("phone"); + int uniqueid = (int) existingLicenses.get("uniqueid"); + String validityDate = (String) existingLicenses.get("validity"); +// Timestamp dateTime = (Timestamp) existingLicenses.get("date"); + String sql = "Insert into old_pet_license (license_no, phone, uniqueid, date, validity) VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(sql, licenseNo, mobno, uniqueid, timestamp, validityDate); + } + + private void updatePetStatus(long mobno, int uniqueid, int status) { + System.out.println("inside pet status method"); + String sql = "UPDATE petdetails SET status =?, mobilenum =? WHERE uniqueid = ?"; + jdbcTemplate.update(sql, status, mobno, uniqueid); + } + + + // get licensedetails api + public List> getLicenseListByMobNo(String licenseno) { + String sql = "SELECT " + + "pd.uniqueid, " + + "pd.tnvcno, " + + "pd.veterinary_consultant, " + + "pd.age, " + + "pd.arvdate, " + + "pd.breed, " + + "pd.dewormdate, " + + "pd.gender, " + + "pd.identificationmark, " + + "pd.mobilenum, " + + "pd.other_breed, " + + "pd.othervac, " + + "pd.petcolor, " + + "pd.petname, " + + "pd.previoslicense_no, " + + "DATE_FORMAT(pd.registerdate, '%d-%m-%Y') AS registerdate, " + + "pd.rejectreason, " + + "pd.species, " + + " DATE_FORMAT(pd.statusdate, '%d-%m-%Y') AS statusdate, " + + "pd.sterilized, " + + "pd.stray, " + + "pd.updatedby, " + + "pd.vaccinated, " + + "pd.zone, " + + "pl.license_no, " + + "psd.address_proof_url, " + + "psd.applicant_photo_url, " + + "psd.pet_photo_url, " + + "psd.rabies_certificate_url, " + + "CASE " + + " WHEN pd.status = 0 THEN 'in_progress' " + + " WHEN pd.status = 1 THEN 'pending_for_payment' " + + " WHEN pd.status = 2 THEN 'license_issued' " + + " WHEN pd.status = 3 THEN 'rejected' " + + " WHEN pd.status = 4 THEN 'expired' " + + " ELSE 'UNKNOWN' " + + "END AS application_status " + + "FROM petdetails pd " + + "JOIN pet_license pl ON pd.uniqueid = pl.uniqueid " + + "JOIN pet_support_doc psd ON pd.uniqueid = psd.petdetails_uniqueid " + + "WHERE pl.license_no = ?"; + return jdbcTemplate.queryForList(sql, licenseno); + } + + + public Map getbymobnoanduniqueId(String mobno,int uniqueid) { + String sql = " select pd.* ,pl.validity,psd.pet_photo_url,psd.pet_file_name" + + " from petdetails pd" + + " left join pet_license pl on pl.uniqueid=pd.uniqueid" + + " left join pet_support_doc psd on psd.petdetails_uniqueid=pd.uniqueid" + + " where pl.phone=? AND pd.uniqueid= ?"; + return jdbcTemplate.queryForMap(sql, mobno,uniqueid); + } + + + + + public Map getbylicensemobnoanduniqueId(String mobno, int uniqueid) { + String sql = "SELECT * FROM pet_license WHERE phone= ? and uniqueid= ? "; + return jdbcTemplate.queryForMap(sql, mobno, uniqueid); + } + + public Map getOwnerDetailsbymobile(String mobile) { + String sql = "select * " + + " from pet_owner where phone = ? "; + return jdbcTemplate.queryForMap(sql, mobile); + } + +// add by sanjay use of allow only accept request + public Map getpetdetails(String petId) { + + String sql ="select * from petdetails where uniqueid = ? AND status IN (2,4)"; + return jdbcTemplate.queryForMap(sql, petId); + } + + public int getCountByMobileNo(String mobileno) { + String sql = "SELECT COUNT(*) FROM petdetails pd WHERE pd.mobilenum = ? AND pd.status IN (0,1,2,4)"; + return jdbcTemplate.queryForObject(sql, Integer.class, mobileno); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/service/PetSMSService.java b/src/main/java/com/gcc/restapiservices/petregistration/service/PetSMSService.java new file mode 100644 index 0000000..26dc068 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/service/PetSMSService.java @@ -0,0 +1,603 @@ +package com.gcc.restapiservices.petregistration.service; + +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.lang3.ObjectUtils.Null; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import jakarta.servlet.http.HttpSession; + +@Service +public class PetSMSService { + + private static final String GUPSHUP_API_URL = "https://media.smsgupshup.com/GatewayAPI/rest"; + private static final String SMS_API_URL = "https://tmegov.onex-aura.com/api/sms?"; + + // Gupshup credentials + private static final String USER_ID = "2000233507"; + private static final String PASSWORD = "h2YjFNcJ"; + + // Onex-Aura credentials + private static final String SMS_ENTITY_ID = "1401572690000011081"; + private static final String SMS_TEMPLATE_ID = ""; + private static final String SMS_SENDER_ID = "GCCCRP"; + + String apikey = "5c995535-6244-11f0-98fc-02c8a5e042bd"; + String from = "919445061913"; + + String key = "pfTEYN6H"; + + public String sendMessage(int scenarioId, String var1, String var2, + String var3, String mobileNumber) { + String templateId = null; + + String message = prepareMessage(scenarioId, var1, var2, var3, mobileNumber); + + if (message.startsWith("Invalid")) { + return message; + } + + String response = sendSms(message); + + // return "Message Sent: " + message + "\nResponse: " + response; + return "Response: " + response; + } + + public String sendWhatsappMessage(int scenarioId, String var1, String var2, + String var3, String mobileNumber) { + + String message = prepareWhatsappMessage(scenarioId, var1, var2, var3, mobileNumber); + + if (message.startsWith("Invalid")) { + return message; + } + + String response = sendWhatsApp(message); + + return "Response: " + response; + } + + private String prepareMessage(int scenarioId, String var1, String var2, String var3, String MobileNo) { + String message; + String urlString = null; + + switch (scenarioId) { + case 1: // Signup OTP + message = "Dear " + var1 + ", your OTP for account sign-up is " + + var2 + ". This code is valid for 10 minutes. Do not share it with anyone. - GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923154012472"; + break; + + case 2: // License Application Received + message = "Dear " + var1 + ", your application ID: " + var2 + " " + + "is currently Received. For more details, please contact us at " + + var3 + ". – GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923230686244"; + break; + + case 3: // License Application On process + message = "Dear " + var1 + ", your application ID: " + var2 + " " + + "is currently on process. For more details, please contact us at " + + var3 + ". – GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923248822204"; + break; + + case 4: // Approved + message = "Dear " + var1 + ", " + + "We are pleased to inform you that your application ID: " + var2 + + " has been approved. " + + "For next steps or further details, please contact us at " + var3 + "– GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923274516644"; + break; + + case 5: // Rejected + message = "Dear " + var1 + ", " + + "We regret to inform you that your application ID: " + var2 + " has been rejected. " + + "For more details or assistance, please contact us at " + var3 + ".– GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923292860654"; + break; + + case 6: // Download License Link + message = "Dear " + var1 + ", your document is ready. Please use your ID: " + + var2 + " to download it here: " + var3 + ". – GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923308512766"; + break; + + case 7: // Pet Transfer OTP + message = "Dear " + var1 + ", your OTP for pet transfer ID: " + + var2 + " is " + var3 + ". Do not share this code with anyone. – GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407175923325699477"; + break; + + case 8: // Additional Details Pet License - Missing Data + message = "Dear " + var1 + ", your request (ID: " + + var2 + + ") is pending due to missing details: (Old Existing details, Microchip ID). Please share the info to proceed. By GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407176034136225728"; + break; + + case 9: // Reset Password OTP for Pet License + message = "Dear " + var1 + + ", You have requested to reset your password. Please use the One-Time Password (OTP) below to proceed. OTP: " + + var2 + + " For your security, this OTP will be valid only for the next [time limit, e.g., 10 minutes]. If you did not request this password reset," + + "please ignore this message or contact our support team immediately. By GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407176034124745780"; + break; + + case 10: // Pet License One Time free License Renewal + message = "Dear Pet Owner, Your previous GCC Pet License ID " + var1 + + " is eligible for one-time free license renewal. Use this OTP " + var2 + + " to skip the payment while applying for your new license.-GCC"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407176413912291986"; + break; + + case 11: // Pet License expires tomorrow + message = "Your Pet License expires tomorrow. Kindly visit your veterinarian today and complete the renewal process to avoid license expiry.\n" + + + "- Greater Chennai Corporation"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407178038425363123"; + break; + + case 12: // Pet License 7 days expiry + message = "Your Pet License will expire in 7 days. Please visit your veterinarian and complete the renewal process at the earliest to ensure uninterrupted registration.\n" + + + "- Greater Chennai Corporation"; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407178038413058122"; + break; + + case 13: // Pet License 30 days expiry + message = "Your GCC Pet License will expire in 30 days. Kindly visit your veterinarian to complete the renewal process and avoid expiry. Thank you\n" + + "- Greater Chennai Corporation."; + urlString = SMS_API_URL + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + MobileNo + + "&body=" + message + "&entityid=1401572690000011081&templateid=1407178038404219687"; + break; + + default: + urlString = "Invalid scenario ID."; + } + + return urlString; + + } + + private String prepareWhatsappMessage(int scenarioId, String var1, String var2, String var3, String mobNo) { + String whatsupmsg = null; + String urlString = ""; + String placeholders = ""; + + switch (scenarioId) { + + case 1: // When the Pet is added - For customer and Doctor: + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Hello+%2A" + var1 + + * "%2A%2C%0AYour+request+to+add+a+new+pet+has+been+received.%0APet+Name%3A+%2A" + * + var2 + + * "%2A%0APet+ID%3A+%2A" + var3 + + * "%2A%0AWe+will+notify+you+once+the+registration+is+complete." + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2 + "|~|" + var3, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055707&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + break; + + case 2: // Confirmation of the License application (Received) + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Dear+" + var1 + "%2C+your+application+%28ID%3A+%2A" + var2 + + * "%2A%29+is+currently+Received+.+%0AFor+more+details%2C+please+contact+us+at+https%3A%2F%2Fpetservice.gccservices.in%2F." + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055762&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 3: // Confirmation of the License application (On process) + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Dear+" + var1 + "%2C+your+application+%28ID%3A+%2A" + var2 + + * "%2A%29+is+currently+On+process+.+%0AFor+more+details%2C+please+contact+us+at+https%3A%2F%2Fpetservice.gccservices.in" + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055764&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 4: // approved + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Hello+" + var1 + + * "%2C%0AWe+are+pleased+to+inform+you+that+your+application+%28ID%3A+%2A" + * + var2 + + * "%2A%29+has+been+approved.%0AFor+next+steps+or+further+details%2C+please+contact+us+at+https%3A%2F%2Fpetservice.gccservices.in" + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055772&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 5: // rejected + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Hello+" + var1 + + * "%2C%0AWe+regret+to+inform+you+that+your+application+%28ID%3A+%2A" + var2 + * + + * "%2A%29+has+been+rejected.%0AFor+more+details+or+assistance%2C+please+contact+us+at+https%3A%2F%2Fpetservice.gccservices.in" + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055776&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 6: // 24 Hours License Status + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Hello+" + var1 + "%2C%0AYour+application+%28ID%3A+%2A" + var2 + + * "%2A%29+is+currently+ON+process.%0AFor+more+details%2C+please+contact+us+at+https%3A%2F%2Fpetservice.gccservices.in" + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3287449&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 7: // Complaint Submitted + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Dear+" + var1 + + * "%2C++%0AWe+have+received+your+complaint%2Fgrievance+with+Reference+ID%3A+%2A" + * + var2 + + * "%2A.++%0AOur+support+team+will+review+the+details+and+keep+you+updated+on+the+progress.++%0AThank+you+for+reaching+out+to+us." + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055806&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 8: // Complaint Status + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Dear+" + var1 + * + + * "%2C++%0AWe+have+received+your+complaint%2Fgrievance+with+Reference+ID%3A+%2A" + * + var2 + + * "%2A.++%0AOur+team+is+reviewing+the+details+and+will+get+back+to+you+shortly.++%0AThank+you+for+bringing+this+to+our+attention." + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055818&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 9: // Complaint Closed + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE" + + * "&msg=Dear+" + var1 + + * "%2C++%0AYour+complaint%2Fgrievance+with+Reference+ID%3A+%2A" + var2 + + * "%2A+has+been+successfully+closed.++%0AIf+you+have+any+further+concerns+or+require+assistance%2C+please+feel+free+to+contact+us.++%0AThank+you+for+your+patience+and+for+giving+us+the+opportunity+to+serve+you." + * + + * "&isTemplate=true" + + * "&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055836&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 10: // Additional Details Pet License - Missing Data + /* + * whatsupmsg = "https://mediaapi.smsgupshup.com/GatewayAPI/rest?" + + * "userid=2000233507" + + * "&password=h2YjFNcJ" + + * "&send_to=" + mobNo + "&v=1.1" + + * "&format=json" + + * "&msg_type=TEXT" + + * "&method=SENDMESSAGE&msg=Hello+" + var1 + * + + * "%2C++%0A%0AWe+noticed+that+some+required+details+are+missing+from+your+recent+submission+ID%3A+" + * + var2 + + * ".++%0ATo+proceed+further%2C+please+share+the+following+missing+information%3A++%0A1.+Upload+documents+%28old+health%2C+vaccine+charts%29%0A2.+Upload+address+proof%0A3.+If+microchipped%2C+share+the+microchip+id+immediately%0A%0AKindly+provide+the+details+at+your+earliest+convenience." + * + + * "++%0AThank+you+for+your+prompt+attention." + + * "&isTemplate=true&footer=-+GCC"; + */ + + try { + placeholders = URLEncoder.encode(var1 + "|~|" + var2, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3055750&placeholders=" + placeholders + ""; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 11: // License expires tomorrow + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3270149"; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 12: // License expires in 7 days + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3270148"; + + System.out.println(urlString + ":" + mobNo); + + break; + + case 13: // License expires in 30 days + + urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=" + apikey + "&from=" + + from + + "&to=91" + mobNo + "" + + "&type=template&templateid=3270142"; + + System.out.println(urlString + ":" + mobNo); + + break; + + default: + whatsupmsg = "Invalid scenario ID."; + } + + // return whatsupmsg; + return urlString; + } + + private String sendWhatsApp(String msgUrl) { + System.out.println("Whatsapp URL :-" + msgUrl); + + String response = ""; + try { + HttpURLConnection connection = null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + private String sendSms(String urlString) { + System.out.print(" urlString---: " + urlString); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + // Create ObjectMapper instance + ObjectMapper mapper = new ObjectMapper(); + + // Parse response to ObjectNode + ObjectNode jsonResponse = (ObjectNode) mapper.readTree(Response); + + bodyMessage = jsonResponse.toString(); + System.out.println(" bodyMessage: " + bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: " + e); + bodyMessage = "Error"; + } + + return bodyMessage; + } +} diff --git a/src/main/java/com/gcc/restapiservices/petregistration/util/ApiResponseUtil.java b/src/main/java/com/gcc/restapiservices/petregistration/util/ApiResponseUtil.java new file mode 100644 index 0000000..7626809 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/util/ApiResponseUtil.java @@ -0,0 +1,46 @@ +package com.gcc.restapiservices.petregistration.util; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +public class ApiResponseUtil { + + public static ResponseEntity>> success(Object data, String message) { + return buildResponse(true, HttpStatus.OK, message, data); + } + + public static ResponseEntity>> notFound(String message) { + return buildResponse(false, HttpStatus.NOT_FOUND, message, Collections.emptyList()); + } + + public static ResponseEntity>> error(String message, HttpStatus status) { + return buildResponse(false, status, message, null); + } + + public static ResponseEntity>> invalidRequest(String message) { + return buildResponse(false, HttpStatus.BAD_REQUEST, message, Collections.emptyList()); + } + + + public static ResponseEntity>> buildResponse( + boolean statusFlag, + HttpStatus httpStatus, + String message, + Object data + ) { + Map response = new LinkedHashMap<>(); + response.put("status", statusFlag); + response.put("code", httpStatus.value()); + response.put("message", message); + response.put("data", data); + + List> responseList = Collections.singletonList(response); + return ResponseEntity.status(httpStatus).body(responseList); + } + +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/petregistration/util/DateTimeUtil.java b/src/main/java/com/gcc/restapiservices/petregistration/util/DateTimeUtil.java new file mode 100644 index 0000000..34fb5af --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/petregistration/util/DateTimeUtil.java @@ -0,0 +1,35 @@ +// package com.gcc.restapiservices.petregistration.util; + +// 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); +// } +// } \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/propertytax/controller/PropertyTaxOtpController.java b/src/main/java/com/gcc/restapiservices/propertytax/controller/PropertyTaxOtpController.java new file mode 100644 index 0000000..4489d5f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/propertytax/controller/PropertyTaxOtpController.java @@ -0,0 +1,324 @@ +package com.gcc.restapiservices.propertytax.controller; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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 com.gcc.restapiservices.propertytax.service.PropertyTaxOtpService; + +@RequestMapping("/gccrestservices/api/propertytax") +@RestController +public class PropertyTaxOtpController { + + private PropertyTaxOtpService propertyTaxOtpService; + + @Autowired + public PropertyTaxOtpController(PropertyTaxOtpService propertyTaxOtpService) { + this.propertyTaxOtpService = propertyTaxOtpService; + } + + // @GetMapping("/getErpDetails") + // public ResponseEntity> getErpDetails( + // @RequestParam String zone, + // @RequestParam String division, + // @RequestParam String billNo, + // @RequestParam(required = false) String subBill) { + + // try { + // System.out.println("zone = " + zone); + // System.out.println("division = " + division); + // System.out.println("billNo = " + billNo); + // System.out.println("subBill = " + subBill); + + // // Validate required parameters + // if (zone == null || zone.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Zone parameter is required" + // )); + // } + + // if (division == null || division.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Division parameter is required" + // )); + // } + + // if (billNo == null || billNo.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Bill number parameter is required" + // )); + // } + + // Map result = propertyTaxOtpService.getErpDetails(zone, division, billNo, subBill); + + // if (result == null || result.isEmpty()) { + // return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of( + // "status", "error", + // "status_code", 404, + // "message", "No ERP details found for the provided parameters" + // )); + // } + + // return ResponseEntity.ok(Map.of( + // "status", "success", + // "status_code", 200, + // "data", result + // )); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + // "status", "error", + // "status_code", 500, + // "message", "Internal Server Error: " + e.getMessage() + // )); + // } + // } + + @GetMapping("/getWardByZoneId") + public ResponseEntity> getWardByZoneId(@RequestParam int zoneId) { + try { + Map result = propertyTaxOtpService.getWardByZoneId(zoneId); + + // Check if the result contains data + List> data = (List>) result.get("data"); + if (data == null || data.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of( + "status", "error", + "status_code", 404, + "message", "No ward data found for zoneId: " + zoneId + )); + } + + return ResponseEntity.ok(Map.of( + "status", "success", + "status_code", 200, + "data", data + )); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + "status", "error", + "status_code", 500, + "message", "Internal Server Error: " + e.getMessage() + )); + } + } + + @GetMapping("/getZoneMaster") + public ResponseEntity> getZoneMaster() { + try { + Map result = propertyTaxOtpService.getZoneMaster(); + + // Check if the result contains data + List> data = (List>) result.get("data"); + if (data == null || data.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of( + "status", "error", + "status_code", 404, + "message", "No zone master data found" + )); + } + + return ResponseEntity.ok(Map.of( + "status", "success", + "status_code", 200, + "data", data + )); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + "status", "error", + "status_code", 500, + "message", "Internal Server Error: " + e.getMessage() + )); + } + } + + // @PostMapping("/sendOTPNew") + // public ResponseEntity> sendOTP(@RequestParam String mobile) { + // try { + // // Validate mobile number + // if (mobile == null || mobile.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number is required" + // )); + // } + + // if (!mobile.matches("\\d{10}")) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number must be exactly 10 digits" + // )); + // } + + // Map result = propertyTaxOtpService.sendOTP(mobile); + + // return ResponseEntity.ok(Map.of( + // "status", "success", + // "status_code", 200, + // "data", result + // )); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + // "status", "error", + // "status_code", 500, + // "message", "Internal Server Error: " + e.getMessage() + // )); + // } + // } + + // @PostMapping("/verifyOTP") + // public ResponseEntity> verifyOTP(@RequestParam String mobile, @RequestParam String otp) { + // try { + // // Validate parameters + // if (mobile == null || mobile.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number is required" + // )); + // } + + // if (otp == null || otp.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "OTP is required" + // )); + // } + + // if (!mobile.matches("\\d{10}")) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number must be exactly 10 digits" + // )); + // } + + // Map result = propertyTaxOtpService.verifyOTP(mobile, otp); + + // return ResponseEntity.ok(Map.of( + // "status", "success", + // "status_code", 200, + // "data", result + // )); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + // "status", "error", + // "status_code", 500, + // "message", "Internal Server Error: " + e.getMessage() + // )); + // } + // } + + // @PostMapping("/submitData") + // public ResponseEntity> submitData( + // @RequestParam String mobile, + // @RequestParam(value = "zone", required = false) String zone, + // @RequestParam(value = "ZONE", required = false) String zoneUpper, + // @RequestParam(value = "division", required = false) String division, + // @RequestParam(value = "DIVISION", required = false) String divisionUpper, + // @RequestParam(value = "billNo", required = false) String billNo, + // @RequestParam(value = "BILL", required = false) String billUpper, + // @RequestParam(required = false) String subBill, + // @RequestParam(required = false) String SUBBILL, + // @RequestParam String email, + // @RequestParam(required = false) String famCardNo) { + + // try { + // // Handle both uppercase and lowercase parameters + // String finalZone = (zone != null && !zone.trim().isEmpty()) ? zone : zoneUpper; + // String finalDivision = (division != null && !division.trim().isEmpty()) ? division : divisionUpper; + // String finalBillNo = (billNo != null && !billNo.trim().isEmpty()) ? billNo : billUpper; + // String finalSubBill = (subBill != null && !subBill.trim().isEmpty()) ? subBill : SUBBILL; + + // // Validate required parameters + // if (mobile == null || mobile.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number is required" + // )); + // } + + // if (finalZone == null || finalZone.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Zone is required" + // )); + // } + + // if (finalDivision == null || finalDivision.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Division is required" + // )); + // } + + // if (finalBillNo == null || finalBillNo.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Bill number is required" + // )); + // } + + // if (email == null || email.trim().isEmpty()) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Email is required" + // )); + // } + + // if (!mobile.matches("\\d{10}")) { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "error", + // "status_code", 400, + // "message", "Mobile number must be exactly 10 digits" + // )); + // } + + // Map result = propertyTaxOtpService.submitData(mobile, finalZone, finalDivision, finalBillNo, finalSubBill, email, famCardNo); + + // return ResponseEntity.ok(Map.of( + // "status", "success", + // "status_code", 200, + // "data", result + // )); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of( + // "status", "error", + // "status_code", 500, + // "message", "Internal Server Error: " + e.getMessage() + // )); + // } + // } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/propertytax/service/PropertyTaxOtpService.java b/src/main/java/com/gcc/restapiservices/propertytax/service/PropertyTaxOtpService.java new file mode 100644 index 0000000..e2a0f74 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/propertytax/service/PropertyTaxOtpService.java @@ -0,0 +1,313 @@ +package com.gcc.restapiservices.propertytax.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; + +@Service +public class PropertyTaxOtpService { + + // private JdbcTemplate oracleJdbcTemplate; + // private JdbcTemplate oraclePropertyTaxJdbcTemplate; + // private JdbcTemplate oraclePropertyTaxUatJdbcTemplate; + private JdbcTemplate mysqlJdbcTemplate; + + // @Autowired + // public void setOracleDataSource(@Qualifier("oracleDataSource") DataSource oracleDataSource) { + // this.oracleJdbcTemplate = new JdbcTemplate(oracleDataSource); + // } + + // @Autowired + // public void setOraclePropertyTaxDataSource(@Qualifier("oraclepropertytaxDataSource") DataSource oraclePropertyTaxDataSource) { + // this.oraclePropertyTaxJdbcTemplate = new JdbcTemplate(oraclePropertyTaxDataSource); + // } + + // @Autowired + // public void setOraclePropertyTaxUatDataSource(@Qualifier("oraclepropertytax_uatDataSource") DataSource oraclePropertyTaxUatDataSource) { + // this.oraclePropertyTaxUatJdbcTemplate = new JdbcTemplate(oraclePropertyTaxUatDataSource); + // } + + @Autowired + public void setMysqlDataSource(@Qualifier("mysqlGccRestServicesDataSource") DataSource mysqlDataSource) { + System.out.println("Setting MySQL DataSource: " + mysqlDataSource); + this.mysqlJdbcTemplate = new JdbcTemplate(mysqlDataSource); + System.out.println("MySQL JdbcTemplate created: " + this.mysqlJdbcTemplate); + } + + // @Transactional("oracleTransactionManager") + // public Map getErpDetails(String zone, String division, String billNo, String subBill) { + // Map response = new HashMap<>(); + // Map result = new HashMap<>(); + + // try { + // // Construct the UPIC number based on parameters + // String upicNo = zone + "-" + division + "-" + billNo; + // if (subBill != null && !subBill.trim().isEmpty()) { + // upicNo += "-" + subBill; + // } + + // String sql = "select upicno, ownersname, address, c.mobileno, emailaddress, fam_card_no " + + // "from mv1@erp a, egpt_basic_property@erp b, egpt_address@erp c " + + // "where a.upicno = b.propertyid and a.upicno = ? and b.ADDRESSID = c.ID_ADDRESS"; + + // List> data = oracleJdbcTemplate.queryForList(sql, upicNo); + + // if (!data.isEmpty()) { + // Map erpData = data.get(0); + // result.put("upicno", erpData.get("UPICNO")); + // result.put("ownersname", erpData.get("OWNERSNAME")); + // result.put("address", erpData.get("ADDRESS")); + // result.put("mobileno", erpData.get("MOBILENO")); + // result.put("emailaddress", erpData.get("EMAILADDRESS")); + // result.put("fam_card_no", erpData.get("FAM_CARD_NO")); + // result.put("Status", "Success"); + // result.put("Status Code", 200); + // result.put("Message", "ERP details fetched successfully"); + // response.put("Response", result); + // } else { + // result.put("Status", "Not Found"); + // result.put("Status Code", 404); + // result.put("Message", "No ERP details found for UPIC: " + upicNo); + // response.put("Response", result); + // } + // } catch (Exception e) { + // e.printStackTrace(); + // result.put("Status", "Error"); + // result.put("Status Code", 500); + // result.put("Message", "Error in fetching ERP details: " + e.getMessage()); + // response.put("Response", result); + // } + + // return response; + // } + + public Map getZoneMaster() { + Map response = new HashMap<>(); + try { + System.out.println("Executing getZoneMaster..."); + String sql = "SELECT id, zone_name FROM zone_master"; + System.out.println("SQL: " + sql); + List> data = mysqlJdbcTemplate.queryForList(sql); + System.out.println("Data retrieved: " + data.size() + " records"); + response.put("data", data); + return response; + } catch (Exception e) { + System.err.println("Error in getZoneMaster: " + e.getMessage()); + e.printStackTrace(); + return new HashMap<>(); + } + } + + public Map getWardByZoneId(int zoneId) { + Map response = new HashMap<>(); + try { + System.out.println("Executing getWardByZoneId for zoneId: " + zoneId); + String sql = "SELECT wm.id, wm.ward_name FROM zone_master zm JOIN ward_master wm ON zm.id = wm.zone_id WHERE zm.id = ?"; + System.out.println("SQL: " + sql); + List> data = mysqlJdbcTemplate.queryForList(sql, zoneId); + System.out.println("Data retrieved: " + data.size() + " records"); + response.put("data", data); + return response; + } catch (Exception e) { + System.err.println("Error in getWardByZoneId: " + e.getMessage()); + e.printStackTrace(); + return new HashMap<>(); + } + } + + // @Transactional("oraclePropertyTaxTransactionManager") + // public Map sendOTP(String mobile) { + // Map response = new HashMap<>(); + // Map result = new HashMap<>(); + // try { + // String checkSql = "SELECT COUNT(*) FROM coc_web.tbl_ptax_mob WHERE MOB = ?"; + // int count = oraclePropertyTaxJdbcTemplate.queryForObject(checkSql, Integer.class, mobile); + + // String smsIdSql = "SELECT coc_web.seq_sms_id.NEXTVAL as sms_id, ROUND(DBMS_RANDOM.VALUE(10000,99999)) as otp FROM dual"; + // Map smsData = oraclePropertyTaxJdbcTemplate.queryForMap(smsIdSql); + + // String smsId = smsData.get("SMS_ID").toString(); + // String otp = smsData.get("OTP").toString(); + + // String insertSql; + // if (count > 0) { + // insertSql = "UPDATE coc_web.tbl_ptax_mob SET OTP = ?, CDATE = SYSDATE WHERE MOB = ?"; + // oraclePropertyTaxJdbcTemplate.update(insertSql, otp, mobile); + // } else { + // insertSql = "INSERT INTO coc_web.tbl_ptax_mob (OTP, MOB, CDATE) VALUES (?, ?, SYSDATE)"; + // oraclePropertyTaxJdbcTemplate.update(insertSql, otp, mobile); + // } + + // String smsMessage = "Your OTP is " + otp + ".OTP is valid for the next 5 minutes.%0aBy%0aGreater Chennai Corporation."; + // smsMessage = smsMessage.replace(" ", "%20"); + + // String urlString = "http://10.1.0.23:8060/api/sendSMS_test?MobileNo=" + mobile + "&generatedToken=" + otp; + + // try { + // String logSql = "INSERT INTO coc_web.tbl_ptax_sms (SMS_ID, MESSAGE, MOBILE, SENT_DATE) VALUES (?, ?, ?, SYSDATE)"; + // oraclePropertyTaxJdbcTemplate.update(logSql, Integer.parseInt(smsId), smsMessage, mobile); + // } catch (Exception e) { + // System.out.println("SMS logging failed: " + e.getMessage()); + // } + + // RestTemplate restTemplate = new RestTemplate(); + // String smsResponse = restTemplate.getForObject(urlString, String.class); + + // result.put("mobile", mobile); + // result.put("otp", otp); + // result.put("sms_id", smsId); + // result.put("message", "OTP sent successfully"); + // result.put("sms_response", smsResponse); + // result.put("Status", "Success"); + // result.put("Status Code", 200); + // response.put("Response", result); + // } catch (Exception e) { + // e.printStackTrace(); + // result.put("Status", "Error"); + // result.put("Status Code", 500); + // result.put("Message", "Error in sending OTP: " + e.getMessage()); + // response.put("Response", result); + // } + // return response; + // } + + // @Transactional("oraclePropertyTaxTransactionManager") + // public Map verifyOTP(String mobile, String otp) { + // Map response = new HashMap<>(); + // Map result = new HashMap<>(); + // try { + // String verifySql = "SELECT COUNT(*) FROM coc_web.tbl_ptax_mob WHERE MOB = ? AND OTP = ?"; + // int count = oraclePropertyTaxJdbcTemplate.queryForObject(verifySql, Integer.class, mobile, otp); + + // if (count > 0) { + // result.put("mobile", mobile); + // result.put("otp", otp); + // result.put("message", "OTP Verified"); + // result.put("verified", true); + // result.put("Status", "Success"); + // result.put("Status Code", 200); + // response.put("Response", result); + // } else { + // result.put("mobile", mobile); + // result.put("otp", otp); + // result.put("message", "OTP Not Verified"); + // result.put("verified", false); + // result.put("Status", "Error"); + // result.put("Status Code", 400); + // response.put("Response", result); + // } + // } catch (Exception e) { + // e.printStackTrace(); + // result.put("Status", "Error"); + // result.put("Status Code", 500); + // result.put("Message", "Error in verifying OTP: " + e.getMessage()); + // response.put("Response", result); + // } + // return response; + // } + + // @Transactional("oraclePropertyTaxTransactionManager") + + // public Map submitData(String mobile, String zone, String division, String billNo, String subBill, String email, String famCardNo) { + // Map response = new HashMap<>(); + // Map result = new HashMap<>(); + + // try { + // // Construct property ID + // String propertyId = zone + "-" + division + "-" + billNo; + // if (subBill != null && !subBill.trim().isEmpty()) { + // propertyId += "-" + subBill; + // } + + // // First, get ERP details to fetch current mobile and email + // String erpSql = "select upicno, ownersname, address, c.mobileno, emailaddress, fam_card_no " + + // "from mv1@erp a, egpt_basic_property@erp b, egpt_address@erp c " + + // "where a.upicno = b.propertyid and a.upicno = ? and b.ADDRESSID = c.ID_ADDRESS"; + + // List> erpData = oracleJdbcTemplate.queryForList(erpSql, propertyId); + + // if (!erpData.isEmpty()) { + // Map erpDetails = erpData.get(0); + // String erpMobile = (String) erpDetails.get("MOBILENO"); + // String erpEmail = (String) erpDetails.get("EMAILADDRESS"); + // String erpFamCardNo = (String) erpDetails.get("FAM_CARD_NO"); + + // // Get address ID from property using Property Tax database + // String addressIdSql = "SELECT addressid FROM egpt_basic_property@erp WHERE PROPERTYID = ?"; + // String addressId = oraclePropertyTaxJdbcTemplate.queryForObject(addressIdSql, String.class, propertyId); + + // if (addressId != null) { + // // Always update with the provided mobile and email values + // // Use provided values if they are not null/empty, otherwise use ERP values as fallback + // String finalMobile = (mobile != null && !mobile.trim().isEmpty()) ? mobile : erpMobile; + // String finalEmail = (email != null && !email.trim().isEmpty()) ? email : erpEmail; + // String finalFamCardNo = (famCardNo != null && !famCardNo.trim().isEmpty()) ? famCardNo : erpFamCardNo; + + // System.out.println("Updating address with:"); + // System.out.println("Address ID: " + addressId); + // System.out.println("Final Mobile: " + finalMobile); + // System.out.println("Final Email: " + finalEmail); + // System.out.println("Provided Mobile: " + mobile); + // System.out.println("Provided Email: " + email); + // System.out.println("ERP Mobile: " + erpMobile); + // System.out.println("ERP Email: " + erpEmail); + + // String updateAddressSql = "UPDATE egpt_address@erp SET MOBILENO = ?, EMAILADDRESS = ? WHERE ID_ADDRESS = ?"; + // int updateCount = oraclePropertyTaxJdbcTemplate.update(updateAddressSql, finalMobile, finalEmail, addressId); + // System.out.println("Update count: " + updateCount); + + // // Insert into history table + // // String historySql = "INSERT INTO coc_web.tbl_ptax_mob_history (ZONE, DIVISION, BILL_NO, SUB_BILL, MOB, EMAIL, CDATE) VALUES (?, ?, ?, ?, ?, ?, SYSDATE)"; + // // oraclePropertyTaxJdbcTemplate.update(historySql, zone, division, billNo, subBill, finalMobile, finalEmail); + + // // Log the submission + // // String logSql = "INSERT INTO coc_web.tbl_ptax_submission_log (MOB, ZONE, DIVISION, BILL_NO, SUB_BILL, EMAIL, CDATE) VALUES (?, ?, ?, ?, ?, ?, SYSDATE)"; + // // oraclePropertyTaxJdbcTemplate.update(logSql, finalMobile, zone, division, billNo, subBill, finalEmail); + + // // Clear OTP after successful submission + // String clearOtpSql = "UPDATE coc_web.tbl_ptax_mob SET OTP = NULL WHERE MOB = ?"; + // oraclePropertyTaxJdbcTemplate.update(clearOtpSql, finalMobile); + + // result.put("mobile", finalMobile); + // result.put("zone", zone); + // result.put("division", division); + // result.put("billNo", billNo); + // result.put("subBill", subBill); + // result.put("email", finalEmail); + // result.put("famCardNo", finalFamCardNo); + // result.put("message", "Data submitted successfully"); + // result.put("Status", "Success"); + // result.put("Status Code", 200); + // response.put("Response", result); + // } else { + // result.put("Status", "Error"); + // result.put("Status Code", 404); + // result.put("Message", "Property not found for ID: " + propertyId); + // response.put("Response", result); + // } + // } else { + // result.put("Status", "Error"); + // result.put("Status Code", 404); + // result.put("Message", "ERP details not found for ID: " + propertyId); + // response.put("Response", result); + // } + // } catch (Exception e) { + // e.printStackTrace(); + // result.put("Status", "Error"); + // result.put("Status Code", 500); + // result.put("Message", "Error in submitting data: " + e.getMessage()); + // response.put("Response", result); + // } + // return response; + // } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/servicesPdf/controller/ServicePdfController.java b/src/main/java/com/gcc/restapiservices/servicesPdf/controller/ServicePdfController.java new file mode 100644 index 0000000..c34ef87 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/servicesPdf/controller/ServicePdfController.java @@ -0,0 +1,126 @@ +package com.gcc.restapiservices.servicesPdf.controller; + +import com.gcc.restapiservices.servicesPdf.service.ServicePdfService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/gccrestservices/api/servicespdf") +public class ServicePdfController { + + @Autowired + private ServicePdfService servicePdfService; + + @GetMapping("/get-services") + public ResponseEntity>> listServices() { + List> services = servicePdfService.findAllServices(); + if (services.isEmpty()) { + return ResponseEntity.noContent().build(); + } + return ResponseEntity.ok(services); + } + + @GetMapping("/get-types") + public ResponseEntity>> getTypesByService( + @RequestParam("serviceId") int serviceId + ) { + List> types = servicePdfService.findTypesByService(serviceId); + if (types.isEmpty()) { + return ResponseEntity.noContent().build(); + } + return ResponseEntity.ok(types); + } + + @GetMapping("/download") + public ResponseEntity downloadPdf( + @RequestParam(value = "serviceId") String serviceIdStr, + @RequestParam(value = "typeId") String typeIdStr + ) { + if (serviceIdStr == null || serviceIdStr.isBlank()) { + return ResponseEntity + .badRequest() + .body(Map.of( + "status", "error", + "message", "Missing required parameter: serviceId" + )); + } + if (typeIdStr == null || typeIdStr.isBlank()) { + return ResponseEntity + .badRequest() + .body(Map.of( + "status", "error", + "message", "Missing required parameter: typeId" + )); + } + + if (!serviceIdStr.matches("\\d+")) { + return ResponseEntity + .badRequest() + .body(Map.of( + "status", "error", + "message", "Invalid parameter: 'serviceId' must be an integer" + )); + } + if (!typeIdStr.matches("\\d+")) { + return ResponseEntity + .badRequest() + .body(Map.of( + "status", "error", + "message", "Invalid parameter: 'typeId' must be an integer" + )); + } + + int serviceId = Integer.parseInt(serviceIdStr); + int typeId = Integer.parseInt(typeIdStr); + + try { + String pdfFullPath = servicePdfService.getPdfPathByServiceAndType(serviceId, typeId); + if (pdfFullPath == null) { + return ResponseEntity.status(404).body(Map.of( + "status", "error", + "message", "No PDF found for serviceId=" + serviceId + ", typeId=" + typeId + )); + } + + Resource resource = new UrlResource(pdfFullPath); + if (!resource.exists()) { + return ResponseEntity.status(404).body(Map.of( + "status", "error", + "message", "PDF file not found on server for serviceId=" + serviceId + + ", typeId=" + typeId + )); + } + + String fileName = pdfFullPath.substring(pdfFullPath.lastIndexOf("/") + 1); + return ResponseEntity.ok(Map.of( + "status", "success", + "serviceId", serviceId, + "typeId", typeId, + "fileName", fileName, + "url", pdfFullPath + )); + + } catch (MalformedURLException e) { + e.printStackTrace(); + return ResponseEntity.status(500).body(Map.of( + "status", "error", + "message", "Invalid URL format for PDF file." + )); + } + } + +} diff --git a/src/main/java/com/gcc/restapiservices/servicesPdf/service/ServicePdfService.java b/src/main/java/com/gcc/restapiservices/servicesPdf/service/ServicePdfService.java new file mode 100644 index 0000000..7e841c1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/servicesPdf/service/ServicePdfService.java @@ -0,0 +1,47 @@ +package com.gcc.restapiservices.servicesPdf.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public class ServicePdfService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public ServicePdfService(@Qualifier("servicesPdfJdbcTemplate") JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public String getPdfPathByServiceAndType(int serviceId, int typeId) { + String sql = "SELECT pdf_file_name FROM service_pdf_mapping WHERE service_id = ?" + + " AND type_id = ? AND is_active = 1 AND is_delete = 0"; + try { + return jdbcTemplate.queryForObject(sql, new Object[]{serviceId, typeId}, String.class); + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error fetching PDF path: " + e.getMessage()); + return null; + } + } + + public List> findAllServices() { + String sql = "SELECT id, service_name FROM services_master"; + return jdbcTemplate.queryForList(sql); + } + + public List> findTypesByService(int serviceId) { + String sql = + "SELECT id AS type_id, type_name, service_id " + + "FROM type_master " + + "WHERE service_id = ?"; + return jdbcTemplate.queryForList(sql, serviceId); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConfig.java b/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConfig.java new file mode 100644 index 0000000..94adc3f --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConfig.java @@ -0,0 +1,59 @@ +//package com.gcc.restapiservices.swimmingpool.constants; +// +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.boot.context.properties.ConfigurationProperties; +//import org.springframework.stereotype.Component; +// +//@Component +//@ConfigurationProperties(prefix = "app") +//public class AppConfig { +// +// private String title; +// private String baseUrl; +// private String getOtpUrl; +// private String erpUrl; +// +// @Value("rzp_test_tDkHFEqWXmuEi8") +// private String keyId; +// +// public String getTitle() { +// return title; +// } +// +// public void setTitle(String title) { +// this.title = title; +// } +// +// public String getBaseUrl() { +// return baseUrl; +// } +// +// public void setBaseUrl(String baseUrl) { +// this.baseUrl = baseUrl; +// } +// +// public String getGetOtpUrl() { +// return getOtpUrl; +// } +// +// public void setGetOtpUrl(String getOtpUrl) { +// this.getOtpUrl = getOtpUrl; +// } +// +// public String getErpUrl() { +// return erpUrl; +// } +// +// public void setErpUrl(String erpUrl) { +// this.erpUrl = erpUrl; +// } +// +// public String getKeyId() { +// return keyId; +// } +// +// public void setKeyId(String keyId) { +// this.keyId = keyId; +// } +//} +// diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConstants.java b/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConstants.java new file mode 100644 index 0000000..837a7ac --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/constants/AppConstants.java @@ -0,0 +1,14 @@ +package com.gcc.restapiservices.swimmingpool.constants; + +import org.springframework.stereotype.Component; + +@Component +public final class AppConstants { + // public static String key_id="rzp_live_ySI5Ns54Y7qOcJ"; + // public static String key_secret="Nwf1TjhUtaskof8vePkRR8Sb"; + + + //uncomment for testing payment + public static String key_id="rzp_test_tDkHFEqWXmuEi8"; + public static String key_secret="cBQUjMcKZ4J6vmOKSyNZ92py"; +} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/controller/PoolApiController.java b/src/main/java/com/gcc/restapiservices/swimmingpool/controller/PoolApiController.java new file mode 100644 index 0000000..9a431a1 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/controller/PoolApiController.java @@ -0,0 +1,380 @@ +//package com.gcc.restapiservices.swimmingpool.controller; +// +//import com.gcc.restapiservices.configuration.AppConfig; +//import com.gcc.restapiservices.swimmingpool.constants.AppConstants; +//import com.gcc.restapiservices.swimmingpool.service.PoolService; +//import com.razorpay.Order; +//import com.razorpay.RazorpayClient; +//import com.razorpay.RazorpayException; +//import jakarta.servlet.http.HttpServletRequest; +//import org.json.JSONObject; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.dao.DataAccessException; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import java.time.LocalDate; +//import java.time.format.DateTimeFormatter; +//import java.time.format.DateTimeParseException; +//import java.util.List; +//import java.util.Map; +// +// +//@RequestMapping("/gccrestservices/api/swimmingpool") +//@RestController +//public class PoolApiController { +// +// @Autowired +// private PoolService poolService; +// @Autowired +// private AppConfig appConfig; +// +// @Autowired +// public AppConstants appConstants; +// +// @GetMapping("/slots") +// public ResponseEntity getSlotsWithGender( +// @RequestParam String gender, +// @RequestParam("date") String date +// ) { +// // 1) validate gender up‐front +// if (!"1".equals(gender) && !"2".equals(gender)) { +// // returns 400 + { "message": "..." } +// return ResponseEntity +// .badRequest() +// .body(Map.of( +// "message", +// "Invalid gender: must be '2' (women) or '1' (men)" +// )); +// } +// +// try { +// // 2) validate date +// LocalDate.parse(date); +// +// // 3) run your normal query +// List> slots = poolService.getSlotsWithGender(gender, date); +// return ResponseEntity.ok(slots); +// +// } catch (DateTimeParseException dtpe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); +// } catch (DataAccessException dae) { +// return ResponseEntity +// .status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body(Map.of("message", "Something went wrong on our end")); +// } +// } +// +// @GetMapping("/getBookedCountbySlot") +// public ResponseEntity getBookedCountbySlot( +// @RequestParam("slotid") String slotid, +// @RequestParam("date") String date +// ) { +// try { +// // 1) Numeric check +// Integer.parseInt(slotid); +// +// // 2) Trim & parse with explicit ISO formatter +// String trimmed = date.trim(); +// LocalDate.parse(trimmed, DateTimeFormatter.ISO_LOCAL_DATE); +// +// // 3) Safe to call the service +// List> bookingDetails = +// poolService.getBookedCountbySlot(slotid, trimmed); +// +// return ResponseEntity.ok(bookingDetails); +// +// } catch (NumberFormatException nfe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid slotid: must be a number")); +// +// } catch (DateTimeParseException dtpe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); +// +// } catch (DataAccessException dae) { +// return ResponseEntity +// .status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body(Map.of("message", "Something went wrong on our end")); +// } +// } +// +// +// @GetMapping("/calculatePayment") +// public ResponseEntity calculatePayment( +// @RequestParam("adultsCount") String adultsCountStr, +// @RequestParam("kidsCount") String kidsCountStr, +// @RequestParam(value = "bookingMode", defaultValue = "ONLINE") +// String bookingMode +// ) { +// int adultsCount, kidsCount; +// // 1) parse and validate counts +// try { +// adultsCount = Integer.parseInt(adultsCountStr); +// kidsCount = Integer.parseInt(kidsCountStr); +// } catch (NumberFormatException nfe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "adultsCount and kidsCount must be integers")); +// } +// +// // 2) validate bookingMode +// if (!"ONLINE".equalsIgnoreCase(bookingMode)) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid bookingMode: must be 'ONLINE'")); +// } +// +// // 3) delegate to service +// Map result = poolService.calculatePayment(adultsCount, kidsCount, bookingMode); +// +// // 4) if service signals an error, propagate as 400 +// if (result.containsKey("error")) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", result.get("error"))); +// } +// +// // 5) successful response +// return ResponseEntity.ok(result); +// } +// +// +// @PostMapping("/saveTempBooking") +// public ResponseEntity saveTempBooking( +// // HttpServletRequest request, +// @RequestParam String name, +// @RequestParam String mobileNo, +// @RequestParam String noofadults, +// @RequestParam String noofkids, +// @RequestParam String slotfromdate, +// @RequestParam String slottodate, +// @RequestParam String totalAmount, +// @RequestParam String bookingtype, +// @RequestParam String slotorder, +// @RequestParam String poolId, +// @RequestParam String bookingMode +// ) { +// // 1) Required-field checks +// if (name.isBlank()) { +// return ResponseEntity.badRequest().body(Map.of("message", "Missing required parameter: name")); +// } +// if (mobileNo.isBlank()) { +// return ResponseEntity.badRequest().body(Map.of("message", "Missing required parameter: mobileNo")); +// } +// +// // 2) mobileNo must be digits and at least 10 characters +// if (!mobileNo.matches("\\d{10,}")) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid mobileNo: must be at least 10 digits")); +// } +// +// // 3) Numeric-only checks +// if (!noofadults.matches("\\d+")) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid noofadults: must be a whole number")); +// } +// if (!noofkids.matches("\\d+")) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid noofkids: must be a whole number")); +// } +// if (!slotorder.matches("\\d+")) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid slotorder: must be a whole number")); +// } +// if (!poolId.matches("\\d+")) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid poolId: must be a whole number")); +// } +// if (!totalAmount.matches("\\d+(\\.\\d+)?")) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid totalAmount: must be a number")); +// } +// +// // 4) Date format +// try { +// LocalDate.parse(slotfromdate); +// LocalDate.parse(slottodate); +// } catch (DateTimeParseException e) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); +// } +// +// // 5) Booking‐mode +// if (!List.of("ONLINE", "OFFLINE").contains(bookingMode.toUpperCase())) { +// return ResponseEntity.badRequest().body(Map.of("message", "Invalid bookingMode: must be ONLINE or OFFLINE")); +// } +// +// // 6) Delegate to service +// try { +// String tempId = poolService.saveBooking( +// name, mobileNo, noofadults, noofkids, +// slotfromdate, slottodate, totalAmount, +// bookingtype, slotorder, poolId, bookingMode +// ); +// return ResponseEntity.ok(Map.of( +// "tempId", tempId, +// "message", "Your booking has been saved! Use this tempId to create your payment order." +// )); +// } +// catch (IllegalArgumentException iae) { +// // thrown by your service (e.g. mobile-too-long) +// return ResponseEntity.badRequest().body(Map.of("message", iae.getMessage())); +// } +// catch (DataAccessException dae) { +// return ResponseEntity +// .status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body(Map.of("message", "Database error, please try again later")); +// } +// } +// +// +//// @PostMapping("/saveTempBooking") +//// public String saveTempBooking(HttpServletRequest request, +//// @RequestParam String name, +//// @RequestParam String mobileNo, +//// @RequestParam String noofadults, +//// @RequestParam String noofkids, +//// @RequestParam String slotfromdate, +//// @RequestParam String slottodate, +//// @RequestParam String totalAmount, +//// @RequestParam String bookingtype, +//// @RequestParam String slotorder, +//// @RequestParam String poolId, +//// @RequestParam String bookingMode) { +//// System.out.println("bookingMode: " + bookingMode); +//// return poolService.saveBooking(name,mobileNo,noofadults,noofkids,slotfromdate,slottodate,totalAmount, +//// bookingtype,slotorder,poolId,bookingMode).toString(); +//// } +// +// @PostMapping("/create_order") +// public ResponseEntity createOrder(@RequestParam("tempid") String tempid) { +// // 1) Validate tempid is numeric +// int id; +// try { +// id = Integer.parseInt(tempid); +// } catch (NumberFormatException nfe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid tempid: must be a number")); +// } +// +// // 2) Fetch the temp booking; if none, 404 +// List> tempBookingDetails = poolService.getTempBookingData(tempid); +// if (tempBookingDetails.isEmpty()) { +// return ResponseEntity +// .status(HttpStatus.NOT_FOUND) +// .body(Map.of("message", "No booking found for tempid: " + tempid)); +// } +// +// // 3) Build and call Razorpay +// Map tempInfo = tempBookingDetails.get(0); +// String amountStr = tempInfo.get("total_amount").toString(); +// double amount; +// try { +// amount = Double.parseDouble(amountStr); +// } catch (NumberFormatException nfe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Stored total_amount is invalid: " + amountStr)); +// } +// +// try { +// var client = new RazorpayClient(appConstants.key_id, appConstants.key_secret); +// JSONObject opts = new JSONObject() +// .put("amount", (int)(amount * 100)) +// .put("currency", "INR"); +// Order order = client.orders.create(opts); +// return ResponseEntity.ok(order.toString()); +// +// } catch (RazorpayException re) { +// return ResponseEntity +// .status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body(Map.of("message", "Failed to create Razorpay order", "error", re.getMessage())); +// } +// } +// +// @PostMapping("/Confirm") +// public ResponseEntity confirmPayment( +// @RequestParam("id") String tempid, +// @RequestParam(name = "payment_id", required = false) String payId, +// @RequestParam("order_id") String orderId, +// @RequestParam("status") String status, +// @RequestParam(name = "source", defaultValue = "0") int source +// ) { +// +// if (source < 0 || source > 2) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message","Invalid source: must be 0 (web), 1 (counter) or 2 (whatsapp)")); +// } +// +// // 1) Required-param checks +// if (orderId.isBlank()) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Missing required parameter: order_id")); +// } +// if (status.isBlank()) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Missing required parameter: status")); +// } +// +// // 2) Numeric check on tempid +// int id; +// try { +// id = Integer.parseInt(tempid); +// } catch (NumberFormatException nfe) { +// return ResponseEntity +// .badRequest() +// .body(Map.of("message", "Invalid id: must be a number")); +// } +// +// // 3) Fetch the temp booking; 404 if not found +// List> tempBookingDetails = poolService.getTempBookingData(tempid); +// if (tempBookingDetails.isEmpty()) { +// return ResponseEntity +// .status(HttpStatus.NOT_FOUND) +// .body(Map.of("message", "No booking found for id: " + tempid)); +// } +// +// // 4) Delegate to service +// try { +// poolService.savePaymentInfo( +// tempid, +// /*booking_type*/ tempBookingDetails.get(0).get("booking_type").toString(), +// /*cdate*/ tempBookingDetails.get(0).get("cdate").toString(), +// /*mobile_no*/ tempBookingDetails.get(0).get("mobile_no").toString(), +// /*name*/ tempBookingDetails.get(0).get("name").toString(), +// /*no_of_adults*/ tempBookingDetails.get(0).get("no_of_adults").toString(), +// /*no_of_kids*/ tempBookingDetails.get(0).get("no_of_kids").toString(), +// /*pool_id*/ tempBookingDetails.get(0).get("pool_id").toString(), +// /*slot_from_date*/tempBookingDetails.get(0).get("slot_from_date").toString(), +// /*slot_order*/ tempBookingDetails.get(0).get("slot_order").toString(), +// /*slot_to_date*/ tempBookingDetails.get(0).get("slot_to_date").toString(), +// /*totalAmount*/ tempBookingDetails.get(0).get("total_amount").toString(), +// payId, +// orderId, +// status, +// /*paymentdate*/ tempBookingDetails.get(0).get("cdate").toString(), +// tempid, +// /*booking_mode*/ tempBookingDetails.get(0).getOrDefault("booking_mode", "ONLINE").toString(), +// source +// ); +// return ResponseEntity.ok(Map.of( +// "message", +// "Your payment was successful and your booking is now confirmed! " + +// "You’ll receive the full details via WhatsApp and SMS shortly. " + +// "Please have your QR code ready at entry." +// )); +// } catch (Exception e) { +// // you could catch more specific exceptions if you want +// return ResponseEntity +// .status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body(Map.of("message", "Failed to confirm payment", "error", e.getMessage())); +// } +// } +// +// +//} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/controller/SwimmingPoolApiController.java b/src/main/java/com/gcc/restapiservices/swimmingpool/controller/SwimmingPoolApiController.java new file mode 100644 index 0000000..9d8d6ac --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/controller/SwimmingPoolApiController.java @@ -0,0 +1,485 @@ +package com.gcc.restapiservices.swimmingpool.controller; + +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.swimmingpool.constants.AppConstants; +import com.gcc.restapiservices.swimmingpool.service.SwimmingPoolService; +import com.gcc.restapiservices.swimmingpool.util.ApiResponse; +import com.razorpay.Order; +import com.razorpay.RazorpayClient; +import com.razorpay.RazorpayException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.time.format.ResolverStyle; +import java.util.*; +import java.util.stream.Collectors; + + +@RequestMapping("/gccrestservices/api/swimmingpool") +@RestController +public class SwimmingPoolApiController { + + @Autowired + private SwimmingPoolService swimmingPoolService; + + @Autowired + private AppConfig appConfig; + + @Autowired + public AppConstants appConstants; + + @GetMapping("/slots") + public ResponseEntity getSlotsWithGender( + @RequestParam String gender, + @RequestParam("date") String date) { + // 1) validate gender up‐front + if (!"1".equals(gender) && !"2".equals(gender)) { + // returns 400 + { "message": "..." } + return ResponseEntity + .badRequest() + .body(Map.of( + "message", + "Invalid gender: must be '2' (women) or '1' (men)" + )); + } + + try { + // validate input date (still in yyyy-MM-dd format) + LocalDate parsedDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE); + + // query DB with yyyy-MM-dd + List> slots = swimmingPoolService.getSlotsWithGender(gender, date); + + // format response as dd-MM-yyyy + String formattedDate = parsedDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); + for (Map slot : slots) { + slot.put("slot_from_date", formattedDate); + } + + return ResponseEntity.ok(slots); + + } catch (DateTimeParseException dtpe) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); + } catch (DataAccessException dae) { + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Something went wrong")); + } + } + + @GetMapping("/getBookedCountbySlot") + public ResponseEntity getBookedCountbySlot( + @RequestParam("slotid") String slotid, + @RequestParam("date") String date) { + try { + Integer.parseInt(slotid); + + String trimmed = date.trim(); + LocalDate.parse(trimmed, DateTimeFormatter.ISO_LOCAL_DATE); + + List> bookingDetails = + swimmingPoolService.getBookedCountbySlot(slotid, trimmed); + + return ResponseEntity.ok(bookingDetails); + + } catch (NumberFormatException nfe) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "Invalid slotid: must be a number")); + + } catch (DateTimeParseException dtpe) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); + + } catch (DataAccessException dae) { + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Something went wrong")); + } + } + + @GetMapping("/getCountbydate") + public ResponseEntity getBookedCountbySlot( + @RequestParam("date") LocalDate date, + @RequestParam(value = "slotid", required = false) String slotid, + @RequestParam(value = "gender", required = false) String gender + ) { + // 0) Validate date + LocalDate today; + LocalDate parsedDate; + try { + today = LocalDate.now(); + parsedDate = LocalDate.parse(date.toString(), DateTimeFormatter.ISO_LOCAL_DATE); + } catch (DateTimeParseException e) { + return ResponseEntity.badRequest() + .body(Map.of("message","Invalid date format, expected YYYY-MM-DD")); + } + + // 1) Validate optional params + if (slotid != null && !slotid.isBlank() && !slotid.matches("\\d+")) { + return ResponseEntity.badRequest() + .body(Map.of("message","Invalid slotid: must be a number")); + } + if (gender != null && !gender.isBlank()) { + gender = gender.trim().toLowerCase(); + if (!gender.equals("men") && !gender.equals("women")) { + return ResponseEntity.badRequest() + .body(Map.of("message","Invalid gender: must be 'men' or 'women'")); + } + } + + // Women only at slot 4; if they asked for another slot + women: + if ("women".equals(gender) + && slotid != null && !slotid.isBlank() + && !"4".equals(slotid)) { + String msg = String.format( + "Women slots are only available for slotid 4, not slotid %s", + slotid + ); + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(Map.of("message", msg)); + } + + + // 2) Fetch all availabilities + List> slots = + swimmingPoolService.getAvailabilityByDate(parsedDate); + + // 3) Filter by slotid if present + if (slotid != null && !slotid.isBlank()) { + slots = slots.stream() + .filter(m -> slotid.equals(m.get("slot_order").toString())) + .collect(Collectors.toList()); + } + + // 4) If today, drop past slots + if (parsedDate.equals(today)) { + DateTimeFormatter fmt = new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .appendPattern("h:mm a") + .toFormatter(Locale.ENGLISH) + .withResolverStyle(ResolverStyle.SMART); + LocalTime now = LocalTime.now(); + + slots = slots.stream() + .filter(m -> { + String start = ((String)m.get("slot_timing")) + .split("\\s*-\\s*")[0].trim(); + try { + return LocalTime.parse(start, fmt).isAfter(now); + } catch (DateTimeParseException ex) { + return true; + } + }) + .collect(Collectors.toList()); + } + + // 5) Filter by gender if present + if (gender != null && !gender.isBlank()) { + String finalGender = gender; + slots = slots.stream() + .filter(m -> finalGender.equalsIgnoreCase((String)m.get("gender"))) + .collect(Collectors.toList()); + } + + // 6) If still empty, generic 404 + if (slots.isEmpty()) { + String msg; + if (slotid != null && !slotid.isBlank()) { + msg = String.format( + "No slots available for slot %s%s on %s", + slotid, + (gender!=null? " and gender="+gender : ""), + date + ); + } else { + msg = String.format( + "No slots available%s on %s", + (gender!=null? " for gender="+gender : ""), + date + ); + } + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(Map.of("message", msg)); + } + + // 7) Otherwise OK + return ResponseEntity.ok(slots); + } + + + @GetMapping("/calculatePayment") + public ResponseEntity calculatePayment( + @RequestParam("adultsCount") String adultsCountStr, + @RequestParam("kidsCount") String kidsCountStr, + @RequestParam(value = "bookingMode", defaultValue = "ONLINE") + String bookingMode) { + int adultsCount, kidsCount; + // 1) parse and validate counts + try { + adultsCount = Integer.parseInt(adultsCountStr); + kidsCount = Integer.parseInt(kidsCountStr); + } catch (NumberFormatException nfe) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "adultsCount and kidsCount must be integers")); + } + + // 2) validate bookingMode + if (!"ONLINE".equalsIgnoreCase(bookingMode)) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "Invalid bookingMode: must be 'ONLINE'")); + } + + // 3) delegate to service + Map result = swimmingPoolService.calculatePayment(adultsCount, kidsCount, bookingMode); + + // 4) if service signals an error, propagate as 400 + if (result.containsKey("error")) { + return ResponseEntity + .badRequest() + .body(Map.of("message", result.get("error"))); + } + + // 5) successful response + return ResponseEntity.ok(result); + } + + + @PostMapping("/saveTempBooking") + public ResponseEntity saveTempBooking( + HttpServletRequest request, + @RequestParam String name, + @RequestParam String mobileNo, + @RequestParam String noofadults, + @RequestParam String noofkids, + @RequestParam String slotfromdate, + @RequestParam String slottodate, + @RequestParam String totalAmount, + @RequestParam String bookingtype, + @RequestParam String slotorder, + @RequestParam String poolId, + @RequestParam String bookingMode) { + // 1) Required-field checks + if (name.isBlank()) { + return ResponseEntity.badRequest().body(Map.of("message", "Missing required parameter: name")); + } + if (mobileNo.isBlank()) { + return ResponseEntity.badRequest().body(Map.of("message", "Missing required parameter: mobileNo")); + } + + // 2) mobileNo must be digits and at least 10 characters + if (!mobileNo.matches("\\d{10,}")) { + return ResponseEntity + .badRequest() + .body(Map.of("message", "Invalid mobileNo: must be at least 10 digits")); + } + + // 3) Numeric-only checks + if (!noofadults.matches("\\d+")) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid noofadults: must be a whole number")); + } + if (!noofkids.matches("\\d+")) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid noofkids: must be a whole number")); + } + if (!slotorder.matches("\\d+")) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid slotorder: must be a whole number")); + } + if (!poolId.matches("\\d+")) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid poolId: must be a whole number")); + } + if (!totalAmount.matches("\\d+(\\.\\d+)?")) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid totalAmount: must be a number")); + } + + // 4) Date format + try { + LocalDate.parse(slotfromdate); + LocalDate.parse(slottodate); + } catch (DateTimeParseException e) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid date format, expected YYYY-MM-DD")); + } + + // 5) Booking‐mode + if (!List.of("ONLINE", "OFFLINE").contains(bookingMode.toUpperCase())) { + return ResponseEntity.badRequest().body(Map.of("message", "Invalid bookingMode: must be ONLINE or OFFLINE")); + } + + // 6) Delegate to service + try { + String tempId = swimmingPoolService.saveBooking( + name, mobileNo, noofadults, noofkids, + slotfromdate, slottodate, totalAmount, + bookingtype, slotorder, poolId, bookingMode + ); + return ResponseEntity.ok(Map.of( + "tempId", tempId, + "message", "Your booking has been saved! Use this tempId to create your payment order." + )); + } catch (IllegalArgumentException iae) { + // thrown by your service (e.g. mobile-too-long) + return ResponseEntity.badRequest().body(Map.of("message", iae.getMessage())); + } catch (DataAccessException dae) { + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Database error, please try again later")); + } + } + + + @PostMapping("/create_order") + public ResponseEntity createOrder(@RequestParam("tempid") String tempid) { + try { + Map tempBookingDetails = swimmingPoolService.getTempBookingData(tempid); + + if (tempBookingDetails != null && !tempBookingDetails.isEmpty()) { + String tempbookid = tempBookingDetails.get("temp_id").toString(); + String amount = tempBookingDetails.get("total_amount").toString(); + double amountDouble = 0.0; + + try { + amountDouble = Double.parseDouble(amount); + } catch (NumberFormatException e) { + return new ResponseEntity<>(new ApiResponse("error", "Invalid amount format", null, HttpStatus.BAD_REQUEST.value()), HttpStatus.BAD_REQUEST); + } + + // Razorpay order creation + var client = new RazorpayClient(appConstants.key_id, appConstants.key_secret); + JSONObject options = new JSONObject(); + options.put("amount", amountDouble * 100); + options.put("currency", "INR"); + Order od = client.orders.create(options); + swimmingPoolService.saveorderLog(od.get("id").toString(), od.toString(), tempbookid); + + return ResponseEntity.ok(new ApiResponse("success", "Order created successfully", od.toJson().toMap(), HttpStatus.OK.value())); + } else { + return new ResponseEntity<>(new ApiResponse("error", "No data found for tempid: " + tempid, null, HttpStatus.NOT_FOUND.value()), HttpStatus.NOT_FOUND); + } + } catch (RazorpayException e) { + return new ResponseEntity<>(new ApiResponse("error", "Razorpay error: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } catch (Exception e) { + return new ResponseEntity<>(new ApiResponse("error", "Unexpected error: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @PostMapping("/Confirm") + public ResponseEntity confirmPayment( + @RequestParam("id") String tempid, + @RequestParam(name = "source", defaultValue = "0") int source, + @RequestParam String orderid, + @RequestBody Map paymentResponse) { + + try { + return swimmingPoolService.processPaymentConfirmation(tempid, source, orderid, paymentResponse); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment", "error", e.getMessage())); + } + } + + @GetMapping("/getbookings") + public ResponseEntity getBookingByMobileNo(@RequestParam(value = "mobileNo", required = false) String mobileNo) { + + if (mobileNo == null || mobileNo.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("status", "error"); + errorResponse.put("message", "Missing required parameter: mobileNo"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (!mobileNo.matches("\\d{10,}")) { + Map errorResponse = new HashMap<>(); + errorResponse.put("status", "error"); + errorResponse.put("message", "Invalid mobile number. It should be at least 10 digits."); + return ResponseEntity.badRequest().body(errorResponse); + } + + long mobile = Long.parseLong(mobileNo); + List> bookings = swimmingPoolService.getBookingByMobileNo(mobile); + + if (bookings.isEmpty()) { + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(Map.of( + "status", "error", + "message", "No bookings found for mobileNo: " + mobileNo + )); + } + return ResponseEntity.ok(bookings); + } + + + @GetMapping(value = "/sendOTP") + public ResponseEntity> sendOtp(HttpServletRequest request, @RequestParam String mobileNo) { + Map response = new HashMap<>(); + + if (mobileNo == null || mobileNo.isBlank()) { + response.put("status","error"); + response.put("message","Missing required parameter: mobileNo"); + return ResponseEntity.badRequest().body(response); + } + + if (!mobileNo.matches("\\d{10}")) { + response.put("status", "error"); + response.put("message", "Invalid mobile number. It should be 10 digits."); + return ResponseEntity.badRequest().body(response); + } + + List bookingDetailsList = swimmingPoolService.findByMobileNo(Long.parseLong(mobileNo)); + if (bookingDetailsList == null || bookingDetailsList.isEmpty()) { + response.put("status", "error"); + response.put("message", "This number is not registered."); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + + int otp = new Random().nextInt(90000) + 10000; + String generatedToken = "Welcome to GCC! Your OTP for GCC Swimming Pool booking is " + otp; + String key = "pfTEYN6H"; + String urlString = appConfig.getGetOtpUrl() + "from=GCCCRP&key=" + key + "&sender=GCCCRP&to=" + mobileNo + + "&body=" + generatedToken + "&entityid=1401572690000011081&templateid=1407172681010820867"; + + String bodyMessage; + try { + RestTemplate restTemplate = new RestTemplate(); + bodyMessage = restTemplate.getForObject(urlString, String.class); + } catch (Exception e) { + response.put("status", "error"); + response.put("message", "Failed to send OTP. Please try again."); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + + // Save OTP in session + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + session.setAttribute("mobileNo", mobileNo); + + // Prepare response + response.put("status", "success"); + response.put("message", "OTP sent successfully"); + response.put("otp", otp); + // response.put("smsApiResponse", bodyMessage); + + return ResponseEntity.ok(response); + } + + + +} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/service/PoolService.java b/src/main/java/com/gcc/restapiservices/swimmingpool/service/PoolService.java new file mode 100644 index 0000000..cbad203 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/service/PoolService.java @@ -0,0 +1,525 @@ +//package com.gcc.restapiservices.swimmingpool.service; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Qualifier; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.dao.DataAccessException; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//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.web.client.RestTemplate; +// +// +//import javax.sql.DataSource; +//import java.net.HttpURLConnection; +//import java.net.URL; +//import java.sql.Connection; +//import java.sql.Date; +//import java.sql.PreparedStatement; +//import java.sql.SQLException; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +//import java.util.function.Function; +// +//@Service +//@Configuration +//public class PoolService { +// private JdbcTemplate jdbcTemplate; +// @Autowired +// private RestTemplate restTemplate; +// +// @Autowired +// public void setDataSource(@Qualifier("mysqlSwimmingpoolDataSource") DataSource activityDataSource) { +// // Initialize JdbcTemplate with the correct DataSource +// this.jdbcTemplate = new JdbcTemplate(activityDataSource); +// } +// +// public List> getSlotsWithGender(String gender, String date) { +// String sql = " SELECT " + +// " st.slot_timing AS time, " + +// " CASE WHEN st.gender_avail = '1' THEN 'men' ELSE 'women' END AS gender, " + +// " st.id AS value, " + +// " ? AS slot_from_date " + +// " FROM slot_timing st " + +// " LEFT JOIN booking_details b " + +// " ON b.slot_order = st.slot_order " + +// " AND b.slot_from_date = ? " + +// " AND b.is_active = 1 " + +// " AND b.is_delete = 0 " + +// " WHERE st.gender_avail = ? " + +// " GROUP BY " + +// " st.slot_timing, st.gender_avail, st.id " + +// " ORDER BY st.id"; +// +// return jdbcTemplate.queryForList(sql, date, date, gender); +// } +// +// +// +// public List> getBookedCountbySlot(String slotid, String date) { +// String sqlQuery = " SELECT " +// + " b.slot_from_date, " +// + " st.slot_timing, " +// + " CASE " +// + " WHEN b.slot_order = '4' THEN 'women' " +// + " ELSE 'men' " +// + " END AS gender, " +// + " 200 AS total_capacity, " +// + " 200 - (COALESCE(SUM(b.no_of_kids), 0) + COALESCE(SUM(b.no_of_adults), 0)) AS available_slots, " +// + " (COALESCE(SUM(b.no_of_kids), 0) + COALESCE(SUM(b.no_of_adults), 0)) AS booked_slots " +// + " FROM " +// + " booking_details b " +// + " JOIN " +// + " slot_timing st ON b.slot_order = st.slot_order " +// + " WHERE " +// + " b.is_active = 1 " +// + " AND b.is_delete = 0 " +// + " AND b.slot_from_date = ? " +// + " AND b.slot_order = ? " +// + " GROUP BY " +// + " b.slot_from_date, " +// + " b.slot_order, " +// + " st.slot_timing "; +// +// System.out.println(sqlQuery); +// +// List> bookingDetails = jdbcTemplate.queryForList(sqlQuery, date, slotid); +// +// // If no data is returned, create a default response with 0 values +// if (bookingDetails.isEmpty()) { +// Map defaultData = new HashMap<>(); +// defaultData.put("slot_from_date", date); +// defaultData.put("slot_timing", "Not Available"); // Set a default value for slot_timing +// defaultData.put("slot_order", slotid); +// defaultData.put("total_capacity", 200); // Set total capacity to 200 +// defaultData.put("available_slots", 200); // If no bookings, all slots are available +// defaultData.put("booked_slots", 0); // No slots booked if no data +// bookingDetails.add(defaultData); +// } +// +// return bookingDetails; +// } +// +// +// public Map calculatePayment(int adultsCount, int kidsCount, String bookingMode) { +// int adultRate = 0; +// int kidRate = 0; +// +// // Rates based on booking mode +// if ("ONLINE".equalsIgnoreCase(bookingMode)) { +// adultRate = 45; +// kidRate = 25; +// } else { +// // Return an error response if booking mode is invalid +// Map errorResponse = new HashMap<>(); +// errorResponse.put("error", "Invalid booking mode"); +// return errorResponse; +// } +// +// // Calculate total amount +// int totalAdultsAmount = adultsCount * adultRate; +// int totalKidsAmount = kidsCount * kidRate; +// int totalAmount = totalAdultsAmount + totalKidsAmount; +// +// // Prepare the response map +// Map response = new HashMap<>(); +// response.put("adultsCount", adultsCount); +// response.put("kidsCount", kidsCount); +// response.put("totalAdultsAmount", totalAdultsAmount); +// response.put("totalKidsAmount", totalKidsAmount); +// response.put("totalAmount", totalAmount); +// +// return response; +// } +// +// public String saveBooking( +// String name, +// String mobileNo, +// String noofadults, +// String noofkids, +// String slotfromdate, +// String slottodate, +// String totalAmount, +// String bookingtype, +// String slotorder, +// String poolId, +// String bookingMode) { +// +// // helper to take everything before the first comma +// Function firstData = s -> { +// if (s == null) return null; +// int idx = s.indexOf(','); +// return idx < 0 ? s.trim() : s.substring(0, idx).trim(); +// }; +// +// // sanitize EVERY incoming param +// name = firstData.apply(name); +// mobileNo = firstData.apply(mobileNo); +// noofadults = firstData.apply(noofadults); +// noofkids = firstData.apply(noofkids); +// slotfromdate = firstData.apply(slotfromdate); +// slottodate = firstData.apply(slottodate); +// totalAmount = firstData.apply(totalAmount); +// bookingtype = firstData.apply(bookingtype); +// slotorder = firstData.apply(slotorder); +// poolId = firstData.apply(poolId); +// bookingMode = firstData.apply(bookingMode); +// +// if (mobileNo.length() > 20) { +// throw new IllegalArgumentException("Mobile number too long: " + mobileNo); +// } +// +// // parse the numeric/date fields +// int adultsCount = Integer.parseInt(noofadults); +// int kidsCount = Integer.parseInt(noofkids); +// int pool = Integer.parseInt(poolId); +// java.sql.Date fromDate = java.sql.Date.valueOf(slotfromdate); +// java.sql.Date toDate = java.sql.Date.valueOf(slottodate); +// +// String sql = " INSERT INTO temp_booking_details( booking_type, mobile_no, name, no_of_adults, no_of_kids, pool_id, slot_from_date, slot_order, slot_to_date, total_amount, booking_mode) VALUES (?,?,?,?,?,?,?,?,?,?,?) "; +// +// KeyHolder keyHolder = new GeneratedKeyHolder(); +// String finalBookingtype = bookingtype; +// String finalMobileNo = mobileNo; +// String finalName = name; +// String finalSlotorder = slotorder; +// String finalTotalAmount = totalAmount; +// String finalBookingMode = bookingMode; +// int rows = jdbcTemplate.update(con -> { +// PreparedStatement ps = con.prepareStatement(sql, new String[]{"temp_id"}); +// ps.setString(1, finalBookingtype); +// ps.setString(2, finalMobileNo); +// ps.setString(3, finalName); +// ps.setInt (4, adultsCount); +// ps.setInt (5, kidsCount); +// ps.setInt (6, pool); +// ps.setDate (7, fromDate); +// ps.setString(8, finalSlotorder); +// ps.setDate (9, toDate); +// ps.setString(10, finalTotalAmount); +// ps.setString(11, finalBookingMode); +// return ps; +// }, keyHolder); +// +// if (rows == 0) { +// throw new RuntimeException("Insert returned 0 rows affected"); +// } +// return keyHolder.getKey().toString(); +// } +// +// public List> getTempBookingData(String tempid) { +// String sqlQuery = "SELECT * FROM temp_booking_details WHERE temp_id='"+tempid+"'"; +// List> tempBookingDetails = jdbcTemplate.queryForList(sqlQuery); +// return tempBookingDetails; +// } +// +// public String savePaymentInfo( +// String tempId, +// String booking_type, +// String cdate, +// String mobile_no, +// String name, +// String no_of_adults, +// String no_of_kids, +// String pool_id, +// String slot_from_date, +// String slot_order, +// String slot_to_date, +// String totalAmount, +// String payment_id, +// String payment_orderid, +// String payment_status, +// String paymentdate, +// String uniqueid, +// String booking_mode, +// int source ) { +// +// String lastInsertId = "0"; +// +// String sqlQuery = "INSERT INTO `payment`(`amount`, `mobno`, `order_id`, `payment_id`, `payment_status`, `paymentdate`, `uniqueid`) " +// + "VALUES (?,?,?,?,?,?,?)"; +// +// KeyHolder keyHolder = new GeneratedKeyHolder(); +// +// try { +// int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { +// @Override +// public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { +// PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"temp_id"}); +// ps.setString(1, totalAmount); +// ps.setString(2, mobile_no); +// ps.setString(3, payment_orderid); +// ps.setString(4, payment_id); +// ps.setString(5, payment_status); +// ps.setString(6, paymentdate); +// ps.setString(7, uniqueid); +// return ps; +// } +// }, keyHolder); +// +// if (affectedRows > 0) { +// Number generatedId = keyHolder.getKey(); +// lastInsertId = generatedId.toString(); +// +// lastInsertId = saveBookingInfo(tempId, booking_type, cdate, mobile_no, +// name, +// no_of_adults, +// no_of_kids, +// pool_id, +// slot_from_date, +// slot_order, +// slot_to_date, +// totalAmount, +// payment_id, +// payment_orderid, +// payment_status, +// paymentdate, +// uniqueid, +// booking_mode, +// source); +// +// +// // Define the time slots in Java +// List> daySlots = new ArrayList<>(); +// +// daySlots.add(Map.of("time", "5:30 AM - 6:30 AM", "gender", "men", "value", 0)); +// daySlots.add(Map.of("time", "5:30 AM - 6:30 AM", "gender", "men", "value", 1)); +// daySlots.add(Map.of("time", "6:30 AM - 7:30 AM", "gender", "men", "value", 2)); +// daySlots.add(Map.of("time", "7:30 AM - 8:30 AM", "gender", "men", "value", 3)); +// daySlots.add(Map.of("time", "8:30 AM - 9:30 AM", "gender", "women", "value", 4)); +// daySlots.add(Map.of("time", "9:30 AM - 10:30 AM", "gender", "men", "value", 5)); +// daySlots.add(Map.of("time", "10:30 AM - 11:30 AM", "gender", "men", "value", 6)); +// daySlots.add(Map.of("time", "11:30 AM - 12:30 PM", "gender", "men", "value", 7)); +// daySlots.add(Map.of("time", "12:30 PM - 1:30 PM", "gender", "men", "value", 8)); +// daySlots.add(Map.of("time", "1:30 PM - 2:30 PM", "gender", "men", "value", 9)); +// daySlots.add(Map.of("time", "2:30 PM - 3:30 PM", "gender", "men", "value", 10)); +// daySlots.add(Map.of("time", "3:30 PM - 4:30 PM", "gender", "men", "value", 11)); +// daySlots.add(Map.of("time", "4:30 PM - 5:30 PM", "gender", "men", "value", 12)); +// daySlots.add(Map.of("time", "5:30 PM - 6:30 PM", "gender", "men", "value", 13)); +// daySlots.add(Map.of("time", "6:30 PM - 7:30 PM", "gender", "men", "value", 14)); +// +// // Convert the list to an array +// Map[] slotArray = daySlots.toArray(new Map[0]); +// +// // Access the element in the array +// int slotOrder = Integer.parseInt(slot_order); +// Map slot = slotArray[slotOrder]; // Index 1 (second element) +// String time = (String) slot.get("time"); +// String gender = (String) slot.get("gender"); +// +// +// int adult = Integer.parseInt(no_of_adults); +// int kids = Integer.parseInt(no_of_kids); +// int totalCount = adult + kids; +// String count = String.valueOf(totalCount); +// +// //balaji +// //sendWhatsapp("h2YjFNcJ", mobile_no, slot_from_date, time, count, totalAmount,payment_orderid); +// //System.out.println(mobile_no); +// //"9444173345" +// sendWhatsapp("h2YjFNcJ",mobile_no, slot_from_date, time, count, totalAmount,payment_orderid); +// sendSMS("h2YjFNcJ", mobile_no, slot_from_date, time, count, totalAmount,payment_orderid); +// +// } else { +// System.out.println("Error on temp save!"); +// } +// } 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()); +// } else { +// System.out.println("Message: " + rootCause.getMessage()); +// } +// } +// +// return lastInsertId; +// } +// +// public String saveBookingInfo( +// String tempId, +// String booking_type, +// String cdate, +// String mobile_no, +// String name, +// String no_of_adults, +// String no_of_kids, +// String pool_id, +// String slot_from_date, +// String slot_order, +// String slot_to_date, +// String totalAmount, +// String payment_id, +// String payment_orderid, +// String payment_status, +// String paymentdate, +// String uniqueid, +// String booking_mode, +// int source) { +// +// String lastInsertId = "0"; +// +// String sqlQuery = "INSERT INTO `booking_details`(`booking_mode`, `booking_type`, `cdate`, " +// + "`mobile_no`, `name`, `no_of_adults`, `no_of_kids`, `pool_id`, `slot_from_date`, " +// + "`slot_order`, `slot_to_date`, `total_amount`,`orderid`, `adults_remaining`,`kids_remaining`,`source`) " +// + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; +// +// KeyHolder keyHolder = new GeneratedKeyHolder(); +// System.out.println("booking_mode:" + booking_mode); +// try { +// int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { +// @Override +// public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { +// PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); +// ps.setString(1, booking_mode); +// ps.setString(2, booking_type); +// ps.setString(3, cdate); +// ps.setString(4, mobile_no); +// ps.setString(5, name); +// ps.setString(6, no_of_adults); +// ps.setString(7, no_of_kids); +// ps.setString(8, pool_id); +// ps.setString(9, slot_from_date); +// ps.setString(10, slot_order); +// ps.setString(11, slot_to_date); +// ps.setString(12, totalAmount); +// ps.setString(13, payment_orderid); +// ps.setString(14, no_of_adults); +// ps.setString(15, no_of_kids); +// ps.setString(16, String.valueOf(source)); +// return ps; +// } +// }, keyHolder); +// +// if (affectedRows > 0) { +// Number generatedId = keyHolder.getKey(); +// lastInsertId = generatedId.toString(); +// } else { +// System.out.println("Error on temp save!"); +// } +// } 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()); +// } else { +// System.out.println("Message: " + rootCause.getMessage()); +// } +// } +// +// return lastInsertId; +// } +// +// public String sendWhatsapp(String password, String mobileno,String date, String slot, String count, String amount, String orderid) { +// System.out.println("trying send whatsapp to :"+ mobileno); +// +// String[] parts = slot.split("-"); +// +// // Trim the parts to remove leading and trailing spaces +// String startTime = parts[0].trim(); +// String endTime = parts[1].trim(); +// // Manually replace characters in startTime and endTime to URL-encoded equivalents +// String formattedStartTime = startTime.replace(":", "%3A").replace(" ", "+"); +// String formattedEndTime = endTime.replace(":", "%3A").replace(" ", "+"); +// +// String tamilurl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+mobileno+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AA%E0%AF%86%E0%AE%B0%E0%AF%81%E0%AE%A8%E0%AE%95%E0%AE%B0+%E0%AE%9A%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%A9%E0%AF%88+%E0%AE%AE%E0%AE%BE%E0%AE%A8%E0%AE%95%E0%AE%B0%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9A%E0%AE%BF+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81.++%0A%0A%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%A4%E0%AF%81+%E0%AE%AE%E0%AF%86%E0%AE%B0%E0%AE%BF%E0%AE%A9%E0%AE%BE++%E0%AE%A8%E0%AF%80%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AE%B2%E0%AF%8D++%E0%AE%95%E0%AF%81%E0%AE%B3%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+"+count+"+%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%A3%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88+%E0%AE%A8%E0%AE%AA%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+"+date+"+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AF%81+++%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+"+formattedStartTime+"+-+"+formattedEndTime+"++%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.+%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9+%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82%2A.+"+amount+"+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.++%0A%0A%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%A9+%E0%AE%A8%E0%AF%80%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AE%B2%E0%AF%8D+%E0%AE%85%E0%AE%A9%E0%AF%81%E0%AE%AA%E0%AE%B5%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AF%81+%E0%AE%AE%E0%AE%95%E0%AE%BF%E0%AE%B4%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%F0%9F%98%8A%0A%0A%E0%AE%A8%E0%AF%81%E0%AE%B4%E0%AF%88%E0%AE%B5%E0%AE%BE%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%F0%9F%91%87&isTemplate=true&buttonUrlParam=swimmingpool%2FbookingQRCode%3Forderid%3D"+orderid; +// //bookingQRCode?orderid=order_P6UOll7Kn1UfrV +// String response = restTemplate.getForObject(tamilurl, String.class); +// System.out.println("response: "+ response); +// +// try{ +// HttpURLConnection connection =null; +// +// URL url = new URL(tamilurl); +// connection = (HttpURLConnection) url.openConnection(); +// connection.setRequestMethod("GET"); +// +// int responseCode = connection.getResponseCode(); +// response=responseCode+""; +// System.out.println("Response Code: " + responseCode); +// +// }catch (Exception e){ +// e.printStackTrace(); +// } +// sendenglishWhatsapp(password, mobileno,date, slot, count, amount, orderid); +// return response; +// } +// +// public String sendenglishWhatsapp(String password, String mobileno,String date, String slot, String count, String amount, String orderid) { +// System.out.println("trying send whatsapp to :"+ mobileno); +// +// String[] parts = slot.split("-"); +// +// // Trim the parts to remove leading and trailing spaces +// String startTime = parts[0].trim(); +// String endTime = parts[1].trim(); +// // Manually replace characters in startTime and endTime to URL-encoded equivalents +// String formattedStartTime = startTime.replace(":", "%3A").replace(" ", "+"); +// String formattedEndTime = endTime.replace(":", "%3A").replace(" ", "+"); +// +// String tamilurl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password="+password+"&send_to="+mobileno+"&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron+%2C+%0AWelcome+to+Greater+Chennai+Corporation.++%0A%0AYou+have+booked+our+Marina+swimming+pool+for+"+count+"+number+of+persons+on+"+date+"+at+time+slot+"+formattedStartTime+"+-+"+formattedEndTime+"+.%0AThe+fee+for+the+slot+is+%2ARs%2A.+"+amount+"+received.+%0A%0AEnjoy+a+pleasant+swimming+experience%F0%9F%98%8A%0A%0APlease+show+your+QR+Code+at+Entrance%F0%9F%91%87&isTemplate=true&buttonUrlParam=swimmingpool%2FbookingQRCode%3Forderid%3D"+orderid; +// //bookingQRCode?orderid=order_P6UOll7Kn1UfrV +// String response = restTemplate.getForObject(tamilurl, String.class); +// System.out.println("response: "+ response); +// +// try{ +// HttpURLConnection connection =null; +// +// URL url = new URL(tamilurl); +// connection = (HttpURLConnection) url.openConnection(); +// connection.setRequestMethod("GET"); +// +// int responseCode = connection.getResponseCode(); +// response=responseCode+""; +// System.out.println("Response Code: " + responseCode); +// +// }catch (Exception e){ +// e.printStackTrace(); +// } +// +// return response; +// } +// +// public String sendSMS(String password, String mobileno,String date, String slot, String count, String amount, String orderid) { +// +// String note=""; +// String[] parts = slot.split("-"); +// +// // Trim the parts to remove leading and trailing spaces +// String startTime = parts[0].trim(); +// String endTime = parts[1].trim(); +// +// String SMSTEXT = "அன்பான வாடிக்கையாளரே, பெருநகர சென்னை மாநகராட்சி தங்களை அன்புடன் வரவேற்கின்றது. எங்களது மெரினா நீச்சல் குளத்தினை "+count+" எண்ணிக்கை நபர்களுக்கு "+date+" அன்று நேர இடைவெளி "+startTime+" முதல் "+endTime+" வரை பயன்படுத்திக்கொள்ள முன்பதிவு செய்துள்ளீர்கள். இதற்கான கட்டணம் ரூ. "+amount+" பெறப்பட்டுள்ளது. இனிமையான நீச்சல் அனுபவத்தினை பெற்று மகிழுங்கள். "+note+" நுழைவாயிலில் உங்கள் QR குறியீட்டை காட்டுங்கள்"; +// +// String urlString="https://tmegov.onex-aura.com/api/sms?key=mRSm0zym&to="+mobileno+"&from=GCCCRP&body="+SMSTEXT+"&entityid=1401572690000011081&templateid=1407172667016050918"; +// //System.out.println(urlString); +// +// RestTemplate restTemplate = new RestTemplate(); +// String Response = restTemplate.getForObject(urlString, String.class); +// +// String SMSEnglish = "Dear Patron, Welcome to Greater Chennai Corporation. You have booked our Marina swimming pool for "+count+" Nos of persons on "+date+" at time interval "+startTime+" to "+endTime+" . The fee for the slot is Rs. "+amount+" Received. Enjoy a pleasant swimming experience. "+note+" Please Show your QR Code at Entrance"; +// +// String urlString2="https://tmegov.onex-aura.com/api/sms?key=mRSm0zym&to="+mobileno+"&from=GCCCRP&body="+SMSEnglish+"&entityid=1401572690000011081&templateid=1407172666960216321"; +// //System.out.println(urlString); +// +// RestTemplate restTemplate2 = new RestTemplate(); +// String Response2 = restTemplate2.getForObject(urlString2, String.class); +// +// return Response2; +// } +// +// +//} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/service/SwimmingPoolService.java b/src/main/java/com/gcc/restapiservices/swimmingpool/service/SwimmingPoolService.java new file mode 100644 index 0000000..e4b011c --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/service/SwimmingPoolService.java @@ -0,0 +1,778 @@ + package com.gcc.restapiservices.swimmingpool.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Configuration; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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.web.client.RestTemplate; +import com.fasterxml.jackson.databind.ObjectMapper; // For converting JSON map to String + + +import javax.sql.DataSource; +import java.net.HttpURLConnection; +import java.net.URL; +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +@Service +@Configuration +public class SwimmingPoolService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + private RestTemplate restTemplate; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public void setDataSource(@Qualifier("mysqlSwimmingpoolDataSource") DataSource activityDataSource) { + this.jdbcTemplate = new JdbcTemplate(activityDataSource); + } + + public List> getSlotsWithGender(String gender, String date) { + String sql = " SELECT " + + "st.slot_timing AS time, " + + "CASE WHEN st.gender_avail = '1' THEN 'men' ELSE 'women' END AS gender, " + + "st.id AS value, " + + "? AS slot_from_date " + + "FROM slot_timing st " + + "LEFT JOIN booking_details b " + + "ON b.slot_order = st.slot_order " + + "AND b.slot_from_date = ? " + + "AND b.is_active = 1 " + + "AND b.is_delete = 0 " + + "WHERE st.gender_avail = ? " + + "GROUP BY " + + "st.slot_timing, st.gender_avail, st.id " + + "ORDER BY st.id"; + + return jdbcTemplate.queryForList(sql, date, date, gender); + } + + + public List> getBookedCountbySlot(String slotid, String date) { + String sqlQuery = "SELECT " + + " b.slot_from_date, " + + " st.slot_timing, " + + " CASE " + + " WHEN b.slot_order = '4' THEN 'women' " + + " ELSE 'men' " + + " END AS gender, " + + " 200 AS total_capacity, " + + " 200 - (COALESCE(SUM(b.no_of_kids), 0) + COALESCE(SUM(b.no_of_adults), 0)) AS available_slots, " + + " (COALESCE(SUM(b.no_of_kids), 0) + COALESCE(SUM(b.no_of_adults), 0)) AS booked_slots " + + "FROM " + + " booking_details b " + + "JOIN " + + " slot_timing st ON b.slot_order = st.slot_order " + + "WHERE " + + " b.is_active = 1 " + + " AND b.is_delete = 0 " + + " AND b.slot_from_date = ? " + + " AND b.slot_order = ? " + + "GROUP BY " + + " b.slot_from_date, " + + " b.slot_order, " + + " st.slot_timing;"; + + List> bookingDetails = jdbcTemplate.queryForList(sqlQuery, date, slotid); + + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + + for (Map row : bookingDetails) { + Object dateObj = row.get("slot_from_date"); + if (dateObj != null) { + try { + LocalDate parsed = LocalDate.parse(dateObj.toString(), inputFormatter); + row.put("slot_from_date", parsed.format(outputFormatter)); + } catch (DateTimeParseException dtpe) { + System.err.println("Date parsing failed for value: " + dateObj + " | Error: " + dtpe.getMessage()); + // You could also add an explicit fallback: + row.put("slot_from_date", dateObj.toString()); + } catch (Exception ex) { + System.err.println("Unexpected error while formatting date: " + ex.getMessage()); + row.put("slot_from_date", dateObj.toString()); + } + } + } + + + // If no data is returned, create a default response with 0 values + if (bookingDetails.isEmpty()) { + Map defaultData = new HashMap<>(); + // Convert incoming date (yyyy-MM-dd) into dd-MM-yyyy + LocalDate parsed = LocalDate.parse(date, inputFormatter); + defaultData.put("slot_from_date", parsed.format(outputFormatter)); + defaultData.put("slot_timing", "Not Available"); + defaultData.put("slot_order", slotid); + String genderVal = "4".equals(slotid) ? "women" : "men"; + defaultData.put("gender", genderVal); + defaultData.put("total_capacity", 200); + defaultData.put("available_slots", 200); + defaultData.put("booked_slots", 0); + bookingDetails.add(defaultData); + } + + return bookingDetails; + } + + + public List> getAvailabilityByDate(LocalDate date) { + String sql = """ + SELECT + st.slot_order, + st.slot_timing, + CASE WHEN st.slot_order = 4 THEN 'women' ELSE 'men' END AS gender, + 200 AS total_capacity, + COALESCE(b.booked_slots, 0) AS booked_slots, + 200 - COALESCE(b.booked_slots, 0) AS available_slots + FROM slot_timing st + LEFT JOIN ( + SELECT + slot_order, + SUM(no_of_adults + no_of_kids) AS booked_slots + FROM booking_details + WHERE slot_from_date = ? + AND is_active = 1 + AND is_delete = 0 + GROUP BY slot_order + ) b ON CAST(st.slot_order AS UNSIGNED) = CAST(b.slot_order AS UNSIGNED) + ORDER BY CAST(st.slot_order AS UNSIGNED); + """; + + // use the ISO date string for the JDBC call + List> list = + jdbcTemplate.queryForList(sql, date.toString()); + + return list; + } + + + public Map calculatePayment(int adultsCount, int kidsCount, String bookingMode) { + int adultRate = 0; + int kidRate = 0; + + // Rates based on booking mode + if ("ONLINE".equalsIgnoreCase(bookingMode)) { + adultRate = 45; + kidRate = 25; + } else { + // Return an error response if booking mode is invalid + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Invalid booking mode"); + return errorResponse; + } + + // Calculate total amount + int totalAdultsAmount = adultsCount * adultRate; + int totalKidsAmount = kidsCount * kidRate; + int totalAmount = totalAdultsAmount + totalKidsAmount; + + // Prepare the response map + Map response = new HashMap<>(); + response.put("adultsCount", adultsCount); + response.put("kidsCount", kidsCount); + response.put("totalAdultsAmount", totalAdultsAmount); + response.put("totalKidsAmount", totalKidsAmount); + response.put("totalAmount", totalAmount); + + return response; + } + + public String saveBooking( + String name, + String mobileNo, + String noofadults, + String noofkids, + String slotfromdate, + String slottodate, + String totalAmount, + String bookingtype, + String slotorder, + String poolId, + String bookingMode) { + + // helper to take everything before the first comma + Function firstData = s -> { + if (s == null) return null; + int idx = s.indexOf(','); + return idx < 0 ? s.trim() : s.substring(0, idx).trim(); + }; + + // sanitize EVERY incoming param + name = firstData.apply(name); + mobileNo = firstData.apply(mobileNo); + noofadults = firstData.apply(noofadults); + noofkids = firstData.apply(noofkids); + slotfromdate = firstData.apply(slotfromdate); + slottodate = firstData.apply(slottodate); + totalAmount = firstData.apply(totalAmount); + bookingtype = firstData.apply(bookingtype); + slotorder = firstData.apply(slotorder); + poolId = firstData.apply(poolId); + bookingMode = firstData.apply(bookingMode); + + if (mobileNo.length() > 20) { + throw new IllegalArgumentException("Mobile number too long: " + mobileNo); + } + + // parse the numeric/date fields + int adultsCount = Integer.parseInt(noofadults); + int kidsCount = Integer.parseInt(noofkids); + int pool = Integer.parseInt(poolId); + Date fromDate = Date.valueOf(slotfromdate); + Date toDate = Date.valueOf(slottodate); + + String sql = " INSERT INTO temp_booking_details( " + + "booking_type, mobile_no, name, " + + "no_of_adults, no_of_kids, pool_id, " + + "slot_from_date, slot_order, slot_to_date, " + + "total_amount, booking_mode" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?) "; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + String finalBookingtype = bookingtype; + String finalMobileNo = mobileNo; + String finalName = name; + String finalSlotorder = slotorder; + String finalTotalAmount = totalAmount; + String finalBookingMode = bookingMode; + int rows = jdbcTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(sql, new String[]{"temp_id"}); + ps.setString(1, finalBookingtype); + ps.setString(2, finalMobileNo); + ps.setString(3, finalName); + ps.setInt(4, adultsCount); + ps.setInt(5, kidsCount); + ps.setInt(6, pool); + ps.setDate(7, fromDate); + ps.setString(8, finalSlotorder); + ps.setDate(9, toDate); + ps.setString(10, finalTotalAmount); + ps.setString(11, finalBookingMode); + return ps; + }, keyHolder); + + if (rows == 0) { + throw new RuntimeException("Insert returned 0 rows affected"); + } + return keyHolder.getKey().toString(); + } + + public Map getTempBookingData(String tempid) { + String sqlQuery = "SELECT * FROM temp_booking_details WHERE temp_id='" + tempid + "'"; + Map tempBookingDetails = jdbcTemplate.queryForMap(sqlQuery); + return tempBookingDetails; + } + + public String savePaymentInfo( + String tempId, + String booking_type, + String cdate, + String mobile_no, + String name, + String no_of_adults, + String no_of_kids, + String pool_id, + String slot_from_date, + String slot_order, + String slot_to_date, + String totalAmount, + String payment_id, + String payment_orderid, + String payment_status, + String paymentdate, + String uniqueid, + String booking_mode, + String reference_id, + int source) { + + String lastInsertId = "0"; + + String sqlQuery = "INSERT INTO `payment`(`amount`, `mobno`, `order_id`, `payment_id`, `reference_id`,`payment_status`, `paymentdate`, `uniqueid`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"temp_id"}); + ps.setString(1, totalAmount); + ps.setString(2, mobile_no); + ps.setString(3, payment_orderid); + ps.setString(4, payment_id); + ps.setString(5, reference_id); + ps.setString(6, payment_status); + ps.setString(7, paymentdate); + ps.setString(8, uniqueid); + return ps; + } + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + lastInsertId = generatedId.toString(); + + lastInsertId = saveBookingInfo(tempId, booking_type, cdate, mobile_no, + name, + no_of_adults, + no_of_kids, + pool_id, + slot_from_date, + slot_order, + slot_to_date, + totalAmount, + payment_id, + payment_orderid, + payment_status, + paymentdate, + uniqueid, + booking_mode, + source); + + + // Define the time slots in Java + List> daySlots = new ArrayList<>(); + + daySlots.add(Map.of("time", "5:30 AM - 6:30 AM", "gender", "men", "value", 0)); + daySlots.add(Map.of("time", "5:30 AM - 6:30 AM", "gender", "men", "value", 1)); + daySlots.add(Map.of("time", "6:30 AM - 7:30 AM", "gender", "men", "value", 2)); + daySlots.add(Map.of("time", "7:30 AM - 8:30 AM", "gender", "men", "value", 3)); + daySlots.add(Map.of("time", "8:30 AM - 9:30 AM", "gender", "women", "value", 4)); + daySlots.add(Map.of("time", "9:30 AM - 10:30 AM", "gender", "men", "value", 5)); + daySlots.add(Map.of("time", "10:30 AM - 11:30 AM", "gender", "men", "value", 6)); + daySlots.add(Map.of("time", "11:30 AM - 12:30 PM", "gender", "men", "value", 7)); + daySlots.add(Map.of("time", "12:30 PM - 1:30 PM", "gender", "men", "value", 8)); + daySlots.add(Map.of("time", "1:30 PM - 2:30 PM", "gender", "men", "value", 9)); + daySlots.add(Map.of("time", "2:30 PM - 3:30 PM", "gender", "men", "value", 10)); + daySlots.add(Map.of("time", "3:30 PM - 4:30 PM", "gender", "men", "value", 11)); + daySlots.add(Map.of("time", "4:30 PM - 5:30 PM", "gender", "men", "value", 12)); + daySlots.add(Map.of("time", "5:30 PM - 6:30 PM", "gender", "men", "value", 13)); + daySlots.add(Map.of("time", "6:30 PM - 7:30 PM", "gender", "men", "value", 14)); + + // Convert the list to an array + Map[] slotArray = daySlots.toArray(new Map[0]); + + // Access the element in the array + int slotOrder = Integer.parseInt(slot_order); + Map slot = slotArray[slotOrder]; // Index 1 (second element) + String time = (String) slot.get("time"); + String gender = (String) slot.get("gender"); + + + int adult = Integer.parseInt(no_of_adults); + int kids = Integer.parseInt(no_of_kids); + int totalCount = adult + kids; + String count = String.valueOf(totalCount); + + //balaji + //sendWhatsapp("h2YjFNcJ", mobile_no, slot_from_date, time, count, totalAmount,payment_orderid); + //System.out.println(mobile_no); + //"9444173345" + sendWhatsapp("h2YjFNcJ", mobile_no, slot_from_date, time, count, totalAmount, payment_orderid); + sendSMS("h2YjFNcJ", mobile_no, slot_from_date, time, count, totalAmount, payment_orderid); + + } else { + System.out.println("Error on temp save!"); + } + } 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()); + } else { + System.out.println("Message: " + rootCause.getMessage()); + } + } + + return lastInsertId; + } + + public String saveBookingInfo( + String tempId, + String booking_type, + String cdate, + String mobile_no, + String name, + String no_of_adults, + String no_of_kids, + String pool_id, + String slot_from_date, + String slot_order, + String slot_to_date, + String totalAmount, + String payment_id, + String payment_orderid, + String payment_status, + String paymentdate, + String uniqueid, + String booking_mode, + int source) { + + String lastInsertId = "0"; + + String sqlQuery = "INSERT INTO `booking_details`(`booking_mode`, `booking_type`, `cdate`, " + + "`mobile_no`, `name`, `no_of_adults`, `no_of_kids`, `pool_id`, `slot_from_date`, " + + "`slot_order`, `slot_to_date`, `total_amount`,`orderid`, `adults_remaining`,`kids_remaining`,`source`)" + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + System.out.println("booking_mode:" + booking_mode); + try { + int affectedRows = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); + ps.setString(1, booking_mode); + ps.setString(2, booking_type); + ps.setString(3, cdate); + ps.setString(4, mobile_no); + ps.setString(5, name); + ps.setString(6, no_of_adults); + ps.setString(7, no_of_kids); + ps.setString(8, pool_id); + ps.setString(9, slot_from_date); + ps.setString(10, slot_order); + ps.setString(11, slot_to_date); + ps.setString(12, totalAmount); + ps.setString(13, payment_orderid); + ps.setString(14, no_of_adults); + ps.setString(15, no_of_kids); + ps.setString(16, String.valueOf(source)); + return ps; + } + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + lastInsertId = generatedId.toString(); + } else { + System.out.println("Error on temp save!"); + } + } 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()); + } else { + System.out.println("Message: " + rootCause.getMessage()); + } + } + + return lastInsertId; + } + + public String sendWhatsapp(String password, String mobileno, String date, String slot, String count, String amount, String orderid) { + System.out.println("trying send whatsapp to :" + mobileno); + + String[] parts = slot.split("-"); + + // Trim the parts to remove leading and trailing spaces + String startTime = parts[0].trim(); + String endTime = parts[1].trim(); + // Manually replace characters in startTime and endTime to URL-encoded equivalents + String formattedStartTime = startTime.replace(":", "%3A").replace(" ", "+"); + String formattedEndTime = endTime.replace(":", "%3A").replace(" ", "+"); + + String tamilurl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=" + password + "&send_to=" + mobileno + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%B5%E0%AE%BE%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B3%E0%AE%B0%E0%AF%87%2C+%0A%E0%AE%AA%E0%AF%86%E0%AE%B0%E0%AF%81%E0%AE%A8%E0%AE%95%E0%AE%B0+%E0%AE%9A%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%A9%E0%AF%88+%E0%AE%AE%E0%AE%BE%E0%AE%A8%E0%AE%95%E0%AE%B0%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9A%E0%AE%BF+%E0%AE%A4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%8D+%E0%AE%B5%E0%AE%B0%E0%AE%B5%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A4%E0%AF%81.++%0A%0A%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%A4%E0%AF%81+%E0%AE%AE%E0%AF%86%E0%AE%B0%E0%AE%BF%E0%AE%A9%E0%AE%BE++%E0%AE%A8%E0%AF%80%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AE%B2%E0%AF%8D++%E0%AE%95%E0%AF%81%E0%AE%B3%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+" + count + "+%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%A3%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%88+%E0%AE%A8%E0%AE%AA%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+" + date + "+%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AF%81+++%E0%AE%A8%E0%AF%87%E0%AE%B0+%E0%AE%87%E0%AE%9F%E0%AF%88%E0%AE%B5%E0%AF%86%E0%AE%B3%E0%AE%BF+" + formattedStartTime + "+-+" + formattedEndTime + "++%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AE%E0%AF%81%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BF%E0%AE%B5%E0%AF%81+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D.+%0A%E0%AE%87%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AE%BE%E0%AE%A9+%E0%AE%95%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%A3%E0%AE%AE%E0%AF%8D+%2A%E0%AE%B0%E0%AF%82%2A.+" + amount + "+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.++%0A%0A%E0%AE%87%E0%AE%A9%E0%AE%BF%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%A9+%E0%AE%A8%E0%AF%80%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AE%B2%E0%AF%8D+%E0%AE%85%E0%AE%A9%E0%AF%81%E0%AE%AA%E0%AE%B5%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%A9%E0%AF%88+%E0%AE%AA%E0%AF%86%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AF%81+%E0%AE%AE%E0%AE%95%E0%AE%BF%E0%AE%B4%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%F0%9F%98%8A%0A%0A%E0%AE%A8%E0%AF%81%E0%AE%B4%E0%AF%88%E0%AE%B5%E0%AE%BE%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+QR+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AF%80%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%88+%E0%AE%95%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D%F0%9F%91%87&isTemplate=true&buttonUrlParam=swimmingpool%2FbookingQRCode%3Forderid%3D" + orderid; + //bookingQRCode?orderid=order_P6UOll7Kn1UfrV + String response = restTemplate.getForObject(tamilurl, String.class); + System.out.println("response: " + response); + + try { + HttpURLConnection connection = null; + + URL url = new URL(tamilurl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + sendenglishWhatsapp(password, mobileno, date, slot, count, amount, orderid); + return response; + } + + public String sendenglishWhatsapp(String password, String mobileno, String date, String slot, String count, String amount, String orderid) { + System.out.println("trying send whatsapp to :" + mobileno); + + String[] parts = slot.split("-"); + + // Trim the parts to remove leading and trailing spaces + String startTime = parts[0].trim(); + String endTime = parts[1].trim(); + // Manually replace characters in startTime and endTime to URL-encoded equivalents + String formattedStartTime = startTime.replace(":", "%3A").replace(" ", "+"); + String formattedEndTime = endTime.replace(":", "%3A").replace(" ", "+"); + + String tamilurl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=" + password + "&send_to=" + mobileno + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Dear+Patron+%2C+%0AWelcome+to+Greater+Chennai+Corporation.++%0A%0AYou+have+booked+our+Marina+swimming+pool+for+" + count + "+number+of+persons+on+" + date + "+at+time+slot+" + formattedStartTime + "+-+" + formattedEndTime + "+.%0AThe+fee+for+the+slot+is+%2ARs%2A.+" + amount + "+received.+%0A%0AEnjoy+a+pleasant+swimming+experience%F0%9F%98%8A%0A%0APlease+show+your+QR+Code+at+Entrance%F0%9F%91%87&isTemplate=true&buttonUrlParam=swimmingpool%2FbookingQRCode%3Forderid%3D" + orderid; + //bookingQRCode?orderid=order_P6UOll7Kn1UfrV + String response = restTemplate.getForObject(tamilurl, String.class); + System.out.println("response: " + response); + + try { + HttpURLConnection connection = null; + + URL url = new URL(tamilurl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public String sendSMS(String password, String mobileno, String date, String slot, String count, String amount, String orderid) { + + String note = ""; + String[] parts = slot.split("-"); + + // Trim the parts to remove leading and trailing spaces + String startTime = parts[0].trim(); + String endTime = parts[1].trim(); + + String SMSTEXT = "அன்பான வாடிக்கையாளரே, பெருநகர சென்னை மாநகராட்சி தங்களை அன்புடன் வரவேற்கின்றது. எங்களது மெரினா நீச்சல் குளத்தினை " + count + " எண்ணிக்கை நபர்களுக்கு " + date + " அன்று நேர இடைவெளி " + startTime + " முதல் " + endTime + " வரை பயன்படுத்திக்கொள்ள முன்பதிவு செய்துள்ளீர்கள். இதற்கான கட்டணம் ரூ. " + amount + " பெறப்பட்டுள்ளது. இனிமையான நீச்சல் அனுபவத்தினை பெற்று மகிழுங்கள். " + note + " நுழைவாயிலில் உங்கள் QR குறியீட்டை காட்டுங்கள்"; + + String urlString = "https://tmegov.onex-aura.com/api/sms?key=mRSm0zym&to=" + mobileno + "&from=GCCCRP&body=" + SMSTEXT + "&entityid=1401572690000011081&templateid=1407172667016050918"; + //System.out.println(urlString); + + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + String SMSEnglish = "Dear Patron, Welcome to Greater Chennai Corporation. You have booked our Marina swimming pool for " + count + " Nos of persons on " + date + " at time interval " + startTime + " to " + endTime + " . The fee for the slot is Rs. " + amount + " Received. Enjoy a pleasant swimming experience. " + note + " Please Show your QR Code at Entrance"; + + String urlString2 = "https://tmegov.onex-aura.com/api/sms?key=mRSm0zym&to=" + mobileno + "&from=GCCCRP&body=" + SMSEnglish + "&entityid=1401572690000011081&templateid=1407172666960216321"; + //System.out.println(urlString); + + RestTemplate restTemplate2 = new RestTemplate(); + String Response2 = restTemplate2.getForObject(urlString2, String.class); + + return Response2; + } + + public int saveorderLog(String order_id, String order_info, String uniqueid) { + if (order_id == null || uniqueid == null) { + System.out.println("Missing required fields. Order ID: " + order_id + ", Temp Book ID: " + uniqueid); + return 0; + } + + int temp_booking_id = Integer.parseInt(uniqueid); + + String sqlQuery = "INSERT INTO orderslogs(order_id, order_info, uniqueid) VALUES (?,?,?)"; + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int affectedRows = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sqlQuery, new String[]{"id"}); + ps.setString(1, order_id); + ps.setString(2, order_info); + ps.setInt(3, temp_booking_id); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + Number generatedId = keyHolder.getKey(); + return (generatedId != null) ? generatedId.intValue() : 0; + } else { + System.out.println("Failed to insert into order_log."); + return 0; + } + } catch (Exception e) { + System.out.println("Exception during insert to order_log: " + e.getMessage()); + e.printStackTrace(); + return 0; + } + } + + + public ResponseEntity processPaymentConfirmation(String tempid, int source, String orderid, Map paymentResponse) { + + if (source < 0 || source > 2) { + return ResponseEntity.badRequest() + .body(Map.of("message", "Invalid source: must be 0 (web), 1 (counter) or 2 (whatsapp)")); + } + + // Validate tempid + int id; + try { + id = Integer.parseInt(tempid); + } catch (NumberFormatException nfe) { + return ResponseEntity.badRequest() + .body(Map.of("message", "Invalid id: must be a number")); + } + + // Fetch temp booking + Map tempBookingDetails = getTempBookingData(tempid); + if (tempBookingDetails.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("message", "No booking found for id: " + tempid)); + } + + try { + Map transaction = (Map) paymentResponse.get("transaction"); + Map amountMap = (Map) transaction.get("amount"); + Map methodMap = (Map) transaction.get("method"); + + String payId = transaction.get("pg_transaction_id").toString(); + String referenceId = paymentResponse.get("reference_id").toString(); + String orderId = orderid; + String status = transaction.get("status").toString(); + + savePaymentResponse(orderId, payId, status, referenceId, paymentResponse, tempid); + + // Save failed transaction + if ("failed".equalsIgnoreCase(status)) { + // Convert entire response map to JSON string + ObjectMapper mapper = new ObjectMapper(); + String fullResponseJson = mapper.writeValueAsString(paymentResponse); + + // Save to DB (assuming you have a method) + saveFailedTransaction(orderId, payId, status, referenceId, fullResponseJson, id); + + return ResponseEntity.ok(Map.of( + "message", "Your payment failed. Please try again." + )); + } else if ("success".equalsIgnoreCase(status)) { + + savePaymentInfo(tempid, + tempBookingDetails.get("booking_type").toString(), + tempBookingDetails.get("cdate").toString(), + tempBookingDetails.get("mobile_no").toString(), + tempBookingDetails.get("name").toString(), + tempBookingDetails.get("no_of_adults").toString(), + tempBookingDetails.get("no_of_kids").toString(), + tempBookingDetails.get("pool_id").toString(), + tempBookingDetails.get("slot_from_date").toString(), + tempBookingDetails.get("slot_order").toString(), + tempBookingDetails.get("slot_to_date").toString(), + tempBookingDetails.get("total_amount").toString(), + payId, + orderId, + referenceId, + status, + tempBookingDetails.get("cdate").toString(), + tempid, + tempBookingDetails.getOrDefault("booking_mode", "ONLINE").toString(), + source); + + String qrCodeUrl = "https://gccservices.chennaicorporation.gov.in/swimmingpool/bookingQRCode?orderid=" + orderId; + return ResponseEntity.ok(Map.of( + "message", "Your payment was successful and your booking is now confirmed! " + + "You’ll receive the full details via WhatsApp and SMS shortly. " + + "Please have your QR code ready at entry.", + "qrCodeUrl", qrCodeUrl + )); + + + } + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment")); + + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("message", "Failed to confirm payment", "error", e.getMessage())); + } + } + + private void savePaymentResponse(String orderId, String payId, String status, String referenceId, + Map paymentResponse, String tempid) { + + String sql = "INSERT INTO payment_response (order_id, payment_id, payment_status,reference_id,response, uniqueId) " + + "VALUES (?, ?, ?, ?, ?, ?)"; + + try { + String jsonResponse = objectMapper.writeValueAsString(paymentResponse); + jdbcTemplate.update(sql, + orderId, + payId, + status, + referenceId, + jsonResponse, + tempid + ); + } catch (Exception e) { + e.printStackTrace(); // log or rethrow as needed + } + } + + public void saveFailedTransaction(String orderId, String paymentId, String status, String referenceId, String fullJsonResponse, int uniqueId) { + String sql = "INSERT INTO payment_failed_response (order_id, payment_id, payment_status, response, uniqueId,reference_id) " + + "VALUES (?, ?, ?, ?, ?, ?)"; + + jdbcTemplate.update(sql, orderId, paymentId, status, referenceId, fullJsonResponse, uniqueId); + } + + + public List> getBookingByMobileNo(long mobileNo) { + String sqlQuery = "SELECT b.id, b.booking_mode, b.booking_type, " + + "DATE_FORMAT(b.cdate, '%d-%m-%Y') AS cdate, " + // format dd-MM-yyyy + "b.mobile_no, b.name, b.no_of_adults, b.no_of_kids, " + + "DATE_FORMAT(b.slot_from_date, '%d-%m-%Y') AS slot_from_date, " + // format dd-MM-yyyy + "st.slot_timing AS slot_order, " + + "DATE_FORMAT(b.slot_to_date, '%d-%m-%Y') AS slot_to_date, " + // format dd-MM-yyyy + "b.total_amount, b.orderid, " + + "b.adults_remaining, b.kids_remaining " + + "FROM booking_details b " + + "LEFT JOIN slot_timing st ON b.slot_order = st.id " + + "WHERE b.mobile_no = ? " + + "ORDER BY b.cdate DESC"; + + List> bookings = jdbcTemplate.queryForList(sqlQuery, mobileNo); + + String baseQrUrl = "https://gccservices.chennaicorporation.gov.in/swimmingpool/bookingQRCode?orderid="; + for (Map booking : bookings) { + // orderid comes back as a String in the map + String orderId = String.valueOf(booking.get("orderid")); + booking.put("acknowledgementLink", baseQrUrl + orderId); + } + + return bookings; + } + + + public List> findByMobileNo(long mobileNo){ + String sqlQuery = "select id from booking_details where mobile_no = '"+mobileNo+"'"; + System.out.println(sqlQuery); + return jdbcTemplate.queryForList(sqlQuery); + } +} diff --git a/src/main/java/com/gcc/restapiservices/swimmingpool/util/ApiResponse.java b/src/main/java/com/gcc/restapiservices/swimmingpool/util/ApiResponse.java new file mode 100644 index 0000000..404a68e --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/swimmingpool/util/ApiResponse.java @@ -0,0 +1,49 @@ +package com.gcc.restapiservices.swimmingpool.util; + +public class ApiResponse { + private String status; + private String message; + private Object data; + private int statusCode; + + // Constructor + public ApiResponse(String status, String message, Object data, int statusCode) { + this.status = status; + this.message = message; + this.data = data; + this.statusCode = statusCode; + } + + // Getters and Setters + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } +} \ No newline at end of file diff --git a/src/main/java/com/gcc/restapiservices/townplanning/controller/BuildingApprovalApiController.java b/src/main/java/com/gcc/restapiservices/townplanning/controller/BuildingApprovalApiController.java new file mode 100644 index 0000000..8cd9d0d --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/townplanning/controller/BuildingApprovalApiController.java @@ -0,0 +1,42 @@ +package com.gcc.restapiservices.townplanning.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.databind.JsonNode; +import com.gcc.restapiservices.townplanning.service.BuildingApprovalService; + +@RequestMapping("/gccrestservices/api/townplanning") +@RestController +public class BuildingApprovalApiController { + + @Autowired + private BuildingApprovalService buildingApprovalService; + + + // ✅ API 1: By BA Number + @GetMapping("/get-building-approval-details-by-ba") + public ResponseEntity getDetailsByBaNumber(@RequestParam String baNumber) { + JsonNode result = buildingApprovalService.getBuildingApprovalDetailsByBaNumber(baNumber); + if (result == null) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + return ResponseEntity.ok(result); + } + + // ✅ API 2: By PPA Number + @GetMapping("/get-building-approval-details-by-ppa") + public ResponseEntity getDetailsByPpaNumber(@RequestParam String ppaNumber) { + JsonNode result = buildingApprovalService.getBuildingApprovalDetailsByPpaNumber(ppaNumber); + if (result == null) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + return ResponseEntity.ok(result); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/townplanning/service/BuildingApprovalService.java b/src/main/java/com/gcc/restapiservices/townplanning/service/BuildingApprovalService.java new file mode 100644 index 0000000..2f8d57d --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/townplanning/service/BuildingApprovalService.java @@ -0,0 +1,53 @@ +package com.gcc.restapiservices.townplanning.service; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +@Service +public class BuildingApprovalService { + + private JdbcTemplate jdbcTemplate; + + private final RestTemplate restTemplate = new RestTemplate(); + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccRestServicesDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + //BA Number + public JsonNode getBuildingApprovalDetailsByBaNumber(String baNumber) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/newmobileservice" + + "?serviceId=common_api&jsonResp=Yes&subService=getBPADetails&baNum=" + baNumber; + + String response = restTemplate.getForObject(url, String.class); + return mapper.readTree(response); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + //PPA Number + public JsonNode getBuildingApprovalDetailsByPpaNumber(String ppaNumber) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/newmobileservice" + + "?serviceId=common_api&jsonResp=Yes&subService=getBPADetails&ppaNum=" + ppaNumber; + + String response = restTemplate.getForObject(url, String.class); + return mapper.readTree(response); + } catch (Exception e) { + e.printStackTrace(); + return null; + } +} +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/configuration/VPHPaymentConfig.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/configuration/VPHPaymentConfig.java new file mode 100644 index 0000000..0d1060d --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/configuration/VPHPaymentConfig.java @@ -0,0 +1,96 @@ +package com.gcc.restapiservices.victoriaHallBooking.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@Configuration +@PropertySource("classpath:paymentConfig.properties") +public class VPHPaymentConfig { + + @Value("${payment.worldline.merchantId}") + private String merchantId; + + @Value("${payment.worldline.encryptionKey}") + private String encryptionKey; + + @Value("${payment.worldline.encryptionIV}") + private String encryptionIV; + + @Value("${payment.worldline.schemeCode}") + private String schemeCode; + + @Value("${payment.worldline.merchantName}") + private String merchantName; + + @Value("${payment.worldline.transactionSuccessCode}") + private String transactionSuccessCode; + + @Value("${payment.worldline.refundSuccessCode}") + private String refundSuccessCode; + + + public String getMerchantId() { + return merchantId; + } + + public void setMerchantId(String merchantId) { + this.merchantId = merchantId; + } + + public String getEncryptionKey() { + return encryptionKey; + } + public byte[] getEncryptionKeyByte() { + return encryptionKey.getBytes(); + } + + public void setEncryptionKey(String encryptionKey) { + this.encryptionKey = encryptionKey; + } + + public String getEncryptionIV() { + return encryptionIV; + } + + public byte[] getEncryptionIVByte() { + return encryptionIV.getBytes(); + } + + public void setEncryptionIV(String encryptionIV) { + this.encryptionIV = encryptionIV; + } + + public String getSchemeCode() { + return schemeCode; + } + + public void setSchemeCode(String schemeCode) { + this.schemeCode = schemeCode; + } + + public String getMerchantName() { + return merchantName; + } + + public void setMerchantName(String merchantName) { + this.merchantName = merchantName; + } + + public String getTransactionSuccessCode() { + return transactionSuccessCode; + } + + public void setTransactionSuccessCode(String transactionSuccessCode) { + this.transactionSuccessCode = transactionSuccessCode; + } + + public String getRefundSuccessCode() { + return refundSuccessCode; + } + + public void setRefundSuccessCode(String refundSuccessCode) { + this.refundSuccessCode = refundSuccessCode; + }} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/controller/VPHHallController.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/controller/VPHHallController.java new file mode 100644 index 0000000..8525d33 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/controller/VPHHallController.java @@ -0,0 +1,992 @@ +package com.gcc.restapiservices.victoriaHallBooking.controller; + +import com.gcc.restapiservices.victoriaHallBooking.dto.PaymentWebhookPayload; +import com.gcc.restapiservices.victoriaHallBooking.service.VPHPaymentService; +import com.gcc.restapiservices.victoriaHallBooking.service.victoriaHallService; +import com.gcc.restapiservices.configuration.AppConfig; +import com.gcc.restapiservices.coworkspace.controller.ApiResponse; + +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.dao.EmptyResultDataAccessException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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 java.security.NoSuchAlgorithmException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Random; + +@RestController +@RequestMapping("/gccrestservices/victoriahall/api") +public class VPHHallController { + + @Autowired + private VPHPaymentService chPaymentService; + + @Autowired + private victoriaHallService hallService; + @Autowired + private AppConfig appConfig; + + @GetMapping("/getHallList") + public List> getHallList() { + List> hallList = new ArrayList>(); + hallList = hallService.getHallList(); + + if (hallList.isEmpty()) { + return hallList; + } + return hallList; + } + + @GetMapping("/getReasonMaster") + public ResponseEntity getReasonMaster() { + try { + List> result = hallService.getReasonMaster(); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found"); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getDocumentsByReasonId") + public ResponseEntity getDocumentsByReasonId(@RequestParam(value = "reasonId", required = false) Long reasonId) { + if (reasonId == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "reasonId is required"); + errorResponse.put("message", "Missing required parameter for reasonId"); + return ResponseEntity.badRequest().body(errorResponse); + } + try { + List> result = hallService.getDocumentsByReasonId(reasonId); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found for reasonId: " + reasonId); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getRelationTypes") + public ResponseEntity getRelationTypes() { + try { + List> result = hallService.getRelationTypesAsMap(); + + if (result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No data found"); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/getUserDetails") + public ResponseEntity getUserDetails(@RequestParam(value = "Mobilenumber", required = false) Long Mobilenumber) {// @RequestParam(value + // = + // "mobileNumber", + // required + // = + // false) + // Long + // mobileNumber, + if (Mobilenumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + // Check if mobile number is 10 digits + String mobileStr = String.valueOf(Mobilenumber); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + try { + List> result = hallService.getUserDetails(Mobilenumber); + + if (result == null || result.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No data found for Mobilenumber: " + Mobilenumber); + } + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @GetMapping("/calculatehallamount") + public ResponseEntity> getHallDetailsConcession( + @RequestParam(value = "numDays", required = false) Integer numDays, + @RequestParam(value = "startPeriod", required = false) String startPeriod, + @RequestParam(value = "endPeriod", required = false) String endPeriod, + @RequestParam(value = "reasonforBooking", required = false) String reasonforBooking, + @RequestParam(value = "hallId", required = false) Integer hallId) { + + // Validation for required parameters + if (numDays == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Number of days is required"); + errorResponse.put("message", "Please provide the numDays parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (startPeriod == null || startPeriod.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Start period is required"); + errorResponse.put("message", "Please provide the startPeriod parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + if (!startPeriod.equals("1") && !startPeriod.equals("2")) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Invalid startPeriod"); + errorResponse.put("message", "startPeriod must be either '1' or '2'"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (endPeriod == null || endPeriod.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "End period is required"); + errorResponse.put("message", "Please provide the endPeriod parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + if (!endPeriod.equals("1") && !endPeriod.equals("2")) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Invalid endPeriod"); + errorResponse.put("message", "endPeriod must be either '1' or '2'"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (reasonforBooking == null || reasonforBooking.trim().isEmpty()) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Reason for booking is required"); + errorResponse.put("message", "Please provide the reasonforBooking parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (hallId == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Hall ID is required"); + errorResponse.put("message", "Please provide the hallId parameter"); + return ResponseEntity.badRequest().body(errorResponse); + } + + Map hallDetails = hallService.getHallDetailsById(hallId); + + if (hallDetails == null) { + return ResponseEntity.status(404).body(Map.of("message", "Incorrect HallID")); + } + System.out.println("hallDetails..." + hallDetails); + + Map concession = hallService.getHallConcessionByHallId(hallId); + System.out.println("concession....." + concession); + + Boolean isSGEObj = (Boolean) hallDetails.get("is_sge"); + Boolean isCGEObj = (Boolean) hallDetails.get("is_cge"); + + boolean isSGE = isSGEObj != null && isSGEObj; + boolean isCGE = isCGEObj != null && isCGEObj; + + double fullDayAmount = toDouble(hallDetails.get("full_day_rent")); + double halfDayAmount = toDouble(hallDetails.get("half_day_rent")); + double depositAmount = toDouble(hallDetails.get("deposit_amount")); + double gstRate = toDouble(hallDetails.get("gst")); + System.out.println("tete"); + System.out.println(depositAmount); + + Map response = new HashMap<>(); + double amount = calculateAmount(numDays, startPeriod, endPeriod, fullDayAmount, halfDayAmount); + double totalDepositAmount = calculateDepositAmount(numDays, startPeriod, endPeriod, depositAmount); + double totalAmount = 0; + double discountAmount = 0; + + response.put("reasonforBooking", reasonforBooking); + + if (!isSGE) { + double gst = round(amount * gstRate / 100.0); + totalAmount = round(amount + gst + totalDepositAmount); + response.put("discount", 0); + response.put("amount", round(amount)); + response.put("totalAmount", totalAmount); + response.put("depositAmount", round(totalDepositAmount)); + response.put("gst", gst); + response.put("discountAmount", round(amount)); + } else if ("SGE".equalsIgnoreCase(reasonforBooking) && concession != null) { + double fullCleaning = toDouble(concession.get("fullday_cleaningcharges")); + double fullPA = toDouble(concession.get("fullday_pasystem")); + double fullEB = toDouble(concession.get("fullday_ebcharges")); + double halfCleaning = toDouble(concession.get("halfday_cleaningcharges")); + double halfPA = toDouble(concession.get("halfday_pasystem")); + double halfEB = toDouble(concession.get("halfday_ebcharges")); + + double fullAdd = fullCleaning + fullPA + fullEB; + double halfAdd = halfCleaning + halfPA + halfEB; + double addCharges = calculateAmount(numDays, startPeriod, endPeriod, fullAdd, halfAdd); + double sgeDiscount = toDouble(hallDetails.get("sge_discount")); + double fullRent = toDouble(concession.get("fulldayhallamount")); + double halfRent = toDouble(concession.get("halfdayhallamount")); + + double gst = round(addCharges * gstRate / 100.0); + totalAmount = round(addCharges + totalDepositAmount + gst); + discountAmount = round((fullRent * sgeDiscount) / 100.0); + + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("fulldayhallAmount", round(fullRent)); + response.put("halfdayhallAmount", round(halfRent)); + response.put("discount", sgeDiscount); + response.put("rentAmount", 0); + response.put("additionalCharges", round(addCharges)); + response.put("netAmount", round(addCharges)); + response.put("gst", gst); + response.put("depositAmount", round(totalDepositAmount)); + response.put("totalAmount", totalAmount); + response.put("discountAmount", discountAmount); + } else if ("CGE".equalsIgnoreCase(reasonforBooking) && concession != null) { + double fullCleaning = toDouble(concession.get("fullday_cleaningcharges")); + double fullPA = toDouble(concession.get("fullday_pasystem")); + double fullEB = toDouble(concession.get("fullday_ebcharges")); + double halfCleaning = toDouble(concession.get("halfday_cleaningcharges")); + double halfPA = toDouble(concession.get("halfday_pasystem")); + double halfEB = toDouble(concession.get("halfday_ebcharges")); + + double fullAdd = fullCleaning + fullPA + fullEB; + double halfAdd = halfCleaning + halfPA + halfEB; + double addCharges = calculateAmount(numDays, startPeriod, endPeriod, fullAdd, halfAdd); + double cgeDiscount = toDouble(hallDetails.get("cge_discount")); + + double rentAmount = round((amount * cgeDiscount) / 100.0); + double netAmount = round(rentAmount + addCharges); + double gst = round(netAmount * gstRate / 100.0); + totalAmount = round(netAmount + gst + totalDepositAmount); + + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("fulldayhallAmount", round(fullDayAmount)); + response.put("halfdayhallAmount", round(halfDayAmount)); + response.put("discount", cgeDiscount); + response.put("rentAmount", rentAmount); + response.put("additionalCharges", round(addCharges)); + response.put("netAmount", netAmount); + response.put("gst", gst); + response.put("depositAmount", round(totalDepositAmount)); + response.put("totalAmount", totalAmount); + response.put("discountAmount", round(discountAmount)); + } else { + double gstValue = round(gstRate * amount / 100.0); + totalAmount = round(amount + gstValue + totalDepositAmount); + response.put("discount", 0); + response.put("amount", round(amount)); + response.put("totalAmount", totalAmount); + response.put("depositAmount", round(totalDepositAmount)); + response.put("gst", gstValue); + response.put("discountAmount", round(amount)); + } + response.put("numDays", numDays); + response.put("startPeriod", startPeriod); + response.put("endPeriod", endPeriod); + response.put("reasonforBooking", reasonforBooking); + response.put("hallId", hallId); + + return ResponseEntity.ok(response); + } + + // Helper to safely convert Object to double + private double toDouble(Object value) { + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + return 0.0; + } + + // Helper to round to 2 decimal places + private double round(double value) { + return Math.round(value * 100.0) / 100.0; + } + + public double calculateAmount(double numDays, String startPeriod, String endPeriod, double fullDayAmount, + double halfDayAmount) { + double amount = 0; + + // If there is only one day + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + amount = halfDayAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + amount = halfDayAmount; + } else { + amount = numDays; + } + } else { + // For multiple days + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount * numDays; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 1) + halfDayAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 1) + halfDayAmount; + } else if ("2".equals(startPeriod) && "1".equals(endPeriod)) { + amount = fullDayAmount * (numDays - 2) + halfDayAmount * 2; + } else { + amount = numDays; + } + } + + return amount; + } + + public double calculateDepositAmount(double numDays, String startPeriod, String endPeriod, double depositAmount) { + double damount = 0; + + // If there is only one day + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount; + } else { + damount = numDays; + } + } else { + // For multiple days + if ("1".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount * numDays; + } else if ("1".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount * (numDays - 1) + depositAmount; + } else if ("2".equals(startPeriod) && "2".equals(endPeriod)) { + damount = depositAmount * (numDays - 1) + depositAmount; + } else if ("2".equals(startPeriod) && "1".equals(endPeriod)) { + damount = depositAmount * (numDays - 2) + depositAmount; + } else { + damount = numDays; + } + } + + return damount; + } + + /* + * @GetMapping("/checkMobileExits") public String checkMobileExits(@RequestParam + * (value = "Mobilenumber", required = false) long Mobilenumber) { + * // @RequestParam(value = "mobileNumber", required = false) Long mobileNumber, + * + * try { + * + * // Validate mobile number has exactly 10 digits String mobileStr = + * String.valueOf(Mobilenumber); if (mobileStr.length() != 10) { return + * "Invalid mobile number. Must be exactly 10 digits."; } return + * !hallService.checkMobileExits(Mobilenumber).isEmpty() ? "Already Registered" + * : "Allow to Register"; } catch (Exception e) { return "error"; } } + */ + @GetMapping("/checkMobileExits") + public ResponseEntity checkMobileExits( + @RequestParam(value = "Mobilenumber", required = false) Long Mobilenumber) { + + if (Mobilenumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + try { + String mobileStr = String.valueOf(Mobilenumber); + if (mobileStr.length() != 10) { + return ResponseEntity.badRequest().body("Invalid mobile number. Must be exactly 10 digits."); + } + + boolean exists = !hallService.checkMobileExits(Mobilenumber).isEmpty(); + return ResponseEntity.ok(exists ? "Already Registered" : "Allow to Register"); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal server error"); + } + } + + // otp + @GetMapping(value = "/sendOTP") + public String sendOtp(HttpServletRequest request, @RequestParam String mobile) { + + // Validate mobile number has exactly 10 digits + if (mobile == null || mobile.trim().isEmpty()) { + return "Mobile number is required."; + } + + String mobileTrimmed = mobile.trim(); + if (mobileTrimmed.length() != 10) { + return "Invalid mobile number. Must be exactly 10 digits."; + } + + String MobileNo = mobile; + System.out.print("\n MobileNo---:" + mobile); + Random rand = new Random(); + int otp = rand.nextInt(90000) + 10000; + +// int otp= 22222; + System.out.print("\n otp---:" + otp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm"); + LocalDateTime now = LocalDateTime.now(); + System.out.println(dtf.format(now)); + + String generatedToken = "Welcome to GCC! Your OTP for GCC Community Centre is " + otp; + String key = "pfTEYN6H"; + String urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + MobileNo + + "&from=GCCCRP&body=OTP for your Victoria Public Hall booking " + otp + + "\r\n- GCC&entityid=1401572690000011081&templateid=1407176491887361640"; + + System.out.print("\n urlString---: " + urlString); + String bodyMessage = ""; + try { + RestTemplate restTemplate = new RestTemplate(); + String Response = restTemplate.getForObject(urlString, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonResponse = (ObjectNode) objectMapper.readTree(Response); + + jsonResponse.put("MobileNo", MobileNo); + jsonResponse.put("otp", otp); + + bodyMessage = jsonResponse.toString(); + System.out.println("\n bodyMessage" + bodyMessage); + + System.out.println("OTP sent successfully!"); + + } catch (Exception e) { + System.out.print("ERROR---: " + e); + bodyMessage = "Error"; + } + HttpSession session = request.getSession(); + session.setAttribute("otp", otp); + return bodyMessage; + + } + + @GetMapping("/verifyEmployee") + public ResponseEntity verifyEmployee(@RequestParam String userType, + @RequestParam(value = "EmployeeID", required = false) String EmployeeID) { + if (EmployeeID == null || EmployeeID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'EmployeeID' parameter"); + } + + if (!"GCC EMPLOYEE".equalsIgnoreCase(userType)) { + return ResponseEntity.badRequest().body("Invalid userType for Employee verification."); + } + + if (EmployeeID == null || EmployeeID.isBlank()) { + return ResponseEntity.badRequest().body("Employee ID is required for GCC EMPLOYEE."); + } + + List> existingEmployeeUsers = hallService.checkEmployeeExits(EmployeeID); + if (existingEmployeeUsers != null && !existingEmployeeUsers.isEmpty()) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Employee number already registered"); + } + + try { + String responseBody = getEmployeeResponse(EmployeeID); + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(responseBody); + boolean resultStatus = rootNode.path("ResultStatus").asBoolean(); + + if (!resultStatus) { + return ResponseEntity.badRequest().body("Invalid employee ID."); + } + + return ResponseEntity.ok(rootNode); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Employee verification failed."); + } + } + + @GetMapping("/verifyPensioner") + public ResponseEntity verifyPensioner(@RequestParam String userType, + @RequestParam(value = "PensionerID", required = false) String PensionerID) { + + if (PensionerID == null || PensionerID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'PensionerID' parameter"); + } + + if (!"GCC PENSIONER".equalsIgnoreCase(userType)) { + return ResponseEntity.badRequest().body("Invalid userType for Pensioner verification."); + } + + if (PensionerID == null || PensionerID.isBlank()) { + return ResponseEntity.badRequest().body("Pensioner ID is required for GCC PENSIONER."); + } + + List> existingEmployeeUsers = hallService.checkPenionerExits(PensionerID); + if (existingEmployeeUsers != null && !existingEmployeeUsers.isEmpty()) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Pensioner number already registered"); + } + + try { + String responseBody = getPensionerResponse(PensionerID); + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(responseBody); + boolean resultStatus = rootNode.path("ResultStatus").asBoolean(); + + if (!resultStatus) { + return ResponseEntity.badRequest().body("Invalid pensioner ID."); + } + + return ResponseEntity.ok(rootNode); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Pensioner verification failed."); + } + } + + @PostMapping("/register") + public ResponseEntity registerUser(@RequestParam(value = "userType", required = false) String userType, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "mobileNumber", required = false) Long mobileNumber, + @RequestParam(value = "aadharNumber", required = false) String aadharNumber, + @RequestParam(required = false) MultipartFile profilePhoto, @RequestParam(required = false) String emailId, + @RequestParam(value = "doorNo", required = false) String doorNo, + @RequestParam(value = "street", required = false) String street, + @RequestParam(value = "area", required = false) String area, + @RequestParam(value = "location", required = false) String location, + @RequestParam(value = "pincode", required = false) String pincode, + @RequestParam(required = false) String PensionerID, + @RequestParam(required = false) String PensionerDepartment, + @RequestParam(required = false) String EmployeeID, + @RequestParam(required = false) String EmployeeDepartment) { + + try { + + if (userType == null || userType.trim().isEmpty()) { + return ResponseEntity.badRequest().body("User type is required."); + } + + if (name == null || name.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Name is required."); + } + + if (mobileNumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + if (aadharNumber == null || aadharNumber.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Aadhar number is required."); + } + + if (doorNo == null || doorNo.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Door number is required."); + } + + if (street == null || street.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Street is required."); + } + + if (area == null || area.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Area is required."); + } + + if (location == null || location.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Location is required."); + } + + if (pincode == null || pincode.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Pincode is required."); + } + + // Additional validations for specific user types + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + if (PensionerID == null || PensionerID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Pensioner ID is required for GCC PENSIONER user type."); + } + if (PensionerID.length() != 6) { + + return ResponseEntity.badRequest().body("Invalid PensionerID. Must be exactly 6 digits.."); + } + if (PensionerDepartment == null || PensionerDepartment.trim().isEmpty()) { + return ResponseEntity.badRequest() + .body("Pensioner Department is required for GCC PENSIONER user type."); + } + } + + if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + if (EmployeeID == null || EmployeeID.trim().isEmpty()) { + return ResponseEntity.badRequest().body("Employee ID is required for GCC EMPLOYEE user type."); + } + if (EmployeeID.length() != 6) { + + return ResponseEntity.badRequest().body("Invalid EmployeeID. Must be exactly 6 digits.."); + } + + if (EmployeeDepartment == null || EmployeeDepartment.trim().isEmpty()) { + return ResponseEntity.badRequest() + .body("Employee Department is required for GCC EMPLOYEE user type."); + } + } + + // Format validations + if (String.valueOf(mobileNumber).length() != 10) { + return ResponseEntity.badRequest().body("Mobile number must be exactly 10 digits."); + } + + if (pincode.length() != 6) { + return ResponseEntity.badRequest().body("Pincode must be exactly 6 digits."); + } + + if (emailId != null && !emailId.isBlank()) { + String emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.com$"; + if (!emailId.matches(emailRegex)) { + return ResponseEntity.badRequest().body("Invalid email ID."); + } + } + + if (aadharNumber.length() != 12) { + return ResponseEntity.badRequest().body("Aadhar number must be exactly 12 digits."); + } + + // Mobile number check only for PUBLIC users + if ("PUBLIC".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkMobileExits(mobileNumber); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Mobile number already registered"); + } + } + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkPenionerExits(PensionerID); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Pensioner number already registered "); + } + } + if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + List> existingUsers = hallService.checkEmployeeExits(EmployeeID); + boolean exists = existingUsers != null && !existingUsers.isEmpty(); + if (exists) { + return ResponseEntity.status(HttpStatus.CONFLICT).body("Employee number already registered"); + } + } + + // Register all user types + hallService.registerUser(userType, name, mobileNumber, aadharNumber, profilePhoto, emailId, doorNo, street, + area, location, pincode, PensionerID, PensionerDepartment, EmployeeID, EmployeeDepartment); + + // return ResponseEntity.ok("Pending."); + // Return different success messages based on user type + String successMessage; + if ("PUBLIC".equalsIgnoreCase(userType)) { + successMessage = "Welcome to GCC, Your User Registration for booking Community Centre is successful."; + } else if ("GCC PENSIONER".equalsIgnoreCase(userType) || "COUNCILLOR".equalsIgnoreCase(userType) + || "GCC EMPLOYEE".equalsIgnoreCase(userType)) { + successMessage = "Welcome to GCC, Your User Registration request for booking Community Centre is submitted successfully."; + } else { + successMessage = "Welcome to GCC, your registration is successful."; + } + return ResponseEntity.ok(successMessage); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Registration failed."); + } + } + + private String getPensionerResponse(String pensionerId) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/external/mobileservice?serviceId=getPensionerDetailsList&pensionerId=" + + pensionerId; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + String responseBody = responseEntity.getBody(); + System.out.println("response.. " + responseBody); + return responseBody; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private String getEmployeeResponse(String employeeId) { + try { + String url = "https://erp.chennaicorporation.gov.in/pgr/external/mobileservice?serviceId=getEmployeeDetail&EmployeeID=" + + employeeId; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + String responseBody = responseEntity.getBody(); + System.out.println("Employee API response: " + responseBody); + return responseBody; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @GetMapping("/verifyCounsellor") + public ResponseEntity checkCounsellorMobileExits( + @RequestParam(value = "mobileNo", required = false) Long mobileNo) {// @RequestParam(value = "mobileNumber", + // required = false) Long mobileNumber, + if (mobileNo == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + String mobileStr = String.valueOf(mobileNo); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + + try { + // Validate input + if (mobileNo == null || mobileNo.toString().trim().isEmpty()) { + return ResponseEntity.badRequest().body("Missing or empty 'mobileNo' parameter."); + } + + // Search for counsellor using mobile1 or mobile2 + List> counsellorList = hallService.findCounsellorByMobile(mobileNo); + + if (counsellorList == null || counsellorList.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Counsellor mobile number not found."); + } + + Map counsellor = counsellorList.get(0); + String mobile1 = String.valueOf(counsellor.get("mobile1")); + String mobile2 = String.valueOf(counsellor.get("mobile2")); + + // Check if either number is already used in Users table + boolean isMobile1Used = !hallService.checkMobileExits(Long.parseLong(mobile1)).isEmpty(); + boolean isMobile2Used = !hallService.checkMobileExits(Long.parseLong(mobile2)).isEmpty(); + + if (isMobile1Used || isMobile2Used) { + return ResponseEntity.status(HttpStatus.CONFLICT) + .body("One of the counsellor's mobile numbers is already used."); + } + + return ResponseEntity.ok(counsellor.get("name").toString()); + + } catch (NumberFormatException e) { + return ResponseEntity.badRequest().body("Invalid mobile number format."); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Mobile number verification failed."); + } + } + + // acknowledgment + /* + * @GetMapping("/acknowledgement") public ResponseEntity> + * getBookingDetails(@RequestParam(value = "bookingId", required = false) int + * bookingId) { Map bookingDetails = + * hallService.getBookingDetailsById(bookingId); return + * ResponseEntity.ok(bookingDetails); } + */ + @GetMapping("/acknowledgement") + public ResponseEntity getBookingDetails(@RequestParam(value = "bookingId", required = false) Integer bookingId) { + if (bookingId == null) { + return ResponseEntity.badRequest().body("Booking ID is required."); + } + + try { + Map bookingDetails = hallService.getBookingDetailsById(bookingId); + + return ResponseEntity.ok(bookingDetails); + + } catch (EmptyResultDataAccessException ex) { + // No booking found + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No booking found for bookingId"); + } catch (Exception e) { + // Any other error + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + //mobile + /* + * @GetMapping("/viewhistory") public ResponseEntity> + * getBookingsByMobile( + * + * @RequestParam("mobileNumber") Long mobileNumber) { + * + * + * Map response = new HashMap<>(); + * + * // Step 1: Check if user exists List> userResult = + * hallService.checkMobileExits(mobileNumber); + * + * if (userResult.isEmpty()) { response.put("status", "NOT_FOUND"); + * response.put("message", "No user found with the given mobile number"); return + * ResponseEntity.ok(response); } + * + * // Step 2: If exists → Call service List> bookings = + * hallService.getBookingsByMobile(mobileNumber); + * + * response.put("status", "SUCCESS"); + * + * response.put("mobile_no", mobileNumber); response.put("bookings", bookings); + * + * return ResponseEntity.ok(response); } + */ + @GetMapping("/viewhistory") + public ResponseEntity getBookingsByMobile( + @RequestParam(value = "mobileNumber", required = false) Long mobileNumber) { + if (mobileNumber == null) { + return ResponseEntity.badRequest().body("Mobile number is required."); + } + + // Check if mobile number is exactly 10 digits + String mobileStr = String.valueOf(mobileNumber); + if (mobileStr.length() != 10) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Mobile number must be exactly 10 digits."); + } + + try { + // Step 1: Check if user exists + List> userResult = hallService.checkMobileExits(mobileNumber); + if (userResult.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No user found with the given mobile number "); + } + + // Step 2: Get bookings + List> bookings = hallService.getBookingsByMobile(mobileNumber); + if (bookings == null || bookings.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("No bookings found for mobile number: " + mobileNumber); + } + + // Success response + Map response = new HashMap<>(); + response.put("status", "SUCCESS"); + response.put("mobile_no", mobileNumber); + response.put("bookings", bookings); + + return ResponseEntity.ok(response); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Internal server error: " + e.getMessage()); + } + } + + @PostMapping(path = "/saveTheRequest2", consumes = {"multipart/form-data"}) + public ResponseEntity saveTheBookingDetails2(HttpServletRequest request) { + try { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map bookingDetails = splitFormData(multipartRequest); + Map saveBookingDetails = hallService.saveBookingDetails(bookingDetails); + + return ResponseEntity.ok(new ApiResponse("success", "Booking details saved successfully", + saveBookingDetails, HttpStatus.OK.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to save booking details " + e.getMessage(), null, + HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + public Map splitFormData(MultipartHttpServletRequest multipartRequest) { + Map formData = new HashMap<>(); + + // Iterate through the request parameters + Enumeration parameterNames = multipartRequest.getParameterNames(); + while (parameterNames.hasMoreElements()) { + String paramName = parameterNames.nextElement(); + String paramValues = multipartRequest.getParameter(paramName); + formData.put(paramName, paramValues); + } + + // Iterate through the request parts (files) + try { + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entry : fileMap.entrySet()) { + MultipartFile file = entry.getValue(); + if (!file.isEmpty()) { + formData.put(entry.getKey(), file); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return formData; + } + + @PostMapping("/payment-request") + public ResponseEntity startPayment(@RequestParam int bookingId) { + try { + Map paymentDetails = hallService.startPayment(bookingId); + + return ResponseEntity.ok(new ApiResponse("success", "Payment request initiated successfully", + paymentDetails, HttpStatus.OK.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ApiResponse("error", "Failed to initiate payment request: " + e.getMessage(), null, + HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @PostMapping("/payment-response") + public ResponseEntity paymentResponse(@RequestParam String orderId, @RequestBody PaymentWebhookPayload payload) { + try { + ResponseEntity result = chPaymentService.processPaymentResponse(orderId, payload); + + return ResponseEntity + .ok(new ApiResponse("success", "Payment processed successfully", result, HttpStatus.OK.value())); + + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return ResponseEntity.badRequest().body(new ApiResponse("error", "Invalid request: " + e.getMessage(), null, + HttpStatus.BAD_REQUEST.value())); + + } catch (EmptyResultDataAccessException e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse("error", + "No payment record found for Order ID: " + orderId, null, HttpStatus.NOT_FOUND.value())); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ApiResponse("error", + "Failed to Process the Payment: " + e.getMessage(), null, HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + } + + @GetMapping("/checkSlot") + public ResponseEntity> checkSlotAvailability( + @RequestParam int hallId, + @RequestParam String startDate, + @RequestParam String endDate, + @RequestParam int startingSlot, // 1 = morning, 2 = evening + @RequestParam int endingSlot // 1 = morning, 2 = evening + ) { + Map result = hallService.checkSlotAvailability(hallId, startDate, endDate, startingSlot, endingSlot); + return ResponseEntity.ok(result); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/PaymentWebhookPayload.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/PaymentWebhookPayload.java new file mode 100644 index 0000000..a5e27bc --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/PaymentWebhookPayload.java @@ -0,0 +1,198 @@ +package com.gcc.restapiservices.victoriaHallBooking.dto; + +import java.math.BigDecimal; + +public class PaymentWebhookPayload { + private String reference_id; + private Currency currency; + private Amount paymentAmount; + private Transaction transaction; + + public String getReference_id() { + return reference_id; + } + + public void setReference_id(String reference_id) { + this.reference_id = reference_id; + } + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public Amount getPaymentAmount() { + return paymentAmount; + } + + public void setPaymentAmount(Amount paymentAmount) { + this.paymentAmount = paymentAmount; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + public static class Currency { + private String reference_id; + private Amount amount; + private String currency; + private Transaction transaction; + + public String getReference_id() { + return reference_id; + } + + public void setReference_id(String reference_id) { + this.reference_id = reference_id; + } + + public Amount getAmount() { + return amount; + } + + public void setAmount(Amount amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + } + + public static class Amount { + private double value; + private double offset; + + public double getValue() { + return value; + } + + public void setValue(double value) { + this.value = value; + } + + public double getOffset() { + return offset; + } + + public void setOffset(double offset) { + this.offset = offset; + } + } + + public static class Transaction { + private String id; + private String pg_transaction_id; + private String type; + private String status; + private long created_timestamp; + private long updated_timestamp; + private Amount amount; + private String currency; + private Method method; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPg_transaction_id() { + return pg_transaction_id; + } + + public void setPg_transaction_id(String pg_transaction_id) { + this.pg_transaction_id = pg_transaction_id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public long getCreated_timestamp() { + return created_timestamp; + } + + public void setCreated_timestamp(long created_timestamp) { + this.created_timestamp = created_timestamp; + } + + public long getUpdated_timestamp() { + return updated_timestamp; + } + + public void setUpdated_timestamp(long updated_timestamp) { + this.updated_timestamp = updated_timestamp; + } + + public Amount getAmount() { + return amount; + } + + public void setAmount(Amount amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + } + + public static class Method { + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionData.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionData.java new file mode 100644 index 0000000..44088ca --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionData.java @@ -0,0 +1,83 @@ +package com.gcc.restapiservices.victoriaHallBooking.dto; + +public class TransactionData { + private Merchant merchant = new Merchant(); + private Transaction transaction = new Transaction(); + + public Merchant getMerchant() { + return merchant; + } + + public Transaction getTransaction() { + return transaction; + } + + public static class Merchant { + private String identifier; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + } + + public static class Transaction { + private String amount; + private String identifier; + private String dateTime; + private String requestType; + private String token; + private String reference; + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public String getRequestType() { + return requestType; + } + + public void setRequestType(String requestType) { + this.requestType = requestType; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getReference() { + return reference; + } + + public void setReference(String reference) { + this.reference = reference; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionRefundResponse.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionRefundResponse.java new file mode 100644 index 0000000..461c487 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/dto/TransactionRefundResponse.java @@ -0,0 +1,73 @@ +package com.gcc.restapiservices.victoriaHallBooking.dto; + +public class TransactionRefundResponse { + private String merchantTransactionIdentifier; + private PaymentMethod paymentMethod; + + public String getMerchantTransactionIdentifier() { + return merchantTransactionIdentifier; + } + + public void setMerchantTransactionIdentifier(String merchantTransactionIdentifier) { + this.merchantTransactionIdentifier = merchantTransactionIdentifier; + } + + public PaymentMethod getPaymentMethod() { + return paymentMethod; + } + + public void setPaymentMethod(PaymentMethod paymentMethod) { + this.paymentMethod = paymentMethod; + } + + public static class PaymentMethod { + private PaymentTransaction paymentTransaction; + + public PaymentTransaction getPaymentTransaction() { + return paymentTransaction; + } + + public void setPaymentTransaction(PaymentTransaction paymentTransaction) { + this.paymentTransaction = paymentTransaction; + } + } + + public static class PaymentTransaction { + private String statusCode; + private String amount; + private String balanceAmount; + private String refundIdentifier; + + public String getStatusCode() { + return statusCode; + } + + public void setStatusCode(String statusCode) { + this.statusCode = statusCode; + } + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getBalanceAmount() { + return balanceAmount; + } + + public void setBalanceAmount(String balanceAmount) { + this.balanceAmount = balanceAmount; + } + + public String getRefundIdentifier() { + return refundIdentifier; + } + + public void setRefundIdentifier(String refundIdentifier) { + this.refundIdentifier = refundIdentifier; + } + } +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/VPHPaymentService.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/VPHPaymentService.java new file mode 100644 index 0000000..92bf4f2 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/VPHPaymentService.java @@ -0,0 +1,536 @@ +package com.gcc.restapiservices.victoriaHallBooking.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gcc.restapiservices.victoriaHallBooking.configuration.VPHPaymentConfig; +import com.gcc.restapiservices.victoriaHallBooking.dto.PaymentWebhookPayload; +import com.gcc.restapiservices.victoriaHallBooking.dto.TransactionData; +import com.gcc.restapiservices.victoriaHallBooking.dto.TransactionRefundResponse; +import com.gcc.restapiservices.victoriaHallBooking.util.VPHEncryptionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.client.RestTemplate; +import java.util.HashMap; + +import javax.sql.DataSource; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Service +public class VPHPaymentService { + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private VPHPaymentConfig paymentConfig; + + @Autowired + private WhatsappMsgService whatsappMsgServiceImpl; + + @Autowired + private VPHEncryptionUtils encryptionUtils; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public void setDataSource(@Qualifier("mysqlCommunityHallDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Transactional("mysqlCommunityHallTransactionManager") + public ResponseEntity processPaymentResponse( + @RequestParam String OrderId, + @RequestBody PaymentWebhookPayload payload) throws Exception { + + Map result = new HashMap<>(); + + String transactionId = OrderId; + String pgTxnId = payload.getTransaction().getPg_transaction_id(); + String status = payload.getTransaction().getStatus(); + double amount = payload.getTransaction().getAmount().getValue() / 100.0; + String dateTime = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") + .withZone(ZoneId.of("Asia/Kolkata")) + .format(Instant.ofEpochSecond(payload.getTransaction().getCreated_timestamp())); + + Map txn; + try { + txn = jdbcTemplate.queryForMap( + "SELECT * FROM transaction_response WHERE txansaction_id = ? AND status_code ='temp' ", + transactionId); + } catch (EmptyResultDataAccessException e) { + result.put("status", "error"); + result.put("message", "Transaction not found or already processed."); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); + } + + int bookingId = (int) txn.get("booking_id"); + int hallId = (int) txn.get("hall_id"); + String userId = (String) txn.get("user_id"); + + jdbcTemplate.update( + "UPDATE transaction_response SET tpsl_txn_id = ?, amount = ?, date = ?, status_code = ?, response = ?, " + + + "booking_id = ?, hall_id = ?, user_id = ? WHERE txansaction_id = ?", + pgTxnId, String.valueOf(amount), dateTime, status, + objectMapper.writeValueAsString(payload), bookingId, hallId, userId, transactionId); + + Map booking; + try { + booking = jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?", bookingId); + } catch (EmptyResultDataAccessException e) { + result.put("status", "error"); + result.put("message", "Booking not found."); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result); + } + + double expectedAmount = booking.get("amount_received") != null + ? ((Number) booking.get("amount_received")).doubleValue() + : 0.0; + + jdbcTemplate.update("INSERT INTO payments " + + " (transaction_id, amount_received, payment_status, cdate, booking_details_booking_id) " + + " VALUES (?, ?, ?, ?, ?)", transactionId, amount, "Not Completed", new Date(), + bookingId); + + if (expectedAmount != amount) { + updatePaymentStatus(transactionId, "Failed"); + // bookingFailure(bookingId, 1); + result.put("status", "error"); + result.put("message", "Amount mismatch. Payment failed."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + if ("success".equalsIgnoreCase(status)) { + updatePaymentStatus(transactionId, "Success"); + confirmBooking(bookingId); + + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + + bookingId; + result.put("status", "success"); + result.put("message", "Payment processed successfully."); + result.put("acknowledgement_url", acknowledgementUrl); + return ResponseEntity.ok(result); + } else { + updatePaymentStatus(transactionId, "Failed"); + result.put("status", "error"); + result.put("message", "Payment failed."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + } + + public void updatePaymentStatus(String transactionId, String status) { + jdbcTemplate.update("UPDATE payments SET payment_status = ? WHERE transaction_id = ?", status, transactionId); + } + + @Transactional(value = "mysqlCommunityHallTransactionManager", propagation = Propagation.REQUIRES_NEW) + public void bookingFailure(int bookingId, int flag) { + String comment = flag == 1 ? "Booking Not Confirmed" + : "Slot occupied by other user, Amount paid will be refunded."; + jdbcTemplate.update("UPDATE booking_details SET booking_status = 'REFUNDED', comments = ? WHERE booking_id = ?", + comment, bookingId); + /* + * String refundStatus = booking.get("refund_status").toString(); + * if (!("COMPLETED".equalsIgnoreCase(refundStatus)) && + * !("CLOSED".equalsIgnoreCase(refundStatus))) { + * refundTheAmount(bookingId, Integer.parseInt(userId)); + * } + */ + } + + @Transactional("mysqlCommunityHallTransactionManager") + public String confirmBooking(int bookingId) { + Map booking = jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?", + bookingId); + try { + int hallId = (int) booking.get("hall_details_hall_id"); + LocalDate startDate = LocalDate.parse((String) booking.get("start_date")); + LocalDate endDate = LocalDate.parse((String) booking.get("end_date")); + int startSlot = (int) booking.get("starting_slot"); + int endSlot = (int) booking.get("ending_slot"); + double noOfDays = booking.get("no_of_days") != null ? (double) booking.get("no_of_days") : 1.0; + + // int i = 0; + // for (LocalDate date = startDate; !date.isAfter(endDate); date = + // date.plusDays(1)) { + // String checkSql = "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id + // = ?"; + // List> existing = jdbcTemplate.queryForList(checkSql, + // date, hallId); + + // if (!existing.isEmpty()) { + // Map cal = existing.get(0); + // if ((boolean) cal.get("is_blocked")) throw new RuntimeException("GCC Blocked + // Date"); + // boolean morningBooked = (boolean) cal.get("morning_slot"); + // boolean eveningBooked = (boolean) cal.get("evening_slot"); + // if ((date.equals(startDate) && startSlot == 1 && morningBooked) || + // (date.equals(startDate) && startSlot == 2 && eveningBooked) || + // (date.equals(endDate) && endSlot == 1 && morningBooked) || + // (date.equals(endDate) && endSlot == 2 && eveningBooked)) { + // throw new RuntimeException("Slot already booked or partially occupied"); + // } + // updateCalendarWithBooking(date, bookingId, hallId, startDate, endDate, + // startSlot, endSlot, i); + // } else { + // insertCalendarWithBooking(date, bookingId, hallId, startDate, endDate, + // startSlot, endSlot, i); + // } + // i++; + // } + + int i = 0; + for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { + + String checkSql = "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?"; + List> existing = jdbcTemplate.queryForList(checkSql, date, hallId); + + if (!existing.isEmpty()) { + Map cal = existing.get(0); + if ((boolean) cal.get("is_blocked")) + throw new RuntimeException("GCC Blocked Date"); + + boolean morningBooked = (boolean) cal.get("morning_slot"); + boolean eveningBooked = (boolean) cal.get("evening_slot"); + int isBooked = (int) cal.get("is_booked"); + String bookingId1 = (String) cal.get("booking_id_1"); + String bookingId2 = (String) cal.get("booking_id_2"); + + // ====== Validation ====== + if ((date.equals(startDate) && startSlot == 1 && morningBooked) || + (date.equals(startDate) && startSlot == 2 && eveningBooked) || + (date.equals(endDate) && endSlot == 1 && morningBooked) || + (date.equals(endDate) && endSlot == 2 && eveningBooked) || + (morningBooked && eveningBooked)) { + throw new RuntimeException("Slot already booked or partially occupied"); + } + + // ====== Update slots ====== + if (date.equals(startDate)) { + if (startSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + if (!date.equals(endDate) || (startDate.equals(endDate) && endSlot == 2)) { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else if (date.equals(endDate)) { + if (endSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + if (endSlot == 2) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } + } + } else { + morningBooked = true; + eveningBooked = true; + bookingId1 = String.valueOf(bookingId); + bookingId2 = String.valueOf(bookingId); + isBooked += 2; + } + + // ====== Run UPDATE ====== + String updateSql = "UPDATE booking_calendar " + + "SET morning_slot=?, evening_slot=?, is_booked=?, booking_id_1=?, booking_id_2=? " + + "WHERE bdate=? AND hall_id=?"; + jdbcTemplate.update(updateSql, + morningBooked, eveningBooked, isBooked, bookingId1, bookingId2, + date, hallId); + + } else { + // ====== Insert new row ====== + boolean morningBooked = false; + boolean eveningBooked = false; + boolean isDelete = false; + boolean isBlocked = false; + int isBooked = 0; + String bookingId1 = null, bookingId2 = null; + + if (date.equals(startDate)) { + if (startSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + if (!date.equals(endDate) || (startDate.equals(endDate) && endSlot == 2)) { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + } + } else if (date.equals(endDate)) { + if (endSlot == 1) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } else { + eveningBooked = true; + bookingId2 = String.valueOf(bookingId); + isBooked++; + if (endSlot == 2) { + morningBooked = true; + bookingId1 = String.valueOf(bookingId); + isBooked++; + } + } + } else { + morningBooked = true; + eveningBooked = true; + bookingId1 = String.valueOf(bookingId); + bookingId2 = String.valueOf(bookingId); + isBooked += 2; + } + + String uniqueId = date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId; + + System.out.println("uniqueId...."+uniqueId+"\n hallId: "+hallId+"\n morningBooked: "+morningBooked+ + "\n eveningBooked: "+eveningBooked+"\n isBooked: "+isBooked+"\n bookingId1: "+bookingId1+"\n bookingId2: "+bookingId2); + + String insertSql = "INSERT INTO booking_calendar " + + "(bdate, hall_id, morning_slot, evening_slot, is_booked, booking_id_1, booking_id_2, is_active, unique_id, is_delete, is_blocked) " + +"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertSql,date, hallId, morningBooked, eveningBooked, isBooked,bookingId1, bookingId2, true, uniqueId, isDelete, isBlocked); + } + i++; + } + + String reason = (String) booking.get("reason"); + String reasonCode = fetchReasonCode(reason); + + String status = "APPROVED"; + String comments = "Booking Confirmed Successfully"; + if (reasonCode != null && !reasonCode.trim().isEmpty()) { + if (List.of("CGE", "CAO", "SGE").contains(reasonCode)) { + status = "WAITING_FOR_NOC"; + comments = "Waiting For NOC Documents"; + } + } + + jdbcTemplate.update("UPDATE booking_details SET booking_status = ?, comments = ? WHERE booking_id = ?", + status, comments, bookingId); + + sendConfirmationMessages(bookingId, booking); + return comments; + } catch (Exception e) { + e.printStackTrace(); + // bookingFailure(bookingId, 2); + return "redirect:/communityhall/user/acknowledgement?bookingId=" + bookingId; + } + } + + private void updateCalendarWithBooking(LocalDate date, int bookingId, int hallId, LocalDate startDate, + LocalDate endDate, int startSlot, int endSlot, int i) { + String updateSql = "UPDATE booking_calendar SET morning_slot = ?, evening_slot = ?, booking_id_1 = ?, booking_id_2 = ?, is_booked = is_booked + ? WHERE bdate = ? AND hall_id = ?"; + boolean isMorning = true; + boolean isEvening = true; + int increment = 2; + jdbcTemplate.update(updateSql, isMorning, isEvening, bookingId, bookingId, increment, date, hallId); + } + + private void insertCalendarWithBooking(LocalDate date, int bookingId, int hallId, LocalDate startDate, + LocalDate endDate, int startSlot, int endSlot, int i) { + String uniqueId = date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId; + String insertSql = "INSERT INTO booking_calendar (bdate, hall_id, is_active, is_booked, is_delete, morning_slot, evening_slot, booking_id_1, booking_id_2, is_blocked, unique_id) VALUES (?, ?, true, ?, false, ?, ?, ?, ?, false, ?)"; + jdbcTemplate.update(insertSql, date, hallId, 2, true, true, bookingId, bookingId, uniqueId); + } + + private String fetchReasonCode(String reason) { + try { + String sql = "SELECT reasoncode FROM reason_master WHERE reason = ?"; + return jdbcTemplate.queryForObject(sql, String.class, reason); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + + private String sendConfirmationMessages(int bookingId, Map booking) { + System.out.println("confirmation message calling.."); + try { + String bookingconfirmationmsg, urlString, whatsupmsg; + String reason = booking.get("reason").toString(); + String reasonCode = fetchReasonCode(reason); + String bookingDate = booking.get("booking_date").toString(); + String startDate = booking.get("start_date").toString(); + + int userId = Integer.parseInt(booking.get("users_user_id").toString()); + + Map userData = jdbcTemplate.queryForMap("SELECT * FROM users WHERE user_id = ? ", userId); + String userMobNo = userData.get("mobile_no").toString(); + + if (reasonCode != null && !reasonCode.trim().isEmpty()) { + if (reasonCode.equals("CGE") || reasonCode.equals("CAO") || reasonCode.equals("SGE")) { + + updateBookingStatus(bookingId, "WAITING_FOR_NOC", "Waiting For NOC Documents"); + + bookingconfirmationmsg = "Your booking ID " + bookingId + " on " + bookingDate + + " has been confirmed successfully. Thanks for using GCC Community Hall Booking System."; + + urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + userMobNo + + "&from=GCCCRP&body=" + bookingconfirmationmsg + + "&entityid=1401572690000011081&templateid=1407172346459428987"; + + whatsupmsg = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + +userMobNo + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+booking+with+ID+" + +bookingId + "+on+" + bookingDate+ "+has+been+successfully+confirmed.+%0AThanks+for+using+GCC+Community+Hall+Booking+System."; + + whatsappMsgServiceImpl.sendMsg(whatsupmsg); + whatsappMsgServiceImpl.sendSMS(urlString); + return "Waiting For NOC Documents"; + + } else { + updateBookingStatus(bookingId, "APPROVED", "Booking Confirmed Successfully"); + + bookingconfirmationmsg = "Your booking ID " + bookingId + " on " + startDate + + " has been confirmed successfully. Thanks for using GCC Community Hall Booking System."; + + urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + userMobNo + + "&from=GCCCRP&body=" + bookingconfirmationmsg + + "&entityid=1401572690000011081&templateid=1407172346459428987"; + + whatsupmsg = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + + + userMobNo + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+booking+with+ID+" + + + bookingId + "+on+" + startDate + + "+has+been+successfully+confirmed.+%0AThanks+for+using+GCC+Community+Hall+Booking+System."; + + whatsappMsgServiceImpl.sendMsg(whatsupmsg); + whatsappMsgServiceImpl.sendSMS(urlString); + return "Booking confirmed successfully"; + } + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + return "Incorrect booking data"; + } + + /* + * public String refundTheAmount(int bookingId, int userId) { + * try { + * + * // get mobile no using userId --> need to add + * Map txn = jdbcTemplate. + * queryForMap("SELECT * FROM transaction_response WHERE booking_id = ? AND status_code = ? ORDER BY id DESC LIMIT 1" + * , bookingId, paymentConfig.getTransactionSuccessCode()); + * String amount = (String) txn.get("amount"); + * String txnDate = ((String) txn.get("date")).split(" ")[0]; + * String tpslTxnId = (String) txn.get("tpsl_txn_id"); + * + * TransactionData payload = new TransactionData(); + * payload.getMerchant().setIdentifier(paymentConfig.getMerchantId()); + * payload.getTransaction().setAmount(amount); + * payload.getTransaction().setIdentifier(""); + * payload.getTransaction().setDateTime(txnDate); + * payload.getTransaction().setRequestType("R"); + * payload.getTransaction().setToken(""); + * payload.getTransaction().setReference(tpslTxnId); + * + * String json = objectMapper.writeValueAsString(payload); + * String encrypted = encryptionUtils.encryptHxRefund(json); + * + * String url = "https://www.tpsl-india.in/PaymentGateway/merchant2.pg/" + + * paymentConfig.getMerchantId(); + * ResponseEntity response = new RestTemplate().postForEntity(url, + * encrypted, String.class); + * String decrypted = encryptionUtils.decryptHxTRefund(response.getBody()); + * + * TransactionRefundResponse refundRes = objectMapper.readValue(decrypted, + * TransactionRefundResponse.class); + * String refundStatusCode = + * refundRes.getPaymentMethod().getPaymentTransaction().getStatusCode(); + * String refundTxnId = refundRes.getMerchantTransactionIdentifier(); + * String refundIdentifier = + * refundRes.getPaymentMethod().getPaymentTransaction().getRefundIdentifier(); + * String refundedAmount = + * refundRes.getPaymentMethod().getPaymentTransaction().getAmount(); + * String balanceAmount = + * refundRes.getPaymentMethod().getPaymentTransaction().getBalanceAmount(); + * + * jdbcTemplate. + * update("INSERT INTO refund_response (booking_id, user_id, response, status_code, txansaction_id, amount, balace_amount, date) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" + * , bookingId, userId, decrypted, refundStatusCode, refundTxnId, + * refundedAmount, balanceAmount, LocalDate.now()); + * + * Map booking = + * jdbcTemplate.queryForMap("SELECT * FROM booking_details WHERE booking_id = ?" + * , bookingId); + * + * jdbcTemplate. + * update("INSERT INTO refund_transaction (amount_refunded, cdate, booking_details_booking_id, refund_identifier, refund_status, transaction_id) VALUES (?, ?, ?, ?, ?, ?)" + * , Double.parseDouble(refundedAmount), new Date(), bookingId, + * refundIdentifier, refundStatusCode, refundTxnId); + * + * if (refundStatusCode.equals(paymentConfig.getRefundSuccessCode())) { + * jdbcTemplate. + * update("UPDATE booking_details SET refund_status = 'COMPLETED' WHERE booking_id = ?" + * , bookingId); + * + * long mobile = (long) booking.get("users_user_id"); + * double amt = Double.parseDouble(refundedAmount); + * whatsappMsgServiceImpl.sendSMS(buildSMSUrl(mobile, amt, bookingId)); + * whatsappMsgServiceImpl.sendMsg(buildWhatsAppUrl(mobile, amt, bookingId)); + * return "Refunded"; + * } + * + * return "Error"; + * } catch (Exception e) { + * e.printStackTrace(); + * return "error"; + * } + * } + */ + + private String buildSMSUrl(long mobile, double amt, int bookingId) { + return "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + mobile + + "&from=GCCCRP&body=Your refund amount of Rs. " + amt + " for Booking ID " + bookingId + + " has been initiated."; + } + + private String buildWhatsAppUrl(long mobile, double amt, int bookingId) { + return "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" + mobile + + "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+refund+of+Rs.+" + amt + + "+for+Booking+ID+" + bookingId + "+has+been+initiated."; + } + + public void updateBookingStatus(int bookingId, String bookingStatus, String comments) { + String updateSql = "update booking_details set booking_status =?, comments= ? WHERE booking_id = ?"; + jdbcTemplate.update(updateSql, bookingStatus, comments, bookingId); + } + +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/WhatsappMsgService.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/WhatsappMsgService.java new file mode 100644 index 0000000..8e27b10 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/WhatsappMsgService.java @@ -0,0 +1,41 @@ +package com.gcc.restapiservices.victoriaHallBooking.service; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.net.HttpURLConnection; +import java.net.URL; + +@Service +public class WhatsappMsgService { + + public String sendMsg(String msgUrl) { + System.out.println("Whatsapp URL :-" + msgUrl); + + String response = ""; + try { + HttpURLConnection connection = null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public String sendSMS(String SMS_Url) { + System.out.println("SMS URL:- " + SMS_Url); + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(SMS_Url, String.class); + return response; + } +} + diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/victoriaHallService.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/victoriaHallService.java new file mode 100644 index 0000000..554c9d4 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/service/victoriaHallService.java @@ -0,0 +1,849 @@ + +package com.gcc.restapiservices.victoriaHallBooking.service; + +import com.gcc.restapiservices.victoriaHallBooking.configuration.VPHPaymentConfig; +import com.gcc.restapiservices.victoriaHallBooking.util.VPHTransactionNumberGenerator; +import com.gcc.restapiservices.configuration.AppConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +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.web.bind.annotation.RequestParam; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Random; + +import com.gcc.restapiservices.configuration.AppConfig; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + +@Service + +public class victoriaHallService { + private JdbcTemplate jdbcTemplate; + @Autowired + private AppConfig appConfig; + @Autowired + private Environment environment; + + @Autowired + private VPHPaymentConfig paymentConfig; + + @Autowired + private VPHTransactionNumberGenerator transactionNumberGenerator; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Value("${file.upload.directory.victoriahall}") + private String uploadDirectory; + + @Value("${file.fullpath.victoriahall}") + private String serverPath; + + @Autowired + public void setDataSource(@Qualifier("mysqlVictoriaHallDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + public List> getHallList() { + return jdbcTemplate.queryForList("SELECT * FROM hall_details WHERE is_active = 1 order by hall_name asc"); + } + + public List> getReasonMaster() { + String sql = "SELECT reason_id,reason,maxdays,reasoncode FROM reason_master"; + return jdbcTemplate.queryForList(sql); + } + + public List> getDocumentsByReasonId(Long reasonId) { + String sql = "SELECT doc_field_name,field_name FROM reason_document_master WHERE reason_id = ?"; + return jdbcTemplate.queryForList(sql, reasonId); + } + + public List> getRelationTypesAsMap() { + List> relationList = new ArrayList<>(); + + String[] relations = {"Self"}; + + for (String rel : relations) { + Map map = new HashMap<>(); + map.put("relation_name", rel); + map.put("value", rel); + relationList.add(map); + } + + return relationList; + } + + public List> getUserDetails(Long Mobilenumber) { + String sql = "SELECT name,email,mobile_no,doorno,area,location,pin_code,user_status,usertype,profilephoto FROM users WHERE mobile_no = ?"; + return jdbcTemplate.queryForList(sql, Mobilenumber); + } + + public Map getHallDetailsById(int hallId) { + String sql = "SELECT * FROM hall_details WHERE hall_id = ?"; + List> result = jdbcTemplate.queryForList(sql, hallId); + + if (result.isEmpty()) { + return null; // or Collections.emptyMap() if you prefer + } + + return result.get(0); + } + + public Map getHallConcessionByHallId(int hallId) { + String sql = "SELECT * FROM hall_details_concession WHERE hall_id = ?"; + List> result = jdbcTemplate.queryForList(sql, hallId); + + if (result.isEmpty()) { + return null; // or Collections.emptyMap() + } + + return result.get(0); // ✅ safe return of first result + } + + public List> checkMobileExits(Long Mobilenumber) { + String sql = "SELECT * FROM users WHERE mobile_no = ?"; + return jdbcTemplate.queryForList(sql, Mobilenumber); + } + + public List> checkEmployeeExits(String EmployeeID) { + String sql = "SELECT * FROM users WHERE government_id= ?"; + return jdbcTemplate.queryForList(sql, EmployeeID); + } + + /* + * public Map getBookingDetailsById(int bookingId) { String sql + * = "SELECT " + + * "bd.booking_id, bd.booking_date, bd.start_date, bd.end_date, bd.comments, bd.booking_status, " + * + + * "bd.starting_slot, bd.ending_slot, bd.no_of_days, bd.reason, bd.gst, bd.deposit_amount, " + * + "bd.hall_amount, bd.amount_received AS booking_amount_received, " + + * "u.name, u.usertype, u.mobile_no, u.email, " + + * "hd.zone, hd.division, hd.hall_incharge_name, hd.hall_incharge_no, hd.hall_name, " + * + "CONCAT_WS(', ', hd.street, hd.area, hd.pin_code) AS address, " + + * "p.transaction_id, p.payment_status, p.amount_received AS payment_amount_received " + * + "FROM booking_details bd " + + * "INNER JOIN users u ON bd.users_user_id = u.user_id " + + * "INNER JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + + * "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + + * "WHERE bd.booking_id = ?"; + * + * return jdbcTemplate.queryForMap(sql, bookingId); } + */ + public Map getBookingDetailsById(int bookingId) { + String sql = "SELECT " + + "bd.booking_id, DATE_FORMAT(bd.booking_date, '%d-%m-%Y') AS booking_date, " + + " DATE_FORMAT(bd.start_date, '%d-%m-%Y') AS start_date, " + + " DATE_FORMAT(bd.end_date, '%d-%m-%Y') AS end_date, " + + " bd.comments, bd.booking_status, " + + "bd.starting_slot, bd.ending_slot, bd.no_of_days, bd.reason, bd.gst, bd.deposit_amount, " + + "bd.hall_amount, bd.amount_received AS total_amount, " + "u.name, u.usertype, u.mobile_no, u.email, " + + "hd.zone, hd.division, hd.hall_incharge_name as caretaker_name, hd.hall_incharge_no as caretaker_mobileno, hd.hall_name, " + + "CONCAT_WS(', ', hd.street, hd.area, hd.pin_code) AS hall_address, " + + "p.transaction_id, p.payment_status, p.amount_received AS payment_amount_received " + + "FROM booking_details bd " + "INNER JOIN users u ON bd.users_user_id = u.user_id " + + "INNER JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + + "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + "WHERE bd.booking_id = ?"; + + Map result = jdbcTemplate.queryForMap(sql, bookingId); + + // Add the acknowledgement URL to the result + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + bookingId; + result.put("acknowledgement_url", acknowledgementUrl); + + return result; + } + + public List> getBookingsByMobile(Long mobileNumber) { + String sql = "SELECT bd.booking_id , DATE_FORMAT(bd.booking_date, '%d-%m-%Y') AS booking_date," + + " DATE_FORMAT(bd.start_date, '%d-%m-%Y') AS start_date," + + " DATE_FORMAT(bd.end_date, '%d-%m-%Y') AS end_date, " + + "bd.starting_slot, bd.ending_slot, bd.reason, bd.booking_status, " + + "p.payment_status AS payment_status " + "FROM booking_details bd " + + "INNER JOIN users u ON bd.users_user_id = u.user_id " + + "INNER JOIN payments p ON bd.booking_id = p.booking_details_booking_id " + + "WHERE u.mobile_no = ? " + "AND bd.booking_status NOT IN ('PENDING')"; + + List> bookings = jdbcTemplate.queryForList(sql, mobileNumber); + + // Add acknowledgement URL to each booking + for (Map booking : bookings) { + Object bookingId = booking.get("booking_id"); + if (bookingId != null) { + String acknowledgementUrl = "https://gccservices.chennaicorporation.gov.in/communityhall/user/acknowledgement?bookingId=" + + bookingId; + booking.put("acknowledgement_url", acknowledgementUrl); + } + } + + return bookings; + } + + public List> checkPenionerExits(String PensionerID) { + String sql = "SELECT * FROM users WHERE government_id= ?"; + return jdbcTemplate.queryForList(sql, PensionerID); + } + + // + public List> findCounsellorByMobile(long mobileNo) { + String sql = "SELECT * FROM counsellor_details WHERE mobile1 = ? OR mobile2 = ?"; + return jdbcTemplate.queryForList(sql, mobileNo, mobileNo); + } + + public void registerUser(String userType, String name, long mobileNumber, String aadharNumber, + MultipartFile profilePhoto, String emailId, String doorNo, String street, String area, String location, + String pincode, String pensionerID, String pensionerDepartment, String employeeID, + String employeeDepartment) throws IOException { + + String uploadPhotoUrl = null; + if (profilePhoto != null && !profilePhoto.isEmpty()) { + uploadPhotoUrl = saveFile(profilePhoto); + } + + // Default values for government_id and department + String governmentId = null; + String department = null; + + String userstatus = "APPROVED"; + + // Logic for conditional insertion based on userType + if ("GCC PENSIONER".equalsIgnoreCase(userType)) { + + governmentId = pensionerID; + department = pensionerDepartment; + userstatus = "PENDING"; + } else if ("GCC EMPLOYEE".equalsIgnoreCase(userType)) { + governmentId = employeeID; + department = employeeDepartment; + userstatus = "PENDING"; + } + + String sql = "INSERT INTO users (usertype, name, mobile_no, aadhar_number, profilephoto, email, " + + "doorno, street, area, location, pin_code, government_id, department,user_status) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)"; + + jdbcTemplate.update(sql, userType, name, mobileNumber, aadharNumber, uploadPhotoUrl, emailId, doorNo, street, + area, location, pincode, governmentId, department, userstatus); + } + + public String saveFile(MultipartFile file) throws IOException { + String order_copy_url = ""; + + // Handle file upload if a file is provided + if (file == null || file.isEmpty()) { + return order_copy_url; + } + + // Get the base upload directory from properties + String uploadDirectory = environment.getProperty("file.upload.directory"); // e.g., /opt/myapp/uploads + + // Define the subdirectory structure + String serviceFolderName = "images/userPhoto"; // You can also get from properties if needed + + // Build the full folder path + String fullUploadPath = uploadDirectory + File.separator + serviceFolderName; + Path directoryPath = Paths.get(fullUploadPath); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Generate unique file name + // String datetimetxt = DateTimeUtil.getCurrentDateTime(); + String fileName = generateRandomStringForFile(10) + "_" + file.getOriginalFilename(); + + // Physical file path + Path filePath = directoryPath.resolve(fileName); + + // Write the file to the physical path + Files.write(filePath, file.getBytes()); + + // Relative path for storing in DB + String filepath_txt = "/" + serviceFolderName + "/" + fileName; + + return filepath_txt; + } + + public static String generateRandomStringForFile(int String_Lenth) { + StringBuilder result = new StringBuilder(String_Lenth); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + + } + + @Transactional("mysqlVictoriaHallTransactionManager") + public Map saveBookingDetails(Map formData) { + Map hs = new HashMap<>(); + + Map userMaster = jdbcTemplate.queryForMap("SELECT * FROM users WHERE mobile_no = ?", + (formData.get("mobNo").toString())); + + Integer userId = (Integer) userMaster.get("user_id"); + + Map reasonMaster = jdbcTemplate.queryForMap("SELECT * FROM reason_master WHERE reason_id = ?", + Integer.parseInt(formData.get("reasonId").toString())); + + Map hallDetails = jdbcTemplate.queryForMap("SELECT * FROM hall_details WHERE hall_id = ?", + Integer.parseInt(formData.get("hallId").toString())); + + // Fetch User + Map user = jdbcTemplate.queryForMap("SELECT * FROM users WHERE user_id = ?", userId); + + String bookingId = formData.get("bookingId").toString(); + Map bookingDetails = null; + + if (bookingId != null && bookingId.equals("0")) { + } else { + List> bookings = jdbcTemplate + .queryForList("SELECT * FROM booking_details WHERE booking_id = ?", Integer.parseInt(bookingId)); + if (!bookings.isEmpty()) { + bookingDetails = bookings.get(0); + jdbcTemplate.update("DELETE FROM booking_documents WHERE booking_id = ?", Integer.parseInt(bookingId)); + } + } + + if (user != null) { + String startDate = formData.get("startDate").toString(); + String endDate = formData.get("endDate").toString(); + String relation = formData.get("relation").toString(); + double days = Double.parseDouble(formData.get("days").toString()); + int daysrange = Integer.parseInt(formData.get("daysrange").toString()); + String usertype = user.get("usertype").toString(); + String reason = reasonMaster.get("reason").toString(); + int startingSlot = Integer.parseInt(formData.get("startingSlot").toString()); + int endingSlot = Integer.parseInt(formData.get("endingSlot").toString()); + String startingSlot_txt = formData.get("startingSlot").toString(); + String endingSlot_txt = formData.get("endingSlot").toString(); + + Map discountrange = jdbcTemplate + .queryForMap("SELECT * FROM discount_range WHERE usertype = ?", usertype); + float discount = Float.parseFloat(discountrange.get("discount_range").toString()); + + double hallAmount = calcHallAmountJdbc(hallDetails, daysrange, startingSlot, endingSlot); + hs.put("actualhallamount", hallAmount); + + double depositeamount = Double.parseDouble(hallDetails.get("deposit_amount").toString()); + double halfDepositAmount = Double.parseDouble(hallDetails.get("half_deposit_amount").toString()); + double Totaldepositeamount = calculateDepositAmountJdbc(daysrange, startingSlot_txt, endingSlot_txt, + depositeamount, halfDepositAmount); + depositeamount = Totaldepositeamount; + + double discountAmount = 0; + double gstAmount = 0.00; + String reasoncode = reasonMaster.get("reasoncode") != null ? reasonMaster.get("reasoncode").toString() : ""; + hs.put("reasoncode", reasoncode); + + /*Map governmentevents = jdbcTemplate.queryForMap( + "SELECT * FROM hall_details_concession WHERE hall_id = ?", + Integer.parseInt(hallDetails.get("hall_id").toString()));*/ + + List> rows = jdbcTemplate.queryForList( + "SELECT * FROM hall_details_concession WHERE hall_id = ?", + Integer.parseInt(hallDetails.get("hall_id").toString()) + ); + + Map governmentevents = rows.isEmpty() + ? Collections.emptyMap() // or null, your call + : rows.get(0); + + if (reasoncode.equals("SGE")) { + if (startingSlot == 1 && endingSlot == 2) { + discountAmount = (Double.parseDouble(governmentevents.get("fulldayhallamount").toString()) + * Double.parseDouble(hallDetails.get("sgediscount").toString())) / 100; + hallAmount = Double.parseDouble(governmentevents.get("fulldayhallamount").toString()); + hs.put("discount", hallDetails.get("sgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("full_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("fulldaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("fulldayebcharges").toString()); + double additionalcharges = cleaningCharges + PASystem + EB; + gstAmount = Math.round(additionalcharges * Double.parseDouble(hallDetails.get("gst").toString())) + / 100.0; + double depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + double totalAmount = additionalcharges + gstAmount + depositAmount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, additionalcharges, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } else { + hallAmount = Double.parseDouble(governmentevents.get("halfdayhallamount").toString()); + discountAmount = (hallAmount * Double.parseDouble(hallDetails.get("sgediscount").toString())) / 100; + hs.put("discount", hallDetails.get("sgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("halfdaycleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("halfdaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("halfdayebcharges").toString()); + double additionalcharges = cleaningCharges + PASystem + EB; + gstAmount = Math.round(additionalcharges * Double.parseDouble(hallDetails.get("gst").toString())) + / 100.0; + double depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + double totalAmount = additionalcharges + gstAmount + depositAmount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, additionalcharges, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } else if (reasoncode.equals("CGE")) { + double rentAmount, netAmount, depositAmount, totalAmount, truncatedTotalAmount, additionalcharges; + if (startingSlot == 1 && endingSlot == 2) { + discountAmount = (Double.parseDouble(hallDetails.get("full_day_rent").toString()) + * Double.parseDouble(hallDetails.get("cgediscount").toString())) / 100; + hallAmount = Double.parseDouble(hallDetails.get("full_day_rent").toString()); + hs.put("discount", hallDetails.get("cgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("full_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("fulldaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("fulldayebcharges").toString()); + additionalcharges = cleaningCharges + PASystem + EB; + rentAmount = hallAmount - discountAmount; + netAmount = rentAmount + additionalcharges; + gstAmount = Math.round(netAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + totalAmount = netAmount + gstAmount + depositAmount; + truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("rentAmount", rentAmount); + hs.put("gstAmount", gstAmount); + hs.put("netAmount", netAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, netAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } else { + discountAmount = (Double.parseDouble(hallDetails.get("half_day_rent").toString()) + * Double.parseDouble(hallDetails.get("cge_discount").toString())) / 100; + hallAmount = Double.parseDouble(hallDetails.get("half_day_rent").toString()); + hs.put("discount", hallDetails.get("cgediscount")); + double cleaningCharges = Double + .parseDouble(governmentevents.get("half_day_cleaningcharges").toString()); + double PASystem = Double.parseDouble(governmentevents.get("halfdaypasystem").toString()); + double EB = Double.parseDouble(governmentevents.get("halfdayebcharges").toString()); + additionalcharges = cleaningCharges + PASystem + EB; + rentAmount = hallAmount - discountAmount; + netAmount = rentAmount + additionalcharges; + gstAmount = Math.round(netAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + depositAmount = Double.parseDouble(hallDetails.get("deposit_amount").toString()) * daysrange; + totalAmount = netAmount + gstAmount + depositAmount; + truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("actualhallamount", hallAmount); + hs.put("rentAmount", rentAmount); + hs.put("gstAmount", gstAmount); + hs.put("netAmount", netAmount); + hs.put("additionalcharges", additionalcharges); + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, netAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } else { + + if (usertype.equals("COUNCILLOR") || usertype.equals("PENSIONER") || usertype.equals("GCC_EMPLOYEE") + || usertype.equals("PUBLIC")) { + discountAmount = (hallAmount * discount) / 100; + hallAmount = hallAmount - discountAmount; + gstAmount = Math.round(hallAmount * Double.parseDouble(hallDetails.get("gst").toString())) / 100.0; + double totalAmount = hallAmount + gstAmount + depositeamount; + double truncatedTotalAmount = Math.round(totalAmount * 100.0) / 100.0; + hs.put("totalAmount", truncatedTotalAmount); + bookingId = insertOrUpdateBookingDetailsJdbc(jdbcTemplate, bookingId, user, hallDetails, startDate, + endDate, days, startingSlot, endingSlot, depositeamount, hallAmount, gstAmount, + truncatedTotalAmount, reason, relation, "WAITING", "Booking Slot not Confirmed.", "ONLINE"); + } + } + + System.out.println("bookingId...." + bookingId); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate start = LocalDate.parse(startDate, formatter); + LocalDate end = LocalDate.parse(endDate, formatter); + int hallId = Integer.parseInt(hallDetails.get("hall_id").toString()); + int i = 0; + for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) { + Map bookingCalendar = null; + List> calList = jdbcTemplate.queryForList( + "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?", date.toString(), hallId); + if (!calList.isEmpty()) + bookingCalendar = calList.get(0); + + if (bookingCalendar != null) { + boolean morningSlot = Boolean.TRUE.equals(bookingCalendar.get("morning_slot")); + boolean eveningSlot = Boolean.TRUE.equals(bookingCalendar.get("evening_slot")); + if ((date.equals(start) && startingSlot == 1 && morningSlot) + || (date.equals(start) && startingSlot == 2 && eveningSlot) + || (date.equals(end) && endingSlot == 1 && morningSlot) + || (date.equals(end) && endingSlot == 2 && eveningSlot)) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (morningSlot && eveningSlot) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (!date.equals(end) && i != 0 && i != Math.round(days - 1) + && (morningSlot || eveningSlot)) { + return Collections.singletonMap("status", "slotOccupied"); + } else if (date.equals(end) && endingSlot == 2 && morningSlot && i != 0 + && i == Math.round(days - 1)) { + return Collections.singletonMap("status", "slotOccupied"); + } + } + i++; + } + + List> reasonDocMaster = jdbcTemplate.queryForList( + "SELECT * FROM reason_document_master WHERE reason_id = ?", + Integer.parseInt(formData.get("reasonId").toString())); + List> uploadedDocs = new ArrayList<>(); + for (Map rm : reasonDocMaster) { + Map docMap = new HashMap<>(); + String fieldName = ""; + String value = ""; + String fileName = ""; + String fileUrl = ""; + String filePath = ""; + if (Boolean.TRUE.equals(rm.get("add_text_field"))) { + fieldName = rm.get("field_name").toString(); + value = formData.get(fieldName).toString(); + jdbcTemplate.update( + "INSERT INTO booking_documents (booking_details_booking_id, booking_label, name) VALUES (?, ?, ?)", + Integer.parseInt(bookingId), fieldName, value); + docMap.put("booking_label", fieldName); + docMap.put("name", value); + } + if (Boolean.TRUE.equals(rm.get("add_document_field"))) { + String docFieldName = rm.get("doc_field_name").toString(); + MultipartFile file = (MultipartFile) formData.get(docFieldName); + fileName = bookingId + "_" + file.getOriginalFilename(); + fileUrl = serverPath + "images/" + reason + "/" + fileName; + filePath = uploadDirectory + "/" + reason + "/" + fileName; + + // Create directory if it doesn't exist + File directory = new File(uploadDirectory + "/" + reason); + if (!directory.exists()) { + directory.mkdirs(); // Creates parent directories if needed + } + + docMap.put("documentName", file.getOriginalFilename()); + docMap.put("documentType", file.getContentType()); + docMap.put("bookingDocUrl", fileUrl); + + // Save file to disk + try (FileOutputStream fos = new FileOutputStream(filePath)) { + byte[] bytes = file.getBytes(); + fos.write(bytes); + } catch (Exception e) { + throw new RuntimeException(e); + } + + jdbcTemplate.update( + "INSERT INTO booking_documents (booking_details_booking_id, booking_doc_url, document_name, document_type, booking_label, name) VALUES (?, ?, ?, ?, ?, ?)", + Integer.parseInt(bookingId), fileUrl, file.getOriginalFilename(), file.getContentType(), + fieldName, value); + } + uploadedDocs.add(docMap); + } + + hs.put("bookingId", bookingId); + hs.put("hallName", hallDetails.get("hall_name")); + hs.put("NoOfDay", days); + hs.put("startDate", startDate); + hs.put("endDate", endDate); + hs.put("startingSlot", startingSlot); + hs.put("endingSlot", endingSlot); + hs.put("hallAmount", hallAmount); + hs.put("gst", gstAmount); + hs.put("depositAmount", depositeamount); + hs.put("username", user.get("name")); + hs.put("userId", user.get("user_id")); + hs.put("mobileNo", user.get("mobile_no")); + hs.put("userType", user.get("usertype")); + hs.put("reason", reason); + hs.put("bookingId", bookingId); + hs.put("uploadedDocs", uploadedDocs); + } + + return hs; + } + + private double calcHallAmountJdbc(Map hallDetails, int daysrange, int startPeriod, int endPeriod) { + double fullDayRent = Double.parseDouble(hallDetails.get("full_day_rent").toString()); + double halfDayRent = Double.parseDouble(hallDetails.get("half_day_rent").toString()); + if (daysrange == 1) { + if (startPeriod == 1 && endPeriod == 2) + return fullDayRent; + else if (startPeriod == 1 && endPeriod == 1) + return halfDayRent; + else if (startPeriod == 2 && endPeriod == 2) + return halfDayRent; + else if (startPeriod == 2 && endPeriod == 1) + return fullDayRent; + } else { + if (startPeriod == 1 && endPeriod == 2) + return fullDayRent * daysrange; + else if (startPeriod == 1 && endPeriod == 1) + return fullDayRent * (daysrange - 1) + halfDayRent; + else if (startPeriod == 2 && endPeriod == 2) + return fullDayRent * (daysrange - 1) + halfDayRent; + else if (startPeriod == 2 && endPeriod == 1) + return fullDayRent * (daysrange - 2) + halfDayRent * 2; + } + return 0; + } + + private double calculateDepositAmountJdbc(double numDays, String startPeriod, String endPeriod, + double depositAmount, double HalfDepositAmount) { + double damount = 0; + if (numDays == 1) { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount; + else if ("1".equals(startPeriod) && "1".equals(endPeriod)) + damount = HalfDepositAmount; + else if ("2".equals(startPeriod) && "2".equals(endPeriod)) + damount = HalfDepositAmount; + else + damount = numDays; + } else { + if ("1".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount * numDays; + else if ("1".equals(startPeriod) && "1".equals(endPeriod)) + damount = depositAmount * (numDays - 1) + HalfDepositAmount; + else if ("2".equals(startPeriod) && "2".equals(endPeriod)) + damount = depositAmount * (numDays - 1) + HalfDepositAmount; + else if ("2".equals(startPeriod) && "1".equals(endPeriod)) + damount = depositAmount * (numDays - 2) + depositAmount; + else + damount = numDays; + } + return damount; + } + + private String insertOrUpdateBookingDetailsJdbc(JdbcTemplate jdbcTemplate, String bookingId, + Map user, Map hallDetails, String startDate, String endDate, double days, + int startingSlot, int endingSlot, double depositAmount, double hallAmount, double gst, double totalAmount, + String reason, String relation, String refundStatus, String comments, String bookingType) { + + if (bookingId == null || bookingId.equals("0")) { + // Insert with KeyHolder + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement( + "INSERT INTO booking_details (users_user_id, hall_details_hall_id, start_date, end_date, no_of_days, starting_slot, ending_slot, deposit_amount, hall_amount, gst, amount_received, reason, refund_status, comments, booking_type, relationship, booking_date, schedule_count, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + Statement.RETURN_GENERATED_KEYS); + ps.setObject(1, user.get("user_id")); + ps.setObject(2, hallDetails.get("hall_id")); + ps.setString(3, startDate); + ps.setString(4, endDate); + ps.setDouble(5, days); + ps.setInt(6, startingSlot); + ps.setInt(7, endingSlot); + ps.setDouble(8, depositAmount); + ps.setDouble(9, hallAmount); + ps.setDouble(10, gst); + ps.setDouble(11, totalAmount); + ps.setString(12, reason); + ps.setString(13, refundStatus); + ps.setString(14, comments); + ps.setString(15, bookingType); + ps.setString(16, relation); + ps.setString(17, java.time.LocalDate.now().toString()); + ps.setInt(18, 0); + ps.setInt(19, 2); + return ps; + }, keyHolder); + + Number generatedId = keyHolder.getKey(); + return generatedId != null ? generatedId.toString() : null; + } else { + // Update + jdbcTemplate.update( + "UPDATE booking_details SET users_user_id=?, hall_details_hall_id=?, start_date=?, end_date=?, no_of_days=?, starting_slot=?, ending_slot=?, deposit_amount=?, hall_amount=?, gst=?, amount_received=?, reason=?, refund_status=?, comments=?, booking_type=?, relationship=?, booking_date=?, schedule_count=? WHERE booking_id=?", + user.get("user_id"), hallDetails.get("hall_id"), startDate, endDate, days, startingSlot, endingSlot, + depositAmount, hallAmount, gst, totalAmount, reason, refundStatus, comments, bookingType, relation, + java.time.LocalDate.now().toString(), 0, Integer.parseInt(bookingId)); + return bookingId; + } + } + + public HashMap startPayment(int bookingId) { + HashMap hs = new HashMap<>(); + + String bookingSql = "SELECT b.amount_received, b.users_user_id, b.hall_details_hall_id, " + + " u.user_id, u.mobile_no, u.email " + " FROM booking_details b " + + " JOIN users u ON b.users_user_id = u.user_id " + " WHERE b.booking_id = ?"; + + try { + Map data = jdbcTemplate.queryForMap(bookingSql, bookingId); + + double amountReceived = (double) data.get("amount_received"); + int UserId = (int) data.get("user_id"); + long mobileNo = (long) data.get("mobile_no"); + String email = (String) data.get("email"); + int hallId = (int) data.get("hall_details_hall_id"); + + String txnId = "CHB" + transactionNumberGenerator.generateTransactionNumber() + + String.format("%05d", UserId); + + String totalAmt = String.valueOf(amountReceived); + + String insertSql = "INSERT INTO transaction_response (txansaction_id, hall_id, user_id, status_code, booking_id) " + + " VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(insertSql, txnId, hallId, String.valueOf(UserId), "temp", bookingId); + + String merchantId = paymentConfig.getMerchantId(); + String consumerId = String.format("%05d", UserId); + String encryptedToken = getToken(merchantId + "|", txnId + "|", totalAmt + "|", "|", consumerId + "|", + mobileNo + "|", email + "|", "|", "|", "|", "|", "|", "|", "|", "|", "|", + paymentConfig.getEncryptionKey()); + + hs.put("txansactionId", txnId); + hs.put("token", encryptedToken); + hs.put("amount", totalAmt); + /* + * hs.put("merchantId", merchantId); hs.put("consumerMobileNo", mobileNo); + * hs.put("consumerEmailId", email); hs.put("consumerId", consumerId); + * hs.put("error", false); + */ + + } catch (EmptyResultDataAccessException | NoSuchAlgorithmException e) { + hs.put("error", true); + hs.put("message", "Invalid booking ID or no user data found. "); + e.printStackTrace(); + } + + return hs; + } + + public String getToken(String merchantId, String txnId, String totalAmt, String accountNo, String consumerId, + String consumerMobileNo, String consumerEmailId, String debitStartDate, String debitEndDate, + String maxAmount, String amountType, String frequency, String cardNumber, String expMonth, String expYear, + String cvvCode, String salt) throws NoSuchAlgorithmException { + String token = merchantId + txnId + totalAmt + accountNo + consumerId + consumerMobileNo + consumerEmailId + + debitStartDate + debitEndDate + maxAmount + amountType + frequency + cardNumber + expMonth + expYear + + cvvCode + salt; + + return generateToken(token); + } + + public String generateToken(String token) throws NoSuchAlgorithmException { + // System.out.println("Token:-" + token); + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(token.getBytes()); + + byte[] bytes = md.digest(); + + BigInteger bigInt = new BigInteger(1, bytes); + String encryptedtoken = bigInt.toString(16); + + while (encryptedtoken.length() < 128) { + encryptedtoken = "0" + encryptedtoken; + } + // System.out.println("Encryption :- " + encryptedtoken); + return encryptedtoken; + } + + public Map checkSlotAvailability(int hallId, String startDate, String endDate, int startingSlot, int endingSlot) { + + // Validate slot numbers + if (startingSlot < 1 || startingSlot > 2 || endingSlot < 1 || endingSlot > 2) { + throw new IllegalArgumentException("Slot values must be 1 (morning) or 2 (evening)."); + } + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate start; + LocalDate end; + + try { + start = LocalDate.parse(startDate, formatter); + end = LocalDate.parse(endDate, formatter); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid date format. Use yyyy-MM-dd."); + } + + if (end.isBefore(start)) { + throw new IllegalArgumentException("End date cannot be before start date."); + } + + long days = java.time.temporal.ChronoUnit.DAYS.between(start, end) + 1; + int i = 0; + + try { + for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) { + + List> calList = jdbcTemplate.queryForList( + "SELECT * FROM booking_calendar WHERE bdate = ? AND hall_id = ?", + date.toString(), hallId + ); + + if (!calList.isEmpty()) { + Map bookingCalendar = calList.get(0); + + boolean morningSlot = Boolean.TRUE.equals(bookingCalendar.get("morning_slot")); + boolean eveningSlot = Boolean.TRUE.equals(bookingCalendar.get("evening_slot")); + + if ((date.equals(start) && startingSlot == 1 && morningSlot) + || (date.equals(start) && startingSlot == 1 && eveningSlot) + || (date.equals(end) && endingSlot == 1 && morningSlot) + || (date.equals(end) && endingSlot == 1 && eveningSlot)) { + return Map.of("status", "slotOccupied"); + } else if (morningSlot && eveningSlot) { + return Map.of("status", "slotOccupied"); + } else if (!date.equals(end) && i != 0 && i != Math.round(days - 1) + && (morningSlot || eveningSlot)) { + return Map.of("status", "slotOccupied"); + } else if (date.equals(end) && endingSlot == 2 && morningSlot && i != 0 + && i == Math.round(days - 1)) { + return Map.of("status", "slotOccupied"); + } + } + i++; + } + } catch (DataAccessException e) { + e.printStackTrace(); + throw new RuntimeException("Database error occurred while checking slot availability."); + } + + return Map.of("status", "slotAvailable"); + } +} diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHEncryptionUtils.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHEncryptionUtils.java new file mode 100644 index 0000000..c5df421 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHEncryptionUtils.java @@ -0,0 +1,63 @@ +package com.gcc.restapiservices.victoriaHallBooking.util; + +import com.gcc.restapiservices.victoriaHallBooking.configuration.VPHPaymentConfig; +import org.apache.commons.codec.binary.Hex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +@Component +public class VPHEncryptionUtils { + + @Autowired + private VPHPaymentConfig paymentConfig; + + public String encryptHxRefund(String text) throws Exception { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec keySpec = new SecretKeySpec(this.paymentConfig.getEncryptionKeyByte(), "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(this.paymentConfig.getEncryptionIVByte()); + cipher.init(1, keySpec, ivSpec); + byte[] results = cipher.doFinal(text.getBytes("UTF-8")); + String hxencstr = ToHexStrRefund(results); + return hxencstr; + } + + public String ToHexStrRefund(byte[] dataBuf) { + String hxstr = null; + Hex hx = new Hex(); + hxstr = new String(hx.encode(dataBuf)); + return hxstr; + } + + public String decryptHxTRefund(String hxstrr) throws Exception { + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + + SecretKeySpec keySpec = new SecretKeySpec(this.paymentConfig.getEncryptionKeyByte(), "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(this.paymentConfig.getEncryptionIVByte()); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + + byte[] decbytes = FromHexStr(hxstrr); + + byte[] results = cipher.doFinal(decbytes); + return new String(results, "UTF-8").trim(); + } + + public byte[] FromHexStr(String hxStr) { + byte[] charArray = hxStr.getBytes(); + byte[] bufstr = null; + Hex hxx = new Hex(); + + try { + bufstr = hxx.decode(charArray); + } catch (Exception e) { + e.printStackTrace(); + } + + return bufstr; + } +} + diff --git a/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHTransactionNumberGenerator.java b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHTransactionNumberGenerator.java new file mode 100644 index 0000000..2a5d0f7 --- /dev/null +++ b/src/main/java/com/gcc/restapiservices/victoriaHallBooking/util/VPHTransactionNumberGenerator.java @@ -0,0 +1,37 @@ +package com.gcc.restapiservices.victoriaHallBooking.util; + +import org.springframework.stereotype.Service; + +import java.util.Random; + +@Service +public class VPHTransactionNumberGenerator { + + public String generateTransactionNumber() { + // Define the length of the transaction number + int length = 12; + + // Define characters to be used in the transaction number + String characters = "0123456789"; + + // Create a StringBuilder to store the transaction number + StringBuilder sb = new StringBuilder(); + + // Create an instance of Random class + Random random = new Random(); + + // Generate the transaction number + for (int i = 0; i < length; i++) { + // Generate a random index within the range of characters + int randomIndex = random.nextInt(characters.length()); + + // Append the character at the random index to the transaction number + sb.append(characters.charAt(randomIndex)); + } + + + // Convert StringBuilder to String and return + return sb.toString(); + } + +} diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..d5ddb8e --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,36 @@ + +spring.application.name=restapiservices + +spring.datasource.url=jdbc:mysql://localhost:3306/dumpwastecollector +spring.datasource.username=root +spring.datasource.password=root +#spring.jpa.show-sql=true +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +server.port=8050 + +spring.servlet.multipart.max-file-size=20MB + +file.upload.directory=${user.dir}/gccoffice_uploads +file.dump.upload.directory=${user.dir}/cd_waste_docs/cdwaste_dump + +file.fullpath=/ +file.dump.fullpath=/cd_waste_docs/ + +fileBaseUrl=https://gccservices.in + + +app.getOtpUrl=https://tmegov.onex-aura.com/api/sms? + +app.erpUrl=https://erp.chennaicorporation.gov.in/pgr/external/mobileservice? + +dump_directory=cdwaste_dump + +feedback_directory = whatsapp_feedback + +#fileHanding +file.upload.directory.communityhall=${user.dir}/communityHallDocuments +file.fullpath.communityhall=/ + +# Used for know your zone and division based on address +google.api.key=AIzaSyCi7N6uW5MZaSkd50Kzw7ax2GkMN1vjE-E +gis.api.url=https://gisgcc.chennaicorporation.gov.in/server/rest/services/GCCDepts/EDPMobile2025/FeatureServer/0/query \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties new file mode 100644 index 0000000..9401a69 --- /dev/null +++ b/src/main/resources/application-prod.properties @@ -0,0 +1,46 @@ +spring.application.name= restapiservices +spring.datasource.url=jdbc:mysql://gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306/gcc_c_d_waste_web +spring.datasource.username=root +spring.datasource.password=gcc-facial-password +# spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +server.port=8050 + + + +#for using cd waste +spring.servlet.multipart.max-file-size=20MB + +file.upload.directory=${user.dir}/gccoffice_uploads + +file.fullpath=/ +file.dump.fullpath=/cd_waste_docs/ + + +fileBaseUrl=https://gccservices.in + +#payment.razorpay.my_key_id="rzp_live_66FhxMUNAb9McO" + +#payment.razorpay.my_key_id="rzp_test_tDkHFEqWXmuEi8" + + +app.getOtpUrl=https://tmegov.onex-aura.com/api/sms? + +app.erpUrl=http://coc-staging.egovernments.org:9980/pgr/external/mobileservice? + +dump_directory=cdwaste_dump + +feedback_directory = whatsapp_feedback + +#fileHanding +file.upload.directory.communityhall=${user.dir}/communityHallDocuments +file.fullpath.communityhall=/ + +#fileHanding +file.upload.directory.victoriahall=${user.dir}/victoriaHallDocuments +file.fullpath.victoriahall=/ + +# Used for know your zone and division based on address +google.api.key=AIzaSyCi7N6uW5MZaSkd50Kzw7ax2GkMN1vjE-E +gis.api.url=https://gisgcc.chennaicorporation.gov.in/server/rest/services/GCCDepts/EDPMobile2025/FeatureServer/0/query \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..7587d58 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,3 @@ +#Generated by Eclipse Messages Editor (Eclipse Babel) + +spring.profiles.active = prod diff --git a/src/main/resources/paymentConfig.properties b/src/main/resources/paymentConfig.properties new file mode 100644 index 0000000..c066969 --- /dev/null +++ b/src/main/resources/paymentConfig.properties @@ -0,0 +1,15 @@ +#payment.worldline.merchantId=T955031 +#payment.worldline.encryptionKey=1025180466GPADTD +#payment.worldline.encryptionIV=3232693456UWOWHC +#payment.worldline.schemeCode=FIRST +#payment.worldline.merchantName=Greater Chennai Corporation +#payment.worldline.transactionSuccessCode=0300 +#payment.worldline.refundSuccessCode=0400 + +payment.worldline.merchantId=L1037717 +payment.worldline.encryptionKey=6207149300MFLGNY +payment.worldline.encryptionIV=3422107798TKQCNG +payment.worldline.schemeCode=FIRST +payment.worldline.merchantName=Greater Chennai Corporation +payment.worldline.transactionSuccessCode=0300 +payment.worldline.refundSuccessCode=0400