2016-04-27 22:57:11 +03:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Easy!Appointments - Open Source Web Scheduler
|
|
|
|
*
|
|
|
|
* @package EasyAppointments
|
|
|
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
2017-01-31 09:35:34 +03:00
|
|
|
* @copyright Copyright (c) 2013 - 2017, Alex Tselegidis
|
2016-04-27 22:57:11 +03:00
|
|
|
* @license http://opensource.org/licenses/GPL-3.0 - GPLv3
|
|
|
|
* @link http://easyappointments.org
|
|
|
|
* @since v1.0.0
|
|
|
|
* ---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
window.FrontendBookApi = window.FrontendBookApi || {};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Frontend Book API
|
|
|
|
*
|
|
|
|
* This module serves as the API consumer for the booking wizard of the app.
|
|
|
|
*
|
|
|
|
* @module FrontendBookApi
|
|
|
|
*/
|
|
|
|
(function(exports) {
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2016-07-19 00:23:53 +03:00
|
|
|
var unavailableDatesBackup;
|
|
|
|
var selectedDateStringBackup;
|
2016-10-10 17:45:19 +03:00
|
|
|
var processingUnavailabilities = false;
|
2016-07-19 00:23:53 +03:00
|
|
|
|
2016-04-27 22:57:11 +03:00
|
|
|
/**
|
2016-05-14 13:09:21 +03:00
|
|
|
* Get Available Hours
|
2016-04-27 22:57:11 +03:00
|
|
|
*
|
2016-05-14 13:09:21 +03:00
|
|
|
* This function makes an AJAX call and returns the available hours for the selected service,
|
|
|
|
* provider and date.
|
|
|
|
*
|
|
|
|
* @param {String} selDate The selected date of which the available hours we need to receive.
|
2016-04-27 22:57:11 +03:00
|
|
|
*/
|
|
|
|
exports.getAvailableHours = function(selDate) {
|
|
|
|
$('#available-hours').empty();
|
|
|
|
|
|
|
|
// Find the selected service duration (it is going to be send within the "postData" object).
|
|
|
|
var selServiceDuration = 15; // Default value of duration (in minutes).
|
|
|
|
$.each(GlobalVariables.availableServices, function(index, service) {
|
2017-11-02 16:19:54 +03:00
|
|
|
if (service.id == $('#select-service').val()) {
|
|
|
|
selServiceDuration = service.duration;
|
2016-04-27 22:57:11 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-05-14 13:09:21 +03:00
|
|
|
// If the manage mode is true then the appointment's start date should return as available too.
|
2017-11-02 16:19:54 +03:00
|
|
|
var appointmentId = FrontendBook.manageMode ? GlobalVariables.appointmentData.id : undefined;
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
// Make ajax post request and get the available hours.
|
2016-07-15 21:52:21 +03:00
|
|
|
var postUrl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_get_available_hours';
|
|
|
|
var postData = {
|
|
|
|
csrfToken: GlobalVariables.csrfToken,
|
|
|
|
service_id: $('#select-service').val(),
|
|
|
|
provider_id: $('#select-provider').val(),
|
|
|
|
selected_date: selDate,
|
|
|
|
service_duration: selServiceDuration,
|
|
|
|
manage_mode: FrontendBook.manageMode,
|
|
|
|
appointment_id: appointmentId
|
|
|
|
};
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
$.post(postUrl, postData, function(response) {
|
|
|
|
if (!GeneralFunctions.handleAjaxExceptions(response)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The response contains the available hours for the selected provider and
|
|
|
|
// service. Fill the available hours div with response data.
|
|
|
|
if (response.length > 0) {
|
|
|
|
var currColumn = 1;
|
2017-10-31 14:56:29 +03:00
|
|
|
$('#available-hours').html('<div style="width:80px; float:left;"></div>');
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
$.each(response, function(index, availableHour) {
|
|
|
|
if ((currColumn * 10) < (index + 1)) {
|
|
|
|
currColumn++;
|
2017-10-31 14:56:29 +03:00
|
|
|
$('#available-hours').append('<div style="width:80px; float:left;"></div>');
|
2016-04-27 22:57:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$('#available-hours div:eq(' + (currColumn - 1) + ')').append(
|
2017-10-31 14:56:29 +03:00
|
|
|
'<span class="available-hour">' + Date.parse(availableHour).toString('h:mm tt') + '</span><br/>');
|
2016-04-27 22:57:11 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
if (FrontendBook.manageMode) {
|
|
|
|
// Set the appointment's start time as the default selection.
|
|
|
|
$('.available-hour').removeClass('selected-hour');
|
|
|
|
$('.available-hour').filter(function() {
|
|
|
|
return $(this).text() === Date.parseExact(
|
2017-11-02 16:19:54 +03:00
|
|
|
GlobalVariables.appointmentData.start_datetime,
|
2017-10-31 14:56:29 +03:00
|
|
|
'yyyy-MM-dd HH:mm:ss').toString('h:mm tt');
|
2016-04-27 22:57:11 +03:00
|
|
|
}).addClass('selected-hour');
|
|
|
|
} else {
|
|
|
|
// Set the first available hour as the default selection.
|
|
|
|
$('.available-hour:eq(0)').addClass('selected-hour');
|
|
|
|
}
|
|
|
|
|
2016-05-14 12:36:17 +03:00
|
|
|
FrontendBook.updateConfirmFrame();
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
} else {
|
2017-09-11 17:09:15 +03:00
|
|
|
$('#available-hours').text(EALang.no_available_hours);
|
2016-04-27 22:57:11 +03:00
|
|
|
}
|
|
|
|
}, 'json').fail(GeneralFunctions.ajaxFailureHandler);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register an appointment to the database.
|
|
|
|
*
|
|
|
|
* This method will make an ajax call to the appointments controller that will register
|
|
|
|
* the appointment to the database.
|
|
|
|
*/
|
|
|
|
exports.registerAppointment = function() {
|
|
|
|
var $captchaText = $('.captcha-text');
|
|
|
|
|
|
|
|
if ($captchaText.length > 0) {
|
2017-11-14 15:52:59 +03:00
|
|
|
$captchaText.closest('.form-group').removeClass('has-error');
|
2016-04-27 22:57:11 +03:00
|
|
|
if ($captchaText.val() === '') {
|
2017-11-14 15:52:59 +03:00
|
|
|
$captchaText.closest('.form-group').addClass('has-error');
|
2016-04-27 22:57:11 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-15 21:52:21 +03:00
|
|
|
var formData = jQuery.parseJSON($('input[name="post_data"]').val());
|
|
|
|
var postData = {
|
|
|
|
csrfToken: GlobalVariables.csrfToken,
|
|
|
|
post_data: formData
|
|
|
|
};
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
if ($captchaText.length > 0) {
|
|
|
|
postData.captcha = $captchaText.val();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GlobalVariables.manageMode) {
|
|
|
|
postData.exclude_appointment_id = GlobalVariables.appointmentData.id;
|
|
|
|
}
|
|
|
|
|
2016-07-15 21:52:21 +03:00
|
|
|
var postUrl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_register_appointment';
|
|
|
|
var $layer = $('<div/>');
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
url: postUrl,
|
|
|
|
method: 'post',
|
|
|
|
data: postData,
|
|
|
|
dataType: 'json',
|
|
|
|
beforeSend: function(jqxhr, settings) {
|
|
|
|
$layer
|
|
|
|
.appendTo('body')
|
|
|
|
.css({
|
|
|
|
background: 'white',
|
|
|
|
position: 'fixed',
|
|
|
|
top: '0',
|
|
|
|
left: '0',
|
|
|
|
height: '100vh',
|
|
|
|
width: '100vw',
|
|
|
|
opacity: '0.5'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.done(function(response) {
|
|
|
|
if (!GeneralFunctions.handleAjaxExceptions(response)) {
|
|
|
|
$('.captcha-title small').trigger('click');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response.captcha_verification === false) {
|
|
|
|
$('#captcha-hint')
|
2017-09-11 17:09:15 +03:00
|
|
|
.text(EALang.captcha_is_wrong + '(' + response.expected_phrase + ')')
|
2016-04-27 22:57:11 +03:00
|
|
|
.fadeTo(400, 1);
|
|
|
|
|
|
|
|
setTimeout(function() {
|
|
|
|
$('#captcha-hint').fadeTo(400, 0);
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
$('.captcha-title small').trigger('click');
|
|
|
|
|
2017-11-14 15:52:59 +03:00
|
|
|
$captchaText.closest('.form-group').addClass('has-error');
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-10 11:25:07 +03:00
|
|
|
window.location.href = GlobalVariables.baseUrl
|
|
|
|
+ '/index.php/appointments/book_success/' + response.appointment_id;
|
2016-04-27 22:57:11 +03:00
|
|
|
})
|
|
|
|
.fail(function(jqxhr, textStatus, errorThrown) {
|
|
|
|
$('.captcha-title small').trigger('click');
|
|
|
|
GeneralFunctions.ajaxFailureHandler(jqxhr, textStatus, errorThrown);
|
|
|
|
})
|
|
|
|
.always(function() {
|
|
|
|
$layer.remove();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the unavailable dates of a provider.
|
|
|
|
*
|
|
|
|
* This method will fetch the unavailable dates of the selected provider and service and then it will
|
2016-05-14 13:09:21 +03:00
|
|
|
* select the first available date (if any). It uses the "FrontendBookApi.getAvailableHours" method to
|
|
|
|
* fetch the appointment* hours of the selected date.
|
2016-04-27 22:57:11 +03:00
|
|
|
*
|
2016-05-14 13:09:21 +03:00
|
|
|
* @param {Number} providerId The selected provider ID.
|
|
|
|
* @param {Number} serviceId The selected service ID.
|
|
|
|
* @param {String} selectedDateString Y-m-d value of the selected date.
|
2016-04-27 22:57:11 +03:00
|
|
|
*/
|
|
|
|
exports.getUnavailableDates = function(providerId, serviceId, selectedDateString) {
|
2016-10-10 17:45:19 +03:00
|
|
|
if (processingUnavailabilities) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-15 21:52:21 +03:00
|
|
|
var url = GlobalVariables.baseUrl + '/index.php/appointments/ajax_get_unavailable_dates';
|
|
|
|
var data = {
|
|
|
|
provider_id: providerId,
|
|
|
|
service_id: serviceId,
|
|
|
|
selected_date: encodeURIComponent(selectedDateString),
|
|
|
|
csrfToken: GlobalVariables.csrfToken
|
|
|
|
};
|
2016-04-27 22:57:11 +03:00
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
url: url,
|
|
|
|
type: 'GET',
|
|
|
|
data: data,
|
|
|
|
dataType: 'json'
|
|
|
|
})
|
|
|
|
.done(function(response) {
|
2016-07-19 00:23:53 +03:00
|
|
|
unavailableDatesBackup = response;
|
|
|
|
selectedDateStringBackup = selectedDateString;
|
2016-07-19 10:49:22 +03:00
|
|
|
_applyUnavailableDates(response, selectedDateString, true);
|
2016-04-27 22:57:11 +03:00
|
|
|
})
|
|
|
|
.fail(GeneralFunctions.ajaxFailureHandler);
|
|
|
|
};
|
|
|
|
|
2016-07-19 00:23:53 +03:00
|
|
|
exports.applyPreviousUnavailableDates = function() {
|
|
|
|
_applyUnavailableDates(unavailableDatesBackup, selectedDateStringBackup);
|
|
|
|
};
|
|
|
|
|
|
|
|
function _applyUnavailableDates(unavailableDates, selectedDateString, setDate) {
|
|
|
|
setDate = setDate || false;
|
|
|
|
|
2016-10-10 17:45:19 +03:00
|
|
|
processingUnavailabilities = true;
|
|
|
|
|
2016-07-19 00:23:53 +03:00
|
|
|
// Select first enabled date.
|
|
|
|
var selectedDate = Date.parse(selectedDateString);
|
|
|
|
var numberOfDays = new Date(selectedDate.getFullYear(), selectedDate.getMonth() + 1, 0).getDate();
|
|
|
|
|
|
|
|
if (setDate) {
|
|
|
|
for (var i=1; i<=numberOfDays; i++) {
|
|
|
|
var currentDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i);
|
2016-10-10 17:45:19 +03:00
|
|
|
if (unavailableDates.indexOf(currentDate.toString('yyyy-MM-dd')) === -1) {
|
2016-07-19 00:23:53 +03:00
|
|
|
$('#select-date').datepicker('setDate', currentDate);
|
|
|
|
FrontendBookApi.getAvailableHours(currentDate.toString('yyyy-MM-dd'));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If all the days are unavailable then hide the appointments hours.
|
|
|
|
if (unavailableDates.length === numberOfDays) {
|
2017-09-11 17:09:15 +03:00
|
|
|
$('#available-hours').text(EALang.no_available_hours);
|
2016-07-19 00:23:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Grey out unavailable dates.
|
|
|
|
$('#select-date .ui-datepicker-calendar td:not(.ui-datepicker-other-month)').each(function(index, td) {
|
|
|
|
selectedDate.set({day: index + 1});
|
|
|
|
if ($.inArray(selectedDate.toString('yyyy-MM-dd'), unavailableDates) != -1) {
|
|
|
|
$(td).addClass('ui-datepicker-unselectable ui-state-disabled');
|
|
|
|
}
|
|
|
|
});
|
2016-10-10 17:45:19 +03:00
|
|
|
|
|
|
|
processingUnavailabilities = false;
|
2016-07-19 00:23:53 +03:00
|
|
|
}
|
|
|
|
|
2016-04-27 22:57:11 +03:00
|
|
|
})(window.FrontendBookApi);
|