Implements #142: Grey out unavailable calendar dates

This commit is contained in:
Alex Tselegidis 2016-03-31 20:08:21 +02:00
parent 8118e9fd9b
commit cf6e635aad
2 changed files with 129 additions and 3 deletions

View file

@ -770,6 +770,67 @@ class Appointments extends CI_Controller {
return $available_hours;
}
/**
* [AJAX] Get Unavailable Dates
*
* Get an array with the available dates of a specific provider, service and month
* of the year. Provide the "provider_id", "service_id" and "selected_date" as GET
* parameters to the request. The "selected_date" parameter must have the Y-m-d format.
*
* @return string Returns a JSON array with the dates that are unavailable.
*/
public function ajax_get_unavailable_dates() {
try {
$provider_id = $this->input->get('provider_id');
$service_id = $this->input->get('service_id');
$selected_date = new DateTime($this->input->get('selected_date'));
$number_of_days = (int)$selected_date->format('t');
$unavailable_dates = array();
// Handle the "Any Provider" case.
if ($provider_id === ANY_PROVIDER) {
$provider_id = $this->search_any_provider($service_id, $this->input->get('selected_date'));
if ($provider_id === NULL) { // No provider is available in the selected date.
for ($i=1; $i<=$number_of_days; $i++) {
$current_date = new DateTime($selected_date->format('Y-m') . '-' . $i);
$unavailable_dates[] = $current_date->format('Y-m-d');
}
echo json_encode($unavailable_dates);
return;
}
}
// Get the available time periods for every day of this month.
$this->load->model('services_model');
$service_duration = (int)$this->services_model->get_value('duration', $service_id);
for ($i=1; $i<=$number_of_days; $i++) {
$current_date = new DateTime($selected_date->format('Y-m') . '-' . $i);
if ($current_date < new DateTime()) { // Past dates become immediatelly unavailable.
$unavailable_dates[] = $current_date->format('Y-m-d');
continue;
}
$empty_periods = $this->get_provider_available_time_periods($provider_id,
$current_date->format('Y-m-d'));
$available_hours = $this->calculate_available_hours($empty_periods, $current_date->format('Y-m-d'),
$service_duration);
if (empty($available_hours)) {
$unavailable_dates[] = $current_date->format('Y-m-d');
}
}
echo json_encode($unavailable_dates);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
}
/* End of file appointments.php */

View file

@ -84,6 +84,12 @@ var FrontendBook = {
onSelect: function(dateText, instance) {
FrontendBook.getAvailableHours(dateText);
FrontendBook.updateConfirmFrame();
},
onChangeMonthYear: function(year, month, instance) {
var currentDate = new Date(year, month - 1, 1);
FrontendBook.getUnavailableDates($('#select-provider').val(), $('#select-service').val(),
currentDate.toString('yyyy-MM-dd'));
}
});
@ -116,7 +122,8 @@ var FrontendBook = {
* date - time periods must be updated.
*/
$('#select-provider').change(function() {
FrontendBook.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
FrontendBook.getUnavailableDates($(this).val(), $('#select-service').val(),
$('#select-date').datepicker('getDate').toString('yyyy-MM-dd'));
FrontendBook.updateConfirmFrame();
});
@ -148,8 +155,8 @@ var FrontendBook = {
$('#select-provider').append(new Option('- ' +EALang['any_provider'] + ' -', 'any-provider'));
}
FrontendBook.getAvailableHours($('#select-date').val());
FrontendBook.getUnavailableDates($('#select-provider').val(), $(this).val(),
$('#select-date').datepicker('getDate').toString('yyyy-MM-dd'));
FrontendBook.updateConfirmFrame();
FrontendBook.updateServiceDescription($('#select-service').val(), $('#service-description'));
});
@ -698,5 +705,63 @@ var FrontendBook = {
.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
* select the first available date (if any). It uses the "getAvailableHours" method to fetch the appointment
* hours of the selected date.
*
* @param {int} providerId The selected provider ID.
* @param {int} serviceId The selected service ID.
* @param {string} selectedDateString Y-m-d value of the selected date.
*/
getUnavailableDates: function(providerId, serviceId, selectedDateString) {
var url = GlobalVariables.baseUrl + '/index.php/appointments/ajax_get_unavailable_dates',
data = {
provider_id: providerId,
service_id: serviceId,
selected_date: encodeURIComponent(selectedDateString),
csrfToken: GlobalVariables.csrfToken
};
$.ajax({
url: url,
type: 'GET',
data: data,
dataType: 'json'
})
.done(function(response) {
// Select first enabled date.
var selectedDate = Date.parse(selectedDateString),
numberOfDays = new Date(selectedDate.getFullYear(), selectedDate.getMonth() + 1, 0).getDate();
for (var i=1; i<=numberOfDays; i++) {
var currentDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i);
if ($.inArray(currentDate.toString('yyyy-MM-dd'), response) === -1) {
$('#select-date').datepicker('setDate', currentDate);
FrontendBook.getAvailableHours(currentDate.toString('yyyy-MM-dd'));
break;
}
}
// If all the days are unavailable then hide the appointments hours.
if (response.length === numberOfDays) {
$('#available-hours').text(EALang['no_available_hours']);
}
// Apply the new beforeShowDayHandler method to the #select-date datepicker.
var beforeShowDayHandler = function(date) {
if ($.inArray(date.toString('yyyy-MM-dd'), response) != -1) {
return [false];
}
return [true];
};
$('#select-date').datepicker('option', 'beforeShowDay', beforeShowDayHandler);
})
.fail(GeneralFunctions.ajaxFailureHandler);
}
};