/** * Get AB_CustomerAppointment entities associated with this appointment. * * @return AB_CustomerAppointment[] Array of entities */ public function getCustomerAppointments() { $result = array(); if ($this->get('id')) { $appointments = AB_CustomerAppointment::query('ca')->select('ca.*, c.name, c.phone, c.email')->leftJoin('AB_Customer', 'c', 'c.id = ca.customer_id')->where('ca.appointment_id', $this->get('id'))->fetchArray(); foreach ($appointments as $data) { $ca = new AB_CustomerAppointment(); $ca->setFields($data); // Inject AB_Customer entity. $ca->customer = new AB_Customer(); $data['id'] = $data['customer_id']; $ca->customer->setFields($data, true); $result[] = $ca; } } return $result; }
/** * Export Appointment to CSV */ public function executeExportToCSV() { $start_date = new DateTime($this->getParameter('date_start')); $start_date = $start_date->format('Y-m-d H:i:s'); $end_date = new DateTime($this->getParameter('date_end')); $end_date = $end_date->modify('+1 day')->format('Y-m-d H:i:s'); $delimiter = $this->getParameter('delimiter', ','); header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=Appointments.csv'); $header = array(__('Booking Time', 'bookly'), __('Staff Member', 'bookly'), __('Service', 'bookly'), __('Duration', 'bookly'), __('Price', 'bookly'), __('Customer', 'bookly'), __('Phone', 'bookly'), __('Email', 'bookly')); $custom_fields = array(); $fields_data = json_decode(get_option('ab_custom_fields')); foreach ($fields_data as $field_data) { $custom_fields[$field_data->id] = ''; $header[] = $field_data->label; } $output = fopen('php://output', 'w'); fwrite($output, pack("CCC", 0xef, 0xbb, 0xbf)); fputcsv($output, $header, $delimiter); $rows = AB_CustomerAppointment::query()->select('r.id, r.number_of_persons, r.coupon_discount, r.coupon_deduction, st.full_name AS staff_name, s.title AS service_title, s.duration AS service_duration, c.name AS customer_name, c.phone AS customer_phone, c.email AS customer_email, ss.price, a.start_date')->leftJoin('AB_Appointment', 'a', 'a.id = r.appointment_id')->leftJoin('AB_Service', 's', 's.id = a.service_id')->leftJoin('AB_Staff', 'st', 'st.id = a.staff_id')->leftJoin('AB_Customer', 'c', 'c.id = r.customer_id')->leftJoin('AB_StaffService', 'ss', 'ss.staff_id = st.id AND ss.service_id = s.id')->whereBetween('a.start_date', $start_date, $end_date)->sortBy('a.start_date')->order(AB_Query::ORDER_DESCENDING)->fetchArray(); foreach ($rows as $row) { if ($row['coupon_discount'] or $row['coupon_deduction']) { $coupon = new AB_Coupon(); $coupon->set('discount', $row['coupon_discount']); $coupon->set('deduction', $row['coupon_deduction']); $row['price'] = $coupon->apply($row['price']); } $row['price'] *= $row['number_of_persons']; $row_data = array($row['start_date'], $row['staff_name'], $row['service_title'], AB_Service::durationToString($row['service_duration']), AB_Utils::formatPrice($row['price']), $row['customer_name'], $row['customer_phone'], $row['customer_email']); $customer_appointment = new AB_CustomerAppointment(); $customer_appointment->load($row['id']); foreach ($customer_appointment->getCustomFields() as $custom_field) { $custom_fields[$custom_field['id']] = $custom_field['value']; } fputcsv($output, array_merge($row_data, $custom_fields), $delimiter); $custom_fields = array_map(function () { return ''; }, $custom_fields); } fclose($output); exit; }
/** * 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()); } } } }
/** * Cancel Appointment using token. */ public function executeCancelAppointment() { $customer_appointment = new AB_CustomerAppointment(); if ($customer_appointment->loadBy(array('token' => $this->getParameter('token')))) { // Send email. AB_NotificationSender::send(AB_NotificationSender::INSTANT_CANCELLED_APPOINTMENT, $customer_appointment); $customer_appointment->delete(); $appointment = new AB_Appointment(); $appointment->load($customer_appointment->get('appointment_id')); // Delete appointment, if there aren't customers. $count = AB_CustomerAppointment::query('ca')->where('ca.appointment_id', $customer_appointment->get('appointment_id'))->count(); if (!$count) { $appointment->delete(); } else { $appointment->handleGoogleCalendar(); } if ($this->url = get_option('ab_settings_cancel_page_url')) { wp_redirect($this->url); $this->render('cancel_appointment'); exit(0); } } $this->url = home_url(); if (isset($_SERVER['HTTP_REFERER'])) { if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) == parse_url($this->url, PHP_URL_HOST)) { // Redirect back if user came from our site. $this->url = $_SERVER['HTTP_REFERER']; } } wp_redirect($this->url); $this->render('cancel_appointment'); exit(0); }
/** * Get appointment data when editing an appointment. */ public function executeGetDataForAppointment() { $response = array('success' => false, 'data' => array('customers' => array())); $appointment = new AB_Appointment(); if ($appointment->load($this->getParameter('id'))) { $response['success'] = true; $info = AB_Appointment::query('a')->select('ss.capacity AS max_capacity, SUM( ca.number_of_persons ) AS total_number_of_persons, a.staff_id, a.service_id, a.start_date, a.end_date')->leftJoin('AB_CustomerAppointment', 'ca', 'ca.appointment_id = a.id')->leftJoin('AB_StaffService', 'ss', 'ss.staff_id = a.staff_id AND ss.service_id = a.service_id')->where('a.id', $appointment->get('id'))->fetchRow(); $response['data']['total_number_of_persons'] = $info['total_number_of_persons']; $response['data']['max_capacity'] = $info['max_capacity']; $response['data']['start_date'] = $info['start_date']; $response['data']['end_date'] = $info['end_date']; $response['data']['staff_id'] = $info['staff_id']; $response['data']['service_id'] = $info['service_id']; $customer_appointments = AB_CustomerAppointment::query()->where('appointment_id', $appointment->get('id'))->fetchArray(); foreach ($customer_appointments as $customer_appointment) { $response['data']['customers'][] = array('id' => $customer_appointment['customer_id'], 'custom_fields' => $customer_appointment['custom_fields'] ? json_decode($customer_appointment['custom_fields'], true) : array(), 'number_of_persons' => $customer_appointment['number_of_persons']); } } wp_send_json($response); }