From 22554aca8cdf6335688238b45aede3d13fa30f7e Mon Sep 17 00:00:00 2001 From: Hariprasath S <113695067+Hariprasath4022@users.noreply.github.com> Date: Sat, 3 Oct 2026 11:11:27 +0530 Subject: [PATCH] Added Roadwar works Dashboards --- .../configuration/DataSourceConfig.java | 20 +- .../controller/MainController.java | 23 + .../controller/RoadWarApiController.java | 20 + .../controller/WorksController.java | 114 + .../service/RoadWarService.java | 368 +++ .../service/WorksService.java | 1714 +++++++++++++ src/main/resources/application.properties | 4 +- .../roadwarweb/roadwarregisterdashboard.html | 1940 ++++++++++++++ .../templates/modules/works/dashboard.html | 2259 +++++++++++++++++ .../modules/works/estimatedetails.html | 1095 ++++++++ .../modules/works/roadworksdetails.html | 2156 ++++++++++++++++ 11 files changed, 9707 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/gcc/commissionerreview/controller/WorksController.java create mode 100644 src/main/java/com/gcc/commissionerreview/service/WorksService.java create mode 100644 src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html create mode 100644 src/main/resources/templates/modules/works/dashboard.html create mode 100644 src/main/resources/templates/modules/works/estimatedetails.html create mode 100644 src/main/resources/templates/modules/works/roadworksdetails.html diff --git a/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java b/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java index c73e4e2..bde8ba4 100644 --- a/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java +++ b/src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java @@ -17,11 +17,11 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @EnableTransactionManagement public class DataSourceConfig { - // private static String host = "localhost:3306"; - // private static String dbpassword = "root"; + 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 dbpassword = "gcc-facial-password"; +// 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 { @Primary @@ -333,5 +333,17 @@ public class DataSourceConfig { dataSource.setPassword(dbpassword); return dataSource; } + + + ////////// Works Dashboard ////////////////////// + @Bean(name = "mysqlWorksDataSource") + public DataSource mysqlWorksDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_works_status"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } } diff --git a/src/main/java/com/gcc/commissionerreview/controller/MainController.java b/src/main/java/com/gcc/commissionerreview/controller/MainController.java index 1a1c4c0..6e8858a 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/MainController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/MainController.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Controller; 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.RequestParam; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.ModelAndView; @@ -423,5 +424,27 @@ public class MainController { public String Revenue() { return "modules/communityrevenue"; } + + @GetMapping("/roadworksDashboard") + public String worksDashboard() { + return "modules/works/dashboard"; + } + + @GetMapping("/roadworksviewdetails") + public String worksEstimateDetails(@RequestParam int estid) { + return "modules/works/estimatedetails"; + } + + @GetMapping("/roadestimatedetails") + public String roadEstimateDetails(@RequestParam int estid,@RequestParam int ref_id) { + return "modules/works/roadworksdetails"; + } + + @GetMapping("/roadwarRegisterDashboard") + public String roadwarRegisterDashboard() + { + return "modules/roadwarweb/roadwarregisterdashboard"; + } + } diff --git a/src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java b/src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java index c1fdbf1..7511883 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java @@ -156,4 +156,24 @@ public class RoadWarApiController { roadWarService.downloadRoadWarPdf(refId, response); } + //for road war register dashboard + + @GetMapping("/getdashboardsummary") + public Map getDashboardSummary(@RequestParam(required = false) String zone, + @RequestParam(required = false) String ward, @RequestParam(required = false) Integer roadType, + @RequestParam(required = false) String swd) { + + return roadWarService.getDashboardSummary(zone, ward, roadType, swd); + } + + @GetMapping("/getroadrecords") + public Map getRoadRecords(@RequestParam(required = false) String zone, + @RequestParam(required = false) String ward, @RequestParam(required = false) Integer roadType, + @RequestParam(required = false) String swd) { + + return roadWarService.getRoadRecords(zone, ward, roadType, swd + + ); + } + } diff --git a/src/main/java/com/gcc/commissionerreview/controller/WorksController.java b/src/main/java/com/gcc/commissionerreview/controller/WorksController.java new file mode 100644 index 0000000..e61cd81 --- /dev/null +++ b/src/main/java/com/gcc/commissionerreview/controller/WorksController.java @@ -0,0 +1,114 @@ +package com.gcc.commissionerreview.controller; + +import com.gcc.commissionerreview.service.WorksService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +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 java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/commissionerreview/api/works") + +public class WorksController { + + @Autowired + private WorksService worksService ; + + + @GetMapping("/financial-years") + public List> getFinancialYears() { + return worksService.getFinancialYears(); + } + + + @GetMapping("/work-types") + public List> getWorkTypes() { + return worksService.getWorkTypes(); + } + + + @GetMapping("/road-types") + public List> getRoadTypes() { + return worksService.getRoadTypes(); + } + + @GetMapping("/fund-types") + public List> getFundTypes() { + return worksService.getFundTypes(); + } + + + @GetMapping("/progress-status") + public List> getProgressStatus() { + return worksService.getProgressStatus(); + } + + + @GetMapping("/zones") + public List> getAllZones() { + return worksService.getAllZones(); + } + + @GetMapping("/wards") + public List> getAllWards(int zone) { + return worksService.getAllWards(zone); + } + + + + @GetMapping("/dashboard-details") + public ResponseEntity getDashboardSummary( + + @RequestParam(required = false) String financialYear, + + @RequestParam(required = false) Integer workType, + + @RequestParam(required = false) Integer roadType, + + @RequestParam(required = false) Integer fundType, + + @RequestParam(required = false) String progressStatus, + + @RequestParam(required = false) Integer zone, + + @RequestParam(required = false) Integer ward) { + + Map result = worksService.getDashboardDetails(financialYear, workType, roadType, fundType, + progressStatus, zone, ward); + + return ResponseEntity.ok(result); + } + + @GetMapping("/viewEstimateDetails") + public ResponseEntity getDetailsByEstId(@RequestParam int estid) { + Map result =worksService.getDetailsByEstId(estid); + return ResponseEntity.ok(result); + } + + + @GetMapping("/viewRoadWorks") + public List> viewRoadWorks(int estid) { + return worksService.viewRoadWorks(estid); + } + + @GetMapping("/roadtabdetails") + public List> viewRoadTabDetails(int estid,int ref_id) { + return worksService.viewRoadTabDetails(estid, ref_id); + } + + @GetMapping("/progresstabdetails") + public List> viewProgressTabDetails(int estid,int ref_id) { + return worksService.viewProgressTabDetails(estid, ref_id); + } + + @GetMapping("/getRoadWarDetailsByRoadId") + public Map getRoadWarDetailsByRoadId(int estid,int ref_id){ + return worksService.getRoadWarDetailsByRoadId2(estid, ref_id); + } + +} diff --git a/src/main/java/com/gcc/commissionerreview/service/RoadWarService.java b/src/main/java/com/gcc/commissionerreview/service/RoadWarService.java index 4e3acbf..2da0286 100644 --- a/src/main/java/com/gcc/commissionerreview/service/RoadWarService.java +++ b/src/main/java/com/gcc/commissionerreview/service/RoadWarService.java @@ -1500,6 +1500,374 @@ public class RoadWarService { return p; } + // for road war register dashboard + public Map getDashboardSummary( + String zone, + String ward, + Integer roadType, + String swd) { + + Map response = new HashMap<>(); + + try { + + StringBuilder where = new StringBuilder(""" + WHERE r.is_active = 1 + AND r.is_delete = 0 + """); + + List params = new ArrayList<>(); + + addFilters(where, params, zone, ward, roadType, swd); + + // ------------------------------------ + // 1. Total Roads + // ------------------------------------ + + String totalSql = + "SELECT COUNT(*) " + + "FROM road_details_master r " + + where; + + Integer totalRoads = jdbcTemplate.queryForObject( + totalSql, + params.toArray(), + Integer.class + ); + + // ------------------------------------ + // 2. Zone-wise Road Count + // ------------------------------------ + + String zoneSql = """ + SELECT + z.zone_name AS zone, + COUNT(r.id) AS road_count + FROM zone_master z + LEFT JOIN road_details_master r + ON r.zone = z.zone_name + AND r.is_active = 1 + AND r.is_delete = 0 + """; + + StringBuilder zoneWhere = new StringBuilder(); + + List zoneParams = new ArrayList<>(); + + if (ward != null && !ward.trim().isEmpty()) { + zoneWhere.append(" AND r.ward = ? "); + zoneParams.add(ward); + } + + if (roadType != null) { + zoneWhere.append(" AND r.road_type = ? "); + zoneParams.add(roadType); + } + + if (swd != null && !swd.trim().isEmpty()) { + zoneWhere.append(" AND LOWER(TRIM(r.is_swd)) = LOWER(?) "); + zoneParams.add(swd); + } + + /* + * Important: + * If a particular zone is selected, we still want + * all zones displayed with zero for other zones. + */ + if (zone != null && !zone.trim().isEmpty()) { + zoneWhere.append(" AND r.zone = ? "); + zoneParams.add(zone); + } + + zoneSql += zoneWhere; + zoneSql += """ + WHERE z.is_active = 1 + AND z.is_delete = 0 + GROUP BY z.id, z.zone_name + ORDER BY z.id + """; + + /* + * The above SQL has WHERE after LEFT JOIN condition. + * Because zoneWhere contains r conditions, putting them + * in WHERE would convert LEFT JOIN behavior. + * + * Therefore we use a separate query below. + */ + + zoneSql = buildZoneQuery(zone, ward, roadType, swd); + + List> zoneCounts = jdbcTemplate.queryForList(zoneSql, + buildZoneParams(zone, ward, roadType, swd).toArray()); + + // ------------------------------------ + // 3. Road Type Count + // ------------------------------------ + + String roadTypeSql = """ + SELECT + rt.id AS road_type_id, + rt.road_type AS road_type, + COUNT(r.id) AS road_count + FROM road_type_master rt + LEFT JOIN road_details_master r + ON r.road_type = rt.id + AND r.is_active = 1 + AND r.is_delete = 0 + """; + + StringBuilder roadTypeCondition = new StringBuilder(); + List roadTypeParams = new ArrayList<>(); + + addJoinFilters(roadTypeCondition, roadTypeParams, zone, ward, roadType, swd); + + roadTypeSql += roadTypeCondition; + + roadTypeSql += """ + WHERE rt.is_active = 1 + AND rt.is_delete = 0 + GROUP BY rt.id, rt.road_type + ORDER BY rt.id + """; + + List> roadTypeCounts = jdbcTemplate.queryForList(roadTypeSql, + roadTypeParams.toArray()); + + // ------------------------------------ + // 4. SWD Count + // ------------------------------------ + + String swdSql = """ + SELECT + SUM( + CASE + WHEN LOWER(TRIM(r.is_swd)) = 'yes' + THEN 1 + ELSE 0 + END + ) AS available_count, + + SUM( + CASE + WHEN LOWER(TRIM(r.is_swd)) = 'no' + THEN 1 + ELSE 0 + END + ) AS not_available_count + + FROM road_details_master r + """; + + StringBuilder swdWhere = new StringBuilder(" WHERE r.is_active = 1 AND r.is_delete = 0 "); + + List swdParams = new ArrayList<>(); + + addFilters(swdWhere, swdParams, zone, ward, roadType, null); + + swdSql += swdWhere; + + Map swdResult = jdbcTemplate.queryForMap(swdSql, swdParams.toArray()); + + Map swdCounts = new HashMap<>(); + + swdCounts.put("available", swdResult.get("available_count")); + + swdCounts.put("notAvailable", swdResult.get("not_available_count")); + + response.put("status", true); + response.put("message", "Dashboard data fetched successfully"); + response.put("totalRoads", totalRoads); + response.put("zoneCounts", zoneCounts); + response.put("roadTypeCounts", roadTypeCounts); + response.put("swdCounts", swdCounts); + + } catch (Exception e) { + + e.printStackTrace(); + + response.put("status", false); + response.put("message", "Failed to fetch dashboard data"); + } + + return response; + } + + + private void addFilters(StringBuilder where, List params, String zone, String ward, Integer roadType, + String swd) { + + if (zone != null && !zone.trim().isEmpty()) { + where.append(" AND r.zone = ? "); + params.add(zone); + } + + if (ward != null && !ward.trim().isEmpty()) { + where.append(" AND r.ward = ? "); + params.add(ward); + } + + if (roadType != null) { + where.append(" AND r.road_type = ? "); + params.add(roadType); + } + + if (swd != null && !swd.trim().isEmpty()) { + where.append(" AND LOWER(TRIM(r.is_swd)) = LOWER(?) "); + params.add(swd); + } + } + + private String buildZoneQuery(String zone, String ward, Integer roadType, String swd) { + + StringBuilder sql = new StringBuilder(""" + SELECT + z.id AS zone_id, + z.zone_name AS zone, + COUNT(r.id) AS road_count + FROM zone_master z + LEFT JOIN road_details_master r + ON r.zone = z.zone_name + AND r.is_active = 1 + AND r.is_delete = 0 + """); + + if (zone != null && !zone.trim().isEmpty()) { + sql.append(" AND r.zone = ? "); + } + + if (ward != null && !ward.trim().isEmpty()) { + sql.append(" AND r.ward = ? "); + } + + if (roadType != null) { + sql.append(" AND r.road_type = ? "); + } + + if (swd != null && !swd.trim().isEmpty()) { + sql.append(" AND LOWER(TRIM(r.is_swd)) = LOWER(?) "); + } + + sql.append(""" + WHERE z.is_active = 1 + AND z.is_delete = 0 + GROUP BY z.id, z.zone_name + ORDER BY z.id + """); + + return sql.toString(); + } + + private List buildZoneParams(String zone, String ward, Integer roadType, String swd) { + + List params = new ArrayList<>(); + + if (zone != null && !zone.trim().isEmpty()) { + params.add(zone); + } + + if (ward != null && !ward.trim().isEmpty()) { + params.add(ward); + } + + if (roadType != null) { + params.add(roadType); + } + + if (swd != null && !swd.trim().isEmpty()) { + params.add(swd); + } + + return params; + } + + private void addJoinFilters(StringBuilder condition, List params, String zone, String ward, + Integer roadType, String swd) { + + if (zone != null && !zone.trim().isEmpty()) { + condition.append(" AND r.zone = ? "); + params.add(zone); + } + + if (ward != null && !ward.trim().isEmpty()) { + condition.append(" AND r.ward = ? "); + params.add(ward); + } + + if (roadType != null) { + condition.append(" AND r.road_type = ? "); + params.add(roadType); + } + + if (swd != null && !swd.trim().isEmpty()) { + condition.append(" AND LOWER(TRIM(r.is_swd)) = LOWER(?) "); + params.add(swd); + } + } + + public Map getRoadRecords(String zone, String ward, Integer roadType, String swd) { + + Map response = new HashMap<>(); + + try { + + StringBuilder sql = new StringBuilder(""" + SELECT + r.id, + r.ref_id, + r.road_id, + r.zone, + r.ward, + r.road_name, + r.area_name, + r.locality_name, + r.road_type, + rt.road_type AS road_type_name, + rmm.roadtype_material as road_type_material, + r.road_length, + r.road_row_width, + r.road_avg_width, + r.road_area, + r.is_swd, + r.is_electric_poles, + r.is_streetlight_poles, + r.culvert_bridge_count, + r.details + FROM road_details_master r + LEFT JOIN road_type_master rt + ON rt.id = r.road_type + LEFT JOIN roadtype_material_master rmm + ON rmm.id=r.road_type_material + WHERE r.is_active = 1 + AND r.is_delete = 0 + """); + + List params = new ArrayList<>(); + + addFilters(sql, params, zone, ward, roadType, swd); + + sql.append(""" + ORDER BY r.ref_id ASC + """); + + List> records = jdbcTemplate.queryForList(sql.toString(), params.toArray()); + + response.put("status", true); + response.put("message", "Records fetched successfully"); + response.put("data", records); + response.put("recordsTotal", records.size()); + response.put("recordsFiltered", records.size()); + + } catch (Exception e) { + + e.printStackTrace(); + + response.put("status", false); + response.put("message", "Failed to fetch road records"); + response.put("data", new ArrayList<>()); + } + + return response; + } } diff --git a/src/main/java/com/gcc/commissionerreview/service/WorksService.java b/src/main/java/com/gcc/commissionerreview/service/WorksService.java new file mode 100644 index 0000000..e9b4c9b --- /dev/null +++ b/src/main/java/com/gcc/commissionerreview/service/WorksService.java @@ -0,0 +1,1714 @@ +package com.gcc.commissionerreview.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class WorksService { + + @Autowired + private JdbcTemplate jdbcWorksTemplate; + + @Autowired + private JdbcTemplate jdbcRoadWebTemplate; + + @Autowired + private JdbcTemplate jdbcRoadWarTemplate; + + @Autowired + private final Environment environment; + + private String fileBaseUrl; + + @Autowired + public void setDatasource1(@Qualifier("mysqlWorksDataSource") DataSource datasource) { + this.jdbcWorksTemplate = new JdbcTemplate(datasource); + } + + @Autowired + public void setDatasource2(@Qualifier("mysqlRoadWarWebDataSource") DataSource datasource) { + this.jdbcRoadWebTemplate = new JdbcTemplate(datasource); + } + + + @Autowired + public void setDatasource3(@Qualifier("mysqlRoadWarDataSource") DataSource datasource) { + this.jdbcRoadWarTemplate = new JdbcTemplate(datasource); + } + + public WorksService(Environment environment) { + this.environment = environment; + this.fileBaseUrl = environment.getProperty("fileBaseUrl"); + } + + + + +// public List> getFinancialYears() { +// +// String sql = " Select id, financial_year " + +// " from financial_year_master " + +// " where is_active=1 and is_delete=0 "; +// +// +// return jdbcWorksTemplate.queryForList(sql); +// } + + public List> getFinancialYears() { + + String sql = + " SELECT DISTINCT " + + " SUBSTRING_INDEX( " + + " SUBSTRING_INDEX(estimate_no, '/', 2), " + + " '/', " + + " -1 " + + " ) AS financial_year " + + " FROM works_details " + + " WHERE estimate_no IS NOT NULL " + + " AND estimate_no <> '' AND sub_category=4" + + " ORDER BY financial_year DESC "; + + return jdbcWorksTemplate.queryForList(sql); + } + + public List> getWorkTypes() { + +// String sql = " Select id,work_type,value " + +// " from work_type_master " + +// " where is_active=1 and is_delete=0 "; + + String sql=" SELECT id,answer FROM addworks_answer_master WHERE isactive=1 AND isdelete=0 AND question_id=5 ORDER BY orderby"; + + return jdbcWorksTemplate.queryForList(sql); + } + + + + public List> getRoadTypes() { + +// String sql = " Select id,road_type,value " + +// " from road_type_master " + +// " where is_active=1 and is_delete=0 "; + + String sql=" SELECT id,answer FROM addworks_answer_master WHERE isactive=1 AND isdelete=0 AND question_id=4 ORDER BY orderby"; + + + return jdbcWorksTemplate.queryForList(sql); + } + + + public List> getFundTypes() { + +// String sql = " Select id,fund_type " + +// " from fund_type_master " + +// " where is_active=1 and is_delete=0 "; + + String sql="SELECT id,name FROM fundsource_master WHERE isactive=1"; + + return jdbcWorksTemplate.queryForList(sql); + } + + + public List> getProgressStatus() { + + String sql = " Select id,progress_status " + + " from progress_status_master " + + " where is_active=1 and is_delete=0 "; + + + return jdbcWorksTemplate.queryForList(sql); + } + + + public List> getAllZones() { + + String sql = " Select distinct(zone) " + + " from zones_wards_master " ; + + + return jdbcWorksTemplate.queryForList(sql); + } + + public List> getAllWards(int zone) { + + String sql = " Select id,ward " + + " from zones_wards_master " + + " where zone = ? "; + + + return jdbcWorksTemplate.queryForList(sql,zone); + } + + + + + + + public Map getDashboardDetails( + String financialYear, Integer workType, Integer roadType, Integer fundType, String progressStatus, + Integer zone, Integer ward) { + + StringBuilder where = new StringBuilder(" AND wd.isactive = 1 AND wd.isdelete = 0 "); + + List params = new ArrayList<>(); + + // Build common filters + buildFilters(where, params, financialYear, fundType, progressStatus, zone, ward); + + + Map response = new HashMap<>(); + + response.put("summary", getSummary(where.toString(), params)); + + /*response.put( + "roadStatus", + getRoadStatus( + where.toString(), + params + ) + );*/ + + response.put("roadTypes", RoadTypes(where.toString(), params, roadType, workType)); + + response.put("workTypes", WorkTypes(where.toString(), params, roadType, workType)); + + response.put("nearingCompletion", getNearingCompletion(where.toString(), params)); + + response.put("delayedWorks", getDelayedWorks(where.toString(), params)); + + response.put("tableData", getTableData(where.toString(), params)); + + return response; + } + + + + + private void buildFilters( + StringBuilder where, List params, String financialYear, Integer fundType, String progressStatus, + Integer zone, Integer ward) { + + + // Zone + if (zone != null) { + where.append(" AND wd.zone = ? "); + params.add(zone); + } + + + // Ward + if (ward != null) { + where.append(" AND wd.ward = ? "); + params.add(ward); + } + + + // Fund Type + if (fundType != null) { + where.append(" AND wd.fund_source = ? "); + params.add(fundType); + } + + + // Progress Status + if (progressStatus != null + && !progressStatus.trim().isEmpty()) { + + switch (progressStatus) { + + case "PENDING": + + where.append(""" + AND wd.percentage = 0 + """); + + break; + + + case "INPROGRESS": + + where.append(""" + AND wd.percentage > 0 + AND wd.percentage < 100 + AND DATEDIFF( + CURDATE(), + wd.loa_date + ) <= wd.contractor_period + """); + + break; + + + case "COMPLETED": + + where.append(""" + AND wd.percentage = 100 + """); + + break; + + + case "DELAYED": + + where.append(""" + AND wd.percentage > 0 + AND wd.percentage < 100 + AND DATEDIFF( + CURDATE(), + wd.loa_date + ) > wd.contractor_period + """); + + break; + } + } + + + // Financial Year + if (financialYear != null && !financialYear.isBlank()) { + + where.append(""" + AND SUBSTRING_INDEX( + SUBSTRING_INDEX(wd.estimate_no, '/', 2), + '/', + -1 + ) = ? + """); + + params.add(financialYear); + } + } + + +// summary card method + + private Map getSummary( + String where, + List params) { + + + String summaryWhere = where + + " AND wd.sub_category = 4 "; + + String sql = "SELECT " + + + " COUNT(DISTINCT wd.estid) AS total_estimates, " + + + " COUNT( " + + " DISTINCT CASE " + + " WHEN EXISTS ( " + + " SELECT 1 " + + " FROM addworks_text_details ad " + + " JOIN addworks_question_master aq " + + " ON aq.id = ad.question_id " + + " WHERE ad.estid = wd.estid " + + " AND ad.question_id = 3 " + + " AND aq.subcategory_id = 4 " + + " ) " + + " THEN wd.estid " + + " END " + + " ) AS total_road_works, " + + + " COALESCE( " + + " SUM(wd.estimation_amount), " + + " 0 " + + " ) AS total_estimated_value, " + + + " COALESCE( " + + " SUM(wd.est_val_with_oh), " + + " 0 " + + " ) AS total_work_value, " + + + " COUNT( " + + " CASE " + + " WHEN wd.percentage = 100 " + + " THEN wd.estid " + + " END " + + " ) AS completed_count, " + + + " COUNT( " + + " CASE " + + " WHEN wd.percentage = 0 " + + " THEN wd.estid " + + " END " + + " ) AS pending_count, " + + + " COUNT( " + + " CASE " + + " WHEN wd.percentage > 0 " + + " AND wd.percentage < 100 " + + " AND DATEDIFF( " + + " CURDATE(), " + + " wd.loa_date " + + " ) > wd.contractor_period " + + " THEN wd.estid " + + " END " + + " ) AS delay_count, " + + + " COUNT( " + + " CASE " + + " WHEN wd.percentage > 0 " + + " AND wd.percentage < 100 " + + " AND DATEDIFF( " + + " CURDATE(), " + + " wd.loa_date " + + " ) <= wd.contractor_period " + + " THEN wd.estid " + + " END " + + " ) AS inprogress_count " + + + " FROM works_details wd " + + " WHERE 1=1 " + + + summaryWhere; + + + Map summary = jdbcWorksTemplate.queryForMap( + sql, + params.toArray() + ); + + + Number estimatedValue = + (Number) summary.get("total_estimated_value"); + + Number workValue = + (Number) summary.get("total_work_value"); + + summary.put( + "total_estimated_value_display", + formatAmount( + estimatedValue != null + ? estimatedValue.doubleValue() + : 0 + ) + ); + + summary.put( + "total_work_value_display", + formatAmount( + workValue != null + ? workValue.doubleValue() + : 0 + ) + ); + + return summary; + + + + } + + + private String formatAmount(double amount) { + + if (amount >= 1_00_00_000) { + // Crores + double crores = amount / 1_00_00_000; + + return String.format( + "₹%.2f Cr", + crores + ); + } + + if (amount >= 1_00_000) { + // Lakhs + double lakhs = amount / 1_00_000; + + return String.format( + "₹%.2f L", + lakhs + ); + } + + // Below 1 lakh + return String.format( + "₹%.2f", + amount + ); + } + + + + private Map getDelayedWorks( + String where, + List params) { + + String delayedWhere = where + + " AND wd.sub_category = 4 " + + " AND wd.percentage > 0 " + + " AND wd.percentage < 100 " + + " AND DATEDIFF(CURDATE(), wd.loa_date) > wd.contractor_period "; + + String sql = + "SELECT " + + + // Total delayed works + " COUNT(DISTINCT wd.estid) AS delayed_exceeded, " + + + // Delay > 15 days and <= 30 days + " COUNT(DISTINCT CASE " + + " WHEN (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) > 15 " + + " AND (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) <= 30 " + + " THEN wd.estid " + + " END) AS delayed_15_days, " + + + // Delay > 30 days and <= 90 days + " COUNT(DISTINCT CASE " + + " WHEN (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) > 30 " + + " AND (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) <= 90 " + + " THEN wd.estid " + + " END) AS delayed_1_month, " + + + // Delay > 90 days and <= 180 days + " COUNT(DISTINCT CASE " + + " WHEN (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) > 90 " + + " AND (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) <= 180 " + + " THEN wd.estid " + + " END) AS delayed_3_month, " + + + // Delay > 180 days + " COUNT(DISTINCT CASE " + + " WHEN (DATEDIFF(CURDATE(), wd.loa_date) - wd.contractor_period) > 180 " + + " THEN wd.estid " + + " END) AS delayed_6_month " + + + " FROM works_details wd " + + " WHERE 1=1 "+ + delayedWhere; + + Map delayWorks = + jdbcWorksTemplate.queryForMap( + sql, + params.toArray() + ); + + return delayWorks; + } + + + + +// road works progress chart + + private List> RoadTypes( + String where, + List params, + Integer roadType, + Integer workType) { + + StringBuilder sql = new StringBuilder(); + + sql.append(""" + SELECT + aam.id, + aam.answer, + COALESCE(x.answer_count, 0) AS answer_count + + FROM addworks_answer_master aam + + JOIN addworks_question_master aqm + ON aqm.id = aam.question_id + AND aqm.isactive = 1 + AND aqm.isdelete = 0 + + LEFT JOIN ( + SELECT + ad_rt.answer_id, + COUNT(*) AS answer_count + + FROM ( + SELECT DISTINCT + estid, + ref_id, + answer_id + FROM addworks_details + WHERE question_id = 4 + AND isactive = 1 + AND isdelete = 0 + ) ad_rt + + JOIN works_details wd + ON wd.estid = ad_rt.estid + + WHERE 1 = 1 + """); + + sql.append(where); + + List roadParams = new ArrayList<>(params); + + /* + * If Work Type is selected, + * check question 5 against SAME estid + ref_id. + */ + if (workType != null) { + + sql.append(""" + AND EXISTS ( + SELECT 1 + FROM addworks_details ad_wt + WHERE ad_wt.estid = ad_rt.estid + AND ad_wt.ref_id = ad_rt.ref_id + AND ad_wt.question_id = 5 + AND ad_wt.answer_id = ? + AND ad_wt.isactive = 1 + AND ad_wt.isdelete = 0 + ) + """); + + roadParams.add(workType); + } + + /* + * Optional: + * If Road Type itself is selected, + * filter the RoadTypes chart also. + */ + if (roadType != null) { + + sql.append(""" + AND ad_rt.answer_id = ? + """); + + roadParams.add(roadType); + } + + sql.append(""" + GROUP BY ad_rt.answer_id + ) x + ON x.answer_id = aam.id + + WHERE aqm.id = 4 + AND aam.isactive = 1 + AND aam.isdelete = 0 + + ORDER BY aam.id + """); + +// System.out.println("RoadTypes SQL = " + sql); +// System.out.println("RoadTypes Params = " + roadParams); + + return jdbcWorksTemplate.queryForList( + sql.toString(), + roadParams.toArray() + ); + } + + + private List> WorkTypes( + String where, + List params, + Integer roadType, + Integer workType) { + + StringBuilder sql = new StringBuilder(); + + sql.append(""" + SELECT + aam.id, + aam.answer, + COALESCE(x.answer_count, 0) AS answer_count + + FROM addworks_answer_master aam + + JOIN addworks_question_master aqm + ON aqm.id = aam.question_id + AND aqm.isactive = 1 + AND aqm.isdelete = 0 + + LEFT JOIN ( + SELECT + ad_wt.answer_id, + COUNT(*) AS answer_count + + FROM ( + SELECT DISTINCT + estid, + ref_id, + answer_id + FROM addworks_details + WHERE question_id = 5 + AND isactive = 1 + AND isdelete = 0 + ) ad_wt + + JOIN works_details wd + ON wd.estid = ad_wt.estid + + WHERE 1 = 1 + """); + + sql.append(where); + + List workParams = new ArrayList<>(params); + + /* + * Road Type selected: + * match Q4 using SAME estid + ref_id. + */ + if (roadType != null) { + + sql.append(""" + AND EXISTS ( + SELECT 1 + FROM addworks_details ad_rt + WHERE ad_rt.estid = ad_wt.estid + AND ad_rt.ref_id = ad_wt.ref_id + AND ad_rt.question_id = 4 + AND ad_rt.answer_id = ? + AND ad_rt.isactive = 1 + AND ad_rt.isdelete = 0 + ) + """); + + workParams.add(roadType); + } + + if (workType != null) { + + sql.append(""" + AND ad_wt.answer_id = ? + """); + + workParams.add(workType); + } + + sql.append(""" + GROUP BY ad_wt.answer_id + ) x + ON x.answer_id = aam.id + + WHERE aqm.id = 5 + AND aam.isactive = 1 + AND aam.isdelete = 0 + + ORDER BY aam.id + """); + +// System.out.println("WorkTypes SQL = " + sql); +// System.out.println("WorkTypes Params = " + workParams); + + return jdbcWorksTemplate.queryForList( + sql.toString(), + workParams.toArray() + ); + } + + private Map getNearingCompletion( + String where, + List params) { + + String sql = + " SELECT " + + + " COUNT(CASE " + + " WHEN DATEDIFF(CURDATE(), wd.loa_date) " + + " BETWEEN 1 AND 15 " + + " THEN wd.estid " + + " END) AS within_fifteen_days, " + + + " COUNT(CASE " + + " WHEN DATEDIFF(CURDATE(), wd.loa_date) " + + " BETWEEN 16 AND 31 " + + " THEN wd.estid " + + " END) AS within_one_month, " + + + " COUNT(CASE " + + " WHEN DATEDIFF(CURDATE(), wd.loa_date) " + + " BETWEEN 32 AND 90 " + + " THEN wd.estid " + + " END) AS within_three_months, " + + + " COUNT(CASE " + + " WHEN DATEDIFF(CURDATE(), wd.loa_date) >= 91 " + + " THEN wd.estid " + + " END) AS above_three_months " + + + " FROM works_details wd " + + + " WHERE 1 = 1 " + + + " AND wd.sub_category = 4 " + + + where; + + System.out.println("Nearing Completion SQL = " + sql); + System.out.println("Params = " + params); + + return jdbcWorksTemplate.queryForMap(sql, params.toArray()); + } + + + private List> getTableData( + String where, + List params) { + + String dataWhere = where + + " AND wd.sub_category = 4 "; + + String sql = + " SELECT " + + " wd.estid, " + + " wd.estimate_no, " + + " DATE_FORMAT(wd.estimate_date, '%d-%m-%Y') AS estimate_date, " + + " wd.zone, " + + " wd.ward, " + + " wd.project_name, " + + " wd.estimation_amount, " + + " wd.est_val_with_oh, " + + " wd.percentage, " + + " dm.dept_name, " + + + " CASE " + + " WHEN wd.percentage = 0 " + + " THEN 'Not Started' " + + + " WHEN wd.percentage = 100 " + + " THEN 'Completed' " + + + " WHEN wd.percentage > 0 " + + " AND wd.percentage < 100 " + + " AND DATEDIFF(CURDATE(), wd.loa_date) > wd.contractor_period " + + " THEN 'Delayed' " + + + " WHEN wd.percentage > 0 " + + " AND wd.percentage < 100 " + + " THEN 'In Progress' " + + + " ELSE 'Not Started' " + + " END AS status " + + + " FROM works_details wd " + + + " LEFT JOIN department_master dm " + + " ON dm.id = wd.department " + + " AND dm.isactive = 1 " + + " WHERE 1=1 " + + dataWhere ; + + return jdbcWorksTemplate.queryForList( + sql, + params.toArray() + ); + } + + + public Map getDetailsByEstId(int estid) { + + String sql = + " SELECT " + + " ew.estid, " + + " ew.estimate_no, " + + " DATE_FORMAT(ew.estimate_date, '%d-%m-%Y') AS estimate_date, " + + " ew.zone, " + + " ew.ward, " + + " ew.project_name, " + + " ew.estimation_amount, " + + + " DATE_FORMAT(ew.loa_date, '%d-%m-%Y') AS loa_date, " + + " DATE_FORMAT(ew.agreement_date, '%d-%m-%Y') AS agreement_date, " + + " DATE_FORMAT(ew.work_order_date, '%d-%m-%Y') AS work_order_date, " + + " DATE_FORMAT(ew.admin_sanction_date, '%d-%m-%Y') AS admin_sanction_date, " + + + " ew.percentage, " + + + " dm.dept_name, "+ + " fsm.name AS fund_source_name, " + + " sm.name AS scheme_name, " + + " tm.description AS sub_category, " + + " wtm.name AS category, " + + + " CONCAT('" + fileBaseUrl + "/gcc/files', ew.admin_sanction_file) AS view_admin_sanction_file, " + + " CONCAT('" + fileBaseUrl + "/gcc/files', ew.loa_file) AS view_loa_file, " + + " CONCAT('" + fileBaseUrl + "/gcc/files', ew.agreement_file) AS view_agreement_file, " + + " CONCAT('" + fileBaseUrl + "/gcc/files', ew.work_order_file) AS view_workOrder_file " + + + + " FROM erp_works ew " + + + " LEFT JOIN department_master dm " + + " ON dm.id = ew.department " + + " AND dm.isactive = 1 " + + + "LEFT JOIN fundsource_master fsm " + + " ON fsm.id = ew.fund_source " + + " AND fsm.isactive = 1 " + + + " LEFT JOIN scheme_master sm " + + " ON sm.id = ew.scheme " + + " AND sm.isactive = 1 " + + + " LEFT JOIN typeofwork_master tm " + + " ON tm.id = ew.sub_category " + + " AND tm.isactive = 1 " + + + " LEFT JOIN workstype_master wtm " + + " ON wtm.id = ew.category " + + + " WHERE ew.isactive = 1 " + + " AND ew.isdelete = 0 " + + " AND ew.estid = ? "; + + List> result = jdbcWorksTemplate.queryForList(sql, estid); + + if (result.isEmpty()) { + return null; + } + + return result.get(0); + } + + + + + public List> viewRoadWorks(int estid) { + + String sql = """ + SELECT + ROW_NUMBER() OVER ( + ORDER BY ewt.ref_id + ) AS sl_no, + ewt.estid, + ewt.ref_id, + + SUBSTRING( + txt.road_name, + LOCATE(',', txt.road_name) + 1 + ) AS road_name, + ans.road_type, + ans.work_type, + txt.length, + txt.width, + + COALESCE(etd.percentage, 0) AS physical_percentage, + + CASE + WHEN etd.percentage = 100 + THEN DATE_FORMAT(etd.cdate, '%d-%m-%Y') + ELSE NULL + END AS completion_date, + + CASE + WHEN etd.percentage IS NULL + THEN 'Not Yet Started' + + WHEN etd.percentage = 0 + THEN 'Not Yet Started' + + WHEN etd.percentage = 100 + THEN 'Completed' + + WHEN etd.percentage BETWEEN 1 AND 99 + THEN 'In Progress' + + ELSE 'Not Yet Started' + END AS status + + FROM ( + SELECT DISTINCT + estid, + ref_id, + sub_cat_id + FROM erp_works_task + WHERE estid = ? + AND sub_cat_id = 4 + AND isactive = 1 + AND isdelete = 0 + ) ewt + + /* ========================= + ANSWER QUESTIONS + 4 = Road Type + 5 = Work Type + ========================= */ + LEFT JOIN ( + SELECT + d.estid, + d.ref_id, + + MAX( + CASE + WHEN d.question_id = 4 + THEN a.answer + END + ) AS road_type, + + MAX( + CASE + WHEN d.question_id = 5 + THEN a.answer + END + ) AS work_type + + FROM addworks_details d + + LEFT JOIN addworks_answer_master a + ON a.id = d.answer_id + AND a.isactive = 1 + AND a.isdelete = 0 + + WHERE d.question_id IN (4, 5) + AND d.isactive = 1 + AND d.isdelete = 0 + + GROUP BY + d.estid, + d.ref_id + + ) ans + ON ans.estid = ewt.estid + AND ans.ref_id = ewt.ref_id + + + /* ========================= + TEXT QUESTIONS + 3 = Road Name + 7 = Length + 8 = Width + ========================= */ + LEFT JOIN ( + SELECT + estid, + ref_id, + + MAX( + CASE + WHEN question_id = 3 + THEN answer + END + ) AS road_name, + + MAX( + CASE + WHEN question_id = 7 + THEN answer + END + ) AS length, + + MAX( + CASE + WHEN question_id = 8 + THEN answer + END + ) AS width + + FROM addworks_text_details + + WHERE question_id IN (3, 7, 8) + AND isactive = 1 + AND isdelete = 0 + + GROUP BY + estid, + ref_id + + ) txt + ON txt.estid = ewt.estid + AND txt.ref_id = ewt.ref_id + + + /* ========================= + LATEST TASK DATA + ========================= */ + LEFT JOIN ( + SELECT + x.estid, + x.ref_id, + x.percentage, + x.cdate + + FROM ( + SELECT + td.estid, + td.ref_id, + td.percentage, + td.cdate, + + ROW_NUMBER() OVER ( + PARTITION BY td.estid, td.ref_id + ORDER BY td.cdate DESC, td.tdid DESC + ) AS rn + + FROM erp_task_data td + + WHERE td.isactive = 1 + + ) x + + WHERE x.rn = 1 + + ) etd + ON etd.estid = ewt.estid + AND etd.ref_id = ewt.ref_id + + + ORDER BY + ewt.ref_id + """; + + return jdbcWorksTemplate.queryForList( + sql, + estid + ); + } + + + public List> viewRoadTabDetails(int estid,int ref_id) { + + String sql = """ + SELECT + ROW_NUMBER() OVER ( + ORDER BY ewt.ref_id + ) AS sl_no, + ewt.estid, + ewt.ref_id, + wd.estimation_amount, + DATE_FORMAT(wd.work_commenced_date, '%d-%m-%Y') as work_commenced_date, + UPPER(wd.update_status) as wd_update_status, + wd.percentage as wd_percentage, + CASE + WHEN wd.work_commenced_date IS NOT NULL + AND wd.contractor_period IS NOT NULL + THEN DATE_FORMAT( + DATE_ADD( + wd.work_commenced_date, + INTERVAL wd.contractor_period DAY + ), + '%d-%m-%Y' + ) + ELSE NULL + END AS expected_completion, + + SUBSTRING( + txt.road_name, + LOCATE(',', txt.road_name) + 1 + ) AS road_name, + ans.road_type, + ans.work_type, + txt.length, + txt.width, + txt.azone, + txt.award, + + COALESCE(etd.percentage, 0) AS physical_percentage, + + CASE + WHEN etd.percentage = 100 + THEN DATE_FORMAT(etd.cdate, '%d-%m-%Y') + ELSE NULL + END AS completion_date, + + CASE + WHEN etd.percentage IS NULL + THEN 'Not Yet Started' + + WHEN etd.percentage = 0 + THEN 'Not Yet Started' + + WHEN etd.percentage = 100 + THEN 'Completed' + + WHEN etd.percentage BETWEEN 1 AND 99 + THEN 'In Progress' + + ELSE 'Not Yet Started' + END AS status + + FROM ( + SELECT DISTINCT + estid, + ref_id, + sub_cat_id + FROM erp_works_task + WHERE estid = ? AND ref_id=? + AND sub_cat_id = 4 + AND isactive = 1 + AND isdelete = 0 + ) ewt + + LEFT JOIN works_details wd + ON wd.estid = ewt.estid + AND wd.isactive = 1 + AND wd.isdelete = 0 + + /* ========================= + ANSWER QUESTIONS + 4 = Road Type + 5 = Work Type + ========================= */ + LEFT JOIN ( + SELECT + d.estid, + d.ref_id, + + MAX( + CASE + WHEN d.question_id = 4 + THEN a.answer + END + ) AS road_type, + + MAX( + CASE + WHEN d.question_id = 5 + THEN a.answer + END + ) AS work_type + + FROM addworks_details d + + LEFT JOIN addworks_answer_master a + ON a.id = d.answer_id + AND a.isactive = 1 + AND a.isdelete = 0 + + WHERE d.question_id IN (4, 5) + AND d.isactive = 1 + AND d.isdelete = 0 + + GROUP BY + d.estid, + d.ref_id + + ) ans + ON ans.estid = ewt.estid + AND ans.ref_id = ewt.ref_id + + + /* ========================= + TEXT QUESTIONS + 1 = zone + 2 = ward + 3 = Road Name + 7 = Length + 8 = Width + ========================= */ + LEFT JOIN ( + SELECT + estid, + ref_id, + + MAX( + CASE + WHEN question_id = 3 + THEN answer + END + ) AS road_name, + + MAX( + CASE + WHEN question_id = 7 + THEN answer + END + ) AS length, + + MAX( + CASE + WHEN question_id = 8 + THEN answer + END + ) AS width, + + MAX( + CASE + WHEN question_id=1 + THEN answer + END + ) AS azone, + MAX( + CASE + WHEN question_id=2 + THEN answer + END + ) AS award + + FROM addworks_text_details + + WHERE question_id IN (1,2,3, 7, 8) + AND isactive = 1 + AND isdelete = 0 + + GROUP BY + estid, + ref_id + + ) txt + ON txt.estid = ewt.estid + AND txt.ref_id = ewt.ref_id + + + /* ========================= + LATEST TASK DATA + ========================= */ + LEFT JOIN ( + SELECT + x.estid, + x.ref_id, + x.percentage, + x.cdate + + FROM ( + SELECT + td.estid, + td.ref_id, + td.percentage, + td.cdate, + + ROW_NUMBER() OVER ( + PARTITION BY td.estid, td.ref_id + ORDER BY td.cdate DESC, td.tdid DESC + ) AS rn + + FROM erp_task_data td + + WHERE td.isactive = 1 + + ) x + + WHERE x.rn = 1 + + ) etd + ON etd.estid = ewt.estid + AND etd.ref_id = ewt.ref_id + + + ORDER BY + ewt.ref_id + """; + + return jdbcWorksTemplate.queryForList(sql, estid, ref_id); + } + + public List> viewProgressTabDetails( + int estid, + int ref_id) { + + String sql = " SELECT " + + " td.tdid, " + + " td.estid, " + + " td.ref_id, " + + " td.percentage, " + + " td.stage_file, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', td.stage_file) AS view_stage_file, " + + " DATE_FORMAT(td.cdate, '%d-%m-%Y %H:%i:%s') as cdate," + + " td.cdate, " + + " td.remarks, " + + " td.tmid, " + + " tm.taskname, " + + " tm.orderby " + + " FROM erp_task_data td " + + " INNER JOIN typeofwork_task_master tm " + + " ON tm.tmid = td.tmid " + + " AND tm.isactive = 1 " + + " AND tm.isdelete = 0 " + + " " + + " WHERE td.estid = ? " + + " AND td.ref_id = ? " + + " AND td.isactive = 1 " + + " ORDER BY " + + " tm.orderby DESC, " + + " td.cdate DESC, " + + " td.tdid DESC "; + + return jdbcWorksTemplate.queryForList( + sql, + estid, + ref_id + ); + } + +// using web flow of works project + + public Map getRoadWarDetailsByRoadId(int estid,int ref_id) { + + Map result = new HashMap<>(); + String roadid = null; + + try { + + String findSql=" SELECT SUBSTRING_INDEX(answer, ',', 1) AS road_id FROM addworks_text_details WHERE isactive=1 AND isdelete=0 AND question_id=3 AND estid=? AND ref_id=? "; + + roadid = jdbcWorksTemplate.queryForObject( + findSql, + String.class, + estid, + ref_id + ); + + if(roadid.trim().isEmpty() || roadid==null) { + result.put("status", false); + result.put("message", "Road ID is Empty while returning from addworks_text_details (works)"); + return result; + } + + Integer roadId=Integer.parseInt(roadid); + + System.out.println("roadId==="+roadId); + + String sql = + "SELECT rdm.*,DATE_FORMAT(rdm.cdate, '%d-%m-%Y %r') AS created_date, rtm.road_type As road_type_name,rtmm.roadtype_material as roadtype_material_name,ftm.footpath_type_name as footpath_material_name,ftmr.footpath_type_name as r_footpath_material_name, " + + "fpsm.road_side_name AS footpath_side_name, " + + "swdsm.road_side_name AS swd_side_name, " + + "scpsm.road_side_name AS scp_side_name, " + + "mhsm.road_side_name AS manhole_side_name, " + + "cpsm.road_side_name AS cpipe_side_name, " + + "rwhsm.road_side_name AS rwh_side_name " + + "FROM road_details_master rdm " + + "LEFT JOIN road_type_master rtm ON rtm.id = rdm.road_type " + + "LEFT JOIN roadtype_material_master rtmm ON rtmm.id = rdm.road_type_material " + + "LEFT JOIN footpath_type_master ftm ON ftm.id= rdm.footpath_material " + + "LEFT JOIN footpath_type_master ftmr ON ftmr.id= rdm.r_footpath_material " + + "LEFT JOIN road_side_master fpsm " + + "ON fpsm.id = rdm.footpath_at " + + + "LEFT JOIN road_side_master swdsm " + + "ON swdsm.id = rdm.swd_at " + + + "LEFT JOIN road_side_master scpsm " + + "ON scpsm.id = rdm.scp_at " + + + "LEFT JOIN road_side_master mhsm " + + "ON mhsm.id = rdm.manhole_at " + + + "LEFT JOIN road_side_master cpsm " + + "ON cpsm.id = rdm.cp_at " + + + "LEFT JOIN road_side_master rwhsm " + + "ON rwhsm.id = rdm.rwh_at " + + "WHERE rdm.road_id = ? AND rdm.is_active=1 AND rdm.is_delete=0 "; + + Map road =jdbcRoadWebTemplate.queryForMap(sql, roadId); + + if(road.isEmpty()) { + result.put("status", false); + result.put("message", "Road ID missing in road_details_master in roadwarweb"); + return result; + } + + for (Map.Entry entry : road.entrySet()) { + if (entry.getValue() == null) { + entry.setValue(""); + } + } + + result.putAll(road); + + String road_ref_Id = String.valueOf(road.get("ref_id")); + System.out.println("road_ref_Id>>>>>>."+road_ref_Id); + + List> relayingDetails = + jdbcRoadWebTemplate.queryForList( + " SELECT rd.*,DATE_FORMAT(rd.cdate, '%d-%m-%Y %r') AS created_date,mm.month_name,ym.year_name,rtmm.roadtype_material " + + " FROM relaying_details rd " + + " LEFT JOIN month_master mm on mm.id = rd.relay_month " + + " LEFT JOIN year_master ym on ym.id = rd.relay_year " + + " LEFT JOIN roadtype_material_master rtmm on rtmm.id = rd.road_type_material " + + " WHERE rd.road_ref_id = ? AND rd.is_active=1 AND rd.is_delete=0 ", + road_ref_Id); + + result.put("relayingDetails", relayingDetails); + + List> fileDetails =jdbcRoadWebTemplate.queryForList( + "SELECT *, CONCAT('" + fileBaseUrl + "/gccofficialapp/files',file_path) as file_url " + +" FROM road_master_files " + + " WHERE road_ref_Id = ? AND is_active=1 AND is_delete=0 ", + road_ref_Id); + + for (Map row : fileDetails) { + for (Map.Entry entry : row.entrySet()) { + if (entry.getValue() == null) { + entry.setValue(""); + } + } + } + + result.put("fileDetails", fileDetails); + +// String road_ref_Id = String.valueOf(road.get("road_ref_id")); +// System.out.println("road_ref_Id>>>>>>>>>"+road_ref_Id); + //System.out.println("========Road id========="+roadId); + List> geolocdetails = jdbcRoadWarTemplate.queryForList( + "SELECT *, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', centre_img) AS centre_img_url " + + "FROM centre_street_details " + + "WHERE road_Id = ? AND isactive = 1 AND isdelete = 0", + roadId + ); + // Replace null values with empty string + for (Map row : geolocdetails) { + for (Map.Entry entry : row.entrySet()) { + if (entry.getValue() == null) { + entry.setValue(""); + } + } + } + + result.put("geolocdetails", geolocdetails); + + + result.put("message", "Fetched Details Successfully"); + result.put("status", true); + + } catch (Exception e) { + + result.put("status", false); + result.put("message", e.getMessage()); + + } + + return result; + } + + public Map getRoadWarDetailsByRoadId2( + int estid, + int ref_id) { + + Map result = new HashMap<>(); + + try { + + // ============================== + // 1. Get Road ID from Add Works + // ============================== + + String findSql = """ + SELECT SUBSTRING_INDEX(answer, ',', 1) AS road_id + FROM addworks_text_details + WHERE isactive = 1 + AND isdelete = 0 + AND question_id = 3 + AND estid = ? + AND ref_id = ? + """; + + String roadid = null; + + try { + + roadid = jdbcWorksTemplate.queryForObject( + findSql, + String.class, + estid, + ref_id + ); + + } catch (EmptyResultDataAccessException e) { + + result.put("status", false); + result.put( + "message", + "Road ID is not mapped in addworks_text_details (works)" + ); + + return result; + } + + + if (roadid == null || roadid.trim().isEmpty()) { + + result.put("status", false); + result.put( + "message", + "Road ID is Empty while returning from addworks_text_details (works)" + ); + + return result; + } + + + Integer roadId; + + try { + + roadId = Integer.parseInt(roadid.trim()); + + } catch (NumberFormatException e) { + + result.put("status", false); + result.put( + "message", + "Invalid Road ID mapped in addworks_text_details: " + + roadid + ); + + return result; + } + + + System.out.println("roadId === " + roadId); + + + // ============================== + // 2. Get Road Details + // ============================== + + String sql = + "SELECT rdm.*, " + + "DATE_FORMAT(rdm.cdate, '%d-%m-%Y %r') AS created_date, " + + "rtm.road_type AS road_type_name, " + + "rtmm.roadtype_material AS roadtype_material_name, " + + "ftm.footpath_type_name AS footpath_material_name, " + + "ftmr.footpath_type_name AS r_footpath_material_name, " + + "fpsm.road_side_name AS footpath_side_name, " + + "swdsm.road_side_name AS swd_side_name, " + + "scpsm.road_side_name AS scp_side_name, " + + "mhsm.road_side_name AS manhole_side_name, " + + "cpsm.road_side_name AS cpipe_side_name, " + + "rwhsm.road_side_name AS rwh_side_name " + + + "FROM road_details_master rdm " + + + "LEFT JOIN road_type_master rtm " + + "ON rtm.id = rdm.road_type " + + + "LEFT JOIN roadtype_material_master rtmm " + + "ON rtmm.id = rdm.road_type_material " + + + "LEFT JOIN footpath_type_master ftm " + + "ON ftm.id = rdm.footpath_material " + + + "LEFT JOIN footpath_type_master ftmr " + + "ON ftmr.id = rdm.r_footpath_material " + + + "LEFT JOIN road_side_master fpsm " + + "ON fpsm.id = rdm.footpath_at " + + + "LEFT JOIN road_side_master swdsm " + + "ON swdsm.id = rdm.swd_at " + + + "LEFT JOIN road_side_master scpsm " + + "ON scpsm.id = rdm.scp_at " + + + "LEFT JOIN road_side_master mhsm " + + "ON mhsm.id = rdm.manhole_at " + + + "LEFT JOIN road_side_master cpsm " + + "ON cpsm.id = rdm.cp_at " + + + "LEFT JOIN road_side_master rwhsm " + + "ON rwhsm.id = rdm.rwh_at " + + + "WHERE rdm.road_id = ? " + + "AND rdm.is_active = 1 " + + "AND rdm.is_delete = 0"; + + + List> roadList = + jdbcRoadWebTemplate.queryForList( + sql, + roadId + ); + + + // ============================== + // 3. Road ID not found + // ============================== + + if (roadList.isEmpty()) { + + result.put("status", false); + result.put( + "message", + "No Deatils in Roadwar register" + ); + + return result; + } + + + Map road = roadList.get(0); + + + // ============================== + // 4. Replace null values + // ============================== + + for (Map.Entry entry : road.entrySet()) { + + if (entry.getValue() == null) { + entry.setValue(""); + } + } + + + result.putAll(road); + String road_ref_Id = String.valueOf(road.get("ref_id")); + System.out.println("road_ref_Id>>>>>>."+road_ref_Id); + + List> relayingDetails = + jdbcRoadWebTemplate.queryForList( + " SELECT rd.*,DATE_FORMAT(rd.cdate, '%d-%m-%Y %r') AS created_date,mm.month_name,ym.year_name,rtmm.roadtype_material " + + " FROM relaying_details rd " + + " LEFT JOIN month_master mm on mm.id = rd.relay_month " + + " LEFT JOIN year_master ym on ym.id = rd.relay_year " + + " LEFT JOIN roadtype_material_master rtmm on rtmm.id = rd.road_type_material " + + " WHERE rd.road_ref_id = ? AND rd.is_active=1 AND rd.is_delete=0 ", + road_ref_Id); + + result.put("relayingDetails", relayingDetails); + + List> fileDetails =jdbcRoadWebTemplate.queryForList( + "SELECT *, CONCAT('" + fileBaseUrl + "/gccofficialapp/files',file_path) as file_url " + +" FROM road_master_files " + + " WHERE road_ref_Id = ? AND is_active=1 AND is_delete=0 ", + road_ref_Id); + + for (Map row : fileDetails) { + for (Map.Entry entry : row.entrySet()) { + if (entry.getValue() == null) { + entry.setValue(""); + } + } + } + + result.put("fileDetails", fileDetails); + +// String road_ref_Id = String.valueOf(road.get("road_ref_id")); +// System.out.println("road_ref_Id>>>>>>>>>"+road_ref_Id); + //System.out.println("========Road id========="+roadId); + List> geolocdetails = jdbcRoadWarTemplate.queryForList( + "SELECT *, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', centre_img) AS centre_img_url " + + "FROM centre_street_details " + + "WHERE road_Id = ? AND isactive = 1 AND isdelete = 0", + roadId + ); + // Replace null values with empty string + for (Map row : geolocdetails) { + for (Map.Entry entry : row.entrySet()) { + if (entry.getValue() == null) { + entry.setValue(""); + } + } + } + + result.put("geolocdetails", geolocdetails); + + + result.put("message", "Fetched Details Successfully"); + result.put("status", true); + + } catch (Exception e) { + + result.put("status", false); + result.put("message", e.getMessage()); + + } + + return result; + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2b5d500..7470be5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,2 @@ -spring.profiles.active=prod -#spring.profiles.active=dev +#spring.profiles.active=prod +spring.profiles.active=dev \ No newline at end of file diff --git a/src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html b/src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html new file mode 100644 index 0000000..cbadf5d --- /dev/null +++ b/src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html @@ -0,0 +1,1940 @@ + + + + RoadWarWeb Dashboard Details + + + + + + + + + + + +
+ +
+

Road War Register Dashboard

+

Comprehensive view of all road survey records across Chennai

+
+ +
+
TOTAL ROADS
+
0
+
+ +
+ +
+
+
Filters
+
+ +
+ +
+ + +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ +
+
+ +
+
+ +
+
+
+ + +
+
+ + +
+ +
+ +
+ + Zone-wise Road Count +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + Road Type Count +
+ +
+ +
+ +
+ +
+ +
+ + SWD Availability +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ + Roads Created +
+ +
+ +
+ +
+ + Relaying Timeline +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ Road War Register — Records +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDZONEWARDROAD NAMEAREATYPEMATERIALLENGTH (M)ROW (M)AREA (M²)SWDELEC.ST. LIGHTCULVERTSDETAILS
+ +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/modules/works/dashboard.html b/src/main/resources/templates/modules/works/dashboard.html new file mode 100644 index 0000000..e7afd23 --- /dev/null +++ b/src/main/resources/templates/modules/works/dashboard.html @@ -0,0 +1,2259 @@ + + + + + Works Dashboard + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +

+ Road Works Dashboard +

+ +
+ + + +
+ +
+ +
+ + +
+ + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
+ + + +
+ + + + + +
+ +
+ + + +
+ + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ +
+ + + + + +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ Road Work Summary +
+ +
+ + +
+
+
+ +

+ 0 +

+ +

+ Total Estimates +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Total Road Works +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Total Estimated Value +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Total Work Value +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Completed +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ In Progress +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Not Started +

+ +
+
+
+ + + +
+
+
+ +

+ 0 +

+ +

+ Delayed +

+ +
+
+
+ +
+ +
+ + + +
+ +
+ + +
+ +
+ +
+ +
+ + Road Work Status + +
+ +
+ + +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ + + + + + Completed + + +
+ + 0 + +
+ + +
+ +
+ + + + + + In Progress + + +
+ + 0 + +
+ + +
+ +
+ + + + + + Not Started + + +
+ + 0 + +
+ + +
+ +
+ + + + + + Delayed + + +
+ + 0 + +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + Road Works by Road Type + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+
+
+ + Work Type Analysis + +
+ + +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + Nearing Completion + +
+ + +
+ + +
+ +
+ +
+ +

+ 0 +

+ +

+ Within 15 Days +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

+ 0 +

+ +

+ Within 1 Month +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

0

+ +

Within 3 Months

+ +
+ +
+ +
+ +
+ +
+ +
+ +

+ 0 +

+ +

+ Above 3 Months +

+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + + + + + + + + + + +
+ +
+ +
+ + +
+ + + Delayed Road Works + + +
+ + +
+ + +
+ +
+ +
+ +

+ 0 +

+ +

+ Road Works Exceeded +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

+ 0 +

+ +

+ > 6 Months +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

+ 0 +

+ +

+ > 3 Months +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

+ 0 +

+ +

+ > 1 Month +

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +

+ 0 +

+ +

+ > 15 Days +

+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
S.NoEstimate NoEstimate DateProject NameDepartmentZoneWardsEstimate AmountStatusAction
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/modules/works/estimatedetails.html b/src/main/resources/templates/modules/works/estimatedetails.html new file mode 100644 index 0000000..2790b9a --- /dev/null +++ b/src/main/resources/templates/modules/works/estimatedetails.html @@ -0,0 +1,1095 @@ + + + + + Works Dashboard + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + +

+ + Estimate Information + +

+ + +
+ + + + +
+ Estimate No : +
+ +
+ - +
+ + + + +
+ Estimate Date : +
+ +
+ - +
+ + + + + +
+ Project Name : +
+ +
+ - +
+ + + + +
+ Department : +
+ +
+ - +
+ + + + + +
+ Zone : +
+ +
+ - +
+ + + + +
+ Ward : +
+ +
+ - +
+ + + +
+ Source of Fund : +
+ +
+ - +
+ + + + + +
+ Scheme : +
+ +
+ - +
+ + + + +
+ Category : +
+ +
+ - +
+ + + + + +
+ Sub Category : +
+ +
+ - +
+ + + + +
+ Estimate Amount : +
+ +
+ - +
+ + +
+ +
+ +

+ SANCTIONS & ORDERS +

+ + +
+ + + + +
+ Admin Sanction Date : +
+ +
+ - +
+ + + + +
+ Admin Sanction File : +
+ +
+ - +
+ + + + + +
+ LOA Date : +
+ +
+ - +
+ + + + +
+ LOA File : +
+ +
+ - +
+ + + + + +
+ Agreement Date : +
+ +
+ - +
+ + + + +
+ Agreement File : +
+ +
+ - +
+ + + + + +
+ Work Order Date : +
+ +
+ - +
+ + + + +
+ Work Order File : +
+ +
+ - +
+ + +
+ +
+ + +
+ +
+ + +

+ + Road Works under this Estimate (0 Roads) + +

+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Road / Street NameRoad TypeWork TypeLength (km)Width (km)Physical %StatusAction
Loading road + works...
+ + +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/modules/works/roadworksdetails.html b/src/main/resources/templates/modules/works/roadworksdetails.html new file mode 100644 index 0000000..54c9600 --- /dev/null +++ b/src/main/resources/templates/modules/works/roadworksdetails.html @@ -0,0 +1,2156 @@ + + + + + Works Dashboard + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + +

+ Road Information +

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