PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.1.3
LatePoint – Calendar Booking Plugin for Appointments and Events v5.1.3
5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / controllers / bookings_controller.php
latepoint / lib / controllers Last commit date
activities_controller.php 1 year ago auth_controller.php 1 year ago booking_form_settings_controller.php 1 year ago bookings_controller.php 1 year ago calendars_controller.php 1 year ago carts_controller.php 1 year ago controller.php 1 year ago customer_cabinet_controller.php 1 year ago customers_controller.php 1 year ago dashboard_controller.php 1 year ago default_agent_controller.php 1 year ago events_controller.php 1 year ago form_fields_controller.php 1 year ago integrations_controller.php 1 year ago invoices_controller.php 1 year ago manage_booking_by_key_controller.php 1 year ago manage_order_by_key_controller.php 1 year ago notifications_controller.php 1 year ago orders_controller.php 1 year ago pro_controller.php 1 year ago process_jobs_controller.php 1 year ago processes_controller.php 1 year ago search_controller.php 1 year ago services_controller.php 1 year ago settings_controller.php 1 year ago steps_controller.php 1 year ago stripe_connect_controller.php 1 year ago support_topics_controller.php 1 year ago todos_controller.php 1 year ago transactions_controller.php 1 year ago wizard_controller.php 1 year ago
bookings_controller.php
385 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6
7 if ( ! class_exists( 'OsBookingsController' ) ) :
8
9
10 class OsBookingsController extends OsController {
11
12 private $booking;
13
14 function __construct(){
15 parent::__construct();
16 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'bookings/';
17 $this->vars['page_header'] = OsMenuHelper::get_menu_items_by_id('appointments');
18 $this->vars['breadcrumbs'][] = array('label' => __('Appointments', 'latepoint'), 'link' => OsRouterHelper::build_link(['bookings', 'pending_approval'] ) );
19
20 }
21
22 public function view_booking_log(){
23 $activities = new OsActivityModel();
24 $activities = $activities->where(['booking_id' => absint($this->params['booking_id'])])->order_by('id desc')->get_results_as_models();
25
26 $booking = new OsBookingModel($this->params['booking_id']);
27
28 $this->vars['booking'] = $booking;
29 $this->vars['activities'] = $activities;
30
31 $this->format_render(__FUNCTION__);
32 }
33
34 public function grouped_bookings_quick_view(){
35 if(!isset($this->params['booking_id'])) return false;
36
37 $booking = new OsBookingModel($this->params['booking_id']);
38 $this->vars['booking'] = $booking;
39
40 $group_bookings = new OsBookingModel();
41 $group_bookings = $group_bookings->where(['start_time' => $booking->start_time,
42 'start_date' => $booking->start_date,
43 'service_id' => $booking->service_id,
44 'location_id' => $booking->location_id,
45 'agent_id' => $booking->agent_id])->should_not_be_cancelled()->get_results_as_models();
46 $total_attendees = 0;
47 if($group_bookings){
48 foreach($group_bookings as $group_booking){
49 $total_attendees = $total_attendees + $group_booking->total_attendees;
50 }
51 }
52 $this->vars['total_attendees'] = $total_attendees;
53 $this->vars['group_bookings'] = $group_bookings;
54 $this->format_render(__FUNCTION__);
55 }
56
57 public function pending_approval(){
58 $this->vars['page_header'] = __('Pending Appointments', 'latepoint');
59 $this->vars['breadcrumbs'][] = array('label' => __('Pending Appointments', 'latepoint'), 'link' => false );
60
61 $page_number = isset($this->params['page_number']) ? $this->params['page_number'] : 1;
62 $per_page = OsSettingsHelper::get_number_of_records_per_page();
63 $offset = ($page_number > 1) ? (($page_number - 1) * $per_page) : 0;
64
65 $bookings = new OsBookingModel();
66 $query_args = ['status' => OsBookingHelper::get_booking_statuses_for_pending_page()];
67
68 $bookings->where($query_args)->filter_allowed_records();
69
70 $count_total_bookings = clone $bookings;
71 $total_bookings = $count_total_bookings->count();
72
73 $this->vars['bookings'] = $bookings->set_limit($per_page)->set_offset($offset)->order_by('id desc')->get_results_as_models();
74
75 $total_pages = ceil($total_bookings / $per_page);
76
77 $this->vars['total_pages'] = $total_pages;
78 $this->vars['total_bookings'] = $total_bookings;
79 $this->vars['per_page'] = $per_page;
80 $this->vars['current_page_number'] = $page_number;
81
82 $this->vars['showing_from'] = (($page_number - 1) * $per_page) ? (($page_number - 1) * $per_page) : 1;
83 $this->vars['showing_to'] = min($page_number * $per_page, $this->vars['total_bookings']);
84
85 $this->format_render(__FUNCTION__);
86 }
87
88 public function customize_table(){
89 $this->vars['selected_columns'] = OsSettingsHelper::get_selected_columns_for_bookings_table();
90 $this->vars['available_columns'] = OsSettingsHelper::get_available_columns_for_bookings_table();
91
92 $this->format_render(__FUNCTION__);
93 }
94
95 public function index(){
96
97 $this->vars['page_header'] = false;
98 $this->vars['breadcrumbs'][] = array('label' => __('All', 'latepoint'), 'link' => false );
99
100 $page_number = isset($this->params['page_number']) ? $this->params['page_number'] : 1;
101 $per_page = OsSettingsHelper::get_number_of_records_per_page();
102 $offset = ($page_number > 1) ? (($page_number - 1) * $per_page) : 0;
103
104 $customer = new OsCustomerModel();
105
106 $bookings = new OsBookingModel();
107 $query_args = [];
108
109 $selected_columns = OsSettingsHelper::get_selected_columns_for_bookings_table();
110 $available_columns = OsSettingsHelper::get_available_columns_for_bookings_table();
111
112 $filter = $this->params['filter'] ?? false;
113
114 $order_by = ['key' => 'booking_id', 'direction' => 'desc', 'column' => 'id'];
115
116 // TABLE SEARCH FILTERS
117 if($filter){
118 if(!empty($filter['records_ordered_by_key']) && !empty($filter['records_ordered_by_direction'])){
119 if(in_array($filter['records_ordered_by_direction'], ['desc', 'asc'])) $order_by['direction'] = $filter['records_ordered_by_direction'];
120 $order_by['key'] = $filter['records_ordered_by_key'];
121 switch($filter['records_ordered_by_key']){
122 case 'booking_id':
123 $order_by['column'] = 'id';
124 break;
125 case 'booking_start_datetime':
126 $order_by['column'] = 'start_datetime_utc';
127 break;
128 case 'booking_created_on':
129 $order_by['column'] = 'created_at';
130 break;
131 case 'booking_time_left':
132 $order_by['column'] = 'start_datetime_utc';
133 break;
134 }
135 }
136 if(!empty($filter['service_id'])) $query_args['service_id'] = $filter['service_id'];
137 if(!empty($filter['agent_id'])) $query_args['agent_id'] = $filter['agent_id'];
138 if(!empty($filter['location_id'])) $query_args['location_id'] = $filter['location_id'];
139 if(!empty($filter['time_status'])){
140 switch($filter['time_status']){
141 case 'now':
142 $query_args['start_datetime_utc <='] = OsTimeHelper::now_datetime_utc_in_db_format();
143 $query_args['end_datetime_utc >='] = OsTimeHelper::now_datetime_utc_in_db_format();
144 break;
145 case 'upcoming':
146 $query_args['start_datetime_utc >='] = OsTimeHelper::now_datetime_utc_in_db_format();
147 break;
148 case 'past':
149 $query_args['end_datetime_utc <='] = OsTimeHelper::now_datetime_utc_in_db_format();
150 break;
151 }
152 }
153 if(!empty($filter['status'])) $query_args[LATEPOINT_TABLE_BOOKINGS.'.status'] = $filter['status'];
154 if(!empty($filter['payment_status'])) $query_args[LATEPOINT_TABLE_BOOKINGS.'.payment_status'] = $filter['payment_status'];
155 if(!empty($filter['id'])) $query_args[LATEPOINT_TABLE_BOOKINGS.'.id'] = $filter['id'];
156 if(!empty($filter['created_date_from']) && !empty($filter['created_date_to'])){
157 $query_args[LATEPOINT_TABLE_BOOKINGS.'.created_at >='] = $filter['created_date_from'].' 00:00:00';
158 $query_args[LATEPOINT_TABLE_BOOKINGS.'.created_at <='] = $filter['created_date_to'].' 23:59:59';
159 }
160 if(!empty($filter['booking_date_from']) && !empty($filter['booking_date_to'])){
161 $query_args[LATEPOINT_TABLE_BOOKINGS.'.start_date >='] = $filter['booking_date_from'];
162 $query_args[LATEPOINT_TABLE_BOOKINGS.'.start_date <='] = $filter['booking_date_to'];
163 }
164
165 $selected_columns = OsSettingsHelper::get_selected_columns_for_bookings_table();
166 if(!empty($filter['order'])){
167 $bookings->select( LATEPOINT_TABLE_BOOKINGS . '.*' );
168 $bookings->join( LATEPOINT_TABLE_ORDER_ITEMS, [ 'id' => LATEPOINT_TABLE_BOOKINGS . '.order_item_id' ] );
169 $bookings->join( LATEPOINT_TABLE_ORDERS, [ 'id' => LATEPOINT_TABLE_ORDER_ITEMS . '.order_id' ] );
170 if(!empty($filter['order']['payment_status'])){
171 $bookings->select(LATEPOINT_TABLE_ORDERS.'.payment_status');
172 $query_args[LATEPOINT_TABLE_ORDERS.'.payment_status'] = $filter['order']['payment_status'];
173 }
174
175 }
176 if(!empty($filter['customer'])){
177 $bookings->select( LATEPOINT_TABLE_BOOKINGS . '.*' );
178 if ( ! empty( $filter['customer']['full_name'] ) ) {
179 $bookings->select( LATEPOINT_TABLE_CUSTOMERS . '.first_name, ' . LATEPOINT_TABLE_CUSTOMERS . '.last_name' );
180 $query_args[ 'concat_ws(" ", ' . LATEPOINT_TABLE_CUSTOMERS . '.first_name,' . LATEPOINT_TABLE_CUSTOMERS . '.last_name) LIKE' ] = '%' . $filter['customer']['full_name'] . '%';
181 $this->vars['customer_name_query'] = $filter['customer']['full_name'];
182 }
183 $bookings->join( LATEPOINT_TABLE_CUSTOMERS, [ 'id' => LATEPOINT_TABLE_BOOKINGS . '.customer_id' ] );
184
185
186
187 if ( ! empty( $selected_columns['customer'] ) ) {
188 $meta_filter = [];
189 foreach ( $selected_columns['customer'] as $customer_column_key ) {
190
191 if ( isset( $available_columns['customer'][ $customer_column_key ] ) && ! empty( $filter['customer'][ $customer_column_key ] ) ) {
192
193 if(in_array($customer_column_key, $customer->get_params_to_save())){
194 // native field
195 $bookings->select(LATEPOINT_TABLE_CUSTOMERS.'.'.$customer_column_key);
196 $query_args[LATEPOINT_TABLE_CUSTOMERS.'.'.$customer_column_key.' LIKE'] = '%'.$filter['customer'][$customer_column_key].'%';
197 }else{
198 // meta field
199 $meta_filter[$customer_column_key] = $filter['customer'][ $customer_column_key ];
200 }
201
202 }
203 }
204 if (count($meta_filter)){
205 $customers_ids = OsMetaHelper::get_customers_by_filter($meta_filter) ?: [-1];
206 $query_args[ LATEPOINT_TABLE_CUSTOMERS . '.id IN' ] = $customers_ids;
207 }
208 }
209 }
210 // filters for custom selected columns, only related to booking fields
211 if ( ! empty( $selected_columns['booking'] ) ) {
212 foreach ( $selected_columns['booking'] as $booking_column_key ) {
213 if ( ! empty( $available_columns['booking'][ $booking_column_key ] ) && ! empty( $filter[ $booking_column_key ] ) ) {
214 $query_args[ $booking_column_key . ' LIKE' ] = '%' . $filter[ $booking_column_key ] . '%';
215 }
216 }
217 }
218 }
219
220 $this->vars['agents_list'] = OsAgentHelper::get_agents_list(true);
221 $this->vars['locations_list'] = OsLocationHelper::get_locations_list(true);
222 $this->vars['services_list'] = OsServiceHelper::get_services_list(true);
223
224 $this->vars['selected_columns'] = $selected_columns;
225 $this->vars['available_columns'] = $available_columns;
226
227 $this->vars['records_ordered_by_key'] = $order_by['key'];
228 $this->vars['records_ordered_by_direction'] = $order_by['direction'];
229
230 // OUTPUT CSV IF REQUESTED
231 if(isset($this->params['download']) && $this->params['download'] == 'csv'){
232 $csv_filename = 'all_bookings_'.OsUtilHelper::random_text().'.csv';
233
234 header("Content-Type: text/csv");
235 header("Content-Disposition: attachment; filename={$csv_filename}");
236
237 $labels_row = [ __('ID', 'latepoint'),
238 __('Service', 'latepoint'),
239 __('Start Date & Time', 'latepoint'),
240 __('Duration', 'latepoint'),
241 __('Customer', 'latepoint'),
242 __('Customer Phone', 'latepoint'),
243 __('Customer Email', 'latepoint'),
244 __('Agent', 'latepoint'),
245 __('Agent Phone', 'latepoint'),
246 __('Agent Email', 'latepoint'),
247 __('Status', 'latepoint'),
248 __('Price', 'latepoint'),
249 __('Booked On', 'latepoint') ];
250
251
252 $bookings_data = [];
253 $bookings_data[] = $labels_row;
254
255
256 $bookings_arr = $bookings->where($query_args)->filter_allowed_records()->order_by($order_by['column'].' '.$order_by['direction'])->get_results_as_models();
257
258 if($bookings_arr){
259 foreach($bookings_arr as $booking){
260 $order_item = new OsOrderItemModel( $booking->order_item_id );
261 $values_row = [ $booking->id,
262 $booking->service->name,
263 $booking->nice_start_datetime,
264 $booking->get_total_duration(),
265 $booking->customer->full_name,
266 $booking->customer->phone,
267 $booking->customer->email,
268 $booking->agent->full_name,
269 $booking->agent->phone,
270 $booking->agent->email,
271 $booking->nice_status,
272 OsMoneyHelper::format_price($order_item->get_total(), true, false),
273 $booking->nice_created_at];
274 $values_row = apply_filters('latepoint_booking_row_for_csv_export', $values_row, $booking, $this->params);
275 $bookings_data[] = $values_row;
276 }
277
278 }
279
280 $bookings_data = apply_filters('latepoint_bookings_data_for_csv_export', $bookings_data, $this->params);
281 OsCSVHelper::array_to_csv($bookings_data);
282 return;
283 }
284
285 $query_args = OsRolesHelper::filter_allowed_records_from_arguments_or_filter($query_args);
286 $bookings->where($query_args)->filter_allowed_records();
287 $count_total_bookings = clone $bookings;
288 $total_bookings = $count_total_bookings->count();
289
290 $this->vars['bookings'] = $bookings->set_limit($per_page)->set_offset($offset)->order_by($order_by['column'].' '.$order_by['direction'])->get_results_as_models();
291 $this->vars['total_bookings'] = $total_bookings;
292 $total_pages = ceil($total_bookings / $per_page);
293
294 $this->vars['total_pages'] = $total_pages;
295 $this->vars['per_page'] = $per_page;
296 $this->vars['current_page_number'] = $page_number;
297 $this->vars['total_records'] = $total_bookings;
298
299 $this->vars['showing_from'] = (($page_number - 1) * $per_page) ? (($page_number - 1) * $per_page) : 1;
300 $this->vars['showing_to'] = min($page_number * $per_page, $this->vars['total_bookings']);
301
302 $this->format_render(['json_view_name' => '_table_body', 'html_view_name' => __FUNCTION__], [], ['total_pages' => $total_pages, 'showing_from' => $this->vars['showing_from'], 'showing_to' => $this->vars['showing_to'], 'total_records' => $total_bookings]);
303 }
304
305 function quick_availability(){
306
307 $trigger_form_booking_id = $this->params['trigger_form_booking_id'];
308 $trigger_form_order_item_id = $this->params['trigger_form_order_item_id'];
309
310 $booking = OsOrdersHelper::create_booking_object_from_booking_data_form($this->params['order_items'][$trigger_form_order_item_id]['bookings'][$trigger_form_booking_id]);
311
312 $calendar_start_date = isset($this->params['start_date']) ? new OsWpDateTime($this->params['start_date']) : new OsWpDateTime($booking->start_date);
313 // show one more day before so the current selection does not look weird
314 if(isset($this->params['previous_days'])){
315 $calendar_end_date = clone $calendar_start_date;
316 $calendar_start_date->modify('-30 days');
317 }else{
318 if(!isset($this->params['show_days_only'])) $calendar_start_date->modify('-1 day');
319 $calendar_end_date = clone $calendar_start_date;
320 $calendar_end_date->modify('+30 days');
321 }
322
323 if(OsAuthHelper::get_current_user()->is_single_record_allowed('agent')) $booking->agent_id = OsRolesHelper::get_allowed_records('agent')[0];
324
325 $work_periods = OsWorkPeriodsHelper::get_work_periods(new \LatePoint\Misc\Filter(['date_from' => $calendar_start_date->format('Y-m-d'), 'date_to' => $calendar_end_date->format('Y-m-d'), 'service_id' => $booking->service_id, 'agent_id' => $booking->agent_id, 'location_id' => $booking->location_id]));
326 $work_start_end = OsWorkPeriodsHelper::get_work_start_end_time($work_periods);
327
328 $booking_request = \LatePoint\Misc\BookingRequest::create_from_booking_model($booking);
329 $settings = [];
330 $settings['accessed_from_backend'] = true;
331 if(!$booking->is_new_record()) $settings['exclude_booking_ids'] = [$booking->id];
332 $resources = OsResourceHelper::get_resources_grouped_by_day($booking_request, $calendar_start_date, $calendar_end_date, $settings);
333 $work_boundaries = OsResourceHelper::get_work_boundaries_for_groups_of_resources($resources);
334
335 $this->vars['trigger_form_booking_id'] = $trigger_form_booking_id;
336 $this->vars['trigger_form_order_item_id'] = $trigger_form_order_item_id;
337
338 $this->vars['booking'] = $booking;
339 $this->vars['work_boundaries'] = $work_boundaries;
340 $this->vars['show_days_only'] = isset($this->params['show_days_only']) ? true : false;
341
342 $this->vars['timeblock_interval'] = $booking->service->get_timeblock_interval();
343 $this->vars['calendar_start_date'] = $calendar_start_date;
344 $this->vars['calendar_end_date'] = $calendar_end_date;
345 $this->vars['booking_request'] = $booking_request;
346 $this->vars['resources'] = $resources;
347
348 $agents = new OsAgentModel();
349 $this->vars['agents'] = $agents->filter_allowed_records()->get_results_as_models();
350
351 $this->format_render(__FUNCTION__);
352 }
353
354
355
356
357 function change_status(){
358
359 if(filter_var($this->params['id'], FILTER_VALIDATE_INT)) {
360 $this->check_nonce('change_status_booking_' . $this->params['id']);
361 $booking_id = $this->params['id'];
362 $new_status = $this->params['status'];
363 $booking = new OsBookingModel($booking_id);
364 if (!OsRolesHelper::can_user_make_action_on_model_record($booking, 'edit')) exit;
365
366 if ($booking->update_status($new_status)) {
367 $status = LATEPOINT_STATUS_SUCCESS;
368 $response_html = __('Appointment Status Updated', 'latepoint');
369 } else {
370 $status = LATEPOINT_STATUS_ERROR;
371 $response_html = __('Error Updating Booking Status!', 'latepoint') . ' ' . implode(',', $booking->get_error_messages());
372 }
373 }else{
374 $status = LATEPOINT_STATUS_ERROR;
375 $response_html = __('Error Updating Booking Status! Invalid ID', 'latepoint');
376 }
377
378 if($this->get_return_format() == 'json'){
379 $this->send_json(array('status' => $status, 'message' => $response_html));
380 }
381 }
382
383 }
384
385 endif;