Browse Source

Add api in roadwar_web

master
Hariprasath S 1 week ago
parent
commit
90acf1c20f
  1. 13
      src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java
  2. 412
      src/main/java/com/gcc/commissionerreview/service/RoadWarService.java
  3. 539
      src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html

13
src/main/java/com/gcc/commissionerreview/controller/RoadWarApiController.java

@ -176,4 +176,17 @@ public class RoadWarApiController {
); );
} }
@GetMapping("/getrelayingtimelinerecords")
public Map<String, Object> getRelayingTimelineRecords(@RequestParam String timeline,
@RequestParam(required = false) String zone, @RequestParam(required = false) String ward,
@RequestParam(required = false) Integer roadType, @RequestParam(required = false) String swd) {
return roadWarService.getRelayingTimelineRecords(timeline, zone, ward, roadType, swd);
}
@GetMapping("/getRoadWarDetailsByRoadId")
public Map<String, Object> getRoadWarDetailsByRoadId(@RequestParam int roadId){
return roadWarService.getRoadWarDetailsByRoadId(roadId);
}
} }

412
src/main/java/com/gcc/commissionerreview/service/RoadWarService.java

@ -1675,6 +1675,135 @@ public class RoadWarService {
swdCounts.put("notAvailable", swdResult.get("not_available_count")); swdCounts.put("notAvailable", swdResult.get("not_available_count"));
String relayingSql = """
SELECT
SUM(
CASE
WHEN STR_TO_DATE(
CONCAT(
ym.year_name,
'-',
LPAD(rd.relay_month, 2, '0'),
'-01'
),
'%Y-%m-%d'
) >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
THEN 1
ELSE 0
END
) AS within_six_months,
SUM(
CASE
WHEN STR_TO_DATE(
CONCAT(
ym.year_name,
'-',
LPAD(rd.relay_month, 2, '0'),
'-01'
),
'%Y-%m-%d'
) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
AND STR_TO_DATE(
CONCAT(
ym.year_name,
'-',
LPAD(rd.relay_month, 2, '0'),
'-01'
),
'%Y-%m-%d'
) < DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
THEN 1
ELSE 0
END
) AS sixmonths_to_oneyear,
SUM(
CASE
WHEN STR_TO_DATE(
CONCAT(
ym.year_name,
'-',
LPAD(rd.relay_month, 2, '0'),
'-01'
),
'%Y-%m-%d'
) < DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
THEN 1
ELSE 0
END
) AS above_one_year
FROM road_details_master r
INNER JOIN relaying_details rd
ON r.ref_id = rd.road_ref_id
INNER JOIN month_master mm
ON mm.id = rd.relay_month
AND mm.is_active = 1
AND mm.is_delete = 0
INNER JOIN year_master ym
ON ym.id = rd.relay_year
AND ym.is_active = 1
AND ym.is_delete = 0
WHERE r.is_active = 1
AND r.is_delete = 0
AND rd.is_active = 1
AND rd.is_delete = 0
""";
List<Object> relayingParams = new ArrayList<>();
if (zone != null && !zone.trim().isEmpty()) {
relayingSql += " AND r.zone = ? ";
relayingParams.add(zone);
}
if (ward != null && !ward.trim().isEmpty()) {
relayingSql += " AND r.ward = ? ";
relayingParams.add(ward);
}
if (roadType != null) {
relayingSql += " AND r.road_type = ? ";
relayingParams.add(roadType);
}
if (swd != null && !swd.trim().isEmpty()) {
relayingSql +=
" AND LOWER(TRIM(r.is_swd)) = LOWER(?) ";
relayingParams.add(swd);
}
Map<String, Object> relayingResult = jdbcTemplate.queryForMap(relayingSql, relayingParams.toArray());
Map<String, Object> relayingTimeline = new HashMap<>();
relayingTimeline.put("withinSixMonths", relayingResult.get("within_six_months"));
relayingTimeline.put("sixMonthsToOneYear", relayingResult.get("sixmonths_to_oneyear"));
relayingTimeline.put("aboveOneYear", relayingResult.get("above_one_year"));
response.put("relayingTimeline", relayingTimeline);
response.put("status", true); response.put("status", true);
response.put("message", "Dashboard data fetched successfully"); response.put("message", "Dashboard data fetched successfully");
response.put("totalRoads", totalRoads); response.put("totalRoads", totalRoads);
@ -1870,4 +1999,287 @@ public class RoadWarService {
return response; return response;
} }
public Map<String, Object> getRelayingTimelineRecords(String timeline, String zone, String ward,
Integer roadType, String swd) {
Map<String, Object> response = new HashMap<>();
try {
StringBuilder sql = new StringBuilder("""
SELECT
r.ref_id,
r.zone,
r.ward,
r.road_id,
r.road_name,
r.area_name,
r.locality_name,
r.road_type,
rt.road_type AS road_type_name,
r.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,
rd.relay_month,
mm.month_name,
rd.relay_year,
ym.year_name,
rd.remarks
FROM road_details_master r
INNER JOIN relaying_details rd
ON r.ref_id = rd.road_ref_id
LEFT JOIN road_type_master rt
ON rt.id = r.road_type
INNER JOIN month_master mm
ON mm.id = rd.relay_month
AND mm.is_active = 1
AND mm.is_delete = 0
INNER JOIN year_master ym
ON ym.id = rd.relay_year
AND ym.is_active = 1
AND ym.is_delete = 0
WHERE r.is_active = 1
AND r.is_delete = 0
AND rd.is_active = 1
AND rd.is_delete = 0
""");
List<Object> params = new ArrayList<>();
// ------------------------------------
// Dashboard Filters
// ------------------------------------
if (zone != null && !zone.trim().isEmpty()) {
sql.append(" AND r.zone = ? ");
params.add(zone);
}
if (ward != null && !ward.trim().isEmpty()) {
sql.append(" AND r.ward = ? ");
params.add(ward);
}
if (roadType != null) {
sql.append(" AND r.road_type = ? ");
params.add(roadType);
}
if (swd != null && !swd.trim().isEmpty()) {
sql.append("""
AND LOWER(TRIM(r.is_swd)) = LOWER(?)
""");
params.add(swd);
}
// ------------------------------------
// Timeline Filter
// ------------------------------------
String relayDate = """
STR_TO_DATE(
CONCAT(
ym.year_name,
'-',
LPAD(rd.relay_month, 2, '0'),
'-01'
),
'%Y-%m-%d'
)
""";
if ("within6".equalsIgnoreCase(timeline)) {
sql.append("""
AND %s >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
""".formatted(relayDate));
} else if ("sixToOne".equalsIgnoreCase(timeline)) {
sql.append("""
AND %s >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
AND %s < DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
""".formatted(relayDate, relayDate));
} else if ("aboveOne".equalsIgnoreCase(timeline)) {
sql.append("""
AND %s < DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
""".formatted(relayDate));
} else {
response.put("status", false);
response.put("message", "Invalid timeline type");
return response;
}
sql.append("""
ORDER BY
r.zone,
r.ward,
r.road_name
""");
List<Map<String, Object>> records = jdbcTemplate.queryForList(sql.toString(), params.toArray());
response.put("status", true);
response.put("message", "Relaying timeline records fetched successfully");
response.put("data", records);
return response;
} catch (Exception e) {
e.printStackTrace();
response.put("status", false);
response.put("message", "Failed to fetch relaying timeline records");
return response;
}
}
// using web flow of works project
public Map<String, Object> getRoadWarDetailsByRoadId(int roadId) {
Map<String, Object> result = new HashMap<>();
try {
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<String, Object> road =jdbcTemplate.queryForMap(sql, roadId);
for (Map.Entry<String, Object> 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<Map<String, Object>> relayingDetails =
jdbcTemplate.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<Map<String, Object>> fileDetails =jdbcTemplate.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<String, Object> row : fileDetails) {
for (Map.Entry<String, Object> 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<Map<String, Object>> geolocdetails = roadwarjdbcTemplate.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<String, Object> row : geolocdetails) {
for (Map.Entry<String, Object> 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;
}
} }

539
src/main/resources/templates/modules/roadwarweb/roadwarregisterdashboard.html

@ -462,6 +462,67 @@
gap: 3px; gap: 3px;
} }
}
.timeline-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 0;
border-bottom: 1px solid #f0f1f3;
}
.timeline-row:last-child {
border-bottom: none;
}
.timeline-info {
min-width: 0;
}
.timeline-title {
font-size: 14px;
font-weight: 500;
color: #343a40;
margin-bottom: 3px;
}
.timeline-subtitle {
font-size: 12px;
color: #7b8490;
}
.timeline-count {
font-size: 28px;
font-weight: 700;
margin-left: 15px;
}
.timeline-green {
color: #00b878;
}
.timeline-orange {
color: #f59e0b;
}
.timeline-red {
color: #ef4444;
}
.timeline-clickable {
cursor: pointer;
transition: transform 0.15s ease;
}
.timeline-clickable:hover {
transform: scale(1.08);
}
.timeline-clickable:hover {
text-decoration: underline;
} }
</style> </style>
<body> <body>
@ -475,7 +536,7 @@
<div class="total-roads-card"> <div class="total-roads-card">
<div class="total-roads-label">TOTAL ROADS</div> <div class="total-roads-label">TOTAL ROADS</div>
<div class="total-roads-count" id="erpMasterRoads">0</div>
<div class="total-roads-count" id="erpMasterRoads">36807</div>
</div> </div>
</div> </div>
@ -604,14 +665,14 @@
Additional dashboard information can be added here. Additional dashboard information can be added here.
</div> --> </div> -->
<div class="dashboard-card-title mt-3">
<!-- <div class="dashboard-card-title mt-3">
<span></span> <span></span>
Roads Created Roads Created
</div> </div>
<div id="roadsCreated"> <div id="roadsCreated">
<!-- Dynamically populated -->
</div>
</div> -->
<div class="dashboard-card-title mt-3"> <div class="dashboard-card-title mt-3">
<span></span> <span></span>
@ -619,7 +680,7 @@
</div> </div>
<div id="relayingTimeline"> <div id="relayingTimeline">
<!-- Dynamically populated -->
</div> </div>
</div> </div>
@ -650,6 +711,7 @@
<th>ID</th> <th>ID</th>
<th>ZONE</th> <th>ZONE</th>
<th>WARD</th> <th>WARD</th>
<th>ROAD ID</th>
<th>ROAD NAME</th> <th>ROAD NAME</th>
<th>AREA</th> <th>AREA</th>
<th>TYPE</th> <th>TYPE</th>
@ -923,6 +985,74 @@
<div class="modal fade" id="relayingTimelineModal" tabindex="-1"
aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="relayingTimelineModalTitle">
Relaying Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="relayingTimelineLoader" class="text-center py-4"
style="display: none;">
<div class="spinner-border text-primary" role="status"></div>
<div class="mt-2">Please wait...</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered display nowrap w-100" id="relayingTimelineTable">
<thead>
<tr>
<th>S.NO</th>
<th>Zone</th>
<th>Ward</th>
<th>Road Id</th>
<th>Road Name</th>
<th>Area</th>
<th>Locality</th>
<th>Road Type</th>
<th>Length (M)</th>
<th>ROW Width (M)</th>
<th>Area (M²)</th>
<th>SWD</th>
<th>Relay Month</th>
<th>Relay Year</th>
</tr>
</thead>
<tbody id="relayingTimelineTableBody">
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
@ -1073,7 +1203,7 @@ $("#ward, #roadType, #swd").change(function() {
loadDashboard(); loadDashboard();
}); });
function loadOverallCount() {
/* function loadOverallCount() {
$.ajax({ $.ajax({
url: '/commissionerreview/api/roadwarweb/getoverallcount', url: '/commissionerreview/api/roadwarweb/getoverallcount',
@ -1096,7 +1226,7 @@ function loadOverallCount() {
} }
}); });
}
} */
function renderZoneCounts(data) { function renderZoneCounts(data) {
@ -1199,7 +1329,7 @@ function renderRoadTypeCounts(data) {
} }
function renderSwdCounts(data) { function renderSwdCounts(data) {
let container = $("#swdAvailability,#roadsCreated , #relayingTimeline");
let container = $("#swdAvailability");
container.empty(); container.empty();
@ -1234,6 +1364,98 @@ function renderSwdCounts(data) {
`); `);
} }
function renderRelayingTimeline(data) {
let container = $("#relayingTimeline");
container.empty();
let withinSixMonths =
Number(data?.withinSixMonths || 0);
let sixMonthsToOneYear =
Number(data?.sixMonthsToOneYear || 0);
let aboveOneYear =
Number(data?.aboveOneYear || 0);
container.append(`
<div class="timeline-row">
<div class="timeline-info">
<div class="timeline-title">
Within 6 Months
</div>
<div class="timeline-subtitle">
Recently relayed roads
</div>
</div>
<div class="timeline-count timeline-green ${withinSixMonths > 0 ? 'timeline-clickable' : ''}"
data-timeline="within6">
${withinSixMonths}
</div>
</div>
<div class="timeline-row">
<div class="timeline-info">
<div class="timeline-title">
6 Months – 1 Year
</div>
<div class="timeline-subtitle">
Relayed in past year
</div>
</div>
<div class="timeline-count timeline-orange ${sixMonthsToOneYear > 0 ? 'timeline-clickable' : ''}"
data-timeline="sixToOne">
${sixMonthsToOneYear}
</div>
</div>
<div class="timeline-row">
<div class="timeline-info">
<div class="timeline-title">
Above 1 Year
</div>
<div class="timeline-subtitle">
Older relaying records
</div>
</div>
<div class="timeline-count timeline-red ${aboveOneYear > 0 ? 'timeline-clickable' : ''}"
data-timeline="aboveOne">
${aboveOneYear}
</div>
</div>
`);
}
function loadDashboard() { function loadDashboard() {
let zone = $("#zone").val() || ""; let zone = $("#zone").val() || "";
@ -1261,9 +1483,9 @@ function loadDashboard() {
if (response.status) { if (response.status) {
// Total Roads // Total Roads
$("#erpMasterRoads").text(
/* $("#erpMasterRoads").text(
Number(response.totalRoads).toLocaleString() Number(response.totalRoads).toLocaleString()
);
); */
// Zone-wise // Zone-wise
renderZoneCounts( renderZoneCounts(
@ -1280,6 +1502,10 @@ function loadDashboard() {
response.swdCounts response.swdCounts
); );
renderRelayingTimeline(
response.relayingTimeline
);
} else { } else {
console.error(response.message); console.error(response.message);
@ -1382,6 +1608,10 @@ function loadRoadRecords() {
data: "ward", data: "ward",
defaultContent: "-" defaultContent: "-"
}, },
{
data: "road_id",
defaultContent: "-"
},
{ {
data: "road_name", data: "road_name",
defaultContent: "-" defaultContent: "-"
@ -1934,6 +2164,295 @@ function resetRoadDetailsModal() {
} }
$(document).on("click",".timeline-clickable",function () {
let timeline = $(this).data("timeline");
loadRelayingTimelineRecords(timeline);
}
);
function loadRelayingTimelineRecords(timeline) {
let zone = $("#zone").val() || "";
let ward = $("#ward").val() || "";
let roadType = $("#roadType").val() || "";
let swd = $("#swd").val() || "";
let title = "";
if (timeline === "within6") {
title = "Relaying Details — Within 6 Months";
} else if (timeline === "sixToOne") {
title = "Relaying Details — 6 Months to 1 Year";
} else if (timeline === "aboveOne") {
title = "Relaying Details — Above 1 Year";
}
$("#relayingTimelineModalTitle").text(title);
$("#relayingTimelineTableBody").empty();
$("#relayingTimelineLoader").show();
$("#relayingTimelineModal").modal("show");
$.ajax({
url: "/commissionerreview/api/roadwarweb/getrelayingtimelinerecords",
type: "GET",
data: {
timeline: timeline,
zone: zone,
ward: ward,
roadType: roadType,
swd: swd
},
success: function (response) {
$("#relayingTimelineLoader").hide();
if (!response.status) {
$("#relayingTimelineTableBody").html(`
<tr>
<td colspan="13"
class="text-center text-danger">
${response.message || "Failed to load records"}
</td>
</tr>
`);
return;
}
renderRelayingTimelineRecords(
response.data
);
},
error: function (xhr, status, error) {
$("#relayingTimelineLoader").hide();
console.error(
"Error loading relaying timeline:",
error
);
$("#relayingTimelineTableBody").html(`
<tr>
<td colspan="13"
class="text-center text-danger">
Failed to load records.
</td>
</tr>
`);
}
});
}
function renderRelayingTimelineRecords(data) {
let tbody = $("#relayingTimelineTableBody");
// Destroy existing DataTable
if ($.fn.DataTable.isDataTable("#relayingTimelineTable")) {
$("#relayingTimelineTable")
.DataTable()
.destroy();
}
tbody.empty();
if (!data || data.length === 0) {
tbody.html(`
<tr>
<td colspan="13"
class="text-center text-muted">
No records found.
</td>
</tr>
`);
} else {
$.each(data, function(index, item) {
tbody.append(`
<tr>
<td>
${index + 1}
</td>
<td>
${item.zone || "-"}
</td>
<td>
${item.ward || "-"}
</td>
<td>
${item.road_id || "-"}
</td>
<td>
${item.road_name || "-"}
</td>
<td>
${item.area_name || "-"}
</td>
<td>
${item.locality_name || "-"}
</td>
<td>
${item.road_type_name || "-"}
</td>
<td>
${item.road_length ?? "-"}
</td>
<td>
${item.road_row_width ?? "-"}
</td>
<td>
${item.road_area ?? "-"}
</td>
<td>
${renderYesNo(item.is_swd)}
</td>
<td>
${item.month_name || "-"}
</td>
<td>
${item.year_name || "-"}
</td>
</tr>
`);
});
}
// Initialize DataTable AFTER rows are added
initializeRelayingTimelineTable();
}
function initializeRelayingTimelineTable() {
if ($.fn.DataTable.isDataTable("#relayingTimelineTable")) {
$("#relayingTimelineTable")
.DataTable()
.destroy();
}
$("#relayingTimelineTable").DataTable({
pageLength: 50,
lengthMenu: [
[50, 100, 150, 200],
[50, 100, 150, 200]
],
scrollY: "450px",
scrollX: true,
dom: "Bfrtip",
info: true,
ordering: true,
responsive: false,
searching: true,
buttons: [
{
extend: "excelHtml5",
text: "Export Excel",
title: "Relaying Timeline Report",
exportOptions: {
columns: ":visible"
}
},
{
extend: "pdfHtml5",
text: "Export PDF",
title: "Relaying Timeline Report",
orientation: "landscape",
pageSize: "A4",
exportOptions: {
columns: ":visible"
}
}
]
});
}
$('#relayingTimelineModal').on('shown.bs.modal', function () {
if ($.fn.DataTable.isDataTable('#relayingTimelineTable')) {
let questionDatatable = $('#relayingTimelineTable').DataTable();
questionDatatable.columns.adjust().draw();
}
});
</script> </script>
</body> </body>
Loading…
Cancel
Save