def validate_if_attendance_not_applicable(self, attendance_date): # Check if attendance_date is a Holiday if is_holiday(self.employee, attendance_date): frappe.msgprint( _("Attendance not submitted for {0} as it is a Holiday." ).format(attendance_date), alert=1) return True # Check if employee on Leave leave_record = frappe.db.sql( """select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and docstatus = 1""", (self.employee, attendance_date), as_dict=True, ) if leave_record: frappe.msgprint( _("Attendance not submitted for {0} as {1} on leave.").format( attendance_date, self.employee), alert=1, ) return True return False
def check_employee_wise_availability(date, practitioner_doc): employee = None if practitioner_doc.employee: employee = practitioner_doc.employee elif practitioner_doc.user_id: employee = frappe.db.get_value('Employee', {'user_id': practitioner_doc.user_id}, 'name') if employee: # check holiday if is_holiday(employee, date): frappe.throw(_('{0} is a holiday'.format(date)), title=_('Not Available')) # check leave status leave_record = frappe.db.sql( """select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: frappe.throw(_('{0} is on a Half day Leave on {1}').format( practitioner_doc.name, date), title=_('Not Available')) else: frappe.throw(_('{0} is on Leave on {1}').format( practitioner_doc.name, date), title=_('Not Available'))
def test_is_holiday(self): from erpnext.hr.doctype.employee.employee import is_holiday self.assertTrue(is_holiday(self.test_employee.name)) self.assertTrue( is_holiday(self.test_employee.name, date=self.test_holiday_dates[1])) self.assertFalse( is_holiday(self.test_employee.name, date=getdate() - timedelta(days=1))) # Test weekly_off holidays self.assertTrue( is_holiday(self.test_employee.name, date=self.test_holiday_dates[2])) self.assertFalse( is_holiday(self.test_employee.name, date=self.test_holiday_dates[2], only_non_weekly=True)) # Test with descriptions has_holiday, descriptions = is_holiday(self.test_employee.name, with_description=True) self.assertTrue(has_holiday) self.assertTrue('test holiday1' in descriptions)
def get_employee_emails(company, only_working=True): '''Returns list of Employee user ids for the given company who are working today :param company: Company `name`''' employee_list = frappe.get_all('Employee', fields=['name', 'user_id'], filters={'status': 'Active', 'company': company}) out = [] for e in employee_list: if e.user_id: if only_working and is_holiday(e.name): # don't add if holiday continue out.append(e.user_id) return out
def get_employee_emails(company, only_working=True): '''Returns list of Employee user ids for the given company who are working today :param company: Company `name`''' employee_list = frappe.get_all('Employee', fields=['name', 'user_id'], filters={'status': 'Active', 'company': company}) out = [] for e in employee_list: if e.user_id: if only_working and is_holiday(e.name): # don't add if holiday continue out.append(e.user_id) return out
def get_availability_data(date, physician): """ Get availability data of 'physician' on 'date' :param date: Date to check in schedule :param physician: Name of the physician :return: dict containing a list of available slots, list of appointments and time of appointments """ date = getdate(date) weekday = date.strftime("%A") available_slots = [] slot_details = [] physician_schedule = None employee = None physician_obj = frappe.get_doc("Physician", physician) # Get Physician employee relation if physician_obj.employee: employee = physician_obj.employee elif physician_obj.user_id: if frappe.db.exists({ "doctype": "Employee", "user_id": physician_obj.user_id }): employee = frappe.get_doc("Employee", {"user_id": physician_obj.user_id}).name if employee: # Check if it is Holiday if is_holiday(employee, date): frappe.throw(_("{0} is a company holiday".format(date))) # Check if He/She on Leave leave_record = frappe.db.sql("""select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: frappe.throw(_("Dr {0} on Half day Leave on {1}").format(physician, date)) else: frappe.throw(_("Dr {0} on Leave on {1}").format(physician, date)) # get physicians schedule if physician_obj.physician_schedules: for schedule in physician_obj.physician_schedules: if schedule.schedule: physician_schedule = frappe.get_doc("Physician Schedule", schedule.schedule) else: frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician))) if physician_schedule: available_slots = [] for t in physician_schedule.time_slots: if weekday == t.day: available_slots.append(t) if available_slots: appointments = [] if schedule.service_unit: slot_name = schedule.schedule+" - "+schedule.service_unit allow_overlap = frappe.get_value('Patient Service Unit', schedule.service_unit, 'overlap_appointments') if allow_overlap: # fetch all appointments to physician by service unit appointments = frappe.get_all( "Patient Appointment", filters={"physician": physician, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) else: # fetch all appointments to service unit appointments = frappe.get_all( "Patient Appointment", filters={"service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) else: slot_name = schedule.schedule # fetch all appointments to physician without service unit appointments = frappe.get_all( "Patient Appointment", filters={"physician": physician, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit, "avail_slot":available_slots, 'appointments': appointments}) else: frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician))) if not available_slots and not slot_details: # TODO: return available slots in nearby dates frappe.throw(_("Physician not available on {0}").format(weekday)) return { "slot_details": slot_details }
def attendence_proccessing(employee_list, status, start_date, leave_type=None, company=None, end_date=None): validate_dates(start_date, end_date) employee_list = json.loads(employee_list) days_types = { "Present": "P", "Absent": "A", "Half Day": "HD", "On Leave": "L", "None": "", "Unallocated": "<b>U</b>" } dict_days = frappe._dict() start_date, end_date = getdate(start_date), getdate(end_date) leave_type = "" for single_date in daterange(start_date, end_date): curr_single_date = getdate(single_date) # is_holiday = False for employee in employee_list: employee["date"] = curr_single_date attendance_log = get_emp_log(curr_single_date, employee["employee"]) # frappe.msgprint(str(attendance_log)) if attendance_log == []: is_leave_mission_rest = check_leave_mission_rest( employee["employee"], curr_single_date) if (not is_leave_mission_rest) and (not is_holiday( employee["employee"], curr_single_date)): add_attendance(employee, "Absent", curr_single_date, attend_time="", leave_time="") else: # Check if Emp is Assigned to Period and return Period data emp_data_Dic = check_assigned_period(employee['employee'], curr_single_date) if emp_data_Dic == []: dict_days[curr_single_date] = days_types[ "Unallocated"] # =======> to store days without period elif (emp_data_Dic["attendance_type"] == "Shift"): attend_time = None # اول معاد حضور leave_time = "" # معاد الانصراف attend_notes = "" late_minutes = 0.0 has_signed_after_permission = False after_period_end_time = False atendance_time_margin = frappe.db.get_single_value( "Attendances Settings", "attendance_time_margin", cache=False) max_limit_for_attend = frappe.db.get_single_value( "Attendances Settings", "max_limit_for_attendance", cache=False) time_margin_after_leave_time = frappe.db.get_single_value( "Attendances Settings", "leave_time_margin", cache=False) for item in attendance_log: #---------------------------------------Attend Variables---------------------------------------------- max_time_after_attend = emp_data_Dic[ "start_time"] + timedelta(minutes=int( emp_data_Dic["attendance_permissibility"])) max_time_before_attend = emp_data_Dic[ "start_time"] - timedelta( minutes=int(atendance_time_margin)) max_limit_for_attendance = emp_data_Dic[ "start_time"] + timedelta( minutes=int(max_limit_for_attend)) #---------------------------------------Leave Variables---------------------------------------------- start_time_to_leave = emp_data_Dic[ "end_time"] - timedelta(minutes=int( emp_data_Dic["leave_permissibility"])) max_time_to_leave = emp_data_Dic[ "end_time"] + timedelta( minutes=int(time_margin_after_leave_time)) #----------------------------------------------------------------------------------------------------- item_time_stamp = datetime.strptime( item["timestamp"], "%H:%M:%S") item_time_stamp = timedelta( hours=item_time_stamp.hour, minutes=item_time_stamp.minute, seconds=item_time_stamp.second) # حضور قبل الموعد # During Attendance Time Margin (Before Period Start Time) if (emp_data_Dic["start_time"] > item_time_stamp >= max_time_before_attend): attend_time = item_time_stamp attend_notes = "حضور قبل الموعد" # حضور قبل الموعد وقبل فنرة الحضور المبكر elif (emp_data_Dic["start_time"] > item_time_stamp < max_time_before_attend): attend_time = "" attend_notes = "حضور مبكر" # حضور في الموعد أو خلال فترة السماحية elif ((emp_data_Dic["start_time"] <= item_time_stamp <= max_time_after_attend)): attend_time = item_time_stamp # حضور اول معاد attend_notes = "حضور يومى" #حضور بعد وقت الفترة وبعد وقت السماحية elif (item_time_stamp > max_time_after_attend): if check_permission( employee['employee'], curr_single_date, late_attend=True) and ( not has_signed_after_permission ): # إذن الحضور attend_time = item_time_stamp # إذن حضور attend_notes = "إذن حضور" has_signed_after_permission = True elif (item_time_stamp < max_limit_for_attendance): attend_time = item_time_stamp # حضور مع التاخير attend_notes = " حضور مع التأخير" late_seconds = ( attend_time - max_time_after_attend).total_seconds() late_minutes = late_seconds / 60 #تأخير عن ميعاد الحضور #-------------------------------------------Leave Conditions------------------------------------------------- elif (item_time_stamp < start_time_to_leave): if check_permission(employee['employee'], curr_single_date, late_attend=False): attend_notes += "- اذن انصراف مبكر " else: attend_notes += "- إنصراف قبل الموعد " leave_time = item_time_stamp elif (start_time_to_leave <= item_time_stamp <= max_time_to_leave): leave_time = item_time_stamp attend_notes += "- إنصراف يومى " elif (item_time_stamp > max_time_to_leave): attend_notes += "- إنصراف بعد الموعد " leave_time = "" after_period_end_time = True if attend_time and (not leave_time): if not after_period_end_time: attend_notes += "- عدم توقيع انصراف" add_attendance(employee, status, curr_single_date, attend_time, leave_time, late_minutes, attend_notes, leave_type) elif (emp_data_Dic["attendance_type"] in ("Open Day", "Flexible Hours")): attend_time = None # اول معاد حضور leave_time = "" # معاد الانصراف attend_notes = "" current_timestamp_to_handle = "" total_hours_per_day = "00:00:00" for item in attendance_log: item_time_stamp = datetime.strptime( item["timestamp"], "%H:%M:%S") item_time_stamp = timedelta( hours=item_time_stamp.hour, minutes=item_time_stamp.minute, seconds=item_time_stamp.second) if attend_time == None: attend_time = item_time_stamp current_timestamp_to_handle = item_time_stamp status = "Present" attend_notes = "حضور يومى" elif (current_timestamp_to_handle == ""): current_timestamp_to_handle = item_time_stamp elif (current_timestamp_to_handle != "" and (item_time_stamp - current_timestamp_to_handle) > timedelta(minutes=5)): temp = (item_time_stamp - current_timestamp_to_handle) temp = str(datetime.strptime( str(temp), "%H:%M:%S")).split(' ')[1] total_hours_per_day = \ timedelta(hours=int(str(temp).split(':')[0]), minutes=int(str(temp).split(':')[1]), seconds=int(str(temp).split(':')[1])) + \ timedelta(hours=int(str(total_hours_per_day).split(':')[0]), minutes=int(str(total_hours_per_day).split(':')[1]), seconds=int(str(total_hours_per_day).split(':')[2])) current_timestamp_to_handle = "" leave_time = item_time_stamp add_attendance(employee, status, curr_single_date, attend_time, leave_time, 0.0, attend_notes, leave_type, daily_hours=str(total_hours_per_day))
def get_availability_data(date, practitioner): """ Get availability data of 'practitioner' on 'date' :param date: Date to check in schedule :param practitioner: Name of the practitioner :return: dict containing a list of available slots, list of appointments and time of appointments """ date = getdate(date) weekday = date.strftime("%A") available_slots = [] slot_details = [] practitioner_schedule = None employee = None practitioner_obj = frappe.get_doc("Healthcare Practitioner", practitioner) # Get practitioner employee relation if practitioner_obj.employee: employee = practitioner_obj.employee elif practitioner_obj.user_id: if frappe.db.exists({ "doctype": "Employee", "user_id": practitioner_obj.user_id }): employee = frappe.get_doc("Employee", {"user_id": practitioner_obj.user_id}).name if employee: # Check if it is Holiday if is_holiday(employee, date): frappe.throw(_("{0} is a company holiday".format(date))) # Check if He/She on Leave leave_record = frappe.db.sql("""select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: frappe.throw(_("{0} on Half day Leave on {1}").format(practitioner, date)) else: frappe.throw(_("{0} on Leave on {1}").format(practitioner, date)) # get practitioners schedule if practitioner_obj.practitioner_schedules: for schedule in practitioner_obj.practitioner_schedules: if schedule.schedule: practitioner_schedule = frappe.get_doc("Practitioner Schedule", schedule.schedule) else: frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master".format(practitioner))) if practitioner_schedule: available_slots = [] for t in practitioner_schedule.time_slots: if weekday == t.day: available_slots.append(t) if available_slots: appointments = [] if schedule.service_unit: slot_name = schedule.schedule+" - "+schedule.service_unit allow_overlap = frappe.get_value('Healthcare Service Unit', schedule.service_unit, 'overlap_appointments') if allow_overlap: # fetch all appointments to practitioner by service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) else: # fetch all appointments to service unit appointments = frappe.get_all( "Patient Appointment", filters={"service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) else: slot_name = schedule.schedule # fetch all appointments to practitioner without service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"]) slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit, "avail_slot":available_slots, 'appointments': appointments}) else: frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master".format(practitioner))) if not available_slots and not slot_details: # TODO: return available slots in nearby dates frappe.throw(_("Healthcare Practitioner not available on {0}").format(weekday)) return { "slot_details": slot_details }
def get_availability_data(date, physician): """ Get availability data of 'physician' on 'date' :param date: Date to check in schedule :param physician: Name of the physician :return: dict containing a list of available slots, list of appointments and time of appointments """ date = getdate(date) weekday = date.strftime("%A") available_slots = [] physician_schedule_name = None physician_schedule = None time_per_appointment = None employee = None physician_obj = frappe.get_doc("Physician", physician) # Get Physician employee relation if physician_obj.employee: employee = physician_obj.employee elif physician_obj.user_id: if frappe.db.exists({ "doctype": "Employee", "user_id": physician_obj.user_id }): employee = frappe.get_doc("Employee", { "user_id": physician_obj.user_id }).name if employee: # Check if it is Holiday if is_holiday(employee, date): frappe.throw(_("{0} is a company holiday".format(date))) # Check if He/She on Leave leave_record = frappe.db.sql( """select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and status = 'Approved' and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: frappe.throw( _("Dr {0} on Half day Leave on {1}").format( physician, date)) else: frappe.throw( _("Dr {0} on Leave on {1}").format(physician, date)) # get physicians schedule physician_schedule_name = frappe.db.get_value("Physician", physician, "physician_schedule") if physician_schedule_name: physician_schedule = frappe.get_doc("Physician Schedule", physician_schedule_name) time_per_appointment = frappe.db.get_value("Physician", physician, "time_per_appointment") else: frappe.throw( _("Dr {0} does not have a Physician Schedule. Add it in Physician master" .format(physician))) if physician_schedule: for t in physician_schedule.time_slots: if weekday == t.day: available_slots.append(t) # `time_per_appointment` should never be None since validation in `Patient` is supposed to prevent # that. However, it isn't impossible so we'll prepare for that. if not time_per_appointment: frappe.throw( _('"Time Per Appointment" hasn"t been set for Dr {0}. Add it in Physician master.' ).format(physician)) # if physician not available return if not available_slots: # TODO: return available slots in nearby dates frappe.throw(_("Physician not available on {0}").format(weekday)) # if physician on leave return # if holiday return # if is_holiday(weekday): # get appointments on that day for physician appointments = frappe.get_all( "Patient Appointment", filters={ "physician": physician, "appointment_date": date }, fields=["name", "appointment_time", "duration", "status"]) return { "available_slots": available_slots, "appointments": appointments, "time_per_appointment": time_per_appointment }
def get_availability_data(date, practitioner): """ Get availability data of 'practitioner' on 'date' :param date: Date to check in schedule :param practitioner: Name of the practitioner :return: dict containing a list of available slots, list of appointments and time of appointments """ date = getdate(date) weekday = date.strftime("%A") available_slots = [] slot_details = [] practitioner_schedule = None add_events = [] remove_events = [] employee = None practitioner_obj = frappe.get_doc("Healthcare Practitioner", practitioner) # Get practitioner employee relation if practitioner_obj.employee: employee = practitioner_obj.employee elif practitioner_obj.user_id: if frappe.db.exists({ "doctype": "Employee", "user_id": practitioner_obj.user_id }): employee = frappe.get_doc("Employee", {"user_id": practitioner_obj.user_id}).name if employee: # Check if it is Holiday if is_holiday(employee, date): frappe.throw(_("{0} is a company holiday".format(date))) # Check if He/She on Leave leave_record = frappe.db.sql("""select half_day from `tabLeave Application` where employee = %s and %s between from_date and to_date and docstatus = 1""", (employee, date), as_dict=True) if leave_record: if leave_record[0].half_day: frappe.throw(_("{0} on Half day Leave on {1}").format(practitioner, date)) else: frappe.throw(_("{0} on Leave on {1}").format(practitioner, date)) # Remove events by repeat_on def remove_events_by_repeat_on(events_list): weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] if events_list: i = 0 for event in events_list: if event.repeat_this_event: if event.repeat_on == "Every Day": if event[weekdays[getdate(date).weekday()]]: add_events.append(event.copy()) remove_events.append(event.copy()) if event.repeat_on=="Every Week": if getdate(event.from_date).weekday() == getdate(date).weekday(): add_events.append(event.copy()) remove_events.append(event.copy()) if event.repeat_on=="Every Month": if getdate(event.from_date).day == getdate(date).day: add_events.append(event.copy()) remove_events.append(event.copy()) if event.repeat_on=="Every Year": if getdate(event.from_date).strftime("%j") == getdate(date).strftime("%j"): add_events.append(event.copy()) remove_events.append(event.copy()) # Absent events absent_events = frappe.db.sql(""" select name, event, from_time, to_time, from_date, to_date, duration, service_unit, service_unit, repeat_this_event, repeat_on, repeat_till, monday, tuesday, wednesday, thursday, friday, saturday, sunday from `tabPractitioner Event` where practitioner = %(practitioner)s and present != 1 and ( (repeat_this_event = 1 and (from_date<=%(date)s and ifnull(repeat_till, "3000-01-01")>=%(date)s)) or (repeat_this_event != 1 and (from_date<=%(date)s and to_date>=%(date)s)) ) """.format(),{"practitioner": practitioner, "date": getdate(date)}, as_dict=True) if absent_events: remove_events = [] add_events = [] remove_events_by_repeat_on(absent_events) for e in remove_events: absent_events.remove(e) absent_events = absent_events + add_events # get practitioners schedule enabled_schedule = False if practitioner_obj.practitioner_schedules: for schedule in practitioner_obj.practitioner_schedules: practitioner_schedule = None if schedule.schedule: if frappe.db.exists( "Practitioner Schedule", { "name": schedule.schedule, "disabled": ['!=', 1] } ): practitioner_schedule = frappe.get_doc('Practitioner Schedule', schedule.schedule) enabled_schedule = True if practitioner_schedule: available_slots = [] for t in practitioner_schedule.time_slots: if weekday == t.day: available_slots.append(t) if available_slots: appointments = [] if schedule.service_unit: slot_name = schedule.schedule+" - "+schedule.service_unit allow_overlap = frappe.get_value('Healthcare Service Unit', schedule.service_unit, 'overlap_appointments') if allow_overlap: # fetch all appointments to practitioner by service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") else: # fetch all appointments to service unit appointments = frappe.get_all( "Patient Appointment", filters={"service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") else: slot_name = schedule.schedule # fetch all appointments to practitioner without service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit, "avail_slot":available_slots, 'appointments': appointments, 'absent_events': absent_events, 'fixed_duration': schedule.always_use_slot_duration_as_appointment_duration, 'appointment_type': schedule.appointment_type}) # Present events present_events = frappe.db.sql(""" select name, event, from_time, to_time, from_date, to_date, duration, service_unit, repeat_this_event, repeat_on, repeat_till, monday, tuesday, wednesday, thursday, friday, saturday, sunday from `tabPractitioner Event` where practitioner = %(practitioner)s and present = 1 and ( (repeat_this_event = 1 and (from_date<=%(date)s and ifnull(repeat_till, "3000-01-01")>=%(date)s)) or (repeat_this_event != 1 and (from_date<=%(date)s and to_date>=%(date)s)) ) """.format(),{"practitioner":practitioner, "date":getdate(date)}, as_dict=True) present_events_details = [] if present_events: remove_events = [] add_events = [] remove_events_by_repeat_on(present_events) for e in remove_events: present_events.remove(e) present_events = present_events + add_events for present_event in present_events: event_available_slots = [] total_time_diff = time_diff_in_seconds(present_event.to_time, present_event.from_time)/60 from_time = present_event.from_time slot_name = present_event.event appointments = [] if present_event.service_unit: slot_name = slot_name+" - "+present_event.service_unit allow_overlap = frappe.get_value('Healthcare Service Unit', present_event.service_unit, 'overlap_appointments') if allow_overlap: # fetch all appointments to practitioner by service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": present_event.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") else: # fetch all appointments to service unit appointments = frappe.get_all( "Patient Appointment", filters={"service_unit": present_event.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") else: # fetch all appointments to practitioner without service unit appointments = frappe.get_all( "Patient Appointment", filters={"practitioner": practitioner, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]}, fields=["name", "appointment_time", "duration", "status"], order_by= "appointment_date, appointment_time") for x in range(0, int(total_time_diff), present_event.duration): to_time = from_time + datetime.timedelta(seconds=present_event.duration*60) event_available_slots.append({'from_time': from_time, 'to_time': to_time}) from_time = to_time present_events_details.append({'slot_name': slot_name, "service_unit":present_event.service_unit, 'avail_slot': event_available_slots, 'appointments': appointments, 'absent_events': absent_events}) else: if not practitioner_obj.practitioner_schedules: frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master".format(practitioner))) elif not enabled_schedule: frappe.throw(_("{0} does not have an enabled Healthcare Practitioner Schedule.".format(practitioner))) elif not available_slots and not slot_details: frappe.throw(_("Healthcare Practitioner not available on {0}").format(weekday)) return { "slot_details": slot_details, "present_events": present_events_details }