Skip to content

Commit

Permalink
Merge pull request #711 from frappe/mergify/bp/version-14-hotfix/pr-709
Browse files Browse the repository at this point in the history
fix: don't consider default shift in overlapping period if curr shift is found (backport #709)
  • Loading branch information
ruchamahabal authored Jul 20, 2023
2 parents 942a55a + 106c40d commit 9443af8
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
39 changes: 12 additions & 27 deletions hrms/hr/doctype/shift_assignment/shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def _is_timestamp_within_shift(shift_details: dict, for_timestamp: datetime) ->
def _adjust_overlapping_shifts(shifts: dict):
"""
Compares 2 consecutive shifts and adjusts start and end times
if they are overlapping within grace period
if they are overlapping within extension period (begin checkin before.. to allow checkout after..)
"""
for i in range(len(shifts) - 1):
curr_shift = shifts[i]
Expand Down Expand Up @@ -379,44 +379,29 @@ def get_employee_shift_timings(
if for_timestamp is None:
for_timestamp = now_datetime()

# write and verify a test case for midnight shift.
prev_shift = curr_shift = next_shift = None
curr_shift = get_employee_shift(employee, for_timestamp, consider_default_shift, "forward")

# don't consider default shift in overlapping period as curr shift is already fetched
# default shift is supposed to be used as a fallback
consider_default_shift_in_overlapping_period = False if curr_shift else consider_default_shift

if curr_shift:
next_shift = get_employee_shift(
employee, curr_shift.start_datetime + timedelta(days=1), consider_default_shift, "forward"
employee,
curr_shift.start_datetime + timedelta(days=1),
consider_default_shift_in_overlapping_period,
"forward",
)
prev_shift = get_employee_shift(
employee,
(curr_shift.end_datetime if curr_shift else for_timestamp) + timedelta(days=-1),
consider_default_shift,
consider_default_shift_in_overlapping_period,
"reverse",
)

if curr_shift:
# adjust actual start and end times if they are overlapping with grace period (before start and after end)
if prev_shift:
curr_shift.actual_start = (
prev_shift.end_datetime
if curr_shift.actual_start < prev_shift.end_datetime
else curr_shift.actual_start
)
prev_shift.actual_end = (
curr_shift.actual_start
if prev_shift.actual_end > curr_shift.actual_start
else prev_shift.actual_end
)
if next_shift:
next_shift.actual_start = (
curr_shift.end_datetime
if next_shift.actual_start < curr_shift.end_datetime
else next_shift.actual_start
)
curr_shift.actual_end = (
next_shift.actual_start
if curr_shift.actual_end > next_shift.actual_start
else curr_shift.actual_end
)
_adjust_overlapping_shifts([prev_shift, curr_shift, next_shift])

return prev_shift, curr_shift, next_shift

Expand Down
20 changes: 14 additions & 6 deletions hrms/hr/doctype/shift_assignment/test_shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,17 +228,25 @@ def test_consecutive_day_and_night_shifts(self):
)
make_shift_assignment(shift_type.name, employee, yesterday, yesterday)

# prev shift log
prev_shift = get_actual_start_end_datetime_of_shift(
# prev shift logs
prev_shift_1 = get_actual_start_end_datetime_of_shift(
employee, get_datetime(f"{today} 07:00:00"), True
)
self.assertEqual(prev_shift.shift_type.name, "Test Security - Night")
self.assertEqual(prev_shift.actual_start.date(), yesterday)
self.assertEqual(prev_shift.actual_end.date(), today)
# Even though default shift is from 7-19,
# assigned shift (night shift) has 60 mins of allowed checkout period.
# So assigned shift should have precedence over default shift for 7:01 AM
prev_shift_2 = get_actual_start_end_datetime_of_shift(
employee, get_datetime(f"{today} 07:01:00"), True
)

for checkin in [prev_shift_1, prev_shift_2]:
self.assertEqual(checkin.shift_type.name, "Test Security - Night")
self.assertEqual(checkin.actual_start.date(), yesterday)
self.assertEqual(checkin.actual_end.date(), today)

# current shift IN
checkin = get_actual_start_end_datetime_of_shift(
employee, get_datetime(f"{today} 07:01:00"), True
employee, get_datetime(f"{today} 08:01:00"), True
)
# current shift OUT
checkout = get_actual_start_end_datetime_of_shift(
Expand Down

0 comments on commit 9443af8

Please sign in to comment.