PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.2.0
LatePoint – Calendar Booking Plugin for Appointments and Events v5.2.0
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 / models / booking_model.php
latepoint / lib / models Last commit date
activity_model.php 1 year ago agent_meta_model.php 1 year ago agent_model.php 1 year ago booking_meta_model.php 1 year ago booking_model.php 1 year ago bundle_meta_model.php 1 year ago bundle_model.php 1 year ago cart_item_model.php 1 year ago cart_meta_model.php 1 year ago cart_model.php 1 year ago connector_model.php 1 year ago customer_meta_model.php 1 year ago customer_model.php 9 months ago invoice_model.php 1 year ago join_bundles_services_model.php 1 year ago location_category_model.php 1 year ago location_model.php 1 year ago meta_model.php 1 year ago model.php 9 months ago off_period_model.php 1 year ago order_intent_meta_model.php 1 year ago order_intent_model.php 9 months ago order_item_model.php 1 year ago order_meta_model.php 1 year ago order_model.php 1 year ago otp_model.php 9 months ago payment_request_model.php 1 year ago process_job_model.php 1 year ago process_model.php 1 year ago recurrence_model.php 1 year ago service_category_model.php 9 months ago service_meta_model.php 1 year ago service_model.php 9 months ago session_model.php 1 year ago settings_model.php 1 year ago step_settings_model.php 1 year ago transaction_intent_model.php 1 year ago transaction_model.php 1 year ago transaction_refund_model.php 1 year ago work_period_model.php 1 year ago
booking_model.php
1275 lines
1 <?php
2
3 /**
4 * @property OsCustomerModel $customer
5 * @property OsAgentModel $agent
6 * @property OsServiceModel $service
7 * @property OsLocationModel $location
8 */
9 class OsBookingModel extends OsModel {
10 public $id,
11 $booking_code,
12 $service_id,
13 $customer_id,
14 $agent_id,
15 $location_id,
16 $recurrence_id,
17 $buffer_before = 0,
18 $buffer_after = 0,
19 $status,
20 $start_date,
21 $end_date,
22 $start_time,
23 $end_time,
24 $start_datetime_utc,
25 $end_datetime_utc,
26 $duration,
27 $total_attendees = 1,
28 $total_attendees_sum = 1,
29 $total_customers = 1,
30 $cart_item_id = null,
31 $order_item_id,
32 $server_timezone,
33 $customer_timezone,
34 $meta_class = 'OsBookingMetaModel',
35 $keys_to_manage = [],
36 $generate_recurrent_sequence = [],
37 $updated_at,
38 $created_at;
39
40 function __construct( $id = false ) {
41 parent::__construct();
42 $this->table_name = LATEPOINT_TABLE_BOOKINGS;
43 $this->nice_names = array(
44 'service_id' => __( 'Service', 'latepoint' ),
45 'agent_id' => __( 'Agent', 'latepoint' )
46 );
47
48 if ( $id ) {
49 $this->load_by_id( $id );
50 }
51 }
52
53
54 /**
55 * @return mixed|void
56 *
57 * Returns full amount to charge in database format 1999.0000
58 *
59 */
60 public function full_amount_to_charge() {
61 return OsBookingHelper::calculate_full_amount_for_booking( $this );
62 }
63
64 /**
65 * @return mixed|void
66 *
67 * Returns deposit amount to charge in database format 1999.0000
68 *
69 */
70 public function deposit_amount_to_charge() {
71 return OsBookingHelper::calculate_deposit_amount_to_charge( $this );
72 }
73
74
75 public function get_key_to_manage_for(string $for): string {
76 if($this->is_new_record()) return '';
77 if(!empty($this->keys_to_manage[$for])) return $this->keys_to_manage[$for];
78 $key = OsMetaHelper::get_booking_meta_by_key( 'key_to_manage_for_' . $for, $this->id );
79 if ( empty( $key ) ) {
80 $key = OsUtilHelper::generate_key_to_manage();
81 OsMetaHelper::save_booking_meta_by_key( 'key_to_manage_for_' . $for, $key, $this->id );
82 }
83 $this->keys_to_manage[$for] = $key;
84 return $key;
85 }
86
87 public function manage_by_key_url(string $for = 'customer'): string{
88 return OsBookingHelper::generate_direct_manage_booking_url($this, $for);
89 }
90
91 public function get_service_name_for_summary() {
92 $service_name = $this->service_id ? $this->service->name : '';
93
94 /**
95 * Get service name to be displayed on a booking summary
96 *
97 * @param {string} $service_name Service name to be filtered
98 * @param {OsBookingModel} $booking Booking model which service name is requested
99 *
100 * @returns {string} Filtered service name
101 * @since 5.0.0
102 * @hook latepoint_booking_get_service_name_for_summary
103 *
104 */
105 return apply_filters( 'latepoint_booking_get_service_name_for_summary', $service_name, $this );
106 }
107
108 public function get_order() {
109 if ( $this->order_item_id ) {
110 if ( ! isset( $this->order_item ) || ( $this->order_item->id != $this->order_item_id ) ) {
111 $this->order_item = new OsOrderItemModel( $this->order_item_id );
112 if ( ! isset( $this->order ) || ( $this->order->id != $this->order_item->order_id ) ) {
113 $this->order = new OsOrderModel( $this->order_item->order_id );
114 }
115 }
116 } else {
117 $this->order = new OsOrderModel();
118 }
119
120 return $this->order;
121 }
122
123 public function get_order_item( ) {
124 if (!isset( $this->order_item )) {
125 $this->order_item = new OsOrderItemModel( $this->order_item_id );
126 }
127 return $this->order_item;
128 }
129
130 public function filter_allowed_records(): OsModel {
131 if ( ! OsRolesHelper::are_all_records_allowed() ) {
132 if ( ! OsRolesHelper::are_all_records_allowed( 'agent' ) ) {
133 $this->filter_where_conditions( [ 'agent_id' => OsRolesHelper::get_allowed_records( 'agent' ) ] );
134 }
135 if ( ! OsRolesHelper::are_all_records_allowed( 'location' ) ) {
136 $this->filter_where_conditions( [ 'location_id' => OsRolesHelper::get_allowed_records( 'location' ) ] );
137 }
138 if ( ! OsRolesHelper::are_all_records_allowed( 'service' ) ) {
139 $this->filter_where_conditions( [ 'service_id' => OsRolesHelper::get_allowed_records( 'service' ) ] );
140 }
141 }
142
143 return $this;
144 }
145
146 public function properties_to_query(): array {
147 return [
148 'service_id' => __( 'Service', 'latepoint' ),
149 'agent_id' => __( 'Agent', 'latepoint' ),
150 'status' => __( 'Status', 'latepoint' ),
151 'start_datetime_utc' => __( 'Start Time', 'latepoint' ),
152 ];
153 }
154
155 public function generate_item_data() {
156 return wp_json_encode( $this->generate_params_for_booking_form() );
157 }
158
159
160 public function generate_params_for_booking_form() {
161 $params = [
162 "id" => $this->id,
163 "customer_id" => $this->customer_id,
164 "agent_id" => $this->agent_id,
165 "location_id" => $this->location_id,
166 "service_id" => $this->service_id,
167 "recurrence_id" => $this->recurrence_id,
168 "start_date" => $this->start_date,
169 "start_time" => $this->start_time,
170 "end_date" => $this->end_date,
171 "end_time" => $this->end_time,
172 "status" => $this->status,
173 "buffer_before" => $this->buffer_before,
174 "buffer_after" => $this->buffer_after,
175 "duration" => $this->duration,
176 "generate_recurrent_sequence" => $this->generate_recurrent_sequence,
177 ];
178
179 /**
180 * Returns an array of params generated from OsBookingModel to be used in a booking form
181 *
182 * @param {array} $params Array of booking params
183 * @param {OsBookingModel} $booking Instance of <code>OsBookingModel</code> that params are being generated for
184 *
185 * @returns {array} Filtered array of booking params
186 * @since 5.0.0
187 * @hook latepoint_generated_params_for_booking_form
188 *
189 */
190 return apply_filters( 'latepoint_generated_params_for_booking_form', $params, $this );
191 }
192
193 public function get_formatted_price(){
194 $order_item = new OsOrderItemModel( $this->order_item_id );
195 return OsMoneyHelper::format_price($order_item->get_total());
196 }
197
198 public function generate_first_level_data_vars() : array{
199 $vars = [
200 'id' => $this->id,
201 'booking_code' => $this->booking_code,
202 'start_datetime' => $this->format_start_date_and_time_rfc3339(),
203 'end_datetime' => $this->format_end_date_and_time_rfc3339(),
204 'service_name' => $this->service->name,
205 'duration' => $this->duration,
206 'customer_comment' => $this->order->customer_comment,
207 'status' => $this->status,
208 'start_date' => $this->format_start_date(),
209 'start_time' => OsTimeHelper::minutes_to_hours_and_minutes( $this->start_time ),
210 'timezone' => OsTimeHelper::get_wp_timezone_name(),
211 'agent' => $this->agent->get_data_vars(),
212 'created_datetime' => $this->format_created_datetime_rfc3339(),
213 'manage_booking_for_agent' => OsBookingHelper::generate_direct_manage_booking_url( $this, 'agent' ),
214 'manage_booking_for_customer' => OsBookingHelper::generate_direct_manage_booking_url( $this, 'customer' ),
215 ];
216 return $vars;
217 }
218
219 public function generate_data_vars(): array {
220 $vars = $this->get_first_level_data_vars();
221
222 $vars['customer'] = $this->customer->get_data_vars();
223 $vars['transactions'] = [];
224 $vars['order'] = $this->order->get_first_level_data_vars();
225
226 $transactions = $this->order->get_transactions();
227 if ( $transactions ) {
228 foreach ( $transactions as $transaction ) {
229 $vars['transactions'][] = $transaction->get_data_vars();
230 }
231 }
232
233 return $vars;
234 }
235
236
237 public function is_ready_for_summary() {
238 return ( $this->agent_id && $this->agent_id != LATEPOINT_ANY_AGENT && OsAgentHelper::count_agents() > 1 ) || $this->service_id;
239 }
240
241 public function is_part_of_bundle(): bool {
242 if ( $this->order_item_id ) {
243 $order_item = new OsOrderItemModel( $this->order_item_id );
244
245 return $order_item->is_bundle();
246 }
247
248 return false;
249 }
250
251 public function is_upcoming(): bool {
252 if ( empty( $this->start_datetime_utc ) ) {
253 return false;
254 }
255 $start_time_utc = new OsWpDateTime( $this->start_datetime_utc, new DateTimeZone( 'UTC' ) );
256 $now_time_utc = new OsWpDateTime( 'now', new DateTimeZone( 'UTC' ) );
257
258 return ( $start_time_utc > $now_time_utc );
259 }
260
261 public function set_utc_datetimes(bool $save = false) {
262 if ( empty( $this->start_date ) || empty( $this->end_date ) || empty( $this->start_time ) || empty( $this->end_time ) ) {
263 return;
264 }
265 $this->start_datetime_utc = $this->get_start_datetime('UTC')->format(LATEPOINT_DATETIME_DB_FORMAT);
266 $this->end_datetime_utc = $this->get_end_datetime('UTC')->format(LATEPOINT_DATETIME_DB_FORMAT);
267 if ( $save ) {
268 $this->update_attributes(['start_datetime_utc' => $this->start_datetime_utc, 'end_datetime_utc' => $this->end_datetime_utc]);
269 }
270 }
271
272
273 public function delete( $id = false ) {
274 if ( ! $id && isset( $this->id ) ) {
275 $id = $this->id;
276 }
277
278 $booking_metas = new OsBookingMetaModel();
279 $booking_metas->delete_where( [ 'object_id' => $id ] );
280 $process_jobs = new OsProcessJobModel();
281 $process_jobs->delete_where( [ 'object_id' => $id, 'object_model_type' => 'booking' ] );
282
283
284 return parent::delete( $id );
285 }
286
287 public function delete_meta_by_key( $meta_key ) {
288 if ( $this->is_new_record() ) {
289 return true;
290 }
291
292 $meta = new OsBookingMetaModel();
293
294 return $meta->delete_by_key( $meta_key, $this->id );
295 }
296
297 public function get_url_for_add_to_calendar_button( string $calendar_type ): string {
298 switch ( $calendar_type ) {
299 case 'google':
300 $url = 'https://calendar.google.com/calendar/render';
301 $params = [
302 'action' => 'TEMPLATE',
303 'text' => $this->service->name,
304 'dates' => $this->get_start_datetime_object( new DateTimeZone( 'UTC' ) )->format( 'Ymd\THis\Z' ) . '/' . $this->get_end_datetime_object( new DateTimeZone( 'UTC' ) )->format( 'Ymd\THis\Z' )
305 ];
306 if ( ! empty( $this->location->full_address ) ) {
307 $params['location'] = $this->location->full_address;
308 }
309 break;
310 case 'outlook':
311 $url = 'https://outlook.office.com/calendar/0/deeplink/compose';
312 $params = [
313 'path' => '/calendar/action/compose',
314 'rru' => 'addevent',
315 'startdt' => $this->get_start_datetime_object( new DateTimeZone( 'UTC' ) )->format( 'Y-m-d\TH:i:s\Z' ),
316 'enddt' => $this->get_end_datetime_object( new DateTimeZone( 'UTC' ) )->format( 'Y-m-d\TH:i:s\Z' ),
317 'subject' => $this->service->name,
318 ];
319 break;
320 }
321 /**
322 * Generate params for the add to calendar link
323 *
324 * @param {array} $params Array of parameters that will be converted into a param query
325 * @param {string} $calendar_type Type of calendar the link is requested for
326 * @param {OsBookingModel} $booking A booking object
327 * @returns {array} The filtered array of appointment attributes
328 *
329 * @since 4.8.1
330 * @hook latepoint_build_add_to_calendar_link_params
331 *
332 */
333 $params = apply_filters( 'latepoint_build_add_to_calendar_link_params', $params, $calendar_type, $this );
334
335 $url = $url . '?' . http_build_query( $params );
336
337 /**
338 * URL for the link for a button to add appointment to calendar
339 *
340 * @param {array} $params Array of parameters that will be converted into a param query
341 * @param {string} $calendar_type Type of calendar the link is requested for
342 * @param {OsBookingModel} $booking A booking object
343 * @returns {string} The filtered url of adding appointment to calendar
344 *
345 * @since 4.8.1
346 * @hook latepoint_build_add_to_calendar_link_url
347 *
348 */
349 return apply_filters( 'latepoint_build_add_to_calendar_link_url', $url, $calendar_type, $this );
350 }
351
352 public function get_ical_download_link( $key = false ) {
353 return ( $key ) ? OsRouterHelper::build_admin_post_link( [
354 'manage_booking_by_key',
355 'ical_download'
356 ], [ 'key' => $key ] ) : OsRouterHelper::build_admin_post_link( [
357 'customer_cabinet',
358 'ical_download'
359 ], [ 'latepoint_booking_id' => $this->id ] );
360 }
361
362 public function get_print_link( $key = false ) {
363 return ( $key ) ? OsRouterHelper::build_admin_post_link( [ 'manage_booking_by_key', 'print'], [ 'key' => $key ] ) : OsRouterHelper::build_admin_post_link( [ 'customer_cabinet', 'print_booking_info' ], [ 'latepoint_booking_id' => $this->id ] );
364 }
365
366 public function get_meta_by_key( $meta_key, $default = false ) {
367 if ( $this->is_new_record() ) {
368 return $default;
369 }
370
371 $meta = new OsBookingMetaModel();
372
373 return $meta->get_by_key( $meta_key, $this->id, $default );
374 }
375
376 public function get_coupon_code( ) {
377 $order = $this->get_order();
378 return $order->coupon_code;
379 }
380
381 public function get_coupon_discount( ): string {
382 $order_item = $this->get_order_item();
383 $coupon_discount = $order_item->get_coupon_discount();
384 return $coupon_discount > 0 ? OsMoneyHelper::format_price($order_item->get_coupon_discount()) : '';
385 }
386
387 public function save_meta_by_key( $meta_key, $meta_value ) {
388 if ( $this->is_new_record() ) {
389 return false;
390 }
391
392 $meta = new OsBookingMetaModel();
393
394 return $meta->save_by_key( $meta_key, $meta_value, $this->id );
395 }
396
397 public function calculate_end_date() {
398 if ( empty( $this->start_time ) || empty( $this->start_date ) ) {
399 return $this->start_date;
400 }
401 if ( ( $this->start_time + $this->get_total_duration() ) >= ( 24 * 60 ) ) {
402 $date_obj = new OsWpDateTime( $this->start_date );
403 $end_date = $date_obj->modify( '+1 day' )->format( 'Y-m-d' );
404 } else {
405 $end_date = $this->start_date;
406 }
407
408 return $end_date;
409 }
410
411
412 public function calculate_end_time() {
413 $end_time = (int) $this->start_time + (int) $this->get_total_duration();
414 // continues to next day?
415 if ( $end_time > ( 24 * 60 ) ) {
416 $end_time = $end_time - ( 24 * 60 );
417 }
418
419 return $end_time;
420 }
421
422 public function calculate_end_date_and_time() {
423 $this->end_time = $this->calculate_end_time();
424 $this->end_date = $this->calculate_end_date();
425 }
426
427 public function after_data_was_set( $data ) {
428 if ( empty( $this->end_time ) ) {
429 $this->calculate_end_date_and_time();
430 }
431 if ( empty( $this->end_date ) ) {
432 $this->calculate_end_date();
433 }
434 }
435
436 public function set_buffers() {
437 if ( $this->service_id ) {
438 $service = new OsServiceModel( $this->service_id );
439 if ( $service ) {
440 $this->buffer_before = $service->buffer_before;
441 $this->buffer_after = $service->buffer_after;
442 }
443 }
444 }
445
446 public function get_total_duration( $calculate_from_start_and_end = false ) {
447 if ( $calculate_from_start_and_end ) {
448 if ( $this->start_date == $this->end_date ) {
449 // same day
450 $total_duration = $this->end_time - $this->start_time;
451 } else {
452 // TODO calculate how many days difference there is, if difference is more than 1 day - account for that
453 $total_duration = 60 * 24 - $this->start_time + $this->end_time;
454 }
455 } else {
456 if ( $this->duration ) {
457 $total_duration = $this->duration;
458 } else {
459 $total_duration = ( $this->service_id ) ? $this->service->duration : 60;
460 }
461 $total_duration = apply_filters( 'latepoint_calculated_total_duration', $total_duration, $this );
462 }
463
464 return (int) $total_duration;
465 }
466
467
468 public function get_nice_created_at( $include_time = true ) {
469 $format = $include_time ? OsSettingsHelper::get_readable_date_format() . ' ' . OsSettingsHelper::get_readable_time_format() : OsSettingsHelper::get_readable_date_format();
470 $utc_date = date_create_from_format( LATEPOINT_DATETIME_DB_FORMAT, $this->created_at );
471 $wp_timezone_date = $utc_date->setTimezone(OsTimeHelper::get_wp_timezone());
472
473 return date_format( $wp_timezone_date, $format );
474 }
475
476 public function is_bookable( array $settings = [] ): bool {
477
478 $defaults = [
479 'skip_customer_check' => false,
480 'log_errors' => true
481 ];
482
483 $settings = OsUtilHelper::merge_default_atts( $defaults, $settings );
484
485 $customer = $this->customer_id ? new OsCustomerModel( $this->customer_id ) : false;
486 // check if customer has to be assigned to a booking, or a guest booking is fine at this point
487 if($settings['skip_customer_check']){
488 $customer_requirement_satisfied = true;
489 }else{
490 $customer_requirement_satisfied = ($this->customer_id && $customer && $customer->id && ( $this->customer_id == $customer->id ));
491 }
492
493 // agent, service and customer should be set
494 if ( $this->service_id && $this->agent_id && $customer_requirement_satisfied) {
495
496 if ( $this->agent_id == LATEPOINT_ANY_AGENT && $this->location_id == LATEPOINT_ANY_LOCATION ) {
497 // both location and agent are set to any
498 $connections = new OsConnectorModel();
499 $connection_groups = $connections->select( LATEPOINT_TABLE_AGENTS_SERVICES . '.agent_id, ' . LATEPOINT_TABLE_AGENTS_SERVICES . '.location_id' )
500 ->where( [
501 'service_id' => $this->service_id,
502 LATEPOINT_TABLE_AGENTS . '.status' => LATEPOINT_AGENT_STATUS_ACTIVE,
503 LATEPOINT_TABLE_LOCATIONS . '.status' => LATEPOINT_LOCATION_STATUS_ACTIVE
504 ] )
505 ->join( LATEPOINT_TABLE_AGENTS, [ 'id' => LATEPOINT_TABLE_AGENTS_SERVICES . '.agent_id' ] )
506 ->join( LATEPOINT_TABLE_LOCATIONS, [ 'id' => LATEPOINT_TABLE_AGENTS_SERVICES . '.location_id' ] )
507 ->get_results( ARRAY_A );
508 if ( empty( $connection_groups ) ) {
509 // no active locations and agents are connected to this service
510 $this->add_error( 'send_to_step', __( 'Unfortunately there are no active resources that can offer selected service, please select another service.', 'latepoint' ), 'booking__service' );
511
512 return false;
513 } else {
514 foreach ( $connection_groups as $connection ) {
515 $this->location_id = $connection['location_id'];
516 $this->agent_id = OsBookingHelper::get_any_agent_for_booking_by_rule( $this );
517 // available agent found in this location - break the loop
518 if ( $this->agent_id ) {
519 break;
520 }
521 }
522 if ( ! $this->agent_id ) {
523 $this->add_error( 'send_to_step', __( 'Unfortunately the selected time slot is not available anymore, please select another timeslot.', 'latepoint' ), 'booking__datepicker' );
524
525 return false;
526 }
527 }
528
529
530 } elseif ( $this->agent_id == LATEPOINT_ANY_AGENT ) {
531 $this->agent_id = OsBookingHelper::get_any_agent_for_booking_by_rule( $this );
532 if ( ! $this->agent_id ) {
533 $this->add_error( 'send_to_step', __( 'Unfortunately the selected time slot is not available anymore, please select another timeslot.', 'latepoint' ), 'booking__datepicker' );
534
535 return false;
536 }
537 } elseif ( $this->location_id == LATEPOINT_ANY_LOCATION ) {
538 $this->location_id = OsBookingHelper::get_any_location_for_booking_by_rule( $this );
539 if ( ! $this->location_id ) {
540 $this->add_error( 'send_to_step', __( 'Unfortunately the selected time slot is not available anymore, please select another timeslot.', 'latepoint' ), 'booking__datepicker' );
541
542 return false;
543 }
544 } else {
545 // check if booking time is still available
546 if ( ! OsBookingHelper::is_booking_request_available( \LatePoint\Misc\BookingRequest::create_from_booking_model( $this ) ) ) {
547 // translators: %1$s is the timeslot date and time
548 // translators: %2$s is the service name
549 $error_message = sprintf( __( 'Unfortunately the selected time slot "%1$s" for "%2$s" is not available anymore, please select another timeslot.', 'latepoint' ), $this->get_nice_start_datetime_for_customer(), $this->service->name );
550 $this->add_error( 'send_to_step', $error_message, 'booking__datepicker' );
551
552 return false;
553 }
554 }
555
556 if(!$this->validate(false, ['order_item_id', 'status', 'customer_id'])){
557 return false;
558 }
559
560 return true;
561 } else {
562 if ( ! $this->service_id ) {
563 $this->add_error( 'missing_service', __( 'You have to select a service', 'latepoint' ) );
564 }
565 if ( ! $this->agent_id ) {
566 $this->add_error( 'missing_agent', __( 'You have to select an agent', 'latepoint' ) );
567 }
568 if ( ! $this->customer_id && !$settings['skip_customer_check'] ) {
569 $this->add_error( 'missing_customer', __( 'Customer Not Found', 'latepoint' ) );
570 if($settings['log_errors']){
571 OsDebugHelper::log( 'Customer not found', 'customer_error', print_r( $customer, true ) );
572 }
573 }
574 if ( ! $customer && !$settings['skip_customer_check'] ) {
575 $this->add_error( 'missing_customer', __( 'You have to be logged in', 'latepoint' ) );
576 if($settings['log_errors']){
577 OsDebugHelper::log( 'Customer not logged in', 'customer_error', print_r( $customer, true ) );
578 }
579 }
580 if($settings['log_errors']){
581 OsDebugHelper::log( 'Error saving booking', 'booking_error', 'Agent: ' . $this->agent_id . ', Service: ' . $this->service_id . ', Booking Customer: ' . $this->customer_id );
582 }
583
584 return false;
585 }
586 }
587
588
589 public function get_nice_status() {
590 return OsBookingHelper::get_nice_status_name( $this->status );
591 }
592
593 public function get_latest_bookings_sorted_by_status( $args = array() ) {
594 $args = array_merge( array(
595 'service_id' => false,
596 'customer_id' => false,
597 'agent_id' => false,
598 'location_id' => false,
599 'limit' => false,
600 'offset' => false
601 ), $args );
602
603 $bookings = new OsBookingModel();
604 $query_args = array();
605 if ( $args['service_id'] ) {
606 $query_args['service_id'] = $args['service_id'];
607 }
608 if ( $args['customer_id'] ) {
609 $query_args['customer_id'] = $args['customer_id'];
610 }
611 if ( $args['agent_id'] ) {
612 $query_args['agent_id'] = $args['agent_id'];
613 }
614 if ( $args['location_id'] ) {
615 $query_args['location_id'] = $args['location_id'];
616 }
617 if ( $args['limit'] ) {
618 $bookings->set_limit( $args['limit'] );
619 }
620 if ( $args['offset'] ) {
621 $bookings->set_offset( $args['offset'] );
622 }
623
624 return $bookings->where( $query_args )->should_not_be_cancelled()->order_by( "status != '" . LATEPOINT_BOOKING_STATUS_PENDING . "' asc, start_date asc, start_time asc" )->get_results_as_models();
625
626 }
627
628
629 public function should_not_be_cancelled() {
630 return $this->where( [ $this->table_name . '.status !=' => LATEPOINT_BOOKING_STATUS_CANCELLED ] );
631 }
632
633 public function should_be_cancelled() {
634 return $this->where( [ $this->table_name . '.status' => LATEPOINT_BOOKING_STATUS_CANCELLED ] );
635 }
636
637 public function should_be_approved() {
638 return $this->where( [ $this->table_name . '.status' => LATEPOINT_BOOKING_STATUS_APPROVED ] );
639 }
640
641 public function should_be_in_future() {
642 return $this->where( [
643 'OR' => [
644 'start_date >' => OsTimeHelper::today_date( 'Y-m-d' ),
645 'AND' => [
646 'start_date' => OsTimeHelper::today_date( 'Y-m-d' ),
647 'start_time >' => OsTimeHelper::get_current_minutes()
648 ]
649 ]
650 ] );
651 }
652
653
654 public function get_upcoming_bookings( $agent_id = false, $customer_id = false, $service_id = false, $location_id = false, int $limit = 3 ) {
655 $bookings = new OsBookingModel();
656 $args = array(
657 'OR' => array(
658 'start_date >' => OsTimeHelper::today_date( 'Y-m-d' ),
659 'AND' => array(
660 'start_date' => OsTimeHelper::today_date( 'Y-m-d' ),
661 'start_time >' => OsTimeHelper::get_current_minutes()
662 )
663 )
664 );
665 if ( $service_id ) {
666 $args['service_id'] = $service_id;
667 }
668 if ( $customer_id ) {
669 $args['customer_id'] = $customer_id;
670 }
671 if ( $agent_id ) {
672 $args['agent_id'] = $agent_id;
673 }
674 if ( $location_id ) {
675 $args['location_id'] = $location_id;
676 }
677
678 $args = OsAuthHelper::get_current_user()->clean_query_args( $args );
679 $allowed_statuses = OsCalendarHelper::get_booking_statuses_to_display_on_calendar();
680 if (empty($allowed_statuses)) {
681 return [];
682 }
683
684 return $bookings->select( '*, count(id) as total_customers, sum(total_attendees) as total_attendees_sum' )
685 ->where_in('status', $allowed_statuses )
686 ->group_by( 'start_datetime_utc, agent_id, service_id, location_id' )
687 ->where( $args )
688 ->set_limit( $limit )
689 ->order_by( 'start_datetime_utc asc' )
690 ->get_results_as_models();
691
692 }
693
694 public function get_nice_start_time_for_customer() {
695 return $this->format_start_date_and_time( OsTimeHelper::get_time_format(), false, $this->get_customer_timezone() );
696 }
697
698 public function get_nice_end_time_for_customer() {
699 return $this->format_end_date_and_time( OsTimeHelper::get_time_format(), false, $this->get_customer_timezone() );
700 }
701
702 public function get_nice_start_date_for_customer($customer_timezone = false, $hide_year = false) {
703 if(!$customer_timezone) $customer_timezone = $this->get_customer_timezone();
704 return OsUtilHelper::translate_months($this->format_start_date_and_time( OsSettingsHelper::get_readable_date_format($hide_year), false, $customer_timezone ));
705 }
706
707 public function get_nice_start_datetime_for_customer($customer_timezone = false) {
708 if(!$customer_timezone) $customer_timezone = $this->get_customer_timezone();
709 return OsUtilHelper::translate_months($this->format_start_date_and_time( OsSettingsHelper::get_readable_datetime_format(), false, $customer_timezone ));
710 }
711
712 public function get_start_datetime_for_customer() : OsWpDateTime{
713 return $this->get_start_datetime($this->get_customer_timezone_name());
714 }
715 public function get_end_datetime_for_customer() : OsWpDateTime{
716 return $this->get_end_datetime($this->get_customer_timezone_name());
717 }
718
719 public function get_customer_timezone() : DateTimeZone{
720 if(OsSettingsHelper::is_on('steps_show_timezone_selector')){
721 return ($this->customer_id) ? $this->customer->get_selected_timezone_obj() : OsTimeHelper::get_timezone_from_session();
722 }else{
723 return OsTimeHelper::get_wp_timezone();
724 }
725 }
726 public function get_customer_timezone_name() : string{
727 if(OsSettingsHelper::is_on('steps_show_timezone_selector')) {
728 return ( $this->customer_id ) ? $this->customer->get_selected_timezone_name() : OsTimeHelper::get_timezone_name_from_session();
729 }else{
730 return OsTimeHelper::get_wp_timezone_name();
731 }
732 }
733
734 /**
735 *
736 * Returns time in WP timezone, because start_time is stored in WP timezone, do not use it for customer facing outputs
737 *
738 * @return string|null
739 */
740 public function get_nice_start_time() {
741 return OsTimeHelper::minutes_to_hours_and_minutes( $this->start_time );
742 }
743
744 /**
745 *
746 * Returns time in WP timezone, because end_time is stored in WP timezone, do not use it for customer facing outputs
747 *
748 * @return string|null
749 */
750 public function get_nice_end_time() {
751 return OsTimeHelper::minutes_to_hours_and_minutes( $this->end_time );
752 }
753
754 /**
755 *
756 * Returns time in WP timezone, because start_date is stored in WP timezone, do not use it for customer facing outputs
757 *
758 * @return string|null
759 */
760 public function get_nice_end_date( $hide_year_if_current = false ) {
761 $datetime = OsWpDateTime::os_createFromFormat( "Y-m-d", $this->end_date );
762 OsTimeHelper::format_to_nice_date($datetime, $hide_year_if_current);
763 }
764
765 /**
766 *
767 * Returns time in WP timezone, because end_date is stored in WP timezone, do not use it for customer facing outputs
768 *
769 * @return string|null
770 */
771 public function get_nice_start_date( $hide_year_if_current = false ) : string {
772 $datetime = OsWpDateTime::os_createFromFormat( "Y-m-d", $this->start_date );
773 return OsTimeHelper::format_to_nice_date($datetime, $hide_year_if_current);
774 }
775
776
777
778 /**
779 *
780 * Returns time in WP timezone, because start_date is stored in WP timezone, do not use it for customer facing outputs
781 *
782 * @param $hide_if_today bool
783 * @param $hide_year_if_current bool
784 *
785 * @return string
786 */
787 public function get_nice_start_datetime( bool $hide_if_today = true, bool $hide_year_if_current = true ): string {
788 if ( $hide_if_today && $this->start_date == OsTimeHelper::today_date( 'Y-m-d' ) ) {
789 $date = __( 'Today', 'latepoint' );
790 } else {
791 $date = $this->get_nice_start_date( $hide_year_if_current );
792 }
793
794 return implode( ', ', array_filter( [ $date, $this->get_nice_start_time() ] ) );
795 }
796
797
798 public function is_bundle_scheduling() : bool {
799 return ! empty( $this->order_item_id );
800 }
801
802 public function get_connected_recurring_bookings() : array{
803 if(empty($this->recurrence_id) || $this->is_new_record()) return [];
804 $bookings = new OsBookingModel();
805 return $bookings->where(['recurrence_id' => $this->recurrence_id, 'id !=' => $this->id])->order_by('start_datetime_utc asc')->get_results_as_models();
806 }
807
808 public function get_nice_datetime_for_summary(string $viewer = 'customer'){
809 $nice_datetime = '';
810 if($this->start_date){
811 $nice_datetime = $this->get_nice_start_datetime(false);
812 if(OsSettingsHelper::is_on( 'show_booking_end_time') && !empty($this->end_time) && !empty($this->start_time)){
813 $nice_datetime = $nice_datetime.' - '.$this->get_nice_end_time();
814 }
815 }
816 /**
817 * Get a formatted start and end time (if needed)
818 *
819 * @since 5.1.0
820 * @hook latepoint_get_nice_datetime_for_summary
821 *
822 * @param {string} $statuses Nice datetime
823 * @param {OsBookingModel} $booking An object of booking model
824 *
825 * @returns {string} Filtered nice datetime
826 */
827 $nice_datetime = apply_filters('latepoint_get_nice_datetime_for_summary', $nice_datetime, $this, $viewer);
828 return $nice_datetime;
829 }
830
831
832 public function format_end_date_and_time( $format = LATEPOINT_DATETIME_DB_FORMAT, $input_timezone = false, $output_timezone = false ) {
833 if ( ! $input_timezone ) {
834 $input_timezone = OsTimeHelper::get_wp_timezone();
835 }
836 if ( ! $output_timezone ) {
837 $output_timezone = OsTimeHelper::get_wp_timezone();
838 }
839
840 $date = OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $this->end_date . ' ' . OsTimeHelper::minutes_to_army_hours_and_minutes( $this->end_time ) . ':00', $input_timezone );
841 $date->setTimeZone( $output_timezone );
842
843 return OsUtilHelper::translate_months( $date->format( $format ) );
844 }
845
846 public function format_start_date() {
847 if ( empty( $this->start_date ) ) {
848 $date = new OsWpDateTime();
849 $this->start_date = $date->format( 'Y-m-d' );
850 } else {
851 $date = OsWpDateTime::os_createFromFormat( "Y-m-d", $this->start_date );
852 }
853
854 return $date->format( OsSettingsHelper::get_date_format() );
855 }
856
857 public function format_start_date_and_time( $format = LATEPOINT_DATETIME_DB_FORMAT, $input_timezone = false, $output_timezone = false ) {
858 if ( ! $input_timezone ) {
859 $input_timezone = OsTimeHelper::get_wp_timezone();
860 }
861 if ( ! $output_timezone ) {
862 $output_timezone = OsTimeHelper::get_wp_timezone();
863 }
864
865 if ( is_null( $this->start_time ) || $this->start_time === '' ) {
866 // no time set yet (could be because summary is reloaded when date is picked, before the time is picked)
867 $date = OsWpDateTime::os_createFromFormat( "Y-m-d", $this->start_date );
868 if ( $date ) {
869 return OsUtilHelper::translate_months( $date->format( OsSettingsHelper::get_readable_date_format() ) );
870 } else {
871 return __( 'Invalid Date/Time', 'latepoint' );
872 }
873 } else {
874 // both date & time are set, update timezone and translate
875 $date = OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $this->start_date . ' ' . OsTimeHelper::minutes_to_army_hours_and_minutes( $this->start_time ) . ':00', $input_timezone );
876 if ( $date ) {
877 $date->setTimeZone( $output_timezone );
878
879 return OsUtilHelper::translate_months( $date->format( $format ) );
880 } else {
881 return __( 'Invalid Date/Time', 'latepoint' );
882 }
883 }
884 }
885
886 public function format_start_date_and_time_rfc3339() {
887 return $this->format_start_date_and_time( \DateTime::RFC3339 );
888 }
889
890 public function format_end_date_and_time_rfc3339() {
891 return $this->format_end_date_and_time( \DateTime::RFC3339 );
892 }
893
894 public function format_start_date_and_time_for_google() {
895 return $this->format_start_date_and_time( \DateTime::RFC3339 );
896 }
897
898 public function format_end_date_and_time_for_google() {
899 return $this->format_end_date_and_time( \DateTime::RFC3339 );
900 }
901
902 /*
903 * Checks if the booking has passed
904 */
905 public function time_status() {
906 try {
907 $now_datetime = OsTimeHelper::now_datetime_utc();
908 if(empty($this->start_datetime_utc) || empty($this->end_datetime_utc)){
909 $this->set_utc_datetimes(true);
910 }
911 $booking_start = new OsWpDateTime( $this->start_datetime_utc, new DateTimeZone( 'UTC' ) );
912 $booking_end = new OsWpDateTime( $this->end_datetime_utc, new DateTimeZone( 'UTC' ) );
913 if ( ( $now_datetime <= $booking_end ) && ( $now_datetime >= $booking_start ) ) {
914 return 'now';
915 } elseif ( $now_datetime <= $booking_start ) {
916 return 'upcoming';
917 } else {
918 return 'past';
919 }
920 } catch ( Exception $e ) {
921 return 'past';
922 }
923
924 }
925
926 public function start_datetime_in_format( string $format, string $output_in_timezone_name ) : string {
927 if(empty($this->start_datetime_utc)) return '';
928 $booking_start_datetime = OsTimeHelper::date_from_db( $this->start_datetime_utc );
929 $booking_start_datetime->setTimezone( new DateTimeZone($output_in_timezone_name) );
930 return $booking_start_datetime->format( $format );
931 }
932
933 public function is_start_date_and_time_set() : bool {
934 return ($this->start_date != '' && $this->start_time != '');
935 }
936
937 protected function get_time_left() {
938 $now_datetime = new OsWpDateTime( 'now' );
939 $booking_datetime = OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $this->format_start_date_and_time() );
940 $css_class = 'left-days';
941
942 if ( $booking_datetime ) {
943 $diff = $now_datetime->diff( $booking_datetime );
944 if ( $diff->d > 0 || $diff->m > 0 || $diff->y > 0 ) {
945 $left = $diff->format( '%a ' . __( 'days', 'latepoint' ) );
946 } else {
947 if ( $diff->h > 0 ) {
948 $css_class = 'left-hours';
949 $left = $diff->format( '%h ' . __( 'hours', 'latepoint' ) );
950 } else {
951 $css_class = 'left-minutes';
952 $left = $diff->format( '%i ' . __( 'minutes', 'latepoint' ) );
953 }
954 }
955 } else {
956 $left = 'n/a';
957 }
958
959 return '<span class="time-left ' . esc_attr($css_class) . '">' . esc_html($left) . '</span>';
960 }
961
962
963 protected function get_agent() {
964 if ( $this->agent_id ) {
965 if ( ! isset( $this->agent ) || ( isset( $this->agent ) && ( $this->agent->id != $this->agent_id ) ) ) {
966 $this->agent = new OsAgentModel( $this->agent_id );
967 }
968 } else {
969 $this->agent = new OsAgentModel();
970 }
971
972 return $this->agent;
973 }
974
975 public function get_agent_full_name() {
976 if ( $this->agent_id == LATEPOINT_ANY_AGENT ) {
977 return __( 'Any Available Agent', 'latepoint' );
978 } else {
979 return $this->agent->full_name;
980 }
981 }
982
983
984 public function get_location() {
985 if ( $this->location_id ) {
986 // if location has not been initialized yet, or location_id is different from the one initialized - init again
987 if ( empty( $this->location ) || ( $this->location->id != $this->location_id ) ) {
988 $this->location = new OsLocationModel( $this->location_id );
989 }
990 } else {
991 $this->location = new OsLocationModel();
992 }
993
994 return $this->location;
995 }
996
997 protected function get_customer() {
998 if ( $this->customer_id ) {
999 if ( ! isset( $this->customer ) || ( isset( $this->customer ) && ( $this->customer->id != $this->customer_id ) ) ) {
1000 $this->customer = new OsCustomerModel( $this->customer_id );
1001 }
1002 } else {
1003 $this->customer = new OsCustomerModel();
1004 }
1005
1006 return $this->customer;
1007 }
1008
1009
1010 protected function get_service() {
1011 if ( $this->service_id ) {
1012 if ( ! isset( $this->service ) || ( isset( $this->service ) && ( $this->service->id != $this->service_id ) ) ) {
1013 $this->service = new OsServiceModel( $this->service_id );
1014 }
1015 } else {
1016 $this->service = new OsServiceModel();
1017 }
1018
1019 return $this->service;
1020 }
1021
1022 public function get_nice_start_date_in_timezone(string $timezone_name = '', $hide_year_if_current = false) : string{
1023 $datetime = $this->get_start_datetime($timezone_name);
1024 return OsTimeHelper::format_to_nice_date($datetime, $hide_year_if_current);
1025 }
1026
1027 public function get_nice_end_date_in_timezone(string $timezone_name = '', $hide_year_if_current = false) : string{
1028 $datetime = $this->get_end_datetime($timezone_name);
1029 return OsTimeHelper::format_to_nice_date($datetime, $hide_year_if_current);
1030 }
1031
1032 public function get_nice_start_time_in_timezone(string $timezone_name = '') : string{
1033 $datetime = $this->get_start_datetime($timezone_name);
1034 return OsTimeHelper::format_to_nice_time($datetime);
1035 }
1036
1037 public function get_nice_end_time_in_timezone(string $timezone_name = '') : string{
1038 $datetime = $this->get_end_datetime($timezone_name);
1039 return OsTimeHelper::format_to_nice_time($datetime);
1040 }
1041
1042 public function get_start_datetime_object( ?DateTimeZone $timezone = null ) {
1043 if ( empty( $timezone ) ) {
1044 $timezone = OsTimeHelper::get_wp_timezone();
1045 }
1046 if ( empty( $this->start_datetime_utc ) ) {
1047 // fix data, probably an older booking from the time when we didn't store UTC date
1048 $this->start_datetime_utc = $this->generate_start_datetime_in_db_format();
1049 }
1050 $booking_start_datetime = OsTimeHelper::date_from_db( $this->start_datetime_utc );
1051 if ( $booking_start_datetime ) {
1052 $booking_start_datetime->setTimezone( $timezone );
1053 } else {
1054 OsDebugHelper::log( 'Error generating start date and time for booking ID: ' . $this->id, 'corrupt_booking_data' );
1055 }
1056
1057 return $booking_start_datetime;
1058 }
1059
1060 public function get_end_datetime_object( ?DateTimeZone $timezone = null ) {
1061 if ( empty( $timezone ) ) {
1062 $timezone = OsTimeHelper::get_wp_timezone();
1063 }
1064 if ( empty( $this->end_datetime_utc ) ) {
1065 // fix data, probably an older booking from the time when we didn't store UTC date
1066 $this->end_datetime_utc = $this->generate_end_datetime_in_db_format();
1067 }
1068 $booking_end_datetime = OsTimeHelper::date_from_db( $this->end_datetime_utc );
1069 if ( $booking_end_datetime ) {
1070 $booking_end_datetime->setTimezone( $timezone );
1071 } else {
1072 OsDebugHelper::log( 'Error generating end date and time for booking ID: ' . $this->id, 'corrupt_booking_data' );
1073 }
1074
1075 return $booking_end_datetime;
1076 }
1077
1078 public function get_start_datetime( string $set_timezone = 'UTC') : OsWpDateTime{
1079 try{
1080 // start_time and start_date is legacy stored in wordpress timezone
1081 $dateTime = new OsWpDateTime( $this->start_date . ' 00:00:00', OsTimeHelper::get_wp_timezone() );
1082 if($this->start_time > 0){
1083 $dateTime->modify( '+' . $this->start_time . ' minutes' );
1084 }
1085 if($set_timezone) $dateTime->setTimezone( new DateTimeZone( $set_timezone ) );
1086 return $dateTime;
1087 }catch(Exception $e){
1088 return new OsWpDateTime('now');
1089 }
1090 }
1091
1092 public function get_end_datetime( string $set_timezone = 'UTC') : OsWpDateTime{
1093 try{
1094 // start_time and start_date is legacy stored in wordpress timezone
1095 $dateTime = new OsWpDateTime( $this->end_date . ' 00:00:00', OsTimeHelper::get_wp_timezone() );
1096 if($this->end_time > 0){
1097 $dateTime->modify( '+' . $this->end_time . ' minutes' );
1098 }
1099 if($set_timezone) $dateTime->setTimezone( new DateTimeZone( $set_timezone ) );
1100 return $dateTime;
1101 }catch(Exception $e){
1102 return new OsWpDateTime('now');
1103 }
1104 }
1105
1106 public function generate_start_datetime_in_db_format( string $timezone = 'UTC' ): string {
1107 $dateTime = $this->get_start_datetime($timezone);
1108
1109 return $dateTime->format( LATEPOINT_DATETIME_DB_FORMAT );
1110 }
1111
1112
1113 public function generate_end_datetime_in_db_format( string $timezone = 'UTC' ): string {
1114 $dateTime = $this->get_end_datetime($timezone);
1115
1116 return $dateTime->format( LATEPOINT_DATETIME_DB_FORMAT );
1117 }
1118
1119
1120 protected function before_save() {
1121 // TODO check for uniqueness
1122 if ( empty( $this->booking_code ) ) {
1123 $this->booking_code = strtoupper( OsUtilHelper::random_text( 'distinct', 7 ) );
1124 }
1125 if ( empty( $this->end_date ) ) {
1126 $this->end_date = $this->calculate_end_date();
1127 }
1128 if ( empty( $this->status ) ) {
1129 $this->status = $this->get_default_booking_status();
1130 }
1131 if ( empty( $this->total_attendees ) ) {
1132 $this->total_attendees = 1;
1133 }
1134 if ( empty( $this->duration ) && $this->service_id ) {
1135 $service = new OsServiceModel( $this->service_id );
1136 $this->duration = $service->duration;
1137 }
1138 }
1139
1140 public function get_default_booking_status() {
1141 return OsBookingHelper::get_default_booking_status( $this->service_id );
1142 }
1143
1144 public function update_status( $new_status ) {
1145 if ( $new_status == $this->status ) {
1146 return true;
1147 } else {
1148 if ( ! in_array( $new_status, array_keys( OsBookingHelper::get_statuses_list() ) ) ) {
1149 $this->add_error( 'invalid_booking_status', 'Invalid booking status' );
1150
1151 return false;
1152 }
1153 $old_booking = clone $this;
1154 $this->status = $new_status;
1155 $result = $this->update_attributes( [ 'status' => $new_status ] );
1156 if ( $result ) {
1157 do_action( 'latepoint_booking_updated', $this, $old_booking );
1158
1159 return true;
1160 } else {
1161 return false;
1162 }
1163 }
1164 }
1165
1166 public function convert_start_datetime_into_server_timezone(string $input_timezone, bool $set_as_customer_timezone = true){
1167 $this->server_timezone = OsTimeHelper::get_wp_timezone_name();
1168 if($set_as_customer_timezone) $this->customer_timezone = $input_timezone;
1169 if ( $this->is_start_date_and_time_set() && $this->server_timezone != $input_timezone ) {
1170
1171 try {
1172 // convert from submitted customer timezone into WP timezone
1173 $start_datetime = new OsWpDateTime( $this->start_date . ' 00:00:00', new DateTimeZone( $input_timezone ) );
1174 if ( $this->start_time > 0 ) {
1175 $start_datetime->modify( '+' . $this->start_time . ' minutes' );
1176 }
1177 $start_datetime->setTimezone( OsTimeHelper::get_wp_timezone() );
1178 $this->start_date = $start_datetime->format( 'Y-m-d' );
1179 $this->start_time = OsTimeHelper::convert_datetime_to_minutes( $start_datetime );
1180
1181 } catch ( Exception $e ) {
1182 }
1183
1184 }
1185 }
1186
1187 public function save_avatar( $image_id = false ) {
1188 if ( ( false === $image_id ) && $this->image_id ) {
1189 $image_id = $this->image_id;
1190 }
1191 if ( $image_id && $this->post_id ) {
1192 set_post_thumbnail( $this->post_id, $image_id );
1193 $this->image_id = $image_id;
1194 }
1195
1196 return $this->image_id;
1197 }
1198
1199
1200 protected function allowed_params( $role = 'admin' ) {
1201 $allowed_params = array(
1202 'service_id',
1203 'booking_code',
1204 'agent_id',
1205 'customer_id',
1206 'location_id',
1207 'start_date',
1208 'end_date',
1209 'start_time',
1210 'end_time',
1211 'start_datetime_utc',
1212 'end_datetime_utc',
1213 'buffer_before',
1214 'duration',
1215 'buffer_after',
1216 'total_attendees',
1217 'total_attendees_sum',
1218 'total_customers',
1219 'cart_item_id',
1220 'order_item_id',
1221 'status',
1222 'form_id',
1223 'server_timezone',
1224 'customer_timezone',
1225 'generate_recurrent_sequence',
1226 'recurrence_id'
1227 );
1228
1229 return $allowed_params;
1230 }
1231
1232
1233 protected function params_to_save( $role = 'admin' ) {
1234 $params_to_save = array(
1235 'service_id',
1236 'booking_code',
1237 'agent_id',
1238 'customer_id',
1239 'location_id',
1240 'start_date',
1241 'end_date',
1242 'start_time',
1243 'end_time',
1244 'start_datetime_utc',
1245 'end_datetime_utc',
1246 'duration',
1247 'buffer_before',
1248 'buffer_after',
1249 'total_attendees',
1250 'status',
1251 'order_item_id',
1252 'server_timezone',
1253 'customer_timezone',
1254 'recurrence_id'
1255 );
1256
1257 return $params_to_save;
1258 }
1259
1260
1261 protected function properties_to_validate() {
1262 $validations = array(
1263 'order_item_id' => array( 'presence' ),
1264 'service_id' => array( 'presence' ),
1265 'agent_id' => array( 'presence' ),
1266 'location_id' => array( 'presence' ),
1267 'customer_id' => array( 'presence' ),
1268 'start_date' => array( 'presence' ),
1269 'end_date' => array( 'presence' ),
1270 'status' => array( 'presence' ),
1271 );
1272
1273 return $validations;
1274 }
1275 }