Browse Source

added permanent flow and service, controller ,pages

master
yoganandhan 8 months ago
parent
commit
86ff96e67d
  1. 2
      src/main/java/com/gcc/flagpoles/configuration/DataSourceConfig.java
  2. 17
      src/main/java/com/gcc/flagpoles/constants/AppConstants.java
  3. 152
      src/main/java/com/gcc/flagpoles/controller/ApiController.java
  4. 35
      src/main/java/com/gcc/flagpoles/controller/DateTimeUtil.java
  5. 29
      src/main/java/com/gcc/flagpoles/controller/DropDownApiController.java
  6. 39
      src/main/java/com/gcc/flagpoles/service/DateTimeUtil.java
  7. 25
      src/main/java/com/gcc/flagpoles/service/DropDownService.java
  8. 118
      src/main/java/com/gcc/flagpoles/service/FileUploadService.java
  9. 445
      src/main/java/com/gcc/flagpoles/service/RequestService.java
  10. 4
      src/main/resources/application-dev.properties
  11. 5
      src/main/resources/application-prod.properties
  12. 2
      src/main/resources/application.properties
  13. BIN
      src/main/resources/static/assets/images/logo.png
  14. 20
      src/main/resources/templates/fragments/details.html
  15. 3
      src/main/resources/templates/modules/flagpolesregistration/acknowledgement.html
  16. 325
      src/main/resources/templates/modules/flagpolesregistration/index.html
  17. 4
      src/main/resources/templates/modules/flagpolesregistration/razor-pay.html
  18. 2304
      src/main/resources/templates/modules/flagpolesregistration/requestform.html
  19. 870
      src/main/resources/templates/modules/flagpolesregistration/status.html

2
src/main/java/com/gcc/flagpoles/configuration/DataSourceConfig.java

@ -22,7 +22,7 @@ public class DataSourceConfig {
private static final String host = "localhost";
private static final String dbpassword = "root";
// For AWS
// // For AWS
// private static String host =
// "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306";
// private static String dbpassword = "gcc-facial-password";

17
src/main/java/com/gcc/flagpoles/constants/AppConstants.java

@ -1,15 +1,12 @@
package com.gcc.flagpoles.constants;
public final class AppConstants {
// for Production
// public static String key_id="rzp_live_66FhxMUNAb9McO";
// public static String key_secret="aoIzMGQE3xOxin92rYaK75jV";
// for Production from coworking space booking key_id key_secret
// public static String key_id = "rzp_live_ySI5Ns54Y7qOcJ";
// public static String key_secret = "Nwf1TjhUtaskof8vePkRR8Sb";
// uncomment for testing payment
public static String key_id = "rzp_test_tDkHFEqWXmuEi8";
public static String key_secret = "cBQUjMcKZ4J6vmOKSyNZ92py";
//uncomment for testing payment
public static String key_id="rzp_test_TADBzz8BXbBpos";
public static String key_secret="3es3YZ3DFVYdibbGLBtL8nBB";
}
}

152
src/main/java/com/gcc/flagpoles/controller/ApiController.java

@ -14,6 +14,7 @@ import java.util.Random;
import com.gcc.flagpoles.configuration.AppConfig;
//import org.json.JSONObject;
import com.gcc.flagpoles.constants.AppConstants;
import com.gcc.flagpoles.service.FileUploadService;
import com.gcc.flagpoles.service.PaymentService;
import com.razorpay.Order;
import com.razorpay.RazorpayClient;
@ -22,6 +23,7 @@ import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
@ -67,6 +69,9 @@ public class ApiController {
@Autowired
private PaymentService paymentService;
@Autowired
private FileUploadService fileUploadService;
// @Autowired
// private PaymentService paymentService ;
@ -90,7 +95,7 @@ public class ApiController {
Random rand = new Random();
int otp = rand.nextInt(90000) + 10000;
//int otp = 22222;
// int otp = 22222;
System.out.print("\n otp---:" + otp);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm");
LocalDateTime now = LocalDateTime.now();
@ -180,7 +185,7 @@ public class ApiController {
Random rand = new Random();
int otp = rand.nextInt(90000) + 10000;
//int otp = 22222;
// int otp = 22222;
System.out.print("\n otp---:" + otp);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm");
LocalDateTime now = LocalDateTime.now();
@ -262,10 +267,18 @@ public class ApiController {
}
}
@PostMapping("/saveRequest")
public ResponseEntity<?> saveRequest(@RequestParam MultiValueMap<String, String> params) {
@PostMapping(value = "/saveRequest", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<?> saveRequest(
@RequestParam MultiValueMap<String, String> params,
@RequestParam(required = false) MultipartFile aadhaarFile,
@RequestParam(required = false) MultipartFile pattaFile,
@RequestParam(required = false) MultipartFile affidavitFile,
@RequestParam(required = false) MultipartFile ecFile,
@RequestParam(required = false) MultipartFile fmbSketchFile) {
try {
// ✅ 1. Extract Applicant Info
/* ================= Applicant ================= */
Map<String, Object> applicant = new HashMap<>();
applicant.put("name", params.getFirst("name"));
applicant.put("mobileNumber", params.getFirst("mobileNumber"));
@ -278,26 +291,103 @@ public class ApiController {
"message", "Applicant details are incomplete."));
}
// ✅ 2. Extract Event Info (with cost-related fields)
String aadhaarNo = params.getFirst("aadhaarNo");
if (aadhaarNo == null || !aadhaarNo.matches("\\d{12}")) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", "Valid Aadhaar number is mandatory."));
}
/* ================= Application ================= */
String applicationType = params.getFirst("applicationType"); // 1 TEMP, 2 PERMANENT
String applicationOption = params.getFirst("applicationOption"); // 1 Pole, 2 Statue
if (applicationType == null) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", "Application Type is required."));
}
// Validation for Permanent Application fields
if ("2".equals(applicationType)) {
if (params.getFirst("surveyNo") == null || params.getFirst("surveyNo").trim().isEmpty()) {
return ResponseEntity.badRequest()
.body(Map.of("status", "error", "message", "Survey Number is required."));
}
if (params.getFirst("placeOfErection") == null || params.getFirst("placeOfErection").trim().isEmpty()) {
return ResponseEntity.badRequest()
.body(Map.of("status", "error", "message", "Place of Erection is required."));
}
}
/* ================= FILE UPLOAD (PERMANENT ONLY) ================= */
String aadhaarPath = null;
String pattaPath = null;
String affidavitPath = null;
String ecPath = null;
String fmbPath = null;
if ("2".equals(applicationType)) {
if (aadhaarFile != null && !aadhaarFile.isEmpty())
aadhaarPath = fileUploadService.fileUpload(aadhaarFile, "aadhaar");
if (pattaFile != null && !pattaFile.isEmpty())
pattaPath = fileUploadService.fileUpload(pattaFile, "patta");
if (affidavitFile != null && !affidavitFile.isEmpty())
affidavitPath = fileUploadService.fileUpload(affidavitFile, "affidavit");
if (ecFile != null && !ecFile.isEmpty())
ecPath = fileUploadService.fileUpload(ecFile, "ec");
if (fmbSketchFile != null && !fmbSketchFile.isEmpty())
fmbPath = fileUploadService.fileUpload(fmbSketchFile, "fmb");
}
// Inject paths for service layer
params.set("aadhaarImagePath", aadhaarPath);
params.set("pattaImagePath", pattaPath);
params.set("affidavitImagePath", affidavitPath);
params.set("ecImagePath", ecPath);
params.set("fmbSketchPath", fmbPath);
/* ================= Event ================= */
Map<String, Object> event = new HashMap<>();
event.put("type", params.getFirst("eventType"));
event.put("date", params.getFirst("eventDate"));
event.put("description", params.getFirst("description"));
event.put("totalPoles", params.getFirst("totalPoles"));
// event.put("deposit", params.getFirst("deposit"));
event.put("totalCost", params.getFirst("totalCost"));
if (event.get("type") == null || event.get("date") == null || event.get("description") == null) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", "Event details are incomplete."));
if (!"2".equals(applicationType)) {
if (event.get("type") == null || event.get("date") == null || event.get("description") == null) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", "Event details are incomplete."));
}
}
/* ================= Statue Count ================= */
if ("2".equals(applicationType) && "2".equals(applicationOption)) {
event.put("totalStatue", "1");
event.put("totalPoles", "0");
} else {
event.put("totalStatue", "0");
}
// ✅ 3. Build List of Streets
/* ================= Streets ================= */
List<Map<String, Object>> streets = new ArrayList<>();
int index = 0;
String globalRatePerPole = params.getFirst("ratePerPole"); // top-level
String globalRatePerPole = params.getFirst("ratePerPole");
while (true) {
String prefix = "streets[" + index + "].";
if (params.getFirst(prefix + "streetName") == null)
@ -310,18 +400,16 @@ public class ApiController {
s.put("noOfPoles", params.getFirst(prefix + "noOfPoles"));
s.put("poleHeight", params.getFirst(prefix + "poleHeight"));
s.put("poleMaterial", params.getFirst(prefix + "poleMaterial"));
s.put("pedestalMaterial", params.getFirst(prefix + "pedestalMaterial"));
s.put("statueMaterial", params.getFirst(prefix + "statueMaterial"));
s.put("flagMaterial", params.getFirst(prefix + "flagMaterial"));
s.put("spacing", params.getFirst(prefix + "spacing"));
s.put("durationDays", params.getFirst(prefix + "durationDays"));
// ✅ Ensure latitude/longitude keys match your service
s.put("lat", params.getFirst(prefix + "lat"));
s.put("long", params.getFirst(prefix + "long"));
// ✅ Fix here: use top-level rate if per-street is null
String rate = params.getFirst(prefix + "ratePerPole");
s.put("ratePerPole", rate != null ? rate : globalRatePerPole);
// ⚙️ Optional validation
if (s.get("lat") == null || s.get("long") == null) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
@ -335,31 +423,35 @@ public class ApiController {
if (streets.isEmpty()) {
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", "No street data found in request."));
"message", "No street data found."));
}
if ("2".equals(applicationType) && streets.size() > 1) {
streets = streets.subList(0, 1);
}
// System.out.println("applicant" + applicant);
// System.out.println("streets" + streets);
// System.out.println("events" + event);
// ✅ 4. Save request (Service internally checks for nearby requests)
// String userReqId = requestService.saveFlagPoleRequest(applicant, event,
// streets);
String tempRefId = requestService.saveTempBooking(applicant, event, streets);
/* ================= Save ================= */
String refId;
if ("2".equals(applicationType)) {
refId = requestService.savePermanentRequest(applicant, event, streets, params);
} else {
refId = requestService.saveTempBooking(applicant, event, streets, params);
}
// ✅ 5. Return Success Response
return ResponseEntity.ok(Map.of(
"status", "success",
"message", "Application saved successfully.",
"request_id", tempRefId));
"request_id", refId));
} catch (IllegalArgumentException iae) {
// ⛔ Custom validation or nearby request check failure
return ResponseEntity.badRequest().body(Map.of(
"status", "error",
"message", iae.getMessage()));
} catch (Exception e) {
// ⛔ Unexpected errors
e.printStackTrace();
return ResponseEntity.internalServerError().body(Map.of(
"status", "error",

35
src/main/java/com/gcc/flagpoles/controller/DateTimeUtil.java

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

29
src/main/java/com/gcc/flagpoles/controller/DropDownApiController.java

@ -74,4 +74,33 @@ public class DropDownApiController {
}
}
// get application type
@GetMapping("/getapplicationtype")
public List<Map<String, Object>> getapplicationtype() {
return dropDownService.getApplicationType();
}
// get application type
@GetMapping("/getinstallationtype")
public List<Map<String, Object>> getInstallationType() {
return dropDownService.getInstallationType();
}
// get application type
@GetMapping("/getapplicationoption")
public List<Map<String, Object>> getApplicationOption() {
return dropDownService.getApplicationOption();
}
// get application type
@GetMapping("/getpedestalmaterial")
public List<Map<String, Object>> getPedestalMaterial() {
return dropDownService.getPedestalMaterial();
}
@GetMapping("/getstatuematerial")
public List<Map<String, Object>> getStatueMaterial() {
return dropDownService.getStatueMaterial();
}
}

39
src/main/java/com/gcc/flagpoles/service/DateTimeUtil.java

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

25
src/main/java/com/gcc/flagpoles/service/DropDownService.java

@ -190,4 +190,29 @@ public class DropDownService {
String sql = "SELECT id, ward_name FROM wards WHERE zone_id = ? AND is_active = 1 ";
return mysqlJdbcTemplate.queryForList(sql, zoneId);
}
public List<Map<String, Object>> getApplicationType() {
String sql = "SELECT id, type FROM application_type WHERE is_active = 1 ";
return mysqlJdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> getApplicationOption() {
String sql = "SELECT id, option_name FROM application_option WHERE is_active = 1 ";
return mysqlJdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> getInstallationType() {
String sql = "SELECT id, installation_name FROM installation_type WHERE is_active = 1 and is_delete = 0";
return mysqlJdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> getStatueMaterial() {
String sql = "SELECT id, statue_material_type FROM statue_material WHERE is_active = 1 and is_delete = 0";
return mysqlJdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> getPedestalMaterial() {
String sql = "SELECT id, statue_pedestal_type FROM pedestal_material WHERE is_active = 1 and is_delete = 0";
return mysqlJdbcTemplate.queryForList(sql);
}
}

118
src/main/java/com/gcc/flagpoles/service/FileUploadService.java

@ -0,0 +1,118 @@
package com.gcc.flagpoles.service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
public class FileUploadService {
@Autowired
private Environment environment;
// public String fileUpload(MultipartFile file, String name) {
// String uploadDirectory =
// environment.getProperty("file.upload.directory.mobile");
// String serviceFolderName = environment.getProperty("flagpoles_foldername");
// if (uploadDirectory == null || serviceFolderName == null) {
// throw new RuntimeException("Upload directory or service folder not
// configured");
// }
// var year = DateTimeUtil.getCurrentYear();
// var month = DateTimeUtil.getCurrentMonth();
// uploadDirectory = uploadDirectory + serviceFolderName + "/" + year + "/" +
// month + "/" +doctype;
// try {
// // Create folders if not exist
// Path directoryPath = Paths.get(uploadDirectory);
// if (!Files.exists(directoryPath)) {
// Files.createDirectories(directoryPath);
// }
// // Datetime string
// String datetimetxt = DateTimeUtil.getCurrentDateTime();
// // File name
// String fileName = name + "_" + datetimetxt + "_" +
// file.getOriginalFilename();
// fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename
// String filePath = uploadDirectory + "/" + fileName;
// String filepath_txt = "/" + serviceFolderName + "/" + year + "/" + month +
// "/" + fileName;
// // Create a new Path object
// Path path = Paths.get(filePath);
// // Get the bytes of the file
// byte[] bytes = file.getBytes();
// Files.write(path, bytes);
// // System.out.println(filePath);
// return filepath_txt;
// } catch (IOException e) {
// throw new RuntimeException("Failed to upload file: " +
// file.getOriginalFilename(), e);
// }
// }
public String fileUpload(MultipartFile file, String docType) {
String uploadDirectory = environment.getProperty("file.upload.directory");
String serviceFolderName = environment.getProperty("flagpoles_foldername");
if (uploadDirectory == null || serviceFolderName == null) {
throw new RuntimeException("Upload directory or service folder not configured");
}
String year = DateTimeUtil.getCurrentYear();
String month = DateTimeUtil.getCurrentMonth();
// 👉 base + service + year + month + documentType
String finalUploadDir = uploadDirectory + serviceFolderName + "/" + year + "/" + month + "/" + docType;
try {
// Create directory tree
Path directoryPath = Paths.get(finalUploadDir);
if (!Files.exists(directoryPath)) {
Files.createDirectories(directoryPath);
}
String datetimetxt = DateTimeUtil.getCurrentDateTime();
String originalName = file.getOriginalFilename();
originalName = originalName == null ? "file" : originalName.replaceAll("\\s+", "");
String fileName = docType + "_" + datetimetxt + "_" + originalName;
Path filePath = Paths.get(finalUploadDir + "/" + fileName);
Files.write(filePath, file.getBytes());
// 👉 Path saved to DB (must include docType)
return "/" + serviceFolderName + "/" + year + "/" + month + "/" + docType + "/" + fileName;
} catch (IOException e) {
throw new RuntimeException("Failed to upload file: " + file.getOriginalFilename(), e);
}
}
}

445
src/main/java/com/gcc/flagpoles/service/RequestService.java

@ -70,8 +70,8 @@ public class RequestService {
INSERT INTO user_request_details
(applicant_name, mobile_number, applicant_address,
event_id, event_date, event_desc, no_of_days,
total_poles, total_cost,payment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?)
total_poles, total_cost,application_type,payment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)
""";
KeyHolder keyHolder = new GeneratedKeyHolder();
@ -91,7 +91,8 @@ public class RequestService {
ps.setInt(8, Integer.parseInt(event.get("totalPoles").toString()));
// ps.setDouble(9, deposit);
ps.setDouble(9, Double.parseDouble(event.get("totalCost").toString()));
ps.setString(10, paymentstatus);
ps.setInt(10, 1);
ps.setString(11, paymentstatus);
return ps;
}, keyHolder);
@ -147,32 +148,41 @@ public class RequestService {
public String saveTempBooking(
Map<String, Object> applicant,
Map<String, Object> event,
List<Map<String, Object>> streets) {
List<Map<String, Object>> streets,
MultiValueMap<String, String> params) {
// 1️⃣ Insert TEMP booking (without refid)
KeyHolder keyHolder = new GeneratedKeyHolder();
mysqlJdbcTemplate.update(con -> {
PreparedStatement ps = con.prepareStatement("""
INSERT INTO temp_booking
(
applicant_name,
mobile_number,
applicant_address,
event_id,
event_date,
event_desc,
no_of_days,
total_poles,
deposit,
total_cost,
payment_status,
booking_status,
is_active,
is_delete
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'PENDING', 'INITIATED', 1, 0)
""", Statement.RETURN_GENERATED_KEYS);
INSERT INTO temp_booking
(
applicant_name,
mobile_number,
applicant_address,
event_id,
event_date,
event_desc,
no_of_days,
total_poles,
deposit,
total_cost,
application_type,
aadhaar_no,
aadhaar_image_path,
payment_status,
booking_status,
is_active,
is_delete
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?,
'PENDING', 'INITIATED', 1, 0)
""", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, applicant.get("name").toString());
ps.setString(2, applicant.get("mobileNumber").toString());
@ -184,6 +194,11 @@ public class RequestService {
ps.setInt(8, Integer.parseInt(event.get("totalPoles").toString()));
ps.setDouble(9, 0.0);
ps.setDouble(10, Double.parseDouble(event.get("totalCost").toString()));
ps.setInt(11, Integer.parseInt(params.getFirst("applicationType")));
ps.setString(12, params.getFirst("aadhaarNo"));
ps.setString(13, params.getFirst("aadhaarImagePath"));
return ps;
}, keyHolder);
@ -238,6 +253,206 @@ public class RequestService {
return tempRefId;
}
@Transactional(transactionManager = "mysqlgccFlagPoleTransactionManager")
public String savePermanentRequest(
Map<String, Object> applicant,
Map<String, Object> event,
List<Map<String, Object>> streets,
MultiValueMap<String, String> params) {
KeyHolder kh = new GeneratedKeyHolder();
// ---------- SAFE FINAL VALUES (lambda compatible) ----------
final Integer eventType = (event.get("type") != null && !event.get("type").toString().isBlank())
? Integer.parseInt(event.get("type").toString())
: null;
final int totalPoles = (event.get("totalPoles") != null && !event.get("totalPoles").toString().isBlank())
? Integer.parseInt(event.get("totalPoles").toString())
: 0;
final int totalStatue = (event.get("totalStatue") != null && !event.get("totalStatue").toString().isBlank())
? Integer.parseInt(event.get("totalStatue").toString())
: 0;
final double totalCost = (event.get("totalCost") != null && !event.get("totalCost").toString().isBlank())
? Double.parseDouble(event.get("totalCost").toString())
: 0.0;
// ---------- SAFE EVENT DATE & DESC ----------
final String eventDate = (event.get("date") != null && !event.get("date").toString().isBlank())
? event.get("date").toString()
: null;
final String eventDesc = (event.get("description") != null && !event.get("description").toString().isBlank())
? event.get("description").toString()
: null;
mysqlJdbcTemplate.update(con -> {
PreparedStatement ps = con.prepareStatement("""
INSERT INTO user_request_details
(
applicant_name,
mobile_number,
applicant_address,
event_id,
event_date,
event_desc,
no_of_days,
total_poles,
total_statue,
total_cost,
application_type,
application_option,
installation_type,
aadhaar_no,
aadhaar_image_path,
survey_no,
place_of_erection,
others_specify_statue_material,
patta_image_path,
affidavit_image_path,
ec_image_path,
fmb_sketch_path,
cdate,
payment_status,
booking_status
)
VALUES (?,?,?,?,?,?,?,?,?,?,
?,?,?,
?,?,
?,?,?,?,?,?,?,
NOW(),'NA','PERMANENT')
""", Statement.RETURN_GENERATED_KEYS);
// ---------- Applicant ----------
ps.setString(1, applicant.get("name").toString());
ps.setString(2, applicant.get("mobileNumber").toString());
ps.setString(3, applicant.get("address").toString());
// ---------- Event (NULL for permanent) ----------
ps.setObject(4, eventType);
ps.setString(5, eventDate);
ps.setString(6, eventDesc);
// ---------- Days ----------
ps.setInt(7, getFirstStreetDays(streets));
ps.setInt(8, totalPoles);
ps.setInt(9, totalStatue);
ps.setDouble(10, totalCost);
// ---------- Masters ----------
ps.setInt(11, 2); // PERMANENT
ps.setObject(12,
params.getFirst("applicationOption") != null
? Integer.parseInt(params.getFirst("applicationOption"))
: null);
ps.setObject(13,
params.getFirst("installationType") != null
? Integer.parseInt(params.getFirst("installationType"))
: null);
// ---------- Aadhaar ----------
ps.setString(14, params.getFirst("aadhaarNo"));
ps.setString(15, params.getFirst("aadhaarImagePath"));
// ---------- Permanent extra ----------
ps.setString(16, params.getFirst("surveyNo"));
ps.setString(17, params.getFirst("placeOfErection"));
ps.setString(18, params.getFirst("otherStatueMaterial"));
ps.setString(19, params.getFirst("pattaImagePath"));
ps.setString(20, params.getFirst("affidavitImagePath"));
ps.setString(21, params.getFirst("ecImagePath"));
ps.setString(22, params.getFirst("fmbSketchPath"));
return ps;
}, kh);
int id = kh.getKey().intValue();
// ---------- REFID ----------
String refId = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + id;
mysqlJdbcTemplate.update("""
UPDATE user_request_details
SET refid = ?
WHERE id = ?
""", refId, id);
// ---------- Streets ----------
boolean isStatue = "2".equals(params.getFirst("applicationOption"));
for (Map<String, Object> s : streets) {
int noOfPoles = 0;
int noOfStatue = 0;
if (isStatue) {
noOfStatue = 1;
} else {
noOfPoles = Integer.parseInt(s.get("noOfPoles").toString());
}
mysqlJdbcTemplate.update("""
INSERT INTO street_details
(
street_name,
latitude,
longitude,
zone,
ward,
no_of_poles,
no_of_statue,
height,
pole_material_id,
flag_material_id,
pedestal_material_id,
statue_material_id,
no_of_days,
street_cost,
user_req_id,
refid
)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""",
s.get("streetName"),
s.get("lat"),
s.get("long"),
s.get("zoneId"),
s.get("wardId"),
noOfPoles,
noOfStatue,
// height
s.get("poleHeight"),
// pole + flag
s.get("poleMaterial"),
s.get("flagMaterial"),
// 👇 NEW
s.get("pedestalMaterial"),
s.get("statueMaterial"),
s.get("durationDays"),
s.get("ratePerPole"),
id,
refId);
}
return refId;
}
@Transactional(transactionManager = "mysqlgccFlagPoleTransactionManager")
public String moveTempToFinal(String tempRefId) {
@ -255,6 +470,7 @@ public class RequestService {
total_poles,
deposit,
total_cost,
application_type,
cdate,
payment_status,
booking_status
@ -270,6 +486,7 @@ public class RequestService {
total_poles,
deposit,
total_cost,
application_type,
NOW(),
'COMPLETED',
booking_status
@ -536,7 +753,8 @@ public class RequestService {
DATE_FORMAT(ud.event_date,'%d-%m-%Y') AS event_date,
DATE_FORMAT(ud.cdate,'%d-%m-%Y') AS cdate,
ud.total_poles,
ud.no_of_days
ud.no_of_days,
ud.application_type
FROM temp_booking ud
@ -620,6 +838,7 @@ public class RequestService {
DATE_FORMAT(urd.cdate,'%d-%m-%Y') AS cdate,
urd.total_poles,
urd.no_of_days,
urd.application_type,
p.payment_id,
p.paymentstatus,
@ -830,6 +1049,125 @@ public class RequestService {
// return new ArrayList<>(resultMap.values());
// }
// old
// @Transactional(transactionManager = "mysqlgccFlagPoleTransactionManager")
// public List<Map<String, Object>> searchRequestsByRefIdOrMobile(
// String refId,
// String mobileNumber) {
// StringBuilder sql = new StringBuilder("""
// SELECT
// urd.id,
// urd.applicant_name,
// urd.mobile_number,
// urd.applicant_address,
// urd.event_date,
// urd.ae_status,
// urd.rdo_status,
// urd.no_of_days,
// urd.rdo_remarks,
// urd.refid,
// urd.payment_status,
// urd.booking_status,
// urd.cdate,
// urd.approved_date,
// urd.approved_by,
// sd.street_name,
// sd.zone,
// sd.ward,
// sd.no_of_poles,
// sd.street_cost,
// urd.total_cost,
// et.event_name,
// IFNULL(fc.fine_amount, 0) AS fine_amount,
// IFNULL(rp.amount, 0) AS restoration_amount
// FROM user_request_details urd
// LEFT JOIN street_details sd
// ON urd.refid = sd.refid
// AND sd.is_active = 1
// AND sd.is_delete = 0
// LEFT JOIN event_type et
// ON urd.event_id = et.id
// LEFT JOIN fine_collection fc
// ON urd.refid = fc.ref_id
// AND fc.isactive = 1
// AND fc.isdelete = 0
// LEFT JOIN restoration rp
// ON urd.refid = rp.ref_id
// AND rp.is_active = 1
// AND rp.is_delete = 0
// WHERE 1 = 1
// """);
// List<Object> params = new ArrayList<>();
// // 🔹 Search priority: RefId first, else Mobile
// if (refId != null && !refId.trim().isEmpty()) {
// sql.append(" AND urd.refid = ? ");
// params.add(refId.trim());
// } else if (mobileNumber != null && !mobileNumber.trim().isEmpty()) {
// sql.append(" AND urd.mobile_number = ? ");
// params.add(mobileNumber.trim());
// }
// sql.append(" ORDER BY urd.cdate DESC, sd.id ");
// List<Map<String, Object>> rows =
// mysqlJdbcTemplate.queryForList(sql.toString(), params.toArray());
// // 🔥 GROUP BY REFID
// Map<String, Map<String, Object>> resultMap = new LinkedHashMap<>();
// for (Map<String, Object> row : rows) {
// String refid = (String) row.get("refid");
// Map<String, Object> request = resultMap.computeIfAbsent(refid, k -> {
// Map<String, Object> map = new LinkedHashMap<>();
// map.put("refid", row.get("refid"));
// map.put("applicant_name", row.get("applicant_name"));
// map.put("mobile_number", row.get("mobile_number"));
// map.put("applicant_address", row.get("applicant_address"));
// map.put("event_date", row.get("event_date"));
// map.put("ae_status", row.get("ae_status"));
// map.put("rdo_status", row.get("rdo_status"));
// map.put("rdo_remarks", row.get("rdo_remarks"));
// map.put("approved_by", row.get("approved_by"));
// map.put("approved_date", row.get("approved_date"));
// map.put("no_of_days", row.get("no_of_days"));
// map.put("event_name", row.get("event_name"));
// map.put("total_cost", row.get("total_cost"));
// map.put("payment_status", row.get("payment_status"));
// map.put("booking_status", row.get("booking_status"));
// map.put("fine_amount", row.get("fine_amount"));
// map.put("restoration_amount", row.get("restoration_amount"));
// map.put("streets", new ArrayList<>());
// return map;
// });
// Map<String, Object> street = new LinkedHashMap<>();
// street.put("street_name", row.get("street_name"));
// street.put("zone", row.get("zone"));
// street.put("ward", row.get("ward"));
// street.put("no_of_poles", row.get("no_of_poles"));
// street.put("street_cost", row.get("street_cost"));
// ((List<Map<String, Object>>) request.get("streets")).add(street);
// }
// return new ArrayList<>(resultMap.values());
// }
@Transactional(transactionManager = "mysqlgccFlagPoleTransactionManager")
public List<Map<String, Object>> searchRequestsByRefIdOrMobile(
String refId,
@ -844,18 +1182,37 @@ public class RequestService {
urd.event_date,
urd.ae_status,
urd.rdo_status,
urd.final_status, -- NEW
urd.final_remarks,
urd.final_approved_by, -- OPTIONAL
urd.final_approved_date, -- OPTIONAL
urd.no_of_days,
urd.rdo_remarks,
urd.refid,
urd.payment_status,
urd.booking_status,
urd.application_type,
urd.application_option,
urd.installation_type,
at.type AS application_type_name, -- MASTER JOIN
ao.option_name AS application_option_name, -- MASTER JOIN
it.installation_name AS installation_name, -- MASTER JOIN
urd.aadhaar_no,
urd.survey_no,
urd.place_of_erection,
urd.cdate,
urd.approved_date,
urd.approved_by,
sd.street_name,
sd.zone,
sd.ward,
sd.no_of_poles,
sd.street_cost,
pm.pole_material_name, -- MASTER JOIN
fm.flag_material_name, -- MASTER JOIN
sm.statue_material_type, -- MASTER JOIN
pdm.statue_pedestal_type, -- MASTER JOIN
urd.total_cost,
et.event_name,
@ -873,6 +1230,27 @@ public class RequestService {
LEFT JOIN event_type et
ON urd.event_id = et.id
LEFT JOIN application_type at
ON urd.application_type = at.id
LEFT JOIN application_option ao
ON urd.application_option = ao.id
LEFT JOIN installation_type it
ON urd.installation_type = it.id
LEFT JOIN pole_material pm
ON sd.pole_material_id = pm.id
LEFT JOIN flag_material fm
ON sd.flag_material_id = fm.id
LEFT JOIN statue_material sm
ON sd.statue_material_id = sm.id
LEFT JOIN pedestal_material pdm
ON sd.pedestal_material_id = pdm.id
LEFT JOIN fine_collection fc
ON urd.refid = fc.ref_id
AND fc.isactive = 1
@ -918,12 +1296,27 @@ public class RequestService {
map.put("event_date", row.get("event_date"));
map.put("ae_status", row.get("ae_status"));
map.put("rdo_status", row.get("rdo_status"));
map.put("final_status", row.get("final_status")); // ✅ NEW
map.put("final_remarks", row.get("final_remarks")); // ✅ NEW
map.put("final_approved_by", row.get("final_approved_by")); // ✅ OPTIONAL
map.put("final_approved_date", row.get("final_approved_date")); // ✅ OPTIONAL
map.put("rdo_remarks", row.get("rdo_remarks"));
map.put("approved_by", row.get("approved_by"));
map.put("approved_date", row.get("approved_date"));
map.put("no_of_days", row.get("no_of_days"));
map.put("event_name", row.get("event_name"));
map.put("total_cost", row.get("total_cost"));
map.put("payment_status", row.get("payment_status"));
map.put("booking_status", row.get("booking_status"));
map.put("application_type", row.get("application_type"));
map.put("application_type_name", row.get("application_type_name")); // ✅ NEW
map.put("application_option", row.get("application_option"));
map.put("application_option_name", row.get("application_option_name")); // ✅ NEW
map.put("installation_type", row.get("installation_type"));
map.put("installation_name", row.get("installation_name")); // ✅ NEW
map.put("aadhaar_no", row.get("aadhaar_no"));
map.put("survey_no", row.get("survey_no"));
map.put("place_of_erection", row.get("place_of_erection"));
map.put("fine_amount", row.get("fine_amount"));
map.put("restoration_amount", row.get("restoration_amount"));
map.put("streets", new ArrayList<>());
@ -936,6 +1329,10 @@ public class RequestService {
street.put("ward", row.get("ward"));
street.put("no_of_poles", row.get("no_of_poles"));
street.put("street_cost", row.get("street_cost"));
street.put("pole_material_name", row.get("pole_material_name")); // ✅ NEW
street.put("flag_material_name", row.get("flag_material_name")); // ✅ NEW
street.put("statue_material_type", row.get("statue_material_type")); // ✅ NEW
street.put("statue_pedestal_type", row.get("statue_pedestal_type")); // ✅ NEW
((List<Map<String, Object>>) request.get("streets")).add(street);
}

4
src/main/resources/application-dev.properties

@ -15,6 +15,10 @@ server.port=8083
spring.servlet.multipart.max-file-size=20MB
flagpoles_foldername=flagpoles_files
file.upload.directory=${user.dir}/gccoffice_uploads/
# file.upload.directory=${user.dir}/gccoffice_uploads
# file.dump.upload.directory=${user.dir}/cd_waste_docs/cdwaste_dump

5
src/main/resources/application-prod.properties

@ -13,6 +13,11 @@ server.port=8083
spring.servlet.multipart.max-file-size=20MB
flagpoles_foldername=flagpoles_files
file.upload.directory=${user.dir}/gccoffice_uploads/
#file.upload.directory.mobile=${user.dir}/gcc_mobile_service_uploads/
# file.upload.directory=${user.dir}/gccoffice_uploads
# file.dump.upload.directory=${user.dir}/cd_waste_docs/cdwaste_dump

2
src/main/resources/application.properties

@ -1,2 +1,2 @@
#spring.profiles.active=prod
spring.profiles.active=dev
spring.profiles.active=dev

BIN
src/main/resources/static/assets/images/logo.png

After

Width: 328  |  Height: 438  |  Size: 188 KiB

20
src/main/resources/templates/fragments/details.html

@ -104,6 +104,10 @@
th:text="${requestData.event_name}"></span></p>
<p><strong>Event Date:</strong> <span
th:text="${requestData.event_date}"></span></p>
<p><strong>Application Type:</strong>
<span
th:text="${requestData.application_type == 1 ? 'TEMPORARY' : 'PERMANENT'}"></span>
</p>
</div>
@ -181,6 +185,22 @@
style="background: #FB6340; font-size:18px;">Download</button>
</div>
<!-- <div class="d-flex justify-content-center mt-3">
<button type="button" id="backBtn"
class="btn btn-outline-secondary d-flex align-items-center gap-2" onclick="goBack()">
<i class="bi bi-arrow-left"></i>
Back
</button>
</div> -->
<div style="text-align:center; margin-top:20px;">
<button type="button" id="backBtn" class="btn btn-secondary" onclick="goBack()">
← Back
</button>
</div>
</div>
</div>
</div>

3
src/main/resources/templates/modules/flagpolesregistration/acknowledgement.html

@ -91,6 +91,9 @@
});
}
function goBack() {
window.location.href = '/flagpolesregistration'; // Update the URL as per your project's structure
}
function exportLicToPDF(details, requestId, format = 'a4', orientation = 'portrait') {

325
src/main/resources/templates/modules/flagpolesregistration/index.html

@ -1,123 +1,127 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GCC - FlagPoles</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Only load it once) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Popper.js (Required for Bootstrap 4) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<!-- SweetAlert JS (optional if you plan to use it) -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
/* Header Styling */
.header {
background-color: #1d495a;
padding: 10px 20px;
color: white;
font-family: Arial, sans-serif;
}
.header .logo img {
height: 60px;
}
.header .center-text {
text-align: center;
font-size: 24px;
}
.header .menu-btn {
background-color: transparent;
border: none;
font-size: 24px;
color: white;
}
.header .menu-btn:hover {
color: #ccc;
}
/* Menu Dropdown */
.menu-dropdown {
position: absolute;
top: 80px;
right: 20px;
background-color: #1d495a;
padding: 10px;
display: none;
flex-direction: column;
z-index: 1000; /* Add z-index to bring the menu above other elements */
}
.menu-dropdown a {
color: white;
margin-bottom: 5px;
text-decoration: none;
}
.menu-dropdown a:hover {
text-decoration: underline;
}
/* Mobile Specific Styling */
@media (max-width: 768px) {
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.center-text {
font-size: 18px !important;
flex-grow: 1;
text-align: center;
}
.menu-dropdown {
right: 0;
left: 0;
z-index: 1000; /* Add z-index to bring the menu above other elements */
}
}
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GCC - FlagPoles</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Only load it once) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Popper.js (Required for Bootstrap 4) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<!-- SweetAlert JS (optional if you plan to use it) -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
/* Header Styling */
.header {
background-color: #1d495a;
padding: 10px 20px;
color: white;
font-family: Arial, sans-serif;
}
.header .logo img {
height: 60px;
}
.header .center-text {
text-align: center;
font-size: 24px;
}
.header .menu-btn {
background-color: transparent;
border: none;
font-size: 24px;
color: white;
}
.header .menu-btn:hover {
color: #ccc;
}
/* Menu Dropdown */
.menu-dropdown {
position: absolute;
top: 80px;
right: 20px;
background-color: #1d495a;
padding: 10px;
display: none;
flex-direction: column;
z-index: 1000;
/* Add z-index to bring the menu above other elements */
}
.menu-dropdown a {
color: white;
margin-bottom: 5px;
text-decoration: none;
}
.menu-dropdown a:hover {
text-decoration: underline;
}
/* Mobile Specific Styling */
@media (max-width: 768px) {
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.center-text {
font-size: 18px !important;
flex-grow: 1;
text-align: center;
}
.menu-dropdown {
right: 0;
left: 0;
z-index: 1000;
/* Add z-index to bring the menu above other elements */
}
}
</style>
</head>
<body style="background-color: #ebf1fa;">
<!-- Header Start-->
<header>
<div class="header d-flex justify-content-between align-items-center">
<!-- Left: Logo -->
<div class="logo">
<img src="https://gccservices.in/gcc/assets/images/logo.png" alt="Logo">
</div>
<!-- Center: Text -->
<div class="center-text">
GREATER CHENNAI CORPORATION
</div>
<!-- Right: Button for Menu -->
<div class="menu">
<button class="menu-btn" onclick="toggleMenu()">
&#9776; <!-- Unicode for hamburger menu icon -->
</button>
</div>
</div>
<!-- Dropdown Menu -->
<div class="menu-dropdown" id="menuDropdown">
<!-- Header Start-->
<header>
<div class="header d-flex justify-content-between align-items-center">
<!-- Left: Logo -->
<div class="logo">
<img src="https://gccservices.in/gcc/assets/images/logo.png" alt="Logo">
</div>
<!-- Center: Text -->
<div class="center-text">
GREATER CHENNAI CORPORATION
</div>
<!-- Right: Button for Menu -->
<div class="menu">
<!-- <button class="menu-btn" onclick="toggleMenu()">
&#9776;
</button> -->
</div>
</div>
<!-- Dropdown Menu -->
<!-- <div class="menu-dropdown" id="menuDropdown">
<a href="https://chennaicorporation.gov.in/gcc/">Home</a>
<a href="https://chennaicorporation.gov.in/gcc/about-GCC/">About GCC</a>
<a href="https://chennaicorporation.gov.in/gcc/who-is-who/index_data.jsp">Who's Who</a>
@ -126,31 +130,33 @@
<a href="https://chennaicorporation.gov.in/gcc/department/">Departments</a>
<a href="https://chennaicorporation.gov.in/gcc/online-services/">Online Services</a>
<a href="https://gccservices.in/gcc/login">Official Login</a>
</div>
</header>
<!-- Header End-->
<main class="container mt-4">
<!-- First Card -->
<div class="card mb-4" style="border: 1px solid #1d495a;">
<div class="card-header text-center" style="border-bottom:1px solid #1d495a; ">
<h4>FlagPoles Registration</h4>
</div> -->
</header>
<!-- Header End-->
<main class="container mt-4">
<!-- First Card -->
<div class="card mb-4" style="border: 1px solid #1d495a;">
<div class="card-header text-center" style="border-bottom:1px solid #1d495a; ">
<h4>FlagPoles Registration</h4>
</div>
<div class="card-body d-flex flex-column justify-content-center align-items-center" style="width: 100%;">
<div class="d-flex justify-content-between align-items-center mb-3" style="width: 70%;">
<label for="register-btn" class="text-right" style="width: 40%;">Click Here to Register:</label>
<button type="button" class="btn btn-success" id="register-btn" onclick="goToRegister()"
style="width: 50%;">Register</button>
</div>
<div class="d-flex justify-content-between align-items-center" style="width: 70%;">
<label for="status-btn" class="text-right" style="width: 40%;">Click Here to Check Status:</label>
<button type="button" class="btn btn-primary" id="status-btn" onclick="goToStatus()"
style="width: 50%;">Status</button>
</div>
</div>
</div>
<div class="card-body d-flex flex-column justify-content-center align-items-center" style="width: 100%;">
<div class="d-flex justify-content-between align-items-center mb-3" style="width: 70%;">
<label for="register-btn" class="text-right" style="width: 40%;">Click Here to Register:</label>
<button type="button" class="btn btn-success" id="register-btn" onclick="goToRegister()" style="width: 50%;">Register</button>
</div>
<div class="d-flex justify-content-between align-items-center" style="width: 70%;">
<label for="status-btn" class="text-right" style="width: 40%;">Click Here to Check Status:</label>
<button type="button" class="btn btn-primary" id="status-btn" onclick="goToStatus()" style="width: 50%;">Status</button>
</div>
</div>
</div>
<!-- <div class="card mb-4" style="border: 1px solid #1d495a;">
<!-- <div class="card mb-4" style="border: 1px solid #1d495a;">
<div class="card-header text-center" style="border-bottom:1px solid #1d495a; ">
<h4>DEBRIS DUMPING SECONDARY COLLECTION CENTRE</h4>
</div>
@ -166,30 +172,31 @@
</div> -->
</main>
</main>
<script>
function toggleMenu() {
var dropdown = document.getElementById("menuDropdown");
if (dropdown.style.display === "flex") {
dropdown.style.display = "none";
} else {
dropdown.style.display = "flex";
<script>
function toggleMenu() {
var dropdown = document.getElementById("menuDropdown");
if (dropdown.style.display === "flex") {
dropdown.style.display = "none";
} else {
dropdown.style.display = "flex";
}
}
}
// Function to redirect to the register page
function goToRegister() {
window.location.href = '/flagpolesregistration/register'; // Change '/register' to your actual register page URL
}
// Function to redirect to the status page
function goToStatus() {
window.location.href = '/flagpolesregistration/status'; // Change '/status' to your actual status page URL
}
// Function to redirect to the register page
function goToRegister() {
window.location.href = '/flagpolesregistration/register'; // Change '/register' to your actual register page URL
}
// Function to redirect to the status page
function goToStatus() {
window.location.href = '/flagpolesregistration/status'; // Change '/status' to your actual status page URL
}
</script>
</script>
</body>
</html>
</html>

4
src/main/resources/templates/modules/flagpolesregistration/razor-pay.html

@ -29,8 +29,8 @@
console.log(response);
if (response.status == "created") {
let options = {
"key": "rzp_test_TADBzz8BXbBpos", // for development
//"key": "rzp_live_66FhxMUNAb9McO", // for production
"key": "rzp_test_tDkHFEqWXmuEi8", // for development
//"key": "rzp_live_ySI5Ns54Y7qOcJ", // for production
"amount": response.amount, // Amount is in currency subunits. Default currency is INR. Hence, 50000 refers to 50000 paise
"currency": "INR",
"name": "Greater Chennai Corporation",

2304
src/main/resources/templates/modules/flagpolesregistration/requestform.html
File diff suppressed because it is too large
View File

870
src/main/resources/templates/modules/flagpolesregistration/status.html

@ -240,6 +240,7 @@
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script>
@ -512,134 +513,6 @@
// OTP VERIFY AND VALIDATE FUNTIONS ENDS
// function searchStatus() {
// const inputValue = $("#searchInput").val().trim();
// if (!inputValue) {
// Swal.fire("Please enter Reference ID or Mobile Number");
// return;
// }
// const isMobile = /^\d{10}$/.test(inputValue);
// const params = isMobile ? { mobileNo: inputValue } : { refId: inputValue };
// $.ajax({
// url: "/flagpoles/api/searchRequestStatus",
// method: "GET",
// data: params,
// success: function (response) {
// $("#acknowledgementContainer").empty();
// if (!response.data || response.data.length === 0) {
// Swal.fire("No records found");
// return;
// }
// response.data.forEach(record => {
// const status = record.rdo_status || "PENDING";
// let statusColor = "orange";
// if (status === "APPROVED") statusColor = "green";
// if (status === "REJECTED") statusColor = "red";
// let streetHtml = "";
// record.streets.forEach(s => {
// streetHtml += `
// <li>${s.street_name} (Zone ${s.zone}, Ward ${s.ward})</li>
// `;
// });
// let paymentButton = "";
// if (record.payment_status === "PENDING") {
// paymentButton = `
// <div class="text-center mt-3">
// <button class="btn btn-success"
// onclick="proceedToPayment('${record.refid}')">
// Pay Now
// </button>
// </div>
// `;
// }
// const actionButtons = `
// <div class="text-center mt-3">
// <button class="btn btn-danger me-2"
// onclick="cancelEvent('${record.refid}', '${record.event_date}')">
// Cancel Event
// </button>
// <button class="btn btn-warning me-2"
// onclick="postponeEvent(
// '${record.refid}',
// '${record.event_date}'.replace(' ', 'T'),
// ${record.no_of_days}
// )">
// Postpone Event
// </button>
// </div>
// ${paymentButton}
// `;
// const cardHtml = `
// <div class="card mt-4" style="border:1px solid #1d495a;">
// <div class="card-header text-center">
// <h4>
// Request Details -
// <span style="color:${statusColor};">${status}</span>
// </h4>
// </div>
// <div class="card-body">
// <div class="row mb-2">
// <div class="col-md-4"><strong>Ref ID:</strong> ${record.refid}</div>
// <div class="col-md-4"><strong>Name:</strong> ${record.applicant_name}</div>
// <div class="col-md-4"><strong>Mobile:</strong> ${record.mobile_number}</div>
// </div>
// <div class="row mb-2">
// <div class="col-md-4"><strong>Event:</strong> ${record.event_name}</div>
// <div class="col-md-4"><strong>Event Date:</strong> ${new Date(record.event_date).toLocaleDateString("en-GB")}</div>
// <div class="col-md-4"><strong>No of Days:</strong> ${record.no_of_days}</div>
// </div>
// <div class="row mb-2">
// <div class="col-md-4"><strong>Total Cost:</strong> ₹${record.total_cost}</div>
// <div class="col-md-4"><strong>RDO Remarks:</strong> ${record.rdo_remarks || "-"}</div>
// <div class="col-md-4"><strong>Payment Status:</strong> ${record.payment_status || "-"}</div>
// </div>
// <div class="row mb-2">
// <div class="col-md-4"><strong>AE Status:</strong> ${record.ae_status || "-"}</div>
// <div class="col-md-4"><strong>RDO Status:</strong> ${record.rdo_status || "-"}</div>
// <div class="col-md-4"><strong>Booking Status:</strong> ${record.booking_status || "-"}</div>
// </div>
// <div class="mt-3">
// <strong>Streets:</strong>
// <ul>${streetHtml}</ul>
// </div>
// ${actionButtons}
// </div>
// </div>
// `;
// $("#acknowledgementContainer").append(cardHtml);
// });
// },
// error: function () {
// Swal.fire("Error while fetching request status");
// }
// });
// }
function searchStatus() {
const inputValue = $("#searchInput").val().trim();
@ -652,6 +525,8 @@
},
success: function (response) {
// ✅ REQUIRED for Order Copy
window.lastSearchResponse = response;
$("#acknowledgementContainer").empty();
if (!response.data || response.data.length === 0) {
@ -662,7 +537,9 @@
response.data.forEach(record => {
/* ---------- STATUS ---------- */
const status = record.rdo_status || "PENDING";
//const status = record.rdo_status || "PENDING";
const status = record.final_status || "PENDING";
let statusColor = "orange";
if (status === "APPROVED") statusColor = "green";
if (status === "REJECTED") statusColor = "red";
@ -670,7 +547,15 @@
/* ---------- STREETS ---------- */
let streetHtml = "";
record.streets.forEach(s => {
streetHtml += `<li>${s.street_name} (Zone ${s.zone}, Ward ${s.ward})</li>`;
let materialDetails = [];
if (s.pole_material_name) materialDetails.push(`Pole: ${s.pole_material_name}`);
if (s.flag_material_name) materialDetails.push(`Flag: ${s.flag_material_name}`);
if (s.statue_material_type) materialDetails.push(`Statue: ${s.statue_material_type}`);
if (s.statue_pedestal_type) materialDetails.push(`Pedestal: ${s.statue_pedestal_type}`);
const matStr = materialDetails.length > 0 ? ` | ${materialDetails.join(", ")}` : "";
streetHtml += `<li>${s.street_name} (Zone ${s.zone}, Ward ${s.ward}) - Poles: ${s.no_of_poles}${matStr}</li>`;
});
/* ---------- NORMALIZATION ---------- */
@ -680,12 +565,36 @@
const fineAmount = parseFloat(record.fine_amount || 0);
const restorationAmount = parseFloat(record.restoration_amount || 0);
const appType = record.application_type_name || "-";
const appOption = record.application_option_name || "-";
const installType = record.installation_name || "-";
const isActionDisabled =
(record.booking_status || "").toUpperCase() === "CANCELLED";
/* ---------- ACKNOWLEDGEMENT BUTTONS ---------- */
let acknowledgementButtons = "";
// if ((record.rdo_status || "").toUpperCase() === "APPROVED") {
// acknowledgementButtons += `
// <div class="text-center mt-2">
// <button class="btn btn-secondary act-btn"
// data-refid="${record.refid}">
// Download Order Copy
// </button>
// </div>`;
// }
if ((record.final_status || "").toUpperCase() === "APPROVED") {
acknowledgementButtons += `
<div class="text-center mt-2">
<button class="btn btn-secondary act-btn"
data-refid="${record.refid}">
Download Order Copy
</button>
</div>`;
}
// Booking acknowledgement
if (totalCost > 0) {
acknowledgementButtons += `
@ -723,23 +632,7 @@
}
/* ---------- ACTION BUTTONS ---------- */
let actionButtons = `
<div class="text-center mt-3">
<button class="btn btn-danger me-2"
${isActionDisabled ? "disabled" : ""}
onclick="cancelEvent('${record.refid}')">
Cancel Event
</button>
<button class="btn btn-warning me-2"
onclick="postponeEvent(
'${record.refid}',
'${record.event_date}'.replace(' ', 'T'),
${record.no_of_days}
)">
Postpone Event
</button>
</div>`;
let actionButtons = ``;
if (paymentStatus === "PENDING") {
actionButtons += `
@ -754,7 +647,50 @@
// ✅ append acknowledgement buttons AFTER declaration
actionButtons += acknowledgementButtons;
/* ---------- CARD ---------- */
/* ---------- EXTRA FIELDS (PERMANENT) ---------- */
let permanentRows = "";
if (parseInt(record.application_type || 0) === 2) {
permanentRows = `
<div class="row mb-2">
<div class="col-md-4"><strong>Survey No:</strong> ${record.survey_no || "-"}</div>
<div class="col-md-4"><strong>Place of Erection:</strong> ${record.place_of_erection || "-"}</div>
</div>
`;
}
/* ---------- CONDITIONAL ROWS ---------- */
let eventRow = "";
let costRow = "";
// Check if Permanent (2)
if (parseInt(record.application_type) === 2) {
// PERMANENT: Hide Event row, Show only Application Type in Cost row
costRow = `
<div class="row mb-2">
<div class="col-md-12"><strong>Application Type:</strong> ${appType}</div>
</div>`;
} else {
// TEMPORARY: Show Event row and full Cost/Payment row
eventRow = `
<div class="row mb-2">
<div class="col-md-4"><strong>Event:</strong> ${record.event_name || "-"}</div>
<div class="col-md-4"><strong>Event Date:</strong>
${record.event_date ? new Date(record.event_date).toLocaleDateString("en-GB") : "-"}
</div>
<div class="col-md-4"><strong>No of Days:</strong> ${record.no_of_days || "-"}</div>
</div>`;
costRow = `
<div class="row mb-2">
<div class="col-md-4"><strong>Total Cost:</strong> ₹${record.total_cost}</div>
<div class="col-md-4"><strong>Payment Status:</strong> ${record.payment_status || "-"}</div>
<div class="col-md-4"><strong>Application Type:</strong> ${appType}</div>
</div>`;
}
/* ---------- RENDER CARD ---------- */
const cardHtml = `
<div class="card mt-4" style="border:1px solid #1d495a;">
<div class="card-header text-center">
@ -772,24 +708,23 @@
<div class="col-md-4"><strong>Mobile:</strong> ${record.mobile_number}</div>
</div>
${eventRow}
${costRow}
<div class="row mb-2">
<div class="col-md-4"><strong>Event:</strong> ${record.event_name}</div>
<div class="col-md-4"><strong>Event Date:</strong>
${new Date(record.event_date).toLocaleDateString("en-GB")}
</div>
<div class="col-md-4"><strong>No of Days:</strong> ${record.no_of_days}</div>
<div class="col-md-4"><strong>Option:</strong> ${appOption}</div>
<div class="col-md-4"><strong>Installation Type:</strong> ${installType}</div>
<div class="col-md-4"><strong>Aadhaar No:</strong> ${record.aadhaar_no || "-"}</div>
</div>
<div class="row mb-2">
<div class="col-md-4"><strong>Total Cost:</strong> ₹${record.total_cost}</div>
<div class="col-md-4"><strong>RDO Remarks:</strong> ${record.rdo_remarks || "-"}</div>
<div class="col-md-4"><strong>Payment Status:</strong> ${record.payment_status || "-"}</div>
<div class="col-md-4"><strong>Status:</strong> ${record.final_status || "-"}</div>
</div>
${permanentRows}
<div class="row mb-2">
<div class="col-md-4"><strong>AE Status:</strong> ${record.ae_status || "-"}</div>
<div class="col-md-4"><strong>RDO Status:</strong> ${record.rdo_status || "-"}</div>
<div class="col-md-4"><strong>Booking Status:</strong> ${record.booking_status || "-"}</div>
<div class="col-md-12"><strong>Remarks:</strong> ${record.final_remarks || "-"}</div>
</div>
<div class="mt-3">
@ -800,7 +735,7 @@
${actionButtons}
</div>
</div>`;
</div > `;
$("#acknowledgementContainer").append(cardHtml);
});
@ -812,6 +747,337 @@
});
}
$(document).on("click", ".act-btn", function () {
//console.log("Order copy clicked", $(this).data("refid"));
generateApprovalPdf($(this).data("refid"));
});
function loadImageAsBase64(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
resolve(canvas.toDataURL("image/png"));
};
img.onerror = reject;
img.src = url;
});
}
async function generateApprovalPdf(refid) {
const record = window.lastSearchResponse.data.find(
r => String(r.refid).trim() === String(refid).trim()
);
if (!record) {
Swal.fire("Record not found");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF("p", "mm", "a4");
const pageWidth = doc.internal.pageSize.getWidth();
/* ===== SPACING CONSTANTS ===== */
const left = 15;
const rightWidth = 180;
const lineGap = 5; // normal line
const sectionGap = 8; // between sections
const paragraphGap = 4; // between paragraphs
function addParagraph(text, x, y, maxWidth, lineHeight = lineGap) {
const lines = doc.splitTextToSize(text, maxWidth);
doc.text(lines, x, y);
return y + (lines.length * lineHeight);
}
/* ---------- LOGO ---------- */
const logoBase64 = await loadImageAsBase64("/assets/images/logo.png");
doc.addImage(logoBase64, "PNG", (pageWidth - 22) / 2, 8, 22, 22);
/* ---------- DATE ---------- */
doc.setFont("times", "normal");
doc.setFontSize(10);
const approvalDateRaw = record.final_approved_date || record.rdo_updated_date;
const approvedDate = approvalDateRaw
? new Date(approvalDateRaw).toLocaleDateString("en-GB")
: "";
doc.text(`Date: ${approvedDate} `, pageWidth - left, 18, { align: "right" });
/* ---------- HEADER ---------- */
let y = 35;
doc.setFont("times", "bold");
doc.setFontSize(13);
doc.text("GREATER CHENNAI CORPORATION", pageWidth / 2, y, { align: "center" });
y += 6;
doc.setFontSize(12);
const isPermanent = parseInt(record.application_type || 0) === 2;
if (isPermanent) {
doc.text("PERMISSION FOR INSTALLATION OF STATUE / FLAGPOLE", pageWidth / 2, y, { align: "center" });
} else {
doc.text("PERMISSION FOR TEMPORARY FLAGPOLES ERECTION", pageWidth / 2, y, { align: "center" });
}
y += sectionGap;
/* ---------- BODY CONTENT ---------- */
doc.setFont("times", "normal");
doc.setFontSize(12);
if (isPermanent) {
/* ================= PERMANENT BODY ================= */
y = addParagraph(
`Permission is hereby given for the installation of Statue / Flagpole as per the details below context to the conditions mentioned.`,
left, y, rightWidth
);
y += paragraphGap;
// Permanent Location Details
doc.setFont("times", "bold");
doc.text("Location Details:", left, y);
y += lineGap;
doc.setFont("times", "normal");
const surveyNo = record.survey_no || "-";
const place = record.place_of_erection || "-";
// Construct location text
let locText = `Survey No: ${surveyNo}\nPlace of Erection: ${place}`;
// Append street details if needed, or rely on Place of erection
if (record.streets && record.streets.length > 0) {
const s = record.streets[0];
locText += `\nStreet: ${s.street_name} (Zone ${s.zone}, Ward ${s.ward})`;
}
y = addParagraph(locText, left + 3, y, rightWidth - 3);
} else {
/* ================= TEMPORARY BODY ================= */
const startDate = new Date(record.event_date);
const formatDate = d => d.toLocaleDateString("en-GB");
let eventDateText = formatDate(startDate);
if (record.no_of_days > 1) {
const endDate = new Date(startDate);
endDate.setDate(startDate.getDate() + record.no_of_days - 1);
eventDateText = `${formatDate(startDate)} to ${formatDate(endDate)} `;
}
let totalPoles = 0;
let locationText = "";
record.streets.forEach((s, i) => {
const poles = Number(s.no_of_poles || 0);
totalPoles += poles;
locationText += `${i + 1}.${s.street_name} (Zone ${s.zone}, Ward ${s.ward}) – No.of Poles: ${poles} \n`;
});
y = addParagraph(
`Permission is hereby given for the erection of ${totalPoles} number(s) of temporary flagpoles for the event from ${eventDateText} at the following location(s).`,
left, y, rightWidth
);
y += paragraphGap;
doc.setFont("times", "bold");
doc.text("Location(s):", left, y);
y += lineGap;
doc.setFont("times", "normal");
y = addParagraph(locationText.trim(), left + 3, y, rightWidth - 3);
}
y += sectionGap;
/* ---------- APPLICANT DETAILS ---------- */
doc.setFont("times", "bold");
doc.text("Applicant Details:", left, y);
y += lineGap;
doc.setFont("times", "normal");
let details = [];
if (isPermanent) {
const appOption = record.application_option_name || "-";
const installType = record.installation_name || "-";
details = [
`Applicant Name: ${record.applicant_name} `,
`Application ID: ${record.refid} `,
`Mobile Number: ${record.mobile_number} `,
`Address: ${record.applicant_address} `,
`Request Option: ${appOption} `,
`Installation Type: ${installType} `
];
} else {
details = [
`Applicant Name: ${record.applicant_name} `,
`Application ID: ${record.refid} `,
`Mobile Number: ${record.mobile_number} `,
`Address: ${record.applicant_address} `,
`Event Type: ${record.event_name} `,
`Amount Paid(Rs.) : ${Number(record.total_cost).toLocaleString("en-IN")} `
];
}
details.forEach(d => {
doc.text(d, left, y);
y += lineGap;
});
y += sectionGap;
/* ---------- TERMS & CONDITIONS ---------- */
doc.setFont("times", "bold");
doc.text("Terms & Conditions:", left, y);
y += lineGap;
doc.setFont("times", "normal");
doc.setFontSize(11); // Slightly smaller for terms
if (isPermanent) {
// SECTION 1: STATUES
if (y > 270) { doc.addPage(); y = 20; }
doc.setFont("times", "bold");
doc.text("1. Procedure For Installation of New Statues In Private Land:-", left, y);
y += lineGap;
doc.setFont("times", "normal");
const statueConditions = [
"1. No statues shall be permitted on public roads, pavements, sidewalks, or other public utility places.",
"2. Encroachments along water bodies in any form of statues, flagpoles, or other structures shall not be allowed.",
"3. No statues shall be erected on Panchayat Union Roads, Panchayat Union Tank Bunds, or in public places in rural areas.",
"4. The statues/flagpoles, etc., should be erected only at unobjectionable locations in private lands.",
"5. There is no ban on installing new statues in private lands. However, the proposals in a complete shape has to be routed through Collectors for approval of the Government.",
"6. Statues shall be preferably made of bronze metal.",
"7. The safety of all new statues including the upkeep and maintenance cost shall be borne by those who installed it.",
"8. In sensitive law and order prone areas, in order to avoid damages by miscreants, the new statue may be covered by fiberglass enclosure / non destructible cover.",
"9. In wooded areas (with many trees), forests and lands classified as social forest shall be strictly avoided for the Installation of statues.",
"10. The Government may fix the minimum distance that shall be adhered to when there is an another statue is situated nearby.",
"11. Closed-Circuit Television (CCTV) Coverage should be available round the clock in sensitive areas; and it has to be ensured by local Police with the support of sponsors of the statue."
];
statueConditions.forEach(c => {
if (y > 270) { doc.addPage(); y = 20; }
y = addParagraph(c, left, y, rightWidth);
y += 2;
});
y += sectionGap;
// SECTION 2: FLAGPOLES
if (y > 270) { doc.addPage(); y = 20; }
doc.setFont("times", "bold");
doc.text("2. Procedure for Installation of New Flagpoles in Private Land:-", left, y);
y += lineGap;
doc.setFont("times", "normal");
const flagpoleConditions = [
"1. No Permission shall be granted for erection of permanent flagpoles within the Right of Way (ROW) of the any road maintained by Tamil Nadu State Highways Department.",
"2. No permission shall be granted for the erection of new flagpoles in or on water bodies, supply channels, surplus course, surplus weir, water spread area of reservoirs, tanks, tank bunds and sluices and water course set back lands as of Water Resources Department.",
"3. The Flagpole shall be installed at the cost of the sponsor/requisitioning body.",
"4. The political parties and other organizations are permitted to erect their permanent flagpoles in their own land after obtaining necessary permission from the authority concerned. (District level Committee / State Government).",
"5. Material strength, height, location, safe digging, secured foundation have to be ensured to avoid damage to property and life and prevent damage to underground and over ground infrastructure while erecting flagpoles.",
"6. In wooded areas (with many trees), forests and lands classified as social forest shall be strictly avoided for the Installation of flagpoles.",
"7. In case, if the Flagpole is installed in a residential area, it shall be of maximum 15 feet tall.",
"8. Wall-mounted flag pole shall be fixed vertically.",
"9. Aluminium flagpoles are preferred for their strength and resistance to corrosion.",
"10. Sectional flagpoles are suggested as they are convenient and easy to assemble.",
"11. A Stability Certificate must be obtained from Public Works Department (PWD) authorities.",
"12. Responsibility for regular maintenance and monitoring the safety of the flagpoles shall be the responsibility of the owners / installers."
];
flagpoleConditions.forEach(c => {
if (y > 270) { doc.addPage(); y = 20; }
y = addParagraph(c, left, y, rightWidth);
y += 2;
});
y += sectionGap;
// SECTION 3: REPLACEMENT / SHIFTING
if (y > 270) { doc.addPage(); y = 20; }
doc.setFont("times", "bold");
doc.text("3. Procedure for Replacement / Shifting of existing statues and flagpoles:-", left, y);
y += lineGap;
doc.setFont("times", "normal");
const shiftingConditions = [
"1. If the statue is to be shifted due to construction of flyover or laying or widening of roads, the cost of shifting the existing statue shall be included in the Project Cost.",
"2. In any case as per s.c orders, H.c orders statues , Flagpoles, memorials etc.. cannot be relocated in a public place.",
"3. DLC can accord permission if the condition (for old) remains the same & also there is no local objection.",
"4. If there is any change in feature/ height/ relocation is proposed then government permission is required (only in patta lands).",
"5. To Prevent damage to the existing statue, if the concerned person/organization consider that they should be kept in safe custody & installed later, they can do so after obtaining the orders from the Government.",
"6. In sensitive areas prone to law-and-order, already installed statue may be covered by fiberglass enclosures to non-destructible cover in order to avoid damages by miscreants. The cost of such protection shall be borne by the person or organization that installed the statue."
];
shiftingConditions.forEach(c => {
if (y > 270) { doc.addPage(); y = 20; }
y = addParagraph(c, left, y, rightWidth);
y += 2;
});
} else {
// TEMPORARY CONDITIONS (Existing)
let conditions = [
"1. The applicant shall comply with all applicable laws, rules, guidelines, and safety norms relating to pole erection.",
"2. Applicants are advised to retain the application ID for future reference.",
"3. Temporary flagpoles shall be allowed for a period not exceeding three days (before / on / after the event).",
"4. In case of religious events,maximum period of 7 days may be allowed for installing flagpoles",
"5. Temporary flagpoles shall not be erected on bituminous road surfaces.",
"6. Flagpoles may be erected only on earthen surfaces and not within three meters of the bituminous surface.",
"7. No flagpoles shall be erected on medians, footpaths, drains, bridges, or road furniture within the ROW.",
"8. Maximum height of the flagpole shall be 3.50 m above ground level with a minimum depth of 1.00 m below ground.",
"9. Flagpoles shall not interfere with electric lines and shall be properly insulated.",
"10. The applicant shall be fully responsible for any accidents or damages caused.",
"11. Any damage to public infrastructure shall be restored at the applicant’s cost.",
"12. Flagpoles shall be removed immediately after the permission period at the applicant’s expense.",
"13. If the flagpole is not removed within the stipulatedtime, the poles will be removed by the authorities and the cost shall be borne by the applicant.",
"14. The fee amount once paid will not be refunded on any account."
];
conditions.forEach(c => {
// Check page break
if (y > 270) {
doc.addPage();
y = 20;
}
y = addParagraph(c, left, y, rightWidth);
y += 2;
});
}
y += sectionGap;
/* ---------- FOOTER ---------- */
if (y > 270) {
doc.addPage();
y = 20;
}
doc.text("Authorized Signatory", 145, y);
doc.save(`OrderCopy_${refid}.pdf`);
}
// $(document).on("click", ".ack-btn", function () {
@ -885,179 +1151,177 @@
// });
// }
function cancelEvent(refId, eventDate) {
Swal.fire({
title: "Confirm Cancellation",
text: "Are you sure you want to cancel this event?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Yes, Cancel"
}).then(result => {
if (!result.isConfirmed) return;
// 🔹 STEP 1: Cancel event
$.post("/flagpolesregistration/api/cancelEvent", { refId }, function (res) {
// function cancelEvent(refId, eventDate) {
if (res.status === "CANCELLED") {
// Swal.fire({
// title: "Confirm Cancellation",
// text: "Are you sure you want to cancel this event?",
// icon: "warning",
// showCancelButton: true,
// confirmButtonText: "Yes, Cancel"
// }).then(result => {
Swal.fire("Event Cancelled", "Initiating refund...", "success");
// if (!result.isConfirmed) return;
// 🔹 STEP 2: Initiate refund (ONLY ONCE)
initiateRefund(refId);
// // 🔹 STEP 1: Cancel event
// $.post("/flagpolesregistration/api/cancelEvent", { refId }, function (res) {
} else if (res.status === "NOT_ALLOWED") {
// if (res.status === "CANCELLED") {
Swal.fire(
"Cancellation Not Allowed",
"Cancellation allowed only before 24 hours of event",
"warning"
);
// Swal.fire("Event Cancelled", "Initiating refund...", "success");
} else {
Swal.fire("Error", "Unable to cancel event", "error");
}
// // 🔹 STEP 2: Initiate refund (ONLY ONCE)
// initiateRefund(refId);
}).fail(() => {
Swal.fire("Error", "Server error while cancelling", "error");
});
});
}
// } else if (res.status === "NOT_ALLOWED") {
function initiateRefund(refId) {
// Swal.fire(
// "Cancellation Not Allowed",
// "Cancellation allowed only before 24 hours of event",
// "warning"
// );
$.post("/flagpolesregistration/book/api/initiateRefund", {
refId: refId,
reason: "Event cancelled by user"
}, function (res) {
//console.log(res);
// } else {
// Swal.fire("Error", "Unable to cancel event", "error");
// }
if (res.status === "REFUND_INITIATED") {
// }).fail(() => {
// Swal.fire("Error", "Server error while cancelling", "error");
// });
// });
// }
Swal.fire(
"Refund Initiated",
"Refund ID: " + res.refund_id,
"success"
);
// function initiateRefund(refId) {
searchStatus(); // refresh table
// $.post("/flagpolesregistration/book/api/initiateRefund", {
// refId: refId,
// reason: "Event cancelled by user"
// }, function (res) {
// //console.log(res);
// if (res.status === "REFUND_INITIATED") {
} else {
Swal.fire("Refund Failed", res, "error");
}
// Swal.fire(
// "Refund Initiated",
// "Refund ID: " + res.refund_id,
// "success"
// );
}).fail(err => {
Swal.fire("Refund Error", err.responseText, "error");
});
}
// searchStatus(); // refresh table
// } else {
// Swal.fire("Refund Failed", res, "error");
// }
// }).fail(err => {
// Swal.fire("Refund Error", err.responseText, "error");
// });
// }
function postponeEvent(refId, eventDateStr, noOfDays) {
// ✅ FIX DATE FORMAT
const safeDateStr = eventDateStr.replace(' ', 'T');
const eventTime = new Date(safeDateStr);
// function postponeEvent(refId, eventDateStr, noOfDays) {
if (isNaN(eventTime.getTime())) {
Swal.fire("Invalid event date. Please contact support.");
return;
}
// // ✅ FIX DATE FORMAT
// const safeDateStr = eventDateStr.replace(' ', 'T');
// const eventTime = new Date(safeDateStr);
const now = new Date();
// if (isNaN(eventTime.getTime())) {
// Swal.fire("Invalid event date. Please contact support.");
// return;
// }
// ⛔ 24-hour rule
if ((eventTime - now) / (1000 * 60 * 60) < 24) {
Swal.fire("Postpone not allowed within 24 hours of event");
return;
}
// const now = new Date();
// 🔥 Calculate old event end date
const minSelectableDate = new Date(eventTime);
minSelectableDate.setDate(
minSelectableDate.getDate() + parseInt(noOfDays)
);
minSelectableDate.setHours(0, 0, 0, 0);
// // ⛔ 24-hour rule
// if ((eventTime - now) / (1000 * 60 * 60) < 24) {
// Swal.fire("Postpone not allowed within 24 hours of event");
// return;
// }
const minDateStr = minSelectableDate.toISOString().split("T")[0];
// // 🔥 Calculate old event end date
// const minSelectableDate = new Date(eventTime);
// minSelectableDate.setDate(
// minSelectableDate.getDate() + parseInt(noOfDays)
// );
// minSelectableDate.setHours(0, 0, 0, 0);
Swal.fire({
title: "Select New Event Date",
input: "date",
inputAttributes: {
min: minDateStr
},
html: `<small class="text-muted">
You can select a date from ${minSelectableDate.toLocaleDateString("en-GB")}
</small>`,
showCancelButton: true,
confirmButtonText: "Postpone"
}).then(result => {
// const minDateStr = minSelectableDate.toISOString().split("T")[0];
if (!result.value) return;
// Swal.fire({
// title: "Select New Event Date",
// input: "date",
// inputAttributes: {
// min: minDateStr
// },
// html: `<small class="text-muted">
// You can select a date from ${minSelectableDate.toLocaleDateString("en-GB")}
// </small>`,
// showCancelButton: true,
// confirmButtonText: "Postpone"
// }).then(result => {
const selectedDate = new Date(result.value + "T00:00:00");
// if (!result.value) return;
if (selectedDate < minSelectableDate) {
Swal.fire("Please select a valid future date");
return;
}
// const selectedDate = new Date(result.value + "T00:00:00");
$.post("/flagpolesregistration/api/postponeEvent", {
refId: refId,
newDate: result.value
}, res => {
if (res.status === "POSTPONE_ALREADY_USED") {
Swal.fire(
"Postpone Not Allowed",
"You can postpone an event only once.",
"warning"
);
}
else if (res.status === "NOT_ALLOWED") {
Swal.fire("Postpone not allowed within 24 hours");
}
else if (res.status === "STREET_NOT_AVAILABLE") {
Swal.fire(
"Street Already Booked",
"The selected street/location is already booked for the chosen dates.",
"error"
);
}
else if (res.status === "POSTPONED") {
Swal.fire("Event postponed successfully", "", "success");
searchStatus();
}
});
// if (selectedDate < minSelectableDate) {
// Swal.fire("Please select a valid future date");
// return;
// }
/* ---------------- ACKNOWLEDGEMENT ---------------- */
function openAcknowledgement(refId) {
window.open(
`/flagpolesregistration/paymentrequestform?refId=${refId}`,
"_blank"
);
}
// $.post("/flagpolesregistration/api/postponeEvent", {
// refId: refId,
// newDate: result.value
// }, res => {
// if (res.status === "POSTPONE_ALREADY_USED") {
// Swal.fire(
// "Postpone Not Allowed",
// "You can postpone an event only once.",
// "warning"
// );
// }
// else if (res.status === "NOT_ALLOWED") {
// Swal.fire("Postpone not allowed within 24 hours");
// }
// else if (res.status === "STREET_NOT_AVAILABLE") {
// Swal.fire(
// "Street Already Booked",
// "The selected street/location is already booked for the chosen dates.",
// "error"
// );
// }
// else if (res.status === "POSTPONED") {
// Swal.fire("Event postponed successfully", "", "success");
// searchStatus();
// }
// });
// /* ---------------- ACKNOWLEDGEMENT ---------------- */
// function openAcknowledgement(refId) {
// window.open(
// `/flagpolesregistration/paymentrequestform?refId=${refId}`,
// "_blank"
// );
// }
// $.post("/flagpoles/api/postponeEvent", {
// refId: refId,
// newDate: result.value
// }, res => {
// if (res.status === "NOT_ALLOWED") {
// Swal.fire("Postpone not allowed within 24 hours");
// }
// else if (res.status === "STREET_NOT_AVAILABLE") {
// Swal.fire("Street already booked for selected dates");
// }
// else if (res.status === "POSTPONED") {
// Swal.fire("Event postponed successfully", "", "success");
// searchStatus();
// }
// });
});
}
// // $.post("/flagpoles/api/postponeEvent", {
// // refId: refId,
// // newDate: result.value
// // }, res => {
// // if (res.status === "NOT_ALLOWED") {
// // Swal.fire("Postpone not allowed within 24 hours");
// // }
// // else if (res.status === "STREET_NOT_AVAILABLE") {
// // Swal.fire("Street already booked for selected dates");
// // }
// // else if (res.status === "POSTPONED") {
// // Swal.fire("Event postponed successfully", "", "success");
// // searchStatus();
// // }
// // });
// });
// }

Loading…
Cancel
Save