mirror of
https://github.com/alextselegidis/easyappointments.git
synced 2024-11-10 10:02:33 +03:00
Updated the Availability.php library to work with the updated code.
This commit is contained in:
parent
adc6d00bb5
commit
e4c01f54f8
1 changed files with 61 additions and 54 deletions
|
@ -13,9 +13,11 @@
|
|||
|
||||
|
||||
/**
|
||||
* Class Availability
|
||||
* Availability library
|
||||
*
|
||||
* Handles the availability generation of providers, based on their working plan and their schedule.
|
||||
* Handles availability related functionality.
|
||||
*
|
||||
* @package Libraries
|
||||
*/
|
||||
class Availability {
|
||||
/**
|
||||
|
@ -29,12 +31,14 @@ class Availability {
|
|||
public function __construct()
|
||||
{
|
||||
$this->CI =& get_instance();
|
||||
|
||||
$this->CI->load->model('admins_model');
|
||||
$this->CI->load->model('appointments_model');
|
||||
$this->CI->load->model('providers_model');
|
||||
$this->CI->load->model('secretaries_model');
|
||||
$this->CI->load->model('secretaries_model');
|
||||
$this->CI->load->model('admins_model');
|
||||
$this->CI->load->model('appointments_model');
|
||||
$this->CI->load->model('settings_model');
|
||||
|
||||
$this->CI->load->library('ics_file');
|
||||
}
|
||||
|
||||
|
@ -42,15 +46,13 @@ class Availability {
|
|||
* Get the available hours of a provider.
|
||||
*
|
||||
* @param string $date Selected date (Y-m-d).
|
||||
* @param array $service Service record.
|
||||
* @param array $provider Provider record.
|
||||
* @param array $service Service data.
|
||||
* @param array $provider Provider data.
|
||||
* @param int|null $exclude_appointment_id Exclude an appointment from the availability generation.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_available_hours($date, $service, $provider, $exclude_appointment_id = NULL)
|
||||
public function get_available_hours(string $date, array $service, array $provider, int $exclude_appointment_id = NULL): array
|
||||
{
|
||||
$available_periods = $this->get_available_periods($date, $provider, $exclude_appointment_id);
|
||||
|
||||
|
@ -68,22 +70,18 @@ class Availability {
|
|||
* Get an array containing the free time periods (start - end) of a selected date.
|
||||
*
|
||||
* This method is very important because there are many cases where the system needs to know when a provider is
|
||||
* available for an appointment. This method will return an array that belongs to the selected date and contains
|
||||
* values that have the start and the end time of an available time period.
|
||||
* available for an appointment. It will return an array that belongs to the selected date and contains values that
|
||||
* have the start and the end time of an available time period.
|
||||
*
|
||||
* @param string $date Select date string.
|
||||
* @param array $provider Provider record.
|
||||
* @param string $date Selected date (Y-m-d).
|
||||
* @param array $provider Provider data.
|
||||
* @param int|null $exclude_appointment_id Exclude an appointment from the availability generation.
|
||||
*
|
||||
* @return array Returns an array with the available time periods of the provider.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function get_available_periods(
|
||||
$date,
|
||||
$provider,
|
||||
$exclude_appointment_id = NULL
|
||||
)
|
||||
protected function get_available_periods(string $date, array $provider, int $exclude_appointment_id = NULL): array
|
||||
{
|
||||
// Get the service, provider's working plan and provider appointments.
|
||||
$working_plan = json_decode($provider['settings']['working_plan'], TRUE);
|
||||
|
@ -91,7 +89,7 @@ class Availability {
|
|||
// Get the provider's working plan exceptions.
|
||||
$working_plan_exceptions = json_decode($provider['settings']['working_plan_exceptions'], TRUE);
|
||||
|
||||
$conditions = [
|
||||
$where = [
|
||||
'id_users_provider' => $provider['id'],
|
||||
];
|
||||
|
||||
|
@ -99,10 +97,10 @@ class Availability {
|
|||
// existing appointment).
|
||||
if ($exclude_appointment_id)
|
||||
{
|
||||
$conditions['id !='] = $exclude_appointment_id;
|
||||
$where['id !='] = $exclude_appointment_id;
|
||||
}
|
||||
|
||||
$appointments = $this->CI->appointments_model->get_batch($conditions);
|
||||
$appointments = $this->CI->appointments_model->get($where);
|
||||
|
||||
// Find the empty spaces on the plan. The first split between the plan is due to a break (if any). After that
|
||||
// every reserved appointment is considered to be a taken space in the plan.
|
||||
|
@ -277,40 +275,43 @@ class Availability {
|
|||
/**
|
||||
* Calculate the available appointment hours.
|
||||
*
|
||||
* Calculate the available appointment hours for the given date. The empty spaces
|
||||
* are broken down to 15 min and if the service fit in each quarter then a new
|
||||
* available hour is added to the "$available_hours" array.
|
||||
* Calculate the available appointment hours for the given date. The empty spaces are broken down to 15 min and if
|
||||
* the service fit in each quarter then a new available hour is added to the "$available_hours" array.
|
||||
*
|
||||
* @param string $date Selected date (Y-m-d).
|
||||
* @param array $service Service record.
|
||||
* @param array $empty_periods Empty periods as generated by the "get_provider_available_time_periods"
|
||||
* method.
|
||||
* @param array $service Service data.
|
||||
* @param array $empty_periods Empty periods array.
|
||||
*
|
||||
* @return array Returns an array with the available hours for the appointment.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function generate_available_hours(
|
||||
$date,
|
||||
$service,
|
||||
$empty_periods
|
||||
)
|
||||
string $date,
|
||||
array $service,
|
||||
array $empty_periods
|
||||
): array
|
||||
{
|
||||
$available_hours = [];
|
||||
|
||||
foreach ($empty_periods as $period)
|
||||
{
|
||||
$start_hour = new DateTime($date . ' ' . $period['start']);
|
||||
|
||||
$end_hour = new DateTime($date . ' ' . $period['end']);
|
||||
|
||||
$interval = $service['availabilities_type'] === AVAILABILITIES_TYPE_FIXED ? (int)$service['duration'] : 15;
|
||||
|
||||
$current_hour = $start_hour;
|
||||
|
||||
$diff = $current_hour->diff($end_hour);
|
||||
|
||||
while (($diff->h * 60 + $diff->i) >= (int)$service['duration'] && $diff->invert === 0)
|
||||
{
|
||||
$available_hours[] = $current_hour->format('H:i');
|
||||
|
||||
$current_hour->add(new DateInterval('PT' . $interval . 'M'));
|
||||
|
||||
$diff = $current_hour->diff($end_hour);
|
||||
}
|
||||
}
|
||||
|
@ -324,8 +325,8 @@ class Availability {
|
|||
* This method will add the additional appointment hours whenever a service accepts multiple attendants.
|
||||
*
|
||||
* @param string $date Selected date (Y-m-d).
|
||||
* @param array $service Service record.
|
||||
* @param array $provider Provider record.
|
||||
* @param array $service Service data.
|
||||
* @param array $provider Provider data.
|
||||
* @param int|null $exclude_appointment_id Exclude an appointment from the availability generation.
|
||||
*
|
||||
* @return array Returns the available hours array.
|
||||
|
@ -333,13 +334,13 @@ class Availability {
|
|||
* @throws Exception
|
||||
*/
|
||||
protected function consider_multiple_attendants(
|
||||
$date,
|
||||
$service,
|
||||
$provider,
|
||||
$exclude_appointment_id = NULL
|
||||
)
|
||||
string $date,
|
||||
array $service,
|
||||
array $provider,
|
||||
int $exclude_appointment_id = NULL
|
||||
): array
|
||||
{
|
||||
$unavailability_events = $this->CI->appointments_model->get_batch([
|
||||
$unavailability_events = $this->CI->appointments_model->get([
|
||||
'is_unavailable' => TRUE,
|
||||
'DATE(start_datetime) <=' => $date,
|
||||
'DATE(end_datetime) >=' => $date,
|
||||
|
@ -430,14 +431,15 @@ class Availability {
|
|||
/**
|
||||
* Remove breaks from available time periods.
|
||||
*
|
||||
* @param string $selected_date Selected data (Y-m-d format).
|
||||
* @param array $periods Time periods of the current date.
|
||||
* @param array $breaks Breaks array for the current date.
|
||||
* @param string $date Selected date (Y-m-d).
|
||||
* @param array $periods Empty periods.
|
||||
* @param array $breaks Array of breaks.
|
||||
*
|
||||
* @return array Returns the available time periods without the breaks.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function remove_breaks($selected_date, $periods, $breaks)
|
||||
public function remove_breaks(string $date, array $periods, array $breaks): array
|
||||
{
|
||||
if ( ! $breaks)
|
||||
{
|
||||
|
@ -446,12 +448,14 @@ class Availability {
|
|||
|
||||
foreach ($breaks as $break)
|
||||
{
|
||||
$break_start = new DateTime($selected_date . ' ' . $break['start']);
|
||||
$break_end = new DateTime($selected_date . ' ' . $break['end']);
|
||||
$break_start = new DateTime($date . ' ' . $break['start']);
|
||||
|
||||
$break_end = new DateTime($date . ' ' . $break['end']);
|
||||
|
||||
foreach ($periods as &$period)
|
||||
{
|
||||
$period_start = $period['start'];
|
||||
|
||||
$period_end = $period['end'];
|
||||
|
||||
if ($break_start <= $period_start && $break_end >= $period_start && $break_end <= $period_end)
|
||||
|
@ -501,28 +505,30 @@ class Availability {
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function remove_unavailability_events($periods, $unavailability_events)
|
||||
public function remove_unavailability_events(array $periods, array $unavailability_events): array
|
||||
{
|
||||
foreach ($unavailability_events as $unavailability_event)
|
||||
{
|
||||
$unavailability_start = new DateTime($unavailability_event['start_datetime']);
|
||||
|
||||
$unavailability_end = new DateTime($unavailability_event['end_datetime']);
|
||||
|
||||
foreach ($periods as &$period)
|
||||
{
|
||||
$period_start = $period['start'];
|
||||
|
||||
$period_end = $period['end'];
|
||||
|
||||
if ($unavailability_start <= $period_start && $unavailability_end >= $period_start && $unavailability_end <= $period_end)
|
||||
{
|
||||
// left
|
||||
// Left
|
||||
$period['start'] = $unavailability_end;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($unavailability_start >= $period_start && $unavailability_start <= $period_end && $unavailability_end >= $period_start && $unavailability_end <= $period_end)
|
||||
{
|
||||
// middle
|
||||
// Middle
|
||||
$period['end'] = $unavailability_start;
|
||||
$periods[] = [
|
||||
'start' => $unavailability_end,
|
||||
|
@ -533,7 +539,7 @@ class Availability {
|
|||
|
||||
if ($unavailability_start >= $period_start && $unavailability_start <= $period_end && $unavailability_end >= $period_end)
|
||||
{
|
||||
// right
|
||||
// Right
|
||||
$period['end'] = $unavailability_start;
|
||||
continue;
|
||||
}
|
||||
|
@ -542,7 +548,6 @@ class Availability {
|
|||
{
|
||||
// Unavailability contains period
|
||||
$period['start'] = $unavailability_end;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +562,7 @@ class Availability {
|
|||
* that is set in the back-office the system. Normally we might want the customer to book an appointment
|
||||
* that is at least half or one hour from now. The setting is stored in minutes.
|
||||
*
|
||||
* @param string $selected_date The selected date.
|
||||
* @param string $date The selected date.
|
||||
* @param array $available_hours Already generated available hours.
|
||||
* @param array $provider Provider information.
|
||||
*
|
||||
|
@ -565,17 +570,17 @@ class Availability {
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function consider_book_advance_timeout($selected_date, $available_hours, $provider)
|
||||
protected function consider_book_advance_timeout(string $date, array $available_hours, array $provider): array
|
||||
{
|
||||
$provider_timezone = new DateTimeZone($provider['timezone']);
|
||||
|
||||
$book_advance_timeout = $this->CI->settings_model->get_setting('book_advance_timeout');
|
||||
$book_advance_timeout = setting('book_advance_timeout');
|
||||
|
||||
$threshold = new DateTime('+' . $book_advance_timeout . ' minutes', $provider_timezone);
|
||||
|
||||
foreach ($available_hours as $index => $value)
|
||||
{
|
||||
$available_hour = new DateTime($selected_date . ' ' . $value, $provider_timezone);
|
||||
$available_hour = new DateTime($date . ' ' . $value, $provider_timezone);
|
||||
|
||||
if ($available_hour->getTimestamp() <= $threshold->getTimestamp())
|
||||
{
|
||||
|
@ -584,7 +589,9 @@ class Availability {
|
|||
}
|
||||
|
||||
$available_hours = array_values($available_hours);
|
||||
|
||||
sort($available_hours, SORT_STRING);
|
||||
|
||||
return array_values($available_hours);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue