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