Skip to content

Commit

Permalink
Merge pull request #1284 from frappe/mergify/bp/version-14-hotfix/pr-…
Browse files Browse the repository at this point in the history
…1282

fix: incorrect night shift assignment timings in shift calendar (backport #1282)
  • Loading branch information
ruchamahabal authored Jan 9, 2024
2 parents d43fa5e + b100d32 commit 8bd256d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
47 changes: 29 additions & 18 deletions hrms/hr/doctype/shift_assignment/shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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=[
Expand All @@ -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,
Expand All @@ -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

Expand Down
13 changes: 12 additions & 1 deletion hrms/hr/doctype/shift_assignment/test_shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("[email protected]", company="_Test Company")
employee2 = make_employee("[email protected]", company="_Test Company")

Expand All @@ -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("[email protected]", 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("[email protected]", company="_Test Company")
Expand Down

0 comments on commit 8bd256d

Please sign in to comment.