blob: 340f3adb6727dc1d31590b6100b17682dd9681af [file] [log] [blame]
pranav nachnekar27910542019-09-03 12:04:52 +05301import frappe
2import datetime
pranav nachnekarc5b2a582019-09-03 14:16:47 +05303import json
pranav nachnekar27910542019-09-03 12:04:52 +05304
5@frappe.whitelist(allow_guest=True)
6def get_appointment_settings():
7 settings = frappe.get_doc('Appointment Booking Settings')
8 return settings
9
10@frappe.whitelist(allow_guest=True)
11def get_holiday_list(holiday_list_name):
12 holiday_list = frappe.get_doc('Holiday List',holiday_list_name)
13 return holiday_list
14
15@frappe.whitelist(allow_guest=True)
16def get_timezones():
17 timezones = frappe.get_list('Timezone',fields='*')
18 return timezones
19
20@frappe.whitelist(allow_guest=True)
21def get_appointment_slots(date,timezone):
22 timezone = int(timezone)
23 format_string = '%Y-%m-%d %H:%M:%S'
24 query_start_time = datetime.datetime.strptime(date + ' 00:00:00',format_string)
25 query_end_time = datetime.datetime.strptime(date + ' 23:59:59',format_string)
26 query_start_time = _convert_to_ist(query_start_time,timezone)
27 query_end_time = _convert_to_ist(query_end_time,timezone)
28 # Database queries
29 settings = frappe.get_doc('Appointment Booking Settings')
30 holiday_list = frappe.get_doc('Holiday List', settings.holiday_list)
31 timeslots = get_available_slots_between(query_start_time, query_end_time, settings)
32
33 # Filter timeslots based on date
34 converted_timeslots = []
35 for timeslot in timeslots:
36 # Check if holiday
37 if _is_holiday(timeslot.date(),holiday_list):
38 converted_timeslots.append(dict(time=_convert_to_tz(timeslot,timezone),availability=False))
39 continue
40 # Check availability
41 if check_availabilty(timeslot,settings):
42 converted_timeslots.append(dict(time=_convert_to_tz(timeslot,timezone),availability=True))
43 else:
44 converted_timeslots.append(dict(time=_convert_to_tz(timeslot,timezone),availability=False))
45 date_required = datetime.datetime.strptime(date + ' 00:00:00',format_string).date()
46 converted_timeslots = filter_timeslots(date_required,converted_timeslots)
47 return converted_timeslots
48
49def get_available_slots_between(query_start_time, query_end_time, settings):
50 records = _get_records(query_start_time, query_end_time, settings)
51 timeslots = []
52 appointment_duration = datetime.timedelta(
53 minutes=settings.appointment_duration)
54 for record in records:
55 if record.day_of_week == WEEKDAYS[query_start_time.weekday()]:
56 current_time = _deltatime_to_datetime(
57 query_start_time, record.from_time)
58 end_time = _deltatime_to_datetime(
59 query_start_time, record.to_time)
60 else :
61 current_time = _deltatime_to_datetime(
62 query_end_time, record.from_time)
63 end_time = _deltatime_to_datetime(
64 query_end_time, record.to_time)
65 while current_time + appointment_duration <= end_time:
66 timeslots.append(current_time)
67 current_time += appointment_duration
68 return timeslots
69
70@frappe.whitelist(allow_guest=True)
71def create_appointment(date,time,contact):
pranav nachnekarc5b2a582019-09-03 14:16:47 +053072 appointment = frappe.new_doc('Appointment')
73 format_string = '%Y-%m-%d %H:%M:%S'
74 appointment.scheduled_time = datetime.datetime.strptime(date+" "+time,format_string)
75 contact = json.loads(contact)
76 appointment.customer_name = contact['name']
77 appointment.customer_phone_no = contact['number']
78 appointment.customer_skype = contact['skype']
79 appointment.customer_details = contact['notes']
80 appointment.insert()
pranav nachnekar27910542019-09-03 12:04:52 +053081
pranav nachnekarc5b2a582019-09-03 14:16:47 +053082
83# Helper Functions
pranav nachnekar27910542019-09-03 12:04:52 +053084def filter_timeslots(date,timeslots):
85 filtered_timeslots = []
86 for timeslot in timeslots:
87 if(timeslot['time'].date() == date):
88 filtered_timeslots.append(timeslot)
89 return filtered_timeslots
90
91def check_availabilty(timeslot,settings):
92 return frappe.db.count('Appointment',{'scheduled_time':timeslot})<settings.number_of_agents
93
pranav nachnekar27910542019-09-03 12:04:52 +053094def _is_holiday(date, holiday_list):
95 for holiday in holiday_list.holidays:
96 if holiday.holiday_date == date:
97 return True
98 return False
99
100def _get_records(start_time, end_time, settings):
101 records = []
102 for record in settings.availability_of_slots:
103 if record.day_of_week == WEEKDAYS[start_time.weekday()] or record.day_of_week == WEEKDAYS[end_time.weekday()]:
104 records.append(record)
105 return records
106
107def _deltatime_to_datetime(date, deltatime):
108 time = (datetime.datetime.min + deltatime).time()
109 return datetime.datetime.combine(date.date(), time)
110
111def _datetime_to_deltatime(date_time):
112 midnight = datetime.datetime.combine(date_time.date(),datetime.time.min)
113 return (date_time-midnight)
114
115def _convert_to_ist(datetime_object, timezone):
116 offset = datetime.timedelta(minutes=timezone)
117 datetime_object = datetime_object + offset
118 offset = datetime.timedelta(minutes=-330)
119 datetime_object = datetime_object - offset
120 return datetime_object
121
122def _convert_to_tz(datetime_object, timezone):
123 offset = datetime.timedelta(minutes=timezone)
124 datetime_object = datetime_object - offset
125 offset = datetime.timedelta(minutes=-330)
126 datetime_object = datetime_object + offset
127 return datetime_object
128
129WEEKDAYS = ["Monday", "Tuesday", "Wednesday",
130 "Thursday", "Friday", "Saturday", "Sunday"]