blob: d02cdad4cf485baf8c74421991728d6162c11280 [file] [log] [blame]
Pranav Nachanekarafe52e82019-10-03 16:35:08 +05301frappe.ready(async () => {
Pranav Nachanekarafe52e82019-10-03 16:35:08 +05302 initialise_select_date();
pranav nachnekar27910542019-09-03 12:04:52 +05303})
Pranav Nachanekarafe52e82019-10-03 16:35:08 +05304
Pranav Nachanekar10711dd2019-09-09 15:41:20 +05305async function initialise_select_date() {
Pranav Nachanekara2dbd392019-09-12 10:48:26 +05306 navigate_to_page(1);
Pranav Nachanekar10711dd2019-09-09 15:41:20 +05307 await get_global_variables();
8 setup_date_picker();
9 setup_timezone_selector();
10 hide_next_button();
pranav nachnekar27910542019-09-03 12:04:52 +053011}
12
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053013async function get_global_variables() {
0Pranav793ba8f2019-11-14 11:25:49 +053014 // Using await through this file instead of then.
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053015 window.appointment_settings = (await frappe.call({
Pranav Nachnekar6aa76322019-12-10 16:05:28 +000016 method: 'erpnext.www.book_appointment.index.get_appointment_settings'
Pranav Nachanekarafe52e82019-10-03 16:35:08 +053017 })).message;
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053018 window.timezones = (await frappe.call({
Pranav Nachnekar6aa76322019-12-10 16:05:28 +000019 method:'erpnext.www.book_appointment.index.get_timezones'
pranav nachnekar27910542019-09-03 12:04:52 +053020 })).message;
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053021}
22
23function setup_timezone_selector() {
pranav nachnekar27910542019-09-03 12:04:52 +053024 let timezones_element = document.getElementById('appointment-timezone');
0Pranav84ae2cc2019-12-18 15:44:04 +053025 let local_timezone = moment.tz.guess()
26 window.timezones.forEach(timezone => {
Pranav Nachanekar91a56492019-09-17 16:58:41 +053027 let opt = document.createElement('option');
Pranav Nachanekarc6da5fb2019-10-03 11:56:23 +053028 opt.value = timezone;
0Pranav84ae2cc2019-12-18 15:44:04 +053029 if (timezone == local_timezone) {
Pranav Nachanekarc6da5fb2019-10-03 11:56:23 +053030 opt.selected = true;
31 }
0Pranav84ae2cc2019-12-18 15:44:04 +053032 opt.innerHTML = timezone;
pranav nachnekar27910542019-09-03 12:04:52 +053033 timezones_element.appendChild(opt)
34 });
35}
36
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053037function setup_date_picker() {
pranav nachnekar27910542019-09-03 12:04:52 +053038 let date_picker = document.getElementById('appointment-date');
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053039 let today = new Date();
40 date_picker.min = today.toISOString().substr(0, 10);
Pranav Nachanekar469247b2019-09-12 11:15:42 +053041 today.setDate(today.getDate() + window.appointment_settings.advance_booking_days);
Pranav Nachanekar91a56492019-09-17 16:58:41 +053042 date_picker.max = today.toISOString().substr(0, 10);
pranav nachnekar27910542019-09-03 12:04:52 +053043}
44
Pranav Nachanekar91a56492019-09-17 16:58:41 +053045function hide_next_button() {
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053046 let next_button = document.getElementById('next-button');
47 next_button.disabled = true;
Ankush Menatff96bdf2021-05-25 19:54:40 +053048 next_button.onclick = () => frappe.msgprint(__("Please select a date and time"));
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053049}
50
Pranav Nachanekar91a56492019-09-17 16:58:41 +053051function show_next_button() {
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053052 let next_button = document.getElementById('next-button');
53 next_button.disabled = false;
54 next_button.onclick = setup_details_page;
55}
56
57function on_date_or_timezone_select() {
58 let date_picker = document.getElementById('appointment-date');
59 let timezone = document.getElementById('appointment-timezone');
60 if (date_picker.value === '') {
61 clear_time_slots();
62 hide_next_button();
Ankush Menatff96bdf2021-05-25 19:54:40 +053063 frappe.throw(__('Please select a date'));
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053064 }
65 window.selected_date = date_picker.value;
66 window.selected_timezone = timezone.value;
67 update_time_slots(date_picker.value, timezone.value);
Pranav Nachanekara322b152019-09-11 14:25:26 +053068 let lead_text = document.getElementById('lead-text');
Ernesto Ruiz728ef462022-09-26 08:01:48 -060069 lead_text.innerHTML = __("Select Time")
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053070}
71
72async function get_time_slots(date, timezone) {
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053073 let slots = (await frappe.call({
Pranav Nachnekar6aa76322019-12-10 16:05:28 +000074 method: 'erpnext.www.book_appointment.index.get_appointment_slots',
pranav nachnekar27910542019-09-03 12:04:52 +053075 args: {
76 date: date,
77 timezone: timezone
78 }
79 })).message;
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053080 return slots;
81}
pranav nachnekarc5b2a582019-09-03 14:16:47 +053082
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053083async function update_time_slots(selected_date, selected_timezone) {
84 let timeslot_container = document.getElementById('timeslot-container');
85 window.slots = await get_time_slots(selected_date, selected_timezone);
86 clear_time_slots();
87 if (window.slots.length <= 0) {
88 let message_div = document.createElement('p');
Ernesto Ruiz728ef462022-09-26 08:01:48 -060089 message_div.innerHTML = __("There are no slots available on this date");
pranav nachnekar27910542019-09-03 12:04:52 +053090 timeslot_container.appendChild(message_div);
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053091 return
pranav nachnekar27910542019-09-03 12:04:52 +053092 }
Pranav Nachanekar91a56492019-09-17 16:58:41 +053093 window.slots.forEach((slot, index) => {
Pranav Nachanekar91a56492019-09-17 16:58:41 +053094 // Get and append timeslot div
95 let timeslot_div = get_timeslot_div_layout(slot)
pranav nachnekar27910542019-09-03 12:04:52 +053096 timeslot_container.appendChild(timeslot_div);
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053097 });
98 set_default_timeslot();
Pranav Nachanekar10711dd2019-09-09 15:41:20 +053099}
100
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530101function get_timeslot_div_layout(timeslot) {
102 let start_time = new Date(timeslot.time)
103 let timeslot_div = document.createElement('div');
104 timeslot_div.classList.add('time-slot');
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530105 if (!timeslot.availability) {
106 timeslot_div.classList.add('unavailable')
107 }
108 timeslot_div.innerHTML = get_slot_layout(start_time);
0Pranavd3605d22019-12-11 15:02:23 +0530109 timeslot_div.id = timeslot.time.substring(11, 19);
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530110 timeslot_div.addEventListener('click', select_time);
111 return timeslot_div
112}
113
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530114function clear_time_slots() {
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530115 // Clear any existing divs in timeslot container
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530116 let timeslot_container = document.getElementById('timeslot-container');
117 while (timeslot_container.firstChild) {
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530118 timeslot_container.removeChild(timeslot_container.firstChild);
pranav nachnekar27910542019-09-03 12:04:52 +0530119 }
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530120}
121
122function get_slot_layout(time) {
0Pranav6e6954c2019-11-13 16:00:59 +0530123 let timezone = document.getElementById("appointment-timezone").value;
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530124 time = new Date(time);
0Pranav6e6954c2019-11-13 16:00:59 +0530125 let start_time_string = moment(time).tz(timezone).format("LT");
126 let end_time = moment(time).tz(timezone).add(window.appointment_settings.appointment_duration, 'minutes');
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530127 let end_time_string = end_time.format("LT");
Ernesto Ruiz728ef462022-09-26 08:01:48 -0600128 return `<span style="font-size: 1.2em;">${start_time_string}</span><br><span class="text-muted small">${__("to") } ${end_time_string}</span>`;
pranav nachnekar27910542019-09-03 12:04:52 +0530129}
130
131function select_time() {
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530132 if (this.classList.contains('unavailable')) {
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530133 return;
pranav nachnekar27910542019-09-03 12:04:52 +0530134 }
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530135 let selected_element = document.getElementsByClassName('selected');
Pranav Nachanekar25148d02019-10-04 11:32:39 +0530136 if (!(selected_element.length > 0)) {
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530137 this.classList.add('selected');
138 show_next_button();
139 return;
pranav nachnekar27910542019-09-03 12:04:52 +0530140 }
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530141 selected_element = selected_element[0]
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530142 window.selected_time = this.id;
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530143 selected_element.classList.remove('selected');
144 this.classList.add('selected');
Pranav Nachanekara2dbd392019-09-12 10:48:26 +0530145 show_next_button();
pranav nachnekar27910542019-09-03 12:04:52 +0530146}
147
148function set_default_timeslot() {
149 let timeslots = document.getElementsByClassName('time-slot')
Pranav Nachanekar7323bfd2019-09-18 14:33:10 +0530150 // Can't use a forEach here since, we need to break the loop after a timeslot is selected
pranav nachnekar27910542019-09-03 12:04:52 +0530151 for (let i = 0; i < timeslots.length; i++) {
152 const timeslot = timeslots[i];
153 if (!timeslot.classList.contains('unavailable')) {
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530154 timeslot.classList.add('selected');
pranav nachnekar27910542019-09-03 12:04:52 +0530155 break;
156 }
157 }
158}
159
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530160function navigate_to_page(page_number) {
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530161 let page1 = document.getElementById('select-date-time');
162 let page2 = document.getElementById('enter-details');
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530163 switch (page_number) {
164 case 1:
Pranav Nachanekara2dbd392019-09-12 10:48:26 +0530165 page1.style.display = 'block';
166 page2.style.display = 'none';
167 break;
168 case 2:
169 page1.style.display = 'none';
170 page2.style.display = 'block';
171 break;
172 default:
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530173 break;
Pranav Nachanekara2dbd392019-09-12 10:48:26 +0530174 }
175}
176
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530177function setup_details_page() {
Pranav Nachanekara2dbd392019-09-12 10:48:26 +0530178 navigate_to_page(2)
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530179 let date_container = document.getElementsByClassName('date-span')[0];
180 let time_container = document.getElementsByClassName('time-span')[0];
Pranav Nachnekarc1312702020-01-28 12:20:47 +0000181 setup_search_params();
Pranav Nachanekar5c008ef2019-09-10 13:12:07 +0530182 date_container.innerHTML = moment(window.selected_date).format("MMM Do YYYY");
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530183 time_container.innerHTML = moment(window.selected_time, "HH:mm:ss").format("LT");
pranav nachnekar27910542019-09-03 12:04:52 +0530184}
185
Pranav Nachnekarc1312702020-01-28 12:20:47 +0000186function setup_search_params() {
187 let search_params = new URLSearchParams(window.location.search);
188 let customer_name = search_params.get("name")
189 let customer_email = search_params.get("email")
190 let detail = search_params.get("details")
191 if (customer_name) {
192 let name_input = document.getElementById("customer_name");
193 name_input.value = customer_name;
194 name_input.disabled = true;
195 }
196 if(customer_email) {
197 let email_input = document.getElementById("customer_email");
198 email_input.value = customer_email;
199 email_input.disabled = true;
200 }
201 if(detail) {
202 let detail_input = document.getElementById("customer_notes");
203 detail_input.value = detail;
204 detail_input.disabled = true;
205 }
206}
pranav nachnekarc5b2a582019-09-03 14:16:47 +0530207async function submit() {
0Pranava92f0602019-11-13 12:13:42 +0530208 let button = document.getElementById('submit-button');
209 button.disabled = true;
Pranav Nachanekarc9cf5ae2019-09-24 12:08:37 +0530210 let form = document.querySelector('#customer-form');
Pranav Nachanekar25148d02019-10-04 11:32:39 +0530211 if (!form.checkValidity()) {
Pranav Nachanekarc9cf5ae2019-09-24 12:08:37 +0530212 form.reportValidity();
0Pranava92f0602019-11-13 12:13:42 +0530213 button.disabled = false;
Pranav Nachanekarc9cf5ae2019-09-24 12:08:37 +0530214 return;
215 }
0Pranava92f0602019-11-13 12:13:42 +0530216 let contact = get_form_data();
0Pranav511780a2019-11-14 12:47:08 +0530217 let appointment = frappe.call({
Pranav Nachnekar6aa76322019-12-10 16:05:28 +0000218 method: 'erpnext.www.book_appointment.index.create_appointment',
pranav nachnekarc5b2a582019-09-03 14:16:47 +0530219 args: {
Pranav Nachanekardb21f862019-09-09 17:01:40 +0530220 'date': window.selected_date,
221 'time': window.selected_time,
0Pranava92f0602019-11-13 12:13:42 +0530222 'contact': contact,
0Pranavd1c530c2019-10-31 15:36:33 +0530223 'tz':window.selected_timezone
0Pranav511780a2019-11-14 12:47:08 +0530224 },
225 callback: (response)=>{
226 if (response.message.status == "Unverified") {
Ernesto Ruiz728ef462022-09-26 08:01:48 -0600227 frappe.show_alert(__("Please check your email to confirm the appointment"))
0Pranav511780a2019-11-14 12:47:08 +0530228 } else {
Ernesto Ruiz728ef462022-09-26 08:01:48 -0600229 frappe.show_alert(__("Appointment Created Successfully"));
0Pranav511780a2019-11-14 12:47:08 +0530230 }
231 setTimeout(()=>{
232 let redirect_url = "/";
233 if (window.appointment_settings.success_redirect_url){
234 redirect_url += window.appointment_settings.success_redirect_url;
235 }
0Pranavfb1e8772019-11-26 12:14:41 +0530236 window.location.href = redirect_url;},5000)
0Pranav511780a2019-11-14 12:47:08 +0530237 },
238 error: (err)=>{
Ernesto Ruiz728ef462022-09-26 08:01:48 -0600239 frappe.show_alert(__("Something went wrong please try again"));
0Pranav511780a2019-11-14 12:47:08 +0530240 button.disabled = false;
pranav nachnekarc5b2a582019-09-03 14:16:47 +0530241 }
0Pranav511780a2019-11-14 12:47:08 +0530242 });
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530243}
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530244
Pranav Nachanekar91a56492019-09-17 16:58:41 +0530245function get_form_data() {
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530246 contact = {};
0Pranav6de68c82019-11-01 09:51:32 +0530247 let inputs = ['name', 'skype', 'number', 'notes', 'email'];
248 inputs.forEach((id) => contact[id] = document.getElementById(`customer_${id}`).value)
0Pranava92f0602019-11-13 12:13:42 +0530249 return contact
Pranav Nachanekar10711dd2019-09-09 15:41:20 +0530250}