From 3d8d5afa4ca378f1c14d20e4fa10439e6b40d630 Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Mon, 27 Jun 2022 15:14:46 +0300 Subject: [PATCH] Add new setting for limiting new public bookings in the future (#1203). --- application/libraries/Availability.php | 57 ++++++++++++++----- .../042_add_future_booking_limit_setting.php | 47 +++++++++++++++ application/views/pages/business_settings.php | 29 +++++++--- assets/css/layouts/backend_layout.scss | 3 +- 4 files changed, 115 insertions(+), 21 deletions(-) create mode 100644 application/migrations/042_add_future_booking_limit_setting.php diff --git a/application/libraries/Availability.php b/application/libraries/Availability.php index 7c447926fb..2fd9b557bf 100644 --- a/application/libraries/Availability.php +++ b/application/libraries/Availability.php @@ -16,7 +16,7 @@ * Availability library. * * Handles availability related functionality. - * + * * @package Libraries */ class Availability { @@ -68,7 +68,9 @@ public function get_available_hours(string $date, array $service, array $provide $available_hours = $this->generate_available_hours($date, $service, $available_periods); } - return $this->consider_book_advance_timeout($date, $available_hours, $provider); + $available_hours = $this->consider_book_advance_timeout($date, $available_hours, $provider); + + return $this->consider_future_booking_limit($date, $available_hours, $provider); } /** @@ -93,14 +95,14 @@ protected function get_available_periods(string $date, array $provider, int $exc // Get the provider's working plan exceptions. $working_plan_exceptions_json = $provider['settings']['working_plan_exceptions']; - + $working_plan_exceptions = $working_plan_exceptions_json ? json_decode($provider['settings']['working_plan_exceptions'], TRUE) : NULL; $escaped_provider_id = $this->CI->db->escape($provider['id']); - - $escaped_date = $this->CI->db->escape($date); - - $where = 'id_users_provider = ' . $escaped_provider_id + + $escaped_date = $this->CI->db->escape($date); + + $where = 'id_users_provider = ' . $escaped_provider_id . ' AND DATE(start_datetime) <= ' . $escaped_date . ' AND DATE(end_datetime) >= ' . $escaped_date; // Sometimes it might be necessary to exclude an appointment from the calculation (e.g. when editing an @@ -108,7 +110,7 @@ protected function get_available_periods(string $date, array $provider, int $exc if ($exclude_appointment_id) { $escaped_exclude_appointment_id = $this->CI->db->escape($exclude_appointment_id); - $where .= ' AND id != ' . $escaped_exclude_appointment_id; + $where .= ' AND id != ' . $escaped_exclude_appointment_id; } $appointments = array_values( @@ -304,8 +306,8 @@ protected function get_available_periods(string $date, array $provider, int $exc */ protected function generate_available_hours( string $date, - array $service, - array $empty_periods + array $service, + array $empty_periods ): array { $available_hours = []; @@ -351,9 +353,9 @@ protected function generate_available_hours( */ protected function consider_multiple_attendants( string $date, - array $service, - array $provider, - int $exclude_appointment_id = NULL + array $service, + array $provider, + int $exclude_appointment_id = NULL ): array { $unavailability_events = $this->CI->appointments_model->get([ @@ -610,4 +612,33 @@ protected function consider_book_advance_timeout(string $date, array $available_ return array_values($available_hours); } + + /** + * Remove times if succeed the future booking limit. + * + * @param string $selected_date + * @param array $available_hours + * @param array $provider + * + * @return array|mixed + * + * @throws Exception + */ + protected function consider_future_booking_limit(string $selected_date, array $available_hours, array $provider): array + { + $provider_timezone = new DateTimeZone($provider['timezone']); + + $future_booking_limit = setting('future_booking_limit'); // in days + + $threshold = new DateTime('+' . $future_booking_limit . ' days', $provider_timezone); + + $selected_date_time = new DateTime($selected_date); + + if ($threshold < $selected_date_time) + { + return []; + } + + return $threshold > $selected_date_time ? $available_hours : []; + } } diff --git a/application/migrations/042_add_future_booking_limit_setting.php b/application/migrations/042_add_future_booking_limit_setting.php new file mode 100644 index 0000000000..75e62f7e45 --- /dev/null +++ b/application/migrations/042_add_future_booking_limit_setting.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.4.0 + * ---------------------------------------------------------------------------- */ + +/** + * @property CI_DB_query_builder $db + * @property CI_DB_forge $dbforge + */ +class Migration_Add_future_booking_limit_setting extends CI_Migration { + /** + * Upgrade method. + * + * @throws Exception + */ + public function up() + { + if ( ! $this->db->get_where('settings', ['name' => 'future_booking_limit'])->num_rows()) + { + $this->db->insert('settings', [ + 'name' => 'future_booking_limit', + 'value' => '90' // days + ]); + } + } + + /** + * Downgrade method. + * + * @throws Exception + */ + public function down() + { + if ($this->db->get_where('settings', ['name' => 'future_booking_limit'])->num_rows()) + { + $this->db->delete('settings', ['name' => 'future_booking_limit']); + } + } +} diff --git a/application/views/pages/business_settings.php b/application/views/pages/business_settings.php index e59d46225f..24f39f8529 100755 --- a/application/views/pages/business_settings.php +++ b/application/views/pages/business_settings.php @@ -27,11 +27,11 @@ - - - - - + + + + +
@@ -69,9 +69,9 @@ - +

- +
+ +

+ +
+ + +
+ + + +
+
diff --git a/assets/css/layouts/backend_layout.scss b/assets/css/layouts/backend_layout.scss index 0da3b7a41b..ec0cdf2124 100644 --- a/assets/css/layouts/backend_layout.scss +++ b/assets/css/layouts/backend_layout.scss @@ -836,7 +836,8 @@ body .form-horizontal .controls { cursor: pointer; } -#business-logic #book-advance-timeout { +#business-logic #book-advance-timeout, +#business-logic #future-booking-limit { width: 100px; }