kanimozhi 10 months ago
parent
commit
82fcea0d7e
  1. 14
      src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java
  2. 70
      src/main/java/com/gcc/commissionerreview/controller/HealthCampController.java
  3. 279
      src/main/java/com/gcc/commissionerreview/service/HealthCampService.java
  4. 1274
      src/main/resources/templates/modules/health_camp/foodschemereport.html
  5. 928
      src/main/resources/templates/modules/healthcamp/abstractreport.html

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

@ -95,4 +95,18 @@ public class DataSourceConfig {
dataSource.setPassword("FAS"); dataSource.setPassword("FAS");
return dataSource; return dataSource;
} }
////////////////////////////// Health Camp ////////////////////////
@Bean(name = "mysqlHealthCampDataSource")
public DataSource mysqlHealthCampDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_health_camp");
dataSource.setUsername("root");
dataSource.setPassword(dbpassword);
return dataSource;
}
} }

70
src/main/java/com/gcc/commissionerreview/controller/HealthCampController.java

@ -0,0 +1,70 @@
package com.gcc.commissionerreview.controller;
import com.gcc.commissionerreview.service.HealthCampService;
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")
public class HealthCampController {
@Autowired
private HealthCampService healthCampService ;
@GetMapping("/zonewise")
public ResponseEntity<Map<String, Object>> getHealthCampAbstract(
@RequestParam(value = "date", required = false) String date,
@RequestParam(value = "zone", required = false) String zone) {
List<Map<String, Object>> data =
healthCampService.getZoneWiseHealthCampReport(date, zone);
return ResponseEntity.ok(Map.of(
"status", "success",
"data", data
));
}
@GetMapping("/wardwise")
public ResponseEntity<Map<String, Object>> getWardWiseReport(
@RequestParam (value = "date", required = false)String date,
@RequestParam (value = "zone", required = false) String zone
) {
List<Map<String, Object>> data =
healthCampService.getWardWiseHealthCampReport(date, zone);
return ResponseEntity.ok(Map.of(
"status", "success",
"data", data
));
}
@GetMapping("/patientdetails")
public ResponseEntity<Map<String, Object>> getPatientDetails(
@RequestParam String ward,
@RequestParam String date
) {
return ResponseEntity.ok(Map.of(
"status", "success",
"data", healthCampService.getPatientDetailsByWard(ward, date)
));
}
}

279
src/main/java/com/gcc/commissionerreview/service/HealthCampService.java

@ -0,0 +1,279 @@
package com.gcc.commissionerreview.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class HealthCampService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
public void setFeedbackDataSource(@Qualifier("mysqlHealthCampDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List<Map<String, Object>> getZoneWiseHealthCampReport(String date, String zone) {
StringBuilder sql = new StringBuilder("""
SELECT
cd.zone,
COUNT(DISTINCT cd.id) AS no_of_camps,
/* Camp type counts */
SUM(cd.camp_type_id = 1) AS monsoon_standard_camp_count,
SUM(cd.camp_type_id = 2) AS special_medical_camp_count,
SUM(cd.camp_type_id = 3) AS outreach_camp_count,
/* Age & Gender counts */
SUM(pd.pt_age > 0 AND pd.pt_age <= 10 AND pd.pt_gender_id = 1) AS age_0_10_male,
SUM(pd.pt_age > 0 AND pd.pt_age <= 10 AND pd.pt_gender_id = 2) AS age_0_10_female,
SUM(pd.pt_age > 0 AND pd.pt_age <= 10 AND pd.pt_gender_id = 3) AS age_0_10_transgender,
SUM(pd.pt_age > 10 AND pd.pt_age <= 40 AND pd.pt_gender_id = 1) AS age_11_40_male,
SUM(pd.pt_age > 10 AND pd.pt_age <= 40 AND pd.pt_gender_id = 2) AS age_11_40_female,
SUM(pd.pt_age > 10 AND pd.pt_age <= 40 AND pd.pt_gender_id = 3) AS age_11_40_transgender,
SUM(pd.pt_age > 40 AND pd.pt_age <= 60 AND pd.pt_gender_id = 1) AS age_41_60_male,
SUM(pd.pt_age > 40 AND pd.pt_age <= 60 AND pd.pt_gender_id = 2) AS age_41_60_female,
SUM(pd.pt_age > 40 AND pd.pt_age <= 60 AND pd.pt_gender_id = 3) AS age_41_60_transgender,
SUM(pd.pt_age > 60 AND pd.pt_gender_id = 1) AS age_61_above_male,
SUM(pd.pt_age > 60 AND pd.pt_gender_id = 2) AS age_61_above_female,
SUM(pd.pt_age > 60 AND pd.pt_gender_id = 3) AS age_61_above_transgender,
COUNT(pd.id) AS total_beneficiaries,
/* Disease counts (pre-aggregated per patient) */
SUM(IFNULL(dd.ANC, 0)) AS ANC,
SUM(IFNULL(dd.PN, 0)) AS PN,
SUM(IFNULL(dd.FEVER, 0)) AS FEVER,
SUM(IFNULL(dd.Cough_Cold, 0)) AS Cough_Cold,
SUM(IFNULL(dd.ILI, 0)) AS ILI,
SUM(IFNULL(dd.ADD_, 0)) AS ADD_,
SUM(IFNULL(dd.Skin_Infections, 0)) AS Skin_Infections,
SUM(IFNULL(dd.DM, 0)) AS DM,
SUM(IFNULL(dd.HTN, 0)) AS HTN,
SUM(IFNULL(dd.DM_HTN, 0)) AS DM_HTN,
SUM(IFNULL(dd.Animal_Insect_Bite, 0)) AS Animal_Insect_Bite,
SUM(IFNULL(dd.Injuries, 0)) AS Injuries,
SUM(IFNULL(dd.Other_Cases, 0)) AS Other_Cases
FROM camp_details cd
LEFT JOIN patient_details pd
ON cd.id = pd.camp_id
LEFT JOIN (
SELECT
patient_id,
SUM(disease_id = 1) AS ANC,
SUM(disease_id = 2) AS PN,
SUM(disease_id = 3) AS FEVER,
SUM(disease_id = 4) AS Cough_Cold,
SUM(disease_id = 5) AS ILI,
SUM(disease_id = 6) AS ADD_,
SUM(disease_id = 7) AS Skin_Infections,
SUM(disease_id = 8) AS DM,
SUM(disease_id = 9) AS HTN,
SUM(disease_id = 10) AS DM_HTN,
SUM(disease_id = 11) AS Animal_Insect_Bite,
SUM(disease_id = 12) AS Injuries,
SUM(disease_id = 13) AS Other_Cases
FROM diseases_details
GROUP BY patient_id
) dd
ON pd.patient_id = dd.patient_id
WHERE 1 = 1
""");
List<Object> params = new ArrayList<>();
if (date != null && !date.isBlank()) {
sql.append("""
AND cd.cdate >= ?
AND cd.cdate < DATE_ADD(?, INTERVAL 1 DAY)
""");
params.add(date);
params.add(date);
}
if (zone != null && !zone.isBlank()) {
sql.append(" AND cd.zone = ? ");
params.add(zone);
}
sql.append("""
GROUP BY cd.zone
ORDER BY cd.zone
""");
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
}
public List<Map<String, Object>> getWardWiseHealthCampReport(String date, String zone) {
StringBuilder sql = new StringBuilder("""
SELECT
cd.ward,cd.zone,
/* Camps */
COUNT(DISTINCT cd.id) AS no_of_camps,
SUM(cd.camp_type_id = 1) AS monsoon_standard_camp_count,
SUM(cd.camp_type_id = 2) AS special_medical_camp_count,
SUM(cd.camp_type_id = 3) AS outreach_camp_count,
/* AGE 0–10 */
SUM(pd.pt_age BETWEEN 1 AND 10 AND pd.pt_gender_id = 1) AS age_0_10_male,
SUM(pd.pt_age BETWEEN 1 AND 10 AND pd.pt_gender_id = 2) AS age_0_10_female,
SUM(pd.pt_age BETWEEN 1 AND 10 AND pd.pt_gender_id = 3) AS age_0_10_transgender,
/* AGE 11–40 */
SUM(pd.pt_age BETWEEN 11 AND 40 AND pd.pt_gender_id = 1) AS age_11_40_male,
SUM(pd.pt_age BETWEEN 11 AND 40 AND pd.pt_gender_id = 2) AS age_11_40_female,
SUM(pd.pt_age BETWEEN 11 AND 40 AND pd.pt_gender_id = 3) AS age_11_40_transgender,
/* AGE 41–60 */
SUM(pd.pt_age BETWEEN 41 AND 60 AND pd.pt_gender_id = 1) AS age_41_60_male,
SUM(pd.pt_age BETWEEN 41 AND 60 AND pd.pt_gender_id = 2) AS age_41_60_female,
SUM(pd.pt_age BETWEEN 41 AND 60 AND pd.pt_gender_id = 3) AS age_41_60_transgender,
/* AGE 61+ */
SUM(pd.pt_age >= 61 AND pd.pt_gender_id = 1) AS age_61_above_male,
SUM(pd.pt_age >= 61 AND pd.pt_gender_id = 2) AS age_61_above_female,
SUM(pd.pt_age >= 61 AND pd.pt_gender_id = 3) AS age_61_above_transgender,
/* Beneficiaries */
COUNT(DISTINCT pd.id) AS total_beneficiaries,
/* Diseases (pre-aggregated per patient) */
SUM(IFNULL(dd.ANC,0)) AS ANC,
SUM(IFNULL(dd.PN,0)) AS PN,
SUM(IFNULL(dd.FEVER,0)) AS FEVER,
SUM(IFNULL(dd.Cough_Cold,0)) AS Cough_Cold,
SUM(IFNULL(dd.ILI,0)) AS ILI,
SUM(IFNULL(dd.ADD_,0)) AS ADD_,
SUM(IFNULL(dd.Skin_Infections,0)) AS Skin_Infections,
SUM(IFNULL(dd.DM,0)) AS DM,
SUM(IFNULL(dd.HTN,0)) AS HTN,
SUM(IFNULL(dd.DM_HTN,0)) AS DM_HTN,
SUM(IFNULL(dd.Animal_Insect_Bite,0)) AS Animal_Insect_Bite,
SUM(IFNULL(dd.Injuries,0)) AS Injuries,
SUM(IFNULL(dd.others,0)) AS others
FROM camp_details cd
LEFT JOIN patient_details pd
ON pd.camp_id = cd.id
LEFT JOIN (
SELECT
patient_id,
SUM(disease_id = 1) AS ANC,
SUM(disease_id = 2) AS PN,
SUM(disease_id = 3) AS FEVER,
SUM(disease_id = 4) AS Cough_Cold,
SUM(disease_id = 5) AS ILI,
SUM(disease_id = 6) AS ADD_,
SUM(disease_id = 7) AS Skin_Infections,
SUM(disease_id = 8) AS DM,
SUM(disease_id = 9) AS HTN,
SUM(disease_id = 10) AS DM_HTN,
SUM(disease_id = 11) AS Animal_Insect_Bite,
SUM(disease_id = 12) AS Injuries,
SUM(disease_id = 13) AS others
FROM diseases_details
GROUP BY patient_id
) dd ON dd.patient_id = pd.patient_id
WHERE 1 = 1
""");
List<Object> params = new ArrayList<>();
/* ZONE FILTER */
if (zone != null && !zone.isBlank()) {
sql.append(" AND cd.zone = ? ");
params.add(zone);
}
/* DATE FILTER (works for DATETIME column) */
if (date != null && !date.isBlank()) {
sql.append("""
AND cd.cdate >= ?
AND cd.cdate < DATE_ADD(?, INTERVAL 1 DAY)
""");
params.add(date);
params.add(date);
}
sql.append("""
GROUP BY cd.ward
ORDER BY cd.ward
""");
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
}
public List<Map<String, Object>> getPatientDetailsByWard(
String ward,
String date
) {
String sql = """
SELECT
cd.zone,
cd.ward,
DATE_FORMAT(cd.cdate, '%d-%m-%Y') AS cdate,
pd.pt_name,
pd.pt_age,
pd.pt_mob_no,
pd.pt_address,
pd.remarks,
gm.gender
FROM camp_details cd
LEFT JOIN patient_details pd
ON pd.camp_id = cd.id
LEFT JOIN gender_master gm
ON gm.id=pd.pt_gender_id
WHERE cd.ward = ?
AND cd.cdate >= ?
AND cd.cdate < DATE_ADD(?, INTERVAL 1 DAY)
ORDER BY pd.pt_name
""";
return jdbcTemplate.queryForList(
sql,
ward,
date,
date
);
}
}

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

928
src/main/resources/templates/modules/healthcamp/abstractreport.html

@ -0,0 +1,928 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Health Camp 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>
.page-header-title h4 {
margin: 20px 0;
text-align: center;
}
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;
}
#exportContainerzoneshift .dt-buttons {
display: flex;
gap: 8px;
}
#exportContainerzoneshift .btn {
height: 38px;
padding: 6px 14px;
}
#wardExportContainer .dt-buttons {
display: flex;
gap: 8px;
}
#wardExportContainer .btn {
height: 38px;
padding: 6px 14px;
}
#exportContainerpatientwise .dt-buttons {
display: flex;
gap: 8px;
}
#exportContainerpatientwise .btn {
height: 38px;
padding: 6px 14px;
}
td.date-col,
th.date-col {
white-space: nowrap !important;
}
</style>
</head>
<body>
<div class="page-header-title">
<h4>Health Camp Report</h4>
</div>
<div class="container mt-4">
<div class="row g-4">
<div class="col-md-12">
<div class="card p-3 shadow-sm ">
<div class="d-flex justify-content-between align-items-center mb-3">
<!-- LEFT: TITLE + EXPORT -->
<div class="d-flex align-items-center gap-3 flex-wrap">
<h5 class="mb-0 fw-bold">Zone wise Overallview</h5>
</div>
<!-- RIGHT: FILTERS -->
<div class="d-flex align-items-end gap-3 flex-wrap">
<!-- Zone -->
<div class="d-flex flex-column">
<label class="form-label fw-bold mb-1">Zone</label>
<select id="zoneFilter" class="form-control" style="min-width: 160px;">
<option value="">All Zones</option>
</select>
</div>
<!-- Date -->
<div class="d-flex flex-column">
<label class="form-label fw-bold mb-1">Date</label>
<input type="date" id="reportDate" class="form-control" style="min-width: 160px;">
</div>
<!-- Button -->
<button class="btn btn-primary mt-auto px-4" onclick="loadDriverReport()">
Load Report
</button>
</div>
</div>
<div class="mb-3">
<div id="exportContainerzoneshift" class="d-flex gap-2"></div>
</div>
<div class="table-responsive mt-3">
<table id="zoneandshiftSummaryTable"
class="table table-bordered table-hover text-center w-100">
<thead class="table-primary">
<tr>
<th rowspan="2" class="text-center">S.No</th>
<th rowspan="2" class="text-center">Zone</th>
<th rowspan="2" class="text-center">No of Camps</th>
<th rowspan="2" class="text-center">Monsoon Standard Camp</th>
<th rowspan="2" class="text-center">Special Medical Camp</th>
<th rowspan="2" class="text-center">Outreach Camp</th>
<th colspan="3" class="text-center">Age 0–10</th>
<th colspan="3" class="text-center">Age 11–40</th>
<th colspan="3" class="text-center">Age 41–60</th>
<th colspan="3" class="text-center">Age 61+</th>
<th rowspan="2">Total Beneficiaries</th>
<th rowspan="2" class="text-center">ANC</th>
<th rowspan="2" class="text-center">PN</th>
<th rowspan="2" class="text-center">Fever</th>
<th rowspan="2" class="text-center">Cough/Cold</th>
<th rowspan="2" class="text-center">ILI</th>
<th rowspan="2" class="text-center">ADD</th>
<th rowspan="2" class="text-center">Skin Infection</th>
<th rowspan="2" class="text-center">DM</th>
<th rowspan="2" class="text-center">HTN</th>
<th rowspan="2" class="text-center">DM & HTN</th>
<th rowspan="2" class="text-center">Animal/Insect Bite</th>
<th rowspan="2" class="text-center">Injuries</th>
<th rowspan="2" class="text-center">Other Cases</th>
<!-- <th rowspan="2">Total Beneficiaries</th>-->
</tr>
<tr>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Ward Wise Modal -->
<div class="modal fade" id="wardModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title fw-bold">
Ward Wise Health Camp Report – Zone <span id="modalZone"></span>
</h5>
<button type="button" class="btn-close btn-close-white"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- EXPORT BUTTONS -->
<div class="d-flex justify-content-left mb-2">
<div id="wardExportContainer" class="d-flex gap-2"></div>
</div>
<table id="wardSummaryTable"
class="table table-bordered table-hover text-center w-100">
<thead class="table-primary">
<tr>
<th rowspan="2" class="text-center">S.No</th>
<th rowspan="2" class="text-center">Zone</th>
<th rowspan="2" class="text-center">Ward</th>
<th rowspan="2" class="text-center">No of Camps</th>
<th rowspan="2" class="text-center">Monsoon Standard Camp</th>
<th rowspan="2" class="text-center">Special Medical Camp</th>
<th rowspan="2" class="text-center">Outreach Camp</th>
<th colspan="3" class="text-center">Age 0–10</th>
<th colspan="3" class="text-center">Age 11–40</th>
<th colspan="3" class="text-center">Age 41–60</th>
<th colspan="3" class="text-center">Age 61+</th>
<th rowspan="2">Total Beneficiaries</th>
<th rowspan="2" class="text-center">ANC</th>
<th rowspan="2" class="text-center">PN</th>
<th rowspan="2" class="text-center">Fever</th>
<th rowspan="2" class="text-center">Cough/Cold</th>
<th rowspan="2" class="text-center">ILI</th>
<th rowspan="2" class="text-center">ADD</th>
<th rowspan="2" class="text-center">Skin</th>
<th rowspan="2" class="text-center">DM</th>
<th rowspan="2" class="text-center">HTN</th>
<th rowspan="2" class="text-center">DM & HTN</th>
<th rowspan="2" class="text-center">Animal Bite</th>
<th rowspan="2" class="text-center">Injuries</th>
<th rowspan="2" class="text-center">Other Cases</th>
<!-- <th rowspan="2" class="text-center">Total Beneficiaries</th>-->
</tr>
<tr>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
<th>Male</th><th>Female</th><th>Transgender</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Patient Details Modal -->
<div class="modal fade" id="patientModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h5 class="modal-title fw-bold">
Patient Details – Zone <span id="pZone"></span>,
Ward <span id="pWard"></span>
</h5>
<button type="button" class="btn-close btn-close-white"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="d-flex justify-content-left mb-2">
<div id="exportContainerpatientwise" class="d-flex gap-2"></div>
</div>
<table id="patientTable"
class="table table-bordered table-hover text-center w-100">
<thead class="table-primary">
<tr>
<th class="text-center">S.No</th>
<th class="text-center">Date</th>
<th class="text-center">Zone</th>
<th class="text-center">Ward</th>
<th class="text-center">Patient Name</th>
<th class="text-center">Age</th>
<th class="text-center">Gender</th>
<th class="text-center" width="300px;">Address</th>
<th class="text-center">Mobile Number</th>
<th class="text-center" width="500px;">Remarks</th>
</tr>
</thead>
<tbody></tbody>
</table>
</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" 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>
<script>
let zoneTable;
$(document).ready(function () {
const today = new Date().toISOString().split("T")[0];
$("#reportDate").val(today).attr("max", today);
zoneTable = $('#zoneandshiftSummaryTable').DataTable({
paging: false,
searching: false,
ordering: false,
info: false,
scrollX: true,
scrollY: "60vh",
scrollCollapse: true,
dom: 'Bfrtip',
buttons: [
/* ================= EXCEL EXPORT ================= */
{
extend: 'excelHtml5',
text: 'Download Excel',
className: 'btn btn-success btn-sm',
exportOptions: {
format: {
header: function (data, columnIdx) {
const headers = [
'S.No', 'Zone', 'No of Camps',
'Monsoon Standard Camp', 'Special', 'Outreach',
'Age 0–10 Male', 'Age 0–10 Female', 'Age 0–10 Transgender',
'Age 11–40 Male', 'Age 11–40 Female', 'Age 11–40 Transgender',
'Age 41–60 Male', 'Age 41–60 Female', 'Age 41–60 Transgender',
'Age 61+ Male', 'Age 61+ Female', 'Age 61+ Transgender','Total Beneficiaries',
'ANC','PN','Fever','Cough / Cold','ILI','ADD',
'Skin','DM','HTN','DM & HTN','Animal Bite','Injuries','Other Cases',
];
return headers[columnIdx];
}
}
},
title: function () {
const zone = $('#zoneFilter').val() || 'All Zones';
const date = $('#reportDate').val();
return `Zone Wise Health Camp Report - ${zone} - ${date}`;
},
messageTop: function () {
const zone = $('#zoneFilter').val() || 'All Zones';
const date = $('#reportDate').val();
return `Zone : ${zone}\nDate : ${date}`;
}
},
/* ================= PDF EXPORT ================= */
{
extend: 'pdfHtml5',
text: 'Download PDF',
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A2',
title: '',
exportOptions: {
format: {
header: function (data, columnIdx) {
const headers = [
'S.No', 'Zone', 'No of Camps',
'Monsoon Standard Camp', 'Special', 'Outreach',
'Age 0–10 Male', 'Age 0–10 Female', 'Age 0–10 Transgender',
'Age 11–40 Male', 'Age 11–40 Female', 'Age 11–40 Transgender',
'Age 41–60 Male', 'Age 41–60 Female', 'Age 41–60 Transgender',
'Age 61+ Male', 'Age 61+ Female', 'Age 61+ Transgender','Total Beneficiaries',
'ANC','PN','Fever','Cough / Cold','ILI','ADD',
'Skin','DM','HTN','DM & HTN','Animal Bite','Injuries','Other Cases',
];
return headers[columnIdx];
}
}
},
customize: function (doc) {
const zone = $('#zoneFilter').val() || 'All Zones';
const date = $('#reportDate').val();
/* -------- HEADER -------- */
doc.content.unshift({
margin: [0, 0, 0, 12],
alignment: 'center',
text: [
{ text: 'Zone Wise Health Camp Report\n', fontSize: 16, bold: true },
{ text: 'Zone : ' + zone + '\n', fontSize: 12 },
{ text: 'Date : ' + date, fontSize: 11 }
]
});
/* -------- TABLE HEADER STYLE -------- */
doc.styles.tableHeader = {
bold: true,
fontSize: 12,
color: 'white',
fillColor: '#003366',
alignment: 'center'
};
/* -------- TABLE BODY FONT -------- */
doc.defaultStyle.fontSize = 10;
/* -------- FOOTER -------- */
doc.footer = function (currentPage, pageCount) {
return {
alignment: 'center',
fontSize: 9,
text: [
'Page ', currentPage.toString(),
' of ', pageCount.toString()
]
};
};
}
}
]
});
// Move buttons to your container
zoneTable.buttons().container().appendTo('#exportContainerzoneshift');
loadZones();
loadReport(today);
});
/* ---------------- LOAD ZONES ---------------- */
function loadZones() {
$.get("/commissionerreview/api/zones", function (res) {
const dropdown = $("#zoneFilter");
dropdown.empty().append(`<option value="">All Zones</option>`);
res.data.forEach(z => {
dropdown.append(`<option value="${z.zone}">${z.zone}</option>`);
});
});
}
/* ---------------- LOAD REPORT ---------------- */
function loadReport(date, zone = "") {
$('#pageLoader').show();
let url = `/commissionerreview/api/zonewise?date=${date}`;
if (zone) url += `&zone=${zone}`;
fetch(url)
.then(res => res.json())
.then(json => {
console.log("Zonewise Report Data:", json);
$('#pageLoader').hide();
if (json.status === "success") {
populateTable(json.data);
}
});
}
/* ---------------- POPULATE TABLE ---------------- */
function populateTable(data) {
zoneTable.clear();
let sno = 1;
data.forEach(row => {
zoneTable.row.add([
sno++,
`<a href="javascript:void(0)"
class="text-primary fw-bold zone-link"
data-zone="${row.zone}">
${row.zone}
</a>`,
row.no_of_camps ?? 0,
row.monsoon_standard_camp_count ?? 0,
row.special_medical_camp_count ?? 0,
row.outreach_camp_count ?? 0,
row.age_0_10_male ?? 0,
row.age_0_10_female ?? 0,
row.age_0_10_transgender ?? 0,
row.age_11_40_male ?? 0,
row.age_11_40_female ?? 0,
row.age_11_40_transgender ?? 0,
row.age_41_60_male ?? 0,
row.age_41_60_female ?? 0,
row.age_41_60_transgender ?? 0,
row.age_61_above_male ?? 0,
row.age_61_above_female ?? 0,
row.age_61_above_transgender ?? 0,
row.total_beneficiaries ?? 0,
row.ANC ?? 0,
row.PN ?? 0,
row.FEVER ?? 0,
row.Cough_Cold ?? 0,
row.ILI ?? 0,
row.ADD_ ?? 0,
row.Skin_Infections ?? 0,
row.DM ?? 0,
row.HTN ?? 0,
row.DM_HTN ?? 0,
row.Animal_Insect_Bite ?? 0,
row.Injuries ?? 0,
row.others ?? 0
]);
});
zoneTable.draw();
}
/* ---------------- FILTER BUTTON ---------------- */
function loadDriverReport() {
const date = $("#reportDate").val();
const zone = $("#zoneFilter").val();
loadReport(date, zone);
}
// ward wise related js
let wardTable = null;
function initWardTable() {
if ($.fn.DataTable.isDataTable('#wardSummaryTable')) {
return;
}
wardTable = $('#wardSummaryTable').DataTable({
paging: false,
searching: false,
ordering: false,
info: false,
scrollX: true,
scrollY: "50vh",
scrollCollapse: true,
dom: 'Bfrtip',
buttons: [
/* -------- EXCEL -------- */
{
extend: 'excelHtml5',
text: 'Download Excel',
className: 'btn btn-success btn-sm',
title: function () {
return 'Ward Wise Health Camp Report - Zone ' + $('#modalZone').text();
}
},
/* -------- PDF -------- */
{
extend: 'pdfHtml5',
text: 'Download PDF',
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A2',
title: '',
customize: function (doc) {
const zoneName = $('#modalZone').text();
const reportDate = $('#reportDate').val();
/* -------- CUSTOM HEADER -------- */
doc.content.unshift({
margin: [0, 0, 0, 12],
alignment: 'center',
text: [
{ text: 'Ward Wise Health Camp Report\n', fontSize: 16, bold: true },
{ text: 'Zone : ' + zoneName + '\n', fontSize: 12 },
{ text: 'Date : ' + reportDate, fontSize: 11 }
]
});
/* -------- TABLE HEADER STYLE -------- */
doc.styles.tableHeader = {
bold: true,
fontSize: 12,
color: 'white',
fillColor: '#003366',
alignment: 'center'
};
/* -------- TABLE BODY FONT -------- */
doc.defaultStyle.fontSize = 10;
/* -------- PAGE FOOTER -------- */
doc.footer = function (currentPage, pageCount) {
return {
alignment: 'center',
fontSize: 9,
text: [
'Page ', { text: currentPage.toString() },
' of ', { text: pageCount.toString() }
]
};
};
}
}
]
});
// 🔥 Move buttons to modal export container
wardTable.buttons().container().appendTo('#wardExportContainer');
}
/* ---------------- CLICK ZONE ---------------- */
$(document).on('click', '.zone-link', function () {
const zone = $(this).data('zone');
const date = $("#reportDate").val();
$("#modalZone").text(zone);
initWardTable();
wardTable.clear().draw();
$('#wardModal').modal('show');
fetch(`/commissionerreview/api/wardwise?date=${date}&zone=${zone}`)
.then(res => res.json())
.then(json => {
if (json.status === "success") {
populateWardTable(json.data);
}
});
});
/* ---------------- POPULATE WARD TABLE ---------------- */
function populateWardTable(data) {
wardTable.clear();
let sno = 1;
data.forEach(row => {
wardTable.row.add([
sno++,
row.zone,
row.ward,
row.no_of_camps ?? 0,
row.monsoon_standard_camp_count ?? 0,
row.special_medical_camp_count ?? 0,
row.outreach_camp_count ?? 0,
row.age_0_10_male ?? 0,
row.age_0_10_female ?? 0,
row.age_0_10_transgender ?? 0,
row.age_11_40_male ?? 0,
row.age_11_40_female ?? 0,
row.age_11_40_transgender ?? 0,
row.age_41_60_male ?? 0,
row.age_41_60_female ?? 0,
row.age_41_60_transgender ?? 0,
row.age_61_above_male ?? 0,
row.age_61_above_female ?? 0,
row.age_61_above_transgender ?? 0,
// row.total_beneficiaries ?? 0,
`<a href="javascript:void(0)"
class="text-primary fw-bold beneficiary-link"
data-zone="${$('#modalZone').text()}"
data-ward="${row.ward}">
${row.total_beneficiaries ?? 0}
</a>`,
row.ANC ?? 0,
row.PN ?? 0,
row.FEVER ?? 0,
row.Cough_Cold ?? 0,
row.ILI ?? 0,
row.ADD_ ?? 0,
row.Skin_Infections ?? 0,
row.DM ?? 0,
row.HTN ?? 0,
row.DM_HTN ?? 0,
row.Animal_Insect_Bite ?? 0,
row.Injuries ?? 0,
row.others ?? 0
]);
});
wardTable.draw();
// 🔥 IMPORTANT: Fix width after modal opens
setTimeout(() => {
wardTable.columns.adjust();
}, 200);
}
// patient details modal function
let patientTable = null;
function initPatientTable() {
if ($.fn.DataTable.isDataTable('#patientTable')) return;
patientTable = $('#patientTable').DataTable({
paging: false,
searching: false,
ordering: false,
info: false,
buttons: [
/* -------- EXCEL -------- */
{
extend: 'excelHtml5',
text: 'Download Excel',
className: 'btn btn-success btn-sm',
title: function () {
return 'Ward Wise Health Camp Report - Zone ' + $('#modalZone').text();
}
},
/* -------- PDF -------- */
{
extend: 'pdfHtml5',
text: 'Download PDF',
className: 'btn btn-danger btn-sm',
orientation: 'landscape',
pageSize: 'A4',
title: '',
customize: function (doc) {
const reportDate = $('#reportDate').val();
/* -------- CUSTOM HEADER -------- */
doc.content.unshift({
margin: [0, 0, 0, 12],
alignment: 'center',
text: [
{ text: 'Patient Report\n', fontSize: 16, bold: true },
{ text: 'Date : ' + reportDate, fontSize: 11 },
]
});
/* -------- TABLE HEADER STYLE -------- */
doc.styles.tableHeader = {
bold: true,
fontSize: 9,
color: 'white',
fillColor: '#003366',
alignment: 'center'
};
/* -------- TABLE BODY FONT -------- */
doc.defaultStyle.fontSize = 8;
/* -------- PAGE FOOTER -------- */
doc.footer = function (currentPage, pageCount) {
return {
alignment: 'center',
fontSize: 9,
text: [
'Page ', { text: currentPage.toString() },
' of ', { text: pageCount.toString() }
]
};
};
}
}
],
columnDefs: [
{
targets: 1, // 👈 Date column index (0-based)
className: 'date-col'
}
]
});
// 🔥 Move buttons to modal export container
patientTable.buttons().container().appendTo('#exportContainerpatientwise');
}
$(document).on('click', '.beneficiary-link', function () {
const zone = $(this).data('zone');
const ward = $(this).data('ward');
const date = $('#reportDate').val();
$('#pZone').text(zone);
$('#pWard').text(ward);
initPatientTable();
patientTable.clear().draw();
$('#patientModal').modal('show');
fetch(`/commissionerreview/api/patientdetails?zone=${zone}&ward=${ward}&date=${date}`)
.then(res => res.json())
.then(json => {
if (json.status === "success") {
populatePatientTable(json.data);
}
});
});
function populatePatientTable(data) {
patientTable.clear();
let sno = 1;
data.forEach(row => {
patientTable.row.add([
sno++,
row.cdate,
row.zone,
row.ward,
row.pt_name,
row.pt_age,
row.gender,
row.pt_address,
row.pt_mob_no,
row.remarks
]);
});
patientTable.draw();
}
</script>
</body>
</html>
Loading…
Cancel
Save