Browse Source

Community Hall new changes code updation

master
KaNi-04 2 months ago
parent
commit
1d516f8e10
  1. 3
      .vscode/settings.json
  2. 2
      jwtToken.txt
  3. 25
      src/main/java/com/gcc/communityHall/controller/HeadquartersController.java
  4. 7
      src/main/java/com/gcc/communityHall/controller/UserAPIController.java
  5. 2
      src/main/java/com/gcc/communityHall/entity/BookingDetails.java
  6. 447
      src/main/java/com/gcc/communityHall/paymentService/controller/PaymentAPIController.java
  7. 130
      src/main/java/com/gcc/communityHall/paymentService/scheduler/PaymentStatusScheduler.java
  8. 6
      src/main/java/com/gcc/communityHall/repository/BookingDetailsRepository.java
  9. 8
      src/main/java/com/gcc/communityHall/repository/LoginRepository.java
  10. 287
      src/main/java/com/gcc/communityHall/service/BookingService.java
  11. 381
      src/main/java/com/gcc/communityHall/service/Impl/BookingServiceImpl.java
  12. 2
      src/main/java/com/gcc/communityHall/service/MailService.java
  13. 843
      src/main/resources/resources/templates/headquarters/sixmonthold-transactions.html
  14. 867
      src/main/resources/templates/admin/bookingwaiting.html
  15. 56
      src/main/resources/templates/fragments/PaymentScript.html
  16. 2
      src/main/resources/templates/fragments/headquartersMenu.html
  17. 965
      src/main/resources/templates/headquarters/bookingwaiting.html
  18. 4
      src/main/resources/templates/headquarters/reports.html
  19. 64
      src/main/resources/templates/headquarters/sixmonthold-transactions.html
  20. 18
      src/main/resources/templates/user/hallbookingform.html
  21. 155
      src/main/resources/templates/user/viewhistory.html
  22. 3530
      src/main/resources/templates/user/viewhistory_old.html
  23. 3538
      src/main/resources/templates/user/viewhistory_reschedulelogic.html

3
.vscode/settings.json

@ -1,3 +1,4 @@
{ {
"java.compile.nullAnalysis.mode": "automatic"
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "interactive"
} }

2
jwtToken.txt

@ -1 +1 @@
eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyVHlwZSI6ImhlYWRxdWFydGVycyIsImhhbGxJZCI6MCwiaGFsbElkcyI6IiIsIm1vYmlsZU51bWJlciI6OTUxNzUzODUyNCwiem9uZSI6IjAwIiwiZXhwIjoxNzgzOTI4NDY4fQ.JDuWljfRXzemAjgmLj4MFq3DgmL9Z1hbE8_LoLpQQ0jLZp4wBbyvmEopk9BHmWtzh8SlDN6dxQHEJDsxTRt0_Q
eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyVHlwZSI6ImhlYWRxdWFydGVycyIsImhhbGxJZCI6MCwiaGFsbElkcyI6IiIsIm1vYmlsZU51bWJlciI6OTUxNzUzODUyNCwiem9uZSI6IjAwIiwiZXhwIjoxNzg1MzI4MDYwfQ.aXxOu_OHvSMRSKZFqyQzzi9rFw8KCuC5m-Hv4QNSk36_lWZCcZJSvbPHDyQKyELJkbZdURa9p0dd6sPmDoZsLg

25
src/main/java/com/gcc/communityHall/controller/HeadquartersController.java

@ -1177,11 +1177,6 @@ public class HeadquartersController {
return result; return result;
} }
/**
* Marks a booking as "mail sent":
* 1. Stamps mail_sent = 1, mail_sent_date = NOW() on booking_details.
* 2. Inserts a row into six_month_mail_log for audit history.
*/
@PostMapping("/sixmonthold-transactions/markMailSent") @PostMapping("/sixmonthold-transactions/markMailSent")
@ResponseBody @ResponseBody
@Transactional @Transactional
@ -1206,7 +1201,7 @@ public class HeadquartersController {
String mailBody = mailService.sendRefundFollowupMail( String mailBody = mailService.sendRefundFollowupMail(
bookingId, bookingStatus, transactionId, tpslId, transactionDate, refundAmount); bookingId, bookingStatus, transactionId, tpslId, transactionDate, refundAmount);
// 2. Stamp booking_details: mail_sent = 1, mail_sent_date = NOW()
// 2. Update booking_details: mail_sent = 1, mail_sent_date = NOW()
bookingDetailsRepository.markMailSent(bookingId); bookingDetailsRepository.markMailSent(bookingId);
// 3. Write audit log entry // 3. Write audit log entry
@ -1223,24 +1218,6 @@ public class HeadquartersController {
return response; return response;
} }
/**
* Update Refund Details for Mail Sent Bookings (new method – does NOT touch
* existing endpoints).
*
* ID logic:
* - Cancelled / Rejected → bookingId is the primary reference.
* - Approved → settlementId is the primary reference;
* bookingId used to fetch BookingDetails.
*
* Tables updated (in order):
* 1. booking_history – archive current BookingDetails snapshot.
* 2. booking_details – bookingStatus=COMPLETED, refundStatus=COMPLETED.
* 3. settlement_history – archive Settlement snapshot (APPROVED only).
* 4. settlement – update comments + updatedDate (APPROVED only).
* 5. refund_transaction – upsert.
* 6. refund_response – upsert with arn_number.
* 7. application_logs – audit entry.
*/
@PostMapping("/sixmonthold-transactions/updateRefundDetails") @PostMapping("/sixmonthold-transactions/updateRefundDetails")
@ResponseBody @ResponseBody
@Transactional @Transactional

7
src/main/java/com/gcc/communityHall/controller/UserAPIController.java

@ -1329,9 +1329,12 @@ public class UserAPIController {
public ResponseEntity<String> updateBookingDates( public ResponseEntity<String> updateBookingDates(
@RequestParam int bookingId, @RequestParam int bookingId,
@RequestParam String startDate, @RequestParam String startDate,
@RequestParam String endDate) {
@RequestParam String endDate,
@RequestParam(required = false, defaultValue = "0") int startingSlot,
@RequestParam(required = false, defaultValue = "0") int endingSlot) {
try { try {
Optional<String> updateResult = bookingService.updateBookingDatesAndCalendar(bookingId, startDate, endDate);
Optional<String> updateResult = bookingService.updateBookingDatesAndCalendar(
bookingId, startDate, endDate, startingSlot, endingSlot);
if (updateResult.isPresent()) { if (updateResult.isPresent()) {
if (updateResult.get().equals("Booking dates updated successfully.")) { if (updateResult.get().equals("Booking dates updated successfully.")) {
return new ResponseEntity<>(updateResult.get(), HttpStatus.OK); return new ResponseEntity<>(updateResult.get(), HttpStatus.OK);

2
src/main/java/com/gcc/communityHall/entity/BookingDetails.java

@ -5,6 +5,8 @@ import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.gcc.communityHall.paymentService.entity.RefundResponse;
import jakarta.persistence.*; import jakarta.persistence.*;
@Entity @Entity

447
src/main/java/com/gcc/communityHall/paymentService/controller/PaymentAPIController.java

@ -1,7 +1,8 @@
package com.gcc.communityHall.paymentService.controller; package com.gcc.communityHall.paymentService.controller;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Optional; import java.util.Optional;
@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.gcc.communityHall.entity.BookingCalendar;
import com.gcc.communityHall.entity.BookingDetails; import com.gcc.communityHall.entity.BookingDetails;
import com.gcc.communityHall.entity.Users; import com.gcc.communityHall.entity.Users;
import com.gcc.communityHall.paymentService.DTO.Merchant; import com.gcc.communityHall.paymentService.DTO.Merchant;
@ -28,6 +30,7 @@ import com.gcc.communityHall.paymentService.entity.TransactionResponse;
import com.gcc.communityHall.paymentService.refund.DTO.TransactionRefundResponse; import com.gcc.communityHall.paymentService.refund.DTO.TransactionRefundResponse;
import com.gcc.communityHall.paymentService.service.PaymentGatewayService; import com.gcc.communityHall.paymentService.service.PaymentGatewayService;
import com.gcc.communityHall.paymentService.service.TransactionNumberGenerator; import com.gcc.communityHall.paymentService.service.TransactionNumberGenerator;
import com.gcc.communityHall.repository.BookingCalendarRepository;
import com.gcc.communityHall.repository.BookingDetailsRepository; import com.gcc.communityHall.repository.BookingDetailsRepository;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -35,12 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@Tag(
name = "CRUD REST APIs for Payment in CommunityHall",
description = "CRUD REST APIs in CommunityHall to CREATE, UPDATE, FETCH AND DELETE Booking details"
)
@Tag(name = "CRUD REST APIs for Payment in CommunityHall", description = "CRUD REST APIs in CommunityHall to CREATE, UPDATE, FETCH AND DELETE Booking details")
@RestController @RestController
@RequestMapping("/communityhall/payment/api") @RequestMapping("/communityhall/payment/api")
@AllArgsConstructor @AllArgsConstructor
@ -57,175 +55,274 @@ public class PaymentAPIController {
private BookingDetailsRepository bookRepo; private BookingDetailsRepository bookRepo;
@Autowired @Autowired
private TransactionNumberGenerator transactionNumber;
private BookingCalendarRepository bookingCalendarRepository;
@Autowired
private TransactionNumberGenerator transactionNumber;
// @Operation(
// summary = "Refund the Total Amount REST API",
// description = "REST API to refunding the Total Amount if the admin will cancel and block the hall"
// )
// @GetMapping(value="/refund")
// public ResponseEntity<?> refundAmount(Model model,@RequestParam int bookingId) throws Exception {
// //System.out.println("Refund Api call.......working on it");
// TransactionResponse transactionRes = this.paymentService.getTransactionResponseByBookingIdAndStatusCode(bookingId,this.paymentConfig.getTransactionSuccessCode());
// RefundResponse recordRefundResponse = new RefundResponse();
//
// Merchant merchant = new Merchant();
// merchant.setIdentifier(this.paymentConfig.getMerchantId());
//
// Transaction transaction = new Transaction();
// transaction.setAmount(transactionRes.getAmount());//Amount given here
// transaction.setIdentifier("");
// String[] datestime = transactionRes.getDate().split(" ");
// transaction.setDateTime(datestime[0]); //At what date transaction happens
// transaction.setRequestType("R");
// transaction.setToken("");
// transaction.setReference(transactionRes.getTpslTxnId()); //tpsl refer number
//
// TransactionData transactionData = new TransactionData();
// transactionData.setMerchant(merchant);
// transactionData.setTransaction(transaction);
//
// // Serialize TransactionData object to JSON string
// Gson gson = new Gson();
// String json = gson.toJson(transactionData);
// //System.out.println(json);
//
// String encryptHxRefund = this.paymentService.encryptHxRefund(json);
// RestTemplate resttemplate = new RestTemplate();
// String Url ="https://www.tpsl-india.in/PaymentGateway/merchant2.pg/"+this.paymentConfig.getMerchantId();
// ResponseEntity<String> postForEntity = resttemplate.postForEntity(Url, encryptHxRefund, String.class);
//
// String decryptHxTRefund = this.paymentService.decryptHxTRefund(postForEntity.getBody());
// recordRefundResponse.setResponse(decryptHxTRefund);
// //recordRefundResponse.setUserId("2");//make it dynamic
// recordRefundResponse.setBookingId(bookingId);
// try {
// ObjectMapper objectMapper = new ObjectMapper();
//
// TransactionRefundResponse myObject = objectMapper.readValue(decryptHxTRefund, TransactionRefundResponse.class);
// //System.out.println(myObject.toString());
//
// if(myObject.getPaymentMethod().getPaymentTransaction().getStatusCode().equals(this.paymentConfig.getRefundSuccessCode())) {
// //System.out.println("Refund Process complete........"+bookingId);
// recordRefundResponse.setAmount(myObject.getPaymentMethod().getPaymentTransaction().getAmount());
// recordRefundResponse.setBalaceAmount(myObject.getPaymentMethod().getPaymentTransaction().getBalanceAmount());
// }
// recordRefundResponse.setStatusCode(myObject.getPaymentMethod().getPaymentTransaction().getStatusCode());
// recordRefundResponse.setTxansactionId(myObject.getMerchantTransactionIdentifier());
//
// this.paymentService.recordRefund(recordRefundResponse);
// return ResponseEntity.ok(myObject);
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// return ResponseEntity.ok(decryptHxTRefund);
//
// }
@Operation(
summary = "payment-request REST API",
description = "REST API payment-request"
)
@PostMapping(value = {"/payment-request"})
public HashMap<String,Object> startPayment(int userId,int bookingId) throws NoSuchAlgorithmException {
//System.out.println("I entered payment Service......"+bookingId+ "User Id :- "+userId);
HashMap<String, Object> hs = new HashMap<>();
Optional<BookingDetails> findById = bookRepo.findById(bookingId);
if(findById.isPresent()) {
//System.out.println("Success in finding booking Id");
BookingDetails booking = findById.get();
Users user = booking.getUsers();
int findUserId=user.getUserId();
//System.out.println("Merchant ID:-"+this.paymentConfig.getMerchantId());
String txnId="CHB"+transactionNumber.generateTransactionNumber()+String.format("%05d", findUserId); //create transaction Id unique from our side
String totalAmt = String.valueOf(booking.getAmountReceived()); //Amount of Community Hall from our side
TransactionResponse response = new TransactionResponse();
response.setTxansactionId(txnId);
response.setHallId(booking.getHallDetails().getHallId());
response.setUserId(String.valueOf(findUserId));//make it dynamic
response.setStatusCode("temp");
response.setBookingId(bookingId);
this.paymentService.recordResponse(response);
String merchantId = this.paymentConfig.getMerchantId(); //This is Test Merchant ID from worldLine
String consumerId=String.format("%05d", findUserId); // Replace consumer ID in c964634 from our side
String consumerMobileNo=String.valueOf(user.getMobileNo()); //Replace consumer Mobile no in 9879879870 from our side
String consumerEmailId=user.getEmail(); //replace consumer email Id
String encryptedtoken = this.paymentService.getToken(merchantId+"|", txnId+"|", totalAmt+"|", "|", consumerId+"|", consumerMobileNo+"|", consumerEmailId+"|", "|", "|", "|", "|", "|", "|", "|", "|", "|", this.paymentConfig.getEncryptionKey());
hs.put("txansactionId",txnId);
hs.put("token",encryptedtoken);
hs.put("amount",totalAmt);
hs.put("merchantId",merchantId);
hs.put("consumerMobileNo",consumerMobileNo);
hs.put("consumerEmailId",consumerEmailId);
hs.put("consumerId",consumerId);
hs.put("error", false);
}
else {
hs.put("error", true);
}
return hs;
}
@Operation(
summary = "Additional Damage payment-request REST API",
description = "REST API Additional Damage payment-request"
)
@PostMapping(value = {"/additionaldamage-payment-request"})
public HashMap<String,Object> startextraPayment(int userId,int bookingId) throws NoSuchAlgorithmException {
//System.out.println("I entered payment Service......"+bookingId+ "User Id :- "+userId);
HashMap<String, Object> hs = new HashMap<>();
Optional<BookingDetails> findById = bookRepo.findById(bookingId);
if(findById.isPresent()) {
//System.out.println("Success in finding booking Id");
BookingDetails booking = findById.get();
Users user = booking.getUsers();
int findUserId=user.getUserId();
//System.out.println("Merchant ID:-"+this.paymentConfig.getMerchantId());
String txnId="CHBED"+transactionNumber.generateTransactionNumber()+String.format("%05d", findUserId); //create transaction Id unique from our side
String totalAmt = String.valueOf(booking.getSettlement().getCollectionPending()); //Amount of Community Hall from our side
TransactionResponse response = new TransactionResponse();
response.setTxansactionId(txnId);
response.setHallId(booking.getHallDetails().getHallId());
response.setUserId(String.valueOf(findUserId));//make it dynamic
response.setStatusCode("temp");
response.setBookingId(bookingId);
this.paymentService.recordResponse(response);
String merchantId = this.paymentConfig.getMerchantId(); //This is Test Merchant ID from worldLine
String consumerId=String.format("%05d", findUserId); // Replace consumer ID in c964634 from our side
String consumerMobileNo=String.valueOf(user.getMobileNo()); //Replace consumer Mobile no in 9879879870 from our side
String consumerEmailId=user.getEmail(); //replace consumer email Id
String encryptedtoken = this.paymentService.getToken(merchantId+"|", txnId+"|", totalAmt+"|", "|", consumerId+"|", consumerMobileNo+"|", consumerEmailId+"|", "|", "|", "|", "|", "|", "|", "|", "|", "|", this.paymentConfig.getEncryptionKey());
System.out.println(totalAmt);
hs.put("txansactionId",txnId);
hs.put("token",encryptedtoken);
hs.put("amount",totalAmt);
hs.put("merchantId",merchantId);
hs.put("consumerMobileNo",consumerMobileNo);
hs.put("consumerEmailId",consumerEmailId);
hs.put("consumerId",consumerId);
hs.put("error", false);
}
else {
hs.put("error", true);
}
return hs;
}
// @Operation(
// summary = "Refund the Total Amount REST API",
// description = "REST API to refunding the Total Amount if the admin will
// cancel and block the hall"
// )
// @GetMapping(value="/refund")
// public ResponseEntity<?> refundAmount(Model model,@RequestParam int
// bookingId) throws Exception {
// //System.out.println("Refund Api call.......working on it");
// TransactionResponse transactionRes =
// this.paymentService.getTransactionResponseByBookingIdAndStatusCode(bookingId,this.paymentConfig.getTransactionSuccessCode());
// RefundResponse recordRefundResponse = new RefundResponse();
//
// Merchant merchant = new Merchant();
// merchant.setIdentifier(this.paymentConfig.getMerchantId());
//
// Transaction transaction = new Transaction();
// transaction.setAmount(transactionRes.getAmount());//Amount given here
// transaction.setIdentifier("");
// String[] datestime = transactionRes.getDate().split(" ");
// transaction.setDateTime(datestime[0]); //At what date transaction happens
// transaction.setRequestType("R");
// transaction.setToken("");
// transaction.setReference(transactionRes.getTpslTxnId()); //tpsl refer number
//
// TransactionData transactionData = new TransactionData();
// transactionData.setMerchant(merchant);
// transactionData.setTransaction(transaction);
//
// // Serialize TransactionData object to JSON string
// Gson gson = new Gson();
// String json = gson.toJson(transactionData);
// //System.out.println(json);
//
// String encryptHxRefund = this.paymentService.encryptHxRefund(json);
// RestTemplate resttemplate = new RestTemplate();
// String Url
// ="https://www.tpsl-india.in/PaymentGateway/merchant2.pg/"+this.paymentConfig.getMerchantId();
// ResponseEntity<String> postForEntity = resttemplate.postForEntity(Url,
// encryptHxRefund, String.class);
//
// String decryptHxTRefund =
// this.paymentService.decryptHxTRefund(postForEntity.getBody());
// recordRefundResponse.setResponse(decryptHxTRefund);
// //recordRefundResponse.setUserId("2");//make it dynamic
// recordRefundResponse.setBookingId(bookingId);
// try {
// ObjectMapper objectMapper = new ObjectMapper();
//
// TransactionRefundResponse myObject = objectMapper.readValue(decryptHxTRefund,
// TransactionRefundResponse.class);
// //System.out.println(myObject.toString());
//
// if(myObject.getPaymentMethod().getPaymentTransaction().getStatusCode().equals(this.paymentConfig.getRefundSuccessCode()))
// {
// //System.out.println("Refund Process complete........"+bookingId);
// recordRefundResponse.setAmount(myObject.getPaymentMethod().getPaymentTransaction().getAmount());
// recordRefundResponse.setBalaceAmount(myObject.getPaymentMethod().getPaymentTransaction().getBalanceAmount());
// }
// recordRefundResponse.setStatusCode(myObject.getPaymentMethod().getPaymentTransaction().getStatusCode());
// recordRefundResponse.setTxansactionId(myObject.getMerchantTransactionIdentifier());
//
// this.paymentService.recordRefund(recordRefundResponse);
// return ResponseEntity.ok(myObject);
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// return ResponseEntity.ok(decryptHxTRefund);
//
// }
@Operation(summary = "payment-request REST API", description = "REST API payment-request")
@PostMapping(value = { "/payment-request" })
public HashMap<String, Object> startPayment(int userId, int bookingId) throws NoSuchAlgorithmException {
// System.out.println("I entered payment Service......"+bookingId+ "User Id :-
// "+userId);
HashMap<String, Object> hs = new HashMap<>();
Optional<BookingDetails> findById = bookRepo.findById(bookingId);
if (findById.isPresent()) {
// System.out.println("Success in finding booking Id");
BookingDetails booking = findById.get();
// --- Slot Availability Check ---
String startDateStr = booking.getStartDate();
String endDateStr = booking.getEndDate();
int startingSlot = booking.getStartingSlot();
int endingSlot = booking.getEndingSlot();
int hallId = booking.getHallDetails().getHallId();
String currentBookingIdStr = String.valueOf(bookingId);
if (startDateStr != null && endDateStr != null) {
LocalDate startDate = LocalDate.parse(startDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate endDate = LocalDate.parse(endDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
int dayIndex = 0;
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
BookingCalendar calEntry = bookingCalendarRepository.findByBdateAndHallId(date, hallId);
if (calEntry == null) {
dayIndex++;
continue; // No entry means this date is free
}
// Determine which slots are occupied by OTHER bookings (exclude this booking)
boolean morningOccupied = calEntry.isMorningSlot()
&& !currentBookingIdStr.equals(calEntry.getBookingId_1());
boolean eveningOccupied = calEntry.isEveningSlot()
&& !currentBookingIdStr.equals(calEntry.getBookingId_2());
boolean isConflict = false;
if (date.equals(startDate) && date.equals(endDate)) {
// Single-day booking
if (startingSlot == 1 && endingSlot == 2) {
// Full day needed - conflict if morning or evening is taken
isConflict = morningOccupied || eveningOccupied;
} else if (startingSlot == 1) {
isConflict = morningOccupied;
} else if (startingSlot == 2 || endingSlot == 2) {
isConflict = eveningOccupied;
}
} else if (date.equals(startDate)) {
// Start day of a multi-day booking
if (startingSlot == 1) {
// Morning start: needs morning + evening on start day
isConflict = morningOccupied || eveningOccupied;
} else {
// Evening start: needs only evening on start day
isConflict = eveningOccupied;
}
} else if (date.equals(endDate)) {
// End day of a multi-day booking
if (endingSlot == 1) {
// Morning end: needs only morning on end day
isConflict = morningOccupied;
} else {
// Evening end: needs both morning and evening on end day
isConflict = morningOccupied || eveningOccupied;
}
} else {
// Middle day: entire day must be free
isConflict = morningOccupied || eveningOccupied;
}
if (isConflict) {
hs.put("error", true);
hs.put("slotOccupied", true);
hs.put("occupiedDate", date.toString());
hs.put("message",
"The selected date " + date + " is already occupied. Please Change your dates.");
hs.put("hallId", hallId);
return hs;
}
dayIndex++;
}
}
// --- End Slot Availability Check ---
Users user = booking.getUsers();
int findUserId = user.getUserId();
// System.out.println("Merchant ID:-"+this.paymentConfig.getMerchantId());
String txnId = "CHB" + transactionNumber.generateTransactionNumber() + String.format("%05d", findUserId); // create
// unique
// transaction
// Id
// from
// our
// side
String totalAmt = String.valueOf(booking.getAmountReceived()); // Amount of Community Hall from our side
TransactionResponse response = new TransactionResponse();
response.setTxansactionId(txnId);
response.setHallId(booking.getHallDetails().getHallId());
response.setUserId(String.valueOf(findUserId));// make it dynamic
response.setStatusCode("temp");
response.setBookingId(bookingId);
this.paymentService.recordResponse(response);
String merchantId = this.paymentConfig.getMerchantId(); // This is Test Merchant ID from worldLine
String consumerId = String.format("%05d", findUserId); // Replace consumer ID in c964634 from our side
String consumerMobileNo = String.valueOf(user.getMobileNo()); // Replace consumer Mobile no in 9879879870
// from our side
String consumerEmailId = user.getEmail(); // replace consumer email Id
String encryptedtoken = this.paymentService.getToken(merchantId + "|", txnId + "|", totalAmt + "|", "|",
consumerId + "|", consumerMobileNo + "|", consumerEmailId + "|", "|", "|", "|", "|", "|", "|", "|",
"|", "|", this.paymentConfig.getEncryptionKey());
hs.put("txansactionId", txnId);
hs.put("token", encryptedtoken);
hs.put("amount", totalAmt);
hs.put("merchantId", merchantId);
hs.put("consumerMobileNo", consumerMobileNo);
hs.put("consumerEmailId", consumerEmailId);
hs.put("consumerId", consumerId);
hs.put("error", false);
} else {
hs.put("error", true);
}
return hs;
}
@Operation(summary = "Additional Damage payment-request REST API", description = "REST API Additional Damage payment-request")
@PostMapping(value = { "/additionaldamage-payment-request" })
public HashMap<String, Object> startextraPayment(int userId, int bookingId) throws NoSuchAlgorithmException {
// System.out.println("I entered payment Service......"+bookingId+ "User Id :-
// "+userId);
HashMap<String, Object> hs = new HashMap<>();
Optional<BookingDetails> findById = bookRepo.findById(bookingId);
if (findById.isPresent()) {
// System.out.println("Success in finding booking Id");
BookingDetails booking = findById.get();
Users user = booking.getUsers();
int findUserId = user.getUserId();
// System.out.println("Merchant ID:-"+this.paymentConfig.getMerchantId());
String txnId = "CHBED" + transactionNumber.generateTransactionNumber() + String.format("%05d", findUserId); // create
// transaction
// Id
// unique
// from
// our
// side
String totalAmt = String.valueOf(booking.getSettlement().getCollectionPending()); // Amount of Community
// Hall from our side
TransactionResponse response = new TransactionResponse();
response.setTxansactionId(txnId);
response.setHallId(booking.getHallDetails().getHallId());
response.setUserId(String.valueOf(findUserId));// make it dynamic
response.setStatusCode("temp");
response.setBookingId(bookingId);
this.paymentService.recordResponse(response);
String merchantId = this.paymentConfig.getMerchantId(); // This is Test Merchant ID from worldLine
String consumerId = String.format("%05d", findUserId); // Replace consumer ID in c964634 from our side
String consumerMobileNo = String.valueOf(user.getMobileNo()); // Replace consumer Mobile no in 9879879870
// from our side
String consumerEmailId = user.getEmail(); // replace consumer email Id
String encryptedtoken = this.paymentService.getToken(merchantId + "|", txnId + "|", totalAmt + "|", "|",
consumerId + "|", consumerMobileNo + "|", consumerEmailId + "|", "|", "|", "|", "|", "|", "|", "|",
"|", "|", this.paymentConfig.getEncryptionKey());
System.out.println(totalAmt);
hs.put("txansactionId", txnId);
hs.put("token", encryptedtoken);
hs.put("amount", totalAmt);
hs.put("merchantId", merchantId);
hs.put("consumerMobileNo", consumerMobileNo);
hs.put("consumerEmailId", consumerEmailId);
hs.put("consumerId", consumerId);
hs.put("error", false);
} else {
hs.put("error", true);
}
return hs;
}
} }

130
src/main/java/com/gcc/communityHall/paymentService/scheduler/PaymentStatusScheduler.java

@ -69,15 +69,19 @@ public class PaymentStatusScheduler {
@Autowired @Autowired
private CalendarService calendarService; private CalendarService calendarService;
// @Scheduled(cron = "0 0 0 * * ?", zone = "Asia/Kolkata") //executed at 12:00 AM
// @Scheduled(fixedRate = 900000)
// @Scheduled(cron = "0 0 0 * * ?", zone = "Asia/Kolkata") //executed at 12:00
// AM
// @Scheduled(fixedRate = 900000)
@Scheduled(fixedRate = 60000) @Scheduled(fixedRate = 60000)
public void fetchAndSavePaymentStatus() { public void fetchAndSavePaymentStatus() {
// System.out.println("Fetching Payment Status...At 12:00 AM IST");
// System.out.println("Fetching Payment Status...At 12:00 AM IST");
System.out.println("Fetching Payment Status...At 15 min Testing"); System.out.println("Fetching Payment Status...At 15 min Testing");
try { try {
List<Map<String, Object>> pendingTransactions = transactionResponseRepository.getTransResBycdateandStatus("temp");
List<Map<String, Object>> pendingTransactions = transactionResponseRepository
.getTransResBycdateandStatus("temp");
System.out.println("pendingTransactions size " + pendingTransactions.size() + "\n pendingTransactions list:"
+ pendingTransactions);
for (Map<String, Object> transactionRecord : pendingTransactions) { for (Map<String, Object> transactionRecord : pendingTransactions) {
try { try {
@ -94,7 +98,8 @@ public class PaymentStatusScheduler {
transaction.put("token", ""); transaction.put("token", "");
transaction.put("reference", ""); transaction.put("reference", "");
System.out.println("=====================================" + transactionRecord.get("txansaction_id"));
System.out
.println("=====================================" + transactionRecord.get("txansaction_id"));
System.out.println(merchant); System.out.println(merchant);
System.out.println(transaction); System.out.println(transaction);
System.out.println(status); System.out.println(status);
@ -113,15 +118,16 @@ public class PaymentStatusScheduler {
transaction.put("dateTime", ""); transaction.put("dateTime", "");
} }
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(status); String json = gson.toJson(status);
System.out.println("Hello json " + json); System.out.println("Hello json " + json);
String encryptHxRefund = paymentGatewayService.encryptHxRefund(json); String encryptHxRefund = paymentGatewayService.encryptHxRefund(json);
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
String url = "https://www.tpsl-india.in/PaymentGateway/merchant2.pg/" + paymentConfig.getMerchantId();
ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, encryptHxRefund, String.class);
String url = "https://www.tpsl-india.in/PaymentGateway/merchant2.pg/"
+ paymentConfig.getMerchantId();
ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, encryptHxRefund,
String.class);
String decryptHxTRefund = paymentGatewayService.decryptHxTRefund(postForEntity.getBody()); String decryptHxTRefund = paymentGatewayService.decryptHxTRefund(postForEntity.getBody());
Map<String, Object> myObj = new ObjectMapper().readValue(decryptHxTRefund, Map.class); Map<String, Object> myObj = new ObjectMapper().readValue(decryptHxTRefund, Map.class);
@ -137,7 +143,7 @@ public class PaymentStatusScheduler {
log.setBookingId(transactionRecord.get("booking_id").toString()); log.setBookingId(transactionRecord.get("booking_id").toString());
log.setUserId(transactionRecord.get("user_id").toString()); log.setUserId(transactionRecord.get("user_id").toString());
log.setTransactionId(transactionRecord.get("txansaction_id").toString()); log.setTransactionId(transactionRecord.get("txansaction_id").toString());
// log.setStatus(response.get("status").toString());
// log.setStatus(response.get("status").toString());
log.setErrorMessage(response.get("errorMessage").toString()); log.setErrorMessage(response.get("errorMessage").toString());
log.setStatusMessage(response.get("statusMessage").toString()); log.setStatusMessage(response.get("statusMessage").toString());
log.setStatusCode(response.get("statusCode").toString()); log.setStatusCode(response.get("statusCode").toString());
@ -149,9 +155,9 @@ public class PaymentStatusScheduler {
TransactionStatusLog saveLog = transactionStatusLogRepository.save(log); TransactionStatusLog saveLog = transactionStatusLogRepository.save(log);
TransactionResponse transRes = transactionResponseRepository.findById(Integer.parseInt(transactionRecord.get("id").toString())
).orElseThrow(() -> new Exception("TransactionResponse not found"));
TransactionResponse transRes = transactionResponseRepository
.findById(Integer.parseInt(transactionRecord.get("id").toString()))
.orElseThrow(() -> new Exception("TransactionResponse not found"));
transRes.setStatusCode(log.getStatusCode()); transRes.setStatusCode(log.getStatusCode());
transRes.setAmount(log.getAmount()); transRes.setAmount(log.getAmount());
@ -159,31 +165,33 @@ public class PaymentStatusScheduler {
transRes.setResponse(response.toString()); transRes.setResponse(response.toString());
transRes.setDate(log.getReceivedDate()); transRes.setDate(log.getReceivedDate());
transRes.setSchedulerUpdate(1); transRes.setSchedulerUpdate(1);
//updated scheduler_update column to 1
// updated scheduler_update column to 1
transactionResponseRepository.save(transRes); transactionResponseRepository.save(transRes);
Payments payments = paymentsRepository.findByBookingId(Integer.valueOf(String.valueOf(transRes.getBookingId())));
Payments payments = paymentsRepository
.findByBookingId(Integer.valueOf(String.valueOf(transRes.getBookingId())));
System.out.println("payments hello" + payments); System.out.println("payments hello" + payments);
if (payments != null && response.get("statusCode").toString().equals("0300")) { if (payments != null && response.get("statusCode").toString().equals("0300")) {
payments.setBookingDetails(payments.getBookingDetails());
payments.setBookingDetails(payments.getBookingDetails());
payments.setTransactionId(transRes.getTxansactionId()); payments.setTransactionId(transRes.getTxansactionId());
payments.setAmountReceived(Double.parseDouble(response.get("amount").toString())); payments.setAmountReceived(Double.parseDouble(response.get("amount").toString()));
payments.setPaymentStatus("Success"); payments.setPaymentStatus("Success");
Date date = new Date(payments.getCdate().getTime()); Date date = new Date(payments.getCdate().getTime());
// paymentsRepository.updatePaymentInfo(payments.getPaymentId(),payments.getTransactionId(),payments.getAmountReceived(),payments.getPaymentStatus(),transRes.getBookingId());
// paymentsRepository.updatePaymentInfo(payments.getPaymentId(),payments.getTransactionId(),payments.getAmountReceived(),payments.getPaymentStatus(),transRes.getBookingId());
bookingService.updateBookingStatus(transRes.getBookingId(), BookingDetails.BookingStatus.REFUNDED, "Booking Not Confirmed. Amount will be refunded shortly.");
//intiateRefund(transRes.getBookingId(), Integer.parseInt(transRes.getUserId()));
bookingService.updateBookingStatus(transRes.getBookingId(),
BookingDetails.BookingStatus.REFUNDED,
"Booking Not Confirmed. Amount will be refunded shortly.");
// intiateRefund(transRes.getBookingId(),
// Integer.parseInt(transRes.getUserId()));
} else if (response.get("statusCode").toString().equals("0300")) { } else if (response.get("statusCode").toString().equals("0300")) {
payments = new Payments(); payments = new Payments();
BookingDetails bookingsById = bookingService.getBookingsById(transRes.getBookingId()); BookingDetails bookingsById = bookingService.getBookingsById(transRes.getBookingId());
payments.setBookingDetails(bookingsById); payments.setBookingDetails(bookingsById);
payments.setTransactionId(transRes.getTxansactionId()); payments.setTransactionId(transRes.getTxansactionId());
@ -191,20 +199,26 @@ public class PaymentStatusScheduler {
payments.setPaymentStatus("Success"); payments.setPaymentStatus("Success");
payments.setCdate(new Date()); payments.setCdate(new Date());
//paymentsRepository.insertPaymentinfo(payments.getPaymentId(),payments.getTransactionId(),payments.getAmountReceived(),payments.getPaymentStatus(),transRes.getBookingId(),payments.getCdate() );
// paymentsRepository.insertPaymentinfo(payments.getPaymentId(),payments.getTransactionId(),payments.getAmountReceived(),payments.getPaymentStatus(),transRes.getBookingId(),payments.getCdate()
// );
bookingService.updateBookingStatus(transRes.getBookingId(), BookingDetails.BookingStatus.REFUNDED, "Booking Not Confirmed. Amount will be refunded shortly.");
// intiateRefund(transRes.getBookingId(), Integer.parseInt(transRes.getUserId()));
bookingService.updateBookingStatus(transRes.getBookingId(),
BookingDetails.BookingStatus.REFUNDED,
"Booking Not Confirmed. Amount will be refunded shortly.");
// intiateRefund(transRes.getBookingId(),
// Integer.parseInt(transRes.getUserId()));
} else { } else {
payments.setBookingDetails(payments.getBookingDetails()); payments.setBookingDetails(payments.getBookingDetails());
payments.setTransactionId(transRes.getTxansactionId()); payments.setTransactionId(transRes.getTxansactionId());
payments.setAmountReceived(Double.parseDouble(response.get("amount") != null ? response.get("amount").toString() : "0"));
payments.setAmountReceived(Double
.parseDouble(response.get("amount") != null ? response.get("amount").toString() : "0"));
payments.setPaymentStatus("Not Completed"); payments.setPaymentStatus("Not Completed");
payments.setCdate(new Date()); payments.setCdate(new Date());
paymentsRepository.save(payments); paymentsRepository.save(payments);
bookingService.updateBookingStatus(transRes.getBookingId(), BookingDetails.BookingStatus.PAYMENT_FAILURE, "Booking Not Confirmed. Amount Not Received.");
bookingService.updateBookingStatus(transRes.getBookingId(),
BookingDetails.BookingStatus.PAYMENT_FAILURE,
"Booking Not Confirmed. Amount Not Received.");
} }
updateRefundInfo(response, log); updateRefundInfo(response, log);
@ -219,10 +233,8 @@ public class PaymentStatusScheduler {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void updateRefundInfo(Map<String, Object> response, TransactionStatusLog log) { public void updateRefundInfo(Map<String, Object> response, TransactionStatusLog log) {
if (response.get("refundDdetails") != null) { if (response.get("refundDdetails") != null) {
@ -233,7 +245,8 @@ public class PaymentStatusScheduler {
if (refundDetails != null && !refundDetails.isEmpty()) { if (refundDetails != null && !refundDetails.isEmpty()) {
RefundResponse refundResponse = new RefundResponse(); RefundResponse refundResponse = new RefundResponse();
refundResponse.setAmount(response.get("amount") != null ? response.get("amount").toString() : ""); refundResponse.setAmount(response.get("amount") != null ? response.get("amount").toString() : "");
refundResponse.setBalaceAmount(response.get("balanceAmount") != null ? response.get("balanceAmount").toString() : "");
refundResponse.setBalaceAmount(
response.get("balanceAmount") != null ? response.get("balanceAmount").toString() : "");
refundResponse.setTxansactionId(log.getTransactionId()); refundResponse.setTxansactionId(log.getTransactionId());
Map<String, Object> mapRef = refundDetails.get(refundDetails.size() - 1); Map<String, Object> mapRef = refundDetails.get(refundDetails.size() - 1);
@ -258,7 +271,8 @@ public class PaymentStatusScheduler {
Double amt = Double.parseDouble(response.get("amount").toString()); Double amt = Double.parseDouble(response.get("amount").toString());
Double balAmt = Double.parseDouble(response.get("balanceAmount").toString()); Double balAmt = Double.parseDouble(response.get("balanceAmount").toString());
if (amt != balAmt) { if (amt != balAmt) {
RefundTransaction refundTrans = transactionService.getRefundTrans(saverRefundResponse.getBookingId());
RefundTransaction refundTrans = transactionService
.getRefundTrans(saverRefundResponse.getBookingId());
if (refundTrans != null) { if (refundTrans != null) {
refundTrans.setAmountRefunded(amt - balAmt); refundTrans.setAmountRefunded(amt - balAmt);
@ -266,57 +280,59 @@ public class PaymentStatusScheduler {
refundTrans.setRefundIdentifier(response.get("refundIdentifier").toString()); refundTrans.setRefundIdentifier(response.get("refundIdentifier").toString());
refundTrans.setCdate(new Date()); refundTrans.setCdate(new Date());
transactionService.saveRefundTransaction(refundTrans); transactionService.saveRefundTransaction(refundTrans);
} else { } else {
refundTrans = new RefundTransaction(); refundTrans = new RefundTransaction();
double refundAmt = amt - balAmt; double refundAmt = amt - balAmt;
System.out.println("refundAmt.."+refundAmt);
System.out.println("refundAmt.." + refundAmt);
refundTrans.setAmountRefunded(refundAmt); refundTrans.setAmountRefunded(refundAmt);
refundTrans.setRefundStatus("0400"); refundTrans.setRefundStatus("0400");
refundTrans.setRefundIdentifier(response.get("refundIdentifier").toString()); refundTrans.setRefundIdentifier(response.get("refundIdentifier").toString());
refundTrans.setCdate(new Date()); refundTrans.setCdate(new Date());
refundTrans.setTransactionId(log.getTransactionId()); refundTrans.setTransactionId(log.getTransactionId());
BookingDetails bookings = new BookingDetails(); BookingDetails bookings = new BookingDetails();
BookingDetails bookingsById = bookingService.getBookingsById(Integer.parseInt(log.getBookingId()));
System.out.println("bookingsById"+bookingsById.getBookingId());
BookingDetails bookingsById = bookingService
.getBookingsById(Integer.parseInt(log.getBookingId()));
System.out.println("bookingsById" + bookingsById.getBookingId());
bookings.setBookingId(bookingsById.getBookingId()); bookings.setBookingId(bookingsById.getBookingId());
refundTrans.setBookingDetails(bookings); refundTrans.setBookingDetails(bookings);
System.out.println(refundTrans.toString()); System.out.println(refundTrans.toString());
transactionService.saveRefundTransactionDetails(refundTrans); transactionService.saveRefundTransactionDetails(refundTrans);
} }
// bookingService.updateRefundStatus(saverRefundResponse.getBookingId(), BookingDetails.RefundStatus.COMPLETED);
bookingService.updateRefundStatusScheduler(saverRefundResponse.getBookingId(), BookingDetails.RefundStatus.COMPLETED);
// bookingService.updateRefundStatus(saverRefundResponse.getBookingId(),
// BookingDetails.RefundStatus.COMPLETED);
bookingService.updateRefundStatusScheduler(saverRefundResponse.getBookingId(),
BookingDetails.RefundStatus.COMPLETED);
} }
saveRefundClientInfo(refundDetails, log.getUserId(), log.getBookingId(), log.getTransactionId()); saveRefundClientInfo(refundDetails, log.getUserId(), log.getBookingId(), log.getTransactionId());
} }
} }
} }
public String saveRefundClientInfo(List<Map<String, Object>> refundDetail, String userId, String bookingId, String transactionId) {
public String saveRefundClientInfo(List<Map<String, Object>> refundDetail, String userId, String bookingId,
String transactionId) {
if (refundDetail == null || refundDetail.isEmpty()) { if (refundDetail == null || refundDetail.isEmpty()) {
return "error"; return "error";
} }
for (Map<String, Object> refund : refundDetail) { for (Map<String, Object> refund : refundDetail) {
RefundClientInfo refundClientInfo = new RefundClientInfo(); RefundClientInfo refundClientInfo = new RefundClientInfo();
refundClientInfo.setUserId(Integer.parseInt(userId)); refundClientInfo.setUserId(Integer.parseInt(userId));
refundClientInfo.setBookingId(Integer.parseInt(bookingId)); refundClientInfo.setBookingId(Integer.parseInt(bookingId));
refundClientInfo.setTransactionId(transactionId); refundClientInfo.setTransactionId(transactionId);
refundClientInfo.setClntRfndId(refund.get("clnt_rfnd_id") != null ? refund.get("clnt_rfnd_id").toString() : "");
refundClientInfo
.setClntRfndId(refund.get("clnt_rfnd_id") != null ? refund.get("clnt_rfnd_id").toString() : "");
refundClientInfo.setArnNo(refund.get("ARN_Number") != null ? refund.get("ARN_Number").toString() : ""); refundClientInfo.setArnNo(refund.get("ARN_Number") != null ? refund.get("ARN_Number").toString() : "");
refundClientInfo.setGetRefTxnDate(refund.get("REF_TXN_DATE") != null ? refund.get("REF_TXN_DATE").toString() : "");
refundClientInfo.setRefTxnAmt(refund.get("REF_TXN_AMT") != null ? refund.get("REF_TXN_AMT").toString() : "");
refundClientInfo
.setGetRefTxnDate(refund.get("REF_TXN_DATE") != null ? refund.get("REF_TXN_DATE").toString() : "");
refundClientInfo
.setRefTxnAmt(refund.get("REF_TXN_AMT") != null ? refund.get("REF_TXN_AMT").toString() : "");
refundClientInfo.setRefTxnId(refund.get("REF_TXN_ID") != null ? refund.get("REF_TXN_ID").toString() : ""); refundClientInfo.setRefTxnId(refund.get("REF_TXN_ID") != null ? refund.get("REF_TXN_ID").toString() : "");
refundClientInfo.setStatus(refund.get("STATUS") != null ? refund.get("STATUS").toString() : ""); refundClientInfo.setStatus(refund.get("STATUS") != null ? refund.get("STATUS").toString() : "");
refundClientInfo.setSrno(refund.get("SR_NO") != null ? refund.get("SR_NO").toString() : ""); refundClientInfo.setSrno(refund.get("SR_NO") != null ? refund.get("SR_NO").toString() : "");
@ -327,24 +343,22 @@ public class PaymentStatusScheduler {
return "success"; return "success";
} }
//need to be commented
// need to be commented
// @Transactional // @Transactional
// public void intiateRefund(int bookingId, int userId) throws Exception { // public void intiateRefund(int bookingId, int userId) throws Exception {
// List<BookingCalendar> bc = calendarService.getCalendarByBookingId(bookingId);
// if (bc != null && bc.isEmpty()) {
// String s = paymentGatewayServiceImpl.refundTheAmount(bookingId, userId);
// if (s.equals("Refunded")) {
// bookingService.updateRefundStatus(bookingId, BookingDetails.RefundStatus.COMPLETED);
// }
// } else {
// bookingService.updateRefundStatus(bookingId, BookingDetails.RefundStatus.FAILURE);
// }
// List<BookingCalendar> bc = calendarService.getCalendarByBookingId(bookingId);
// if (bc != null && bc.isEmpty()) {
// String s = paymentGatewayServiceImpl.refundTheAmount(bookingId, userId);
// if (s.equals("Refunded")) {
// bookingService.updateRefundStatus(bookingId,
// BookingDetails.RefundStatus.COMPLETED);
// }
// } else {
// bookingService.updateRefundStatus(bookingId,
// BookingDetails.RefundStatus.FAILURE);
// }
// } // }
} }

6
src/main/java/com/gcc/communityHall/repository/BookingDetailsRepository.java

@ -1766,7 +1766,7 @@ public interface BookingDetailsRepository extends JpaRepository<BookingDetails,
"LEFT JOIN settlement s ON bd.booking_id = s.booking_details_booking_id " + "LEFT JOIN settlement s ON bd.booking_id = s.booking_details_booking_id " +
"LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " + "LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " +
"WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " + "WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " +
"AND bd.booking_status NOT IN ('PENDING','CANCELED','REJECTED') " +
"AND bd.booking_status IN ('APPROVED') and bd.refund_status in ('WAITING','FAILURE') " +
"AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " + "AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " +
"ORDER BY bd.booking_id ASC", nativeQuery = true) "ORDER BY bd.booking_id ASC", nativeQuery = true)
List<Map<String, Object>> findSixMonthOldNonCancelledRejectedBookings(); List<Map<String, Object>> findSixMonthOldNonCancelledRejectedBookings();
@ -1788,7 +1788,7 @@ public interface BookingDetailsRepository extends JpaRepository<BookingDetails,
"LEFT JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + "LEFT JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " +
"LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " + "LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " +
"WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " + "WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " +
"AND bd.booking_status = 'CANCELED' " +
"AND bd.booking_status = 'CANCELED' and bd.refund_status != 'COMPLETED' " +
"AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " + "AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " +
"ORDER BY bd.booking_id ASC", nativeQuery = true) "ORDER BY bd.booking_id ASC", nativeQuery = true)
List<Map<String, Object>> findSixMonthOldCancelledBookings(); List<Map<String, Object>> findSixMonthOldCancelledBookings();
@ -1810,7 +1810,7 @@ public interface BookingDetailsRepository extends JpaRepository<BookingDetails,
"LEFT JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " + "LEFT JOIN hall_details hd ON bd.hall_details_hall_id = hd.hall_id " +
"LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " + "LEFT JOIN transaction_response tr ON bd.booking_id = tr.booking_id " +
"WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " + "WHERE datediff(CURRENT_DATE, bd.booking_date) > 180 " +
"AND bd.booking_status = 'REJECTED' " +
"AND bd.booking_status in ('REJECTED','GCC_BLOCKED') and bd.refund_status != 'COMPLETED' " +
"AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " + "AND (bd.mail_sent IS NULL OR bd.mail_sent = 0) " +
"ORDER BY bd.booking_id ASC", nativeQuery = true) "ORDER BY bd.booking_id ASC", nativeQuery = true)
List<Map<String, Object>> findSixMonthOldRejectedBookings(); List<Map<String, Object>> findSixMonthOldRejectedBookings();

8
src/main/java/com/gcc/communityHall/repository/LoginRepository.java

@ -13,13 +13,13 @@ import java.util.Map;
@Repository @Repository
public interface LoginRepository extends JpaRepository<Login, Long> { public interface LoginRepository extends JpaRepository<Login, Long> {
@Query(value = "SELECT * FROM login where mobile_number=:mobileNo and password=:pin", nativeQuery = true)
@Query(value = "SELECT * FROM login where mobile_number=:mobileNo and password=:pin and is_active = 1 and is_delete = 0", nativeQuery = true)
Login findByMobileNoAndPin(long mobileNo, String pin); Login findByMobileNoAndPin(long mobileNo, String pin);
@Query(value = "SELECT a FROM Login a WHERE a.mobileNumber = ?1")
@Query(value = "SELECT a FROM Login a WHERE a.mobileNumber = ?1 and a.isActive = true and a.isDelete = false")
Login checkUserbyMobile(long mobileNo); Login checkUserbyMobile(long mobileNo);
@Query(value = "SELECT * FROM login where name=:username and password=:pass LIMIT 1", nativeQuery = true)
@Query(value = "SELECT * FROM login where name=:username and password=:pass and is_active = 1 and is_delete = 0 LIMIT 1", nativeQuery = true)
Login findByUsernameAndPass(String username, String pass); Login findByUsernameAndPass(String username, String pass);
@Query(value = "SELECT " + @Query(value = "SELECT " +
@ -53,7 +53,7 @@ public interface LoginRepository extends JpaRepository<Login, Long> {
"ORDER BY cast(l.zone as unsigned)", nativeQuery = true) "ORDER BY cast(l.zone as unsigned)", nativeQuery = true)
List<Map<String, Object>> findActiveLogins(); List<Map<String, Object>> findActiveLogins();
@Query(value = "SELECT * FROM login WHERE id = :id", nativeQuery = true)
@Query(value = "SELECT * FROM login WHERE id = :id and is_active = 1 and is_delete = 0", nativeQuery = true)
Login findLoginById(int id); Login findLoginById(int id);
@Query(value = "SELECT COUNT(*) FROM login WHERE mobile_number = :mobileNo AND is_delete = 0", nativeQuery = true) @Query(value = "SELECT COUNT(*) FROM login WHERE mobile_number = :mobileNo AND is_delete = 0", nativeQuery = true)

287
src/main/java/com/gcc/communityHall/service/BookingService.java

@ -17,242 +17,247 @@ import com.gcc.communityHall.entity.EbDetails;
import com.gcc.communityHall.entity.GccBlockingDate; import com.gcc.communityHall.entity.GccBlockingDate;
public interface BookingService { public interface BookingService {
BookingDetails getBookingsById(int BookingId);
BookingDetails getBookingsById(int BookingId);
// ak
BookingDetails getBookingByRefId(String refId);
// ak
BookingDetails getBookingByRefId(String refId);
// ak
void migrateOldBookingsToRefId();
// ak
void migrateOldBookingsToRefId();
BookingDetails updateBookingDetails(BookingDetails bd);
BookingDetails updateBookingDetails(BookingDetails bd);
public String confirmTheDateAndSlot(String fromDate, String toDate, int days, int fromStartingSlot,
int fromEndingSlot, int toStartingSlot, int toEndingSlot, int bookingId, int userId);
public String confirmTheDateAndSlot(String fromDate, String toDate, int days, int fromStartingSlot,
int fromEndingSlot, int toStartingSlot, int toEndingSlot, int bookingId, int userId);
public Map<String, Object> saveBookingDetails(Map<String, Object> formData);
public Map<String, Object> saveBookingDetails(Map<String, Object> formData);
public BookingDetails updateBookingStatustoGCCBlocked(BookingDetails bookingDetails);
public BookingDetails updateBookingStatustoGCCBlocked(BookingDetails bookingDetails);
public BookingDetails updateBookingStatus(int bookingId, BookingDetails.BookingStatus status, String comments);
public BookingDetails updateBookingStatus(int bookingId, BookingDetails.BookingStatus status, String comments);
public BookingDetails updateBookingStatusById(int bookingId, BookingDetails.BookingStatus status, String comments);
public BookingDetails updateBookingStatusById(int bookingId, BookingDetails.BookingStatus status, String comments);
public EbDetails updateEbDetails(int bookingId, double startUnit, double endUnit, char status);
public EbDetails updateEbDetails(int bookingId, double startUnit, double endUnit, char status);
// typeOfCancel depends { }
String cancelBooking(int bookingId, BookingDetails.BookingStatus currentStatus, String comments);
// typeOfCancel depends { }
String cancelBooking(int bookingId, BookingDetails.BookingStatus currentStatus, String comments);
public String confirmBooking(int bookingId);
public String confirmBooking(int bookingId);
public BookingDetails getBookingDetailsWithSettlement(int settlementId);
public BookingDetails getBookingDetailsWithSettlement(int settlementId);
// sreeja
List<BookingDetails> getPresentsEventsByUserId(Integer hallId);
// sreeja
List<BookingDetails> getPresentsEventsByUserId(Integer hallId);
List<BookingDetails> getPastsEventsByUserId(Integer hallId);
List<BookingDetails> getPastsEventsByUserId(Integer hallId);
List<BookingDetails> getFuturesEventsByUserId(Integer hallId);
List<BookingDetails> getFuturesEventsByUserId(Integer hallId);
List<BookingDetails> getSettlementList(Integer hallId);
List<BookingDetails> getSettlementList(Integer hallId);
public List<BookingDetails> getFilteredBookings(LocalDate fromDate, LocalDate toDate, List<Long> hallIds);
public List<BookingDetails> getFilteredBookings(LocalDate fromDate, LocalDate toDate, List<Long> hallIds);
public List<Map<String, Object>> getPastData(int hall_id);
public List<Map<String, Object>> getPastData(int hall_id);
public String processEbDetailsAndDamage(
int bookingId, int ebId,
double startingReading, double endingReading,
float usedUnit, double ebAmount,
String assetNames[], String comments[], int quantities[], Double assetAmounts[], MultipartFile assetImages[]);
public String processEbDetailsAndDamage(
int bookingId, int ebId,
double startingReading, double endingReading,
float usedUnit, double ebAmount,
String assetNames[], String comments[], int quantities[], Double assetAmounts[],
MultipartFile assetImages[]);
public int checkUserBookinglimitation(int userId);
public int checkUserBookinglimitation(int userId);
List<BookingDetails> getAllBookingsByUserId(Integer userId);
List<BookingDetails> getAllBookingsByUserId(Integer userId);
List<Map<String, Object>> getAllBookingEventsByUserId(Integer userId);
List<Map<String, Object>> getAllBookingEventsByUserId(Integer userId);
// List<BookingDetails> getAllBookingDetailsWithStatus(String fromDate, String
// toDate, String bookingStatus);
// List<BookingDetails> getAllBookingDetailsWithStatus(String fromDate, String
// toDate, String bookingStatus);
// List<Object[]> getAllPaymentsDetails( String fromDate, String toDate);
// List<Object[]> getAllPaymentsDetails( String fromDate, String toDate);
List<Object[]> getBookingUserDetailsReport(String fromDate, String toDate);
List<Object[]> getBookingUserDetailsReport(String fromDate, String toDate);
List<Object[]> getBookingHallDetailsReport(String fromDate, String toDate);
List<Object[]> getBookingHallDetailsReport(String fromDate, String toDate);
List<GccBlockingDate> getBlockedEvents(LocalDate fromDate, LocalDate toDate, List<Long> hallIds);
List<GccBlockingDate> getBlockedEvents(LocalDate fromDate, LocalDate toDate, List<Long> hallIds);
List<Map<String, Object>> getOfflineBookings();
List<Map<String, Object>> getOfflineBookings();
List<BookingCalendar> getBookedslots(LocalDate fromDate, LocalDate endDate, List<Long> hallIdList);
List<BookingCalendar> getBookedslots(LocalDate fromDate, LocalDate endDate, List<Long> hallIdList);
BookingDetails updateCancelledBookingStatus(int bookingId, BookingStatus status, String comments);
BookingDetails updateCancelledBookingStatus(int bookingId, BookingStatus status, String comments);
BookingDetails updateRefundStatus(int bookingId, RefundStatus status);
BookingDetails updateRefundStatus(int bookingId, RefundStatus status);
// officer service
List<BookingDetails> getAllBookingDetailsByZone(String fromDate, String toDate, String zone);
// officer service
List<BookingDetails> getAllBookingDetailsByZone(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingDetailsByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<BookingDetails> getAllBookingDetailsByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<Object[]> getAllPaymentsDetailsByZone(String fromDate, String toDate, String zone);
List<Object[]> getAllPaymentsDetailsByZone(String fromDate, String toDate, String zone);
List<Object[]> getBookingHallDetailsReportByZone(String fromDate, String toDate, String zone);
List<Object[]> getBookingHallDetailsReportByZone(String fromDate, String toDate, String zone);
Optional<String> updateBookingDatesAndCalendar(int bookingId, String startDate, String endDate);
Optional<String> updateBookingDatesAndCalendar(int bookingId, String startDate, String endDate);
List<Object[]> getBookingHallDetailsReportByZone1(String fromDate, String toDate, String zone, Integer hallId);
Optional<String> updateBookingDatesAndCalendar(int bookingId, String startDate, String endDate,
int startingSlot, int endingSlot);
List<Object> getGccBlockingEvents(String hallId);
List<Object[]> getBookingHallDetailsReportByZone1(String fromDate, String toDate, String zone, Integer hallId);
int getBlockedHallCount(String blockingReason, Date startDate, Date endDate);
List<Object> getGccBlockingEvents(String hallId);
@Transactional
void cancelAllBookings(String fromDate, String toDate, List<Long> hallIdsList,
String reasonforblocking, List<String> selectedBookings, String updatedBy, String[] descriptions,
MultipartFile[] documents);
int getBlockedHallCount(String blockingReason, Date startDate, Date endDate);
@Transactional
void blockWithoutCancellingBookings(String fromDate, String toDate, List<Long> hallIdsList,
String reasonforblocking, String updatedBy, String[] descriptions,
MultipartFile[] documents);
@Transactional
void cancelAllBookings(String fromDate, String toDate, List<Long> hallIdsList,
String reasonforblocking, List<String> selectedBookings, String updatedBy, String[] descriptions,
MultipartFile[] documents);
List<BookingDetails> findBookingDetailsByBookingId(Long bookingId);
@Transactional
void blockWithoutCancellingBookings(String fromDate, String toDate, List<Long> hallIdsList,
String reasonforblocking, String updatedBy, String[] descriptions,
MultipartFile[] documents);
// admin dashboard
Map<String, Map<String, Integer>> getBookingStatistics(LocalDate fromDate, LocalDate toDate, String zone,
String division, Integer hallid, String userType);
List<BookingDetails> findBookingDetailsByBookingId(Long bookingId);
public List<Map<String, Object>> getBookingDetailsByHallId(int hallId);
// admin dashboard
Map<String, Map<String, Integer>> getBookingStatistics(LocalDate fromDate, LocalDate toDate, String zone,
String division, Integer hallid, String userType);
// officer dashboard
Map<String, Map<String, Integer>> getOfficerDashboard(LocalDate fromDate, LocalDate toDate, String zone,
String division, Integer hallid, String userType);
public List<Map<String, Object>> getBookingDetailsByHallId(int hallId);
List<Map<String, Object>> getHallDetailsForOfficer(Integer hallIid);
// List<Object[]> getAllPaymentsDetails(String fromDate, String toDate, String
// paymentStatus);
// admin reports
// officer dashboard
Map<String, Map<String, Integer>> getOfficerDashboard(LocalDate fromDate, LocalDate toDate, String zone,
String division, Integer hallid, String userType);
List<Object[]> getBookingDetailsByBookingDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Map<String, Object>> getHallDetailsForOfficer(Integer hallIid);
// List<Object[]> getAllPaymentsDetails(String fromDate, String toDate, String
// paymentStatus);
// admin reports
List<Object[]> getBookingDetailsByEventDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Object[]> getBookingDetailsByBookingDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Object[]> getBookingDetailsByBookingDateWithStatus(String fromDate, String toDate, String bookingStatus,
String zone, String division, Integer hallid);
List<Object[]> getBookingDetailsByEventDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Object[]> getBookingDetailsByEventDateWithStatus(String fromDate, String toDate, String bookingStatus,
String zone, String division, Integer hallid);
List<Object[]> getBookingDetailsByBookingDateWithStatus(String fromDate, String toDate, String bookingStatus,
String zone, String division, Integer hallid);
List<Object[]> getAllPaymentsDetails(String fromDate, String toDate, String paymentStatus, String zone,
String division, Integer hallid);
List<Object[]> getBookingDetailsByEventDateWithStatus(String fromDate, String toDate, String bookingStatus,
String zone, String division, Integer hallid);
List<Object[]> getBookingHallDetailsReportByBookingDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Object[]> getAllPaymentsDetails(String fromDate, String toDate, String paymentStatus, String zone,
String division, Integer hallid);
List<Object[]> getBookingHallDetailsReportByEventDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<Object[]> getBookingHallDetailsReportByBookingDate(String fromDate, String toDate, String zone,
String division,
Integer hallid);
List<BookingDetails> getAllBookingsettlementDetailsByBookingDate(String fromDate, String toDate);
List<Object[]> getBookingHallDetailsReportByEventDate(String fromDate, String toDate, String zone, String division,
Integer hallid);
List<BookingDetails> getAllBookingsettlementDetailsByBookingDateWithStatus(String fromDate, String toDate,
String refundStatus);
List<BookingDetails> getAllBookingsettlementDetailsByBookingDate(String fromDate, String toDate);
List<BookingDetails> getAllBookingsettlementDetailsByEventDate(String fromDate, String toDate);
List<BookingDetails> getAllBookingsettlementDetailsByBookingDateWithStatus(String fromDate, String toDate,
String refundStatus);
List<BookingDetails> getAllBookingsettlementDetailsByEventDateWithStatus(String fromDate, String toDate,
String refundStatus);
List<BookingDetails> getAllBookingsettlementDetailsByEventDate(String fromDate, String toDate);
List<BookingDetails> getAllBookingDetailsBookingDateByZone(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingsettlementDetailsByEventDateWithStatus(String fromDate, String toDate,
String refundStatus);
List<BookingDetails> getAllBookingDetailsEventDateByZone(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingDetailsBookingDateByZone(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingDetailsBookingDateByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<BookingDetails> getAllBookingDetailsEventDateByZone(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingDetailsEventDateByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<BookingDetails> getAllBookingDetailsBookingDateByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByBookingDate(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingDetailsEventDateByZoneWithStatus(String fromDate, String toDate, String zone,
String bookingStatus);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByEventDate(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByBookingDate(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByBookingDateWithStatus(String fromDate, String toDate,
String zone, String refundStatus);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByEventDate(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByEventDateWithStatus(String fromDate, String toDate,
String zone, String refundStatus);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByBookingDateWithStatus(String fromDate, String toDate,
String zone, String refundStatus);
List<Object[]> getBookingHallDetailsReportByZoneByBookingDate(String fromDate, String toDate, String zone);
List<BookingDetails> getAllBookingsettlementDetailsByZoneByEventDateWithStatus(String fromDate, String toDate,
String zone, String refundStatus);
List<Object[]> getBookingHallDetailsReportByZoneByEventDate(String fromDate, String toDate, String zone);
List<Object[]> getBookingHallDetailsReportByZoneByBookingDate(String fromDate, String toDate, String zone);
List<Object[]> getBookingHallDetailsReportByZoneByBookingDateHallname(String fromDate, String toDate, String zone,
Integer hallId);
List<Object[]> getBookingHallDetailsReportByZoneByEventDate(String fromDate, String toDate, String zone);
List<Object[]> getBookingHallDetailsReportByZoneByEventDateHallname(String fromDate, String toDate, String zone,
Integer hallId);
List<Object[]> getBookingHallDetailsReportByZoneByBookingDateHallname(String fromDate, String toDate, String zone,
Integer hallId);
BookingDetails saveebdetails(int bookingId, double startingReading, MultipartFile startingReadingimage);
List<Object[]> getBookingHallDetailsReportByZoneByEventDateHallname(String fromDate, String toDate, String zone,
Integer hallId);
String confirmStateBooking(int bookingId);
BookingDetails saveebdetails(int bookingId, double startingReading, MultipartFile startingReadingimage);
String uploadNOCFile(MultipartFile file, int bookingId);
String confirmStateBooking(int bookingId);
// gccapps
List<BookingDetails> getApprovedBookingDetails();
String uploadNOCFile(MultipartFile file, int bookingId);
List<BookingDetails> getRejectedBookingDetails();
// gccapps
List<BookingDetails> getApprovedBookingDetails();
List<Object[]> getAllPaymentsDetails(String fromDate, String toDate);
List<BookingDetails> getRejectedBookingDetails();
List<BookingDetails> getPastsEvents();
List<Object[]> getAllPaymentsDetails(String fromDate, String toDate);
List<BookingDetails> getPresentsEvents();
List<BookingDetails> getPastsEvents();
List<BookingDetails> getFuturesEvents();
List<BookingDetails> getPresentsEvents();
List<BookingDetails> getSettlementApprovedList();
List<BookingDetails> getFuturesEvents();
List<Map<String, Object>> getHallDetails(Integer hall_id);
List<BookingDetails> getSettlementApprovedList();
List<BookingDetails> getWaitingforNOCapproval();
List<Map<String, Object>> getHallDetails(Integer hall_id);
List<Object[]> getAllExtraPaymentsDetails(String fromDate, String toDate, String paymentStatus, String zone,
String division, Integer hallid);
List<BookingDetails> getWaitingforNOCapproval();
// developer
List<Object[]> getTransactionresponse(String fromDate, String toDate, Long bookingId, Long hallId);
List<Object[]> getAllExtraPaymentsDetails(String fromDate, String toDate, String paymentStatus, String zone,
String division, Integer hallid);
List<Object[]> getRefundResponse(String fromDate, String toDate, Long bookingId);
// developer
List<Object[]> getTransactionresponse(String fromDate, String toDate, Long bookingId, Long hallId);
List<Object[]> getBookingCalendarDetails(String fromDate, String toDate, Long bookingId, String hallName);
List<Object[]> getRefundResponse(String fromDate, String toDate, Long bookingId);
List<BookingDetails> getBookingsByDateAndHall(String bookingDate, Long hallId);
List<Object[]> getBookingCalendarDetails(String fromDate, String toDate, Long bookingId, String hallName);
BookingDetails updateRefundStatusScheduler(int bookingId, RefundStatus status);
List<BookingDetails> getBookingsByDateAndHall(String bookingDate, Long hallId);
List<Object[]> getCounterWiseBookingCount(String fromDate, String toDate);
BookingDetails updateRefundStatusScheduler(int bookingId, RefundStatus status);
List<Object[]> getHallWiseBookingDetails(String fromDate, String toDate, String CounterId);
List<Object[]> getCounterWiseBookingCount(String fromDate, String toDate);
List<Object[]> getBookingDetailsForAllHalls(String fromDate, String toDate, String CounterId, Integer hallid);
List<Object[]> getHallWiseBookingDetails(String fromDate, String toDate, String CounterId);
List<Object[]> getCounterWiseBookingDetails(String fromDate, String toDate);
List<Object[]> getBookingDetailsForAllHalls(String fromDate, String toDate, String CounterId, Integer hallid);
List<Object> getZoneWiseBookingList(String fromDate, String toDate);
List<Object[]> getCounterWiseBookingDetails(String fromDate, String toDate);
List<Object> getAllHallWiseBookingList(String fromDate, String toDate);
List<Object> getZoneWiseBookingList(String fromDate, String toDate);
List<Object> getAllCounterWiseBookingList(String fromDate, String toDate);
List<Object> getAllHallWiseBookingList(String fromDate, String toDate);
// ak
List<Object[]> getSettlementInitiatedReport(String fromDate, String toDate);
List<Object> getAllCounterWiseBookingList(String fromDate, String toDate);
List<GccBlockingDate> getBlockedEvents();
// ak
List<Object[]> getSettlementInitiatedReport(String fromDate, String toDate);
List<GccBlockingDate> getBlockedEvents();
} }

381
src/main/java/com/gcc/communityHall/service/Impl/BookingServiceImpl.java

@ -2288,6 +2288,154 @@ public class BookingServiceImpl implements BookingService {
return Optional.of("Booking not found."); return Optional.of("Booking not found.");
} }
/**
* Overloaded version that also updates startingSlot and endingSlot.
* Used by the /reschedule-dates endpoint when the user has changed the slot.
*/
@Override
public Optional<String> updateBookingDatesAndCalendar(int bookingId, String startDat, String endDat,
int startingSlot, int endingSlot) {
// If slots are 0 (not provided by client), fall through to the existing method
if (startingSlot == 0 && endingSlot == 0) {
return updateBookingDatesAndCalendar(bookingId, startDat, endDat);
}
Optional<BookingDetails> optionalBookingDetails = bookingDetailsRepository.findById(bookingId);
if (optionalBookingDetails.isPresent()) {
BookingDetails bookingDetails = optionalBookingDetails.get();
String starting = bookingDetails.getStartDate();
int hallId = bookingDetails.getHallDetails().getHallId();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate startDate = LocalDate.parse(startDat, formatter);
LocalDate endDate = LocalDate.parse(endDat, formatter);
// Temporarily apply new slots for calendar-check logic
int origStartSlot = bookingDetails.getStartingSlot();
int origEndSlot = bookingDetails.getEndingSlot();
bookingDetails.setStartingSlot(startingSlot);
bookingDetails.setEndingSlot(endingSlot);
// Clear old calendar entries
List<BookingCalendar> existingCalendars = bookingCalendarRepository
.getCancellingdata1(String.valueOf(bookingId));
for (BookingCalendar calendar : existingCalendars) {
if (calendar.getBookingId_1() != null && calendar.getBookingId_1().equals(String.valueOf(bookingId))) {
calendar.setMorningSlot(false);
calendar.setBookingId_1(null);
}
if (calendar.getBookingId_2() != null && calendar.getBookingId_2().equals(String.valueOf(bookingId))) {
calendar.setEveningSlot(false);
calendar.setBookingId_2(null);
}
bookingCalendarRepository.save(calendar);
}
String slotOccExpMsg = "Dates are already occupied. Please select another date.";
int i = 0;
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
BookingCalendar bookingCalendar = bookingCalendarRepository.findByBdateAndHallId(date, hallId);
if (bookingCalendar != null) {
if ((date.equals(startDate) && startingSlot == 1 && bookingCalendar.isMorningSlot()) ||
(date.equals(startDate) && startingSlot == 2 && bookingCalendar.isEveningSlot()) ||
(date.equals(endDate) && endingSlot == 1 && bookingCalendar.isMorningSlot()) ||
(date.equals(endDate) && endingSlot == 2 && bookingCalendar.isEveningSlot())) {
// Restore original slots before throwing
bookingDetails.setStartingSlot(origStartSlot);
bookingDetails.setEndingSlot(origEndSlot);
throw new SlotOccupiedException(slotOccExpMsg);
} else if (bookingCalendar.isMorningSlot() && bookingCalendar.isEveningSlot()) {
bookingDetails.setStartingSlot(origStartSlot);
bookingDetails.setEndingSlot(origEndSlot);
throw new SlotOccupiedException(slotOccExpMsg);
} else if (!date.equals(endDate) && i != 0 && i != Math.round(bookingDetails.getNoOfDays() - 1)
&& (bookingCalendar.isMorningSlot() || bookingCalendar.isEveningSlot())) {
bookingDetails.setStartingSlot(origStartSlot);
bookingDetails.setEndingSlot(origEndSlot);
throw new SlotOccupiedException(slotOccExpMsg);
} else if (date.equals(endDate) && endingSlot == 2 && bookingCalendar.isMorningSlot()
&& i != 0 && i == Math.round(bookingDetails.getNoOfDays() - 1)) {
bookingDetails.setStartingSlot(origStartSlot);
bookingDetails.setEndingSlot(origEndSlot);
throw new SlotOccupiedException(slotOccExpMsg);
}
} else {
String uniqueId = date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId;
bookingCalendar = new BookingCalendar();
bookingCalendar.setBdate(date);
bookingCalendar.setHallId(hallId);
bookingCalendar.setIs_booked(0);
bookingCalendar.setIs_active(true);
bookingCalendar.setUnique_id(uniqueId);
}
// Mark slots
if (date.equals(startDate)) {
if (startingSlot == 1) {
bookingCalendar.setMorningSlot(true);
bookingCalendar.setBookingId_1(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
if (!date.equals(endDate)) {
bookingCalendar.setEveningSlot(true);
bookingCalendar.setBookingId_2(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
} else if (startDate.equals(endDate) && startingSlot == 1 && endingSlot == 2) {
bookingCalendar.setEveningSlot(true);
bookingCalendar.setBookingId_2(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
}
} else {
bookingCalendar.setEveningSlot(true);
bookingCalendar.setBookingId_2(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
}
} else if (date.equals(endDate)) {
if (endingSlot == 1) {
bookingCalendar.setMorningSlot(true);
bookingCalendar.setBookingId_1(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
} else {
bookingCalendar.setEveningSlot(true);
bookingCalendar.setBookingId_2(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
if (endingSlot == 2) {
bookingCalendar.setMorningSlot(true);
bookingCalendar.setBookingId_1(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 1);
}
}
} else {
bookingCalendar.setMorningSlot(true);
bookingCalendar.setEveningSlot(true);
bookingCalendar.setBookingId_1(String.valueOf(bookingId));
bookingCalendar.setBookingId_2(String.valueOf(bookingId));
bookingCalendar.setIs_booked(bookingCalendar.getIs_booked() + 2);
}
bookingCalendarRepository.save(bookingCalendar);
i++;
}
// Persist new dates and slots
updateResheduledBookingDetails(bookingId, startDat, endDat, startingSlot, endingSlot);
String rescheduledmsg = "Your booking ID " + bookingId + " on " + starting
+ " has been successfully rescheduled to " + startDate
+ ". Thanks for using the GCC Community Hall Booking System.";
String urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to="
+ bookingDetails.getUsers().getMobileNo() + "&from=GCCCRP&body=" + rescheduledmsg
+ "&entityid=1401572690000011081&templateid=1407172346565044999";
String rescheduleMsg = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to="
+ bookingDetails.getUsers().getMobileNo()
+ "&v=1.1&format=json&msg_type=TEXT&method=SENDMESSAGE&msg=Your+booking+with+ID+" + bookingId
+ "+on+" + starting + "+has+been+successfully+rescheduled+to+" + startDate
+ "+.+%0AThank+you+for+using+the+GCC+Community+Hall+Booking+System.";
whatsappMsgServiceImpl.sendMsg(rescheduleMsg);
whatsappMsgServiceImpl.sendSMS(urlString);
return Optional.of("Booking dates updated successfully.");
}
return Optional.of("Booking not found.");
}
private void updateResheduledBookingDetails(int bookingId, String startDate, String endDate) { private void updateResheduledBookingDetails(int bookingId, String startDate, String endDate) {
Optional<BookingDetails> book = bookingDetailsRepository.findById(bookingId); Optional<BookingDetails> book = bookingDetailsRepository.findById(bookingId);
BookingDetails bookingDetails = book.get(); BookingDetails bookingDetails = book.get();
@ -2316,6 +2464,37 @@ public class BookingServiceImpl implements BookingService {
bookingHistoryRepository.save(bookingHistory); bookingHistoryRepository.save(bookingHistory);
} }
/** Overload – also persists updated starting/ending slot values. */
private void updateResheduledBookingDetails(int bookingId, String startDate, String endDate,
int startingSlot, int endingSlot) {
Optional<BookingDetails> book = bookingDetailsRepository.findById(bookingId);
BookingDetails bookingDetails = book.get();
bookingDetails.setScheduleCount(bookingDetails.getScheduleCount() + 1);
if (bookingDetails.getReason().equals("Commercial") || bookingDetails.getReason().equals("State Govt Event")
|| bookingDetails.getReason().equals("Central Govt Event")) {
bookingDetails.setBookingStatus(BookingStatus.WAITING_FOR_NOC);
}
BookingHistory bookingHistory = new BookingHistory();
bookingHistory.setStartDate(bookingDetails.getStartDate());
bookingHistory.setEndDate(bookingDetails.getEndDate());
bookingHistory.setComments(bookingDetails.getComments());
bookingHistory.setBookingDetails(bookingDetails);
bookingHistory.setBookingStatus(BookingStatus.APPROVED);
bookingHistory.setUpdatedBy(userSession.getDispayName());
bookingHistory.setCdate(new Date());
bookingHistory.setRefundStatus(bookingDetails.getRefundStatus());
bookingDetails.setStartDate(startDate);
bookingDetails.setEndDate(endDate);
// ── Persist the updated slots ──────────────────────────────────────
bookingDetails.setStartingSlot(startingSlot);
bookingDetails.setEndingSlot(endingSlot);
bookingDetails.setComments("slots Resheduled the Dates");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
bookingDetails.setUpdatedDate(LocalDateTime.now().format(formatter));
bookingDetailsRepository.save(bookingDetails);
bookingHistoryRepository.save(bookingHistory);
}
@Override @Override
public List<Object[]> getBookingHallDetailsReportByZone1(String fromDate, String toDate, String zone, public List<Object[]> getBookingHallDetailsReportByZone1(String fromDate, String toDate, String zone,
Integer hallId) { Integer hallId) {
@ -2361,15 +2540,8 @@ public class BookingServiceImpl implements BookingService {
String reasonforblocking, List<String> selectedBookings, String updatedBy, String[] descriptions, String reasonforblocking, List<String> selectedBookings, String updatedBy, String[] descriptions,
MultipartFile[] documents) { MultipartFile[] documents) {
if (selectedBookings != null && !selectedBookings.isEmpty()) { if (selectedBookings != null && !selectedBookings.isEmpty()) {
// ── Collect cancelled user booking IDs (used later to build ONE GCC record) ──
List<Integer> cancelledBookingIds = new ArrayList<>();
// ── Phase 1: Cancel each selected booking (BookingDetails + BookingCalendar
// slots) ──
for (String bookingIdStr : selectedBookings) { for (String bookingIdStr : selectedBookings) {
Integer bookingId = Integer.parseInt(bookingIdStr); Integer bookingId = Integer.parseInt(bookingIdStr);
System.out.println("bookingId..." + bookingId);
Optional<BookingDetails> optionalBooking = bookingDetailsRepository.findById(bookingId); Optional<BookingDetails> optionalBooking = bookingDetailsRepository.findById(bookingId);
if (optionalBooking.isPresent()) { if (optionalBooking.isPresent()) {
@ -2395,10 +2567,102 @@ public class BookingServiceImpl implements BookingService {
updateBookingStatus(bb); updateBookingStatus(bb);
} }
updateBookingStatusById(booking.getBookingId(), BookingStatus.GCC_BLOCKED,
reasonforblocking);
// GCC blocking entry
GccBlockingDate gcc = new GccBlockingDate();
gcc.setStartDate(convertStringToDate(fromDate));
gcc.setEndDate(convertStringToDate(toDate));
gcc.setHallId(String.join(",",
hallIdsList.stream().map(String::valueOf).collect(Collectors.toList())));
gcc.setUpdatedBy(updatedBy);
gcc.setCdate(new Date());
gcc.setBlockingReason(reasonforblocking);
if (documents != null && documents.length > 0 && descriptions != null
&& descriptions.length > 0) {
int i = 0;
for (MultipartFile document : documents) {
String filePath = uploadDirectory + "/" + gcc.getBlockingId() + "_" + i + "_"
+ document.getOriginalFilename();
String documentUrl = serverPath + "gccblockingdocs/" + gcc.getBlockingId() + "_" + i
+ "_" + document.getOriginalFilename();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
// Save document to the file system
byte[] bytes = document.getBytes();
fos.write(bytes);
// Save document details along with description in the database
GccblockingDocuments documentDetails = new GccblockingDocuments(); // Assuming you
// have a
// DocumentDetails
// entity
documentDetails.setBlockingDate(gcc); // Assuming hallDetails is associated with the
// document
documentDetails.setBlockingDocument(documentUrl); // Save the URL of the uploaded
// document
documentDetails.setDescription(descriptions[i]); // Save corresponding description
gccblockingDocumentsRepo.save(documentDetails); // Save the document and description
// in the database
} catch (IOException e) {
throw new RuntimeException("Failed to save document", e);
}
i++;
}
}
// GCC blocking History
GccBlockingHistory gccblockinghistory = new GccBlockingHistory();
gccblockinghistory.setStartDate(convertStringToDate(fromDate));
gccblockinghistory.setEndDate(convertStringToDate(toDate));
gccblockinghistory.setHallId(String.join(",",
hallIdsList.stream().map(String::valueOf).collect(Collectors.toList())));
gccblockinghistory.setUpdatedBy(updatedBy);
gccblockinghistory.setCdate(new Date());
gccblockinghistory.setBlockingReason(reasonforblocking);
List<Integer> bookingIds = saveGCCBlockingDate(gcc);
gccblockinghistory.setBookingIds(bookingIds.toString());
blockingHistoryRepository.save(gccblockinghistory);
// GCC calendar
for (Long hallId : hallIdsList) {
LocalDate fDate = LocalDate.parse(fromDate);
LocalDate tDate = LocalDate.parse(toDate);
List<LocalDate> dates = getDateRange(fDate, tDate);
for (LocalDate aa : dates) {
String uniqueId = aa.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId;
BookingCalendar data = getbyDates(aa, hallId.toString());
int userbookingbookingId = bookingIds.get(hallIdsList.indexOf(hallId));
if (data != null) {
System.out.println("uniqueId...1" + uniqueId);
data.setBookingId_1(String.valueOf(userbookingbookingId));
data.setBookingId_2(String.valueOf(userbookingbookingId));
data.setMorningSlot(true);
data.setEveningSlot(true);
data.setIs_blocked(true);
data.setUnique_id(uniqueId);
updateBookingStatus(data);
} else {
System.out.println("uniqueId...2" + uniqueId);
BookingCalendar book = new BookingCalendar();
book.setBdate(aa);
book.setBookingId_1(String.valueOf(userbookingbookingId));
book.setBookingId_2(String.valueOf(userbookingbookingId));
book.setMorningSlot(true);
book.setEveningSlot(true);
book.setHallId(hallId.intValue());
book.setIs_active(true);
book.setIs_booked(2);
book.setIs_delete(false);
book.setIs_blocked(true);
book.setUnique_id(uniqueId);
updateBookingStatus(book);
}
}
}
// WhatsApp msg and SMS
updateBookingStatusById(booking.getBookingId(), booking.getBookingStatus().GCC_BLOCKED,
reasonforblocking);
// whatsup msg and SMS
String gccblockedsms = "Your booking ID " + bookingId + " on " + booking.getStartDate() String gccblockedsms = "Your booking ID " + bookingId + " on " + booking.getStartDate()
+ " has been blocked by GCC due to " + reasonforblocking + " has been blocked by GCC due to " + reasonforblocking
+ ". The entire amount paid will be refunded to your account with in 3 to 15 days."; + ". The entire amount paid will be refunded to your account with in 3 to 15 days.";
@ -2415,103 +2679,6 @@ public class BookingServiceImpl implements BookingService {
whatsappMsgServiceImpl.sendMsg(gccblockedwhatsupmsg); whatsappMsgServiceImpl.sendMsg(gccblockedwhatsupmsg);
whatsappMsgServiceImpl.sendSMS(gccblockedurlString); whatsappMsgServiceImpl.sendSMS(gccblockedurlString);
bookingDetailsRepository.save(booking); bookingDetailsRepository.save(booking);
cancelledBookingIds.add(bookingId);
}
}
}
// ── Phase 2: Create ONE GccBlockingDate record for the entire operation ──
GccBlockingDate gcc = new GccBlockingDate();
gcc.setStartDate(convertStringToDate(fromDate));
gcc.setEndDate(convertStringToDate(toDate));
gcc.setHallId(String.join(",",
hallIdsList.stream().map(String::valueOf).collect(Collectors.toList())));
gcc.setUpdatedBy(updatedBy);
gcc.setCdate(new Date());
gcc.setBlockingReason(reasonforblocking);
// Save document(s) if present
if (documents != null && documents.length > 0 && descriptions != null
&& descriptions.length > 0) {
int i = 0;
for (MultipartFile document : documents) {
String filePath = uploadDirectory + "/" + gcc.getBlockingId() + "_" + i + "_"
+ document.getOriginalFilename();
String documentUrl = serverPath + "gccblockingdocs/" + gcc.getBlockingId() + "_" + i
+ "_" + document.getOriginalFilename();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
byte[] bytes = document.getBytes();
fos.write(bytes);
GccblockingDocuments documentDetails = new GccblockingDocuments();
documentDetails.setBlockingDate(gcc);
documentDetails.setBlockingDocument(documentUrl);
documentDetails.setDescription(descriptions[i]);
gccblockingDocumentsRepo.save(documentDetails);
} catch (IOException e) {
throw new RuntimeException("Failed to save document", e);
}
i++;
}
}
// Save the single GCC blocking record
List<Integer> gccBookingIds = saveGCCBlockingDate(gcc);
// Store the actual cancelled user booking IDs on the gcc record
if (!cancelledBookingIds.isEmpty()) {
String cancelledIdsStr = cancelledBookingIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
gcc.setBookingIds(cancelledIdsStr);
gccBlockingDateRepository.save(gcc);
}
// GCC Blocking History — one entry for the whole operation
GccBlockingHistory gccblockinghistory = new GccBlockingHistory();
gccblockinghistory.setStartDate(convertStringToDate(fromDate));
gccblockinghistory.setEndDate(convertStringToDate(toDate));
gccblockinghistory.setHallId(String.join(",",
hallIdsList.stream().map(String::valueOf).collect(Collectors.toList())));
gccblockinghistory.setUpdatedBy(updatedBy);
gccblockinghistory.setCdate(new Date());
gccblockinghistory.setBlockingReason(reasonforblocking);
gccblockinghistory.setBookingIds(cancelledBookingIds.stream()
.map(String::valueOf).collect(Collectors.joining(",")));
blockingHistoryRepository.save(gccblockinghistory);
// ── Phase 3: Update BookingCalendar (mark dates as GCC-blocked) ──
for (Long hallId : hallIdsList) {
LocalDate fDate = LocalDate.parse(fromDate);
LocalDate tDate = LocalDate.parse(toDate);
List<LocalDate> dates = getDateRange(fDate, tDate);
for (LocalDate aa : dates) {
String uniqueId = aa.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + hallId;
BookingCalendar data = getbyDates(aa, hallId.toString());
int userbookingbookingId = gccBookingIds.get(hallIdsList.indexOf(hallId));
if (data != null) {
// data.setBookingId_1(String.valueOf(userbookingbookingId));
// data.setBookingId_2(String.valueOf(userbookingbookingId));
// data.setMorningSlot(true);
// data.setEveningSlot(true);
data.setIs_blocked(true);
data.setUnique_id(uniqueId);
updateBookingStatus(data);
} else {
BookingCalendar book = new BookingCalendar();
book.setBdate(aa);
book.setBookingId_1(String.valueOf(userbookingbookingId));
book.setBookingId_2(String.valueOf(userbookingbookingId));
book.setMorningSlot(true);
book.setEveningSlot(true);
book.setHallId(hallId.intValue());
book.setIs_active(true);
book.setIs_booked(2);
book.setIs_delete(false);
book.setIs_blocked(true);
book.setUnique_id(uniqueId);
updateBookingStatus(book);
} }
} }
} }

2
src/main/java/com/gcc/communityHall/service/MailService.java

@ -46,7 +46,7 @@ public class MailService {
} }
} }
helper.setSubject("Test Mail Refund Status Update Request - Community Hall Booking");
helper.setSubject("Refund Status Update Request - Community Hall Booking");
DecimalFormat df = new DecimalFormat("#,##0.00"); DecimalFormat df = new DecimalFormat("#,##0.00");
String amt = (refundAmount != null) ? "Rs. " + df.format(refundAmount) : "N/A"; String amt = (refundAmount != null) ? "Rs. " + df.format(refundAmount) : "N/A";

843
src/main/resources/resources/templates/headquarters/sixmonthold-transactions.html

@ -1,843 +0,0 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/head-headquarters :: head}"></head>
<style>
.nav-tabs .nav-link.active {
background: #1a73e8;
color: #fff !important;
border-color: #1a73e8;
border-radius: 6px 6px 0 0;
}
.nav-tabs .nav-link {
color: #444;
font-weight: 500;
}
.tab-badge {
background: #e8f0fe;
color: #1a73e8;
border-radius: 10px;
padding: 1px 8px;
font-size: 12px;
font-weight: 700;
margin-left: 4px;
}
.nav-tabs .nav-link.active .tab-badge {
background: rgba(255, 255, 255, 0.25);
color: #fff;
}
.table-responsive {
overflow-x: auto;
}
.card-body table {
width: 100%;
}
.card-body th,
td {
padding: 8px;
text-align: left;
}
.amount-cell {
text-align: right;
padding-right: 1rem;
}
.table {
width: 100% !important;
}
.btn-sendmail {
background: #1a73e8;
color: #fff;
border: none;
border-radius: 4px;
padding: 3px 10px;
cursor: pointer;
font-size: 12px;
}
.btn-sendmail:hover {
background: #1558b0;
}
.btn-viewdetails {
background: #f59e0b;
color: #fff;
border: none;
border-radius: 4px;
padding: 3px 10px;
cursor: pointer;
font-size: 12px;
margin-right: 4px;
}
.btn-viewdetails:hover {
background: #b45309;
}
.badge-cancelled {
background: #dc2626;
color: #fff;
padding: 3px 8px;
border-radius: 10px;
font-size: 11px;
}
.badge-rejected {
background: #7c3aed;
color: #fff;
padding: 3px 8px;
border-radius: 10px;
font-size: 11px;
}
.badge-approved {
background: #16a34a;
color: #fff;
padding: 3px 8px;
border-radius: 10px;
font-size: 11px;
}
.badge-other {
background: #64748b;
color: #fff;
padding: 3px 8px;
border-radius: 10px;
font-size: 11px;
}
.not-initiated {
color: #dc2626;
font-style: italic;
font-size: 12px;
}
/* Draft mail preview */
#draftMailBody {
background: #f8fafc;
border: 1px solid #cbd5e1;
border-radius: 6px;
padding: 16px;
font-family: Arial, sans-serif;
font-size: 14px;
white-space: pre-wrap;
line-height: 1.6;
}
.mail-header-row {
margin-bottom: 6px;
font-size: 13px;
}
.mail-header-row strong {
display: inline-block;
width: 50px;
color: #475569;
}
</style>
<body>
<!-- Page Container -->
<div id="page-container"
class="sidebar-o sidebar-dark enable-page-overlay side-scroll page-header-fixed page-header-dark">
<!-- Side Overlay aside (right)-->
<aside th:replace="~{fragments/aside-right :: aside}"></aside>
<!-- END Side Overlay (right)-->
<!-- Sidebar Nav-->
<nav th:replace="~{fragments/nav-headquarters :: nav}"></nav>
<!-- END Sidebar -->
<!-- Header -->
<header th:replace="~{fragments/header-headquarters :: header}"></header>
<!-- END Header -->
<!-- Main Container -->
<main id="main-container" class="container-fluid mt-4 px-4">
<div class="block block-rounded">
<div class="block-header block-header-default">
<h3 class="block-title">6 Months Old Transaction Details</h3>
</div>
<div class="block-content">
<!-- ── TABS ───────────────────────────────────────────── -->
<ul class="nav nav-tabs mb-0" id="sixMonthTab" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link active" id="tab-sixmonth-lnk" data-toggle="tab" href="#tab-sixmonth"
role="tab" aria-controls="tab-sixmonth" aria-selected="true">
6 Month Old Bookings
<span class="tab-badge"
th:text="${sixMonthOldBookings != null ? #lists.size(sixMonthOldBookings) : 0}">0</span>
</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="tab-cancelled-lnk" data-toggle="tab" href="#tab-cancelled"
role="tab" aria-controls="tab-cancelled" aria-selected="false">
Cancelled Bookings
<span class="tab-badge"
th:text="${cancelledBookings != null ? #lists.size(cancelledBookings) : 0}">0</span>
</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="tab-rejected-lnk" data-toggle="tab" href="#tab-rejected"
role="tab" aria-controls="tab-rejected" aria-selected="false">
Rejected Bookings
<span class="tab-badge"
th:text="${rejectedBookings != null ? #lists.size(rejectedBookings) : 0}">0</span>
</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="tab-mailsent-lnk" data-toggle="tab" href="#tab-mailsent"
role="tab" aria-controls="tab-mailsent" aria-selected="false">
Mail Sent Bookings
<span class="tab-badge"
th:text="${mailSentBookings != null ? #lists.size(mailSentBookings) : 0}">0</span>
</a>
</li>
</ul>
<div class="tab-content border border-top-0 p-3" id="sixMonthTabContent">
<!-- ══════════════════════════════════════════════════
TAB 1 – 6 Month Old Bookings (non-cancelled/rejected)
══════════════════════════════════════════════════ -->
<div class="tab-pane fade show active" id="tab-sixmonth" role="tabpanel" aria-labelledby="tab-sixmonth-lnk">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
id="tbl-sixmonth">
<thead class="thead-light">
<tr>
<th>S.No</th>
<th>Zone</th>
<th>Division</th>
<th>Hall Name</th>
<th>Booking Date</th>
<th>Event Date (Start – End)</th>
<th>Settlement Raised Date</th>
<th>Refund Amount (₹)</th>
<th>Refund Status</th>
<th>Booking Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="row, rowStat : ${sixMonthOldBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td th:text="${row['zone'] != null ? row['zone'] : ''}"></td>
<td th:text="${row['division'] != null ? row['division'] : ''}"></td>
<td th:text="${row['hall_name'] != null ? row['hall_name'] : ''}"></td>
<td class="text-center"
th:text="${row['booking_date'] != null ? row['booking_date'] : ''}">
</td>
<td class="text-center"
th:text="(${row['event_start_date'] != null ? row['event_start_date'] : ''}) + ' – ' + (${row['event_end_date'] != null ? row['event_end_date'] : ''})">
</td>
<!-- Settlement Raised Date: N/A if no settlement -->
<td class="text-center">
<span th:if="${row['settlement_raised_date'] != null}"
th:text="${row['settlement_raised_date']}"></span>
<span th:if="${row['settlement_raised_date'] == null}"
class="not-initiated">Settlement Not Initiated</span>
</td>
<!-- Refund Amount: from settlement.refunded_amount -->
<td class="text-right">
<span th:if="${row['refunded_amount'] != null}"
th:text="'₹ ' + ${row['refunded_amount']}"></span>
<span th:if="${row['refunded_amount'] == null}"
class="not-initiated">—</span>
</td>
<td class="text-center"
th:text="${row['refund_status'] != null ? row['refund_status'] : ''}">
</td>
<td class="text-center">
<span th:classappend="${row['booking_status'] == 'CANCELED' || row['booking_status'] == 'CANCELLED'} ? 'badge-cancelled' :
(${row['booking_status'] == 'REJECTED'} ? 'badge-rejected' :
(${row['booking_status'] == 'APPROVED'} ? 'badge-approved' : 'badge-other'))"
th:text="${row['booking_status'] != null ? row['booking_status'] : ''}"></span>
</td>
<td class="text-center">
<!-- View Details: calls getSettlementList if settlement exists -->
<button th:if="${row['settlement_id'] != null}" class="btn-viewdetails"
th:onclick="|viewSettlement(${row['settlement_id']})|">
View Details
</button>
<span th:if="${row['settlement_id'] == null}"
class="not-initiated d-block mb-1">Settlement Not Initiated</span>
<button class="btn-sendmail"
th:onclick="|openSendMail(${row['booking_id'] != null ? row['booking_id'] : 0}, '${row['booking_status'] != null ? row['booking_status'] : ''}', '${row['txansaction_id'] != null ? row['txansaction_id'] : ''}', '${row['tpsl_txn_id'] != null ? row['tpsl_txn_id'] : ''}', '${row['transaction_date'] != null ? row['transaction_date'] : ''}', ${row['refunded_amount'] != null ? row['refunded_amount'] : 0})|">
Send Mail
</button>
</td>
</tr>
<tr
th:if="${sixMonthOldBookings == null || #lists.isEmpty(sixMonthOldBookings)}">
<td colspan="11" class="text-center text-muted py-3">No records found</td>
</tr>
</tbody>
</table>
</div>
</div><!-- /tab-sixmonth -->
<!-- ══════════════════════════════════════════════════
TAB 2 – Cancelled Bookings
Refund Amount = deposit_amount
No Settlement Raised Date column
══════════════════════════════════════════════════ -->
<div class="tab-pane fade" id="tab-cancelled" role="tabpanel" aria-labelledby="tab-cancelled-lnk">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
id="tbl-cancelled">
<thead class="thead-light">
<tr>
<th>S.No</th>
<th>Zone</th>
<th>Division</th>
<th>Hall Name</th>
<th>Booking Date</th>
<th>Event Date (Start – End)</th>
<th>Refund Amount (₹)</th>
<th>Booking Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="row, rowStat : ${cancelledBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td th:text="${row['zone'] != null ? row['zone'] : ''}"></td>
<td th:text="${row['division'] != null ? row['division'] : ''}"></td>
<td th:text="${row['hall_name'] != null ? row['hall_name'] : ''}"></td>
<td class="text-center"
th:text="${row['booking_date'] != null ? row['booking_date'] : ''}">
</td>
<td class="text-center"
th:text="(${row['event_start_date'] != null ? row['event_start_date'] : ''}) + ' – ' + (${row['event_end_date'] != null ? row['event_end_date'] : ''})">
</td>
<td class="text-right"
th:text="${row['refund_amount'] != null ? '₹ ' + row['refund_amount'] : '—'}">
</td>
<td class="text-center">
<span class="badge-cancelled"
th:text="${row['booking_status'] != null ? row['booking_status'] : ''}"></span>
</td>
<td class="text-center">
<button class="btn-viewdetails"
th:onclick="|viewBookingDetails(${row['booking_id'] != null ? row['booking_id'] : 0})|">
View Details
</button>
<button class="btn-sendmail"
th:onclick="|openSendMail(${row['booking_id'] != null ? row['booking_id'] : 0}, '${row['booking_status'] != null ? row['booking_status'] : ''}', '${row['txansaction_id'] != null ? row['txansaction_id'] : ''}', '${row['tpsl_txn_id'] != null ? row['tpsl_txn_id'] : ''}', '${row['transaction_date'] != null ? row['transaction_date'] : ''}', ${row['refund_amount'] != null ? row['refund_amount'] : 0})|">
Send Mail
</button>
</td>
</tr>
<tr th:if="${cancelledBookings == null || #lists.isEmpty(cancelledBookings)}">
<td colspan="9" class="text-center text-muted py-3">No records found</td>
</tr>
</tbody>
</table>
</div>
</div><!-- /tab-cancelled -->
<!-- ══════════════════════════════════════════════════
TAB 3 – Rejected Bookings
Refund Amount = amount_received (full amount)
No Settlement Raised Date column
══════════════════════════════════════════════════ -->
<div class="tab-pane fade" id="tab-rejected" role="tabpanel" aria-labelledby="tab-rejected-lnk">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
id="tbl-rejected">
<thead class="thead-light">
<tr>
<th>S.No</th>
<th>Zone</th>
<th>Division</th>
<th>Hall Name</th>
<th>Booking Date</th>
<th>Event Date (Start – End)</th>
<th>Refund Amount (₹)</th>
<th>Booking Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="row, rowStat : ${rejectedBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td th:text="${row['zone'] != null ? row['zone'] : ''}"></td>
<td th:text="${row['division'] != null ? row['division'] : ''}"></td>
<td th:text="${row['hall_name'] != null ? row['hall_name'] : ''}"></td>
<td class="text-center"
th:text="${row['booking_date'] != null ? row['booking_date'] : ''}">
</td>
<td class="text-center"
th:text="(${row['event_start_date'] != null ? row['event_start_date'] : ''}) + ' – ' + (${row['event_end_date'] != null ? row['event_end_date'] : ''})">
</td>
<td class="text-right"
th:text="${row['refund_amount'] != null ? '₹ ' + row['refund_amount'] : '—'}">
</td>
<td class="text-center">
<span class="badge-rejected"
th:text="${row['booking_status'] != null ? row['booking_status'] : ''}"></span>
</td>
<td class="text-center">
<button class="btn-viewdetails"
th:onclick="|viewBookingDetails(${row['booking_id'] != null ? row['booking_id'] : 0})|">
View Details
</button>
<button class="btn-sendmail"
th:onclick="|openSendMail(${row['booking_id'] != null ? row['booking_id'] : 0}, '${row['booking_status'] != null ? row['booking_status'] : ''}', '${row['txansaction_id'] != null ? row['txansaction_id'] : ''}', '${row['tpsl_txn_id'] != null ? row['tpsl_txn_id'] : ''}', '${row['transaction_date'] != null ? row['transaction_date'] : ''}', ${row['refund_amount'] != null ? row['refund_amount'] : 0})|">
Send Mail
</button>
</td>
</tr>
<tr th:if="${rejectedBookings == null || #lists.isEmpty(rejectedBookings)}">
<td colspan="9" class="text-center text-muted py-3">No records found</td>
</tr>
</tbody>
</table>
</div>
</div><!-- /tab-rejected -->
<!-- ══════════════════════════════════════════════════
TAB 4 – Mail Sent Bookings
══════════════════════════════════════════════════ -->
<div class="tab-pane fade" id="tab-mailsent" role="tabpanel" aria-labelledby="tab-mailsent-lnk">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
id="tbl-mailsent">
<thead class="thead-light">
<tr>
<th>S.No</th>
<th>Zone</th>
<th>Division</th>
<th>Hall Name</th>
<th>Booking Date</th>
<th>Event Date (Start – End)</th>
<th>Booking Status</th>
<th>Transaction ID</th>
<th>TPSL ID</th>
<th>Mail Sent Date</th>
</tr>
</thead>
<tbody>
<tr th:each="row, rowStat : ${mailSentBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td th:text="${row['zone'] != null ? row['zone'] : ''}"></td>
<td th:text="${row['division'] != null ? row['division'] : ''}"></td>
<td th:text="${row['hall_name'] != null ? row['hall_name'] : ''}"></td>
<td class="text-center"
th:text="${row['booking_date'] != null ? row['booking_date'] : ''}">
</td>
<td class="text-center"
th:text="(${row['event_start_date'] != null ? row['event_start_date'] : ''}) + ' – ' + (${row['event_end_date'] != null ? row['event_end_date'] : ''})">
</td>
<td class="text-center">
<span th:classappend="${row['booking_status'] == 'CANCELED' || row['booking_status'] == 'CANCELLED'} ? 'badge-cancelled' :
(${row['booking_status'] == 'REJECTED'} ? 'badge-rejected' :
(${row['booking_status'] == 'APPROVED'} ? 'badge-approved' : 'badge-other'))"
th:text="${row['booking_status'] != null ? row['booking_status'] : ''}"></span>
</td>
<td class="text-center"
th:text="${row['txansaction_id'] != null ? row['txansaction_id'] : ''}">
</td>
<td class="text-center"
th:text="${row['tpsl_txn_id'] != null ? row['tpsl_txn_id'] : ''}"></td>
<td class="text-center"
th:text="${row['mail_sent_date'] != null ? row['mail_sent_date'] : ''}">
</td>
</tr>
<tr th:if="${mailSentBookings == null || #lists.isEmpty(mailSentBookings)}">
<td colspan="10" class="text-center text-muted py-3">No records found</td>
</tr>
</tbody>
</table>
</div>
</div><!-- /tab-mailsent -->
</div><!-- /tab-content -->
</div><!-- /block-content -->
</div><!-- /block -->
</main>
<!-- END Main Container -->
<!-- ══════════════════════════════════════════════════════════════════
MODAL – Settlement View Details (Tab 1 with settlement)
══════════════════════════════════════════════════════════════════ -->
<div class="modal fade" id="settlementModal" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="settlementModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="block block-rounded block-themed block-transparent mb-0">
<div class="block-header bg-primary-dark">
<h3 class="block-title" id="settlementModalLabel">Settlement Information</h3>
<div class="block-options">
<button type="button" class="btn-block-option" data-dismiss="modal" aria-label="Close">
<i class="fa fa-fw fa-times"></i>
</button>
</div>
</div>
<div class="block-content row p-3" id="settlementModalBody">
<!-- Populated by JS -->
</div>
<div class="block-content block-content-full text-right bg-body">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<!-- ══════════════════════════════════════════════════════════════════
MODAL – Booking View Details (Tab 2 & 3 – cancelled/rejected)
══════════════════════════════════════════════════════════════════ -->
<div class="modal fade" id="bookingModal" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="bookingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="block block-rounded block-themed block-transparent mb-0">
<div class="block-header bg-primary-dark">
<h3 class="block-title" id="bookingModalLabel">Booking Information</h3>
<div class="block-options">
<button type="button" class="btn-block-option" data-dismiss="modal" aria-label="Close">
<i class="fa fa-fw fa-times"></i>
</button>
</div>
</div>
<div class="block-content row p-3" id="bookingModalBody">
<!-- Populated by JS -->
</div>
<div class="block-content block-content-full text-right bg-body">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<!-- ══════════════════════════════════════════════════════════════════
MODAL – Draft Mail Preview & Confirm
══════════════════════════════════════════════════════════════════ -->
<div class="modal fade" id="draftMailModal" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="draftMailModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header" style="background:#1a73e8; color:#fff;">
<h5 class="modal-title" id="draftMailModalLabel">
<i class="fa fa-envelope mr-2"></i>Draft Mail Preview
</h5>
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<!-- Mail Header Fields -->
<div class="mail-header-row"><strong>From:</strong>
communityhallsupport@chennaicorporation.gov.in</div>
<div class="mail-header-row">
<strong>To:</strong>
pgsupport@mail.in.worldline-solutions.com, ranjithkumar@federal.bank.in,
megha.mattamana@federal.bank.in
</div>
<div class="mail-header-row">
<strong>CC:</strong>
arohqcc@gmail.com, it@chennaicorporation.gov.in
</div>
<div class="mail-header-row"><strong>Sub:</strong> Refund Status Update Request – Community Hall
Booking</div>
<hr class="my-2">
<!-- Mail Body -->
<div id="draftMailBody"></div>
<!-- Hidden fields to carry data through to confirm step -->
<input type="hidden" id="dm_bookingId">
<input type="hidden" id="dm_bookingStatus">
<input type="hidden" id="dm_transactionId">
<input type="hidden" id="dm_tpslId">
<input type="hidden" id="dm_refundAmount">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times mr-1"></i>Close
</button>
<button type="button" class="btn btn-primary" id="btn-confirm-mail" onclick="confirmMailSent()">
<i class="fa fa-check mr-1"></i>Confirm &amp; Mark as Mail Sent
</button>
</div>
</div>
</div>
</div>
<!-- File Preview Modal (for settlement images) -->
<div class="modal fade" id="fileModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">File Preview</h5>
<button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
</div>
<div class="modal-body">
<embed id="filePreview" src="" width="100%" height="600px">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<footer th:replace="~{fragments/footer2 :: footer}"></footer>
</div>
<!-- END Page Container -->
<div th:replace="~{fragments/resetpassword :: div}"></div>
<script th:replace="~{fragments/loginscript :: script}"></script>
<script>
// ─────────────────────────────────────────────────────────────────────
// DataTable initialisation & Tab Switch Handlers
// ─────────────────────────────────────────────────────────────────────
$(document).ready(function () {
var dtButtons = [
{ extend: 'pageLength', className: 'btn btn-primary' },
{ extend: 'copyHtml5', text: 'Copy', className: 'btn btn-primary' },
{ extend: 'excelHtml5', text: 'Excel', className: 'btn btn-primary' },
{ extend: 'csvHtml5', text: 'CSV', className: 'btn btn-primary' },
{ extend: 'pdfHtml5', text: 'PDF', className: 'btn btn-primary' }
];
var dtOpts = {
dom: 'Bftip',
columnDefs: [{ targets: 'no-sort', orderable: false }],
lengthMenu: [[50, 100, 200, 500, -1], ['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']],
buttons: dtButtons,
responsive: true,
searching: true,
autoWidth: false
};
// Initialize DataTables
$('#tbl-sixmonth').DataTable(dtOpts);
$('#tbl-cancelled').DataTable(dtOpts);
$('#tbl-rejected').DataTable(dtOpts);
$('#tbl-mailsent').DataTable(dtOpts);
// Explicit click handler to guarantee tab activation
$('#sixMonthTab a').on('click', function (e) {
e.preventDefault();
$(this).tab('show');
});
// Recalculate columns and responsive layout whenever any tab is shown
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var targetTab = $(e.target).attr('href');
if (targetTab && $.fn.dataTable) {
try {
$(targetTab).find('table').each(function () {
if ($.fn.dataTable.isDataTable(this)) {
$(this).DataTable().columns.adjust().responsive.recalc();
}
});
} catch (err) {
console.log('Error adjusting table columns on tab switch:', err);
}
}
});
});
// ─────────────────────────────────────────────────────────────────────
// View Settlement Details (Tab 1 – uses /getSettlementList by settlementId)
// ─────────────────────────────────────────────────────────────────────
function viewSettlement(settlementId) {
$.ajax({
type: 'GET',
url: '/communityhall/api/officer/getSettlementList',
data: { settlementsid: settlementId },
success: function (data) {
populateSettlementModal(data);
$('#settlementModal').modal('show');
},
error: function () {
Swal.fire('Error', 'Failed to fetch settlement details.', 'error');
}
});
}
function populateSettlementModal(d) {
var html = '<div class="col-12">';
html += '<table class="table table-sm table-bordered">';
html += '<tr><th colspan="4" style="background:#f2f2f2;">User Details</th></tr>';
html += '<tr><th style="font-weight:normal">User Name:</th><td>' + (d.users ? d.users.name : '') + '</td>';
html += '<th style="font-weight:normal">Mobile No:</th><td>' + (d.users ? d.users.mobileNo : '') + '</td></tr>';
html += '<tr><th style="font-weight:normal">User Type:</th><td colspan="3">' + (d.users ? d.users.usertype : '') + '</td></tr>';
html += '<tr><th colspan="4" style="background:#f2f2f2;">Hall Details</th></tr>';
html += '<tr><th style="font-weight:normal">Hall Name:</th><td colspan="3">' + (d.hallDetails ? d.hallDetails.hallName : '') + '</td></tr>';
html += '<tr><th colspan="4" style="background:#f2f2f2;">Booking Details (ID: ' + d.bookingId + ')</th></tr>';
html += '<tr><th style="font-weight:normal">Booking Date:</th><td>' + d.bookingDate + '</td>';
html += '<th style="font-weight:normal">Deposit Amount:</th><td>₹ ' + parseFloat(d.depositAmount).toFixed(2) + '</td></tr>';
html += '<tr><th style="font-weight:normal">Start Date:</th><td>' + d.startDate + '</td>';
html += '<th style="font-weight:normal">End Date:</th><td>' + d.endDate + '</td></tr>';
// Settlement
if (d.settlement) {
html += '<tr><th colspan="4" style="background:#f2f2f2;">Settlement Details</th></tr>';
html += '<tr><th style="font-weight:normal">Refunded Amount:</th><td>₹ ' + parseFloat(d.settlement.refundedAmount || 0).toFixed(2) + '</td>';
html += '<th style="font-weight:normal">Damage Amount:</th><td>₹ ' + parseFloat(d.settlement.damageAmount || 0).toFixed(2) + '</td></tr>';
} else {
html += '<tr><td colspan="4" class="text-danger text-center font-italic">Settlement Not Initiated</td></tr>';
}
html += '</table></div>';
$('#settlementModalBody').html(html);
}
// ─────────────────────────────────────────────────────────────────────
// View Booking Details (Tab 2 & 3 – uses /getBookingDetails by bookingId)
// ─────────────────────────────────────────────────────────────────────
function viewBookingDetails(bookingId) {
if (!bookingId || bookingId === 0) {
Swal.fire('Warning', 'Invalid Booking ID.', 'warning');
return;
}
$.ajax({
type: 'GET',
url: '/communityhall/api/officer/getBookingDetails',
data: { bookingsId: bookingId },
success: function (data) {
populateBookingModal(data);
$('#bookingModal').modal('show');
},
error: function () {
Swal.fire('Error', 'Failed to fetch booking details.', 'error');
}
});
}
function populateBookingModal(d) {
var html = '<div class="col-12">';
html += '<table class="table table-sm table-bordered">';
html += '<tr><th colspan="4" style="background:#f2f2f2;">User Details</th></tr>';
html += '<tr><th style="font-weight:normal">User Name:</th><td>' + (d.users ? d.users.name : '') + '</td>';
html += '<th style="font-weight:normal">Mobile No:</th><td>' + (d.users ? d.users.mobileNo : '') + '</td></tr>';
html += '<tr><th style="font-weight:normal">User Type:</th><td colspan="3">' + (d.users ? d.users.usertype : '') + '</td></tr>';
html += '<tr><th colspan="4" style="background:#f2f2f2;">Hall Details</th></tr>';
html += '<tr><th style="font-weight:normal">Hall Name:</th><td colspan="3">' + (d.hallDetails ? d.hallDetails.hallName : '') + '</td></tr>';
html += '<tr><th colspan="4" style="background:#f2f2f2;">Booking Details (ID: ' + d.bookingId + ')</th></tr>';
html += '<tr><th style="font-weight:normal">Booking Date:</th><td>' + d.bookingDate + '</td>';
html += '<th style="font-weight:normal">Booking Status:</th><td>' + d.bookingStatus + '</td></tr>';
html += '<tr><th style="font-weight:normal">Start Date:</th><td>' + d.startDate + '</td>';
html += '<th style="font-weight:normal">End Date:</th><td>' + d.endDate + '</td></tr>';
html += '<tr><th style="font-weight:normal">Deposit Amount:</th><td>₹ ' + parseFloat(d.depositAmount).toFixed(2) + '</td>';
html += '<th style="font-weight:normal">Total Amount:</th><td>₹ ' + parseFloat(d.amountReceived).toFixed(2) + '</td></tr>';
// Payment
if (d.payments) {
html += '<tr><th colspan="4" style="background:#f2f2f2;">Payment Details</th></tr>';
html += '<tr><th style="font-weight:normal">Transaction ID:</th><td colspan="3">' + d.payments.transactionId + '</td></tr>';
html += '<tr><th style="font-weight:normal">Amount Received:</th><td>₹ ' + d.payments.amountReceived + '</td>';
html += '<th style="font-weight:normal">Payment Status:</th><td>' + d.payments.paymentStatus + '</td></tr>';
}
html += '</table></div>';
$('#bookingModalBody').html(html);
}
// ─────────────────────────────────────────────────────────────────────
// Send Mail Flow
// ─────────────────────────────────────────────────────────────────────
function openSendMail(bookingId, bookingStatus, transactionId, tpslId, transactionDate, refundAmount) {
Swal.fire({
title: 'Send Refund Follow-up Mail?',
html: 'This will send a refund status request mail for Booking ID <strong>' + bookingId + '</strong>.<br>Do you want to proceed?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, Show Draft',
cancelButtonText: 'Cancel',
confirmButtonColor: '#1a73e8'
}).then(function (result) {
if (result.isConfirmed) {
showDraftMail(bookingId, bookingStatus, transactionId, tpslId, transactionDate, refundAmount);
}
});
}
function showDraftMail(bookingId, bookingStatus, transactionId, tpslId, transactionDate, refundAmount) {
document.getElementById('dm_bookingId').value = bookingId;
document.getElementById('dm_bookingStatus').value = bookingStatus;
document.getElementById('dm_transactionId').value = transactionId || '';
document.getElementById('dm_tpslId').value = tpslId || '';
document.getElementById('dm_refundAmount').value = refundAmount || 0;
var amt = parseFloat(refundAmount || 0).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
var body = 'Hi,\n\n';
body += 'Kindly update refund status for the foresaid transaction made for Community Hall Booking.\n\n';
body += 'Transaction Details:\n\n';
body += ' Transaction ID : ' + (transactionId || 'N/A') + '\n';
body += ' TPSL ID : ' + (tpslId || 'N/A') + '\n';
body += ' Transaction Date : ' + (transactionDate || 'N/A') + '\n';
body += ' Refund Amount : ₹ ' + amt + '\n\n';
body += 'If refund was not initiated, kindly initiate the refund and update refund status at the earliest. ';
body += 'Make sure that no duplicate refund was processed against this transaction.\n\n';
body += 'Regards,\n';
body += 'Community Hall Support\n';
body += 'Greater Chennai Corporation';
document.getElementById('draftMailBody').textContent = body;
$('#draftMailModal').modal('show');
}
function confirmMailSent() {
var bookingId = document.getElementById('dm_bookingId').value;
var bookingStatus = document.getElementById('dm_bookingStatus').value;
var transactionId = document.getElementById('dm_transactionId').value;
var tpslId = document.getElementById('dm_tpslId').value;
var refundAmount = document.getElementById('dm_refundAmount').value;
var mailTo = "pgsupport@mail.in.worldline-solutions.com,ranjithkumar@federal.bank.in,megha.mattamana@federal.bank.in";
var mailCc = "arohqcc@gmail.com,it@chennaicorporation.gov.in";
var mailSubject = "Refund Status Update Request – Community Hall Booking";
var mailBody = document.getElementById('draftMailBody').textContent;
var mailtoLink = "mailto:" + mailTo + "?cc=" + mailCc + "&subject=" + encodeURIComponent(mailSubject) + "&body=" + encodeURIComponent(mailBody);
window.location.href = mailtoLink;
document.getElementById('btn-confirm-mail').disabled = true;
$.ajax({
type: 'POST',
url: '/communityhall/headquarters/sixmonthold-transactions/markMailSent',
data: {
bookingId: bookingId,
bookingStatus: bookingStatus,
transactionId: transactionId,
tpslId: tpslId,
refundAmount: refundAmount
},
success: function (resp) {
$('#draftMailModal').modal('hide');
if (resp.status === 'success') {
Swal.fire({
icon: 'success',
title: 'Mail Recorded!',
text: 'Booking ID ' + bookingId + ' has been moved to "Mail Sent Bookings" tab.',
confirmButtonColor: '#1a73e8'
}).then(function () {
location.reload();
});
} else {
Swal.fire('Error', resp.message || 'An error occurred.', 'error');
document.getElementById('btn-confirm-mail').disabled = false;
}
},
error: function () {
Swal.fire('Error', 'Failed to mark mail as sent. Please try again.', 'error');
document.getElementById('btn-confirm-mail').disabled = false;
}
});
}
</script>
</body>
</html>

867
src/main/resources/templates/admin/bookingwaiting.html

@ -24,6 +24,7 @@
width: 100% !important; width: 100% !important;
} }
</style> </style>
<body> <body>
<!-- Page Container --> <!-- Page Container -->
<div id="page-container" <div id="page-container"
@ -39,61 +40,62 @@
<!-- END Header --> <!-- END Header -->
<!-- Main Container --> <!-- Main Container -->
<main id="main-container"> <main id="main-container">
<div class="content">
<div class="content">
<div class="block block-rounded"> <div class="block block-rounded">
<div class="block-header block-header-default" >
<h3 class="block-title">List of Bookings Waiting for NOC Approval</h3>
</div>
<div class="block-content p-0">
<div class="p-sm-4 p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive" id="bookingapprovedtable">
<thead class="thead-light">
<tr>
<th class="text-center no-sort">S.No</th>
<th class="text-center">Booking Id</th>
<th class="text-center">Zone</th>
<th class="text-center">Division</th>
<th class="text-center" width="20%">Hall Name</th>
<th class="text-center">User Name</th>
<th class="text-center">User type</th>
<th class="text-center" width="10%">Booking Date</th>
<th class="text-center">Number of days</th>
<th class="text-center">Reason for Booking</th>
<th class="text-center">Caretaker Name/MobileNumber</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr th:each="booking, rowStat : ${waitingBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td class="text-center" th:text="${booking.bookingId}"></td>
<td class="text-center" th:text="${booking.hallDetails.zone}"></td>
<td class="text-center" th:text="${booking.hallDetails.division}"></td>
<td class="text-center" th:text="${booking.hallDetails.hallName}"></td>
<td class="text-center" th:text="${booking.users.name}"></td>
<td class="text-center" th:text="${booking.users.usertype}"></td>
<td class="text-center" th:text="${booking.bookingDate}"></td>
<td class="text-center" th:text="${booking.noOfDays}"></td>
<td class="text-center" th:text="${booking.reason}"></td>
<td class="text-center"
th:text="${booking.hallDetails.hallInchargeName} + ' / ' + ${booking.hallDetails.hallInchargeMobno}">
</td>
<td>
<p>
<span class="badge bg-warning" style="cursor: pointer;"
th:onclick="pendingbooking([[${booking.bookingId}]])">Approve</span>
</p>
</td>
</tr>
</tbody>
</table>
<div class="block-header block-header-default">
<h3 class="block-title">List of Bookings Waiting for NOC Approval</h3>
</div>
<div class="block-content p-0">
<div class="p-sm-4 p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
id="bookingapprovedtable">
<thead class="thead-light">
<tr>
<th class="text-center no-sort">S.No</th>
<th class="text-center">Booking Id</th>
<th class="text-center">Zone</th>
<th class="text-center">Division</th>
<th class="text-center" width="20%">Hall Name</th>
<th class="text-center">User Name</th>
<th class="text-center">User type</th>
<th class="text-center" width="10%">Booking Date</th>
<th class="text-center">Number of days</th>
<th class="text-center">Reason for Booking</th>
<th class="text-center">Caretaker Name/MobileNumber</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr th:each="booking, rowStat : ${waitingBookings}">
<td class="text-center" th:text="${rowStat.index + 1}"></td>
<td class="text-center" th:text="${booking.bookingId}"></td>
<td class="text-center" th:text="${booking.hallDetails.zone}"></td>
<td class="text-center" th:text="${booking.hallDetails.division}"></td>
<td class="text-center" th:text="${booking.hallDetails.hallName}"></td>
<td class="text-center" th:text="${booking.users.name}"></td>
<td class="text-center" th:text="${booking.users.usertype}"></td>
<td class="text-center" th:text="${booking.bookingDate}"></td>
<td class="text-center" th:text="${booking.noOfDays}"></td>
<td class="text-center" th:text="${booking.reason}"></td>
<td class="text-center"
th:text="${booking.hallDetails.hallInchargeName} + ' / ' + ${booking.hallDetails.hallInchargeMobno}">
</td>
<td>
<p>
<span class="badge bg-warning" style="cursor: pointer;"
th:onclick="pendingbooking([[${booking.bookingId}]])">Approve</span>
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</main> </main>
<!-- END Main Container --> <!-- END Main Container -->
@ -291,20 +293,23 @@
</div> </div>
</div> </div>
<div class="row" id="reasondetails"> <div class="row" id="reasondetails">
<div class="col-md-6 mb-2">
<label class="form-label">Reason type :<span class="text-danger">*</span></label>
<select class="form-control" id="reasontype">
<option value="0" >Select Reason type</option>
<option value="1">Illegal</option>
<option value="2">Others</option>
</select>
</div>
<div class="col-md-6 mb-2">
<label class="form-label">Reason:<span class="text-danger">*</span></label>
<textarea class="form-control " name="reason" id="reason" required style="height: 9px;"></textarea>
<div id="reasonValidationText" class="text-danger small mt-1" style="display:none">
Reason is required.</div>
</div>
<div class="col-md-6 mb-2">
<label class="form-label">Reason type :<span
class="text-danger">*</span></label>
<select class="form-control" id="reasontype">
<option value="0">Select Reason type</option>
<option value="1">Illegal</option>
<option value="2">Others</option>
</select>
</div>
<div class="col-md-6 mb-2">
<label class="form-label">Reason:<span class="text-danger">*</span></label>
<textarea class="form-control " name="reason" id="reason" required
style="height: 9px;"></textarea>
<div id="reasonValidationText" class="text-danger small mt-1"
style="display:none">
Reason is required.</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -313,7 +318,7 @@
data-bs-dismiss="modal">Close</button> data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-sm btn-primary" id="accepttbutton" <button type="button" class="btn btn-sm btn-primary" id="accepttbutton"
th:onclick="accept()">Approve</button> th:onclick="accept()">Approve</button>
<button type="button" class="btn btn-sm btn-primary" id="rejectbutton"
<button type="button" class="btn btn-sm btn-primary" id="rejectbutton"
th:onclick="rejectsubmit()">Reject</button> th:onclick="rejectsubmit()">Reject</button>
</div> </div>
</form> </form>
@ -322,7 +327,8 @@
</div> </div>
<!-- End Modal User --> <!-- End Modal User -->
<!-- Footer --> <!-- Footer -->
<div class="modal fade" id="fileModal" tabindex="-1" role="dialog" aria-labelledby="fileModalLabel" aria-hidden="true">
<div class="modal fade" id="fileModal" tabindex="-1" role="dialog" aria-labelledby="fileModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -341,372 +347,419 @@
</div> </div>
</div> </div>
<div th:replace="~{fragments/resetpassword :: div}"></div>
<footer th:replace="~{fragments/footer2 :: footer}"></footer>
<script th:replace="~{fragments/loginscript :: script}"></script>
<script>
//script to open pending form
function pendingbooking(bookingId) {
$.ajax({
type: "GET",
url: '/communityhall/api/officer/getBookingDetails',
data: {
'bookingsId': bookingId
},
success: function (x) {
//console.log(x);
showBookingInfo(x);
}
});
<div th:replace="~{fragments/resetpassword :: div}"></div>
<footer th:replace="~{fragments/footer2 :: footer}"></footer>
<script th:replace="~{fragments/loginscript :: script}"></script>
<script>
//script to open pending form
function pendingbooking(bookingId) {
$.ajax({
type: "GET",
url: '/communityhall/api/officer/getBookingDetails',
data: {
'bookingsId': bookingId
},
success: function (x) {
//console.log(x);
showBookingInfo(x);
}
});
}
}
function showBookingInfo(list) {
$('#pendingBookingForm').modal({
backdrop: 'static',
keyboard: false
});
$('#pendingBookingForm').modal('show');
var todaydate = new Date().toISOString().split('T')[0];
function showBookingInfo(list) {
$('#pendingBookingForm').modal({
backdrop: 'static',
keyboard: false
});
$('#pendingBookingForm').modal('show');
var todaydate = new Date().toISOString().split('T')[0];
// Convert startDate to YYYY-MM-DD format if needed // Convert startDate to YYYY-MM-DD format if needed
var startDate = new Date(list.startDate).toISOString().split('T')[0]; // Ensure this is in the correct format var startDate = new Date(list.startDate).toISOString().split('T')[0]; // Ensure this is in the correct format
if (startDate > todaydate) { if (startDate > todaydate) {
$('#reasondetails').show();
$('#rejectbutton').show();
$('#reasondetails').show();
$('#rejectbutton').show();
} else { } else {
$('#reasondetails').hide();
$('#rejectbutton').hide();
$('#reasondetails').hide();
$('#rejectbutton').hide();
} }
document.getElementById("td_userName").innerHTML = list.users.name;
document.getElementById("td_mobileNumber").innerHTML = list.users.mobileNo;
document.getElementById("td_usertype").innerHTML = list.users.usertype;
document.getElementById("bookingid").value = list.bookingId;
var userDetails = list.users;
var userDetailsString =
userDetails.doorNo + ", " +
userDetails.street + ", " +
userDetails.area + ", " +
userDetails.location + "- " +
userDetails.pinCode;
document.getElementById("td_useraddress").innerHTML = userDetailsString;
document.getElementById("td_hallName").innerHTML = list.hallDetails.hallName;
var hallDetails = list.hallDetails;
var hallDetailsString =
hallDetails.doorNo + ", " +
hallDetails.street + ", " +
hallDetails.area + ", " +
hallDetails.city + "- " +
hallDetails.pinCode;
document.getElementById("td_halladdress").innerHTML = hallDetailsString;
document.getElementById("td_caretakername").innerHTML = list.hallDetails.hallInchargeName;
document.getElementById("td_caretakermobileNumber").innerHTML = list.hallDetails.hallInchargeMobno;
document.getElementById("td_bookingDate").innerHTML = list.bookingDate;
document.getElementById("td_depositeAmount").innerHTML = '₹ ' + parseFloat(list.depositAmount).toFixed(2);
document.getElementById("td_hallAmount").innerHTML = '₹ ' + parseFloat(list.hallAmount).toFixed(2);
document.getElementById("td_totalAmount").innerHTML = '₹ ' + parseFloat(list.amountReceived).toFixed(2);
var gstcl = (list.hallAmount * (list.hallDetails.gst/100));
var formattedGst = gstcl.toFixed(2);
document.getElementById("td_gst").innerHTML = '₹ ' + formattedGst;
document.getElementById("td_startDate").innerHTML = list.startDate;
document.getElementById("td_endDate").innerHTML = list.endDate;
document.getElementById("booking_id").innerHTML = list.bookingId;
function getTimeSlot(slotValue) {
//console.log("Slot Value in getTimeSlot function:", slotValue);
var timeSlot;
var trimmedSlotValue = String(slotValue).trim(); // Convert to string and then trim
if (trimmedSlotValue === '1') {
timeSlot = 'Morning';
} else if (trimmedSlotValue === '2') {
timeSlot = 'Evening';
} else {
timeSlot = 'Unknown';
document.getElementById("td_userName").innerHTML = list.users.name;
document.getElementById("td_mobileNumber").innerHTML = list.users.mobileNo;
document.getElementById("td_usertype").innerHTML = list.users.usertype;
document.getElementById("bookingid").value = list.bookingId;
var userDetails = list.users;
var userDetailsString =
userDetails.doorNo + ", " +
userDetails.street + ", " +
userDetails.area + ", " +
userDetails.location + "- " +
userDetails.pinCode;
document.getElementById("td_useraddress").innerHTML = userDetailsString;
document.getElementById("td_hallName").innerHTML = list.hallDetails.hallName;
var hallDetails = list.hallDetails;
var hallDetailsString =
hallDetails.doorNo + ", " +
hallDetails.street + ", " +
hallDetails.area + ", " +
hallDetails.city + "- " +
hallDetails.pinCode;
document.getElementById("td_halladdress").innerHTML = hallDetailsString;
document.getElementById("td_caretakername").innerHTML = list.hallDetails.hallInchargeName;
document.getElementById("td_caretakermobileNumber").innerHTML = list.hallDetails.hallInchargeMobno;
document.getElementById("td_bookingDate").innerHTML = list.bookingDate;
document.getElementById("td_depositeAmount").innerHTML = '₹ ' + parseFloat(list.depositAmount).toFixed(2);
document.getElementById("td_hallAmount").innerHTML = '₹ ' + parseFloat(list.hallAmount).toFixed(2);
document.getElementById("td_totalAmount").innerHTML = '₹ ' + parseFloat(list.amountReceived).toFixed(2);
var gstcl = (list.hallAmount * (list.hallDetails.gst / 100));
var formattedGst = gstcl.toFixed(2);
document.getElementById("td_gst").innerHTML = '₹ ' + formattedGst;
document.getElementById("td_startDate").innerHTML = list.startDate;
document.getElementById("td_endDate").innerHTML = list.endDate;
document.getElementById("booking_id").innerHTML = list.bookingId;
function getTimeSlot(slotValue) {
//console.log("Slot Value in getTimeSlot function:", slotValue);
var timeSlot;
var trimmedSlotValue = String(slotValue).trim(); // Convert to string and then trim
if (trimmedSlotValue === '1') {
timeSlot = 'Morning';
} else if (trimmedSlotValue === '2') {
timeSlot = 'Evening';
} else {
timeSlot = 'Unknown';
}
//console.log("Time Slot:", timeSlot);
return timeSlot;
} }
//console.log("Time Slot:", timeSlot);
return timeSlot;
document.getElementById("td_startingSlot").innerHTML = getTimeSlot(list.startingSlot);
document.getElementById("td_endingSlot").innerHTML = getTimeSlot(list.endingSlot);
document.getElementById("td_bookingStatus").innerHTML = list.bookingStatus;
// Check if transactionId is not null, otherwise set to "NA"
document.getElementById("td_transactionId").innerHTML = list.payments && list.payments.transactionId ? list.payments.transactionId : "NA";
// Check if amountReceived is not null, otherwise set to "NA"
document.getElementById("td_payamountReceived").innerHTML = list.payments && list.payments.amountReceived ? '₹ ' + list.payments.amountReceived : "NA";
// Check if paymentStatus is not null, otherwise set to "NA"
document.getElementById("td_paymentStatus").innerHTML = list.payments && list.payments.paymentStatus ? list.payments.paymentStatus : "NA";
showReasonDocuments(list);
}
function showReasonDocuments(list) {
$.ajax({
type: "GET",
url: '/communityhall/api/officer/getReasonByName',
data: {
'reasonName': list.reason
},
success: function (x) {
//console.log(x);
showReasonWithDocument(x, list);
}
});
} }
document.getElementById("td_startingSlot").innerHTML = getTimeSlot(list.startingSlot);
document.getElementById("td_endingSlot").innerHTML = getTimeSlot(list.endingSlot);
document.getElementById("td_bookingStatus").innerHTML = list.bookingStatus;
// Check if transactionId is not null, otherwise set to "NA"
document.getElementById("td_transactionId").innerHTML = list.payments && list.payments.transactionId ? list.payments.transactionId : "NA";
// Check if amountReceived is not null, otherwise set to "NA"
document.getElementById("td_payamountReceived").innerHTML = list.payments && list.payments.amountReceived ? '₹ ' + list.payments.amountReceived : "NA";
// Check if paymentStatus is not null, otherwise set to "NA"
document.getElementById("td_paymentStatus").innerHTML = list.payments && list.payments.paymentStatus ? list.payments.paymentStatus : "NA";
showReasonDocuments(list);
}
function showReasonDocuments(list) {
$.ajax({
type: "GET",
url: '/communityhall/api/officer/getReasonByName',
data: {
'reasonName': list.reason
},
success: function (x) {
//console.log(x);
showReasonWithDocument(x, list);
// Display booking documents
function showReasonWithDocument(reasonData, list) {
var reasonDocumentData = reasonData.reasonDocumentMasterList;
var bookingDocumentsList = list.bookingDocumentsList;
console.log("reasonDocumentData;;;" + reasonDocumentData);
console.log("bookingDocumentsList;;;" + bookingDocumentsList);
const reasonFieldsContainer = $('#documents');
reasonFieldsContainer.empty();
// Create a responsive table container
var tableResponsiveDiv = $('<div>').addClass('table-responsive');
// Create the table with Bootstrap classes and custom styles
var table = $('<table>').addClass('table table-bordered table-striped table-vcenter js-dataTable-responsive').css({
'width': '100%',
'height': 'auto',
'border': '1px solid black'
});
// Create the table header (thead)
var thead = $('<thead>').appendTo(table);
var headerRow = $('<tr>').appendTo(thead);
$('<th>').attr('colspan', '3').text('Document Details').css({
'color': 'black',
'font-weight': 'bold',
'background-color': '#f2f2f2',
'padding': '0.45rem 0.45rem'
}).appendTo(headerRow);
// Create header row for columns
var columnHeadersRow = $('<tr>').appendTo(thead);
$('<th>').text('S.No').appendTo(columnHeadersRow);
$('<th>').text('Required Info').appendTo(columnHeadersRow);
$('<th>').text('Required Documents').appendTo(columnHeadersRow);
// Create the table body (tbody)
var tbody = $('<tbody>').appendTo(table);
// Helper: find the latest uploaded doc for a given master document entry.
// If docs have a booking_label, group by label prefix (e.g. NOC_1/NOC_2 under "NOC").
// Otherwise, use offset-from-end positional matching so that when a rescheduled
// re-upload exists (more docs than master entries), the newest doc is shown.
function getDocsForMaster(masterIndex, docFieldName) {
// Try label-based grouping first (e.g. NOC_1, NOC_2 → grouped under "NOC")
var labelPrefix = docFieldName ? docFieldName.replace(/[^a-zA-Z0-9]/g, '_') : null;
var labeled = bookingDocumentsList.filter(function (doc) {
return doc.booking_label && labelPrefix &&
doc.booking_label.toUpperCase().startsWith(labelPrefix.toUpperCase());
});
if (labeled.length > 0) return labeled;
// Fallback: offset-from-end positional match.
// When extra docs exist (e.g. 2 NOC uploads for 1 NOC master row),
// this picks the latest upload instead of the original.
var extraCount = bookingDocumentsList.length - reasonDocumentData.length;
var adjustedIndex = masterIndex + (extraCount > 0 ? extraCount : 0);
return bookingDocumentsList[adjustedIndex] ? [bookingDocumentsList[adjustedIndex]] : [];
} }
});
}
// Display booking documents
function showReasonWithDocument(reasonData, list) {
var reasonDocumentData = reasonData.reasonDocumentMasterList;
var bookingDocumentsList = list.bookingDocumentsList;
const reasonFieldsContainer = $('#documents');
reasonFieldsContainer.empty();
// Create a responsive table container
var tableResponsiveDiv = $('<div>').addClass('table-responsive');
// Create the table with Bootstrap classes and custom styles
var table = $('<table>').addClass('table table-bordered table-striped table-vcenter js-dataTable-responsive').css({
'width': '100%',
'height': 'auto',
'border': '1px solid black'
});
// Create the table header (thead)
var thead = $('<thead>').appendTo(table);
var headerRow = $('<tr>').appendTo(thead);
$('<th>').attr('colspan', '3').text('Document Details').css({
'color': 'black',
'font-weight': 'bold',
'background-color': '#f2f2f2',
'padding': '0.45rem 0.45rem'
}).appendTo(headerRow);
// Create header row for columns
var columnHeadersRow = $('<tr>').appendTo(thead);
$('<th>').text('S.No').appendTo(columnHeadersRow);
$('<th>').text('Required Info').appendTo(columnHeadersRow);
$('<th>').text('Required Documents').appendTo(columnHeadersRow);
// Create the table body (tbody)
var tbody = $('<tbody>').appendTo(table);
// Iterate through the documents list and populate rows
for (var i = 0; i < bookingDocumentsList.length; i++) {
(function (index) {
var row = $('<tr>').appendTo(tbody);
$('<td>').text(index + 1).appendTo(row);
// Determine the text content for the second cell
var name = bookingDocumentsList[index].name ? bookingDocumentsList[index].name : ''; // Empty string if name is null or undefined
var fieldText = reasonDocumentData[index].fieldName;
var fullText = name ? fieldText + ': ' + name : fieldText; // Include colon only if name is not empty
// Iterate over the master document list (one entry per required document type)
for (var i = 0; i < reasonDocumentData.length; i++) {
(function (masterIndex) {
var masterDoc = reasonDocumentData[masterIndex];
var matchedDocs = getDocsForMaster(masterIndex, masterDoc.docFieldName);
var row = $('<tr>').appendTo(tbody);
$('<td>').text(masterIndex + 1).appendTo(row);
// Required Info cell (use name from first matched doc, if any)
var firstName = (matchedDocs.length > 0 && matchedDocs[0].name) ? matchedDocs[0].name : '';
var fullText = firstName ? masterDoc.fieldName + ': ' + firstName : masterDoc.fieldName;
$('<td>').text(fullText).appendTo(row); $('<td>').text(fullText).appendTo(row);
// Create a link to view document image
var viewLink = $('<a>').attr('href', 'javascript:void(0)').text(reasonDocumentData[index].docFieldName).on('click', function () {
showDocumentImage(bookingDocumentsList[index].bookingDocUrl);
});
$('<td>').append(viewLink).appendTo(row);
// Document links cell — show all uploads for this master entry
var docLinksCell = $('<td>');
if (matchedDocs.length === 0) {
docLinksCell.text('Not uploaded');
} else if (matchedDocs.length === 1) {
// Single upload — show plain link with docFieldName label
(function (doc) {
var viewLink = $('<a>').attr('href', 'javascript:void(0)')
.text(masterDoc.docFieldName)
.on('click', function () { showDocumentImage(doc.bookingDocUrl); });
docLinksCell.append(viewLink);
})(matchedDocs[0]);
} else {
// Multiple uploads (e.g. NOC original + after reschedule) — show labeled links
var uploadLabels = ['Original', 'After Reschedule'];
for (var j = 0; j < matchedDocs.length; j++) {
(function (doc, uploadIndex) {
var label = uploadLabels[uploadIndex] || ('Upload ' + (uploadIndex + 1));
var viewLink = $('<a>').attr('href', 'javascript:void(0)')
.text(masterDoc.docFieldName + ' (' + label + ')')
.on('click', function () { showDocumentImage(doc.bookingDocUrl); });
if (uploadIndex > 0) docLinksCell.append($('<br>'));
docLinksCell.append(viewLink);
})(matchedDocs[j], j);
}
}
docLinksCell.appendTo(row);
})(i); })(i);
} }
// Append table to the responsive container
tableResponsiveDiv.append(table);
// Append table to the container in the DOM
reasonFieldsContainer.append(tableResponsiveDiv);
}
function showDocumentImage(fileURL) {
//console.log(fileURL);
openFileModal(fileURL);
}
// Event delegation for dynamically added elements
$(document).on('click', '.view-document', function () {
const fileURL = $(this).data('url');
openFileModal(fileURL);
});
function openFileModal(fileURL) {
$('#filePreview').attr('src', fileURL);
$('#fileModal').modal('show');
}
function accept() {
let id = document.getElementById("bookingid").value;
Swal.fire({
title: 'Do you want to Accept this User?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'YES',
denyButtonText: 'NO',
}).then((result) => {
if (result.isConfirmed) {
// Show loading popup
const loadingSwal = Swal.fire({
title: 'Processing...',
text: 'Please wait while we process the acceptance.',
allowOutsideClick: false, // Prevent closing the popup
didOpen: () => {
Swal.showLoading(); // Show the loading spinner
},
showConfirmButton: false, // Hide the confirm button during loading
});
$.ajax({
type: "POST",
url: '/communityhall/api/officer/updateBookingApproved/' + id,
data: {
'status': 'APPROVED',
'comments': 'Accepted',
'bookingId': id
},
success: function (data, textStatus, xhr) {
loadingSwal.close(); // Close the loading popup
if (xhr.status === 200) {
Swal.fire(
'Done',
'Successfully Approved to the ID: ' + id,
'success'
).then(() => {
location.reload(); // Reload page after success
});
} else {
Swal.fire(
'Error',
'Failed to accept the Booking',
'error'
);
}
},
error: function (xhr, textStatus, errorThrown) {
loadingSwal.close(); // Close the loading popup
Swal.fire(
'Error',
'Failed to accept the Booking',
'error'
);
}
});
} else if (result.isDenied) {
Swal.fire('Changes are not saved', '', 'info');
}
});
}
function rejectsubmit() {
let id = document.getElementById("bookingid").value;
let reason = document.getElementById("reason").value.trim();
let reasontype = document.getElementById("reasontype").value;
// Check if reason is empty only when rejecting
if (reason === "" || reason.length === 0) {
document.getElementById("reasonValidationText").style.display = "block";
return false; // Prevent form submission
} else {
document.getElementById("reasonValidationText").style.display = "none";
// Append table to the responsive container
tableResponsiveDiv.append(table);
// Append table to the container in the DOM
reasonFieldsContainer.append(tableResponsiveDiv);
} }
Swal.fire({
title: 'Do you want to Reject this User ?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'YES',
denyButtonText: 'NO',
}).then((result) => {
/* Read more about isConfirmed, isDenied below */
if (result.isConfirmed) {
$.ajax({
type: "POST",
url: '/communityhall/api/officer/updateBookingReject/' + id,
data: {
'status': 'REJECTED',
'comments': reason,
'bookingId': id,
'reasontype': reasontype
},
success: function (data, textStatus, xhr) {
//console.log("Rejection successful");
if (xhr.status === 200) { // Check if the response status is OK
function showDocumentImage(fileURL) {
//console.log(fileURL);
openFileModal(fileURL);
}
// Event delegation for dynamically added elements
$(document).on('click', '.view-document', function () {
const fileURL = $(this).data('url');
openFileModal(fileURL);
});
function openFileModal(fileURL) {
$('#filePreview').attr('src', fileURL);
$('#fileModal').modal('show');
}
function accept() {
let id = document.getElementById("bookingid").value;
Swal.fire({
title: 'Do you want to Accept this User?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'YES',
denyButtonText: 'NO',
}).then((result) => {
if (result.isConfirmed) {
// Show loading popup
const loadingSwal = Swal.fire({
title: 'Processing...',
text: 'Please wait while we process the acceptance.',
allowOutsideClick: false, // Prevent closing the popup
didOpen: () => {
Swal.showLoading(); // Show the loading spinner
},
showConfirmButton: false, // Hide the confirm button during loading
});
$.ajax({
type: "POST",
url: '/communityhall/api/officer/updateBookingApproved/' + id,
data: {
'status': 'APPROVED',
'comments': 'Accepted',
'bookingId': id
},
success: function (data, textStatus, xhr) {
loadingSwal.close(); // Close the loading popup
if (xhr.status === 200) {
Swal.fire(
'Done',
'Successfully Approved to the ID: ' + id,
'success'
).then(() => {
location.reload(); // Reload page after success
});
} else {
Swal.fire(
'Error',
'Failed to accept the Booking',
'error'
);
}
},
error: function (xhr, textStatus, errorThrown) {
loadingSwal.close(); // Close the loading popup
Swal.fire( Swal.fire(
'Done',
'Successfully Rejected to the ID:' + id,
'success'
).then(() => {
location.reload();
});
} else {
'Error',
'Failed to accept the Booking',
'error'
);
}
});
} else if (result.isDenied) {
Swal.fire('Changes are not saved', '', 'info');
}
});
}
function rejectsubmit() {
let id = document.getElementById("bookingid").value;
let reason = document.getElementById("reason").value.trim();
let reasontype = document.getElementById("reasontype").value;
// Check if reason is empty only when rejecting
if (reason === "" || reason.length === 0) {
document.getElementById("reasonValidationText").style.display = "block";
return false; // Prevent form submission
} else {
document.getElementById("reasonValidationText").style.display = "none";
}
Swal.fire({
title: 'Do you want to Reject this User ?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'YES',
denyButtonText: 'NO',
}).then((result) => {
/* Read more about isConfirmed, isDenied below */
if (result.isConfirmed) {
$.ajax({
type: "POST",
url: '/communityhall/api/officer/updateBookingReject/' + id,
data: {
'status': 'REJECTED',
'comments': reason,
'bookingId': id,
'reasontype': reasontype
},
success: function (data, textStatus, xhr) {
//console.log("Rejection successful");
if (xhr.status === 200) { // Check if the response status is OK
Swal.fire(
'Done',
'Successfully Rejected to the ID:' + id,
'success'
).then(() => {
location.reload();
});
} else {
Swal.fire(
'Error',
'Failed to reject the user',
'error'
);
}
},
error: function (xhr, textStatus, errorThrown) {
console.error("Error:", errorThrown);
Swal.fire( Swal.fire(
'Error', 'Error',
'Failed to reject the user', 'Failed to reject the user',
'error' 'error'
); );
} }
},
error: function (xhr, textStatus, errorThrown) {
console.error("Error:", errorThrown);
Swal.fire(
'Error',
'Failed to reject the user',
'error'
);
}
});
} else if (result.isDenied) {
Swal.fire('Changes are not saved', '', 'info')
}
});
return false; // Prevent form submission
}
$(document).ready(
function () {
var buttons = [{
extend: 'pageLength',
className: 'btn btn-primary'
}, {
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-primary',
id: 'copyBtn'
}, {
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-primary',
id: 'excelBtn'
}, {
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-primary',
id: 'csvBtn'
}, {
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-primary',
id: 'pdfBtn'
},
];
$('#bookingapprovedtable').DataTable(
{
dom: 'Bftip',
columnDefs: [{
targets: 'no-sort',
orderable: false
}],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows',
'500 rows', 'Show all']],
scrollY: '50vh',
fixedColumns: {
left: 1,
right: 1
},
buttons: [buttons],
responsive: true,
searching: true, // Enable search
select: false,
processing: false,
});
} else if (result.isDenied) {
Swal.fire('Changes are not saved', '', 'info')
}
});
return false; // Prevent form submission
}
$(document).ready(
function () {
var buttons = [{
extend: 'pageLength',
className: 'btn btn-primary'
}, {
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-primary',
id: 'copyBtn'
}, {
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-primary',
id: 'excelBtn'
}, {
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-primary',
id: 'csvBtn'
}, {
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-primary',
id: 'pdfBtn'
},
];
$('#bookingapprovedtable').DataTable(
{
dom: 'Bftip',
columnDefs: [{
targets: 'no-sort',
orderable: false
}],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows',
'500 rows', 'Show all']],
scrollY: '50vh',
fixedColumns: {
left: 1,
right: 1
},
buttons: [buttons],
responsive: true,
searching: true, // Enable search
select: false,
processing: false,
});
// Link the search input to DataTable
$('#searchInput').on('keyup', function () {
dataTable.search(this.value).draw();
}); });
// Link the search input to DataTable
$('#searchInput').on('keyup', function () {
dataTable.search(this.value).draw();
}); });
});
</script>
</script>
</body> </body>
</html> </html>

56
src/main/resources/templates/fragments/PaymentScript.html

@ -117,11 +117,31 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: '/communityhall/payment/api/payment-request', url: '/communityhall/payment/api/payment-request',
data: {'userId': userIdd, 'bookingId': bookingIdd},
data: { 'userId': userIdd, 'bookingId': bookingIdd },
success: function (response) { success: function (response) {
// console.log(response); // console.log(response);
if (response.error) { if (response.error) {
alert("please Contact Admin..")
if (response.slotOccupied) {
Swal.fire({
icon: 'warning',
title: 'Slot Already Occupied',
text: response.message,
confirmButtonText: 'OK',
confirmButtonColor: '#d33'
}).then((result) => {
if (result.isConfirmed) {
window.location.href = "/communityhall/user/hallbookingform";
}
});
} else {
Swal.fire({
icon: 'error',
title: 'Error',
text: response.message ? response.message : 'Something went wrong. Please contact Admin.',
confirmButtonText: 'OK',
confirmButtonColor: '#d33'
});
}
} else { } else {
txansactionId = response.txansactionId; txansactionId = response.txansactionId;
@ -163,11 +183,27 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: '/communityhall/payment/api/additionaldamage-payment-request', url: '/communityhall/payment/api/additionaldamage-payment-request',
data: {'userId': userIdd, 'bookingId': bookingIdd},
data: { 'userId': userIdd, 'bookingId': bookingIdd },
success: function (response) { success: function (response) {
// console.log(response); // console.log(response);
if (response.error) { if (response.error) {
alert("please Contact Admin..")
if (response.slotOccupied) {
Swal.fire({
icon: 'warning',
title: 'Slot Already Occupied',
text: response.message,
confirmButtonText: 'OK',
confirmButtonColor: '#d33'
});
} else {
Swal.fire({
icon: 'error',
title: 'Error',
text: response.message ? response.message : 'Something went wrong. Please contact Admin.',
confirmButtonText: 'OK',
confirmButtonColor: '#d33'
});
}
} else { } else {
txansactionId = response.txansactionId; txansactionId = response.txansactionId;
@ -218,12 +254,12 @@
$(document).off("click", "#extrapaymentbtnSubmit").on("click", "#extrapaymentbtnSubmit", function (e) { $(document).off("click", "#extrapaymentbtnSubmit").on("click", "#extrapaymentbtnSubmit", function (e) {
e.preventDefault(); e.preventDefault();
// console.log(txansactionId);
// console.log(consumerMobileNo);
// console.log(token);
// console.log(merchantId);
// console.log(consumerId);
// console.log(amount);
// console.log(txansactionId);
// console.log(consumerMobileNo);
// console.log(token);
// console.log(merchantId);
// console.log(consumerId);
// console.log(amount);
var reqJson = { var reqJson = {

2
src/main/resources/templates/fragments/headquartersMenu.html

@ -39,7 +39,7 @@
<li class="nav-main-item"> <li class="nav-main-item">
<a class="nav-main-link" href="/communityhall/headquarters/GccblockingNew"> <a class="nav-main-link" href="/communityhall/headquarters/GccblockingNew">
<i class="nav-main-link-icon fa fa-location-arrow"></i> <i class="nav-main-link-icon fa fa-location-arrow"></i>
<span class="nav-main-link-name">GCC Blocking (New)</span>
<span class="nav-main-link-name">GCC Blocking</span>
</a> </a>
</li> </li>
<li class="nav-main-item"> <li class="nav-main-item">

965
src/main/resources/templates/headquarters/bookingwaiting.html
File diff suppressed because it is too large
View File

4
src/main/resources/templates/headquarters/reports.html

@ -947,7 +947,7 @@
</div> </div>
</div> </div>
<div class="row col-md-12 col-lg-12 col-sm-12" id="ebdetails" <div class="row col-md-12 col-lg-12 col-sm-12" id="ebdetails"
style="display:none;margin-left: 0px;margin-top: -10px">
style="display:none;margin-left: 0px;">
<div class="card-body"> <div class="card-body">
<table> <table>
<tr> <tr>
@ -1066,7 +1066,7 @@
</div> </div>
</div> </div>
<div class="row col-md-12 col-lg-12 col-sm-12" id="refundamountDetails" <div class="row col-md-12 col-lg-12 col-sm-12" id="refundamountDetails"
style="display:none;margin-left: 0px;margin-top: -49px">
style="display:none;margin-left: 0px;">
<div class="card-body"> <div class="card-body">
<table> <table>
<tr> <tr>

64
src/main/resources/templates/headquarters/sixmonthold-transactions.html

@ -544,10 +544,10 @@
</button><br><br> </button><br><br>
<!-- Update Refund Details: opens refund update modal (calls /updateApprovedSettlementStatus) --> <!-- Update Refund Details: opens refund update modal (calls /updateApprovedSettlementStatus) -->
<button class="btn-sendmail btn-update-refund" <button class="btn-sendmail btn-update-refund"
th:if="${row['booking_status'] != 'COMPLETED'}"
th:data-booking-id="${row['booking_id']}" th:data-booking-id="${row['booking_id']}"
th:data-booking-status="${row['booking_status']}" th:data-booking-status="${row['booking_status']}"
th:data-settlement-id="${row['settlement_id']}"
th:disabled="${row['booking_status'] == 'COMPLETED'}">
th:data-settlement-id="${row['settlement_id']}">
Update Refund Details Update Refund Details
</button> </button>
</td> </td>
@ -564,57 +564,6 @@
</main> </main>
<!-- END Main Container --> <!-- END Main Container -->
<!-- ══════════════════════════════════════════════════════════════════
MODAL – Settlement View Details (Tab 1 with settlement)
══════════════════════════════════════════════════════════════════ -->
<!-- <div class="modal fade" id="settlementModal" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="settlementModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="block block-rounded block-themed block-transparent mb-0">
<div class="block-header bg-primary-dark">
<h3 class="block-title" id="settlementModalLabel">Settlement Information</h3>
<div class="block-options">
<button type="button" class="btn-block-option" data-dismiss="modal" aria-label="Close">
<i class="fa fa-fw fa-times"></i>
</button>
</div>
</div>
<div class="block-content row p-3" id="settlementModalBody">
</div>
<div class="block-content block-content-full text-right bg-body">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="bookingModal" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="bookingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="block block-rounded block-themed block-transparent mb-0">
<div class="block-header bg-primary-dark">
<h3 class="block-title" id="bookingModalLabel">Booking Information</h3>
<div class="block-options">
<button type="button" class="btn-block-option" data-dismiss="modal" aria-label="Close">
<i class="fa fa-fw fa-times"></i>
</button>
</div>
</div>
<div class="block-content row p-3" id="bookingModalBody">
</div>
<div class="block-content block-content-full text-right bg-body">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div> -->
<div class="modal fade backdrop" id="initiateSettlementForm" data-backdrop="static" tabindex="-1" role="dialog" <div class="modal fade backdrop" id="initiateSettlementForm" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="staticBackdropLabel" aria-hidden="true"> aria-labelledby="staticBackdropLabel" aria-hidden="true">
@ -933,7 +882,7 @@
<select class="form-control" id="ur_status"> <select class="form-control" id="ur_status">
<option value="">-- Select Status --</option> <option value="">-- Select Status --</option>
<option value="COMPLETED">COMPLETED</option> <option value="COMPLETED">COMPLETED</option>
<option value="CLOSED">CLOSED</option>
<!-- <option value="CLOSED">CLOSED</option> -->
</select> </select>
</div> </div>
<!-- Refund Date --> <!-- Refund Date -->
@ -941,14 +890,16 @@
<label for="ur_refundDate"> <label for="ur_refundDate">
<strong>Refund Date <span class="text-danger">*</span></strong> <strong>Refund Date <span class="text-danger">*</span></strong>
</label> </label>
<input type="date" class="form-control" id="ur_refundDate" required>
<input type="date" class="form-control" id="ur_refundDate" onkeydown="return false;"
onpaste="return false;" autocomplete="off" onclick="this.showPicker();" required>
</div> </div>
<!-- ARN Number --> <!-- ARN Number -->
<div class="form-group"> <div class="form-group">
<label for="ur_arnNumber"><strong>ARN Number <span <label for="ur_arnNumber"><strong>ARN Number <span
class="text-danger">*</span></strong></label> class="text-danger">*</span></strong></label>
<input type="text" class="form-control" id="ur_arnNumber" placeholder="Enter ARN Number..." <input type="text" class="form-control" id="ur_arnNumber" placeholder="Enter ARN Number..."
maxlength="15" minlength="12" pattern="\d{12,15}" inputmode="numeric" required>
maxlength="15" minlength="12" pattern="[0-9]{12,15}" inputmode="numeric"
oninput="this.value = this.value.replace(/\D/g, '')" required>
</div> </div>
<!-- Comments --> <!-- Comments -->
<div class="form-group"> <div class="form-group">
@ -1560,6 +1511,7 @@
// submitRefundUpdate: posts to /updateRefundDetails with the correct ID depending on booking status // submitRefundUpdate: posts to /updateRefundDetails with the correct ID depending on booking status
function submitRefundUpdate() { function submitRefundUpdate() {
var today = new Date().toISOString().split('T')[0];
var settlementId = document.getElementById('ur_settlementId').value; var settlementId = document.getElementById('ur_settlementId').value;
var status = document.getElementById('ur_status').value; var status = document.getElementById('ur_status').value;
var refundDate = document.getElementById('ur_refundDate').value; var refundDate = document.getElementById('ur_refundDate').value;

18
src/main/resources/templates/user/hallbookingform.html

@ -1000,6 +1000,18 @@
pointer-events: auto !important; pointer-events: auto !important;
} }
td.highlight-violet.ui-state-disabled {
opacity: 1 !important;
}
td.highlight-yellow.ui-state-disabled {
opacity: 1 !important;
}
td.highlight-pink.ui-state-disabled {
opacity: 1 !important;
}
/* css fror toast */ /* css fror toast */
/* Toast styling */ /* Toast styling */
#toast { #toast {
@ -3337,11 +3349,11 @@
function handleBookingStatus(bookingStatus, defaultMessage) { function handleBookingStatus(bookingStatus, defaultMessage) {
if (bookingStatus[2] && bookingStatus[0] && !bookingStatus[1]) { if (bookingStatus[2] && bookingStatus[0] && !bookingStatus[1]) {
return [true, "highlight-yellow disabled", "GCC Blocked"];
return [false, "highlight-yellow disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && !bookingStatus[0]) { } else if (bookingStatus[2] && bookingStatus[1] && !bookingStatus[0]) {
return [true, "highlight-violet disabled", "GCC Blocked"];
return [false, "highlight-violet disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] != 'GCC_BLOCKED' && bookingStatus[4] != 'GCC_BLOCKED') { } else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] != 'GCC_BLOCKED' && bookingStatus[4] != 'GCC_BLOCKED') {
return [true, "highlight-pink disabled", "GCC Blocked"];
return [false, "highlight-pink disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] == 'GCC_BLOCKED' && bookingStatus[4] == 'GCC_BLOCKED') { } else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] == 'GCC_BLOCKED' && bookingStatus[4] == 'GCC_BLOCKED') {
return [false, "highlight-blue disabled", "GCC Blocked"]; return [false, "highlight-blue disabled", "GCC Blocked"];
} else if (bookingStatus[2]) { } else if (bookingStatus[2]) {

155
src/main/resources/templates/user/viewhistory.html

@ -549,6 +549,31 @@
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 5px; border-radius: 5px;
} }
td.highlight-blue.ui-state-disabled {
opacity: 1 !important;
}
td.highlight-blue.ui-state-disabled .ui-state-default,
td.highlight-blue.ui-state-disabled a,
td.highlight-blue.ui-state-disabled span {
background: blue !important;
color: #fff !important;
cursor: not-allowed !important;
pointer-events: auto !important;
}
td.highlight-violet.ui-state-disabled {
opacity: 1 !important;
}
td.highlight-yellow.ui-state-disabled {
opacity: 1 !important;
}
td.highlight-pink.ui-state-disabled {
opacity: 1 !important;
}
</style> </style>
<body> <body>
@ -1456,17 +1481,19 @@
<div class="col"> <div class="col">
<input type="hidden" id="daysDiff"> <input type="hidden" id="daysDiff">
<label for="startingSlot" class="form-label">Starting Slot:</label> <label for="startingSlot" class="form-label">Starting Slot:</label>
<input type="text" class="form-control" id="startingSlotText"
name="startingSlot" readonly>
<input type="hidden" class="form-control" id="startingSlot"
name="startingSlot" required>
<select class="form-control" id="startingSlot" name="startingSlot">
<option value="1">Morning (6:00 AM)</option>
<option value="2">Afternoon (2:00 PM)</option>
</select>
</div> </div>
<div class="col"> <div class="col">
<label for="endingSlot" class="form-label">Ending Slot:</label> <label for="endingSlot" class="form-label">Ending Slot:</label>
<input type="text" class="form-control" id="endingSlotText"
name="endDateInput" readonly>
<input type="hidden" class="form-control" id="endingSlot"
name="endDateInput" readonly>
<select class="form-control" id="endingSlot" name="endingSlot" disabled>
<option value="1">Afternoon (2:00 PM)</option>
<option value="2">Evening (10:00 PM)</option>
</select>
<!-- mirrors endingSlot for form submission since disabled fields are excluded -->
<input type="hidden" id="endingSlotHidden" name="endingSlot">
</div> </div>
</div> </div>
<div class="row" style="margin-top: 39px;"> <div class="row" style="margin-top: 39px;">
@ -2382,14 +2409,15 @@
document.getElementById("startDateInput").value = startDate; document.getElementById("startDateInput").value = startDate;
document.getElementById("endDateInput").value = endDate; document.getElementById("endDateInput").value = endDate;
document.getElementById("noOfDaysInput").value = noOfDays; document.getElementById("noOfDaysInput").value = noOfDays;
document.getElementById("startingSlot").value = startingSlot;
document.getElementById("endingSlot").value = endingSlot;
document.getElementById("startingSlot").value = String(startingSlot);
document.getElementById("endingSlot").value = String(endingSlot);
document.getElementById("endingSlotHidden").value = String(endingSlot);
document.getElementById("daysDiff").value = daysDiff; document.getElementById("daysDiff").value = daysDiff;
// Display slot text in the modal // Display slot text in the modal
document.getElementById("startDatetext").value = startDate; document.getElementById("startDatetext").value = startDate;
document.getElementById("startingSlotText").value = getSlotText(startingSlot);
document.getElementById("endingSlotText").value = getSlotText(endingSlot);
// document.getElementById("startingSlotText").value = getSlotText(startingSlot);
// document.getElementById("endingSlotText").value = getSlotText(endingSlot);
// Store booking details for OTP verification // Store booking details for OTP verification
rescheduleBookingId = bookingId; rescheduleBookingId = bookingId;
@ -2503,9 +2531,9 @@
$("#startDateInput").on("change", function () { $("#startDateInput").on("change", function () {
var selectedDate = $(this).val(); var selectedDate = $(this).val();
var noOfDays = document.getElementById('noOfDaysInput').value;
// var noOfDays = document.getElementById('noOfDaysInput').value;
var startingSlot = document.getElementById("startingSlot").value; var startingSlot = document.getElementById("startingSlot").value;
var endingSlot = document.getElementById("endingSlot").value;
var endingSlot = document.getElementById("endingSlotHidden").value;
var noofdays = document.getElementById("noOfDaysInput").value; var noofdays = document.getElementById("noOfDaysInput").value;
updateEndDate(selectedDate, noofdays, startingSlot, endingSlot); updateEndDate(selectedDate, noofdays, startingSlot, endingSlot);
}); });
@ -2540,15 +2568,15 @@
function handleBookingStatus(bookingStatus, defaultMessage) { function handleBookingStatus(bookingStatus, defaultMessage) {
if (bookingStatus[2] && bookingStatus[0] && !bookingStatus[1]) { if (bookingStatus[2] && bookingStatus[0] && !bookingStatus[1]) {
return [true, "highlight-yellow disabled", "GCC Blocked"];
return [false, "highlight-yellow disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && !bookingStatus[0]) { } else if (bookingStatus[2] && bookingStatus[1] && !bookingStatus[0]) {
return [true, "highlight-violet disabled", "GCC Blocked"];
return [false, "highlight-violet disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] != 'GCC_BLOCKED' && bookingStatus[4] != 'GCC_BLOCKED') { } else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] != 'GCC_BLOCKED' && bookingStatus[4] != 'GCC_BLOCKED') {
return [true, "highlight-pink disabled", "GCC Blocked"];
return [false, "highlight-pink disabled", "GCC Blocked"];
} else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] == 'GCC_BLOCKED' && bookingStatus[4] == 'GCC_BLOCKED') { } else if (bookingStatus[2] && bookingStatus[1] && bookingStatus[0] && bookingStatus[3] == 'GCC_BLOCKED' && bookingStatus[4] == 'GCC_BLOCKED') {
return [true, "highlight-blue disabled", "GCC Blocked"];
return [false, "highlight-blue disabled", "GCC Blocked"];
} else if (bookingStatus[2]) { } else if (bookingStatus[2]) {
return [true, "highlight-blue disabled", "GCC Blocked"];
return [false, "highlight-blue disabled", "GCC Blocked"];
} else if (bookingStatus[0] && bookingStatus[1]) { } else if (bookingStatus[0] && bookingStatus[1]) {
return [true, "highlight-pink disabled", "Slot Occupied"]; return [true, "highlight-pink disabled", "Slot Occupied"];
} else if (bookingStatus[0] && !bookingStatus[1]) { } else if (bookingStatus[0] && !bookingStatus[1]) {
@ -2936,7 +2964,7 @@
// --- Slot availability check for today's date --- // --- Slot availability check for today's date ---
var startDate = document.getElementById("startDateInput").value; var startDate = document.getElementById("startDateInput").value;
var startingSlot = document.getElementById("startingSlot").value; var startingSlot = document.getElementById("startingSlot").value;
var endingSlot = document.getElementById("endingSlot").value;
var endingSlot = document.getElementById("endingSlotHidden").value;
var todayDateStr = $("#serverDate").val(); var todayDateStr = $("#serverDate").val();
var currentHour = new Date().getHours(); var currentHour = new Date().getHours();
@ -3149,7 +3177,9 @@
console.log('Reschedule data:', { console.log('Reschedule data:', {
bookingId: rescheduleBookingId, bookingId: rescheduleBookingId,
startDate: rescheduleStartDate, startDate: rescheduleStartDate,
endDate: rescheduleEndDate
endDate: rescheduleEndDate,
startingSlot: rescheduleStartingSlot,
endingSlot: rescheduleEndingSlot
}); });
$.ajax({ $.ajax({
@ -3158,7 +3188,9 @@
data: { data: {
bookingId: rescheduleBookingId, bookingId: rescheduleBookingId,
startDate: rescheduleStartDate, startDate: rescheduleStartDate,
endDate: rescheduleEndDate
endDate: rescheduleEndDate,
startingSlot: rescheduleStartingSlot,
endingSlot: rescheduleEndingSlot
}, },
success: function (response) { success: function (response) {
Swal.fire({ Swal.fire({
@ -3210,7 +3242,8 @@
var endDate = document.getElementById("endDateInput").value; var endDate = document.getElementById("endDateInput").value;
var originalStartDate = document.getElementById("startDatetext").value; var originalStartDate = document.getElementById("startDatetext").value;
var startingSlot = document.getElementById("startingSlot").value; var startingSlot = document.getElementById("startingSlot").value;
var endingSlot = document.getElementById("endingSlot").value;
// var endingSlot = document.getElementById("endingSlot").value;
var endingSlot = document.getElementById("endingSlotHidden").value;
// Get today's date from server // Get today's date from server
var todayDateStr = $("#serverDate").val(); var todayDateStr = $("#serverDate").val();
@ -3228,15 +3261,15 @@
}); });
// Check if the rescheduled start date is the same as the original booked start date // Check if the rescheduled start date is the same as the original booked start date
if (startDate === originalStartDate) {
Swal.fire({
icon: 'warning',
title: 'Warning',
text: 'Your Rescheduled Start Date is the same as Your booking Start Date. Please change the date.',
showConfirmButton: true
});
return;
}
// if (startDate === originalStartDate) {
// Swal.fire({
// icon: 'warning',
// title: 'Warning',
// text: 'Your Rescheduled Start Date is the same as Your booking Start Date. Please change the date.',
// showConfirmButton: true
// });
// return;
// }
if (!endDate) { if (!endDate) {
Swal.fire({ Swal.fire({
icon: 'error', icon: 'error',
@ -3286,11 +3319,15 @@
// Store the validated dates // Store the validated dates
rescheduleStartDate = startDate; rescheduleStartDate = startDate;
rescheduleEndDate = endDate; rescheduleEndDate = endDate;
rescheduleStartingSlot = document.getElementById('startingSlot').value;
rescheduleEndingSlot = document.getElementById('endingSlotHidden').value;
// Debug: Log the final dates being sent // Debug: Log the final dates being sent
console.log('Final reschedule dates:', { console.log('Final reschedule dates:', {
startDate: rescheduleStartDate, startDate: rescheduleStartDate,
endDate: rescheduleEndDate, endDate: rescheduleEndDate,
startingSlot: rescheduleStartingSlot,
endingSlot: rescheduleEndingSlot,
bookingId: rescheduleBookingId bookingId: rescheduleBookingId
}); });
proceedWithReschedule(); proceedWithReschedule();
@ -3452,6 +3489,60 @@
} }
} }
// ── Slot helper ──────────────────────────────────────────────────────
// Ending slot is deterministic: given (startSlot + noOfDays) there is
// exactly one valid ending slot. The user can only change Starting Slot;
// Ending Slot auto-fixes based on this table:
//
// noOfDays | start=1(Morning) → end | start=2(Afternoon) → end
// ---------|------------------------|-------------------------
// 0.5 | 1 (same slot, half-day) | 2 (same slot, half-day)
// 1 | 2 (6AM→10PM, full day) | 1 (2PM→next day 2PM)
// 1.5 | 1 (6AM→next day 2PM) | 2 (2PM→next day 10PM)
// 2 | 2 (6AM→day+1 10PM) | ❌ not allowed
function computeEndingSlot(startSlot, noOfDays) {
startSlot = String(startSlot);
noOfDays = parseFloat(noOfDays);
if (noOfDays === 0.5) return startSlot; // same slot, half-day
if (noOfDays === 1) return startSlot === "1" ? "2" : "1"; // flip: full-day
if (noOfDays === 1.5) return startSlot; // same slot, 1.5 days
if (noOfDays === 2) return startSlot === "1" ? "2" : null; // only morning valid for 2-day
return null;
}
// When user changes Starting Slot → auto-fix Ending Slot, re-validate end date
document.getElementById("startingSlot").addEventListener("change", function () {
var startSlot = this.value;
var noOfDays = parseFloat(document.getElementById("noOfDaysInput").value);
var endSlot = computeEndingSlot(startSlot, noOfDays);
// Guard: Afternoon start is not valid for 2-day booking
if (endSlot === null) {
Swal.fire({
icon: 'warning',
title: 'Slot Not Allowed',
text: 'Afternoon start is not supported for a ' + noOfDays + '-day booking. Reverting to the original slot.',
showConfirmButton: true
});
this.value = String(rescheduleStartingSlot);
return;
}
// Auto-fix the (disabled) ending slot display and its hidden mirror
document.getElementById("endingSlot").value = endSlot;
document.getElementById("endingSlotHidden").value = endSlot;
// Clear the computed end date — user must re-pick or it will re-compute
document.getElementById("endDateInput").value = "";
// If a start date is already selected, re-compute end date immediately
var startDate = document.getElementById("startDateInput").value;
if (startDate) {
updateEndDate(startDate, noOfDays, startSlot, endSlot);
}
});
// OTP input navigation for reschedule modal // OTP input navigation for reschedule modal
$('.otp-input').on('keyup', function (e) { $('.otp-input').on('keyup', function (e) {
var $this = $(this); var $this = $(this);

3530
src/main/resources/templates/user/viewhistory_old.html
File diff suppressed because it is too large
View File

3538
src/main/resources/templates/user/viewhistory_reschedulelogic.html
File diff suppressed because it is too large
View File

Loading…
Cancel
Save