From bbc2b7d453a8298e8dcce5b4ac0742a1a9c23b91 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 19:47:31 +0530 Subject: [PATCH 1/4] fix: set intro message for leave application (backport #1696) (#1741) * fix: set intro message for leave application * fix: set intro message for leave application * fix: make the message consistent --------- Co-authored-by: Rucha Mahabal (cherry picked from commit ab834b8f74e31a035ef25d5b163c1a3fe13a89ca) Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com> --- hrms/hr/doctype/leave_application/leave_application.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hrms/hr/doctype/leave_application/leave_application.js b/hrms/hr/doctype/leave_application/leave_application.js index 28b3933366..1d9a4ab2d1 100755 --- a/hrms/hr/doctype/leave_application/leave_application.js +++ b/hrms/hr/doctype/leave_application/leave_application.js @@ -100,6 +100,15 @@ frappe.ui.form.on("Leave Application", { frm.set_intro(""); if (frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) { frm.set_intro(__("Fill the form and save it")); + } else if ( + frm.perm[0] && + frm.perm[0].submit && + !frm.is_dirty() && + !frm.is_new() && + !frappe.model.has_workflow(this.doctype) && + frm.doc.docstatus === 0 + ) { + frm.set_intro(__("Submit this Leave Application to confirm.")); } frm.trigger("set_employee"); From 4efdb1ff4ced63a3b846caeab7869e704f245b97 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 12:03:09 +0530 Subject: [PATCH 2/4] chore: grant Employee role read permission for Payroll Period (backport #1746) (#1747) * chore: grant Employee role read permission for Payroll Period (#1746) (cherry picked from commit ce8647884e93792037c9fd8b820b5f8f31e948e8) # Conflicts: # hrms/payroll/doctype/payroll_period/payroll_period.json * chore: fix conflicts --------- Co-authored-by: Rucha Mahabal --- .../doctype/payroll_period/payroll_period.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hrms/payroll/doctype/payroll_period/payroll_period.json b/hrms/payroll/doctype/payroll_period/payroll_period.json index 0e0948475c..ee729a586d 100644 --- a/hrms/payroll/doctype/payroll_period/payroll_period.json +++ b/hrms/payroll/doctype/payroll_period/payroll_period.json @@ -53,7 +53,7 @@ } ], "links": [], - "modified": "2020-06-29 17:17:12.689089", + "modified": "2024-05-05 14:50:12.419714", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll Period", @@ -71,6 +71,15 @@ "share": 1, "write": 1 }, + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", + "share": 1 + }, { "create": 1, "delete": 1, From 03b0cafecce93399a59b52b3428cb2f93020bfce Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 6 May 2024 12:00:53 +0530 Subject: [PATCH 3/4] fix(Auto Attendance): incorrect previous shift computation for a timestamp leading to incorrect absent marking (cherry picked from commit cda77bbb1673483117f2e83e45d3d913407606b5) --- hrms/hr/doctype/shift_assignment/shift_assignment.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hrms/hr/doctype/shift_assignment/shift_assignment.py b/hrms/hr/doctype/shift_assignment/shift_assignment.py index f6b2d34f5f..5cdd5d7d9b 100644 --- a/hrms/hr/doctype/shift_assignment/shift_assignment.py +++ b/hrms/hr/doctype/shift_assignment/shift_assignment.py @@ -459,7 +459,11 @@ def get_prev_or_next_shift( for date_range in shift_dates: # midnight shifts will span more than a day start_date, end_date = date_range[0], add_days(date_range[1], 1) - reverse = next_shift_direction == "reverse" + + if reverse := (next_shift_direction == "reverse"): + end_date = min(end_date, for_timestamp.date()) + elif next_shift_direction == "forward": + start_date = max(start_date, for_timestamp.date()) for dt in generate_date_range(start_date, end_date, reverse=reverse): shift_details = get_employee_shift( From 15686c044cbdf6bd0e1fec62bb76ff1e350a52f2 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 7 May 2024 21:17:29 +0530 Subject: [PATCH 4/4] test: prev & curr shift edge cases (cherry picked from commit ab2f10975ded330f9522003f8a228973a8726248) --- .../shift_assignment/test_shift_assignment.py | 33 +++++++++++++++++++ hrms/hr/doctype/shift_type/test_shift_type.py | 23 +++++++++++++ 2 files changed, 56 insertions(+) diff --git a/hrms/hr/doctype/shift_assignment/test_shift_assignment.py b/hrms/hr/doctype/shift_assignment/test_shift_assignment.py index 2473c728dc..a33aba7abf 100644 --- a/hrms/hr/doctype/shift_assignment/test_shift_assignment.py +++ b/hrms/hr/doctype/shift_assignment/test_shift_assignment.py @@ -295,3 +295,36 @@ def test_consecutive_day_and_night_shifts(self): self.assertEqual(checkin.shift_type, checkout.shift_type) self.assertEqual(checkin.actual_start.date(), today) self.assertEqual(checkout.actual_end.date(), today) + + def test_shift_details_on_consecutive_days_with_overlapping_timings(self): + # defaults + employee = make_employee("test_shift_assignment@example.com", company="_Test Company") + today = getdate() + yesterday = add_days(today, -1) + + # shift 1 + shift_type = setup_shift_type(shift_type="Morning", start_time="07:00:00", end_time="12:00:00") + make_shift_assignment(shift_type.name, employee, add_days(yesterday, -1), yesterday) + + # shift 2 + shift_type = setup_shift_type(shift_type="Afternoon", start_time="09:30:00", end_time="14:00:00") + make_shift_assignment(shift_type.name, employee, today, add_days(today, 1)) + + # current_shift shift log - checkin in the grace period of current shift, non-overlapping with prev shift + current_shift = get_actual_start_end_datetime_of_shift( + employee, get_datetime(f"{today} 14:01:00"), True + ) + self.assertEqual(current_shift.shift_type.name, "Afternoon") + self.assertEqual(current_shift.actual_start, get_datetime(f"{today} 08:30:00")) + self.assertEqual(current_shift.actual_end, get_datetime(f"{today} 15:00:00")) + + # previous shift + checkin = get_actual_start_end_datetime_of_shift( + employee, get_datetime(f"{yesterday} 07:01:00"), True + ) + checkout = get_actual_start_end_datetime_of_shift( + employee, get_datetime(f"{yesterday} 13:00:00"), True + ) + self.assertTrue(checkin.shift_type.name == checkout.shift_type.name == "Morning") + self.assertEqual(checkin.actual_start, get_datetime(f"{yesterday} 06:00:00")) + self.assertEqual(checkout.actual_end, get_datetime(f"{yesterday} 13:00:00")) diff --git a/hrms/hr/doctype/shift_type/test_shift_type.py b/hrms/hr/doctype/shift_type/test_shift_type.py index 1932d6c7ca..99602c03fe 100644 --- a/hrms/hr/doctype/shift_type/test_shift_type.py +++ b/hrms/hr/doctype/shift_type/test_shift_type.py @@ -371,6 +371,29 @@ def test_mark_absent_for_dates_with_no_attendance_for_midnight_shift(self): self.assertEqual(len(absent_records), 2) def test_do_not_mark_absent_before_shift_actual_end_time(self): + from hrms.hr.doctype.employee_checkin.test_employee_checkin import make_checkin + + employee = make_employee("test_employee_checkin@example.com", company="_Test Company") + today = getdate() + yesterday = add_days(today, -1) + + # shift 1 + shift_1 = setup_shift_type(shift_type="Morning", start_time="07:00:00", end_time="12:30:00") + make_shift_assignment(shift_1.name, employee, add_days(yesterday, -1), yesterday) + + # shift 2 + shift_2 = setup_shift_type(shift_type="Afternoon", start_time="09:30:00", end_time="18:00:00") + make_shift_assignment(shift_2.name, employee, today, add_days(today, 1)) + + # update last sync of checkin for shift 2 + shift_2.process_attendance_after = add_days(today, -2) + shift_2.last_sync_of_checkin = datetime.combine(today, get_time("09:01:00")) + shift_2.save() + shift_2.process_auto_attendance() + + self.assertIsNone(frappe.db.get_value("Attendance", {"attendance_date": today, "employee": employee})) + + def test_do_not_mark_absent_before_shift_actual_end_time_for_midnight_shift(self): """ Tests employee is not marked absent for a shift spanning 2 days before its actual end time