fix: handle shift grace overlap while finding current shift
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 86564e0..88aeb4c 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -8,7 +8,7 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.query_builder import Criterion, Column
-from frappe.utils import cstr, get_link_to_form, getdate, now_datetime, nowdate
+from frappe.utils import cstr, get_link_to_form, get_datetime, getdate, now_datetime, nowdate
 
 from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
 from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday
@@ -172,10 +172,33 @@
 
 
 def get_shift_for_time(shifts, for_timestamp):
+	valid_shifts = []
 	for entry in shifts:
 		shift_details = get_shift_details(entry.shift_type, for_date=for_timestamp.date())
-		if shift_details.actual_start <= for_timestamp <= shift_details.actual_end:
-			return shift_details
+
+		if get_datetime(shift_details.actual_start) <= get_datetime(for_timestamp) <= get_datetime(shift_details.actual_end):
+			valid_shifts.append(shift_details)
+
+	valid_shifts.sort(key=lambda x: x['actual_start'])
+
+	if len(valid_shifts) > 1:
+		for i in range(len(valid_shifts) - 1):
+			# comparing 2 consecutive shifts and adjusting start and end times
+			# if they are overlapping within grace period
+			curr_shift = valid_shifts[i]
+			next_shift = valid_shifts[i + 1]
+
+			if curr_shift and 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
+
+			valid_shifts[i] = curr_shift
+			valid_shifts[i + 1] = next_shift
+
+		exact_shift = get_exact_shift(valid_shifts, for_timestamp)
+		return exact_shift and exact_shift[2]
+
+	return valid_shifts and valid_shifts[0]
 
 
 def get_shifts_for_date(employee, for_timestamp):
@@ -251,7 +274,7 @@
 		sort_order = 'desc' if next_shift_direction == 'reverse' else 'asc'
 		dates = frappe.db.get_all('Shift Assignment',
 			['start_date', 'end_date'],
-			{'employee':employee, 'start_date': (direction, for_timestamp.date()), 'docstatus': '1', "status": "Active"},
+			{'employee': employee, 'start_date': (direction, for_timestamp.date()), 'docstatus': 1, 'status': 'Active'},
 			as_list=True,
 			limit=MAX_DAYS, order_by='start_date ' + sort_order)
 
@@ -259,7 +282,7 @@
 			for date in dates:
 				if date[1] and date[1] < for_timestamp.date():
 					continue
-				shift_details = get_employee_shift(employee, datetime.combine(date, for_timestamp.time()), consider_default_shift, None)
+				shift_details = get_employee_shift(employee, datetime.combine(date[0], for_timestamp.time()), consider_default_shift, None)
 				if shift_details:
 					break
 
@@ -320,11 +343,15 @@
 		None is returned if the timestamp is outside any actual shift timings.
 		Shift Details is also returned(current/upcoming i.e. if timestamp not in any actual shift then details of next shift returned)
 	"""
-	actual_shift_start = actual_shift_end = shift_details = None
 	shift_timings_as_per_timestamp = get_employee_shift_timings(employee, for_datetime, consider_default_shift)
+	return get_exact_shift(shift_timings_as_per_timestamp, for_datetime)
+
+
+def get_exact_shift(shifts, for_datetime):
+	actual_shift_start = actual_shift_end = shift_details = None
 	timestamp_list = []
 
-	for shift in shift_timings_as_per_timestamp:
+	for shift in shifts:
 		if shift:
 			timestamp_list.extend([shift.actual_start, shift.actual_end])
 		else:
@@ -337,11 +364,11 @@
 			break
 
 	if timestamp_index and timestamp_index%2 == 1:
-		shift_details = shift_timings_as_per_timestamp[int((timestamp_index-1)/2)]
+		shift_details = shifts[int((timestamp_index-1)/2)]
 		actual_shift_start = shift_details.actual_start
 		actual_shift_end = shift_details.actual_end
 	elif timestamp_index:
-		shift_details = shift_timings_as_per_timestamp[int(timestamp_index/2)]
+		shift_details = shifts[int(timestamp_index/2)]
 
 	return actual_shift_start, actual_shift_end, shift_details