Hello, I have configure two shifts as mentioned below:
I want to auto detect shift (with allowing early checkin and late checkout) based on the time the employee check-in logs while marking auto attendance
I have updated shift and log type based on time on before save event of employee check-in doctype by using below code,
Name = doc.name
emp = doc.employee
company = doc.company
checkin_time = doc.time
nightShift="Night Shift - SU2"
dayShift="Day Shift - SU2"
Time = frappe.utils.get_datetime(checkin_time)
today_time = frappe.utils.get_time(checkin_time)
today_date = frappe.utils.get_date_str(checkin_time)
today_date_notstr = Time.date()
today = str(today_date_notstr)
yesterday_Date = frappe.utils.add_days(today_date, -1)
yesterday_Date_str = str(yesterday_Date)
ans1 = frappe.utils.get_datetime(yesterday_Date)
ans2 = ans1.date()
ans3 = str(ans2)
tomorrow_date = frappe.utils.add_days(today_date, 1)
tomorrow_date_str = str(tomorrow_date)
# Day Shift Fields
dayData = frappe.db.get_value('Shift Type', dayShift, ['start_time','end_time','begin_check_in_before_shift_start_time','allow_check_out_after_shift_end_time'])
dayStart = dayData[0]
day_start_datetime = frappe.utils.format_time(dayStart, "HH:mm:ss")
dayEnd = dayData[1]
day_end_datetime = frappe.utils.format_time(dayEnd, "HH:mm:ss")
dayBegin = dayData[2]
dayAfter = dayData[3]
# Night Shift Fields
nightData = frappe.db.get_value('Shift Type', nightShift, ['start_time','end_time','begin_check_in_before_shift_start_time','allow_check_out_after_shift_end_time'])
nightStart = nightData[0]
night_start_datetime = frappe.utils.format_time(nightStart, "HH:mm:ss")
nightStart_Str = str(night_start_datetime)
nightEnd = nightData[1]
night_end_datetime = frappe.utils.format_time(nightEnd, "HH:mm:ss")
nightEnd_Str = str(night_end_datetime)
nightBegin = nightData[2]
nightBegin_Str = str(nightBegin)
duration_seconds = nightBegin * 60
night_Begin = frappe.utils.format_duration(duration_seconds, "HH:mm:ss")
final_Begin = frappe.utils.format_time(night_Begin, "HH:mm:ss")
nightAfter = nightData[3]
# Night Shift - Actual Start Time and Actual End Time
night_start_today = today+" "+nightStart_Str
night_start_today_formated = frappe.utils.format_datetime(night_start_today,"YYYY-MM-dd HH:mm:ss")
night_start_today_1 = frappe.utils.add_to_date(night_start_today_formated, minutes=-nightBegin)
Final_Night_Start_Today = frappe.utils.format_datetime(night_start_today_1,"YYYY-MM-dd HH:mm:ss")
night_end_tomorrow = tomorrow_date_str+" "+nightEnd_Str
night_end_tomorrow_formated = frappe.utils.format_datetime(night_end_tomorrow,"YYYY-MM-dd HH:mm:ss")
night_end_tomorrow_1 = frappe.utils.add_to_date(night_end_tomorrow_formated, minutes=nightAfter)
Final_Night_End_Tomorrow = frappe.utils.format_datetime(night_end_tomorrow_1,"YYYY-MM-dd HH:mm:ss")
night_end_today = today+" "+nightEnd_Str
night_end_today_1 = frappe.utils.add_to_date(night_end_today, minutes=nightAfter, as_datetime=True, as_string=True)
night_start_yesterday = ans3+" "+nightStart_Str
night_start_yesterday_1 = frappe.utils.add_to_date(night_start_yesterday, minutes=-nightBegin, as_datetime=True, as_string=True)
# Day Shift - Actual Start Time and Actual End Time
day_start = today+" "+day_start_datetime
day_start_formated = frappe.utils.format_datetime(day_start,"YYYY-MM-dd HH:mm:ss")
day_before = frappe.utils.add_to_date(day_start_formated, minutes=-dayBegin)
day_new_before = frappe.utils.format_datetime(day_before,"YYYY-MM-dd HH:mm:ss")
day_end = today_date+' '+day_end_datetime
day_start_formated = frappe.utils.format_datetime(day_end,"YYYY-MM-dd HH:mm:ss")
day_after = frappe.utils.add_to_date(day_end, minutes=dayAfter)
day_new_after = frappe.utils.format_datetime(day_after,"YYYY-MM-dd HH:mm:ss")
# Day Shift
Day_Start = frappe.utils.get_time(day_new_before)
Day_Shift_1 = today_date+' '+day_end_datetime
Day_Shift_1_formated = frappe.utils.format_datetime(Day_Shift_1,"YYYY-MM-dd HH:mm:ss")
Day_Shift_End = frappe.utils.add_to_date(Day_Shift_1_formated, hours=-1.5)
Final_Day_End = frappe.utils.format_datetime(Day_Shift_End,"YYYY-MM-dd HH:mm:ss")
Day_End = frappe.utils.get_time(Final_Day_End)
# Night Shift
Night_Start = frappe.utils.get_time(Final_Night_Start_Today)
day_record = frappe.get_list("Employee Checkin", filters={"employee": emp, "date":today_date, "shift":dayShift, 'log_type':"IN"}, fields=['name','shift'])
night_record = frappe.get_list("Employee Checkin", filters={"employee": emp, "date":yesterday_Date, "shift":nightShift, 'log_type':"IN"}, fields=['name','shift'])
night_record2 = frappe.get_list("Employee Checkin", filters={"employee": emp, "date":today_date, "shift":nightShift, "log_type": "OUT"}, fields=['name','shift'])
if day_record:
Shift = day_record[0].shift
doc.shift = Shift
doc.log_type = "OUT"
doc.shift_actual_start = day_new_before
doc.shift_actual_end = day_new_after
elif (night_record and not night_record2):
nShift = night_record[0].shift
doc.shift = nShift
doc.log_type = "OUT"
doc.shift_actual_start = night_start_yesterday_1
doc.shift_actual_end = night_end_today_1
else:
if Day_Start <= today_time < Day_End:
doc.shift = "Day Shift - SU2"
doc.log_type = "IN"
doc.shift_actual_start = day_new_before
doc.shift_actual_end = day_new_after
elif Night_Start <= today_time:
doc.shift = "Night Shift - SU2"
doc.log_type = "IN"
doc.shift_actual_start = Final_Night_Start_Today
doc.shift_actual_end = Final_Night_End_Tomorrow
While marking attendance, the problem is that if the time of employee check-in is outside of its shift time, then it considers only the check-in record and does not consider the checkout record, and because of it working hours are not calculated
Employee Checkin Logs
Attendance
Please anyone can help me to figure out this issue
Thanks in advance!