From c648526f430bf2ee60de252a26b838318a4fc896 Mon Sep 17 00:00:00 2001 From: bhavesh95863 Date: Fri, 22 May 2026 21:29:30 +0000 Subject: [PATCH 1/3] fix: attendance report directly get the details without report permission --- employee_self_service/mobile/v1/attendance/__init__.py | 3 +-- employee_self_service/mobile/v1/ess.py | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/employee_self_service/mobile/v1/attendance/__init__.py b/employee_self_service/mobile/v1/attendance/__init__.py index 4504f7e..5e567c5 100644 --- a/employee_self_service/mobile/v1/attendance/__init__.py +++ b/employee_self_service/mobile/v1/attendance/__init__.py @@ -154,7 +154,6 @@ def get_ess_calendar_details(year=None, month=None): attendance_data = build_attendance_data( year, month, days_in_month, attendance_records, holidays ) - return gen_response( 200, "ESS calendar data fetched successfully", attendance_data ) @@ -179,7 +178,7 @@ def get_attendance_records(employee, start_date, end_date): def get_employee_holidays(employee, start_date, end_date): """Fetch holiday dates for a given employee and date range.""" holiday_list = get_holiday_list_for_employee(employee, raise_exception=False) - + frappe.log_error(title="holi",message=holiday_list) if not holiday_list: return set() diff --git a/employee_self_service/mobile/v1/ess.py b/employee_self_service/mobile/v1/ess.py index ec03d52..2a6c774 100644 --- a/employee_self_service/mobile/v1/ess.py +++ b/employee_self_service/mobile/v1/ess.py @@ -880,6 +880,7 @@ def get_attendance_details(emp_data, year=None, month=None): @frappe.whitelist() def run_attendance_report(employee, company): + from hrms.hr.report.monthly_attendance_sheet.monthly_attendance_sheet import execute filters = { "filter_based_on": "Month", "month": cstr(frappe.utils.getdate().month), @@ -888,11 +889,10 @@ def run_attendance_report(employee, company): "employee": employee, "summarized_view": 1, } - from frappe.desk.query_report import run - attendance_report = run("Monthly Attendance Sheet", filters=filters) - if attendance_report.get("result"): - return attendance_report.get("result")[0] + columns, data, *_ = execute(filters) + if data: + return data[0] def get_latest_leave(dashboard_data, employee): From c34edf5e32bf8f04d5af14d1817e2e1f6923e722 Mon Sep 17 00:00:00 2001 From: bhavesh95863 Date: Sat, 23 May 2026 08:30:35 +0000 Subject: [PATCH 2/3] fix: attendance calerdar function issues --- .../mobile/v1/attendance/__init__.py | 103 +++++++++++++++++- employee_self_service/mobile/v1/ess.py | 4 +- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/employee_self_service/mobile/v1/attendance/__init__.py b/employee_self_service/mobile/v1/attendance/__init__.py index 5e567c5..f3335d6 100644 --- a/employee_self_service/mobile/v1/attendance/__init__.py +++ b/employee_self_service/mobile/v1/attendance/__init__.py @@ -5,7 +5,7 @@ get_holiday_list_for_employee, ) from frappe import _ -from frappe.utils import cint, getdate +from frappe.utils import add_days, cint, date_diff, flt, getdate, today from employee_self_service.mobile.v1.api_utils import ( convert_timezone, @@ -212,3 +212,104 @@ def build_attendance_data(year, month, days_in_month, attendance_records, holida attendance_data[date_str] = "Holiday" if date in holidays else "No Record" return attendance_data + + +def _get_attendance_summary(employee, year, month): + """ + Compute present/absent/days-off counts for a given month using the same + data sources as get_ess_calendar_details (attendance records + holiday list). + + Returns a dict in the same shape as get_attendance_details in ess.py. + """ + days_in_month = monthrange(year, month)[1] + month_start = getdate(f"{year}-{month:02d}-01") + month_end = getdate(f"{year}-{month:02d}-{days_in_month}") + yesterday = getdate(add_days(today(), -1)) + + if yesterday < month_start: + till_date_days = 0 + elif yesterday > month_end: + till_date_days = days_in_month + else: + till_date_days = date_diff(yesterday, month_start) + 1 + + present_count = flt(0) + leave_count = flt(0) + holidays_till_date = flt(0) + + if till_date_days > 0: + till_date = min(yesterday, month_end) + + attendance_records = get_attendance_records( + employee, + month_start.strftime("%Y-%m-%d"), + month_end.strftime("%Y-%m-%d"), + ) + holidays = get_employee_holidays( + employee, + month_start.strftime("%Y-%m-%d"), + month_end.strftime("%Y-%m-%d"), + ) + + for record in attendance_records: + record_date = getdate(record["attendance_date"]) + if record_date > till_date: + continue + status = record["status"] + if status in ("Present", "Work From Home"): + present_count += 1 + elif status == "Half Day": + present_count += 0.5 + leave_count += 0.5 + elif status == "On Leave": + leave_count += 1 + + holidays_till_date = flt(sum(1 for h in holidays if h <= till_date)) + + days_off = leave_count + holidays_till_date + absent = max(flt(0), flt(till_date_days) - present_count - days_off) + + return { + "month_title": month_start.strftime("%B"), + "data": [ + {"type": "Total Days", "data": [till_date_days, days_in_month]}, + {"type": "Presents", "data": [present_count, till_date_days]}, + {"type": "Absents", "data": [absent, till_date_days]}, + {"type": "Days off", "data": [days_off, till_date_days]}, + ], + } + + +@frappe.whitelist() +def get_attendance_details_dashboard(): + """Current-month attendance summary for the dashboard.""" + try: + emp_data = get_employee_by_user(frappe.session.user, fields=["name", "company"]) + if not emp_data: + return gen_response(404, "Employee not found") + today_date = getdate(today()) + summary = _get_attendance_summary(emp_data["name"], today_date.year, today_date.month) + return gen_response(200, "Attendance data get successfully", summary) + except Exception as e: + return exception_handler(e) + + +@frappe.whitelist() +def get_attendance_details_by_month(year=None, month=None): + """Attendance summary for a given year and month.""" + try: + if not year or not month: + return gen_response(500, "year and month are required") + + year, month = cint(year), cint(month) + today_date = getdate(today()) + if (year, month) > (today_date.year, today_date.month): + return gen_response(400, "Cannot fetch attendance for a future month") + + emp_data = get_employee_by_user(frappe.session.user, fields=["name", "company"]) + if not emp_data: + return gen_response(404, "Employee not found") + summary = _get_attendance_summary(emp_data["name"], year, month) + return gen_response(200, "Attendance data get successfully", summary) + except Exception as e: + return exception_handler(e) \ No newline at end of file diff --git a/employee_self_service/mobile/v1/ess.py b/employee_self_service/mobile/v1/ess.py index 2a6c774..edaa7e5 100644 --- a/employee_self_service/mobile/v1/ess.py +++ b/employee_self_service/mobile/v1/ess.py @@ -754,6 +754,7 @@ def get_leave_balance_dashboard(): return exception_handler(e) +#moved into attendance.py file @frappe.whitelist() def get_attendance_details_dashboard(): try: @@ -1294,7 +1295,7 @@ def get_attendance_list(year=None, month=None): "days_in_month": calendar.monthrange(int(year), int(month))[1], "present": present_count, "absent": absent_count, - "late": late_count, + "late": late_count } attendance_data = { "attendance_details": attendance_details, @@ -2442,6 +2443,7 @@ def get_hr_policies(): return exception_handler(e) +# moved into the attendance.py file @frappe.whitelist() def get_attendance_details_by_month(year, month): try: From 61445b12a86dc00bb13c4b04f802538a3ab34eba Mon Sep 17 00:00:00 2001 From: bhavesh95863 Date: Sat, 23 May 2026 08:34:11 +0000 Subject: [PATCH 3/3] fix: use generic attendance function for the attendance reporting --- employee_self_service/mobile/v1/ess.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/employee_self_service/mobile/v1/ess.py b/employee_self_service/mobile/v1/ess.py index edaa7e5..66d368d 100644 --- a/employee_self_service/mobile/v1/ess.py +++ b/employee_self_service/mobile/v1/ess.py @@ -47,6 +47,7 @@ get_till_date_holiday_month_wise, validate_employee_data, ) +from employee_self_service.mobile.v1.attendance import _get_attendance_summary from employee_self_service.mobile.v1.task import * from employee_self_service.mobile.v1.transactions import * from employee_self_service.utils import add_ess_comment @@ -759,10 +760,11 @@ def get_leave_balance_dashboard(): def get_attendance_details_dashboard(): try: emp_data = get_employee_by_user(frappe.session.user, fields=["name", "company"]) - attendance_details = get_attendance_details(emp_data) - return gen_response( - 200, "Leave balance data get successfully", attendance_details - ) + if not emp_data: + return gen_response(404, "Employee not found") + today_date = getdate() + summary = _get_attendance_summary(emp_data["name"], today_date.year, today_date.month) + return gen_response(200, "Attendance data get successfully", summary) except Exception as e: return exception_handler(e) @@ -2447,11 +2449,15 @@ def get_hr_policies(): @frappe.whitelist() def get_attendance_details_by_month(year, month): try: + year, month = cint(year), cint(month) + today_date = getdate() + if (year, month) > (today_date.year, today_date.month): + return gen_response(400, "Cannot fetch attendance for a future month") emp_data = get_employee_by_user(frappe.session.user, fields=["name", "company"]) - attendance_details = get_attendance_details(emp_data, year, month) - return gen_response( - 200, "Leave balance data get successfully", attendance_details - ) + if not emp_data: + return gen_response(404, "Employee not found") + summary = _get_attendance_summary(emp_data["name"], year, month) + return gen_response(200, "Attendance data get successfully", summary) except Exception as e: return exception_handler(e)