You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1260 lines
49 KiB

6 days ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head th:replace="~{fragments/user-head :: head}"></head>
  4. <style>
  5. .navbar-logo {
  6. width: 100% !important;
  7. }
  8. body {
  9. background: #f7f9fb;
  10. font-family: Arial, sans-serif;
  11. }
  12. .filter-box {
  13. background: white;
  14. padding: 20px;
  15. border-radius: 12px;
  16. border: 1px solid #ddd;
  17. margin-bottom: 25px;
  18. }
  19. .btn-custom {
  20. background: #043B55;
  21. color: white;
  22. font-weight: bold;
  23. border-radius: 10px;
  24. }
  25. .btn-custom:hover {
  26. background: #022b3d;
  27. }
  28. table.dataTable thead th {
  29. background-color: #343a40 !important;
  30. color: white !important;
  31. }
  32. .btn-custom {
  33. background: #043B55 !important;
  34. color: #fff !important;
  35. font-weight: bold;
  36. }
  37. thead.thead-dark th {
  38. background-color: #343a40 !important;
  39. color: white !important;
  40. }
  41. </style>
  42. <body>
  43. <div th:replace="~{fragments/preloader :: div}"></div>
  44. <div id="pcoded" class="pcoded">
  45. <div class="pcoded-container">
  46. <!-- TOP NAV -->
  47. <nav th:replace="~{fragments/nav-admin :: nav}"></nav>
  48. <nav th:replace="~{fragments/nav-adminmenu :: nav}"></nav>
  49. <div class="pcoded-main-container">
  50. <div class="pcoded-wrapper">
  51. <div class="pcoded-content">
  52. <div class="pcoded-inner-content">
  53. <br><br>
  54. <div class="container-fluid mt-5 px-4">
  55. <!-- Page Heading -->
  56. <h3 class="text-center font-weight-bold mb-4">
  57. Victoria Public Hall Reports
  58. </h3>
  59. <div class="filter-box">
  60. <h5 class="text-center font-weight-bold mb-3">
  61. Report Filters
  62. </h5>
  63. <div class="row">
  64. <!-- From Date -->
  65. <div class="col-md-3">
  66. <label>From Date</label>
  67. <input type="date" id="fromDate" class="form-control">
  68. </div>
  69. <!-- To Date -->
  70. <div class="col-md-3">
  71. <label>To Date</label>
  72. <input type="date" id="toDate" class="form-control">
  73. </div>
  74. <!-- Dropdown -->
  75. <div class="col-md-4">
  76. <label>Select Report</label>
  77. <select id="reportType" class="form-control">
  78. <option value="hallBooking">
  79. Hall Booking Details
  80. </option>
  81. <option value="visitorDetails" selected>
  82. Victoria Hall Visitor Details
  83. </option>
  84. <option value="bookingDetails">
  85. Victoria Hall Booking Details
  86. </option>
  87. <option value="hallEvent">
  88. Hall Event Report
  89. </option>
  90. <option value="bulkBooking">
  91. Bulk Booking Details
  92. </option>
  93. </select>
  94. </div>
  95. <!-- Apply Button -->
  96. <div class="col-md-2 d-flex align-items-end">
  97. <button id="filterBtn" class="btn btn-custom w-100">
  98. Apply
  99. </button>
  100. </div>
  101. </div>
  102. </div>
  103. <div id="hallBookingSection" class="card shadow-sm" style="display:none;">
  104. <div class="card-body">
  105. <h5 class="text-center font-weight-bold mb-3">
  106. Hall Booking Report Results
  107. </h5>
  108. <!-- <div class="d-flex justify-content-end mb-3">
  109. <div id="exportButtons"></div>
  110. </div>-->
  111. <div id="exportButtons"></div>
  112. <div class="table-responsive">
  113. <table id="hallTable" class="table table-bordered table-striped">
  114. <thead class="thead-dark">
  115. <tr>
  116. <th>Hall Name</th>
  117. <th>User Name</th>
  118. <th>Booking Date</th>
  119. <th>Status</th>
  120. <th>Event Date</th>
  121. </tr>
  122. </thead>
  123. <tbody></tbody>
  124. </table>
  125. </div>
  126. </div>
  127. </div>
  128. <div id="visitorSection" class="card shadow-sm">
  129. <div class="card-body">
  130. <h5 class="text-center font-weight-bold mb-3">
  131. Date Wise Visits Summary
  132. </h5>
  133. <!-- <div class="d-flex justify-content-end mb-3">
  134. <div id="totalVisitsExport"></div>
  135. </div>-->
  136. <div id="totalVisitsExport"></div>
  137. <div class="table-responsive">
  138. <table id="totalVisitsTable" class="table table-bordered table-striped">
  139. <thead class="thead-dark">
  140. <tr>
  141. <th>Date</th>
  142. <th>Total Booking Count</th>
  143. <th>Total Visitors</th>
  144. <th>Actual Visitors</th>
  145. <th>Visiting %</th>
  146. <th>Rejected</th>
  147. <th>Not Visited</th>
  148. <th>Adult</th>
  149. <th>Children</th>
  150. <th>Senior</th>
  151. <th>Students</th>
  152. <th>Foreigner</th>
  153. <th>Physically Challenged</th>
  154. </tr>
  155. </thead>
  156. <tbody></tbody>
  157. </table>
  158. </div>
  159. </div>
  160. </div>
  161. <div id="eventSection" class="card shadow-sm" style="display:none;">
  162. <div class="card-body">
  163. <h5 class="text-center font-weight-bold mb-3">
  164. Hall Event Report Results
  165. </h5>
  166. <!-- <div class="d-flex justify-content-end mb-3">
  167. <div id="eventExport"></div>
  168. </div>-->
  169. <div id="eventExport"></div>
  170. <div class="table-responsive">
  171. <table id="eventTable" class="table table-bordered table-striped">
  172. <thead class="thead-dark">
  173. <tr>
  174. <th>Event Date</th>
  175. <th>Event Name</th>
  176. <th>Category</th>
  177. <th>Type</th>
  178. <th>Amount</th>
  179. <th>Max Capacity</th>
  180. <th>Total Registrations</th>
  181. <th>Total Tickets Sold</th>
  182. <th>Amount Received</th>
  183. </tr>
  184. </thead>
  185. <tbody></tbody>
  186. </table>
  187. </div>
  188. </div>
  189. </div>
  190. <div id="bulkBookingSection" class="card shadow-sm" style="display:none;">
  191. <div class="card-body">
  192. <h5 class="text-center font-weight-bold mb-3">
  193. Bulk Booking Summary Report
  194. </h5>
  195. <!-- <div class="d-flex justify-content-end mb-3">
  196. <div id="bulkExport"></div>
  197. </div>-->
  198. <div id="bulkExport"></div>
  199. <div class="table-responsive">
  200. <table id="bulkTable" class="table table-bordered table-striped">
  201. <thead class="thead-dark">
  202. <tr>
  203. <th>Prefer Visit Date</th>
  204. <th>Ref ID</th>
  205. <th>Name of Organization</th>
  206. <th>Payment Status</th>
  207. <th>Total Visitors</th>
  208. <th>Adult</th>
  209. <th>Children</th>
  210. <th>Senior</th>
  211. <th>Students</th>
  212. <th>Foreigner</th>
  213. <th>Physically Challenged</th>
  214. </tr>
  215. </thead>
  216. <tbody></tbody>
  217. </table>
  218. </div>
  219. </div>
  220. </div>
  221. <div id="bookingSection" class="card shadow-sm" style="display:none;">
  222. <div class="card-body">
  223. <h5 class="text-center font-weight-bold mb-3">
  224. Datewise Booking Summary
  225. </h5>
  226. <!-- <div class="d-flex justify-content-end mb-3">
  227. <div id="totalBookedExport"></div>
  228. </div> -->
  229. <div id="totalBookedExport"></div>
  230. <table id="totalBookedTable" class="table table-bordered table-striped">
  231. <thead class="thead-dark">
  232. <tr>
  233. <th>Date</th>
  234. <th>Total Booking Count</th>
  235. <th>Total Visitors</th>
  236. <th>Adult</th>
  237. <th>Children</th>
  238. <th>Senior Citizen</th>
  239. <th>Students</th>
  240. <th>Foreigner</th>
  241. <th>Physically Challenged</th>
  242. </tr>
  243. </thead>
  244. <tbody></tbody>
  245. </table>
  246. </div>
  247. </div>
  248. </div>
  249. </div>
  250. </div>
  251. </div>
  252. </div>
  253. </div>
  254. <div class="modal fade" id="bookingDetailsModal" tabindex="-1">
  255. <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
  256. <div class="modal-content">
  257. <div class="modal-header">
  258. <h5 class="modal-title">
  259. Booking Details - <span id="modalBookingDate"></span>
  260. </h5>
  261. <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
  262. </div>
  263. <div class="modal-body">
  264. <div id="bookingModalExport" class="mb-2"></div>
  265. <table class="table table-bordered" id="bookingDetailTable">
  266. <thead class="table-primary">
  267. <tr>
  268. <th>Ref ID</th>
  269. <th>Mobile</th>
  270. <th>Email</th>
  271. <th>Visit Date</th>
  272. <th>No. of People</th>
  273. <th>Amount Paid</th>
  274. <th>ID Card</th>
  275. <th>Time</th>
  276. <th>Slot</th>
  277. <th>Language</th>
  278. </tr>
  279. </thead>
  280. <tbody></tbody>
  281. </table>
  282. </div>
  283. </div>
  284. </div>
  285. </div>
  286. <div class="modal fade" id="visitordetailsModal" tabindex="-1">
  287. <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
  288. <div class="modal-content">
  289. <div class="modal-header">
  290. <h5 class="modal-title">
  291. Visitor Details - <span id="modalVisitdetailsDate"></span>
  292. </h5>
  293. <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
  294. </div>
  295. <div class="modal-body">
  296. <div id="visitordeatailsModalExport" class="mb-2"></div>
  297. <table class="table table-bordered" id="visitordeatailsDetailTable">
  298. <thead class="table-primary">
  299. <tr>
  300. <th>Ref ID</th>
  301. <th>Mobile</th>
  302. <th>Email</th>
  303. <th>Visit Date</th>
  304. <th>Booking Date</th>
  305. <th>No. of People</th>
  306. <th>Amount Paid</th>
  307. <th>ID Card</th>
  308. <th>Time</th>
  309. <th>Slot</th>
  310. <th>Language</th>
  311. </tr>
  312. </thead>
  313. <tbody></tbody>
  314. </table>
  315. </div>
  316. </div>
  317. </div>
  318. </div>
  319. </div>
  320. <!-- ===========================
  321. EVENT DETAILS MODAL
  322. =========================== -->
  323. <div class="modal fade" id="eventDetailsModal" tabindex="-1">
  324. <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
  325. <div class="modal-content">
  326. <div class="modal-header">
  327. <h5 class="modal-title">
  328. Event Registration Details - <span id="modalEventName"></span> -<span
  329. id="modalEventDate"></span>
  330. </h5>
  331. <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
  332. </div>
  333. <div class="modal-body">
  334. <div id="eventModalExport" class="mb-2"></div>
  335. <table class="table table-bordered" id="eventDetailTable">
  336. <thead class="table-primary">
  337. <tr>
  338. <th>Mobile No</th>
  339. <th>No. of People</th>
  340. <th>Total Amount</th>
  341. <th>Payment Status</th>
  342. <th>Booking Flag</th>
  343. <th>Event Timing</th>
  344. </tr>
  345. </thead>
  346. <tbody></tbody>
  347. </table>
  348. </div>
  349. </div>
  350. </div>
  351. </div>
  352. <div class="modal fade" id="bulkBookingModal" tabindex="-1">
  353. <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
  354. <div class="modal-content">
  355. <div class="modal-header">
  356. <h5 class="modal-title">
  357. Bulk Booking Details - Ref ID:
  358. <span id="bulkRefIdTitle"></span>
  359. </h5>
  360. <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
  361. </div>
  362. <div class="modal-body">
  363. <table class="table table-bordered" id="bulkDetailTable">
  364. <thead class="table-primary">
  365. <tr>
  366. <th>Ref ID</th>
  367. <th>Payment Status</th>
  368. <th>No. of People</th>
  369. <th>Mobile</th>
  370. <th>Email</th>
  371. <th>Timing</th>
  372. </tr>
  373. </thead>
  374. <tbody></tbody>
  375. </table>
  376. </div>
  377. </div>
  378. </div>
  379. </div>
  380. <!-- ===========================
  381. SCRIPTS
  382. ============================ -->
  383. <!-- jQuery -->
  384. <script th:replace="~{fragments/user-script :: script}"></script>
  385. <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  386. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
  387. <!-- DataTables -->
  388. <link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css">
  389. <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css">
  390. <script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
  391. <script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script>
  392. <script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script>
  393. <!-- DataTable Buttons -->
  394. <script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
  395. <script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.bootstrap5.min.js"></script>
  396. <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
  397. <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
  398. <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
  399. <script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
  400. <!-- SweetAlert -->
  401. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  402. <script>
  403. document.addEventListener("DOMContentLoaded", function () {
  404. let fromDate = document.getElementById("fromDate");
  405. let toDate = document.getElementById("toDate");
  406. let reportType = document.getElementById("reportType");
  407. let filterBtn = document.getElementById("filterBtn");
  408. function setYesterdayDates() {
  409. let yesterday = new Date();
  410. yesterday.setDate(yesterday.getDate() );
  411. let yDate = yesterday.toISOString().split("T")[0];
  412. fromDate.value = yDate;
  413. toDate.value = yDate;
  414. // Restrict future selection
  415. let today = new Date().toISOString().split("T")[0];
  416. fromDate.max = today;
  417. toDate.max = today;
  418. }
  419. // ✅ Bulk Booking → Today to +30 Days
  420. function setBulkBookingDates() {
  421. let todayObj = new Date();
  422. let from = todayObj.toISOString().split("T")[0];
  423. let future = new Date();
  424. future.setDate(todayObj.getDate() + 30);
  425. let to = future.toISOString().split("T")[0];
  426. fromDate.value = from;
  427. toDate.value = to;
  428. // Allow future dates ONLY for bulk booking
  429. toDate.max = to;
  430. }
  431. /*reportType.addEventListener("change", function () {
  432. if (reportType.value === "bulkBooking") {
  433. // Bulk Booking → Today + 30 Days
  434. setBulkBookingDates();
  435. } else {
  436. // Other Reports → Yesterday Default
  437. setYesterdayDates();
  438. }
  439. });*/
  440. // If user changes FROM date → clear TO date
  441. fromDate.addEventListener("change", function () {
  442. if (fromDate.value !== "") {
  443. // ✅ Restrict To Date: cannot select before From Date
  444. toDate.min = fromDate.value;
  445. toDate.value = "";
  446. }
  447. });
  448. // If user changes TO date → clear FROM date
  449. // Default Yesterday Load
  450. setYesterdayDates();
  451. // Default Report Selection
  452. reportType.value = "visitorDetails";
  453. // Hide All Sections Initially
  454. $("#hallBookingSection").hide();
  455. $("#bookingSection").hide();
  456. $("#eventSection").hide();
  457. $("#bulkBookingSection").hide();
  458. // Show Visitor Section Default
  459. $("#visitorSection").show();
  460. // Auto Load Visitor Summary
  461. loadTotalVisitsSummary(fromDate.value, toDate.value);
  462. filterBtn.addEventListener("click", function () {
  463. let fromVal = fromDate.value;
  464. let toVal = toDate.value;
  465. let selectedReport = reportType.value;
  466. // Validation
  467. if (!fromVal || !toVal) {
  468. Swal.fire("Warning", "Please select both dates!", "warning");
  469. return;
  470. }
  471. if (toVal < fromVal) {
  472. Swal.fire("Warning", "To Date cannot be earlier than From Date!", "warning");
  473. return;
  474. }
  475. // Hide All Sections First
  476. $("#hallBookingSection").hide();
  477. $("#visitorSection").hide();
  478. $("#bookingSection").hide();
  479. $("#eventSection").hide();
  480. $("#bulkBookingSection").hide();
  481. if (selectedReport === "hallBooking") {
  482. $("#hallBookingSection").show();
  483. loadHallBookings(fromVal, toVal);
  484. }
  485. else if (selectedReport === "visitorDetails") {
  486. $("#visitorSection").show();
  487. loadTotalVisitsSummary(fromVal, toVal);
  488. }
  489. else if (selectedReport === "bookingDetails") {
  490. $("#bookingSection").show();
  491. loadTotalBookedSummary(fromVal, toVal);
  492. }
  493. else if (selectedReport === "hallEvent") {
  494. $("#eventSection").show();
  495. loadHallEventReport(fromVal, toVal);
  496. }
  497. else if (selectedReport === "bulkBooking") {
  498. $("#bulkBookingSection").show();
  499. loadBulkBookingSummary(fromVal, toVal);
  500. }
  501. });
  502. });
  503. function loadBulkBookingSummary(fromDate, toDate) {
  504. if ($.fn.DataTable.isDataTable('#bulkTable')) {
  505. $('#bulkTable').DataTable().clear().destroy();
  506. $("#bulkExport").empty();
  507. }
  508. $("#bulkTable tbody").empty();
  509. $.ajax({
  510. url: "/victoriapublichall/reportapi/bulk-booking-summary",
  511. method: "GET",
  512. data: { fromDate, toDate },
  513. success: function (data) {
  514. if (!data || data.length === 0) {
  515. $("#bulkTable tbody").append(`
  516. <tr>
  517. <td colspan="11" class="text-center text-danger">
  518. No Bulk Bookings Found
  519. </td>
  520. </tr>
  521. `);
  522. return;
  523. }
  524. $.each(data, function (i, r) {
  525. $("#bulkTable tbody").append(`
  526. <tr>
  527. <td data-order="${r.prefer_visit_date}">
  528. ${formatDate(r.prefer_visit_date)}
  529. </td>
  530. <td>${r.ref_id}</td>
  531. <td>${r.booked_by}</td>
  532. <td>${r.payment_status}</td>
  533. <td class="text-right">
  534. <a href="javascript:void(0)"
  535. class="fw-bold text-primary"
  536. onclick="openBulkBookingModal('${r.ref_id}')">
  537. ${r.TotalCount}
  538. </a>
  539. </td>
  540. <td class="text-right">${r.Adult}</td>
  541. <td class="text-right">${r.Children}</td>
  542. <td class="text-right">${r.SeniorCitizen}</td>
  543. <td class="text-right">${r.Students}</td>
  544. <td class="text-right">${r.Foreigner}</td>
  545. <td class="text-right">${r.PhysicallyChallenged}</td>
  546. </tr>
  547. `);
  548. });
  549. $('#bulkTable').DataTable({
  550. paging: true,
  551. searching: true,
  552. dom: 'Bfrtip',
  553. buttons: [
  554. { extend: 'excelHtml5', text: 'Download Excel', title: 'Bulk Booking Summary' },
  555. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Bulk Booking Summary' }
  556. ]
  557. }).buttons().container().appendTo("#bulkExport");
  558. }
  559. });
  560. }
  561. function openBulkBookingModal(refId) {
  562. $("#bulkRefIdTitle").text(refId);
  563. loadBulkBookingDetails(refId);
  564. $("#bulkBookingModal").modal("show");
  565. }
  566. function loadBulkBookingDetails(refId) {
  567. if ($.fn.DataTable.isDataTable('#bulkDetailTable')) {
  568. $('#bulkDetailTable').DataTable().clear().destroy();
  569. }
  570. $("#bulkDetailTable tbody").empty();
  571. $.ajax({
  572. url: "/victoriapublichall/reportapi/bulk-booking-details",
  573. method: "GET",
  574. data: { refId: refId },
  575. success: function (data) {
  576. $.each(data, function (i, r) {
  577. $("#bulkDetailTable tbody").append(`
  578. <tr>
  579. <td>${r.ref_id}</td>
  580. <td>${r.payment_status}</td>
  581. <td class="text-right">${r.no_of_people}</td>
  582. <td>${r.mob_no || "-"}</td>
  583. <td>${r.email || "-"}</td>
  584. <td>${r.timing}</td>
  585. </tr>
  586. `);
  587. });
  588. $('#bulkDetailTable').DataTable({
  589. paging: true,
  590. searching: true
  591. });
  592. }
  593. });
  594. }
  595. function loadHallBookings(fromDate, toDate) {
  596. if ($.fn.DataTable.isDataTable('#hallTable')) {
  597. $('#hallTable').DataTable().clear().destroy();
  598. $("#exportButtons").empty();
  599. }
  600. $("#hallTable tbody").empty();
  601. $.ajax({
  602. url: "/victoriapublichall/reportapi/hall-bookings-dashboardreport",
  603. method: "GET",
  604. data: { fromDate, toDate },
  605. success: function (data) {
  606. if (!data || data.length === 0) {
  607. $("#hallTable tbody").append(`
  608. <tr>
  609. <td colspan="5" class="text-center text-danger">
  610. No records found
  611. </td>
  612. </tr>
  613. `);
  614. return;
  615. }
  616. $.each(data, function (i, r) {
  617. $("#hallTable tbody").append(`
  618. <tr>
  619. <td>${r.hall_name}</td>
  620. <td>${r.userName}</td>
  621. <td>${r.bookingDate}</td>
  622. <td>${r.bookingstatus}</td>
  623. <td>${r.eventDate}</td>
  624. </tr>
  625. `);
  626. });
  627. setTimeout(() => {
  628. $('#hallTable').DataTable({
  629. paging: true,
  630. searching: true,
  631. ordering: true,
  632. dom: 'Bfrtip',
  633. buttons: [
  634. {
  635. extend: 'excelHtml5',
  636. text: 'Download Excel',
  637. title: 'Hall Bookings Report'
  638. },
  639. {
  640. extend: 'pdfHtml5',
  641. text: 'Download PDF',
  642. orientation: 'landscape',
  643. title: 'Hall Bookings Report'
  644. }
  645. ]
  646. }).buttons().container().appendTo("#exportButtons");
  647. }, 200);
  648. },
  649. error: function () {
  650. Swal.fire("Error", "Failed to load Hall Booking Report!", "error");
  651. }
  652. });
  653. }
  654. function loadTotalVisitsSummary(fromDate, toDate) {
  655. if ($.fn.DataTable.isDataTable('#totalVisitsTable')) {
  656. $('#totalVisitsTable').DataTable().clear().destroy();
  657. $("#totalVisitsExport").empty();
  658. }
  659. $("#totalVisitsTable tbody").empty();
  660. $.ajax({
  661. url: "/victoriapublichall/reportapi/total-visits-summary",
  662. method: "GET",
  663. data: { fromDate, toDate },
  664. success: function (data) {
  665. if (!data || data.length === 0) {
  666. $("#totalVisitsTable tbody").append(`
  667. <tr>
  668. <td colspan="13" class="text-center text-danger">
  669. No visitor summary found
  670. </td>
  671. </tr>
  672. `);
  673. return;
  674. }
  675. $.each(data, function (i, r) {
  676. let percentage = ((r.accepted_people / r.TotalCount) * 100).toFixed(2);
  677. $("#totalVisitsTable tbody").append(`
  678. <tr>
  679. <td data-order="${r.bookingDate}">
  680. ${formatDate(r.bookingDate)}
  681. </td>
  682. <td class="text-right">
  683. <a href="javascript:void(0)"
  684. class="fw-bold text-primary"
  685. onclick="openVisitorBreakupModal('${r.bookingDate}')">
  686. ${r.totalBookingCount}
  687. </a>
  688. </td>
  689. <td class="text-right">${r.TotalCount}</td>
  690. <td class="text-right">${r.accepted_people}</td>
  691. <td class="text-right"><b>${percentage}%</b></td>
  692. <td class="text-right">${r.rejected_people}</td>
  693. <td class="text-right">${r.NotVisitedCount}</td>
  694. <td class="text-right">${r.Adult}</td>
  695. <td class="text-right">${r.Children}</td>
  696. <td class="text-right">${r.SeniorCitizen}</td>
  697. <td class="text-right">${r.Students}</td>
  698. <td class="text-right">${r.Foreigner}</td>
  699. <td class="text-right">${r.PhysicallyChallenged}</td>
  700. </tr>
  701. `);
  702. });
  703. $('#totalVisitsTable').DataTable({
  704. paging: true,
  705. searching: true,
  706. ordering: true,
  707. dom: 'Bfrtip',
  708. buttons: [
  709. { extend: 'excelHtml5', text: 'Download Excel', title: 'Visits Summary' },
  710. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Visits Summary' }
  711. ]
  712. }).buttons().container().appendTo('#totalVisitsExport');
  713. },
  714. error: function () {
  715. Swal.fire("Error", "Failed to load Visitor Summary!", "error");
  716. }
  717. });
  718. }
  719. function loadHallEventReport(fromDate, toDate) {
  720. console.log(fromDate);
  721. if ($.fn.DataTable.isDataTable('#eventTable')) {
  722. $('#eventTable').DataTable().clear().destroy();
  723. $("#eventExport").empty();
  724. }
  725. $("#eventTable tbody").empty();
  726. $.ajax({
  727. url: "/victoriapublichall/reportapi/hall-event-report",
  728. method: "GET",
  729. data: { fromDate, toDate },
  730. success: function (data) {
  731. console.log(data);
  732. if (!data || data.length === 0) {
  733. $("#eventTable tbody").append(`
  734. <tr>
  735. <td colspan="10" class="text-center text-danger">
  736. No events found
  737. </td>
  738. </tr>
  739. `);
  740. return;
  741. }
  742. $.each(data, function (i, r) {
  743. $("#eventTable tbody").append(`
  744. <tr>
  745. <td data-order="${r.event_date}">
  746. ${formatDate(r.event_date)}
  747. </td>
  748. <td>
  749. <a href="javascript:void(0)"
  750. class="fw-bold text-primary"
  751. onclick="openEventDetailsModal('${r.event_id}','${r.event_name}','${formatDate(r.event_date)}')">
  752. ${r.event_name}
  753. </a>
  754. </td>
  755. <td>${r.event_category}</td>
  756. <td>${r.event_type}</td>
  757. <td class="text-right">${r.amount}</td>
  758. <td class="text-right">${r.max_capacity}</td>
  759. <td class="text-right">${r.total_registrations}</td>
  760. <td class="text-right">${r.total_people ?? '-'}</td>
  761. <td class="text-right">${r.Amountreceived ?? '-'}</td>
  762. </tr>
  763. `);
  764. });
  765. $('#eventTable').DataTable({
  766. paging: true,
  767. searching: true,
  768. ordering: true,
  769. dom: 'Bfrtip',
  770. buttons: [
  771. { extend: 'excelHtml5', text: 'Download Excel', title: 'Hall Event Report' },
  772. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Hall Event Report' }
  773. ]
  774. }).buttons().container().appendTo("#eventExport");
  775. }
  776. });
  777. }
  778. function openEventDetailsModal(eventId, eventName, eventDate) {
  779. $("#modalEventName").text(eventName);
  780. $("#modalEventDate").text(eventDate);
  781. loadEventRegistrations(eventId);
  782. $("#eventDetailsModal").modal("show");
  783. }
  784. function loadEventRegistrations(eventId) {
  785. if ($.fn.DataTable.isDataTable('#eventDetailTable')) {
  786. $('#eventDetailTable').DataTable().clear().destroy();
  787. $("#eventModalExport").empty();
  788. }
  789. $("#eventDetailTable tbody").empty();
  790. $.ajax({
  791. url: "/victoriapublichall/reportapi/event-registration-details",
  792. method: "GET",
  793. data: { eventId: eventId },
  794. success: function (data) {
  795. $.each(data, function (i, r) {
  796. $("#eventDetailTable tbody").append(`
  797. <tr>
  798. <td>${r.mob_no}</td>
  799. <td class="text-right">${r.no_of_people}</td>
  800. <td class="text-right">${r.total_amount}</td>
  801. <td>${r.payment_status}</td>
  802. <td>${r.booking_flag}</td>
  803. <td>${r.event_timing}</td>
  804. </tr>
  805. `);
  806. });
  807. $('#eventDetailTable').DataTable({
  808. paging: true,
  809. searching: true,
  810. dom: 'Bfrtip',
  811. buttons: [
  812. { extend: 'excelHtml5', text: 'Download Excel', title: 'Event Registrations' },
  813. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Event Registrations' }
  814. ]
  815. }).buttons().container().appendTo("#eventModalExport");
  816. }
  817. });
  818. }
  819. function openVisitorBreakupModal(date) {
  820. $("#modalVisitdetailsDate").text(formatDate(date));
  821. loadVisitorDetailsByDate(date);
  822. $("#visitordetailsModal").modal("show");
  823. }
  824. function loadVisitorDetailsByDate(visitDate) {
  825. if ($.fn.DataTable.isDataTable('#visitordeatailsDetailTable')) {
  826. $('#visitordeatailsDetailTable').DataTable().clear().destroy();
  827. $("#visitordeatailsModalExport").empty();
  828. }
  829. $("#visitordeatailsDetailTable tbody").empty();
  830. $.ajax({
  831. url: "/victoriapublichall/reportapi/visitor-details-by-dates",
  832. method: "GET",
  833. data: { visitDate: visitDate }, // ✅ date passed here
  834. success: function (data) {
  835. $('#pageLoader').hide();
  836. $.each(data, function (i, r) {
  837. $("#visitordeatailsDetailTable tbody").append(`
  838. <tr>
  839. <td>${r.ref_id}</td>
  840. <td>${r.mob_no ?? '-'}</td>
  841. <td>${r.email ?? '-'}</td>
  842. <!-- <td>${r.visitDate}</td>-->
  843. <td class="nowrap">${formatDate(r.visitDate)}</td>
  844. <td class="nowrap">${formatDate(r.bookingDate)}</td>
  845. <td class="text-right">${r.no_of_people}</td>
  846. <td class="text-right">${r.amountPaid}</td>
  847. <!-- <td>${r.IdCardNumber}</td>-->
  848. <td>${r.IdCardNumber && r.IdCardNumber.trim() !== '' ? r.IdCardNumber : '-'}</td>
  849. <td class="nowrap">${r.time}</td>
  850. <td class="nowrap">${r.slot}</td>
  851. <td>${r.language}</td>
  852. </tr>
  853. `);
  854. });
  855. $('#visitordeatailsDetailTable').DataTable({
  856. paging: true,
  857. searching: true,
  858. ordering: true,
  859. dom: 'Bfrtip',
  860. buttons: [
  861. { extend: 'excelHtml5', text: 'Download Excel', title: 'Visitor Details - ' + formatDate(visitDate) },
  862. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Visitor Details - ' + formatDate(visitDate) }
  863. ]
  864. }).buttons().container().appendTo('#visitordeatailsModalExport');
  865. }
  866. });
  867. }
  868. function loadTotalBookedSummary(fromDate, toDate) {
  869. if ($.fn.DataTable.isDataTable('#totalBookedTable')) {
  870. $('#totalBookedTable').DataTable().clear().destroy();
  871. $("#totalBookedExport").empty();
  872. }
  873. $("#totalBookedTable tbody").empty();
  874. $.ajax({
  875. url: "/victoriapublichall/reportapi/total-booked-summary",
  876. method: "GET",
  877. data: { fromDate, toDate },
  878. success: function (data) {
  879. if (!data || data.length === 0) {
  880. $("#totalBookedTable tbody").append(`
  881. <tr>
  882. <td colspan="9" class="text-center text-danger">
  883. No booking summary found
  884. </td>
  885. </tr>
  886. `);
  887. return;
  888. }
  889. $.each(data, function (i, r) {
  890. $("#totalBookedTable tbody").append(`
  891. <tr>
  892. <td data-order="${r.bookingDate}">
  893. ${formatDate(r.bookingDate)}
  894. </td>
  895. <td class="text-right">
  896. <a href="javascript:void(0)"
  897. class="fw-bold text-primary"
  898. onclick="openBookingDetailsModal('${r.bookingDate}')">
  899. ${r.totalBookingCount}
  900. </a>
  901. </td>
  902. <td class="text-right">${r.TotalCount}</td>
  903. <td class="text-right">${r.Adult}</td>
  904. <td class="text-right">${r.Children}</td>
  905. <td class="text-right">${r.SeniorCitizen}</td>
  906. <td class="text-right">${r.Students}</td>
  907. <td class="text-right">${r.Foreigner}</td>
  908. <td class="text-right">${r.PhysicallyChallenged}</td>
  909. </tr>
  910. `);
  911. });
  912. $('#totalBookedTable').DataTable({
  913. paging: true,
  914. searching: true,
  915. ordering: true,
  916. dom: 'Bfrtip',
  917. buttons: [
  918. { extend: 'excelHtml5', text: 'Download Excel', title: 'Booking Summary' },
  919. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Booking Summary' }
  920. ]
  921. }).buttons().container().appendTo('#totalBookedExport');
  922. },
  923. error: function () {
  924. Swal.fire("Error", "Failed to load Booking Summary!", "error");
  925. }
  926. });
  927. }
  928. function openBookingDetailsModal(date) {
  929. $("#modalBookingDate").text(formatDate(date));
  930. loadBookingDetailsByDate(date);
  931. $("#bookingDetailsModal").modal("show");
  932. }
  933. function loadBookingDetailsByDate(visitDate) {
  934. if ($.fn.DataTable.isDataTable('#bookingDetailTable')) {
  935. $('#bookingDetailTable').DataTable().clear().destroy();
  936. $("#bookingModalExport").empty();
  937. }
  938. $("#bookingDetailTable tbody").empty();
  939. $.ajax({
  940. url: "/victoriapublichall/reportapi/booking-details-by-dates",
  941. method: "GET",
  942. data: { visitDate: visitDate },
  943. success: function (data) {
  944. $.each(data, function (i, r) {
  945. $("#bookingDetailTable tbody").append(`
  946. <tr>
  947. <td>${r.ref_id}</td>
  948. <td>${r.mob_no ?? '-'}</td>
  949. <td>${r.email ?? '-'}</td>
  950. <td>${formatDate(r.visitDate)}</td>
  951. <td class="text-right">${r.no_of_people}</td>
  952. <td class="text-right">${r.amountPaid}</td>
  953. <td>${r.IdCardNumber || '-'}</td>
  954. <td>${r.time}</td>
  955. <td>${r.slot}</td>
  956. <td>${r.language}</td>
  957. </tr>
  958. `);
  959. });
  960. $('#bookingDetailTable').DataTable({
  961. paging: true,
  962. searching: true,
  963. ordering: true,
  964. dom: 'Bfrtip',
  965. buttons: [
  966. { extend: 'excelHtml5', text: 'Download Excel', title: 'Booking Details - ' + formatDate(visitDate) },
  967. { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', title: 'Booking Details - ' + formatDate(visitDate) }
  968. ]
  969. }).buttons().container().appendTo('#bookingModalExport');
  970. }
  971. });
  972. }
  973. function formatDate(dateStr) {
  974. let d = new Date(dateStr);
  975. return d.toLocaleDateString("en-GB");
  976. }
  977. </script>
  978. </body>
  979. </html>