Browse Source

new changes in food distribution controller, service and pages

master
yoganandhan 6 months ago
parent
commit
4aa4280aa4
  1. 12
      src/main/java/com/gcc/commissionerreview/controller/FoodDistrubutionReportApiController.java
  2. 49
      src/main/java/com/gcc/commissionerreview/service/Fooddistributionservice.java
  3. 86
      src/main/resources/templates/modules/fooddistribution/fooddistributionreport.html

12
src/main/java/com/gcc/commissionerreview/controller/FoodDistrubutionReportApiController.java

@ -36,10 +36,12 @@ public class FoodDistrubutionReportApiController {
@GetMapping("/complianceAbstract") @GetMapping("/complianceAbstract")
public ResponseEntity<Map<String, Object>> getComplianceAbstractReport( public ResponseEntity<Map<String, Object>> getComplianceAbstractReport(
@RequestParam(value = "date", required = false) String date) {
@RequestParam(value = "fromDate", required = false) String fromDate,
@RequestParam(value = "toDate", required = false) String toDate) {
Map<String, Object> response = new HashMap<>(); Map<String, Object> response = new HashMap<>();
try { try {
List<Map<String, Object>> reportData = fooddistributionservice.getComplianceAbstractReport(date);
List<Map<String, Object>> reportData = fooddistributionservice.getComplianceAbstractReport(fromDate,
toDate);
response.put("status", "success"); response.put("status", "success");
response.put("data", reportData); response.put("data", reportData);
} catch (Exception e) { } catch (Exception e) {
@ -51,14 +53,16 @@ public class FoodDistrubutionReportApiController {
@GetMapping("/complianceDetails") @GetMapping("/complianceDetails")
public ResponseEntity<Map<String, Object>> getComplianceDetailedReport( public ResponseEntity<Map<String, Object>> getComplianceDetailedReport(
@RequestParam(value = "date", required = false) String date,
@RequestParam(value = "fromDate", required = false) String fromDate,
@RequestParam(value = "toDate", required = false) String toDate,
@RequestParam("hubId") Integer hubId, @RequestParam("hubId") Integer hubId,
@RequestParam(value = "shiftId", required = false) Integer shiftId, @RequestParam(value = "shiftId", required = false) Integer shiftId,
@RequestParam("qid") Integer qid, @RequestParam("qid") Integer qid,
@RequestParam("statusFilter") String statusFilter) { @RequestParam("statusFilter") String statusFilter) {
Map<String, Object> response = new HashMap<>(); Map<String, Object> response = new HashMap<>();
try { try {
List<Map<String, Object>> detailedData = fooddistributionservice.getComplianceDetailedReport(date, hubId,
List<Map<String, Object>> detailedData = fooddistributionservice.getComplianceDetailedReport(fromDate,
toDate, hubId,
shiftId, qid, statusFilter); shiftId, qid, statusFilter);
response.put("status", "success"); response.put("status", "success");
response.put("data", detailedData); response.put("data", detailedData);

49
src/main/java/com/gcc/commissionerreview/service/Fooddistributionservice.java

@ -26,7 +26,7 @@ public class Fooddistributionservice {
} }
public List<Map<String, Object>> getQuestions() { public List<Map<String, Object>> getQuestions() {
String sql = "SELECT qcm.qcm_id, qcm.audit_category, pqm.qid, pqm.q_english " +
String sql = "SELECT qcm.qcm_id, qcm.audit_category, qcm.code, pqm.qid, pqm.q_english " +
"FROM pmc_questions_master pqm " + "FROM pmc_questions_master pqm " +
"JOIN questions_category_master qcm ON pqm.qcm_id = qcm.qcm_id " + "JOIN questions_category_master qcm ON pqm.qcm_id = qcm.qcm_id " +
"WHERE pqm.isactive = 1 AND pqm.isdelete = 0 AND qcm.isactive = 1 AND qcm.isdelete = 0 " + "WHERE pqm.isactive = 1 AND pqm.isdelete = 0 AND qcm.isactive = 1 AND qcm.isdelete = 0 " +
@ -34,10 +34,16 @@ public class Fooddistributionservice {
return jdbcTemplate.queryForList(sql); return jdbcTemplate.queryForList(sql);
} }
public List<Map<String, Object>> getComplianceAbstractReport(String date) {
public List<Map<String, Object>> getComplianceAbstractReport(String fromDate, String toDate) {
String dateFilter = ""; String dateFilter = "";
if (date != null && !date.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) = ? ";
java.util.List<Object> params = new java.util.ArrayList<>();
if (fromDate != null && !fromDate.trim().isEmpty() && toDate != null && !toDate.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) >= ? AND DATE(pa.audit_date) <= ? ";
params.add(fromDate);
params.add(toDate);
} else if (fromDate != null && !fromDate.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) >= ? ";
params.add(fromDate);
} }
String sql = "SELECT " + String sql = "SELECT " +
@ -46,7 +52,12 @@ public class Fooddistributionservice {
"qcm.qcm_id, qcm.audit_category, " + "qcm.qcm_id, qcm.audit_category, " +
"pqm.qid, pqm.q_english, " + "pqm.qid, pqm.q_english, " +
"pam.english_name AS answer_status, " + "pam.english_name AS answer_status, " +
"COUNT(pf.id) AS issue_count " +
"COUNT(pf.id) AS issue_count, " +
"SUM(CASE WHEN pf.food_swing_sts IS NOT NULL AND pf.food_swing_sts != '' AND pf.food_swing_sts != '-' "
+
"AND pf.fs_remarks IS NOT NULL AND pf.fs_remarks != '' AND pf.fs_remarks != '-' " +
"AND pf.fs_image IS NOT NULL AND pf.fs_image != '' " +
"THEN 1 ELSE 0 END) AS fs_review_count " +
"FROM hub_master hm " + "FROM hub_master hm " +
"CROSS JOIN shift_master sm " + "CROSS JOIN shift_master sm " +
"LEFT JOIN pmc_audit pa ON pa.hub_id = hm.id AND pa.shiftid = sm.shiftid AND pa.isactive = 1 AND pa.isdelete = 0 " "LEFT JOIN pmc_audit pa ON pa.hub_id = hm.id AND pa.shiftid = sm.shiftid AND pa.isactive = 1 AND pa.isdelete = 0 "
@ -62,18 +73,24 @@ public class Fooddistributionservice {
+ +
"ORDER BY hm.id, sm.orderby, qcm.orderby, pqm.orderby"; "ORDER BY hm.id, sm.orderby, qcm.orderby, pqm.orderby";
if (date != null && !date.trim().isEmpty()) {
return jdbcTemplate.queryForList(sql, date);
if (!params.isEmpty()) {
return jdbcTemplate.queryForList(sql, params.toArray());
} else { } else {
return jdbcTemplate.queryForList(sql); return jdbcTemplate.queryForList(sql);
} }
} }
public List<Map<String, Object>> getComplianceDetailedReport(String date, Integer hubId, Integer shiftId,
public List<Map<String, Object>> getComplianceDetailedReport(String fromDate, String toDate, Integer hubId, Integer shiftId,
Integer qid, String status) { Integer qid, String status) {
String dateFilter = ""; String dateFilter = "";
if (date != null && !date.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) = ? ";
java.util.List<Object> params = new java.util.ArrayList<>();
if (fromDate != null && !fromDate.trim().isEmpty() && toDate != null && !toDate.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) >= ? AND DATE(pa.audit_date) <= ? ";
params.add(fromDate);
params.add(toDate);
} else if (fromDate != null && !fromDate.trim().isEmpty()) {
dateFilter = " AND DATE(pa.audit_date) >= ? ";
params.add(fromDate);
} }
String shiftFilter = ""; String shiftFilter = "";
if (shiftId != null && shiftId > 0) { if (shiftId != null && shiftId > 0) {
@ -82,7 +99,7 @@ public class Fooddistributionservice {
String sql = "SELECT " + String sql = "SELECT " +
"pf.id, " + "pf.id, " +
"DATE_FORMAT(pa.audit_date, '%d/%m/%y %H:%i') AS auditDate, " +
"DATE_FORMAT(pa.cdate, '%d/%m/%y %h:%i %p') AS auditDate, " +
"sm.name AS shift, " + "sm.name AS shift, " +
"hm.zone, " + "hm.zone, " +
"hm.ward, " + "hm.ward, " +
@ -97,7 +114,11 @@ public class Fooddistributionservice {
"pf.food_swing_sts AS fsStatus, " + "pf.food_swing_sts AS fsStatus, " +
"dl2.name AS fsChallengedBy, " + "dl2.name AS fsChallengedBy, " +
"pf.fs_remarks AS fsRemarks, " + "pf.fs_remarks AS fsRemarks, " +
"CONCAT('" + fileBaseUrl + "/gccofficialapp/files', pf.fs_image) AS fsVideoLink " +
"CONCAT('" + fileBaseUrl + "/gccofficialapp/files', pf.fs_image) AS fsVideoLink, " +
"IFNULL(pf.ce_sts, '-') AS chief_engineer_status, " +
"IFNULL(pf.ce_remarks, '-') AS chief_engineer_remarks, " +
"CASE WHEN pf.ce_cby = '11930' THEN 'CE' WHEN pf.ce_cby IS NOT NULL AND pf.ce_cby != '' THEN 'SE' ELSE '-' END AS chief_engineer " +
"FROM pmc_feedback pf " + "FROM pmc_feedback pf " +
"JOIN pmc_audit pa ON pa.id = pf.pmc_audit_id AND pa.isactive = 1 AND pa.isdelete = 0 " + dateFilter "JOIN pmc_audit pa ON pa.id = pf.pmc_audit_id AND pa.isactive = 1 AND pa.isdelete = 0 " + dateFilter
+ shiftFilter + + shiftFilter +
@ -111,10 +132,6 @@ public class Fooddistributionservice {
"WHERE pf.isactive = 1 AND pf.isdelete = 0 " + "WHERE pf.isactive = 1 AND pf.isdelete = 0 " +
"ORDER BY pf.id DESC"; "ORDER BY pf.id DESC";
java.util.List<Object> params = new java.util.ArrayList<>();
if (date != null && !date.trim().isEmpty()) {
params.add(date);
}
if (shiftId != null && shiftId > 0) { if (shiftId != null && shiftId > 0) {
params.add(shiftId); params.add(shiftId);
} }

86
src/main/resources/templates/modules/fooddistribution/fooddistributionreport.html

@ -196,14 +196,18 @@
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<div class="page-header-title"> <div class="page-header-title">
<h4>Food Distribution FSSAI Compliance Report</h4>
<h4>Food Distribution Report</h4>
</div> </div>
<!-- Filter Section --> <!-- Filter Section -->
<div class="filter-section d-flex justify-content-center align-items-end gap-3 flex-wrap"> <div class="filter-section d-flex justify-content-center align-items-end gap-3 flex-wrap">
<div> <div>
<label for="filterDate" class="form-label fw-bold">Select Date</label>
<input type="date" id="filterDate" class="form-control">
<label for="fromDate" class="form-label fw-bold">From Date:</label>
<input type="date" id="fromDate" class="form-control">
</div>
<div>
<label for="toDate" class="form-label fw-bold">To Date:</label>
<input type="date" id="toDate" class="form-control">
</div> </div>
<div> <div>
<button id="btnSearch" class="btn btn-primary px-4"><i class="fa-solid fa-search"></i> Search</button> <button id="btnSearch" class="btn btn-primary px-4"><i class="fa-solid fa-search"></i> Search</button>
@ -249,7 +253,7 @@
<table id="modalDataTable" class="table table-bordered table-striped"> <table id="modalDataTable" class="table table-bordered table-striped">
<thead class="table-dark"> <thead class="table-dark">
<tr> <tr>
<th class="text-center">ID</th>
<th class="text-center">S.No</th>
<th class="text-center">Audit Date</th> <th class="text-center">Audit Date</th>
<th class="text-center">Shift</th> <th class="text-center">Shift</th>
<th class="text-center">Zone</th> <th class="text-center">Zone</th>
@ -266,6 +270,9 @@
<th class="text-center">FS Challenged By</th> <th class="text-center">FS Challenged By</th>
<th class="text-center">FS Remarks</th> <th class="text-center">FS Remarks</th>
<th class="text-center">FS Image/Video Viewer</th> <th class="text-center">FS Image/Video Viewer</th>
<th class="text-center">CE Status</th>
<th class="text-center">CE Remarks</th>
<th class="text-center">CE Updated By</th>
</tr> </tr>
</thead> </thead>
<tbody id="modalTableBody"> <tbody id="modalTableBody">
@ -313,13 +320,26 @@
var modalTable = null; var modalTable = null;
$(document).ready(function () { $(document).ready(function () {
// Set default date to yesterday
// Set default dates to yesterday
var yesterday = new Date(); var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1); yesterday.setDate(yesterday.getDate() - 1);
var yyyy = yesterday.getFullYear(); var yyyy = yesterday.getFullYear();
var mm = String(yesterday.getMonth() + 1).padStart(2, '0'); var mm = String(yesterday.getMonth() + 1).padStart(2, '0');
var dd = String(yesterday.getDate()).padStart(2, '0'); var dd = String(yesterday.getDate()).padStart(2, '0');
$('#filterDate').val(yyyy + '-' + mm + '-' + dd);
var defaultDate = yyyy + '-' + mm + '-' + dd;
$('#fromDate').val(defaultDate);
$('#toDate').val(defaultDate);
$('#toDate').attr('min', defaultDate);
$('#fromDate').on('change', function () {
var selectedDate = $(this).val();
$('#toDate').attr('min', selectedDate);
// if toDate is now before fromDate, reset it to fromDate
if ($('#toDate').val() < selectedDate) {
$('#toDate').val(selectedDate);
}
});
// Init modal DT just once // Init modal DT just once
modalTable = $('#modalDataTable').DataTable({ modalTable = $('#modalDataTable').DataTable({
@ -341,7 +361,10 @@
{ width: "120px", targets: 13 }, { width: "120px", targets: 13 },
{ width: "150px", targets: 14 }, { width: "150px", targets: 14 },
{ width: "220px", targets: 15 }, // FS Remarks { width: "220px", targets: 15 }, // FS Remarks
{ width: "150px", targets: 16 }
{ width: "150px", targets: 16 }, // fsImgBtn
{ width: "120px", targets: 17 }, // CE Status
{ width: "220px", targets: 18 }, // CE Remarks
{ width: "150px", targets: 19 } // Chief Engineer
], ],
responsive: false, responsive: false,
scrollX: true, scrollX: true,
@ -377,12 +400,15 @@
// Delegate click for modal details // Delegate click for modal details
$('#ComplianceAbstractTable tbody').on('click', '.clickable-cell', function () { $('#ComplianceAbstractTable tbody').on('click', '.clickable-cell', function () {
var filterDate = $('#filterDate').val() || '';
var fromDate = $('#fromDate').val() || '';
var toDate = $('#toDate').val() || '';
var hubId = $(this).data('hubid'); var hubId = $(this).data('hubid');
var shiftId = $(this).data('shiftid'); var shiftId = $(this).data('shiftid');
var qid = $(this).data('qid'); var qid = $(this).data('qid');
var statusFilter = $(this).data('status'); var statusFilter = $(this).data('status');
var clickedCell = $(this);
if (!hubId || !qid || !statusFilter) return; if (!hubId || !qid || !statusFilter) return;
// Show loading... // Show loading...
@ -392,7 +418,8 @@
url: '/commissionerreview/api/fooddistribution/complianceDetails', url: '/commissionerreview/api/fooddistribution/complianceDetails',
method: 'GET', method: 'GET',
data: { data: {
date: filterDate,
fromDate: fromDate,
toDate: toDate,
hubId: hubId, hubId: hubId,
shiftId: shiftId, shiftId: shiftId,
qid: qid, qid: qid,
@ -428,7 +455,11 @@
var groupedCategories = {}; var groupedCategories = {};
categoryMap.forEach(function (q) { categoryMap.forEach(function (q) {
if (!groupedCategories[q.qcm_id]) { if (!groupedCategories[q.qcm_id]) {
groupedCategories[q.qcm_id] = { name: q.audit_category, questions: [] };
var catName = q.audit_category;
if (q.code && q.code.trim() !== '' && q.code !== 'null') {
catName += ' - ' + q.code;
}
groupedCategories[q.qcm_id] = { name: catName, questions: [] };
} }
groupedCategories[q.qcm_id].questions.push(q); groupedCategories[q.qcm_id].questions.push(q);
}); });
@ -449,7 +480,8 @@
} }
function loadAbstractReport() { function loadAbstractReport() {
var filterDate = $('#filterDate').val() || '';
var fromDate = $('#fromDate').val() || '';
var toDate = $('#toDate').val() || '';
// Show loading // Show loading
Swal.fire({ title: 'Fetching Data...', allowOutsideClick: false, didOpen: function () { Swal.showLoading(); } }); Swal.fire({ title: 'Fetching Data...', allowOutsideClick: false, didOpen: function () { Swal.showLoading(); } });
@ -457,7 +489,7 @@
$.ajax({ $.ajax({
url: '/commissionerreview/api/fooddistribution/complianceAbstract', url: '/commissionerreview/api/fooddistribution/complianceAbstract',
method: 'GET', method: 'GET',
data: { date: filterDate },
data: { fromDate: fromDate, toDate: toDate },
success: function (res) { success: function (res) {
Swal.close(); Swal.close();
if (res.status === 'success') { if (res.status === 'success') {
@ -486,10 +518,14 @@
var tableEl = document.getElementById('ComplianceAbstractTable'); var tableEl = document.getElementById('ComplianceAbstractTable');
// Use SheetJS to convert it purely visually exactly as the screen merges it // Use SheetJS to convert it purely visually exactly as the screen merges it
var wb = XLSX.utils.table_to_book(tableEl, { sheet: "FSSAI Report", raw: true });
var wb = XLSX.utils.table_to_book(tableEl, { sheet: "FSSAI Report", raw: true, display: true });
// Trigger download
XLSX.writeFile(wb, 'Food_Distribution_Compliance.xlsx');
// Get date for file naming
var dFrom = $('#fromDate').val() || 'All_Dates';
var dTo = $('#toDate').val() || 'All_Dates';
// Trigger download with custom date in filename
XLSX.writeFile(wb, 'Food_Distribution_Compliance_' + dFrom + '_to_' + dTo + '.xlsx');
// Restore old page length // Restore old page length
dt.page.len(currentLen).draw(false); dt.page.len(currentLen).draw(false);
@ -554,11 +590,14 @@
var qId = row.qid; var qId = row.qid;
if (qId) { if (qId) {
if (!hubGroups[kId].shifts[shiftId].counts[qId]) { if (!hubGroups[kId].shifts[shiftId].counts[qId]) {
hubGroups[kId].shifts[shiftId].counts[qId] = { 'Issue Found': 0, 'No Issue': 0 };
hubGroups[kId].shifts[shiftId].counts[qId] = { 'Issue Found': 0, 'No Issue': 0, 'fs_review': 0 };
} }
var s = row.answer_status; var s = row.answer_status;
if (s === 'Issue Found' || s === 'No Issue') { if (s === 'Issue Found' || s === 'No Issue') {
hubGroups[kId].shifts[shiftId].counts[qId][s] += row.issue_count; hubGroups[kId].shifts[shiftId].counts[qId][s] += row.issue_count;
if (row.fs_review_count && row.fs_review_count > 0) {
hubGroups[kId].shifts[shiftId].counts[qId]['fs_review'] += row.fs_review_count;
}
} }
} }
}); });
@ -593,10 +632,12 @@
var counts = shift.counts[q.qid] || { 'Issue Found': 0 }; var counts = shift.counts[q.qid] || { 'Issue Found': 0 };
var issueCount = counts['Issue Found'] || 0; var issueCount = counts['Issue Found'] || 0;
var fsRevCount = counts['fs_review'] || 0;
totalIssues += issueCount; totalIssues += issueCount;
questionTotals[q.qid] = (questionTotals[q.qid] || 0) + issueCount; questionTotals[q.qid] = (questionTotals[q.qid] || 0) + issueCount;
var tdIssue = '<td><span class="clickable-cell" data-hubid="' + hub.hub_id + '" data-shiftid="' + shift.shift_id + '" data-qid="' + q.qid + '" data-status="Issue Found">' + (issueCount || '') + '</span></td>';
var textVal = issueCount > 0 ? '<span class="clickable-cell" ' + (fsRevCount > 0 ? 'style="color: red;"' : '') + ' data-hubid="' + hub.hub_id + '" data-shiftid="' + shift.shift_id + '" data-qid="' + q.qid + '" data-status="Issue Found">' + issueCount + '</span>' : '';
var tdIssue = '<td>' + textVal + '</td>';
tr.append(tdIssue); tr.append(tdIssue);
}); });
@ -628,7 +669,7 @@
function populateModal(data) { function populateModal(data) {
modalTable.clear(); modalTable.clear();
data.forEach(function (item) {
data.forEach(function (item, index) {
var ext = item.videoLink ? item.videoLink.split('.').pop().toLowerCase() : ''; var ext = item.videoLink ? item.videoLink.split('.').pop().toLowerCase() : '';
var isVideo = ['mp4', 'mov', 'avi', 'webm', 'mkv'].includes(ext); var isVideo = ['mp4', 'mov', 'avi', 'webm', 'mkv'].includes(ext);
@ -646,9 +687,9 @@
} }
modalTable.row.add([ modalTable.row.add([
item.id,
index + 1,
item.auditDate || '-', item.auditDate || '-',
item.shiftid || '-',
item.shift || '-',
item.zone || '-', item.zone || '-',
item.ward || '-', item.ward || '-',
item.address || '-', item.address || '-',
@ -662,7 +703,10 @@
item.fsStatus || '-', item.fsStatus || '-',
item.fsChallengedBy || '-', item.fsChallengedBy || '-',
item.fsRemarks || '-', item.fsRemarks || '-',
fsImgBtn
fsImgBtn,
item.chief_engineer_status || '-',
item.chief_engineer_remarks || '-',
item.chief_engineer || '-'
]); ]);
}); });
modalTable.draw(); modalTable.draw();

Loading…
Cancel
Save