diff --git a/src/main/java/com/gcc/commissionerreview/controller/MainController.java b/src/main/java/com/gcc/commissionerreview/controller/MainController.java index 7a2cea0..1850904 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/MainController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/MainController.java @@ -227,4 +227,37 @@ public class MainController { return "modules/vphreport"; } + @GetMapping("/vphreportdashboard") + public String vphreportdashboard(Model model) { + /* + * Map categoryTotals = + * vphservice.getCategoryTotalsTillToday(); + * + * int hallBookingCount = vphservice.getHallBookingCountTillToday(); + * + * Map visitorTotals = vphservice.getVisitorTotalsTillToday(); + * + * int visitorBookingCount = vphservice.getVisitorBookingCountTillToday(); + * + * int totalBookingCount = vphservice.getTotalBookingCountTillToday(); + * + * model.addAttribute("categoryTotals", categoryTotals); + * model.addAttribute("hallBookingCount", hallBookingCount); + * model.addAttribute("visitorTotals", visitorTotals); + * model.addAttribute("visitorBookingCount", visitorBookingCount); + * model.addAttribute("totalBookingCount", totalBookingCount); + * + * // visistor based count + * + * Map vistorbasedcount = + * vphservice.getVisitorbasedStatusTillToday(); + * + * model.addAttribute("vistorbasedcount", vistorbasedcount); + */ + + return "modules/vphreportdashboard"; + } + + // visistor based count + } diff --git a/src/main/java/com/gcc/commissionerreview/controller/VphApiController.java b/src/main/java/com/gcc/commissionerreview/controller/VphApiController.java index 7f13c66..03e82fc 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/VphApiController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/VphApiController.java @@ -2,6 +2,7 @@ package com.gcc.commissionerreview.controller; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,12 +37,21 @@ public class VphApiController { @RequestParam String toDate) { return vphservice.getTotalVisitors(fromDate, toDate); } + // with date filter + /* + * @GetMapping("/hall-bookings") + * public List> hallBookings( + * + * @RequestParam String fromDate, + * + * @RequestParam String toDate) { + * return vphservice.getHallBookings(fromDate, toDate); + * } + */ @GetMapping("/hall-bookings") - public List> hallBookings( - @RequestParam String fromDate, - @RequestParam String toDate) { - return vphservice.getHallBookings(fromDate, toDate); + public List> hallBookings() { + return vphservice.getHallBookings(); } @GetMapping("/visitor-details-by-date") @@ -55,4 +65,70 @@ public class VphApiController { return vphservice.getVisitorDetailsByDate(localDate); } + // new dashboard + + /* + * @GetMapping("/total-booked-summary") + * public List> totalBookedSummary() { + * return vphservice.getTotalBookedSummary(); + * } + */ + @GetMapping("/total-booked-summary") + public List> totalBookedSummary( + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate) { + + return vphservice.getTotalBookedSummary(fromDate, toDate); + } + + @GetMapping("/booking-details-by-dates") + public List> visitorDetailsByDate( + @RequestParam String visitDate) { + + return vphservice.getVisitorDetailsByDate(visitDate); + } + + /* + * @GetMapping("/total-visits-summary") + * public List> totalVisitsSummary() { + * return vphservice.getTotalVisitsSummary(); + * } + */ + @GetMapping("/total-visits-summary") + public List> totalVisitsSummary( + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate) { + + return vphservice.getTotalVisitsSummary(fromDate, toDate); + } + + @GetMapping("/visitor-details-by-dates") + public List> visitorbookingDetailsByDate( + @RequestParam String visitDate) { + + return vphservice.getVisitorbookingDetailsByDate(visitDate); + } + + @GetMapping("/top-dashboard") + public Map topDashboard( + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate) { + + Map res = new HashMap<>(); + res.put("totalBookingCount", + vphservice.getTotalBookingCount(fromDate, toDate)); + res.put("categoryTotals", + vphservice.getCategoryTotals(fromDate, toDate)); + + return res; + } + + @GetMapping("/visitor-based-status") + public Map visitorStatus( + @RequestParam(required = false) String fromDate, + @RequestParam(required = false) String toDate) { + + return vphservice.getVisitorbasedStatus(fromDate, toDate); + } + } diff --git a/src/main/java/com/gcc/commissionerreview/service/VphService.java b/src/main/java/com/gcc/commissionerreview/service/VphService.java index ae1a22e..dda5cfe 100644 --- a/src/main/java/com/gcc/commissionerreview/service/VphService.java +++ b/src/main/java/com/gcc/commissionerreview/service/VphService.java @@ -64,8 +64,29 @@ public class VphService { return jdbcTemplate.queryForList(sql, fromDate, toDate); } - - public List> getHallBookings(String fromDate, String toDate) { + // with date filter + + /* + * public List> getHallBookings(String fromDate, String + * toDate) { + * + * String sql = """ + * SELECT hd.hall_name, + * us.name userName, + * DATE_FORMAT(bd.booking_date,'%d-%m-%Y') bookingDate, + * DATE_FORMAT(bd.end_date,'%d-%m-%Y') eventDate + * FROM booking_details bd + * LEFT JOIN hall_details hd ON bd.hall_details_hall_id=hd.hall_id + * LEFT JOIN users us ON bd.users_user_id=us.user_id + * WHERE bd.booking_status IN ('WAITING_FOR_NOC','APPROVED') + * AND DATE(bd.booking_date) BETWEEN ? AND ? + * ORDER BY bd.booking_date + * """; + * + * return jdbcTemplate.queryForList(sql, fromDate, toDate); + * } + */ + public List> getHallBookings() { String sql = """ SELECT hd.hall_name, @@ -76,11 +97,11 @@ public class VphService { LEFT JOIN hall_details hd ON bd.hall_details_hall_id=hd.hall_id LEFT JOIN users us ON bd.users_user_id=us.user_id WHERE bd.booking_status IN ('WAITING_FOR_NOC','APPROVED') - AND DATE(bd.booking_date) BETWEEN ? AND ? + AND DATE(bd.booking_date) BETWEEN '2026-01-01' AND CURDATE() ORDER BY bd.booking_date """; - return jdbcTemplate.queryForList(sql, fromDate, toDate); + return jdbcTemplate.queryForList(sql); } // card @@ -178,6 +199,262 @@ public class VphService { tm.time_id, tsm.language FROM reg_details rd + LEFT JOIN time_master tm + ON rd.time_id = tm.time_id + LEFT JOIN avslot_reg_det ard + ON rd.ref_id = ard.ref_id + LEFT JOIN time_slot_master tsm + ON ard.slot_id = tsm.slot_id + LEFT JOIN visitor_count_details vcd + ON rd.ref_id = vcd.ref_id + WHERE DATE(rd.cdate) = ? + AND rd.booking_flag = 'B' + GROUP BY + rd.ref_id, + rd.mob_no, + rd.email, + DATE(rd.visit_date), + rd.no_of_people, + rd.total_amount, + rd.id_details, + tm.timing, + tm.time_id, + tsm.timing, + tsm.language + ORDER BY tm.time_id ASC, + tsm.timing ASC + """; + + return jdbcTemplate.queryForList(sql, visitDate); + } + + // vph dashboard + + public Map getCategoryTotalsTillToday(String fromDate, String toDate) { + + String sql = """ + SELECT + IFNULL(vac.user_type, 'TOTAL') AS userCategory, + COALESCE(SUM(rd.no_of_people), 0) AS registeredCount + FROM reg_details rd + LEFT JOIN visitor_count_details vcd ON rd.ref_id = vcd.ref_id + LEFT JOIN visit_amount_config vac ON vcd.user_type_id = vac.id + WHERE rd.booking_flag = 'B' + AND DATE(rd.cdate) BETWEEN '2026-01-01' AND CURDATE() + + + GROUP BY vac.user_type WITH ROLLUP + """; + + Map result = new HashMap<>(); + + jdbcTemplate.query(sql, rs -> { + result.put( + rs.getString("userCategory"), + rs.getInt("registeredCount")); + }); + + return result; + } + + public int getTotalBookingCountTillToday() { + + String sql = """ + select count(id) as totalBookingCount from reg_details where DATE(cdate) BETWEEN '2026-01-01' AND CURDATE() and booking_flag = 'B' + + """; + + return jdbcTemplate.queryForObject(sql, Integer.class); + } + + /* + * public List> getTotalBookedSummary() { + * + * String sql = """ + * SELECT DATE(rd.cdate) AS bookingDate,COUNT(DISTINCT rd.ref_id) AS + * totalBookingCount, + * COALESCE(SUM(CASE WHEN vac.user_type='Adult ' THEN vcd.no_of_people END),0) + * Adult, + * COALESCE(SUM(CASE WHEN vac.user_type='Children [ below 10 year]' THEN + * vcd.no_of_people END),0) Children, + * COALESCE(SUM(CASE WHEN vac.user_type='Senior Citizen [above 60+]' THEN + * vcd.no_of_people END),0) SeniorCitizen, + * COALESCE(SUM(CASE WHEN vac.user_type='Students' THEN vcd.no_of_people END),0) + * Students, + * COALESCE(SUM(CASE WHEN vac.user_type='Foreigner' THEN vcd.no_of_people + * END),0) Foreigner, + * COALESCE(SUM(CASE WHEN vac.user_type='Physically challeged' THEN + * vcd.no_of_people END),0) PhysicallyChallenged, + * COALESCE(SUM(vcd.no_of_people),0) TotalCount + * FROM reg_details rd + * LEFT JOIN visitor_count_details vcd ON rd.ref_id = vcd.ref_id + * LEFT JOIN visit_amount_config vac ON vcd.user_type_id = vac.id + * WHERE rd.booking_flag = 'B' + * AND DATE(rd.cdate) BETWEEN '2026-01-01' AND CURDATE() + * GROUP BY DATE(rd.cdate) + * ORDER BY DATE(rd.cdate) + * + * """; + * + * return jdbcTemplate.queryForList(sql); + * } + */ + + public List> getVisitorDetailsByDate(String visitDate) { + + String sql = """ + SELECT + rd.ref_id, + rd.mob_no, + rd.email, + DATE(rd.visit_date) AS visitDate, + rd.no_of_people, + rd.total_amount AS amountPaid, + rd.id_details AS IdCardNumber, + tm.timing AS time, + tsm.timing AS slot, + tm.time_id, + tsm.language + FROM reg_details rd + LEFT JOIN time_master tm + ON rd.time_id = tm.time_id + LEFT JOIN avslot_reg_det ard + ON rd.ref_id = ard.ref_id + LEFT JOIN time_slot_master tsm + ON ard.slot_id = tsm.slot_id + LEFT JOIN visitor_count_details vcd + ON rd.ref_id = vcd.ref_id + WHERE DATE(rd.cdate) = ? + AND rd.booking_flag = 'B' + GROUP BY + rd.ref_id, + rd.mob_no, + rd.email, + DATE(rd.visit_date), + rd.no_of_people, + rd.total_amount, + rd.id_details, + tm.timing, + tm.time_id, + tsm.timing, + tsm.language + ORDER BY tm.time_id ASC, tsm.timing ASC + """; + + return jdbcTemplate.queryForList(sql, visitDate); + } + + public Map getVisitorbasedStatusTillToday() { + + String sql = """ + select + count(id) as totalBookingCount, + COALESCE(count(accepted_people),0) as acceptedPeople, + COALESCE(count(rejected_people),0) as rejectedPeople, + COALESCE(sum(no_of_people),0) as Visitors + from reg_details + where DATE(visit_date) BETWEEN '2026-01-01' AND CURDATE() + and booking_flag = 'B' + """; + + return jdbcTemplate.queryForMap(sql); + } + + // total visit modal + public List> getTotalVisitsSummary(String fromDate, String toDate) { + + String sql = """ + + + + SELECT + d.bookingDate, + COALESCE(r.totalBookingCount,0) AS totalBookingCount, + + d.Adult, + d.Children, + d.SeniorCitizen, + d.Students, + d.Foreigner, + d.PhysicallyChallenged, + d.TotalCount, + + COALESCE(r.accepted_people,0) AS accepted_people, + COALESCE(r.rejected_people,0) AS rejected_people, + + COALESCE(d.NotVisitedCount,0) AS NotVisitedCount + + FROM + ( + -- Visitor counts from visitor_count_details + SELECT + DATE(rd.visit_date) AS bookingDate, + + COALESCE(SUM(CASE WHEN vac.user_type='Adult ' THEN vcd.no_of_people END),0) AS Adult, + COALESCE(SUM(CASE WHEN vac.user_type='Children [ below 10 year]' THEN vcd.no_of_people END),0) AS Children, + COALESCE(SUM(CASE WHEN vac.user_type='Senior Citizen [above 60+]' THEN vcd.no_of_people END),0) AS SeniorCitizen, + COALESCE(SUM(CASE WHEN vac.user_type='Students' THEN vcd.no_of_people END),0) AS Students, + COALESCE(SUM(CASE WHEN vac.user_type='Foreigner' THEN vcd.no_of_people END),0) AS Foreigner, + COALESCE(SUM(CASE WHEN vac.user_type='Physically challeged' THEN vcd.no_of_people END),0) AS PhysicallyChallenged, + COALESCE(SUM(vcd.no_of_people),0) AS TotalCount, + + COALESCE(SUM( + CASE + WHEN rd.entry_status IS NULL THEN vcd.no_of_people + ELSE 0 + END + ),0) AS NotVisitedCount + + FROM reg_details rd + LEFT JOIN visitor_count_details vcd ON rd.ref_id = vcd.ref_id + LEFT JOIN visit_amount_config vac ON vcd.user_type_id = vac.id + WHERE rd.booking_flag = 'B' + AND DATE(rd.visit_date) BETWEEN ? AND ? + GROUP BY DATE(rd.visit_date) + ) d + + LEFT JOIN + ( + -- Accepted / Rejected from reg_details ONLY + SELECT + DATE(visit_date) AS bookingDate, + COUNT(DISTINCT ref_id) AS totalBookingCount, + SUM(accepted_people) AS accepted_people, + SUM(rejected_people) AS rejected_people + FROM reg_details + WHERE booking_flag = 'B' + AND DATE(visit_date) BETWEEN ? AND ? + GROUP BY DATE(visit_date) + ) r + ON d.bookingDate = r.bookingDate + + ORDER BY d.bookingDate; + + """; + + return jdbcTemplate.queryForList(sql, resolveFromDate(fromDate), + resolveToDate(toDate), + resolveFromDate(fromDate), + resolveToDate(toDate)); + } + + public List> getVisitorbookingDetailsByDate(String visitDate) { + + String sql = """ + SELECT + rd.ref_id, + rd.mob_no, + rd.email, + DATE(rd.visit_date) AS visitDate, + DATE(rd.cdate) AS bookingDate, + rd.no_of_people, + rd.total_amount AS amountPaid, + rd.id_details AS IdCardNumber, + tm.timing AS time, + tsm.timing AS slot, + tm.time_id, + tsm.language + FROM reg_details rd LEFT JOIN time_master tm ON rd.time_id = tm.time_id LEFT JOIN avslot_reg_det ard @@ -193,6 +470,7 @@ public class VphService { rd.mob_no, rd.email, DATE(rd.visit_date), + DATE(rd.cdate) , rd.no_of_people, rd.total_amount, rd.id_details, @@ -206,4 +484,106 @@ public class VphService { return jdbcTemplate.queryForList(sql, visitDate); } + + // with date filter + public int getTotalBookingCount(String fromDate, String toDate) { + + String sql = """ + SELECT COUNT(id) + FROM reg_details + WHERE booking_flag='B' + AND DATE(cdate) BETWEEN ? AND ? + """; + + return jdbcTemplate.queryForObject( + sql, + Integer.class, + resolveFromDate(fromDate), + resolveToDate(toDate)); + } + + public Map getCategoryTotals(String fromDate, String toDate) { + + String sql = """ + SELECT IFNULL(vac.user_type,'TOTAL') AS userCategory, + COALESCE(SUM(vcd.no_of_people),0) AS registeredCount + FROM reg_details rd + LEFT JOIN visitor_count_details vcd ON rd.ref_id = vcd.ref_id + LEFT JOIN visit_amount_config vac ON vcd.user_type_id = vac.id + WHERE rd.booking_flag = 'B' + AND DATE(rd.cdate) BETWEEN ? AND ? + GROUP BY vac.user_type WITH ROLLUP + """; + + Map result = new HashMap<>(); + + jdbcTemplate.query( + sql, + new Object[] { + resolveFromDate(fromDate), + resolveToDate(toDate) + }, + rs -> { + result.put( + rs.getString("userCategory"), + rs.getInt("registeredCount")); + }); + + return result; + } + + public Map getVisitorbasedStatus(String fromDate, String toDate) { + + String sql = """ + SELECT + COUNT(id) AS totalBookingCount, + COALESCE(SUM(accepted_people),0) AS acceptedPeople, + COALESCE(SUM(rejected_people),0) AS rejectedPeople, + COALESCE(SUM(no_of_people),0) AS Visitors + FROM reg_details + WHERE booking_flag='B' + AND DATE(visit_date) BETWEEN ? AND ? + """; + + return jdbcTemplate.queryForMap( + sql, + resolveFromDate(fromDate), + resolveToDate(toDate)); + } + + private String resolveFromDate(String fromDate) { + return (fromDate == null || fromDate.isEmpty()) ? "2026-01-01" : fromDate; + } + + private String resolveToDate(String toDate) { + return (toDate == null || toDate.isEmpty()) ? LocalDate.now().toString() : toDate; + } + + public List> getTotalBookedSummary(String fromDate, String toDate) { + + String sql = """ + SELECT DATE(rd.cdate) AS bookingDate, + COUNT(DISTINCT rd.ref_id) AS totalBookingCount, + COALESCE(SUM(CASE WHEN vac.user_type='Adult ' THEN vcd.no_of_people END),0) Adult, + COALESCE(SUM(CASE WHEN vac.user_type='Children [ below 10 year]' THEN vcd.no_of_people END),0) Children, + COALESCE(SUM(CASE WHEN vac.user_type='Senior Citizen [above 60+]' THEN vcd.no_of_people END),0) SeniorCitizen, + COALESCE(SUM(CASE WHEN vac.user_type='Students' THEN vcd.no_of_people END),0) Students, + COALESCE(SUM(CASE WHEN vac.user_type='Foreigner' THEN vcd.no_of_people END),0) Foreigner, + COALESCE(SUM(CASE WHEN vac.user_type='Physically challeged' THEN vcd.no_of_people END),0) PhysicallyChallenged, + COALESCE(SUM(vcd.no_of_people),0) TotalCount + FROM reg_details rd + LEFT JOIN visitor_count_details vcd ON rd.ref_id = vcd.ref_id + LEFT JOIN visit_amount_config vac ON vcd.user_type_id = vac.id + WHERE rd.booking_flag = 'B' + AND DATE(rd.cdate) BETWEEN ? AND ? + GROUP BY DATE(rd.cdate) + ORDER BY DATE(rd.cdate) + """; + + return jdbcTemplate.queryForList( + sql, + resolveFromDate(fromDate), + resolveToDate(toDate)); + } + } \ No newline at end of file diff --git a/src/main/resources/templates/modules/vphreport.html b/src/main/resources/templates/modules/vphreport.html index b42bc69..41b1715 100644 --- a/src/main/resources/templates/modules/vphreport.html +++ b/src/main/resources/templates/modules/vphreport.html @@ -298,9 +298,9 @@
Visitor Booking Details – Category Wise
- +
@@ -556,7 +556,7 @@ `); }); - $('#visitorDetailTable').DataTable({ + /*$('#visitorDetailTable').DataTable({ paging: true, pageLength: 10, lengthMenu: [10, 25, 50, 100], @@ -566,7 +566,7 @@ info: false, buttons: [ { extend: 'excelHtml5', text: 'Download Excel' } - /*{ + { extend: 'pdfHtml5', text: 'Download PDF', orientation: 'landscape', // ✅ MUST @@ -587,10 +587,72 @@ const table = doc.content[1].table; table.widths = Array(table.body[0].length).fill('*'); } - }*/ + } + + ] + }).buttons().container().appendTo('#visitorModalExport');*/ + $('#visitorDetailTable').DataTable({ + paging: true, + pageLength: 10, + lengthMenu: [10, 25, 50, 100], + searching: true, + ordering: true, + dom: 'Bfrtip', + info: false, + buttons: [ + { + extend: 'excelHtml5', + text: 'Download Excel' + }, + { + extend: 'pdfHtml5', + text: 'Download PDF', + orientation: 'landscape', + pageSize: 'A4', + + exportOptions: { + columns: ':visible', + modifier: { + page: 'all' + } + }, + + customize: function (doc) { + + // Smaller font + doc.defaultStyle.fontSize = 7; + doc.styles.tableHeader.fontSize = 8; + + // Tight margins + doc.pageMargins = [10, 10, 10, 10]; + + const table = doc.content[1].table; + + // ✅ FIXED WIDTHS (VERY IMPORTANT) + table.widths = [ + 55, // Ref ID + 60, // Mobile + 90, // Email + 65, // Visit Date + 55, // No. of People + 55, // Amount Paid + 90, // ID Card + 85, // Time + 55, // Slot + 55 // Language + ]; + + // Repeat header on every page + table.headerRows = 1; + + // Prevent row breaking + table.dontBreakRows = true; + } + } ] }).buttons().container().appendTo('#visitorModalExport'); + } }); } diff --git a/src/main/resources/templates/modules/vphreportdashboard.html b/src/main/resources/templates/modules/vphreportdashboard.html new file mode 100644 index 0000000..0f5dde7 --- /dev/null +++ b/src/main/resources/templates/modules/vphreportdashboard.html @@ -0,0 +1,1464 @@ + + + + + + Victoria MIS Dashboard + + + + + + + + + + + +
+
+
+ + + + +
+ + +
+ + +
+

Victoria Public Hall

+
+ + +
+
+ + + +
+
+
Victoria Hall Booking Details
+ +
+ + +
+
+
+
+
Total Bookings
+

+ + 0 + +

+
+
+
+ +
+
+
+
Total Visitors
+ +

+ 0 +

+ +
+
+
+
+
+
+
Senior Citizen
+

+ 0 +

+
+
+
+ +
+
+
+
Adult
+

+ 0 +

+
+
+
+ +
+
+
+
Children
+

+ 0 +

+
+
+
+ + + +
+
+
+
Students
+

+ 0 +

+
+
+
+ +
+
+
+
Foreigner
+

+ 0 +

+
+
+
+ +
+
+
+
Physically Challenged
+

+ 0 +

+
+
+
+ + + + + + + +
+ + + + + + + + + + +
+
Victoria Hall Visitor Details
+ + +
+ + + +
+
+ +
+
+
+
+
Total Scheduled Visits
+

+ + 0 + +

+
+
+
+ + + +
+
+
+
Visitors
+

+ 0 +

+
+
+
+ +
+
+
+
Visitors Accepted
+

+ 0 +

+
+
+
+ +
+
+
+
Visitors Rejected
+

+ 0 +

+
+
+
+ +
+ + +
Hall Booking Details
+
+ + +
+ + + + + + + + + + + + + +
Hall NameUser NameBooking DateEvent Date
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file