Browse Source

green committee report added

main
kanimozhi 8 months ago
parent
commit
c1bf33d74f
  1. 51
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/controller/Maincontroller.java
  2. 119
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/controller/ReportApicontroller.java
  3. 603
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/ReportService.java
  4. 53
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/vtrack/controller/VehicleApiController.java
  5. 23
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/vtrack/service/VehicleService.java
  6. 906
      gcc_officer_portal/src/main/resources/templates/modules/greencommittee/dashboard.html

51
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/controller/Maincontroller.java

@ -15,7 +15,7 @@ import in.gov.chennaicorporation.gccoffice.service.LoginUserInfo;
public class Maincontroller {
@Autowired
private LoginUserInfo loginUserInfo;
private LoginUserInfo loginUserInfo;
@Autowired
private PendinglistService pendinglistService;
@ -24,36 +24,20 @@ public class Maincontroller {
private DashboardService dashboardService;
@GetMapping("/dashboard")
public String viewdashboard(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
public String viewdashboard(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
int app_count=dashboardService.getApplicationsCount();
model.addAttribute("app_count", app_count);
int dgc_count=dashboardService.getDGCcompletedCount();
model.addAttribute("dgc_count", dgc_count);
int inspec_count=app_count-dgc_count;
model.addAttribute("inspec_count", inspec_count);
int cc_count=dashboardService.getCommitteeCompleted();
int cp_count=dgc_count-cc_count;
model.addAttribute("cp_count", cp_count);
return "modules/greencommittee/dashboard";
}
@GetMapping("/createmeeting")
public String viewcreatemeeting(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
public String viewcreatemeeting(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
@ -62,10 +46,9 @@ public class Maincontroller {
}
@GetMapping("/pendinglist")
public String viewpendinglist(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
public String viewpendinglist(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
@ -74,10 +57,9 @@ public class Maincontroller {
}
@GetMapping("/monitoring")
public String viewmonitoring(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
public String viewmonitoring(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
@ -86,10 +68,9 @@ public class Maincontroller {
}
@GetMapping("/reports")
public String viewreports(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
public String viewreports(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);

119
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/controller/ReportApicontroller.java

@ -2,6 +2,7 @@ package in.gov.chennaicorporation.gccoffice.greencommittee.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -21,28 +22,112 @@ public class ReportApicontroller {
private ReportService reportService;
@GetMapping("/getgreencommitteelist")
public List<Map<String, Object>> getgreencommitteelist(@RequestParam String meetingid,
@RequestParam String zones) {
public List<Map<String, Object>> getgreencommitteelist(@RequestParam String meetingid,
@RequestParam String zones) {
List<String> refnums = reportService.getrefnums(meetingid, zones);
System.out.println("refnums="+refnums);
List<String> refnums = reportService.getrefnums(meetingid, zones);
System.out.println("refnums=" + refnums);
List<Map<String, Object>> finalList = new ArrayList<>();
List<Map<String, Object>> finalList = new ArrayList<>();
if (refnums.isEmpty()) {
return Collections.emptyList();
}
if (refnums.isEmpty()) {
return Collections.emptyList();
}
for (String ref : refnums) {
System.out.println("ref=" + ref);
Map<String, Object> data = reportService.getlistdata(ref);
if (data != null && !data.isEmpty()) {
finalList.add(data);
}
}
for (String ref : refnums) {
System.out.println("ref="+ref);
Map<String, Object> data = reportService.getlistdata(ref);
if (data != null && !data.isEmpty()) {
finalList.add(data);
}
}
return finalList;
}
return finalList;
}
@GetMapping("/getabscount")
public Map<String, Object> getabscount(@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
Map<String, Object> response = new HashMap<>();
try {
List<Map<String, Object>> data = reportService.getabscount(startDate, endDate);
response.put("data", data);
response.put("message", "Zone-wise abstract report");
response.put("status", "Success");
} catch (Exception e) {
e.printStackTrace();
response.put("data", Collections.emptyList());
response.put("message", "Failed to fetch abstract report");
response.put("status", "Error");
}
return response;
}
@GetMapping("/getWardDetailsByZone")
public Map<String, Object> getWardDetailsByZone(@RequestParam(required = true) String zone,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
Map<String, Object> response = new HashMap<>();
try {
List<Map<String, Object>> data = reportService.getWardDetailsByZone(zone, startDate, endDate);
response.put("data", data);
response.put("message", "Ward-wise abstract report");
response.put("status", "Success");
} catch (Exception e) {
e.printStackTrace();
response.put("data", Collections.emptyList());
response.put("message", "Failed to fetch abstract report");
response.put("status", "Error");
}
return response;
}
@GetMapping("/getPendingDetails")
public Map<String, Object> getPendingDetails(
@RequestParam String zone,
@RequestParam(required = false) String ward,
@RequestParam String type,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
Map<String, Object> response = new HashMap<>();
try {
List<String> refIds = reportService.getPendingRefIds(zone, ward, type, startDate, endDate);
List<Map<String, Object>> dataList = new ArrayList<>();
for (String refId : refIds) {
Map<String, Object> fullData = reportService.getfulldetailsdata(refId);
if (fullData != null && !fullData.isEmpty()) {
dataList.add((Map<String, Object>) fullData.get("data"));
}
}
response.put("data", dataList);
response.put("message", "Complaint List");
response.put("status", "Success");
} catch (Exception e) {
e.printStackTrace();
response.put("data", Collections.emptyList());
response.put("message", "Failed to fetch complaints");
response.put("status", "Error");
}
return response;
}
}

603
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/ReportService.java

@ -2,13 +2,16 @@ package in.gov.chennaicorporation.gccoffice.greencommittee.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@ -18,6 +21,8 @@ public class ReportService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Value("${fileBaseUrl}")
private String fileBaseUrl;
@Autowired
public void setDataSource(@Qualifier("mysqlGreenCommitteeDataSource") DataSource dataSource) {
@ -25,184 +30,492 @@ public class ReportService {
}
public List<String> getrefnums(String meetingid, String zones) {
try {
StringBuilder sql = new StringBuilder(
" SELECT DISTINCT ref_id FROM ( " +
" SELECT cd.ref_id " +
" FROM committee_data cd " +
" LEFT JOIN reg_details rd ON rd.ref_id = cd.ref_id " +
" WHERE cd.isactive = 1 " +
" UNION " +
" SELECT ri.ref_id " +
" FROM reinspection ri " +
" INNER JOIN ( " +
" SELECT ref_id, MAX(cdate) AS max_cdate " +
" FROM reinspection " +
" WHERE isactive = 1 " +
" GROUP BY ref_id " +
" ) latest " +
" ON latest.ref_id = ri.ref_id " +
" AND latest.max_cdate = ri.cdate " +
" LEFT JOIN reg_details rd2 ON rd2.ref_id = ri.ref_id " +
" WHERE ri.isactive = 1 " +
" ) t WHERE 1=1 "
);
List<Object> params = new ArrayList<>();
/* Meeting filter */
if (meetingid != null && !meetingid.isEmpty()) {
sql.append(
" AND ref_id IN ( " +
" SELECT ref_id FROM committee_data WHERE meeting_id = ? " +
" UNION " +
" SELECT ref_id FROM reinspection WHERE meeting_id = ? " +
" ) "
);
params.add(meetingid);
params.add(meetingid);
}
/* Zone filter */
if (zones != null && !zones.isEmpty()) {
sql.append(
" AND ref_id IN ( " +
" SELECT ref_id FROM reg_details WHERE zone = ? " +
" ) "
);
params.add(zones);
}
return jdbcTemplate.queryForList(
sql.toString(),
params.toArray(),
String.class
);
} catch (Exception e) {
System.err.println("Error in getrefnums(): " + e.getMessage());
e.printStackTrace();
return Collections.emptyList();
}
try {
StringBuilder sql = new StringBuilder(
" SELECT DISTINCT ref_id FROM ( " +
" SELECT cd.ref_id " +
" FROM committee_data cd " +
" LEFT JOIN reg_details rd ON rd.ref_id = cd.ref_id " +
" WHERE cd.isactive = 1 " +
" UNION " +
" SELECT ri.ref_id " +
" FROM reinspection ri " +
" INNER JOIN ( " +
" SELECT ref_id, MAX(cdate) AS max_cdate " +
" FROM reinspection " +
" WHERE isactive = 1 " +
" GROUP BY ref_id " +
" ) latest " +
" ON latest.ref_id = ri.ref_id " +
" AND latest.max_cdate = ri.cdate " +
" LEFT JOIN reg_details rd2 ON rd2.ref_id = ri.ref_id " +
" WHERE ri.isactive = 1 " +
" ) t WHERE 1=1 ");
List<Object> params = new ArrayList<>();
/* Meeting filter */
if (meetingid != null && !meetingid.isEmpty()) {
sql.append(
" AND ref_id IN ( " +
" SELECT ref_id FROM committee_data WHERE meeting_id = ? " +
" UNION " +
" SELECT ref_id FROM reinspection WHERE meeting_id = ? " +
" ) ");
params.add(meetingid);
params.add(meetingid);
}
/* Zone filter */
if (zones != null && !zones.isEmpty()) {
sql.append(
" AND ref_id IN ( " +
" SELECT ref_id FROM reg_details WHERE zone = ? " +
" ) ");
params.add(zones);
}
return jdbcTemplate.queryForList(
sql.toString(),
params.toArray(),
String.class);
} catch (Exception e) {
System.err.println("Error in getrefnums(): " + e.getMessage());
e.printStackTrace();
return Collections.emptyList();
}
}
public Map<String, Object> getlistdata(String ref) {
Map<String, Object> regDetails = getRegDetails(ref);
Map<String, Object> regDetails = getRegDetails(ref);
List<Map<String, Object>> compDetails = getComplaintDetails(ref);
List<Map<String, Object>> compDetails = getComplaintDetails(ref);
regDetails.put("comp_details", compDetails);
regDetails.put("comp_details", compDetails);
List<Map<String, Object>> inspectionList = new ArrayList<>();
List<Map<String, Object>> inspectionList = new ArrayList<>();
String sql = "SELECT id.*, um.name AS inspector_name, " +
" DATE_FORMAT(id.cdate, '%d-%m-%Y %l:%i %p') AS f_Cdate " +
"FROM inspection_data id " +
"LEFT JOIN user_maping um ON um.userid = id.cby " +
"INNER JOIN ( " +
" SELECT inspection_by, MAX(cdate) AS latest_date " +
" FROM inspection_data " +
" WHERE ref_id = ? AND isactive = 1 " +
" GROUP BY inspection_by " +
") latest ON id.inspection_by = latest.inspection_by " +
" AND id.cdate = latest.latest_date " +
"WHERE id.ref_id = ? AND id.isactive = 1 " +
"ORDER BY FIELD(id.inspection_by, 'GCC', 'NGO', 'TNFD')";
String sql =
"SELECT id.*, um.name AS inspector_name, " +
" DATE_FORMAT(id.cdate, '%d-%m-%Y %l:%i %p') AS f_Cdate " +
"FROM inspection_data id " +
"LEFT JOIN user_maping um ON um.userid = id.cby " +
"INNER JOIN ( " +
" SELECT inspection_by, MAX(cdate) AS latest_date " +
" FROM inspection_data " +
" WHERE ref_id = ? AND isactive = 1 " +
" GROUP BY inspection_by " +
") latest ON id.inspection_by = latest.inspection_by " +
" AND id.cdate = latest.latest_date " +
"WHERE id.ref_id = ? AND id.isactive = 1 " +
"ORDER BY FIELD(id.inspection_by, 'GCC', 'NGO', 'TNFD')";
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
sql, ref, ref);
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
sql, ref, ref
);
for (Map<String, Object> row : rows) {
Integer inspId = (Integer) row.get("inspection_data_id");
for (Map<String, Object> row : rows) {
// 4a — Recommendation details
List<Map<String, Object>> recommend = jdbcTemplate.queryForList(
"SELECT rm.name, itd.nooftrees AS count " +
"FROM inspection_tree_data itd " +
"JOIN inspection_recommend_master rm ON rm.rid = itd.action " +
"WHERE itd.inspection_data_id=? AND itd.isactive=1",
inspId);
Integer inspId = (Integer) row.get("inspection_data_id");
row.put("recommendations", recommend);
// 4a — Recommendation details
List<Map<String, Object>> recommend = jdbcTemplate.queryForList(
"SELECT rm.name, itd.nooftrees AS count " +
"FROM inspection_tree_data itd " +
"JOIN inspection_recommend_master rm ON rm.rid = itd.action " +
"WHERE itd.inspection_data_id=? AND itd.isactive=1",
inspId
);
inspectionList.add(row);
}
row.put("recommendations", recommend);
regDetails.put("inspections", inspectionList);
inspectionList.add(row);
}
String reSql = "SELECT r.id AS reins_id, r.committee_action, r.remarks AS reins_remarks, " +
" DATE_FORMAT(r.cdate, '%d-%m-%Y %l:%i %p') AS reins_date, " +
" cm.event_name, DATE_FORMAT(cm.event_date, '%d-%m-%Y') AS event_date, crm.name as ins_name " +
"FROM reinspection r " +
"LEFT JOIN create_meeting cm ON cm.id = r.meeting_id " +
" LEFT JOIN committee_recommend_master crm ON crm.id=r.committee_action " +
"WHERE r.ref_id = ? AND r.isactive = 1 " +
"ORDER BY r.id DESC";
regDetails.put("inspections", inspectionList);
List<Map<String, Object>> reinspectionList = jdbcTemplate.queryForList(reSql, ref);
regDetails.put("reinspections", reinspectionList);
String reSql =
"SELECT r.id AS reins_id, r.committee_action, r.remarks AS reins_remarks, " +
" DATE_FORMAT(r.cdate, '%d-%m-%Y %l:%i %p') AS reins_date, " +
" cm.event_name, DATE_FORMAT(cm.event_date, '%d-%m-%Y') AS event_date, crm.name as ins_name " +
"FROM reinspection r " +
"LEFT JOIN create_meeting cm ON cm.id = r.meeting_id " +
" LEFT JOIN committee_recommend_master crm ON crm.id=r.committee_action " +
"WHERE r.ref_id = ? AND r.isactive = 1 " +
"ORDER BY r.id DESC";
Map<String, Object> c1 = null;
List<Map<String, Object>> reinspectionList = jdbcTemplate.queryForList(reSql, ref);
List<Map<String, Object>> committeeList = jdbcTemplate.queryForList(
"SELECT cd.*, DATE_FORMAT(cd.cdate, '%d-%m-%Y %l:%i %p') AS c_Cdate, " +
"cm.event_name AS meeting_name, cm.event_date AS meeting_date " +
"FROM committee_data cd " +
"LEFT JOIN create_meeting cm ON cm.id = cd.meeting_id " +
"WHERE cd.ref_id = ? AND cd.isactive = 1",
ref);
regDetails.put("reinspections", reinspectionList);
if (!committeeList.isEmpty()) {
c1 = committeeList.get(0);
Map<String, Object> c1 = null;
List<Map<String, Object>> com_complaints = jdbcTemplate.queryForList(
"SELECT crm.name AS nature, SUM(ctd.nooftrees) AS count " +
"FROM committee_tree_data ctd " +
"JOIN committee_recommend_master crm ON crm.id = ctd.committee_action " +
"WHERE ctd.ref_id = ? " +
"GROUP BY crm.name",
ref);
List<Map<String, Object>> committeeList = jdbcTemplate.queryForList(
"SELECT cd.*, DATE_FORMAT(cd.cdate, '%d-%m-%Y %l:%i %p') AS c_Cdate, " +
"cm.event_name AS meeting_name, cm.event_date AS meeting_date " +
"FROM committee_data cd " +
"LEFT JOIN create_meeting cm ON cm.id = cd.meeting_id " +
"WHERE cd.ref_id = ? AND cd.isactive = 1",
ref
);
c1.put("com_complaints", com_complaints);
}
if (!committeeList.isEmpty()) {
c1 = committeeList.get(0);
// IMPORTANT: always put committee key (even if null)
regDetails.put("committee", c1);
List<Map<String, Object>> com_complaints = jdbcTemplate.queryForList(
"SELECT crm.name AS nature, SUM(ctd.nooftrees) AS count " +
"FROM committee_tree_data ctd " +
"JOIN committee_recommend_master crm ON crm.id = ctd.committee_action " +
"WHERE ctd.ref_id = ? " +
"GROUP BY crm.name",
ref
);
return regDetails;
}
c1.put("com_complaints", com_complaints);
}
public Map<String, Object> getRegDetails(String ref) {
String sql = "SELECT * FROM reg_details WHERE is_active = 1 AND ref_id = ?";
return jdbcTemplate.queryForMap(sql, ref);
}
// IMPORTANT: always put committee key (even if null)
regDetails.put("committee", c1);
public List<Map<String, Object>> getComplaintDetails(String ref) {
String sql = "SELECT cn.name AS nature, SUM(cd.no_of_trees) AS total_trees " +
"FROM complaint_details cd " +
"JOIN comp_nature cn ON cn.id = cd.comp_nature_id " +
"WHERE cd.is_active = 1 AND cd.ref_id = ? " +
"GROUP BY cn.name";
return regDetails;
return jdbcTemplate.queryForList(sql, ref);
}
public Map<String, Object> getRegDetails(String ref) {
String sql = "SELECT * FROM reg_details WHERE is_active = 1 AND ref_id = ?";
return jdbcTemplate.queryForMap(sql, ref);
public List<Map<String, Object>> getabscount(String startDate, String endDate) {
String baseSql = "SELECT " +
" zm.zone_name, " +
" COALESCE(COUNT(DISTINCT rd.ref_id), 0) AS total_requests, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='NGO' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id=id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS ngo_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='GCC' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id=id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS gcc_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='TNFD' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id=id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS tnfd_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND ( " +
" SELECT COUNT(DISTINCT inspection_by) " +
" FROM inspection_data id " +
" WHERE id.ref_id = rd.ref_id AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id=id.reinspection_id) ) " +
" ) = 3 " +
" THEN 1 ELSE 0 END), 0) AS committee_pending, " +
" COALESCE(SUM(CASE WHEN rd.is_withdraw = 1 THEN 1 ELSE 0 END), 0) AS withdrawn, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" THEN 1 ELSE 0 END), 0) AS completed " +
"FROM zone_master zm " +
"LEFT JOIN reg_details rd " +
" ON rd.zone = zm.zone_name " +
" AND rd.is_active = 1 ";
StringBuilder sql = new StringBuilder(baseSql);
List<Object> params = new ArrayList<>();
if (startDate != null && !startDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) >= ? ");
params.add(startDate);
}
if (endDate != null && !endDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) <= ? ");
params.add(endDate);
}
sql.append(
" WHERE zm.is_active = 1 " +
" AND zm.is_delete = 0 " +
" GROUP BY zm.zone_name " +
" ORDER BY zm.zone_name ");
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
}
public List<Map<String, Object>> getComplaintDetails(String ref) {
public List<Map<String, Object>> getWardDetailsByZone(
String zone,
String startDate,
String endDate) {
String baseSql = "SELECT " +
" wm.zone_id, " +
" wm.ward_name, " +
" COALESCE(COUNT(DISTINCT rd.ref_id), 0) AS total_requests, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='NGO' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS ngo_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='GCC' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS gcc_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='TNFD' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
" ) " +
" THEN 1 ELSE 0 END), 0) AS tnfd_pending, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IS NOT NULL " +
" AND rd.is_withdraw = 0 " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
" AND ( " +
" SELECT COUNT(DISTINCT inspection_by) " +
" FROM inspection_data id " +
" WHERE id.ref_id = rd.ref_id AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
" ) = 3 " +
" THEN 1 ELSE 0 END), 0) AS committee_pending, " +
" COALESCE(SUM(CASE WHEN rd.is_withdraw=1 THEN 1 ELSE 0 END), 0) AS withdrawn, " +
" COALESCE(SUM(CASE " +
" WHEN rd.ref_id IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
" THEN 1 ELSE 0 END), 0) AS completed " +
"FROM ward_master wm " +
"JOIN zone_master zm ON zm.id = wm.zone_id AND zm.zone_name = ? " +
"LEFT JOIN reg_details rd " +
" ON rd.ward = wm.ward_name " +
" AND rd.is_active = 1 ";
StringBuilder sql = new StringBuilder(baseSql);
List<Object> params = new ArrayList<>();
params.add(zone);
if (startDate != null && !startDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) >= ? ");
params.add(startDate);
}
if (endDate != null && !endDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) <= ? ");
params.add(endDate);
}
sql.append(
" WHERE wm.is_active=1 AND wm.is_delete=0 " +
" GROUP BY wm.zone_id, wm.ward_name " +
" ORDER BY wm.ward_name ");
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
}
String sql = "SELECT cn.name AS nature, SUM(cd.no_of_trees) AS total_trees " +
"FROM complaint_details cd " +
"JOIN comp_nature cn ON cn.id = cd.comp_nature_id " +
"WHERE cd.is_active = 1 AND cd.ref_id = ? " +
"GROUP BY cn.name";
public List<String> getPendingRefIds(
String zone,
String ward,
String type,
String startDate,
String endDate) {
String baseSql;
switch (type.toUpperCase()) {
case "NGO":
baseSql = "SELECT rd.ref_id FROM reg_details rd " +
"WHERE rd.zone=? " +
"AND rd.is_active=1 AND rd.is_withdraw=0 " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
"AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='NGO' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
")";
break;
case "GCC":
baseSql = "SELECT rd.ref_id FROM reg_details rd " +
"WHERE rd.zone=? " +
"AND rd.is_active=1 AND rd.is_withdraw=0 " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
"AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='GCC' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
")";
break;
case "TNFD":
baseSql = "SELECT rd.ref_id FROM reg_details rd " +
"WHERE rd.zone=? " +
"AND rd.is_active=1 AND rd.is_withdraw=0 " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM committee_data WHERE isactive=1) " +
"AND rd.ref_id NOT IN (SELECT ref_id FROM reinspection WHERE isactive=1) " +
"AND rd.ref_id NOT IN ( " +
" SELECT id.ref_id FROM inspection_data id " +
" WHERE id.inspection_by='TNFD' AND id.isactive=1 " +
" AND ( (rd.reinspection_id IS NULL AND id.reinspection_id IS NULL) " +
" OR (rd.reinspection_id = id.reinspection_id) ) " +
")";
break;
case "WITHDRAW":
baseSql = "SELECT rd.ref_id FROM reg_details rd " +
"WHERE rd.zone=? AND rd.is_withdraw=1";
break;
default:
return Collections.emptyList();
}
StringBuilder sql = new StringBuilder(baseSql);
List<Object> params = new ArrayList<>();
params.add(zone);
if (ward != null && !ward.isEmpty()) {
sql.append(" AND rd.ward = ? ");
params.add(ward);
}
if (startDate != null && !startDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) >= ? ");
params.add(startDate);
}
if (endDate != null && !endDate.isEmpty()) {
sql.append(" AND DATE(rd.cdate) <= ? ");
params.add(endDate);
}
return jdbcTemplate.query(
sql.toString(),
params.toArray(),
(rs, rowNum) -> rs.getString("ref_id"));
}
return jdbcTemplate.queryForList(sql, ref);
public Map<String, Object> getfulldetailsdata(String refId) {
Map<String, Object> response = new HashMap<>();
// 1 — Application details
Map<String, Object> app = jdbcTemplate.queryForMap(
"SELECT *,DATE_FORMAT(cdate, '%d-%m-%Y %l:%i %p') as r_Cdate,IFNULL(reinspection_id, '') AS com_reinspection_id FROM reg_details WHERE ref_id=? AND is_active=1",
refId);
// 2 — Complaint details (grouped)
List<Map<String, Object>> complaints = jdbcTemplate.queryForList(
"SELECT cn.name AS nature, SUM(cd.no_of_trees) AS count " +
"FROM complaint_details cd JOIN comp_nature cn ON cn.id=cd.comp_nature_id " +
"WHERE cd.ref_id=? GROUP BY cn.name",
refId);
String compDetails = complaints.stream()
.map(c -> c.get("nature") + "-" + c.get("count"))
.collect(Collectors.joining(","));
// 3 — Complaint images
List<Map<String, Object>> imagePaths = jdbcTemplate.queryForList(
"SELECT img_path FROM img_uploads WHERE ref_id=? AND is_active=1",
new Object[] { refId }).stream()
.map(row -> {
Map<String, Object> img = new HashMap<>();
img.put(
"img_path",
fileBaseUrl + "/gccofficialapp/files" + row.get("img_path").toString());
return img;
})
.collect(Collectors.toList());
app.put("complaints", complaints);
app.put("comp_details", compDetails);
app.put("image_paths", imagePaths);
response.put("data", app);
return response;
}
}

53
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/vtrack/controller/VehicleApiController.java

@ -23,10 +23,10 @@ import in.gov.chennaicorporation.gccoffice.vtrack.service.VehicleService;
@RestController
@RequestMapping("/gcc/api/vtrack")
public class VehicleApiController {
@Autowired
public VehicleService vehicleService;
@Autowired
public VehicleService vehicleService;
@GetMapping("/getTemplateDetails")
@GetMapping("/getTemplateDetails")
public ResponseEntity<List<Map<String, Object>>> getTemplateDetails() {
try {
List<Map<String, Object>> templateNames = vehicleService.getAllTemplateNames();
@ -42,51 +42,50 @@ public class VehicleApiController {
}
}
@PostMapping("/saveMessageDetails")
@PostMapping("/saveMessageDetails")
public String saveMessageDetails(@RequestParam("date") String date, @RequestParam("image") MultipartFile image,
@RequestParam("templateType") String tempType) throws IOException {
@RequestParam("templateType") String tempType) throws IOException {
String img_path = vehicleService.fileUpload("vtrack",tempType,image);
String img_path = vehicleService.fileUpload("vtrack", tempType, image);
int result = vehicleService.saveMessageDetails(date, tempType, img_path);
int result = vehicleService.saveMessageDetails(date, tempType, img_path);
if(result>0){
return "success";
}
return "Failed";
if (result > 0) {
return "success";
}
return "Failed";
}
@GetMapping({"/sendmessage"})
public String sendmessage(
@RequestParam(value = "msgid", required = true) String msgid,
@RequestParam(value = "datetxt", required = false) String datetxt,
@RequestParam(value = "fileurl", required = false) String fileurl
) {
@GetMapping({ "/sendmessage" })
public String sendmessage(
@RequestParam(value = "msgid", required = true) String msgid,
@RequestParam(value = "datetxt", required = false) String datetxt,
@RequestParam(value = "fileurl", required = false) String fileurl) {
String LoginUserId = LoginUserInfo.getLoginUserId();
String LoginUserId = LoginUserInfo.getLoginUserId();
return vehicleService.sendMessage(msgid, datetxt, fileurl);
}
return vehicleService.sendMessage(msgid, datetxt, fileurl);
}
@PostMapping("/disablemessage")
public String disablemessage(@RequestParam(value="msgId", required = true) String msgid){
@PostMapping("/disablemessage")
public String disablemessage(@RequestParam(value = "msgId", required = true) String msgid) {
String status = vehicleService.disablemessage(msgid);
if(status.equals("success")){
if (status.equals("success")) {
return "success";
} else{
} else {
return "Failed to update";
}
}
@PostMapping("/enablemessage")
public String enablemessage(@RequestParam(value="msgId", required = true) String msgid){
public String enablemessage(@RequestParam(value = "msgId", required = true) String msgid) {
String status = vehicleService.enableMessage(msgid);
if(status.equals("success")){
if (status.equals("success")) {
return "success";
} else{
} else {
return "Failed to update";
}
}

23
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/vtrack/service/VehicleService.java

@ -670,6 +670,29 @@ public class VehicleService {
break;
case "23":
System.out.println("TempID is 22 (1590940 - Green Committee Report - IMAGE - STATIC)");
urlString = "https://media.smsgupshup.com/GatewayAPI/rest?"
+ "userid=" + username
+ "&password=" + password
+ "&send_to=" + sendTo
+ "&v=1.1&format=json"
+ "&msg_type=IMAGE"
+ "&method=SENDMEDIAMESSAGE"
+ "&caption=%2AGCC+Enforcement+Team+Monitoring%2A%0A%0AToday%27s+%28" + msgDate
+ "%29+Zone+wise+Enforcement+Team+activity+details+shared+above+for+your+reference.%0A%0AFor+more+details%2C+please+click+the+link+below."
+ "&media_url=" + fileURL
+ "&isTemplate=true&footer=GCC+-+IT+Cell";
urlString = "https://sendapiv1.pinbot.ai/pinwa/sendMessage?type=template"
+ "&apikey=" + apikey
+ "&from=" + from
+ "&to={{to}}&templateid=2784943"
+ "&url=" + fileURL
+ "&placeholders=Green%20Committee%20Report%20Details";
break;
default:
System.out.println("TempID (" + tempid + ") is unknown");
}

906
gcc_officer_portal/src/main/resources/templates/modules/greencommittee/dashboard.html

@ -1,39 +1,52 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.card-box {
box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
}
.card{
margin-bottom: 0px !important;
}
.card-title-fixed {
min-height: 48px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
/* Thumbnail styling */
.complaint-thumb {
width: 110px;
height: 110px;
object-fit: cover;
margin: 5px;
cursor: pointer;
transition: transform 0.2s ease-in-out, box-shadow 0.2s;
}
.complaint-thumb:hover {
transform: scale(1.05);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
/* Image grid alignment */
.image-grid {
gap: 8px;
}
#pendingModal .modal-body {
min-height: 60vh;
max-height: 70vh;
overflow-y: auto;
}
</style>
<body>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header mb-2">
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header mb-2">
<div class="row align-items-end">
<div class="col-lg-8">
<div class="page-header-title">
@ -47,8 +60,8 @@
<div class="col-lg-4">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/gcc/index"><i
class="ik ik-home"></i></a></li>
<li class="breadcrumb-item"><a href="/gcc/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">Green Committee</li>
<li class="breadcrumb-item active" aria-current="page">Dashboard</li>
</ol>
@ -58,94 +71,789 @@
</div>
<br>
<div class="row mt-2" style="row-gap:10px;">
<div class="col-xl-3 col-md-6 col-sm-12">
<div class="card card-box p-3 text-center h-100">
<div class="card-title-fixed">
<h6 class="text-facebook mb-2">
<b>Application Received</b>
</h6>
</div>
<div class="row mt-1">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-sm-4">
<label for="startDate" style="font-size: medium;">From Date:</label>
<input type="date" id="startDate" class="form-control"
onclick="this.showPicker()">
</div>
<div class="col-sm-4">
<label for="endDate" style="font-size: medium;">To Date:</label>
<input type="date" id="endDate" class="form-control"
onclick="this.showPicker()">
</div>
<h4 class="text-twitter fw-700 mt-3" th:text="${app_count}"></h4>
</div>
</div>
<div class="col-xl-3 col-md-6 col-sm-12">
<div class="card card-box p-3 text-center h-100">
</div>
<div class="row mt-4">
<div class="col-12 d-flex justify-content-center">
<button onclick="loadZoneReport()"
class="btn btn-primary mx-2">Search</button>
<button class="btn btn-danger mx-2" id="resetBtn" name="reset"
type="reset">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card-title-fixed">
<h6 class="text-facebook mb-2">
<b>DGC Member Inspection Completed</b>
</h6>
</div>
<h4 class="text-twitter fw-700 mt-3" th:text="${dgc_count}"></h4>
</div>
</div>
<div class="row mt-1">
<div class="col-xl-3 col-md-6 col-sm-12">
<div class="card card-box p-3 text-center h-100">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="page-header-title">
<h5 style="margin: 0;font-weight: bold;">Zone-wise Abstract Data</h5>
<hr>
</div>
<table id="ZoneDatatable"
class="table table-striped table-bordered table-hover dataTable" role="grid">
<thead class="thead-dark">
<tr role="row">
<th rowspan="2" class="text-center">Zones</th>
<th rowspan="2" class="text-center">Total Request</th>
<th colspan="3" class="text-center">Inspection</th>
<th rowspan="2" class="text-center">Committee Pending</th>
<th rowspan="2" class="text-center">Withdraw</th>
<th rowspan="2" class="text-center">Completed</th>
</tr>
<tr>
<th class="text-center">NGO Pending</th>
<th class="text-center">GCC Pending</th>
<th class="text-center">TNFD Pending</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr class="font-weight-bold bg-light">
<th class="text-center">TOTAL</th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<div class="card-title-fixed">
<h6 class="text-facebook mb-2">
<b>Inspection Pending</b>
</h6>
</div>
<h4 class="text-twitter fw-700 mt-3" th:text="${inspec_count}"></h4>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 col-sm-12">
<div class="card card-box p-3 text-center h-100">
<div class="card-title-fixed">
<h6 class="text-facebook mb-2">
<b>Committee Decision Pending</b>
</h6>
</div>
<h4 class="text-twitter fw-700 mt-3" th:text="${cp_count}"></h4>
</div>
</div>
<div class="modal fade" id="zoneDetailsModal" tabindex="-1" aria-labelledby="zoneDetailsLabel"
aria-hidden="true" data-bs-keyboard="false" data-bs-backdrop="static">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="zoneModalTitle">Zone Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<table id="WardDatatable" class="table table-striped table-bordered display nowrap w-100">
<thead class="thead-dark">
<tr role="row">
<th rowspan="2" class="text-center">Zones</th>
<th rowspan="2" class="text-center">Total Request</th>
<th colspan="3" class="text-center">Inspection</th>
<th rowspan="2" class="text-center">Committee Pending</th>
<th rowspan="2" class="text-center">Withdraw</th>
<th rowspan="2" class="text-center">Completed</th>
</tr>
<tr>
<th class="text-center">NGO Pending</th>
<th class="text-center">GCC Pending</th>
<th class="text-center">TNFD Pending</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr class="font-weight-bold bg-light">
<th class="text-center">TOTAL</th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<div id="pageLoader" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
<div class="modal fade" id="pendingModal" tabindex="-1" aria-labelledby="DetailsLabel" aria-hidden="true"
data-bs-keyboard="false" data-bs-backdrop="static">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 id="pendingModalTitle"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="pendingModalBody"></div>
</div>
</div>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
<div class="modal fade" id="imagePreviewModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-body text-center p-2">
<img id="previewImage" src="" class="img-fluid rounded">
</div>
</div>
</div>
</div>
<script type="text/javascript">
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
<script type="text/javascript">
let CURRENT_ZONE = null;
function openImagePreview(src) {
$('#previewImage').attr('src', src);
$('#imagePreviewModal').modal('show');
}
$(document).ready(function () {
var table = $('#ZoneDatatable').DataTable({
dom: 'Bfrtip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
scrollY: '80vh',
scrollX: true,
buttons: [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary',
id: 'copyBtn'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary',
id: 'excelBtn'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary',
id: 'csvBtn'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary',
id: 'pdfBtn'
}
],
fixedHeader: false,
autoWidth: false,
responsive: false,
searching: false,
select: false,
processing: false
});
// Set today's date as max
const today = new Date().toISOString().split('T')[0];
$('#startDate, #endDate').attr('max', today);
// When start date changes → set min for end date
$('#startDate').on('change', function () {
const startDate = $(this).val();
$('#endDate').attr('min', startDate);
// If endDate already selected but invalid → clear it
if ($('#endDate').val() && $('#endDate').val() < startDate) {
$('#endDate').val('');
}
});
// When end date changes → validate against start date
$('#endDate').on('change', function () {
const startDate = $('#startDate').val();
const endDate = $(this).val();
if (startDate && endDate < startDate) {
Swal.fire({
icon: 'warning',
title: 'Invalid Date Range',
text: 'End date cannot be before start date'
});
$(this).val('');
}
});
loadZoneReport();
$('#zoneDetailsModal').on('shown.bs.modal', function () {
if ($.fn.DataTable.isDataTable('#WardDatatable')) {
let questionDatatable = $('#WardDatatable').DataTable();
questionDatatable.columns.adjust().draw();
}
});
});
function openZoneModal(zoneCode) {
CURRENT_ZONE = zoneCode;
//console.log("Opening modal for zone:", zoneCode);
const startDate = $('#startDate').val(); // yyyy-mm-dd or ""
const endDate = $('#endDate').val();
$('#pageLoader').show();
// Set data in modal (example)
$('#zoneModalTitle').text('Zone ' + zoneCode + ' Details');
$.ajax({
url: '/gcc/api/greencommittee/report/getWardDetailsByZone',
method: 'GET',
data: {
zone: zoneCode,
startDate: startDate,
endDate: endDate
},
success: function (response) {
var res = Array.isArray(response) ? response[0] : response;
//console.log("Response:", res);
$('#pageLoader').hide();
if (res.status === "Success") {
if (Array.isArray(res.data) && res.data.length > 0) {
// console.log("Details Array:", response);
let table = $('#WardDatatable').DataTable({
destroy: true,
autoWidth: true,
info: true,
data: res.data, // using response directly
columns: [
{ data: 'ward_name', className: 'text-center' },
{ data: 'total_requests', className: 'text-center' },
{
data: 'ngo_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'NGO', 'WARD')
},
{
data: 'gcc_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'GCC', 'WARD')
},
{
data: 'tnfd_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'TNFD', 'WARD')
},
{
data: 'committee_pending',
className: 'text-center'
},
{
data: 'withdrawn',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'WITHDRAW', 'WARD')
},
{ data: 'completed', className: 'text-center' }
],
footerCallback: footerSumCallback,
dom: 'Bfrtip',
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
buttons: [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary',
id: 'copyBtn'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary',
id: 'excelBtn'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary',
id: 'csvBtn'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary',
id: 'pdfBtn'
}
],
scrollY: '400px',
scrollX: true,
responsive: false,
searching: false,
ordering: false
});
$('#zoneDetailsModal').modal('show');
}
else if (Array.isArray(res.data) && res.data.length === 0) {
$('#pageLoader').hide();
//alert("No data available.");
Swal.fire({
icon: 'info',
title: 'No Data',
text: 'No data available.',
showConfirmButton: true,
timer: 3000
});
}
else {
$('#pageLoader').hide();
//alert("Error: " + response.message);
Swal.fire({
icon: 'error',
title: 'Error',
text: res.message,
showConfirmButton: true,
timer: 3000
});
}
}
else {
$('#pageLoader').hide();
//alert("Error: " + response.message);
Swal.fire({
icon: 'error',
title: 'Error',
text: res.message,
showConfirmButton: true,
timer: 3000
});
}
},
error: function (xhr, status, error) {
$('#pageLoader').hide();
//alert("Request failed: " + error);
Swal.fire({
icon: 'error',
title: 'Error',
text: error,
showConfirmButton: true,
timer: 3000
});
}
});
}
document.getElementById('resetBtn').addEventListener('click', function () {
event.preventDefault();
location.reload();
});
function loadZoneReport() {
const startDate = $('#startDate').val();
const endDate = $('#endDate').val();
$('#pageLoader').show();
$.ajax({
url: '/gcc/api/greencommittee/report/getabscount',
method: 'GET',
data: {
startDate: startDate,
endDate: endDate
},
success: function (response) {
// Safely extract data whether it's an array or an object
var res = Array.isArray(response) ? response[0] : response;
//console.log("Response:", res);
$('#pageLoader').hide();
if (res.status === "Success") {
if (Array.isArray(res.data) && res.data.length > 0) {
//console.log("Details Array:", response);
let table = $('#ZoneDatatable').DataTable({
destroy: true,
info: true,
paging: true,
data: res.data, // using response directly
columns: [
{
data: 'zone_name',
className: 'text-center',
render: d => `<a href="javascript:void(0)" onclick="openZoneModal('${d}')" class="text-primary">${d}</a>`
},
{ data: 'total_requests', className: 'text-center' },
{
data: 'ngo_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'NGO', 'ZONE')
},
{
data: 'gcc_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'GCC', 'ZONE')
},
{
data: 'tnfd_pending',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'TNFD', 'ZONE')
},
{
data: 'committee_pending',
className: 'text-center'
},
{
data: 'withdrawn',
className: 'text-center',
render: (d, t, r) => renderPendingCell(d, r, 'WITHDRAW', 'ZONE')
},
{ data: 'completed', className: 'text-center' }
],
dom: 'Bfrtip',
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
buttons: [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary',
id: 'copyBtn'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary',
id: 'excelBtn'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary',
id: 'csvBtn'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary',
id: 'pdfBtn'
}
],
footerCallback: footerSumCallback,
scrollY: 'auto',
scrollX: true,
fixedHeader: false,
autoWidth: false,
responsive: false,
searching: false,
select: false,
processing: false
});
}
else if (Array.isArray(res.data) && res.data.length === 0) {
$('#pageLoader').hide();
//alert("No data available.");
Swal.fire({
icon: 'info',
title: 'No Data',
text: 'No data available.',
showConfirmButton: true,
timer: 3000
});
}
else {
$('#pageLoader').hide();
//alert("Error: " + response.message);
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Error',
showConfirmButton: true,
timer: 3000
});
}
}
else {
$('#pageLoader').hide();
//alert("Error: " + response.message);
Swal.fire({
icon: 'error',
title: 'Error',
text: res.message,
showConfirmButton: true,
timer: 3000
});
}
},
error: function (xhr, status, error) {
$('#pageLoader').hide();
// alert("Request failed: " + error);
Swal.fire({
icon: 'error',
title: 'Error',
text: error,
showConfirmButton: true,
timer: 3000
});
}
});
}
function footerSumCallback(row, data) {
let api = this.api();
const sum = idx =>
api.column(idx).data()
.reduce((a, b) => Number(a) + Number(b || 0), 0);
for (let i = 1; i <= 7; i++) {
$(api.column(i).footer()).html(sum(i));
}
}
function openPendingModal(zone, ward, type, startDate, endDate, level) {
//console.log("data="+zone+","+ward+","+startDate+","+endDate);
$('#pendingModal').modal('show');
$('#pendingModalTitle').text(
`${type} Pending - Zone ${zone}${ward ? ', Ward ' + ward : ''}`
);
$('#pageLoader').show();
$.ajax({
url: '/gcc/api/greencommittee/report/getPendingDetails',
method: 'GET',
data: {
zone: zone,
ward: ward || null,
type: type,
startDate: startDate || null,
endDate: endDate || null
},
success: function (res) {
$('#pageLoader').hide();
if (res.status === 'Success' && res.data.length > 0) {
renderComplaintCards(res.data);
} else {
$('#pendingModalBody').html(
`<p class="text-center text-muted">No complaints found</p>`
);
}
},
error: function () {
$('#pageLoader').hide();
Swal.fire('Error', 'Failed to load details', 'error');
}
});
}
function renderComplaintCards(data) {
let html = '';
data.forEach(item => {
// ✅ Name fallback logic
const displayName =
item.p_name && item.p_name.trim() !== ''
? item.p_name
: [item.dept_name, item.designation].filter(Boolean).join(' - ') || '-';
html += `
<div class="card mb-3 shadow-sm">
<div class="card-header text-white font-weight-bold" style="background-color:#404e67">
${item.ref_id} — ${item.r_Cdate}
</div>
<div class="card-body">
<div class="row align-items-start">
<!-- LEFT -->
<div class="col-md-8">
<p><strong>Name:</strong> ${displayName}</p>
<p><strong>Mobile:</strong> ${item.ph_no}</p>
<p>
<strong>Zone:</strong> ${item.zone}
<span class="mx-3">|</span>
<strong>Ward:</strong> ${item.ward}
<span class="mx-3">|</span>
<strong>Total Trees:</strong> ${item.total_trees}
</p>
<p><strong>Address:</strong> ${item.address}</p>
<p><strong>Remarks:</strong> ${item.remarks}</p>
<p><strong>Complaints:</strong> ${item.comp_details}</p>
</div>
<!-- RIGHT (Images) -->
<div class="col-md-4">
<div class="d-flex flex-wrap image-grid">
${item.image_paths.map(img => `
<img
src="${img.img_path}"
class="img-thumbnail complaint-thumb"
onclick="openImagePreview('${img.img_path}')"
>
`).join('')}
</div>
</div>
</div>
</div>
</div>`;
});
$('#pendingModalBody').html(html);
}
function renderPendingCell(value, row, type, level) {
if (!value || value === 0) {
return `<span class="text-muted">${value}</span>`;
}
const zone = row.zone_name || CURRENT_ZONE;
const ward = row.ward_name || '';
const startDate = $('#startDate').val() || '';
const endDate = $('#endDate').val() || '';
return `
<a href="javascript:void(0)"
class="text-primary font-weight-bold"
onclick="openPendingModal(
'${zone}',
'${ward}',
'${type}',
'${startDate}',
'${endDate}',
'${level}'
)">
${value}
</a>`;
}
</script>
</body>
</script>
</body>
</html>
Loading…
Cancel
Save