/** * Get schedule items of staff member. * * @return array */ public function getScheduleItems() { if (!$this->isLoaded()) { return array(); } $start_of_week = (int) get_option('start_of_week'); // Start of week affects the sorting. // If it is 0(Sun) then the result should be 1,2,3,4,5,6,7. // If it is 1(Mon) then the result should be 2,3,4,5,6,7,1. // If it is 2(Tue) then the result should be 3,4,5,6,7,1,2. Etc. return AB_StaffScheduleItem::query()->where('staff_id', $this->get('id'))->sortBy("IF(r.day_index + 10 - {$start_of_week} > 10, r.day_index + 10 - {$start_of_week}, 16 + r.day_index)")->indexBy('day_index')->find(); }
/** * Contructor. * * @param $form_id */ public function __construct($form_id) { $this->form_id = $form_id; // Set up default parameters. $prior_time = AB_BookingConfiguration::getMinimumTimePriorBooking(); $this->set('date_from', date('Y-m-d', current_time('timestamp') + $prior_time)); $schedule_item = AB_StaffScheduleItem::query('ssi')->select('SUBSTRING_INDEX(MIN(ssi.start_time), ":", 2) AS min_end_time')->whereNot('start_time', null)->fetchArray(); $this->set('time_from', $schedule_item[0]['min_end_time']); $schedule_item = AB_StaffScheduleItem::query('ssi')->select('SUBSTRING_INDEX(MAX(end_time), ":", 2) AS max_end_time')->whereNot('start_time', null)->fetchArray(); $this->set('time_to', $schedule_item[0]['max_end_time']); // If logged in then set name, email and if existing customer then also phone. $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { $customer = new AB_Customer(); if ($customer->loadBy(array('wp_user_id' => $current_user->ID))) { $this->set('name', $customer->get('name')); $this->set('email', $customer->get('email')); $this->set('phone', $customer->get('phone')); } else { $this->set('name', $current_user->display_name); $this->set('email', $current_user->user_email); } } }
/** * Prepare data for staff. * * @param DateTime $start_date */ private function _prepareStaffData(DateTime $start_date) { $this->staffData = array(); $services = AB_StaffService::query('ss')->select('ss.staff_id, ss.price, ss.capacity')->whereIn('ss.staff_id', $this->staff_ids)->where('ss.service_id', $this->userData->get('service_id'))->fetchArray(); foreach ($services as $item) { $this->staffData[$item['staff_id']] = array('price' => $item['price'], 'capacity' => $item['capacity'], 'holidays' => array(), 'bookings' => array(), 'working_hours' => array()); } // Load holidays. $holidays = AB_Holiday::query('h')->whereIn('h.staff_id', $this->staff_ids)->fetchArray(); foreach ($holidays as $item) { $this->staffData[$item['staff_id']]['holidays'][] = $item; } // Load working schedule. $working_schedule = AB_StaffScheduleItem::query('ssi')->select('ssi.*, break.start_time AS break_start, break.end_time AS break_end')->leftJoin('AB_ScheduleItemBreak', 'break', 'break.staff_schedule_item_id = ssi.id')->whereIn('ssi.staff_id', $this->staff_ids)->whereNot('ssi.start_time', null)->fetchArray(); foreach ($working_schedule as $item) { if (!isset($this->staffData[$item['staff_id']]['working_hours'][$item['day_index']])) { $this->staffData[$item['staff_id']]['working_hours'][$item['day_index']] = array('start_time' => $item['start_time'], 'end_time' => $item['end_time'], 'breaks' => array()); } if ($item['break_start']) { $this->staffData[$item['staff_id']]['working_hours'][$item['day_index']]['breaks'][] = array('start' => $item['break_start'], 'end' => $item['break_end']); } } // Load bookings. $bookings = AB_CustomerAppointment::query('ca')->select('a.*, SUM(ca.number_of_persons) AS number_of_bookings')->leftJoin('AB_Appointment', 'a', 'a.id = ca.appointment_id')->leftJoin('AB_StaffService', 'ss', 'ss.staff_id = a.staff_id AND ss.service_id = a.service_id')->whereIn('a.staff_id', $this->staff_ids)->whereGte('a.start_date', $this->userData->get('date_from'))->groupBy('a.start_date')->groupBy('a.staff_id')->groupBy('a.service_id')->fetchArray(); foreach ($bookings as $item) { $item['from_google'] = false; // Handle bookings which end at 24:00. if (substr($item['end_date'], 11) == '00:00:00') { // Set time to 24:00:00 (date part does not matter, it just needs to be 10 characters length). $item['end_date'] = '10_symbols 24:00:00'; } $this->staffData[$item['staff_id']]['bookings'][] = $item; } // Handle Google Calendar events. if (get_option('ab_settings_google_two_way_sync')) { $query = AB_Staff::query('s')->whereIn('s.id', array_merge($this->userData->get('staff_ids'), array(0))); foreach ($query->find() as $staff) { $google = new AB_Google(); if ($google->loadByStaff($staff)) { $this->staffData[$staff->get('id')]['bookings'] = array_merge($this->staffData[$staff->get('id')]['bookings'], $google->getCalendarEvents($start_date) ?: array()); } } } }
/** * Fetches ids of the available days + the available time range * For the 1st step of the booking wizard * * @return array */ public function fetchAvailableWorkDaysAndTime() { /** @var WP_Locale $wp_locale */ global $wp_locale; $schedule_items = AB_StaffScheduleItem::query('ssi')->select('GROUP_CONCAT( DISTINCT ssi.day_index ORDER BY ssi.day_index ) AS available_day_ids, SUBSTRING_INDEX(MIN(ssi.start_time), \':\', 2) AS min_start_time, SUBSTRING_INDEX(MAX(ssi.end_time), \':\', 2) AS max_end_time')->whereNot('ssi.start_time', null)->fetchArray(); $data = current($schedule_items); $result = array('available_days' => array(), 'time_range' => array()); if ($data['available_day_ids']) { $wp_week_start_day = (int) get_option('start_of_week'); $available_day_ids = explode(',', $data['available_day_ids']); $week_days = array_values($wp_locale->weekday_abbrev); if ($wp_week_start_day >= $available_day_ids[0]) { $list_start = array_slice($week_days, $wp_week_start_day, 7, TRUE); $list_end = array_slice($week_days, 0, $wp_week_start_day, TRUE); $week_days = $list_start + $list_end; } foreach ($week_days as $day_id => $day_name) { if (in_array($day_id + 1, $available_day_ids)) { $result['available_days'][$day_id + 1] = $day_name; } } } if ($data['min_start_time'] && $data['max_end_time']) { $start_timestamp = strtotime(sprintf("1970-01-01 %s", $data['min_start_time'])); $end_timestamp = strtotime(sprintf("1970-01-01 %s", $data['max_end_time'])); $now_timestamp = $start_timestamp; $now_timestamp_print = $start_timestamp; $end_timestamp_print = $end_timestamp; if ($this->client_timezone_offset !== false) { $now_timestamp_print -= ($this->client_timezone_offset + get_option('gmt_offset')) * 3600; $end_timestamp_print -= ($this->client_timezone_offset + get_option('gmt_offset')) * 3600; } while ($now_timestamp <= $end_timestamp) { $result['time_range'][AB_DateTimeUtils::buildTimeString($now_timestamp, false)] = AB_DateTimeUtils::formatTime($now_timestamp_print); // The next value will be rounded to integer number of hours, i.e. e.g. 8:00, 9:00, 10:00 and so on. $now_timestamp = $this->roundTime($now_timestamp + 30 * 60); $now_timestamp_print = $this->roundTime($now_timestamp_print + 30 * 60); } // The last value should always be the end time. $result['time_range'][AB_DateTimeUtils::buildTimeString($end_timestamp, false)] = AB_DateTimeUtils::formatTime($end_timestamp_print); } return $result; }