This commit is contained in:
807
application/controllers/Calendar.php
Normal file
807
application/controllers/Calendar.php
Normal file
@@ -0,0 +1,807 @@
|
||||
<?php defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Easy!Appointments - Online Appointment Scheduler
|
||||
*
|
||||
* @package EasyAppointments
|
||||
* @author A.Tselegidis <alextselegidis@gmail.com>
|
||||
* @copyright Copyright (c) Alex Tselegidis
|
||||
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
|
||||
* @link https://easyappointments.org
|
||||
* @since v1.5.0
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Calendar controller.
|
||||
*
|
||||
* Handles calendar related operations.
|
||||
*
|
||||
* @package Controllers
|
||||
*/
|
||||
class Calendar extends EA_Controller
|
||||
{
|
||||
public array $allowed_customer_fields = [
|
||||
'id',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone_number',
|
||||
'address',
|
||||
'city',
|
||||
'state',
|
||||
'zip_code',
|
||||
'timezone',
|
||||
'language',
|
||||
'notes',
|
||||
'custom_field_1',
|
||||
'custom_field_2',
|
||||
'custom_field_3',
|
||||
'custom_field_4',
|
||||
'custom_field_5',
|
||||
];
|
||||
|
||||
public array $optional_customer_fields = [
|
||||
//
|
||||
];
|
||||
|
||||
public array $allowed_appointment_fields = [
|
||||
'id',
|
||||
'start_datetime',
|
||||
'end_datetime',
|
||||
'location',
|
||||
'notes',
|
||||
'color',
|
||||
'status',
|
||||
'is_unavailability',
|
||||
'id_users_provider',
|
||||
'id_users_customer',
|
||||
'id_services',
|
||||
];
|
||||
|
||||
public array $optional_appointment_fields = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Calendar constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('appointments_model');
|
||||
$this->load->model('unavailabilities_model');
|
||||
$this->load->model('blocked_periods_model');
|
||||
$this->load->model('customers_model');
|
||||
$this->load->model('services_model');
|
||||
$this->load->model('providers_model');
|
||||
$this->load->model('roles_model');
|
||||
|
||||
$this->load->library('accounts');
|
||||
$this->load->library('google_sync');
|
||||
$this->load->library('notifications');
|
||||
$this->load->library('synchronization');
|
||||
$this->load->library('timezones');
|
||||
$this->load->library('webhooks_client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the calendar page and display the selected appointment.
|
||||
*
|
||||
* This method will call the "index" callback to handle the page rendering.
|
||||
*
|
||||
* @param string $appointment_hash Appointment hash.
|
||||
*/
|
||||
public function reschedule(string $appointment_hash): void
|
||||
{
|
||||
$this->index($appointment_hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the main backend page.
|
||||
*
|
||||
* This method displays the main backend page. All login permission can view this page which displays a calendar
|
||||
* with the events of the selected provider or service. If a user has more privileges he will see more menus at the
|
||||
* top of the page.
|
||||
*
|
||||
* @param string $appointment_hash Appointment hash.
|
||||
*/
|
||||
public function index(string $appointment_hash = ''): void
|
||||
{
|
||||
session([
|
||||
'dest_url' => site_url('calendar/index' . (!empty($appointment_hash) ? '/' . $appointment_hash : '')),
|
||||
]);
|
||||
|
||||
$user_id = session('user_id');
|
||||
|
||||
if (cannot('view', PRIV_APPOINTMENTS)) {
|
||||
if ($user_id) {
|
||||
abort(403, 'Forbidden');
|
||||
}
|
||||
|
||||
redirect('login');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$role_slug = session('role_slug');
|
||||
|
||||
$user = $this->users_model->find($user_id);
|
||||
|
||||
$secretary_providers = [];
|
||||
|
||||
if ($role_slug === DB_SLUG_SECRETARY) {
|
||||
$secretary = $this->secretaries_model->find(session('user_id'));
|
||||
|
||||
$secretary_providers = $secretary['providers'];
|
||||
}
|
||||
|
||||
$edit_appointment = null;
|
||||
|
||||
if (!empty($appointment_hash)) {
|
||||
$occurrences = $this->appointments_model->get(['hash' => $appointment_hash]);
|
||||
|
||||
if ($appointment_hash !== '' && !empty($occurrences)) {
|
||||
$edit_appointment = $occurrences[0];
|
||||
|
||||
$this->appointments_model->load($edit_appointment, ['customer']);
|
||||
}
|
||||
}
|
||||
|
||||
$privileges = $this->roles_model->get_permissions_by_slug($role_slug);
|
||||
|
||||
$available_providers = $this->providers_model->get_available_providers();
|
||||
|
||||
if ($role_slug === DB_SLUG_PROVIDER) {
|
||||
$available_providers = array_values(
|
||||
array_filter($available_providers, function ($available_provider) use ($user_id) {
|
||||
return (int) $available_provider['id'] === (int) $user_id;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if ($role_slug === DB_SLUG_SECRETARY) {
|
||||
$available_providers = array_values(
|
||||
array_filter($available_providers, function ($available_provider) use ($secretary_providers) {
|
||||
return in_array($available_provider['id'], $secretary_providers);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
$available_services = $this->services_model->get_available_services();
|
||||
|
||||
$calendar_view = request('view', $user['settings']['calendar_view']);
|
||||
|
||||
$appointment_status_options = setting('appointment_status_options');
|
||||
|
||||
script_vars([
|
||||
'user_id' => $user_id,
|
||||
'role_slug' => $role_slug,
|
||||
'date_format' => setting('date_format'),
|
||||
'time_format' => setting('time_format'),
|
||||
'first_weekday' => setting('first_weekday'),
|
||||
'company_working_plan' => setting('company_working_plan'),
|
||||
'timezones' => $this->timezones->to_array(),
|
||||
'privileges' => $privileges,
|
||||
'calendar_view' => $calendar_view,
|
||||
'available_providers' => $available_providers,
|
||||
'available_services' => $available_services,
|
||||
'secretary_providers' => $secretary_providers,
|
||||
'edit_appointment' => $edit_appointment,
|
||||
'google_sync_feature' => config('google_sync_feature'),
|
||||
'customers' => $this->customers_model->get(null, 50, null, 'update_datetime DESC'),
|
||||
'default_language' => setting('default_language'),
|
||||
'default_timezone' => setting('default_timezone'),
|
||||
]);
|
||||
|
||||
html_vars([
|
||||
'page_title' => lang('calendar'),
|
||||
'active_menu' => PRIV_APPOINTMENTS,
|
||||
'user_display_name' => $this->accounts->get_user_display_name($user_id),
|
||||
'timezone' => session('timezone'),
|
||||
'timezones' => $this->timezones->to_array(),
|
||||
'grouped_timezones' => $this->timezones->to_grouped_array(),
|
||||
'privileges' => $privileges,
|
||||
'calendar_view' => $calendar_view,
|
||||
'available_providers' => $available_providers,
|
||||
'available_services' => $available_services,
|
||||
'secretary_providers' => $secretary_providers,
|
||||
'appointment_status_options' => json_decode($appointment_status_options, true) ?? [],
|
||||
'require_first_name' => setting('require_first_name'),
|
||||
'require_last_name' => setting('require_last_name'),
|
||||
'require_email' => setting('require_email'),
|
||||
'require_phone_number' => setting('require_phone_number'),
|
||||
'require_address' => setting('require_address'),
|
||||
'require_city' => setting('require_city'),
|
||||
'require_zip_code' => setting('require_zip_code'),
|
||||
'require_notes' => setting('require_notes'),
|
||||
]);
|
||||
|
||||
$this->load->view('pages/calendar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save appointment changes that are made from the backend calendar page.
|
||||
*/
|
||||
public function save_appointment(): void
|
||||
{
|
||||
try {
|
||||
$customer_data = request('customer_data');
|
||||
|
||||
$appointment_data = request('appointment_data');
|
||||
|
||||
$this->check_event_permissions((int) $appointment_data['id_users_provider']);
|
||||
|
||||
// Save customer changes to the database.
|
||||
if ($customer_data) {
|
||||
$customer = $customer_data;
|
||||
|
||||
$required_permissions = !empty($customer['id'])
|
||||
? can('add', PRIV_CUSTOMERS)
|
||||
: can('edit', PRIV_CUSTOMERS);
|
||||
|
||||
if (!$required_permissions) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$this->customers_model->only($customer, $this->allowed_customer_fields);
|
||||
|
||||
$this->customers_model->optional($customer, $this->optional_customer_fields);
|
||||
|
||||
$customer['id'] = $this->customers_model->save($customer);
|
||||
}
|
||||
|
||||
// Save appointment changes to the database.
|
||||
$manage_mode = !empty($appointment_data['id']);
|
||||
|
||||
if ($appointment_data) {
|
||||
$appointment = $appointment_data;
|
||||
|
||||
$required_permissions = !empty($appointment['id'])
|
||||
? can('add', PRIV_APPOINTMENTS)
|
||||
: can('edit', PRIV_APPOINTMENTS);
|
||||
|
||||
if (!$required_permissions) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
// If the appointment does not contain the customer record id, then it means that is going to be inserted.
|
||||
|
||||
if (!isset($appointment['id_users_customer'])) {
|
||||
$appointment['id_users_customer'] = $customer['id'] ?? $customer_data['id'];
|
||||
}
|
||||
|
||||
if ($manage_mode && !empty($appointment['id'])) {
|
||||
$this->synchronization->remove_appointment_on_provider_change($appointment['id']);
|
||||
}
|
||||
|
||||
$this->appointments_model->only($appointment, $this->allowed_appointment_fields);
|
||||
|
||||
$this->appointments_model->optional($appointment, $this->optional_appointment_fields);
|
||||
|
||||
$appointment['id'] = $this->appointments_model->save($appointment);
|
||||
}
|
||||
|
||||
if (empty($appointment['id'])) {
|
||||
throw new RuntimeException('The appointment ID is not available.');
|
||||
}
|
||||
|
||||
$appointment = $this->appointments_model->find($appointment['id']);
|
||||
$provider = $this->providers_model->find($appointment['id_users_provider']);
|
||||
$customer = $this->customers_model->find($appointment['id_users_customer']);
|
||||
$service = $this->services_model->find($appointment['id_services']);
|
||||
|
||||
$company_color = setting('company_color');
|
||||
|
||||
$settings = [
|
||||
'company_name' => setting('company_name'),
|
||||
'company_link' => setting('company_link'),
|
||||
'company_email' => setting('company_email'),
|
||||
'company_color' => !empty($company_color) && $company_color != DEFAULT_COMPANY_COLOR ? $company_color : null,
|
||||
'date_format' => setting('date_format'),
|
||||
'time_format' => setting('time_format'),
|
||||
];
|
||||
|
||||
$this->synchronization->sync_appointment_saved($appointment, $service, $provider, $customer, $settings);
|
||||
|
||||
$this->notifications->notify_appointment_saved(
|
||||
$appointment,
|
||||
$service,
|
||||
$provider,
|
||||
$customer,
|
||||
$settings,
|
||||
$manage_mode,
|
||||
);
|
||||
|
||||
$this->webhooks_client->trigger(WEBHOOK_APPOINTMENT_SAVE, $appointment);
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
private function check_event_permissions(int $provider_id): void
|
||||
{
|
||||
$user_id = (int) session('user_id');
|
||||
$role_slug = session('role_slug');
|
||||
|
||||
if (
|
||||
$role_slug === DB_SLUG_SECRETARY &&
|
||||
!$this->secretaries_model->is_provider_supported($user_id, $provider_id)
|
||||
) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
if ($role_slug === DB_SLUG_PROVIDER && $user_id !== $provider_id) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete appointment from the database.
|
||||
*
|
||||
* This method deletes an existing appointment from the database. Once this action is finished it cannot be undone.
|
||||
* Notification emails are send to both provider and customer and the delete action is executed to the Google
|
||||
* Calendar account of the provider, if the "google_sync" setting is enabled.
|
||||
*/
|
||||
public function delete_appointment(): void
|
||||
{
|
||||
try {
|
||||
if (cannot('delete', 'appointments')) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$appointment_id = request('appointment_id');
|
||||
$cancellation_reason = (string) request('cancellation_reason');
|
||||
|
||||
if (empty($appointment_id)) {
|
||||
throw new InvalidArgumentException('No appointment id provided.');
|
||||
}
|
||||
|
||||
// Store appointment data for later use in this method.
|
||||
$appointment = $this->appointments_model->find($appointment_id);
|
||||
|
||||
$this->check_event_permissions((int) $appointment['id_users_provider']);
|
||||
|
||||
$provider = $this->providers_model->find($appointment['id_users_provider']);
|
||||
$customer = $this->customers_model->find($appointment['id_users_customer']);
|
||||
$service = $this->services_model->find($appointment['id_services']);
|
||||
|
||||
$company_color = setting('company_color');
|
||||
|
||||
$settings = [
|
||||
'company_name' => setting('company_name'),
|
||||
'company_email' => setting('company_email'),
|
||||
'company_link' => setting('company_link'),
|
||||
'company_color' => !empty($company_color) && $company_color != DEFAULT_COMPANY_COLOR ? $company_color : null,
|
||||
'date_format' => setting('date_format'),
|
||||
'time_format' => setting('time_format'),
|
||||
];
|
||||
|
||||
// Delete appointment record from the database.
|
||||
$this->appointments_model->delete($appointment_id);
|
||||
|
||||
$this->notifications->notify_appointment_deleted(
|
||||
$appointment,
|
||||
$service,
|
||||
$provider,
|
||||
$customer,
|
||||
$settings,
|
||||
$cancellation_reason,
|
||||
);
|
||||
|
||||
$this->synchronization->sync_appointment_deleted($appointment, $provider);
|
||||
|
||||
$this->webhooks_client->trigger(WEBHOOK_APPOINTMENT_DELETE, $appointment);
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert of update unavailability to database.
|
||||
*/
|
||||
public function save_unavailability(): void
|
||||
{
|
||||
try {
|
||||
// Check privileges
|
||||
$unavailability = request('unavailability');
|
||||
|
||||
$required_permissions = !isset($unavailability['id'])
|
||||
? can('add', PRIV_APPOINTMENTS)
|
||||
: can('edit', PRIV_APPOINTMENTS);
|
||||
|
||||
if (!$required_permissions) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$provider_id = (int) $unavailability['id_users_provider'];
|
||||
|
||||
$this->check_event_permissions($provider_id);
|
||||
|
||||
$provider = $this->providers_model->find($provider_id);
|
||||
|
||||
$unavailability_id = $this->unavailabilities_model->save($unavailability);
|
||||
|
||||
$unavailability = $this->unavailabilities_model->find($unavailability_id);
|
||||
|
||||
$this->synchronization->sync_unavailability_saved($unavailability, $provider);
|
||||
|
||||
$this->webhooks_client->trigger(WEBHOOK_UNAVAILABILITY_SAVE, $unavailability);
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
'warnings' => $warnings ?? [],
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an unavailability from database.
|
||||
*/
|
||||
public function delete_unavailability(): void
|
||||
{
|
||||
try {
|
||||
if (cannot('delete', PRIV_APPOINTMENTS)) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$unavailability_id = request('unavailability_id');
|
||||
|
||||
$unavailability = $this->unavailabilities_model->find($unavailability_id);
|
||||
|
||||
$this->check_event_permissions((int) $unavailability['id_users_provider']);
|
||||
|
||||
$provider = $this->providers_model->find($unavailability['id_users_provider']);
|
||||
|
||||
$this->unavailabilities_model->delete($unavailability_id);
|
||||
|
||||
$this->synchronization->sync_unavailability_deleted($unavailability, $provider);
|
||||
|
||||
$this->webhooks_client->trigger(WEBHOOK_UNAVAILABILITY_DELETE, $unavailability);
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert of update working plan exceptions to database.
|
||||
*/
|
||||
public function save_working_plan_exception(): void
|
||||
{
|
||||
try {
|
||||
if (cannot('edit', PRIV_USERS)) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$date = request('date');
|
||||
|
||||
$original_date = request('original_date');
|
||||
|
||||
$working_plan_exception = request('working_plan_exception');
|
||||
|
||||
if (!$working_plan_exception) {
|
||||
$working_plan_exception = null;
|
||||
}
|
||||
|
||||
$provider_id = request('provider_id');
|
||||
|
||||
$this->providers_model->save_working_plan_exception($provider_id, $date, $working_plan_exception);
|
||||
|
||||
if ($original_date && $date !== $original_date) {
|
||||
$this->providers_model->delete_working_plan_exception($provider_id, $original_date);
|
||||
}
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a working plan exceptions time period to database.
|
||||
*/
|
||||
public function delete_working_plan_exception(): void
|
||||
{
|
||||
try {
|
||||
$required_permissions = can('edit', PRIV_CUSTOMERS);
|
||||
|
||||
if (!$required_permissions) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$date = request('date');
|
||||
|
||||
$provider_id = request('provider_id');
|
||||
|
||||
$this->providers_model->delete_working_plan_exception($provider_id, $date);
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Calendar Events
|
||||
*
|
||||
* This method will return all the calendar events within a specified period.
|
||||
*/
|
||||
public function get_calendar_appointments_for_table_view(): void
|
||||
{
|
||||
try {
|
||||
$required_permissions = can('view', PRIV_APPOINTMENTS);
|
||||
|
||||
if (!$required_permissions) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$start_date = request('start_date') . ' 00:00:00';
|
||||
|
||||
$end_date = request('end_date') . ' 23:59:59';
|
||||
|
||||
$response = [
|
||||
'appointments' => $this->appointments_model->get([
|
||||
'start_datetime >=' => $start_date,
|
||||
'end_datetime <=' => $end_date,
|
||||
]),
|
||||
'unavailabilities' => $this->unavailabilities_model->get([
|
||||
'start_datetime >=' => $start_date,
|
||||
'end_datetime <=' => $end_date,
|
||||
]),
|
||||
];
|
||||
|
||||
foreach ($response['appointments'] as &$appointment) {
|
||||
$appointment['provider'] = $this->providers_model->find($appointment['id_users_provider']);
|
||||
$appointment['service'] = $this->services_model->find($appointment['id_services']);
|
||||
$appointment['customer'] = $this->customers_model->find($appointment['id_users_customer']);
|
||||
}
|
||||
|
||||
unset($appointment);
|
||||
|
||||
$user_id = session('user_id');
|
||||
|
||||
$role_slug = session('role_slug');
|
||||
|
||||
// If the current user is a provider he must only see his own appointments.
|
||||
if ($role_slug === DB_SLUG_PROVIDER) {
|
||||
foreach ($response['appointments'] as $index => $appointment) {
|
||||
if ((int) $appointment['id_users_provider'] !== (int) $user_id) {
|
||||
unset($response['appointments'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['appointments'] = array_values($response['appointments']);
|
||||
|
||||
foreach ($response['unavailabilities'] as $index => $unavailability) {
|
||||
if ((int) $unavailability['id_users_provider'] !== (int) $user_id) {
|
||||
unset($response['unavailabilities'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['unavailabilities'] = array_values($response['unavailabilities']);
|
||||
}
|
||||
|
||||
// If the current user is a secretary he must only see the appointments of his providers.
|
||||
if ($role_slug === DB_SLUG_SECRETARY) {
|
||||
$providers = $this->secretaries_model->find($user_id)['providers'];
|
||||
|
||||
foreach ($response['appointments'] as $index => $appointment) {
|
||||
if (!in_array((int) $appointment['id_users_provider'], $providers)) {
|
||||
unset($response['appointments'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['appointments'] = array_values($response['appointments']);
|
||||
|
||||
foreach ($response['unavailabilities'] as $index => $unavailability) {
|
||||
if (!in_array((int) $unavailability['id_users_provider'], $providers)) {
|
||||
unset($response['unavailabilities'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['unavailabilities'] = array_values($response['unavailabilities']);
|
||||
}
|
||||
|
||||
foreach ($response['unavailabilities'] as &$unavailability) {
|
||||
$unavailability['provider'] = $this->providers_model->find($unavailability['id_users_provider']);
|
||||
}
|
||||
|
||||
unset($unavailability);
|
||||
|
||||
// Add blocked periods to the response.
|
||||
$start_date = request('start_date');
|
||||
$end_date = request('end_date');
|
||||
$response['blocked_periods'] = $this->blocked_periods_model->get_for_period($start_date, $end_date);
|
||||
|
||||
json_response($response);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered appointments for the given date period and record.
|
||||
*
|
||||
* This method returns the database appointments and unavailability periods for the user selected date period and
|
||||
* record type (provider or service).
|
||||
*/
|
||||
public function get_calendar_appointments(): void
|
||||
{
|
||||
try {
|
||||
if (cannot('view', PRIV_APPOINTMENTS)) {
|
||||
throw new RuntimeException('You do not have the required permissions for this task.');
|
||||
}
|
||||
|
||||
$record_id = request('record_id');
|
||||
|
||||
$is_all = request('record_id') === FILTER_TYPE_ALL;
|
||||
|
||||
$filter_type = request('filter_type');
|
||||
|
||||
if (!$filter_type && !$is_all) {
|
||||
json_response([
|
||||
'appointments' => [],
|
||||
'unavailabilities' => [],
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$record_id = $this->db->escape($record_id);
|
||||
|
||||
if ($filter_type == FILTER_TYPE_PROVIDER) {
|
||||
$where_id = 'id_users_provider';
|
||||
} elseif ($filter_type === FILTER_TYPE_SERVICE) {
|
||||
$where_id = 'id_services';
|
||||
} else {
|
||||
$where_id = $record_id;
|
||||
}
|
||||
|
||||
// Get appointments
|
||||
$start_date = $this->db->escape(request('start_date'));
|
||||
$end_date = $this->db->escape(date('Y-m-d', strtotime(request('end_date') . ' +1 day')));
|
||||
|
||||
$where_clause =
|
||||
$where_id .
|
||||
' = ' .
|
||||
$record_id .
|
||||
'
|
||||
AND ((start_datetime > ' .
|
||||
$start_date .
|
||||
' AND start_datetime < ' .
|
||||
$end_date .
|
||||
')
|
||||
or (end_datetime > ' .
|
||||
$start_date .
|
||||
' AND end_datetime < ' .
|
||||
$end_date .
|
||||
')
|
||||
or (start_datetime <= ' .
|
||||
$start_date .
|
||||
' AND end_datetime >= ' .
|
||||
$end_date .
|
||||
'))
|
||||
AND is_unavailability = 0
|
||||
';
|
||||
|
||||
$response['appointments'] = $this->appointments_model->get($where_clause);
|
||||
|
||||
foreach ($response['appointments'] as &$appointment) {
|
||||
$appointment['provider'] = $this->providers_model->find($appointment['id_users_provider']);
|
||||
$appointment['service'] = $this->services_model->find($appointment['id_services']);
|
||||
$appointment['customer'] = $this->customers_model->find($appointment['id_users_customer']);
|
||||
}
|
||||
|
||||
unset($appointment);
|
||||
|
||||
// Get unavailability periods (only for provider).
|
||||
$response['unavailabilities'] = [];
|
||||
|
||||
if ($filter_type == FILTER_TYPE_PROVIDER || $is_all) {
|
||||
$where_clause =
|
||||
$where_id .
|
||||
' = ' .
|
||||
$record_id .
|
||||
'
|
||||
AND ((start_datetime > ' .
|
||||
$start_date .
|
||||
' AND start_datetime < ' .
|
||||
$end_date .
|
||||
')
|
||||
or (end_datetime > ' .
|
||||
$start_date .
|
||||
' AND end_datetime < ' .
|
||||
$end_date .
|
||||
')
|
||||
or (start_datetime <= ' .
|
||||
$start_date .
|
||||
' AND end_datetime >= ' .
|
||||
$end_date .
|
||||
'))
|
||||
AND is_unavailability = 1
|
||||
';
|
||||
|
||||
$response['unavailabilities'] = $this->unavailabilities_model->get($where_clause);
|
||||
}
|
||||
|
||||
$user_id = session('user_id');
|
||||
|
||||
$role_slug = session('role_slug');
|
||||
|
||||
// If the current user is a provider he must only see his own appointments.
|
||||
if ($role_slug === DB_SLUG_PROVIDER) {
|
||||
foreach ($response['appointments'] as $index => $appointment) {
|
||||
if ((int) $appointment['id_users_provider'] !== (int) $user_id) {
|
||||
unset($response['appointments'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['appointments'] = array_values($response['appointments']);
|
||||
|
||||
foreach ($response['unavailabilities'] as $index => $unavailability) {
|
||||
if ((int) $unavailability['id_users_provider'] !== (int) $user_id) {
|
||||
unset($response['unavailabilities'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($unavailability);
|
||||
|
||||
$response['unavailabilities'] = array_values($response['unavailabilities']);
|
||||
}
|
||||
|
||||
// If the current user is a secretary he must only see the appointments of his providers.
|
||||
if ($role_slug === DB_SLUG_SECRETARY) {
|
||||
$providers = $this->secretaries_model->find($user_id)['providers'];
|
||||
|
||||
foreach ($response['appointments'] as $index => $appointment) {
|
||||
if (!in_array((int) $appointment['id_users_provider'], $providers)) {
|
||||
unset($response['appointments'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['appointments'] = array_values($response['appointments']);
|
||||
|
||||
foreach ($response['unavailabilities'] as $index => $unavailability) {
|
||||
if (!in_array((int) $unavailability['id_users_provider'], $providers)) {
|
||||
unset($response['unavailabilities'][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$response['unavailabilities'] = array_values($response['unavailabilities']);
|
||||
}
|
||||
|
||||
foreach ($response['unavailabilities'] as &$unavailability) {
|
||||
$unavailability['provider'] = $this->providers_model->find($unavailability['id_users_provider']);
|
||||
}
|
||||
|
||||
unset($unavailability);
|
||||
|
||||
// Add blocked periods to the response.
|
||||
$start_date = request('start_date');
|
||||
$end_date = request('end_date');
|
||||
$response['blocked_periods'] = $this->blocked_periods_model->get_for_period($start_date, $end_date);
|
||||
|
||||
json_response($response);
|
||||
} catch (Throwable $e) {
|
||||
json_exception($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user