Browse Source

food distribution updated code

master
AJITHKUMAR12 10 months ago
parent
commit
ccde722577
  1. 95
      src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java
  2. 226
      src/main/java/com/gcc/commissionerreview/controller/FoodSchemeController.java
  3. 2218
      src/main/java/com/gcc/commissionerreview/service/FoodSchemeService.java
  4. 677
      src/main/resources/templates/modules/food_scheme/driverreport.html
  5. 858
      src/main/resources/templates/modules/food_scheme/feedbackreport.html
  6. 1748
      src/main/resources/templates/modules/food_scheme/foodschemereport.html

95
src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java

@ -0,0 +1,95 @@
package com.gcc.commissionerreview.configuration;
<<<<<<< HEAD
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
=======
import javax.sql.DataSource;
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
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 dbpassword = "gcc-facial-password";
public static class MyDataSourceConfig {
@Primary
@Bean(name = "mydatasource")
<<<<<<< HEAD
=======
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
public DataSource MyDataSource() {
// DriverManagerDataSource dataSource = new DriverManagerDataSource();
// dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
// dataSource.setUrl("jdbc:mysql://"+host+"/dashboard_service");
// dataSource.setUsername("root");
// dataSource.setPassword("root");
// return dataSource;
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://" + host + "/commissioner_review");
// dataSource.setUrl("jdbc:mysql://"+host+"/dashboard_service");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return dataSource;
}
@Primary
@Bean(name = "myTransactionManager")
public PlatformTransactionManager myTransactionManager(@Qualifier("mydatasource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
////////////////////////////// Domestic Waste Management
////////////////////////////// ////////////////////////
@Bean(name = "mysqlSofaBedCollectionDataSource")
public DataSource mysqlSofaBedCollectionDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/domestic_waste_management");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
return dataSource;
}
////////////////////////////// Food distribution ////////////////////////
@Bean(name = "mysqlFoodDistributionDataSource")
public DataSource mysqlFoodDistributionDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_food_distribution");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
return dataSource;
}
////////////////////////////// ORACLE ////////////////////////
@Bean(name = "oracleDataSource")
public DataSource oracleDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:@10.1.0.14:1521:chncorp");
dataSource.setUsername("FAS");
dataSource.setPassword("FAS");
return dataSource;
}
}

226
src/main/java/com/gcc/commissionerreview/controller/FoodSchemeController.java

@ -0,0 +1,226 @@
package com.gcc.commissionerreview.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
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 com.gcc.commissionerreview.service.FoodSchemeService;
@RestController
@RequestMapping("/commissionerreview/api")
public class FoodSchemeController {
@Autowired
private FoodSchemeService foodSchemeService;
/*
* @GetMapping("/feedback-summary")
* public List<Map<String, Object>> getFeedbackSummary(@RequestParam String
* date) {
* return feedbackService.getFeedbackSummary(date);
* }
*
* @GetMapping("/driver-report")
* public List<Map<String, Object>> getDriverReport(@RequestParam String date) {
* //System.out.println("Date received in controller: " + date);
* return feedbackService.getDriverReport(date);
* }
*/
// ak
@GetMapping("/feedback-summary")
public ResponseEntity<?> getFeedbackSummary(@RequestParam String date) {
try {
List<Map<String, Object>> data = foodSchemeService.getFeedbackSummary(date);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", data);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
<<<<<<< HEAD
// ak
@GetMapping("/zone-details")
public ResponseEntity<?> getZoneDetails(
@RequestParam int qid,
@RequestParam String column,
@RequestParam String date) {
try {
List<Map<String, Object>> data = foodSchemeService.getZoneDetails(qid, column, date);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", data);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
@GetMapping("/ward-details")
public ResponseEntity<?> getWardDetails(
@RequestParam int qid,
@RequestParam String column,
@RequestParam String date,
@RequestParam int zoneId) {
return ResponseEntity.ok(Map.of(
"status", "success",
"date", date,
"data", foodSchemeService.getWardDetails(qid, column, date, zoneId)));
}
@GetMapping("/driver-report")
public ResponseEntity<?> getDriverReport(@RequestParam String date, @RequestParam(required = false) Integer zone) {
try {
List<Map<String, Object>> data = foodSchemeService.getDriverReport(date, zone);
=======
@GetMapping("/driver-report")
public ResponseEntity<?> getDriverReport(@RequestParam String date) {
try {
List<Map<String, Object>> data = foodSchemeService.getDriverReport(date);
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", data);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
<<<<<<< HEAD
@GetMapping("/zones")
public ResponseEntity<?> getZones() {
List<Map<String, Object>> data = foodSchemeService.getZones();
return ResponseEntity.ok(Map.of("data", data));
}
=======
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
/// yogi
@GetMapping("/abstract")
public ResponseEntity<?> getAbstractReport(@RequestParam String date) {
try {
List<Map<String, Object>> report = foodSchemeService.getAbstractReport(date);
// System.out.println("report : " + report);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", report);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
@GetMapping("/zoneandshiftbasedreport")
public ResponseEntity<?> getZoneWiseShiftBasedReport(@RequestParam String date, @RequestParam Integer shiftId) {
try {
List<Map<String, Object>> report = foodSchemeService.getZoneWiseShiftBasedReport(date, shiftId);
// System.out.println("report : " + report);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", report);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
<<<<<<< HEAD
@GetMapping("/wardwiseShiftReport")
public ResponseEntity<?> getWardWiseShiftReport(
@RequestParam String date,
@RequestParam Integer shiftId,
@RequestParam Integer zone) {
try {
List<Map<String, Object>> data = foodSchemeService.getWardWiseShiftReport(shiftId, zone, date);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("zone", zone);
response.put("data", data);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
=======
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
@GetMapping("/wardlocationreport")
public ResponseEntity<?> getWardLocationReport(@RequestParam String date) {
try {
List<Map<String, Object>> report = foodSchemeService.getWardLocationWiseReport(date);
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("date", date);
response.put("data", report);
return ResponseEntity.ok(response);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", "error");
error.put("message", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
}

2218
src/main/java/com/gcc/commissionerreview/service/FoodSchemeService.java
File diff suppressed because it is too large
View File

677
src/main/resources/templates/modules/food_scheme/driverreport.html

@ -0,0 +1,677 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Food Scheme Operations Dashboard</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- DataTables CSS -->
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.dataTables.min.css" rel="stylesheet" />
<style>
table.dataTable th,
table.dataTable td {
text-align: center;
vertical-align: middle;
border: 1px solid #000;
}
table.dataTable th {
background-color: #003366 !important;
color: white;
}
.dataTables_wrapper .dt-buttons {
margin-bottom: 10px;
}
.dataTables_filter {
margin-bottom: 25px;
/* adjust as needed */
}
.page-header-title h4 {
margin: 20px 0;
text-align: center;
}
#zoneDetailsTable_wrapper .dataTables_scrollBody {
border: none !important;
}
#zoneDetailsTable td,
#zoneDetailsTable th {
vertical-align: middle;
text-align: center;
white-space: nowrap;
}
<<<<<<< HEAD
.time-column {
white-space: nowrap !important;
}
=======
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
</style>
</head>
<body>
<div class="page-header-title">
<h4>Food Scheme Report</h4>
</div>
<<<<<<< HEAD
<div class="container mt-4">
<div class="card p-3 shadow-sm">
<div class="d-flex justify-content-between">
<h5><strong>Driver Logistics Report</strong></h5>
<!--<div class="d-flex gap-2">
<input type="date" id="driverDate" class="form-control" style="width: 160px;">
<button class="btn btn-primary" onclick="loadDriverReport()">Load Report</button>
<button class="btn btn-success" onclick="goToSchemereport()">
Back
</button>
</div>-->
<div class="d-flex gap-3 align-items-end">
<!-- DATE FIELD -->
<div class="d-flex flex-column">
<label class="form-label fw-bold mb-1">Date</label>
<input type="date" id="driverDate" class="form-control" style="width: 160px;">
</div>
<!-- ZONE FIELD -->
<div class="d-flex flex-column">
<label class="form-label fw-bold mb-1">Zone</label>
<select id="zoneFilter" class="form-control" style="width: 140px;">
<option value="">All Zones</option>
</select>
</div>
<!-- BUTTONS -->
<div class="d-flex gap-2">
<button class="btn btn-primary" onclick="loadDriverReport()">Load Report</button>
<button class="btn btn-success" onclick="goToSchemereport()">Back</button>
</div>
</div>
</div>
<table id="driverReportTable" class="table table-bordered table-hover mt-3 text-center"
style="display:none">
<thead class="table-primary">
<tr>
<th>Zone</th>
<th>Ward</th>
<th>Driver Name</th>
<th>Driver Mobile Number</th>
<th>Location Details</th>
<!-- <th>Current Location of the Driver</th>-->
<th>Start Image</th>
<th>Start Address</th>
<th>Start Time</th>
<th>End Address</th>
<th>End Time</th>
<th>End Image</th>
</tr>
</thead>
<tbody id="driverReportBody">
<!-- Rows inserted dynamically -->
</tbody>
</table>
</div>
</div>
<div class="modal fade" id="imagePreviewModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<!-- CLOSE BUTTON -->
<div class="modal-header border-0">
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center">
<img id="fullImage" src="" style="width: 100%; border-radius: 5px;">
</div>
</div>
</div>
</div>
=======
<div class="container mt-4">
<div class="card p-3 shadow-sm">
<div class="d-flex justify-content-between">
<h5><strong>Driver Logistics Report</strong></h5>
<div class="d-flex gap-2">
<!-- DATE PICKER -->
<input type="date" id="driverDate" class="form-control" style="width: 160px;">
<!-- SHIFT DROPDOWN -->
<!-- <select id="driverShift" class="form-control" style="width: 140px;">
<option value="">Select Shift</option>
<option value="A">Shift A</option>
<option value="B">Shift B</option>
<option value="C">Shift C</option>
</select>-->
<button class="btn btn-primary" onclick="loadDriverReport()">Load Report</button>
<button class="btn btn-success" onclick="goToSchemereport()">
Back
</button>
</div>
</div>
<table id="driverReportTable" class="table table-bordered table-hover mt-3 text-center" style="display:none">
<thead class="table-primary">
<tr>
<th>Driver Name</th>
<th>Driver Mobile Number</th>
<th>Location Description</th>
<!-- <th>Current Location of the Driver</th>-->
<th>Photo of the Vehicle</th>
<th>Start Point</th>
<th>Start Time</th>
<th>End Point</th>
<th>End Time</th>
</tr>
</thead>
<tbody id="driverReportBody">
<!-- Rows inserted dynamically -->
</tbody>
</table>
</div>
</div>
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only"></span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- DataTables JS -->
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<!-- SweetAlert -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<<<<<<< HEAD
<script>
let today = new Date().toISOString().split("T")[0];
document.getElementById("driverDate").setAttribute("max", today);
document.getElementById("driverDate").value = today;
$('#pageLoader').show();
// Auto-load report for today
loadDriverReport();
loadZones();
function goToSchemereport() {
window.location.href = "/commissionerreview/foodSchemeReport";
}
$(document).on("click", ".preview-img", function () {
let imgSrc = $(this).attr("src");
$("#fullImage").attr("src", imgSrc);
$("#imagePreviewModal").modal("show");
});
function loadZones() {
$.ajax({
url: "/commissionerreview/api/zones",
method: "GET",
success: function (res) {
let zones = res.data; // <-- FIXED
let dropdown = $("#zoneFilter");
dropdown.empty();
dropdown.append(`<option value="">All Zones</option>`);
zones.forEach(z => {
dropdown.append(`<option value="${z.zone}">${z.zone}</option>`);
});
}
});
}
function loadDriverReport() {
let date = document.getElementById("driverDate").value;
let zone = $("#zoneFilter").val();
console.log(zone);
if (!date) {
Swal.fire("Required!", "Please select Date", "warning");
return;
}
let tbody = document.getElementById("driverReportBody");
if ($.fn.DataTable.isDataTable("#driverReportTable")) {
$("#driverReportTable").DataTable().clear().destroy();
}
tbody.innerHTML = "";
$.ajax({
url: "/commissionerreview/api/driver-report",
method: "GET",
//data: { date: date },
data: { date: date, zone: zone },
success: function (response) {
$('#pageLoader').hide();
// console.log(response);
// Build table rows
response.data.forEach(d => {
tbody.innerHTML += `
<tr>
<td>${d.Zone || ''}</td>
<td>${d.Ward || ''}</td>
<td>${d.DriverName || ''}</td>
<td>${d.DriverMobile || ''}</td>
<td>${d.LocationDescription || ''}</td>
<td> <img src="${d.StartImage || ''}" width="80" class="img-thumbnail preview-img"></td>
<td>${d.StartAddress || ''}</td>
<td>${d.StartTime || ''}</td>
<td>${d.EndAddress || ''}</td>
<td class="time-column">${d.EndTime || ''}</td>
<td> <img src="${d.EndImage || ''}" width="80" class="img-thumbnail preview-img"></td>
</tr>
`;
});
document.getElementById("driverReportTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#driverReportTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-success btn-sm',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
},
error: function () {
Swal.fire("Error!", "Unable to fetch driver report.", "error");
}
});
}
// Allow TODAY + PAST only (Restrict future)
// Restrict future dates
/*let today = new Date().toISOString().split("T")[0];
document.getElementById("driverDate").setAttribute("max", today);
document.getElementById("driverDate").value = today;
// Auto-load report for today
loadDriverReport();
function loadDriverReport() {
let date = document.getElementById("driverDate").value;
if (!date) {
Swal.fire("Required!", "Please select Date", "warning");
return;
}
let tbody = document.getElementById("driverReportBody");
if ($.fn.DataTable.isDataTable("#driverReportTable")) {
$("#driverReportTable").DataTable().clear().destroy();
}
tbody.innerHTML = "";
$.ajax({
url: "/commissionerreview/api/feedback/driver-report",
method: "GET",
data: { date: date },
success: function(data) {
console.log(data);
// Build table rows
data.forEach(d => {
tbody.innerHTML += `
<tr>
<td>${d.DriverName || ''}</td>
<td>-</td>
<td>${d.LocationDescription || ''}</td>
<td><img src="${d.upload_image_url}" width="80" class="img-thumbnail"></td>
<td>${d.StartPoint || ''}</td>
<td>${d.StartTime || ''}</td>
<td>${d.EndPoint || ''}</td>
<td>${d.EndTime || ''}</td>
</tr>
`;
});
document.getElementById("driverReportTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#driverReportTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-success btn-sm',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
},
error: function() {
Swal.fire("Error!", "Unable to fetch driver report.", "error");
}
});
}*/
=======
<script>
let today = new Date().toISOString().split("T")[0];
document.getElementById("driverDate").setAttribute("max", today);
document.getElementById("driverDate").value = today;
$('#pageLoader').show();
// Auto-load report for today
loadDriverReport();
function goToSchemereport() {
window.location.href = "/commissionerreview/foodSchemeReport";
}
function loadDriverReport() {
let date = document.getElementById("driverDate").value;
if (!date) {
Swal.fire("Required!", "Please select Date", "warning");
return;
}
let tbody = document.getElementById("driverReportBody");
if ($.fn.DataTable.isDataTable("#driverReportTable")) {
$("#driverReportTable").DataTable().clear().destroy();
}
tbody.innerHTML = "";
$.ajax({
url: "/commissionerreview/api/driver-report",
method: "GET",
data: { date: date },
success: function(response) {
$('#pageLoader').hide();
// console.log(response);
// Build table rows
response.data.forEach(d => {
tbody.innerHTML += `
<tr>
<td>${d.DriverName || ''}</td>
<td>-</td>
<td>${d.LocationDescription || ''}</td>
<td><img src="${d.upload_image_url}" width="80" class="img-thumbnail"></td>
<td>${d.StartPoint || ''}</td>
<td>${d.StartTime || ''}</td>
<td>${d.EndPoint || ''}</td>
<td>${d.EndTime || ''}</td>
</tr>
`;
});
document.getElementById("driverReportTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#driverReportTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-success btn-sm',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
},
error: function() {
Swal.fire("Error!", "Unable to fetch driver report.", "error");
}
});
}
// Allow TODAY + PAST only (Restrict future)
// Restrict future dates
/*let today = new Date().toISOString().split("T")[0];
document.getElementById("driverDate").setAttribute("max", today);
document.getElementById("driverDate").value = today;
// Auto-load report for today
loadDriverReport();
function loadDriverReport() {
let date = document.getElementById("driverDate").value;
if (!date) {
Swal.fire("Required!", "Please select Date", "warning");
return;
}
let tbody = document.getElementById("driverReportBody");
if ($.fn.DataTable.isDataTable("#driverReportTable")) {
$("#driverReportTable").DataTable().clear().destroy();
}
tbody.innerHTML = "";
$.ajax({
url: "/commissionerreview/api/feedback/driver-report",
method: "GET",
data: { date: date },
success: function(data) {
console.log(data);
// Build table rows
data.forEach(d => {
tbody.innerHTML += `
<tr>
<td>${d.DriverName || ''}</td>
<td>-</td>
<td>${d.LocationDescription || ''}</td>
<td><img src="${d.upload_image_url}" width="80" class="img-thumbnail"></td>
<td>${d.StartPoint || ''}</td>
<td>${d.StartTime || ''}</td>
<td>${d.EndPoint || ''}</td>
<td>${d.EndTime || ''}</td>
</tr>
`;
});
document.getElementById("driverReportTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#driverReportTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-success btn-sm',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'Driver_Report_' + date,
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
},
error: function() {
Swal.fire("Error!", "Unable to fetch driver report.", "error");
}
});
}*/
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
</script>
</body>
</html>

858
src/main/resources/templates/modules/food_scheme/feedbackreport.html

@ -0,0 +1,858 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Feedback Summary Report</title>
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<<<<<<< HEAD
<style>
table th,
table td {
=======
<!-- DataTables CSS -->
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.dataTables.min.css" rel="stylesheet" />
<style>
table.dataTable th,
table.dataTable td {
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
text-align: center;
vertical-align: middle;
border: 1px solid #000;
}
<<<<<<< HEAD
table th {
=======
table.dataTable th {
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
background-color: #003366 !important;
color: white;
}
.page-header-title h4 {
margin-top: 20px;
text-align: center;
}
<<<<<<< HEAD
.summary-title {
background: #f4a460;
padding: 6px;
font-weight: bold;
margin-top: 30px;
border-radius: 4px;
text-align: center;
}
.tables-row {
display: flex;
justify-content: space-between;
gap: 20px;
}
.table-block {
width: 32%;
}
/* Same column width across all tables */
table td:nth-child(1),
table th:nth-child(1) {
width: 65%;
}
table td:nth-child(2),
table th:nth-child(2) {
width: 35%;
}
/* Bold border above Grand Total */
.total-row td {
border-top: 3px solid black !important;
font-weight: bold;
}
.total-row td {
border-top: 3px solid #000 !important;
border-bottom: 3px solid #000 !important;
/* ADD THIS */
font-weight: bold;
}
#detailModal table tfoot th {
background-color: white !important;
color: black !important;
border-top: 3px solid black !important;
}
#detailModal tfoot tr th {
border-top: 3px solid black !important;
border-bottom: 3px solid black !important;
}
#imagePreviewModal .modal-dialog {
max-width: 300px;
/* you can change this */
}
#wardModal table tfoot tr th {
background-color: white !important;
color: black !important;
font-weight: bold !important;
border-top: 3px solid black !important;
border-bottom: 3px solid black !important;
text-align: center !important;
}
.table img {
display: block;
margin: auto;
padding: 3px;
/* gives spacing so border becomes visible */
border: 1px solid #ccc;
border-radius: 4px;
}
/* FIX COLUMN WIDTHS ONLY INSIDE WARD MODAL */
#wardModal table th:nth-child(1),
#wardModal table td:nth-child(1) {
width: 60px !important;
}
/* Location column */
#wardModal table th:nth-child(2),
#wardModal table td:nth-child(2) {
width: 60px !important;
text-align: left !important;
}
/* Count column */
#wardModal table th:nth-child(3),
#wardModal table td:nth-child(3) {
width: 350px !important;
}
/* Image column */
#wardModal table th:nth-child(4),
#wardModal table td:nth-child(4) {
width: 120px !important;
}
#wardModal table {
border-bottom: 3px solid #000 !important;
}
.export-btn-container {
text-align: right;
margin-bottom: 10px;
}
=======
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
</style>
</head>
<body>
<div class="page-header-title">
<h4><strong>Food Scheme – Feedback Summary</strong></h4>
</div>
<div class="container mt-4">
<div class="card shadow-sm p-3">
<div class="d-flex justify-content-between align-items-center mb-3">
<<<<<<< HEAD
<h5 class="mb-0"><strong>Feedback Summary</strong></h5>
<div class="d-flex align-items-center gap-2">
<input type="date" id="reportDate" class="form-control" style="width: 200px;">
<button class="btn btn-success" onclick="goToSchemereport()">Back</button>
</div>
</div>
<div class="tables-row">
<div class="table-block">
<div class="summary-title">Feedback - Food Distribution Time</div>
<table class="table table-bordered mt-2">
<thead>
<tr>
<th>Category</th>
<th>Count</th>
</tr>
</thead>
<tbody id="tableTime">
</tbody>
</table>
</div>
<div class="table-block">
<div class="summary-title">Feedback - Food Taste</div>
<table class="table table-bordered mt-2">
<thead>
<tr>
<th>Category</th>
<th>Count</th>
</tr>
</thead>
<tbody id="tableTaste"></tbody>
</table>
</div>
<div class="table-block">
<div class="summary-title">Feedback - Food Quantity</div>
<table class="table table-bordered mt-2">
<thead>
<tr>
<th>Category</th>
<th>Count</th>
</tr>
</thead>
<tbody id="tableQuantity"></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="detailModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Feedback Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Dynamic Title -->
<h5 id="modalTitle" class="text-center mb-3"></h5>
<div id="ModalExportContainer" class="mt-2"></div>
<table id="detailModalTable" class="table table-bordered table-hover mt-3 text-center">
<thead>
<tr>
<th>Zone</th>
<th>Count</th>
</tr>
</thead>
<tbody id="modalTableBody"></tbody>
<!-- <tfoot>
<tr>
<th>Grand Total</th>
<th id="modalGrandTotal"></th>
</tr>
</tfoot>-->
</table>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Ward Modal (second popup) -->
<div class="modal fade" id="wardModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<!--<h5 class="modal-title">Ward Details</h5>-->
<h5 class="modal-title" id="wardModalMainTitle">Ward Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<h5 id="wardModalTitle" class="text-center mb-3"></h5>
<table id="wardModalTable" class="table table-bordered table-hover mt-3 text-center">
<thead>
<tr>
<th>S.No</th>
<th>Ward</th>
<th>Location</th>
<th>Image</th>
</tr>
</thead>
<tbody id="wardModalTableBody"></tbody>
<tfoot>
<tr>
<!-- <th></th>
<th>Grand Total</th>
<th id="wardModalGrandTotal"></th>
<th></th>-->
</tr>
</tfoot>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="imagePreviewModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<!-- CLOSE BUTTON -->
<div class="modal-header border-0">
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center">
<img id="fullImage" src="" style="width: 100%; border-radius: 5px;">
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;"></div>
=======
<h5 class="mb-0"><strong>Feedback Questions Summary</strong></h5>
<div class="d-flex align-items-center gap-2">
<input type="date" id="reportDate" class="form-control" style="width: 200px;">
<button class="btn btn-success" onclick="goToSchemereport()">Back</button>
</div>
</div>
<!----------------------- TABLE ------------------------->
<table id="feedbackSummaryTable" class="table table-bordered mt-3">
<thead>
<tr>
<th>Question</th>
<th>Yes Count</th>
<th>No Count</th>
</tr>
</thead>
<tbody id="feedbackSummaryBody"></tbody>
</table>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only"></span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<<<<<<< HEAD
<!-- jQuery -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- DataTables JS -->
=======
<!-- jQuery -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- DataTables -->
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script>
<<<<<<< HEAD
$(document).ready(function () {
$('#pageLoader').show();
=======
$(document).ready(function () {
$('#pageLoader').show();
// Set date picker to today (and restrict future)
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
let today = new Date().toISOString().split("T")[0];
$("#reportDate").val(today);
$("#reportDate").attr("max", today);
<<<<<<< HEAD
loadSummary(today);
$("#reportDate").on("change", function () {
loadSummary(this.value);
});
});
$(document).on("click", ".preview-img", function () {
let imgSrc = $(this).attr("src");
$("#fullImage").attr("src", imgSrc);
$("#imagePreviewModal").modal("show");
});
//excel and pdf
function goToSchemereport() {
window.location.href = "/commissionerreview/foodSchemeReport";
}
$(document).on("click", ".clickable", function () {
let qid = $(this).data("qid");
let column = $(this).data("column");
let count = $(this).data("value");
let date = $("#reportDate").val();
let category = column.replace(/_/g, " ").toUpperCase();
if ($.fn.DataTable.isDataTable("#detailModalTable")) {
$("#detailModalTable").DataTable().clear().destroy();
}
// Title: Question + Category
$("#modalTitle").text("");
$.ajax({
url: "/commissionerreview/api/zone-details",
method: "GET",
data: { qid, column, date },
success: function (res) {
console.log(res);
let rows = res.data;
let tbody = $("#modalTableBody");
tbody.empty();
let grandTotal = 0;
if (rows.length > 0) {
// Set Title
$("#modalTitle").text(rows[0].question + " – " + category);
rows.forEach(r => {
tbody.append(`
<tr>
<td>${r.zone}</td>
<td class="zoneCountClickable"
data-zone="${r.zone}"
data-qid="${qid}"
data-column="${column}"
style="cursor:pointer;color:blue;text-decoration:underline;">
${r.count_value}
</td>
</tr>
`);
grandTotal += r.count_value;
});
}
tbody.append(`
<tr class="total-row">
<td><b>Grand Total</b></td>
<td><b>${grandTotal}</b></td>
</tr>
`);
// Destroy existing DataTable instance if exists
document.getElementById("detailModalTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#detailModalTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'zone_report',
// className: 'btn btn-success btn-sm',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'zone_report',
// className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
new bootstrap.Modal(document.getElementById("detailModal")).show();
}
});
});
$(document).on("click", ".zoneCountClickable", function () {
let zoneId = $(this).data("zone");
let qid = $(this).data("qid");
let column = $(this).data("column");
let date = $("#reportDate").val();
let label = column.replace(/_/g, " ").toUpperCase();
if ($.fn.DataTable.isDataTable("#wardModalTable")) {
$("#wardModalTable").DataTable().clear().destroy();
}
$("#wardModalMainTitle").text("Zone " + zoneId + " – Ward Details");
$.ajax({
url: "/commissionerreview/api/ward-details",
method: "GET",
data: { qid, column, date, zoneId },
success: function (res) {
console.log(res);
let rows = res.data;
let tbody = $("#wardModalTableBody");
tbody.empty();
let grandTotal = 0;
if (rows.length > 0) {
$("#wardModalTitle").text(rows[0].question + " – " + label);
rows.forEach((r, index) => {
tbody.append(`
<tr>
<td>${index + 1}</td>
<td>${r.ward}</td>
<td>${r.location}</td>
<td>
<img src="${r.feedbackImage}" width="80" height="80" class="img-thumbnail preview-img">
</td>
</tr>
`);
});
}
$("#wardModalGrandTotal").text(grandTotal);
document.getElementById("wardModalTable").style.display = "table";
// Reinitialize DataTable WITH PDF & EXCEL
setTimeout(() => {
$("#wardModalTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
title: 'ward_report',
text: 'Download Excel'
},
{
extend: 'pdfHtml5',
title: 'ward_report',
orientation: 'landscape',
pageSize: 'A4',
text: 'Download PDF'
}
]
});
}, 150);
new bootstrap.Modal(document.getElementById("wardModal")).show();
}
});
});
/* $(document).on("click", ".clickable", function () {
let qid = $(this).data("qid");
let column = $(this).data("column");
let count = $(this).data("value");
let date = $("#reportDate").val();
$("#mCategory").text(column.replace(/_/g, " ").toUpperCase());
$("#mCount").text(count);
$.ajax({
url: "/commissionerreview/api/zone-details",
method: "GET",
data: { qid, column, date },
success: function (res) {
console.log("Modal Data:", res);
if (res.data && res.data.length > 0) {
let row = res.data[0];
$("#mZone").text(row.zone);
$("#mQuestion").text(row.question);
} else {
$("#mZone").text("No Data");
$("#mQuestion").text("No Data");
}
new bootstrap.Modal(document.getElementById("detailModal")).show();
}
});
});*/
/* --------------------------------
LOAD 3 FEEDBACK BLOCKS
--------------------------------- */
function loadSummary(date) {
$.ajax({
url: "/commissionerreview/api/feedback-summary",
method: "GET",
data: { date: date },
success: function (response) {
$('#pageLoader').hide();
// Extract the array
let rows = response.data;
// Clear tables
$("#tableTime").empty();
$("#tableTaste").empty();
$("#tableQuantity").empty();
// qid → table mapping
const tableMap = {
1: { body: $("#tableTime"), titleIndex: 0 },
2: { body: $("#tableTaste"), titleIndex: 1 },
3: { body: $("#tableQuantity"), titleIndex: 2 }
};
rows.forEach(row => {
let tbl = tableMap[row.qid];
if (!tbl) return;
// Set dynamic title
$(".summary-title").eq(tbl.titleIndex).text(row.question);
let keys = [];
let total = 0;
// Keys based on qid
if (row.qid === 1) {
keys = ["on_time_distribution", "delayeded"];
} else if (row.qid === 2) {
keys = ["good", "average"];
} else if (row.qid === 3) {
keys = ["sufficient_food_quantity", "less_quantity"];
}
// Add rows
keys.forEach(key => {
let value = row[key];
/* tbl.body.append(`
<tr>
<td>${key.replace(/_/g, " ").toUpperCase()}</td>
<td>${value}</td>
</tr>
`);*/
/*tbl.body.append(`
<tr>
<td>${key.replace(/_/g, " ").toUpperCase()}</td>
<td class="clickable"
data-qid="${row.qid}"
data-column="${key}"
data-value="${value}"
style="cursor:pointer;color:blue;text-decoration:underline;">
${value}
</td>
</tr>
`);*/
let clickableClass = value > 0 ? "clickable" : "";
let clickableStyle = value > 0 ? "cursor:pointer;color:blue;text-decoration:underline;" : "color:black;cursor:default;";
tbl.body.append(`
<tr>
<td>${key.replace(/_/g, " ").toUpperCase()}</td>
<td class="${clickableClass}"
data-qid="${row.qid}"
data-column="${key}"
data-value="${value}"
style="${clickableStyle}">
${value}
</td>
</tr>
`);
total += value;
});
// Add total row
tbl.body.append(`
<tr class="total-row">
<td>Grand Total</td>
<td>${total}</td>
</tr>
`);
});
}
});
}
=======
// Load initial data
loadFeedbackSummary(today);
// On date change
$("#reportDate").on("change", function () {
loadFeedbackSummary(this.value);
});
});
function goToSchemereport() {
window.location.href = "/commissionerreview/foodSchemeReport";
}
/* -------------------------------
LOAD SUMMARY AJAX FUNCTION
--------------------------------*/
function loadFeedbackSummary(date) {
$.ajax({
url: "/commissionerreview/api/feedback-summary",
method: "GET",
data: { date: date },
success: function (response) {
$('#pageLoader').hide();
// console.log("Feedback Summary Data:", response);
// 1. Destroy existing DataTable FIRST
if ($.fn.DataTable.isDataTable("#feedbackSummaryTable")) {
$("#feedbackSummaryTable").DataTable().clear().destroy();
}
// 2. Clear old rows
$("#feedbackSummaryBody").empty();
// 3. Append new rows
// response.forEach(row => {
response.data.forEach(row => {
$("#feedbackSummaryBody").append(`
<tr>
<td>${row.question}</td>
<td class="text-success fw-bold">${row.yes_count}</td>
<td class="text-danger fw-bold">${row.no_count}</td>
</tr>
`);
});
// 4. Initialize DataTable AFTER inserting new rows
$("#feedbackSummaryTable").DataTable({
dom: 'Bfrtip',
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
{
extend: 'excelHtml5',
text: 'Download Excel',
className: 'btn btn-success btn-sm',
title: 'Feedback_Summary_' + date
},
{
extend: 'pdfHtml5',
text: 'Download PDF',
className: 'btn btn-danger btn-sm',
title: 'Feedback_Summary_' + date,
orientation: 'landscape'
}
]
});
}
});
}
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643
</script>
</body>
<<<<<<< HEAD
</html>
=======
</html>
>>>>>>> fabb49a5aeb9c63fb5d5a238dd689811f2cc2643

1748
src/main/resources/templates/modules/food_scheme/foodschemereport.html
File diff suppressed because it is too large
View File

Loading…
Cancel
Save