12 changed files with 4575 additions and 149 deletions
-
19src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java
-
160src/main/java/com/gcc/commissionerreview/controller/DbfotApiController.java
-
10src/main/java/com/gcc/commissionerreview/controller/MainController.java
-
17src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java
-
832src/main/java/com/gcc/commissionerreview/service/DbfotService.java
-
42src/main/java/com/gcc/commissionerreview/service/RoadWarService.java
-
150src/main/java/com/gcc/commissionerreview/service/StreetVendorService.java
-
4src/main/resources/application.properties
-
1311src/main/resources/templates/modules/dbfot/CompDetails.html
-
2023src/main/resources/templates/modules/dbfot/locDetails.html
-
68src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html
-
40src/main/resources/templates/modules/streetvendor/overalldetails.html
@ -0,0 +1,160 @@ |
|||
package com.gcc.commissionerreview.controller; |
|||
|
|||
import java.util.Collections; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import com.gcc.commissionerreview.service.DbfotService; |
|||
|
|||
@RestController |
|||
@RequestMapping("/commissionerreview/api/dbfot") |
|||
public class DbfotApiController { |
|||
|
|||
@Autowired |
|||
private DbfotService dbfotService; |
|||
|
|||
|
|||
|
|||
|
|||
@GetMapping("/getzones") |
|||
public Map<String, Object> ViewZoneDropdown() { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
List<Map<String, Object>> zones = dbfotService.ViewZoneDropdown(); |
|||
|
|||
if (!zones.isEmpty()) { |
|||
response.put("status", true); |
|||
response.put("message", "Zone list fetched successfully"); |
|||
response.put("data", zones); |
|||
} else { |
|||
response.put("status", false); |
|||
response.put("message", "No zones found"); |
|||
response.put("data", Collections.emptyList()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@GetMapping("/getwardbyzone") |
|||
public Map<String, Object> ViewWardDropdown(@RequestParam String zone) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
List<Map<String, Object>> wards = dbfotService.ViewWardDropdown(zone); |
|||
|
|||
if (!wards.isEmpty()) { |
|||
response.put("status", true); |
|||
response.put("message", "Ward list fetched successfully"); |
|||
response.put("data", wards); |
|||
} else { |
|||
response.put("status", false); |
|||
response.put("message", "No wards found"); |
|||
response.put("data", Collections.emptyList()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@GetMapping("/getpctstatus") |
|||
public Map<String, Object> ViewPctStatusDropdown() { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
List<Map<String, Object>> status = dbfotService.ViewPctStatusDropdown(); |
|||
|
|||
if (!status.isEmpty()) { |
|||
response.put("status", true); |
|||
response.put("message", "Pct Status fetched successfully"); |
|||
response.put("data", status); |
|||
} else { |
|||
response.put("status", false); |
|||
response.put("message", "No Pct Status found"); |
|||
response.put("data", Collections.emptyList()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
// location overview |
|||
|
|||
@GetMapping("/getdashboardsummary") |
|||
public Map<String, Object> getDashboardSummary(@RequestParam(required = false) String date, |
|||
@RequestParam(required = false) String zone, @RequestParam(required = false) String ward, |
|||
@RequestParam(required = false) String status, @RequestParam(required = false) String searchAddress) { |
|||
|
|||
return dbfotService.getDashboardSummary(date, zone, ward, status, searchAddress); |
|||
} |
|||
|
|||
|
|||
@GetMapping("/getpctcomplaints") |
|||
public Map<String, Object> getPctComplaints(@RequestParam String pct, @RequestParam(required = false) String date, |
|||
@RequestParam(required = false) String zone, @RequestParam(required = false) String ward, |
|||
@RequestParam(required = false) String status, @RequestParam(required = false) String searchAddress, |
|||
@RequestParam(required = false, defaultValue = "ALL") String complaintStatus) { |
|||
|
|||
return dbfotService.getPctComplaints(pct, date, zone, ward, status, searchAddress, complaintStatus); |
|||
} |
|||
|
|||
@GetMapping("/getcomplainttimeline") |
|||
public Map<String, Object> getComplaintTimeline( |
|||
@RequestParam("complaint_id") String complaintId) { |
|||
|
|||
return dbfotService.getComplaintTimeline(complaintId); |
|||
} |
|||
|
|||
@GetMapping("/getmanpowerdetails") |
|||
public Map<String, Object> getManpowerDetails(@RequestParam("pct") String pct, |
|||
@RequestParam(required = false) String date, @RequestParam(required = false) String zone, |
|||
@RequestParam(required = false) String ward, @RequestParam(required = false) String status, |
|||
@RequestParam(required = false) String searchAddress) { |
|||
|
|||
return dbfotService.getManpowerDetails(pct, date, zone, ward, status, searchAddress); |
|||
} |
|||
|
|||
// complaints overview |
|||
|
|||
@GetMapping("/getlocationsbyward") |
|||
public Map<String, Object> ViewLocationDropdown(@RequestParam String ward) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
List<Map<String, Object>> wards = dbfotService.ViewLocationDropdown(ward); |
|||
|
|||
if (!wards.isEmpty()) { |
|||
response.put("status", true); |
|||
response.put("message", "Location list fetched successfully"); |
|||
response.put("data", wards); |
|||
} else { |
|||
response.put("status", false); |
|||
response.put("message", "No Location found"); |
|||
response.put("data", Collections.emptyList()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@GetMapping("/getcomplaintsoverview") |
|||
public Map<String, Object> getComplaintsOverview(@RequestParam String date, |
|||
@RequestParam(required = false) String zone, @RequestParam(required = false) String ward, |
|||
@RequestParam(required = false) String location, @RequestParam(required = false) String status, |
|||
@RequestParam(required = false) String source, @RequestParam(required = false) String searchAddress) { |
|||
|
|||
if (date == null || date.trim().isEmpty()) { |
|||
Map<String, Object> response = new HashMap<>(); |
|||
response.put("status", "Failed"); |
|||
response.put("message", "Date is mandatory"); |
|||
return response; |
|||
} |
|||
|
|||
return dbfotService.getComplaintsOverview(date, zone, ward, location, status, source, searchAddress); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,832 @@ |
|||
package com.gcc.commissionerreview.service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
import javax.sql.DataSource; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Qualifier; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.core.env.Environment; |
|||
import org.springframework.jdbc.core.JdbcTemplate; |
|||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; |
|||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
@Service |
|||
public class DbfotService { |
|||
|
|||
@Autowired |
|||
@Value("${fileBaseUrl}") |
|||
|
|||
private String fileBaseUrl; |
|||
@Autowired |
|||
private JdbcTemplate jdbcTemplate; |
|||
|
|||
@Autowired |
|||
private Environment environment; |
|||
|
|||
|
|||
|
|||
@Autowired |
|||
public void setDataSource(@Qualifier("mysqlDBFOT_TOILETSDataSource") DataSource DataSource) { |
|||
this.jdbcTemplate = new JdbcTemplate(DataSource); |
|||
|
|||
} |
|||
|
|||
public DbfotService(Environment environment) { |
|||
|
|||
this.environment = environment; |
|||
|
|||
this.fileBaseUrl = environment.getProperty("fileBaseUrl"); |
|||
} |
|||
|
|||
public List<Map<String, Object>> ViewZoneDropdown() { |
|||
String sql = "SELECT DISTINCT(zone) " |
|||
+ "FROM pct_master " |
|||
+ "WHERE isactive=1 AND isdelete=0 ORDER BY zone"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql); |
|||
} catch (Exception e) { |
|||
// TODO: handle exception |
|||
e.printStackTrace(); |
|||
return Collections.emptyList(); |
|||
} |
|||
} |
|||
|
|||
public List<Map<String, Object>> ViewWardDropdown(String zone) { |
|||
String sql = "SELECT DISTINCT(ward) " |
|||
+ "FROM pct_master " |
|||
+ "WHERE isactive=1 AND isdelete=0 AND zone=? ORDER BY ward"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql,zone); |
|||
} catch (Exception e) { |
|||
// TODO: handle exception |
|||
e.printStackTrace(); |
|||
return Collections.emptyList(); |
|||
} |
|||
} |
|||
|
|||
public List<Map<String, Object>> ViewPctStatusDropdown() { |
|||
String sql = "SELECT DISTINCT(status) " |
|||
+ "FROM pct_master " |
|||
+ "WHERE isactive=1 AND isdelete=0 ORDER BY status"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql); |
|||
} catch (Exception e) { |
|||
// TODO: handle exception |
|||
e.printStackTrace(); |
|||
return Collections.emptyList(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public Map<String, Object> getDashboardSummary(String date, String zone, String ward, String status, |
|||
String searchAddress) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
try { |
|||
|
|||
// Default date to today |
|||
String selectedDate = (date == null || date.trim().isEmpty()) ? java.time.LocalDate.now().toString() |
|||
: date.trim(); |
|||
|
|||
// ========================================== |
|||
// 1. OVERALL COUNTS - NO FILTERS |
|||
// ========================================== |
|||
|
|||
String totalLocationsSql = "SELECT COUNT(*) FROM pct_master " + "WHERE isactive = 1 AND isdelete = 0"; |
|||
|
|||
Integer totalLocations = jdbcTemplate.queryForObject(totalLocationsSql, Integer.class); |
|||
|
|||
String activeLocationsSql = "SELECT COUNT(*) FROM pct_master " + "WHERE UPPER(TRIM(status)) = 'ACTIVE' " |
|||
+ "AND isactive = 1 AND isdelete = 0"; |
|||
|
|||
Integer totalActiveLocations = jdbcTemplate.queryForObject(activeLocationsSql, Integer.class); |
|||
|
|||
String totalComplaintsSql = "SELECT COUNT(*) FROM complaints_details " |
|||
+ "WHERE isactive = 1 AND isdelete = 0"; |
|||
|
|||
Integer totalComplaints = jdbcTemplate.queryForObject(totalComplaintsSql, Integer.class); |
|||
|
|||
// ========================================== |
|||
// 2. BUILD FILTERS AND PARAMETERS |
|||
// ========================================== |
|||
|
|||
StringBuilder filters = new StringBuilder(); |
|||
List<Object> filterParams = new ArrayList<>(); |
|||
|
|||
if (zone != null && !zone.trim().isEmpty() && !"ALL".equalsIgnoreCase(zone.trim())) { |
|||
|
|||
filters.append(" AND pm.zone = ? "); |
|||
filterParams.add(zone.trim()); |
|||
} |
|||
|
|||
if (ward != null && !ward.trim().isEmpty() && !"ALL".equalsIgnoreCase(ward.trim())) { |
|||
|
|||
filters.append(" AND pm.ward = ? "); |
|||
filterParams.add(ward.trim()); |
|||
} |
|||
|
|||
if (status != null && !status.trim().isEmpty() && !"ALL".equalsIgnoreCase(status.trim())) { |
|||
|
|||
filters.append(" AND UPPER(TRIM(pm.status)) = ? "); |
|||
|
|||
filterParams.add(status.trim().toUpperCase()); |
|||
} |
|||
|
|||
if (searchAddress != null && !searchAddress.trim().isEmpty()) { |
|||
|
|||
filters.append(" AND pm.address LIKE ? "); |
|||
|
|||
filterParams.add("%" + searchAddress.trim() + "%"); |
|||
} |
|||
|
|||
// ========================================== |
|||
// 3. LOCATION TABLE |
|||
// ========================================== |
|||
|
|||
String locationsSql = "SELECT " + " pm.id, " + " pm.pct, " + " pm.zone, " + " pm.ward, " + " pm.address, " |
|||
+ " pm.status, " + " COALESCE(mp.manpower_count, 0) AS manpower, " |
|||
+ " COALESCE(cc.total_complaints, 0) AS total_complaints, " + " COALESCE(cc.opened, 0) AS opened, " |
|||
+ " COALESCE(cc.under_review, 0) AS under_review, " |
|||
+ " COALESCE(cc.pending_closure, 0) AS pending_closure, " + " COALESCE(cc.closed, 0) AS closed " + |
|||
|
|||
"FROM pct_master pm " + |
|||
|
|||
// Manpower present per PCT on selected date |
|||
"LEFT JOIN ( " + " SELECT me.pct, COUNT(*) AS manpower_count " + " FROM man_power_employees me " |
|||
+ " WHERE me.att_date >= ? " + " AND me.att_date < DATE_ADD(?, INTERVAL 1 DAY) " |
|||
+ " AND me.isactive = 1 AND me.isdelete = 0 " + " AND EXISTS ( " |
|||
+ " SELECT 1 FROM man_power_details md " + " WHERE md.pct = me.pct " |
|||
+ " AND md.isactive = 1 AND md.isdelete = 0 " + " ) " + " GROUP BY me.pct " |
|||
+ ") mp ON mp.pct = pm.pct " + |
|||
|
|||
// Complaint counts per PCT |
|||
"LEFT JOIN ( " + " SELECT " + " cd.pct, " + " COUNT(*) AS total_complaints, " + |
|||
|
|||
" SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'OPEN' " |
|||
+ " THEN 1 ELSE 0 END) AS opened, " + |
|||
|
|||
" SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'UNDER REVIEW' " |
|||
+ " THEN 1 ELSE 0 END) AS under_review, " + |
|||
|
|||
" SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'PENDING CLOSURE' " |
|||
+ " THEN 1 ELSE 0 END) AS pending_closure, " + |
|||
|
|||
" SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'CLOSED' " |
|||
+ " THEN 1 ELSE 0 END) AS closed " + |
|||
|
|||
" FROM complaints_details cd " + " WHERE cd.isactive = 1 AND cd.isdelete = 0 " |
|||
+" AND cd.complaint_raised_on >= ? " + |
|||
" AND cd.complaint_raised_on < DATE_ADD(?, INTERVAL 1 DAY) " |
|||
+ " GROUP BY cd.pct " + ") cc ON cc.pct = pm.pct " + |
|||
|
|||
"WHERE pm.isactive = 1 AND pm.isdelete = 0 " + filters + " ORDER BY pm.zone, pm.ward, pm.address"; |
|||
|
|||
// The first two parameters belong to the manpower subquery. |
|||
List<Object> locationParams = new ArrayList<>(); |
|||
|
|||
locationParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
locationParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
|
|||
locationParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
locationParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
|
|||
|
|||
// Append filter parameters in SQL order. |
|||
locationParams.addAll(filterParams); |
|||
|
|||
List<Map<String, Object>> locations = jdbcTemplate.queryForList(locationsSql, locationParams.toArray()); |
|||
|
|||
// ========================================== |
|||
// 4. TODAY'S COMPLAINTS - FILTERED |
|||
// ========================================== |
|||
|
|||
String todayComplaintsSql = "SELECT COUNT(*) " + "FROM complaints_details cd " |
|||
+ "INNER JOIN pct_master pm ON pm.pct = cd.pct " + "WHERE cd.complaint_raised_on >= ? " |
|||
+ "AND cd.complaint_raised_on < DATE_ADD(?, INTERVAL 1 DAY) " |
|||
+ "AND cd.isactive = 1 AND cd.isdelete = 0 " + "AND pm.isactive = 1 AND pm.isdelete = 0 " + filters; |
|||
|
|||
List<Object> todayParams = new ArrayList<>(); |
|||
|
|||
todayParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
todayParams.add(java.sql.Date.valueOf(selectedDate)); |
|||
todayParams.addAll(filterParams); |
|||
|
|||
Integer todaysComplaints = jdbcTemplate.queryForObject(todayComplaintsSql, Integer.class, |
|||
todayParams.toArray()); |
|||
|
|||
// ========================================== |
|||
// 5. MANPOWER PRESENT - FILTERED TOTAL |
|||
// ========================================== |
|||
|
|||
int manpowerPresent = 0; |
|||
|
|||
for (Map<String, Object> row : locations) { |
|||
|
|||
Object manpower = row.get("manpower"); |
|||
|
|||
if (manpower instanceof Number) { |
|||
manpowerPresent += ((Number) manpower).intValue(); |
|||
} |
|||
} |
|||
|
|||
// ========================================== |
|||
// 6. RESPONSE |
|||
// ========================================== |
|||
|
|||
response.put("totalLocations", totalLocations != null ? totalLocations : 0); |
|||
|
|||
response.put("totalActiveLocations", totalActiveLocations != null ? totalActiveLocations : 0); |
|||
|
|||
response.put("totalComplaints", totalComplaints != null ? totalComplaints : 0); |
|||
|
|||
response.put("todaysComplaints", todaysComplaints != null ? todaysComplaints : 0); |
|||
|
|||
response.put("manpowerPresent", manpowerPresent); |
|||
|
|||
response.put("locations", locations); |
|||
|
|||
response.put("status", "Success"); |
|||
response.put("message", "Fetched dashboard summary Successfully"); |
|||
|
|||
} catch (Exception e) { |
|||
|
|||
e.printStackTrace(); |
|||
|
|||
response.put("status", "Failed"); |
|||
response.put("message", "Error while fetching dashboard summary"); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
|
|||
public Map<String, Object> getPctComplaints(String pct, String date, String zone, String ward, String status, |
|||
String searchAddress, String complaintStatus) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
try { |
|||
|
|||
if (pct == null || pct.trim().isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "PCT is required"); |
|||
return response; |
|||
} |
|||
|
|||
String pctValue = pct.trim(); |
|||
|
|||
// ========================================== |
|||
// 1. FETCH PCT DETAILS |
|||
// ========================================== |
|||
|
|||
String pctSql = "SELECT id, pct, zone, ward, address, status " + "FROM pct_master " |
|||
+ "WHERE pct = ? AND isactive = 1 AND isdelete = 0"; |
|||
|
|||
List<Map<String, Object>> pctList = jdbcTemplate.queryForList(pctSql, pctValue); |
|||
|
|||
if (pctList.isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "PCT not found"); |
|||
return response; |
|||
} |
|||
|
|||
Map<String, Object> pctDetails = pctList.get(0); |
|||
|
|||
// ========================================== |
|||
// 2. BUILD COMMON FILTERS |
|||
// ========================================== |
|||
|
|||
StringBuilder conditions = new StringBuilder(); |
|||
|
|||
List<Object> commonParams = new ArrayList<>(); |
|||
|
|||
conditions.append(" AND cd.pct = ? "); |
|||
commonParams.add(pctValue); |
|||
|
|||
conditions.append(" AND cd.isactive = 1 AND cd.isdelete = 0 "); |
|||
conditions.append(" AND pm.isactive = 1 AND pm.isdelete = 0 "); |
|||
|
|||
if (date != null && !date.trim().isEmpty()) { |
|||
|
|||
java.sql.Date selectedDate = java.sql.Date.valueOf(date.trim()); |
|||
|
|||
conditions.append(" AND cd.complaint_raised_on >= ? " |
|||
+ " AND cd.complaint_raised_on < DATE_ADD(?, INTERVAL 1 DAY) "); |
|||
|
|||
commonParams.add(selectedDate); |
|||
commonParams.add(selectedDate); |
|||
} |
|||
|
|||
if (zone != null && !zone.trim().isEmpty() && !"ALL".equalsIgnoreCase(zone.trim())) { |
|||
|
|||
conditions.append(" AND pm.zone = ? "); |
|||
commonParams.add(zone.trim()); |
|||
} |
|||
|
|||
if (ward != null && !ward.trim().isEmpty() && !"ALL".equalsIgnoreCase(ward.trim())) { |
|||
|
|||
conditions.append(" AND pm.ward = ? "); |
|||
commonParams.add(ward.trim()); |
|||
} |
|||
|
|||
if (status != null && !status.trim().isEmpty() && !"ALL".equalsIgnoreCase(status.trim())) { |
|||
|
|||
conditions.append(" AND UPPER(TRIM(pm.status)) = ? "); |
|||
commonParams.add(status.trim().toUpperCase()); |
|||
} |
|||
|
|||
if (searchAddress != null && !searchAddress.trim().isEmpty()) { |
|||
|
|||
conditions.append(" AND pm.address LIKE ? "); |
|||
commonParams.add("%" + searchAddress.trim() + "%"); |
|||
} |
|||
|
|||
String baseFrom = " FROM complaints_details cd " + " LEFT JOIN pct_master pm ON pm.pct = cd.pct " |
|||
+ " WHERE 1 = 1 " + conditions; |
|||
|
|||
// ========================================== |
|||
// 3. COUNTS FOR ALL FIVE TABS |
|||
// ========================================== |
|||
|
|||
String countsSql = "SELECT " + " COUNT(*) AS all_count, " + |
|||
|
|||
" COALESCE(SUM(CASE " + " WHEN UPPER(TRIM(cd.status)) = 'OPEN' " |
|||
+ " THEN 1 ELSE 0 END), 0) AS opened, " + |
|||
|
|||
" COALESCE(SUM(CASE " + " WHEN UPPER(TRIM(cd.status)) = 'UNDER REVIEW' " |
|||
+ " THEN 1 ELSE 0 END), 0) AS under_review, " + |
|||
|
|||
" COALESCE(SUM(CASE " + " WHEN UPPER(TRIM(cd.status)) = 'PENDING CLOSURE' " |
|||
+ " THEN 1 ELSE 0 END), 0) AS pending_closure, " + |
|||
|
|||
" COALESCE(SUM(CASE " + " WHEN UPPER(TRIM(cd.status)) = 'CLOSED' " |
|||
+ " THEN 1 ELSE 0 END), 0) AS closed " + |
|||
|
|||
baseFrom; |
|||
|
|||
Map<String, Object> tabCounts = jdbcTemplate.queryForMap(countsSql, commonParams.toArray()); |
|||
|
|||
// ========================================== |
|||
// 4. FETCH COMPLAINTS FOR SELECTED TAB |
|||
// ========================================== |
|||
|
|||
StringBuilder complaintStatusCondition = new StringBuilder(); |
|||
List<Object> complaintParams = new ArrayList<>(commonParams); |
|||
|
|||
if (complaintStatus != null && !complaintStatus.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(complaintStatus.trim())) { |
|||
|
|||
String normalizedStatus = complaintStatus.trim().toUpperCase(); |
|||
|
|||
List<String> allowedStatuses = Arrays.asList("OPEN", "UNDER REVIEW", "PENDING CLOSURE", "CLOSED"); |
|||
|
|||
if (!allowedStatuses.contains(normalizedStatus)) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "Invalid complaint status"); |
|||
return response; |
|||
} |
|||
|
|||
complaintStatusCondition.append(" AND UPPER(TRIM(cd.status)) = ? "); |
|||
|
|||
complaintParams.add(normalizedStatus); |
|||
} |
|||
|
|||
String complaintsSql = "SELECT " + " cd.id, " + " cd.pct, " + " cd.complaint_id, " |
|||
+ " cd.status AS complaint_status, " + " cd.source, " + " cd.description, " |
|||
+ " cd.complaint_raised_on, " + " cd.turn_around_time, " + " cd.created_date, " + " cd.location, " |
|||
+ " cd.address " + baseFrom + complaintStatusCondition |
|||
+ " ORDER BY cd.complaint_raised_on DESC, cd.id DESC"; |
|||
|
|||
List<Map<String, Object>> complaints = jdbcTemplate.queryForList(complaintsSql, complaintParams.toArray()); |
|||
|
|||
// ========================================== |
|||
// 5. RESPONSE |
|||
// ========================================== |
|||
|
|||
response.put("status", "Success"); |
|||
response.put("pctDetails", pctDetails); |
|||
response.put("tabCounts", tabCounts); |
|||
response.put("complaints", complaints); |
|||
response.put("selectedComplaintStatus", complaintStatus == null ? "ALL" : complaintStatus.toUpperCase()); |
|||
|
|||
} catch (Exception e) { |
|||
|
|||
e.printStackTrace(); |
|||
|
|||
response.put("status", "Failed"); |
|||
response.put("message", "Error while fetching PCT complaints"); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
public Map<String, Object> getComplaintTimeline(String complaintId) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
try { |
|||
|
|||
if (complaintId == null || complaintId.trim().isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "Complaint ID is required"); |
|||
return response; |
|||
} |
|||
|
|||
String sql = |
|||
"SELECT " + |
|||
" cd.id AS complaint_detail_id, " + |
|||
" cd.complaint_id, " + |
|||
" cd.status AS current_status, " + |
|||
" cd.description, " + |
|||
" cd.source, " + |
|||
" cd.location, " + |
|||
" cd.address, " + |
|||
" cd.complaint_raised_on AS current_raised_on, " + |
|||
" cd.turn_around_time, " + |
|||
" ch.id AS history_id, " + |
|||
" ch.status AS history_status, " + |
|||
" ch.remarks, " + |
|||
" ch.complaint_raised_on, " + |
|||
" ch.complaint_raised_by, " + |
|||
" ch.complaint_updated_on, " + |
|||
" ch.complaint_updated_by, " + |
|||
|
|||
" CASE " + |
|||
" WHEN ch.imgfile IS NOT NULL AND TRIM(ch.imgfile) <> '' " + |
|||
" THEN CONCAT('" + fileBaseUrl + "/gccofficialapp/files', ch.imgfile) " + |
|||
" ELSE NULL " + |
|||
" END AS imgfile " + |
|||
"FROM complaints_details cd " + |
|||
|
|||
"LEFT JOIN complaints_history ch " + |
|||
" ON ch.complaint_id = cd.complaint_id " + |
|||
" AND ch.isactive = 1 " + |
|||
" AND ch.isdelete = 0 " + |
|||
|
|||
"WHERE cd.complaint_id = ? " + |
|||
" AND cd.isactive = 1 " + |
|||
" AND cd.isdelete = 0 " + |
|||
|
|||
"ORDER BY ch.complaint_updated_on DESC, ch.id DESC"; |
|||
|
|||
List<Map<String, Object>> rows = |
|||
jdbcTemplate.queryForList(sql, complaintId.trim()); |
|||
|
|||
if (rows.isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "Complaint not found"); |
|||
return response; |
|||
} |
|||
|
|||
// Header information from complaints_details. |
|||
Map<String, Object> firstRow = rows.get(0); |
|||
|
|||
Map<String, Object> complaint = new HashMap<>(); |
|||
|
|||
complaint.put("complaint_id", firstRow.get("complaint_id")); |
|||
complaint.put("current_status", firstRow.get("current_status")); |
|||
complaint.put("description", firstRow.get("description")); |
|||
complaint.put("source", firstRow.get("source")); |
|||
complaint.put("location", firstRow.get("location")); |
|||
complaint.put("address", firstRow.get("address")); |
|||
complaint.put("turn_around_time",firstRow.get("turn_around_time")); |
|||
complaint.put("complaint_raised_on", |
|||
firstRow.get("current_raised_on")); |
|||
|
|||
// Timeline records from complaints_history. |
|||
List<Map<String, Object>> timeline = new ArrayList<>(); |
|||
|
|||
for (Map<String, Object> row : rows) { |
|||
|
|||
// LEFT JOIN may return a complaint without history. |
|||
if (row.get("history_id") == null) { |
|||
continue; |
|||
} |
|||
|
|||
Map<String, Object> history = new HashMap<>(); |
|||
|
|||
history.put("id", row.get("history_id")); |
|||
history.put("status", row.get("history_status")); |
|||
history.put("remarks", row.get("remarks")); |
|||
|
|||
history.put("complaint_raised_on", |
|||
row.get("complaint_raised_on")); |
|||
|
|||
history.put("complaint_raised_by", |
|||
row.get("complaint_raised_by")); |
|||
|
|||
history.put("complaint_updated_on", |
|||
row.get("complaint_updated_on")); |
|||
|
|||
history.put("complaint_updated_by", |
|||
row.get("complaint_updated_by")); |
|||
|
|||
history.put("imgfile", row.get("imgfile")); |
|||
|
|||
timeline.add(history); |
|||
} |
|||
|
|||
response.put("status", "Success"); |
|||
response.put("complaint", complaint); |
|||
response.put("timeline", timeline); |
|||
response.put("message", "Complaint timeline fetched successfully"); |
|||
|
|||
} catch (Exception e) { |
|||
|
|||
e.printStackTrace(); |
|||
|
|||
response.put("status", "Failed"); |
|||
response.put("message", "Error while fetching complaint timeline"); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
public Map<String, Object> getManpowerDetails(String pct, String date, String zone, String ward, String status, |
|||
String searchAddress) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
try { |
|||
if (pct == null || pct.trim().isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "PCT is required"); |
|||
return response; |
|||
} |
|||
|
|||
String selectedDate = (date == null || date.trim().isEmpty()) ? java.time.LocalDate.now().toString() |
|||
: date.trim(); |
|||
|
|||
java.sql.Date attendanceDate = java.sql.Date.valueOf(selectedDate); |
|||
|
|||
StringBuilder filters = new StringBuilder(); |
|||
List<Object> params = new ArrayList<>(); |
|||
|
|||
// Attendance date parameters |
|||
params.add(attendanceDate); |
|||
params.add(attendanceDate); |
|||
|
|||
// The selected PCT |
|||
filters.append(" AND pm.pct = ? "); |
|||
params.add(pct.trim()); |
|||
|
|||
// Same dashboard filters |
|||
if (zone != null && !zone.trim().isEmpty() && !"ALL".equalsIgnoreCase(zone.trim())) { |
|||
filters.append(" AND pm.zone = ? "); |
|||
params.add(zone.trim()); |
|||
} |
|||
|
|||
if (ward != null && !ward.trim().isEmpty() && !"ALL".equalsIgnoreCase(ward.trim())) { |
|||
filters.append(" AND pm.ward = ? "); |
|||
params.add(ward.trim()); |
|||
} |
|||
|
|||
if (status != null && !status.trim().isEmpty() && !"ALL".equalsIgnoreCase(status.trim())) { |
|||
filters.append(" AND UPPER(TRIM(pm.status)) = ? "); |
|||
params.add(status.trim().toUpperCase()); |
|||
} |
|||
|
|||
if (searchAddress != null && !searchAddress.trim().isEmpty()) { |
|||
filters.append(" AND pm.address LIKE ? "); |
|||
params.add("%" + searchAddress.trim() + "%"); |
|||
} |
|||
|
|||
String sql = "SELECT " + " pm.id AS pct_id, " + " pm.pct, " + " pm.address, " + " pm.zone, " + " pm.ward, " |
|||
+ " pm.status AS pct_status, " + " me.id AS employee_id, " + " me.emp_name, " |
|||
+ " me.mobile_number, " + " me.att_date, " + " me.location, " + " CASE " |
|||
+ " WHEN me.imgfile IS NOT NULL " + " AND TRIM(me.imgfile) <> '' " + " THEN CONCAT('" |
|||
+ fileBaseUrl + "/gccofficialapp/files', me.imgfile) " + " ELSE NULL " + " END AS file_url " + |
|||
|
|||
"FROM pct_master pm " + |
|||
|
|||
"LEFT JOIN man_power_employees me " + " ON me.pct = pm.pct " + " AND me.att_date >= ? " |
|||
+ " AND me.att_date < DATE_ADD(?, INTERVAL 1 DAY) " + " AND me.isactive = 1 " |
|||
+ " AND me.isdelete = 0 " + |
|||
|
|||
"WHERE pm.isactive = 1 " + " AND pm.isdelete = 0 " + |
|||
|
|||
" AND EXISTS ( " + " SELECT 1 FROM man_power_details md " + " WHERE md.pct = pm.pct " |
|||
+ " AND md.isactive = 1 " + " AND md.isdelete = 0 " + " ) " + |
|||
|
|||
filters + |
|||
|
|||
" ORDER BY me.att_date DESC, me.id DESC"; |
|||
|
|||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, params.toArray()); |
|||
|
|||
if (rows.isEmpty()) { |
|||
response.put("status", "Failed"); |
|||
response.put("message", "No manpower attendance found for the selected PCT and date"); |
|||
response.put("employees", Collections.emptyList()); |
|||
return response; |
|||
} |
|||
|
|||
Map<String, Object> firstRow = rows.get(0); |
|||
|
|||
Map<String, Object> pctDetails = new HashMap<>(); |
|||
pctDetails.put("pct_id", firstRow.get("pct_id")); |
|||
pctDetails.put("pct", firstRow.get("pct")); |
|||
pctDetails.put("address", firstRow.get("address")); |
|||
pctDetails.put("zone", firstRow.get("zone")); |
|||
pctDetails.put("ward", firstRow.get("ward")); |
|||
pctDetails.put("status", firstRow.get("pct_status")); |
|||
pctDetails.put("date", selectedDate); |
|||
|
|||
List<Map<String, Object>> employees = new ArrayList<>(); |
|||
|
|||
for (Map<String, Object> row : rows) { |
|||
Map<String, Object> employee = new HashMap<>(); |
|||
|
|||
employee.put("id", row.get("employee_id")); |
|||
employee.put("emp_name", row.get("emp_name")); |
|||
employee.put("mobile_number", row.get("mobile_number")); |
|||
employee.put("att_date", row.get("att_date")); |
|||
employee.put("location", row.get("location")); |
|||
employee.put("imgfile", row.get("file_url")); |
|||
|
|||
employees.add(employee); |
|||
} |
|||
|
|||
response.put("status", "Success"); |
|||
response.put("message", "Manpower details fetched successfully"); |
|||
response.put("pctDetails", pctDetails); |
|||
response.put("employees", employees); |
|||
|
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
|
|||
response.put("status", "Failed"); |
|||
response.put("message", "Error while fetching manpower details"); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
// complainyts overview |
|||
|
|||
public List<Map<String, Object>> ViewLocationDropdown(String ward) { |
|||
String sql = "SELECT DISTINCT(address),pct " |
|||
+ "FROM pct_master " |
|||
+ "WHERE isactive=1 AND isdelete=0 AND ward=? ORDER BY address"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql,ward); |
|||
} catch (Exception e) { |
|||
// TODO: handle exception |
|||
e.printStackTrace(); |
|||
return Collections.emptyList(); |
|||
} |
|||
} |
|||
|
|||
public Map<String, Object> getComplaintsOverview( |
|||
String date, |
|||
String zone, |
|||
String ward, |
|||
String location, |
|||
String status, |
|||
String source, |
|||
String searchAddress) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
try { |
|||
java.time.LocalDate selectedDate = |
|||
java.time.LocalDate.parse(date.trim()); |
|||
|
|||
StringBuilder filters = new StringBuilder(); |
|||
List<Object> params = new ArrayList<>(); |
|||
|
|||
filters.append(" AND cd.complaint_raised_on >= ? "); |
|||
filters.append(" AND cd.complaint_raised_on < DATE_ADD(?, INTERVAL 1 DAY) "); |
|||
|
|||
params.add(java.sql.Date.valueOf(selectedDate)); |
|||
params.add(java.sql.Date.valueOf(selectedDate)); |
|||
|
|||
if (zone != null && !zone.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(zone.trim())) { |
|||
filters.append(" AND pm.zone = ? "); |
|||
params.add(zone.trim()); |
|||
} |
|||
|
|||
if (ward != null && !ward.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(ward.trim())) { |
|||
filters.append(" AND pm.ward = ? "); |
|||
params.add(ward.trim()); |
|||
} |
|||
|
|||
if (location != null && !location.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(location.trim())) { |
|||
filters.append(" AND pm.pct = ? "); |
|||
params.add(location.trim()); |
|||
} |
|||
|
|||
if (status != null && !status.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(status.trim())) { |
|||
filters.append(" AND UPPER(TRIM(cd.status)) = ? "); |
|||
params.add(status.trim().toUpperCase()); |
|||
} |
|||
|
|||
if (source != null && !source.trim().isEmpty() |
|||
&& !"ALL".equalsIgnoreCase(source.trim())) { |
|||
filters.append(" AND LOWER(TRIM(cd.source)) = LOWER(?) "); |
|||
params.add(source.trim()); |
|||
} |
|||
|
|||
if (searchAddress != null && !searchAddress.trim().isEmpty()) { |
|||
filters.append(" AND pm.address LIKE ? "); |
|||
params.add("%" + searchAddress.trim() + "%"); |
|||
} |
|||
|
|||
String baseWhere = |
|||
" FROM complaints_details cd " + |
|||
" INNER JOIN pct_master pm ON pm.pct = cd.pct " + |
|||
" WHERE cd.isactive = 1 AND cd.isdelete = 0 " + |
|||
" AND pm.isactive = 1 AND pm.isdelete = 0 " + |
|||
filters; |
|||
|
|||
// 1. Summary cards: all filters apply. |
|||
String summarySql = |
|||
"SELECT COUNT(*) AS total_complaints, " + |
|||
"COALESCE(SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'OPEN' " + |
|||
"THEN 1 ELSE 0 END), 0) AS opened, " + |
|||
"COALESCE(SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'UNDER REVIEW' " + |
|||
"THEN 1 ELSE 0 END), 0) AS under_review, " + |
|||
"COALESCE(SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'PENDING CLOSURE' " + |
|||
"THEN 1 ELSE 0 END), 0) AS pending_closure, " + |
|||
"COALESCE(SUM(CASE WHEN UPPER(TRIM(cd.status)) = 'CLOSED' " + |
|||
"THEN 1 ELSE 0 END), 0) AS closed " + |
|||
baseWhere; |
|||
|
|||
Map<String, Object> summary = |
|||
jdbcTemplate.queryForMap(summarySql, params.toArray()); |
|||
|
|||
// 2. DataTable: one row per complaint. |
|||
// The history subquery returns at most one row per complaint ID. |
|||
String tableSql = |
|||
"SELECT " + |
|||
" pm.pct, pm.zone, pm.ward, pm.address, " + |
|||
" cd.id AS complaint_detail_id, " + |
|||
" cd.complaint_id, cd.description, " + |
|||
" cd.turn_around_time, cd.source, cd.status, " + |
|||
" cd.complaint_raised_on AS raised_on, " + |
|||
" ch.closed_on " + |
|||
baseWhere + |
|||
" LEFT JOIN ( " + |
|||
" SELECT complaint_id, MAX(complaint_updated_on) AS closed_on " + |
|||
" FROM complaints_history " + |
|||
" WHERE UPPER(TRIM(status)) = 'CLOSED' " + |
|||
" AND isactive = 1 AND isdelete = 0 " + |
|||
" GROUP BY complaint_id " + |
|||
" ) ch ON ch.complaint_id = cd.complaint_id " + |
|||
" ORDER BY cd.complaint_raised_on DESC, cd.id DESC"; |
|||
|
|||
// Put the history join before WHERE in the final SQL. |
|||
tableSql = |
|||
"SELECT pm.pct, pm.zone, pm.ward, pm.address, " + |
|||
"cd.id AS complaint_detail_id, cd.complaint_id, " + |
|||
"cd.description, cd.turn_around_time, cd.source, cd.status, " + |
|||
"cd.complaint_raised_on AS raised_on, ch.closed_on " + |
|||
"FROM complaints_details cd " + |
|||
"INNER JOIN pct_master pm ON pm.pct = cd.pct " + |
|||
"LEFT JOIN ( " + |
|||
" SELECT complaint_id, MAX(complaint_updated_on) AS closed_on " + |
|||
" FROM complaints_history " + |
|||
" WHERE UPPER(TRIM(status)) = 'CLOSED' " + |
|||
" AND isactive = 1 AND isdelete = 0 " + |
|||
" GROUP BY complaint_id " + |
|||
") ch ON ch.complaint_id = cd.complaint_id " + |
|||
"WHERE cd.isactive = 1 AND cd.isdelete = 0 " + |
|||
"AND pm.isactive = 1 AND pm.isdelete = 0 " + |
|||
filters + |
|||
" ORDER BY cd.complaint_raised_on DESC, cd.id DESC"; |
|||
|
|||
List<Map<String, Object>> complaints = |
|||
jdbcTemplate.queryForList(tableSql, params.toArray()); |
|||
|
|||
response.put("totalComplaints", summary.get("total_complaints")); |
|||
response.put("opened", summary.get("opened")); |
|||
response.put("underReview", summary.get("under_review")); |
|||
response.put("pendingClosure", summary.get("pending_closure")); |
|||
response.put("closed", summary.get("closed")); |
|||
response.put("complaints", complaints); |
|||
response.put("status", "Success"); |
|||
response.put("message", "Complaints overview fetched successfully"); |
|||
|
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
response.put("status", "Failed"); |
|||
response.put("message", "Error while fetching complaints overview"); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
} |
|||
@ -1,2 +1,2 @@ |
|||
spring.profiles.active=prod |
|||
#spring.profiles.active=dev |
|||
#spring.profiles.active=prod |
|||
spring.profiles.active=dev |
|||
1311
src/main/resources/templates/modules/dbfot/CompDetails.html
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2023
src/main/resources/templates/modules/dbfot/locDetails.html
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue