|
|
|
@ -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<String, Object> getParkWiseSummaryWithFilters(String fromDateStr, String toDateStr, Integer zone, |
|
|
|
String category) { |
|
|
|
try { |
|
|
|
|
|
|
|
Map<String, Object> 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<Object> 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<Map<String, Object>> 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<String, Object> errorResponse = new java.util.HashMap<>(); |
|
|
|
errorResponse.put("status", "error"); |
|
|
|
errorResponse.put("message", "An error occurred while fetching data"); |
|
|
|
return errorResponse; |
|
|
|
} |
|
|
|
} |
|
|
|
} |