diff --git a/src/main/java/com/gcc/commissionerreview/controller/AttendanceController.java b/src/main/java/com/gcc/commissionerreview/controller/AttendanceController.java index 6fbb396..8de56ff 100644 --- a/src/main/java/com/gcc/commissionerreview/controller/AttendanceController.java +++ b/src/main/java/com/gcc/commissionerreview/controller/AttendanceController.java @@ -86,4 +86,16 @@ public class AttendanceController { return result; } + @GetMapping("/parkWiseSummaryWithFilters") + public Map getParkWiseSummaryWithFilters( + @RequestParam(name = "fromDate", required = false) String fromDate, + @RequestParam(name = "toDate", required = false) String toDate, + @RequestParam(name = "zone", required = false) Integer zone, + @RequestParam(name = "category") String category) { + Map result = attendanceService.getParkWiseSummaryWithFilters(fromDate, toDate, zone, + category); + System.out.println("Park Wise Summary Result: " + result); + return result; + } + } diff --git a/src/main/java/com/gcc/commissionerreview/service/AttendanceService.java b/src/main/java/com/gcc/commissionerreview/service/AttendanceService.java index 9260451..bac741b 100644 --- a/src/main/java/com/gcc/commissionerreview/service/AttendanceService.java +++ b/src/main/java/com/gcc/commissionerreview/service/AttendanceService.java @@ -443,4 +443,200 @@ public class AttendanceService { return Collections.emptyList(); } } + + /** + * Returns park-wise count for a single category, excluding parks where count = + * 0. + * + * Columns returned: park_id, park_name, supervisor_name, supervisor_mobile, + * count + * + * Categories: + * notregistered - employees with facial_attendance = 0 + * present - employees with indatetime in the date range + * od - employees with oddatetime in the date range + * leave - employees with leavedatetime in the date range + * notmarked - facial-registered employees with NO attendance in the date range + * total - all active employees + */ + public Map getParkWiseSummaryWithFilters(String fromDateStr, String toDateStr, Integer zone, + String category) { + try { + + Map response = new java.util.HashMap<>(); + + if (zone == null) { + logger.warn("Method: getParkWiseSummaryWithFilters | zone is null, returning empty list"); + response.put("status", "empty"); + response.put("message", "No data found"); + return response; + } + + LocalDate fromDate; + LocalDate toDate; + + if (fromDateStr == null || fromDateStr.trim().isEmpty()) { + fromDate = LocalDate.now(); + } else { + fromDate = LocalDate.parse(fromDateStr, INPUT_FORMAT); + } + + if (toDateStr == null || toDateStr.trim().isEmpty()) { + toDate = LocalDate.now(); + } else { + toDate = LocalDate.parse(toDateStr, INPUT_FORMAT); + } + + String fromDateTime = fromDate + " 00:00:00"; + String toDateTime = toDate + " 23:59:59"; + + System.out.println("getParkWiseSummaryWithFilters | Category: " + category + + ", Zone: " + zone + ", From: " + fromDateTime + ", To: " + toDateTime); + + // Common SELECT columns (same for every category) + String selectCols = "SELECT et.park_id, " + + "COALESCE(pd.park_name, '') AS park_name, " + + "COALESCE(pd.supervisor_name, '') AS supervisor_name, " + + "COALESCE(pd.supervisor_mobile, '') AS supervisor_mobile, "; + + // Common FROM + park_details JOIN + String fromClause = "FROM enrollment_table et " + + "LEFT JOIN park_details pd ON et.park_id = pd.park_id " + + " AND pd.is_active = 1 AND pd.is_delete = 0 "; + + // Common base WHERE (zone filter applied here) + String baseWhere = "WHERE et.isactive = 1 AND et.isdelete = 0 " + + "AND et.emp_type = 'Park' AND et.zone != 0 AND et.zone = ? "; + + // Common GROUP BY + String groupBy = "GROUP BY et.park_id, pd.park_name, pd.supervisor_name, pd.supervisor_mobile "; + + String sql; + java.util.List params = new java.util.ArrayList<>(); + + if (category != null && category.equalsIgnoreCase("notregistered")) { + // Parks with employees NOT registered for facial attendance + sql = selectCols + + "COUNT(DISTINCT et.enrollment_id) AS totalCount " + + fromClause + + baseWhere + + " AND et.facial_attendance = 0 " + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(zone); + + } else if (category != null && category.equalsIgnoreCase("present")) { + // Parks with employees who marked attendance (indatetime) in the date range + sql = selectCols + + "COUNT(DISTINCT att.enrollment_id) AS totalCount " + + fromClause + + "INNER JOIN attendance att ON et.enrollment_id = att.enrollment_id " + + " AND att.indatetime >= ? AND att.indatetime <= ? " + + " AND att.indatetime IS NOT NULL " + + baseWhere + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(fromDateTime); + params.add(toDateTime); + params.add(zone); + + } else if (category != null && category.equalsIgnoreCase("od")) { + // Parks with employees on OD in the date range + sql = selectCols + + "COUNT(DISTINCT att.enrollment_id) AS totalCount " + + fromClause + + "INNER JOIN attendance att ON et.enrollment_id = att.enrollment_id " + + " AND att.oddatetime >= ? AND att.oddatetime <= ? " + + " AND att.oddatetime IS NOT NULL " + + baseWhere + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(fromDateTime); + params.add(toDateTime); + params.add(zone); + + } else if (category != null && category.equalsIgnoreCase("leave")) { + // Parks with employees on leave in the date range + sql = selectCols + + "COUNT(DISTINCT att.enrollment_id) AS totalCount " + + fromClause + + "INNER JOIN attendance att ON et.enrollment_id = att.enrollment_id " + + " AND att.leavedatetime >= ? AND att.leavedatetime <= ? " + + " AND att.leavedatetime IS NOT NULL " + + baseWhere + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(fromDateTime); + params.add(toDateTime); + params.add(zone); + + } else if (category != null && category.equalsIgnoreCase("notmarked")) { + // Parks with facial-registered employees who have NO attendance in the date + // range + sql = selectCols + + "COUNT(DISTINCT et.enrollment_id) AS totalCount " + + fromClause + + baseWhere + + " AND et.facial_attendance = 1 " + + " AND et.enrollment_id NOT IN ( " + + " SELECT enrollment_id FROM attendance " + + " WHERE date(indatetime) BETWEEN ? AND ? " + + " OR date(oddatetime) BETWEEN ? AND ? " + + " OR date(leavedatetime) BETWEEN ? AND ? " + + " ) " + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(zone); + params.add(fromDate); + params.add(toDate); + params.add(fromDate); + params.add(toDate); + params.add(fromDate); + params.add(toDate); + + } else { + // total — all active employees grouped by park + sql = selectCols + + "COUNT(DISTINCT et.enrollment_id) AS totalCount " + + fromClause + + baseWhere + + groupBy + + "HAVING totalCount > 0 " + + "ORDER BY pd.park_name"; + params.add(zone); + } + + System.out.println("SQL: " + sql); + System.out.println("Params: " + params); + + List> result = jdbcTemplate.queryForList(sql, params.toArray()); + System.out.println("Result size: " + result.size()); + + if (result.isEmpty()) { + + response.put("status", "empty"); + response.put("message", "No data found"); + } else { + response.put("status", "success"); + response.put("data", result); + } + + return response; + + } catch (Exception e) { + logger.error( + "Method: getParkWiseSummaryWithFilters | Parameters: category={}, fromDateStr={}, toDateStr={}, zone={} | Date: {} | Exception: {} - {}", + category, fromDateStr, toDateStr, zone, LocalDateTime.now(), + e.getClass().getName(), e.getMessage(), e); + Map errorResponse = new java.util.HashMap<>(); + errorResponse.put("status", "error"); + errorResponse.put("message", "An error occurred while fetching data"); + return errorResponse; + } + } }