diff --git a/hrms/hr/doctype/shift_assignment/shift_assignment.py b/hrms/hr/doctype/shift_assignment/shift_assignment.py index 24749e80b9..70f5d99043 100644 --- a/hrms/hr/doctype/shift_assignment/shift_assignment.py +++ b/hrms/hr/doctype/shift_assignment/shift_assignment.py @@ -159,19 +159,21 @@ def get_events(start, end, filters=None): employee = "" company = frappe.db.get_value("Global Defaults", None, "default_company") - events = add_assignments(start, end, filters) - return events + assignments = get_shift_assignments(start, end, filters) + return get_shift_events(assignments) -def add_assignments(start, end, filters): +def get_shift_assignments(start: str, end: str, filters: str | list | None = None) -> list[dict]: import json - events = [] if isinstance(filters, str): filters = json.loads(filters) + if not filters: + filters = [] + filters.extend([["start_date", ">=", start], ["end_date", "<=", end], ["docstatus", "=", 1]]) - records = frappe.get_list( + return frappe.get_list( "Shift Assignment", filters=filters, fields=[ @@ -185,21 +187,28 @@ def add_assignments(start, end, filters): ], ) - shift_timing_map = get_shift_type_timing([d.shift_type for d in records]) - for d in records: +def get_shift_events(assignments: list[dict]) -> list[dict]: + events = [] + shift_timing_map = get_shift_type_timing([d.shift_type for d in assignments]) + + for d in assignments: daily_event_start = d.start_date - daily_event_end = d.end_date if d.end_date else getdate() + daily_event_end = d.end_date or getdate() + shift_start = shift_timing_map[d.shift_type]["start_time"] + shift_end = shift_timing_map[d.shift_type]["end_time"] + delta = timedelta(days=1) while daily_event_start <= daily_event_end: - start_timing = ( - frappe.utils.get_datetime(daily_event_start) + shift_timing_map[d.shift_type]["start_time"] - ) - end_timing = ( - frappe.utils.get_datetime(daily_event_start) + shift_timing_map[d.shift_type]["end_time"] - ) - daily_event_start += delta - e = { + start_timing = frappe.utils.get_datetime(daily_event_start) + shift_start + + if shift_start > shift_end: + # shift spans across 2 days + end_timing = frappe.utils.get_datetime(daily_event_start) + shift_end + delta + else: + end_timing = frappe.utils.get_datetime(daily_event_start) + shift_end + + event = { "name": d.name, "doctype": "Shift Assignment", "start_date": start_timing, @@ -209,8 +218,10 @@ def add_assignments(start, end, filters): "allDay": 0, "convertToUserTz": 0, } - if e not in events: - events.append(e) + if event not in events: + events.append(event) + + daily_event_start += delta return events diff --git a/hrms/hr/doctype/shift_assignment/test_shift_assignment.py b/hrms/hr/doctype/shift_assignment/test_shift_assignment.py index e5f05d1488..7752223fb3 100644 --- a/hrms/hr/doctype/shift_assignment/test_shift_assignment.py +++ b/hrms/hr/doctype/shift_assignment/test_shift_assignment.py @@ -227,7 +227,7 @@ def test_multiple_shift_assignments_for_same_day(self): date = getdate() make_shift_assignment(shift_type.name, employee, date) - def test_shift_assignment_calendar(self): + def test_calendar(self): employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company") employee2 = make_employee("test_shift_assignment2@example.com", company="_Test Company") @@ -242,6 +242,17 @@ def test_shift_assignment_calendar(self): self.assertEqual(len(events), 1) self.assertEqual(events[0]["name"], shift1.name) + def test_calendar_for_night_shift(self): + employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company") + + shift_type = setup_shift_type(shift_type="Shift 1", start_time="08:00:00", end_time="02:00:00") + date = getdate() + shift = make_shift_assignment(shift_type.name, employee1, date, date) + + events = get_events(start=date, end=date) + self.assertEqual(events[0]["start_date"], get_datetime(f"{date} 08:00:00")) + self.assertEqual(events[0]["end_date"], get_datetime(f"{add_days(date, 1)} 02:00:00")) + def test_consecutive_day_and_night_shifts(self): # defaults employee = make_employee("test_default_shift_assignment@example.com", company="_Test Company")