diff --git a/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java b/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java index c4d21da..7bcaac9 100644 --- a/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java +++ b/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java @@ -20,7 +20,7 @@ public class DataSourceConfig { // private static String host = "localhost:3306"; // private static String dbpassword = "root"; - private static String host ="gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; + private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; private static String dbpassword = "gcc-facial-password"; public static class MyDataSourceConfig { @@ -107,4 +107,26 @@ public class DataSourceConfig { return dataSource; } + ////////////////////////////// vph //////////////////////// + @Bean(name = "mysqlVphDataSource") + public DataSource mysqlVphDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/victoriahallbooking"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + //////////////////////////// (For GCC flagpoles) //////////////////////// + @Bean(name = "mysqlFlagPoleManagerSystemDataSource") + public DataSource mysqlFlagPoleManagerSystemDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_flag_pole"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + } diff --git a/src/main/java/com/gcc/commissionerreview/controller/FlagpolesApiController.java b/src/main/java/com/gcc/commissionerreview/controller/FlagpolesApiController.java new file mode 100644 index 0000000..d567f99 --- /dev/null +++ b/src/main/java/com/gcc/commissionerreview/controller/FlagpolesApiController.java @@ -0,0 +1,72 @@ +package com.gcc.commissionerreview.controller; + +import java.util.Map; + +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import com.gcc.commissionerreview.service.FlagpolesService; +import java.util.Map; +import java.util.List; + +@RestController +@RequestMapping("/commissionerreview/api") +public class FlagpolesApiController { + + @Autowired + private FlagpolesService flagpolesService; + + @GetMapping("/flagpoles/abstract") + public Map getAbstractData( + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate, + @RequestParam(required = false) String applicationType) { + try { + List> data = flagpolesService.getZoneWiseRequestCounts(fromDate, toDate, + applicationType); + // Only fetch summary if no type filter or type is NULL (to avoid re-fetching + // summary when just filtering table, but front-end might want to keep it) + // Actually, keep fetching summary so numbers don't disappear if specific logic + // changes. + // But usually summary counts should stay static for the date range unless date + // changes. + Map summary = flagpolesService.getTypeWiseCounts(fromDate, toDate); + return Map.of("status", "success", "data", data, "summary", summary); + } catch (Exception e) { + e.printStackTrace(); + return Map.of("status", "error", "message", e.getMessage()); + } + } + + @GetMapping("/flagpoles/details") + public Map getRequestDetails( + @RequestParam String zone, + @RequestParam(required = false) String status, + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate) { + try { + List> data = flagpolesService.getRequestDetails(zone, status, fromDate, toDate); + return Map.of("status", "success", "data", data); + } catch (Exception e) { + e.printStackTrace(); + return Map.of("status", "error", "message", e.getMessage()); + } + } + + @GetMapping("/flagpoles/street-details") + public Map getStreetDetails(@RequestParam int requestId) { + try { + List> data = flagpolesService.getStreetDetails(requestId); + return Map.of("status", "success", "data", data); + } catch (Exception e) { + e.printStackTrace(); + return Map.of("status", "error", "message", e.getMessage()); + } + } + +} diff --git a/src/main/java/com/gcc/commissionerreview/controller/MainController.java b/src/main/java/com/gcc/commissionerreview/controller/MainController.java index 1850904..9a6893a 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/MainController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/MainController.java @@ -15,6 +15,7 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.client.RestTemplate; +import org.springframework.web.servlet.ModelAndView; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -260,4 +261,9 @@ public class MainController { // visistor based count + @GetMapping("/flagpolereport") + public String getFlagpoleReportPage(Model model) { + return "modules/flagpoles/abstractreport"; + } + } diff --git a/src/main/java/com/gcc/commissionerreview/service/FlagpolesService.java b/src/main/java/com/gcc/commissionerreview/service/FlagpolesService.java new file mode 100644 index 0000000..9948917 --- /dev/null +++ b/src/main/java/com/gcc/commissionerreview/service/FlagpolesService.java @@ -0,0 +1,199 @@ +package com.gcc.commissionerreview.service; + +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Service +public class FlagpolesService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlFlagPoleManagerSystemDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + public List> getZoneWiseRequestCounts(String fromDate, String toDate, String applicationType) { + StringBuilder sql = new StringBuilder("SELECT " + + " s.zone, " + + " COUNT(u.id) as total_requests, " + + " SUM(CASE WHEN u.final_status = 'Approved' THEN 1 ELSE 0 END) as approved_count, " + + " SUM(CASE WHEN u.final_status = 'Rejected' THEN 1 ELSE 0 END) as rejected_count " + + "FROM user_request_details u " + + "JOIN street_details s ON u.id = s.user_req_id " + + "LEFT JOIN application_type at ON u.application_type = at.id "); + + List params = new java.util.ArrayList<>(); + + // Helper to handle date and type filters + boolean whereAdded = false; + + if (fromDate != null && !fromDate.isEmpty() && toDate != null && !toDate.isEmpty()) { + sql.append("WHERE DATE(u.cdate) BETWEEN ? AND ? "); + params.add(fromDate); + params.add(toDate); + whereAdded = true; + } + + if (applicationType != null && !applicationType.isEmpty() && !applicationType.equalsIgnoreCase("OVERALL")) { + if (whereAdded) { + sql.append("AND at.type = ? "); + } else { + sql.append("WHERE at.type = ? "); + whereAdded = true; + } + params.add(applicationType); + } + + sql.append("GROUP BY s.zone ORDER BY s.zone"); + + List> dbResults = jdbcTemplate.queryForList(sql.toString(), params.toArray()); + + // Parse DB results into a Map keyed by Zone Number for robust matching + Map> zoneDataMap = new java.util.HashMap<>(); + for (Map row : dbResults) { + String zoneStr = (String) row.get("zone"); + if (zoneStr != null) { + // Extract number from "Zone 10" or "Zone 05" + String numberOnly = zoneStr.replaceAll("[^0-9]", ""); + if (!numberOnly.isEmpty()) { + try { + int zoneNum = Integer.parseInt(numberOnly); + // Update zone display format to "01", "02", etc. + row.put("zone", String.format("%02d", zoneNum)); + zoneDataMap.put(zoneNum, row); + } catch (NumberFormatException e) { + // ignore malformed zone names + } + } + } + } + + // Generate final list for Zones 1 to 15 + List> finalResults = new java.util.ArrayList<>(); + for (int i = 1; i <= 15; i++) { + if (zoneDataMap.containsKey(i)) { + finalResults.add(zoneDataMap.get(i)); + } else { + Map emptyRow = new java.util.HashMap<>(); + emptyRow.put("zone", String.format("%02d", i)); + emptyRow.put("total_requests", 0); + emptyRow.put("approved_count", 0); + emptyRow.put("rejected_count", 0); + finalResults.add(emptyRow); + } + } + + return finalResults; + } + + public List> getRequestDetails(String zone, String status, String fromDate, String toDate) { + StringBuilder sql = new StringBuilder("SELECT " + + " u.id, " + + " u.refid, " + + " u.applicant_name, " + + " u.mobile_number, " + + " u.event_desc, " + + " DATE_FORMAT(u.event_date, '%d-%m-%Y') as event_date, " + + " u.final_status, " + + " at.type as application_type, " + + " ao.option_name as application_option, " + + " it.installation_name as installation_type " + + "FROM user_request_details u " + + "LEFT JOIN application_type at ON u.application_type = at.id " + + "LEFT JOIN application_option ao ON u.application_option = ao.id " + + "LEFT JOIN installation_type it ON u.installation_type = it.id " + + "LEFT JOIN street_details s ON u.id = s.user_req_id " + + "WHERE 1=1 "); + + List params = new java.util.ArrayList<>(); + + if (zone != null && !zone.isEmpty()) { + // Handle various zone formats (01, 1, Zone 1, Zone 01) + String zoneNumStr = zone.replaceAll("[^0-9]", ""); + if (!zoneNumStr.isEmpty()) { + try { + int z = Integer.parseInt(zoneNumStr); + sql.append("AND (s.zone = ? OR s.zone = ? OR s.zone = ? OR s.zone = ?) "); + params.add("Zone " + z); + params.add("Zone " + String.format("%02d", z)); + params.add(String.valueOf(z)); + params.add(String.format("%02d", z)); + } catch (NumberFormatException e) { + sql.append("AND s.zone = ? "); + params.add(zone); + } + } else { + sql.append("AND s.zone = ? "); + params.add(zone); + } + } + + if (status != null && !status.isEmpty() && !status.equalsIgnoreCase("Total")) { + sql.append("AND u.final_status = ? "); + params.add(status); + } + + if (fromDate != null && !fromDate.isEmpty() && toDate != null && !toDate.isEmpty()) { + sql.append("AND DATE(u.cdate) BETWEEN ? AND ? "); + params.add(fromDate); + params.add(toDate); + } + + sql.append("GROUP BY u.id ORDER BY u.cdate DESC"); + + return jdbcTemplate.queryForList(sql.toString(), params.toArray()); + } + + public List> getStreetDetails(int requestId) { + String sql = "SELECT " + + " s.zone, " + + " s.ward, " + + " s.street_name, " + + " s.no_of_poles, " + + " s.no_of_statue " + + "FROM street_details s " + + "WHERE s.user_req_id = ?"; + return jdbcTemplate.queryForList(sql, requestId); + } + + public Map getTypeWiseCounts(String fromDate, String toDate) { + StringBuilder sql = new StringBuilder("SELECT " + + " at.type, " + + " COUNT(u.id) as count " + + "FROM user_request_details u " + + "JOIN application_type at ON u.application_type = at.id "); + + Object[] params = new Object[] {}; + + if (fromDate != null && !fromDate.isEmpty() && toDate != null && !toDate.isEmpty()) { + sql.append("WHERE DATE(u.cdate) BETWEEN ? AND ? "); + params = new Object[] { fromDate, toDate }; + } + + sql.append("GROUP BY at.type"); + + List> results = jdbcTemplate.queryForList(sql.toString(), params); + Map counts = new java.util.HashMap<>(); + counts.put("TEMPORARY", 0); + counts.put("PERMANENT", 0); + + int total = 0; + for (Map row : results) { + String type = ((String) row.get("type")).toUpperCase(); + Number count = (Number) row.get("count"); + int val = count.intValue(); + counts.put(type, val); + total += val; + } + counts.put("OVERALL", total); + return counts; + } +} diff --git a/src/main/resources/templates/modules/flagpoles/abstractreport.html b/src/main/resources/templates/modules/flagpoles/abstractreport.html new file mode 100644 index 0000000..65c5393 --- /dev/null +++ b/src/main/resources/templates/modules/flagpoles/abstractreport.html @@ -0,0 +1,416 @@ + + + + + + Flagpoles Abstract Report + + + + + + + + + + + + + +
+

Flagpoles Abstract Report

+
+ +
+
+
Report
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + + + +
+
+
+
+
Total Overall Requests
+

0

+
+
+
Total Temporary Requests
+

0

+
+
+
Total Permanent Requests
+

0

+
+
+
+
+ + + + + + + + + + + + + +
ZoneTotal RequestsApprovedRejected
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file