PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.2.4
LatePoint – Calendar Booking Plugin for Appointments and Events v5.2.4
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 / service_model.php
latepoint / lib / models Last commit date
activity_model.php 11 months ago agent_meta_model.php 1 year ago agent_model.php 1 year ago booking_meta_model.php 1 year ago booking_model.php 11 months ago bundle_meta_model.php 11 months ago bundle_model.php 11 months 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 9 months 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 11 months 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
service_model.php
534 lines
1 <?php
2 class OsServiceModel extends OsModel{
3 public $id,
4 $name = '',
5 $short_description,
6 $selection_image_id,
7 $description_image_id,
8 $is_price_variable,
9 $price_min,
10 $price_max,
11 $charge_amount,
12 $deposit_amount,
13 $duration_name = '',
14 $duration = 60,
15 $buffer_before,
16 $buffer_after,
17 $category_id,
18 $override_default_booking_status = false,
19 $status,
20 $bg_color,
21 $order_number,
22 $visibility = LATEPOINT_SERVICE_VISIBILITY_VISIBLE,
23 $capacity_min = 1,
24 $capacity_max = 1,
25 $timeblock_interval,
26 $is_custom_price = false,
27 $is_custom_hours = false,
28 $is_custom_duration = false,
29 $meta_class = 'OsServiceMetaModel',
30 $services_agents_table_name,
31 $is_deposit_required,
32 $earliest_possible_booking,
33 $latest_possible_booking,
34 $deposit_value,
35 $updated_at,
36 $created_at;
37
38 function __construct($id = false){
39 parent::__construct();
40 $this->table_name = LATEPOINT_TABLE_SERVICES;
41 $this->services_agents_table_name = LATEPOINT_TABLE_AGENTS_SERVICES;
42 $this->nice_names = array(
43 'name' => __('Service Name', 'latepoint'),
44 'short_description' => __('Service Short Description', 'latepoint'),
45 'selection_image_id' => __('Service Selection Image', 'latepoint'),
46 'description_image_id' => __('Service Description Image', 'latepoint'),
47 'is_price_variable' => __('Variable Price', 'latepoint'),
48 'price_min' => __('Minimum Price', 'latepoint'),
49 'price_max' => __('Maximum Price', 'latepoint'),
50 'charge_amount' => __('Charge Amount', 'latepoint'),
51 'deposit_amount' => __('Deposit Amount', 'latepoint'),
52 'duration_name' => __('Duration Name', 'latepoint'),
53 'duration' => __('Service Duration', 'latepoint'),
54 'buffer_before' => __('Buffer Before', 'latepoint'),
55 'buffer_after' => __('Buffer After', 'latepoint'),
56 'bg_color' => __('Background Color', 'latepoint'),
57 'category_id' => __('Service Category', 'latepoint'));
58
59 if($id){
60 $this->load_by_id($id);
61 }
62 }
63
64 protected function params_to_save($role = 'admin'){
65 $params_to_save = array('id',
66 'name',
67 'short_description',
68 'category_id',
69 'selection_image_id',
70 'is_price_variable',
71 'price_min',
72 'price_max',
73 'charge_amount',
74 'deposit_amount',
75 'duration_name',
76 'duration',
77 'buffer_before',
78 'buffer_after',
79 'bg_color',
80 'timeblock_interval',
81 'override_default_booking_status',
82 'order_number',
83 'visibility',
84 'status',
85 'earliest_possible_booking',
86 'latest_possible_booking',
87 'capacity_min',
88 'capacity_max',
89 'description_image_id');
90 return $params_to_save;
91 }
92
93 protected function allowed_params($role = 'admin'){
94 $allowed_params = array('id',
95 'name',
96 'short_description',
97 'category_id',
98 'selection_image_id',
99 'is_price_variable',
100 'price_min',
101 'price_max',
102 'charge_amount',
103 'deposit_amount',
104 'duration_name',
105 'duration',
106 'buffer_before',
107 'buffer_after',
108 'bg_color',
109 'timeblock_interval',
110 'override_default_booking_status',
111 'order_number',
112 'visibility',
113 'earliest_possible_booking',
114 'latest_possible_booking',
115 'status',
116 'capacity_min',
117 'capacity_max',
118 'description_image_id');
119 return $allowed_params;
120 }
121
122
123 public function prepare_data_before_it_is_set( $data ) {
124 if ( isset( $data['name'] ) ) {
125 $data['name'] = sanitize_text_field( $data['name'] );
126 }
127 if ( isset( $data['short_description'] ) ) {
128 $data['short_description'] = wp_kses_post( $data['short_description'] );
129 }
130
131
132 return $data;
133 }
134
135 public function get_default_booking_status(){
136 if(!empty($this->override_default_booking_status)){
137 $all_statuses = OsBookingHelper::get_statuses_list();
138 if(isset($all_statuses[$this->override_default_booking_status])) return $this->override_default_booking_status;
139 }
140 return OsBookingHelper::get_default_booking_status();
141 }
142
143 public function get_category_name(){
144 if($this->category_id){
145 $category = new OsServiceCategoryModel($this->category_id);
146 if($category->exists()){
147 return $category->name;
148 }
149 }
150 return '';
151 }
152
153
154 // determine how much capacity service can accept before the slot is blocked
155 public function get_capacity_needed_before_slot_is_blocked(): int{
156 $capacity_min = $this->capacity_min ? $this->capacity_min : 1;
157 $capacity_max = $this->capacity_max ? $this->capacity_max : 1;
158 return ($this->get_meta_by_key('block_timeslot_when_minimum_capacity_met', 'off') == 'on') ? $capacity_min : $capacity_max;
159 }
160
161 public function get_timeblock_interval(){
162 if(!$this->timeblock_interval){
163 $this->timeblock_interval = OsSettingsHelper::get_default_timeblock_interval();
164 }
165 return $this->timeblock_interval;
166 }
167
168 public function filter_allowed_records(): OsModel{
169 if(!OsRolesHelper::are_all_records_allowed('service')){
170 $this->filter_where_conditions(['id' => OsRolesHelper::get_allowed_records('service')]);
171 }
172 return $this;
173 }
174
175
176 protected function before_create(){
177 }
178
179 public function should_show_capacity_selector(){
180 return (($this->capacity_max != $this->capacity_min) && ($this->get_meta_by_key('fixed_total_attendees', 'off') != 'on'));
181 }
182
183 public function is_group_service(){
184 return ($this->capacity_max > 1);
185 }
186
187 public function get_all_durations_arr(){
188 $durations = [['id' => 'default', 'name' => $this->duration_name, 'duration' => $this->duration, 'charge_amount' => $this->charge_amount, 'deposit_amount' => $this->deposit_amount]];
189 $durations = array_merge($durations, $this->get_extra_durations());
190 return $durations;
191 }
192
193 public function get_extra_durations(){
194 $durations = [];
195 $extra_durations = $this->get_meta_by_key('durations', false);
196 if($extra_durations){
197 $extra_durations_arr = json_decode($extra_durations, true);
198 if(!empty($extra_durations_arr)){
199 foreach($extra_durations_arr as $duration_id => $extra_duration){
200 $durations[] = ['id' => $duration_id, 'name' => ($extra_duration['name'] ?? ''), 'duration' => $extra_duration['duration'], 'charge_amount' => $extra_duration['charge_amount'], 'deposit_amount' => $extra_duration['deposit_amount']];
201 }
202 }
203 }
204 return $durations;
205 }
206
207 public function get_full_amount_for_duration($duration = false){
208 if($duration && $duration != $this->duration){
209 $extra_durations = $this->get_extra_durations();
210 foreach($extra_durations as $extra_duration){
211 if($extra_duration['duration'] == $duration) return $extra_duration['charge_amount'];
212 }
213 }
214 return $this->charge_amount;
215 }
216
217 public function get_deposit_amount_for_duration($duration = false){
218 if($duration && $duration != $this->duration){
219 $extra_durations = $this->get_extra_durations();
220 foreach($extra_durations as $extra_duration){
221 if($extra_duration['duration'] == $duration) return $extra_duration['deposit_amount'];
222 }
223 }
224 return $this->deposit_amount;
225 }
226
227 protected function set_defaults(){
228 if(empty($this->category_id)) $this->category_id = 0;
229 if(empty($this->buffer_before)) $this->buffer_before = 0;
230 if(empty($this->buffer_after)) $this->buffer_after = 0;
231 if(empty($this->price_min)) $this->price_min = 0;
232 if(empty($this->price_max)) $this->price_max = 0;
233 if(empty($this->charge_amount)) $this->charge_amount = 0;
234 if(empty($this->deposit_amount)) $this->deposit_amount = 0;
235 if(empty($this->is_deposit_required)) $this->is_deposit_required = false;
236 if(empty($this->status)) $this->status = LATEPOINT_SERVICE_STATUS_ACTIVE;
237 if(empty($this->bg_color)) $this->bg_color = $this->generate_new_bg_color();
238 }
239
240 public function save_custom_schedule($work_periods){
241 foreach($work_periods as &$work_period){
242 $work_period['service_id'] = $this->id;
243 }
244 unset($work_period);
245 OsWorkPeriodsHelper::save_work_periods($work_periods);
246 }
247
248 public function delete_custom_schedule(){
249 $work_periods_model = new OsWorkPeriodModel();
250 $work_periods = $work_periods_model->where(array('service_id' => $this->id, 'agent_id' => 0, 'location_id' => 0, 'custom_date' => 'IS NULL'))->get_results_as_models();
251 if(is_array($work_periods)){
252 foreach($work_periods as $work_period){
253 $work_period->delete();
254 }
255 }
256 }
257
258 public function generate_new_bg_color(){
259 $services = new OsServiceModel();
260 $service_colors_results = $services->select('bg_color')->group_by('bg_color')->get_results(ARRAY_A);
261 $services_used_colors = array_map(function($service){ return $service['bg_color']; }, $service_colors_results);
262 $default_colors = OsServiceHelper::get_default_colors();
263 $colors_left = array_diff($default_colors, $services_used_colors);
264 if(!empty($colors_left)){
265 // reset array
266 $colors_left = array_values($colors_left);
267 $bg_color = $colors_left[0];
268 }else{
269 $bg_color = '#3d52ea';
270 }
271 return $bg_color;
272 }
273
274
275 public function delete($id = false){
276 if(!$id && isset($this->id)){
277 $id = $this->id;
278 }
279 if($id && $this->db->delete( $this->table_name, array('id' => $id), array( '%d' ))){
280 $this->db->delete(LATEPOINT_TABLE_AGENTS_SERVICES, array('service_id' => $id), array( '%d' ) );
281 $this->db->delete(LATEPOINT_TABLE_WORK_PERIODS, array('service_id' => $id), array( '%d' ) );
282 $this->db->delete(LATEPOINT_TABLE_SERVICE_META, array('object_id' => $id), array( '%d' ) );
283 $this->db->delete(LATEPOINT_TABLE_BOOKINGS, array('service_id' => $id), array( '%d' ) );
284 do_action('latepoint_service_deleted', $id);
285 return true;
286 }else{
287 return false;
288 }
289 }
290
291 protected function params_to_sanitize(){
292 return ['charge_amount' => 'money',
293 'deposit_amount' => 'money',
294 'price_min' => 'money',
295 'price_max' => 'money',
296 ];
297 }
298
299 public function is_hidden(){
300 return ($this->visibility == LATEPOINT_SERVICE_VISIBILITY_HIDDEN);
301 }
302
303 public function should_be_active(){
304 return $this->where(['status' => LATEPOINT_SERVICE_STATUS_ACTIVE]);
305 }
306
307 public function should_not_be_hidden(){
308 return $this->where(['visibility !=' => LATEPOINT_SERVICE_VISIBILITY_HIDDEN]);
309 }
310
311 public function is_active(){
312 return ($this->status == LATEPOINT_SERVICE_STATUS_ACTIVE);
313 }
314
315
316 protected function get_price_min_formatted(){
317 if($this->price_min > 0){
318 return OsMoneyHelper::format_price($this->price_min);
319 }else{
320 return OsMoneyHelper::format_price(0);
321 }
322 }
323
324
325 public function get_selection_image_url(){
326 $default_service_image_url = LATEPOINT_IMAGES_URL . 'service-image.png';
327 return OsImageHelper::get_image_url_by_id($this->selection_image_id, 'thumbnail', $default_service_image_url);
328 }
329
330 public function get_description_image_url(){
331 $default_service_image_url = LATEPOINT_IMAGES_URL . 'service-image.png';
332 return OsImageHelper::get_image_url_by_id($this->description_image_id, 'full', $default_service_image_url);
333 }
334
335
336 public function connect_to_agent($agent_id, $location_id){
337 $agent_connection_row = $this->db->get_row($this->db->prepare('SELECT id FROM '.$this->services_agents_table_name.' WHERE service_id = %d AND agent_id = %d AND location_id = %d', array($this->id, $agent_id, $location_id)));
338 if($agent_connection_row){
339 // update
340 }else{
341 $insert_data = array('agent_id' => $agent_id, 'service_id' => $this->id, 'location_id' => $location_id);
342 if($this->db->insert($this->services_agents_table_name, $insert_data)){
343 return $this->db->insert_id;
344 }
345 }
346 }
347
348 public function save_durations($durations){
349 foreach($durations as &$duration){
350 $duration['charge_amount'] = OsParamsHelper::sanitize_param($duration['charge_amount'], 'money');
351 $duration['deposit_amount'] = OsParamsHelper::sanitize_param($duration['deposit_amount'], 'money');
352 }
353 unset($duration);
354 $this->save_meta_by_key('durations', wp_json_encode($durations));
355 return true;
356 }
357
358
359
360 public function delete_meta_by_key($meta_key){
361 if($this->is_new_record()) return false;
362
363 $meta = new OsServiceMetaModel();
364 return $meta->delete_by_key($meta_key, $this->id);
365 }
366
367 public function get_meta_by_key($meta_key, $default = false){
368 if($this->is_new_record()) return $default;
369
370 $meta = new OsServiceMetaModel();
371 return $meta->get_by_key($meta_key, $this->id, $default);
372 }
373
374 public function save_meta_by_key($meta_key, $meta_value){
375 if($this->is_new_record()) return false;
376
377 $meta = new OsServiceMetaModel();
378 return $meta->save_by_key($meta_key, $meta_value, $this->id);
379 }
380
381 public function save_agents(){
382 foreach($this->agents as $agent){
383 $agent_connection_row = $this->db->get_row($this->db->prepare('SELECT id FROM '.$this->services_agents_table_name.' WHERE service_id = %d AND agent_id = %d', array($this->id, $agent->id)));
384 if($agent_connection_row){
385 $update_data = array('is_custom_hours' => $agent->is_custom_hours, 'is_custom_price' => $agent->is_custom_price, 'is_custom_duration' => $agent->is_custom_duration);
386 $this->db->update($this->services_agents_table_name, $update_data, array('id' => $agent_connection_row->id));
387 }else{
388 $insert_data = array('agent_id' => $agent->id, 'service_id' => $this->id, 'is_custom_hours' => $agent->is_custom_hours, 'is_custom_price' => $agent->is_custom_price, 'is_custom_duration' => $agent->is_custom_duration);
389 if($this->db->insert($this->services_agents_table_name, $insert_data)){
390 $agent_connection_row_id = $this->db->insert_id;
391 }
392 }
393 }
394 return true;
395 }
396
397
398
399 public function remove_agents_by_ids($ids_to_remove = array()){
400 if($ids_to_remove){
401 $query = $this->db->prepare('DELETE FROM %i WHERE service_id = %d AND agent_id IN ' . OsModel::where_in_array_to_string($ids_to_remove), [$this->services_agents_table_name, $this->id]);
402 $this->db->query( $query );
403 }
404 }
405
406
407
408 public function get_agent_ids_to_remove($new_agents = array()){
409 $current_agent_ids = $this->get_current_agent_ids_from_db();
410 $new_agent_ids = array();
411 foreach($new_agents as $agent){
412 if($agent['connected'] == "yes") $new_agent_ids[] = $agent['id'];
413 }
414 $agent_ids_to_remove = array_diff($current_agent_ids, $new_agent_ids);
415 return $agent_ids_to_remove;
416 }
417
418
419 public function save_agents_and_locations($agents){
420 if(!$agents) return true;
421 $connections_to_save = [];
422 $connections_to_remove = [];
423 foreach($agents as $agent_key => $locations){
424 $agent_id = str_replace('agent_', '', $agent_key);
425 foreach($locations as $location_key => $location){
426 $location_id = str_replace('location_', '', $location_key);
427 $connection = ['service_id' => $this->id, 'agent_id' => $agent_id, 'location_id' => $location_id];
428 if($location['connected'] == 'yes'){
429 $connections_to_save[] = $connection;
430 }else{
431 $connections_to_remove[] = $connection;
432 }
433 }
434 }
435 if(!empty($connections_to_save)){
436 foreach($connections_to_save as $connection_to_save){
437 OsConnectorHelper::save_connection($connection_to_save);
438 }
439 }
440 if(!empty($connections_to_remove)){
441 foreach($connections_to_remove as $connection_to_remove){
442 OsConnectorHelper::remove_connection($connection_to_remove);
443 }
444 }
445 return true;
446 }
447
448 public function get_current_agent_ids_from_db(){
449 $query = $this->db->prepare('SELECT agent_id FROM '.$this->services_agents_table_name.' WHERE service_id = %d', $this->id);
450 $agent_rows = $this->db->get_results( $query );
451
452 $agent_ids = array();
453
454 if($agent_rows){
455 foreach($agent_rows as $agent_row){
456 $agent_ids[] = $agent_row->agent_id;
457 }
458 }
459 return $agent_ids;
460 }
461
462
463 public function get_current_agent_ids(){
464 $agent_ids = array();
465 foreach($this->agents as $agent){
466 $agent_ids[] = $agent->id;
467 }
468 return $agent_ids;
469 }
470
471
472 public function get_agents(){
473 if(!isset($this->agents)){
474 $query = 'SELECT * FROM '.$this->services_agents_table_name.' WHERE service_id = %d GROUP BY agent_id';
475 $query_args = array($this->id);
476 $agents_rows = $this->get_query_results( $query, $query_args );
477
478 $this->agents = array();
479
480 if($agents_rows){
481 foreach($agents_rows as $agent_row){
482 $agent = new OsAgentModel($agent_row->agent_id);
483 $agent->is_custom_hours = $agent_row->is_custom_hours;
484 $agent->is_custom_price = $agent_row->is_custom_price;
485 $agent->is_custom_duration = $agent_row->is_custom_duration;
486 $this->agents[] = $agent;
487 }
488 }
489 }
490 return $this->agents;
491 }
492
493 public function set_agents($agent_datas){
494 $this->agents = array();
495
496 foreach($agent_datas as $agent_data){
497 if($agent_data['connected'] == "yes"){
498 $agent = new OsAgentModel();
499 $agent->id = $agent_data['id'];
500 $agent->is_custom_hours = $agent_data['is_custom_hours'];
501 $agent->is_custom_price = $agent_data['is_custom_price'];
502 $agent->is_custom_duration = $agent_data['is_custom_duration'];
503 $this->agents[] = $agent;
504 }
505 }
506 return $this;
507 }
508
509
510 public function has_agent($agent_id){
511 return OsConnectorHelper::has_connection(['service_id' => $this->id, 'agent_id' => $agent_id]);
512 }
513
514 public function has_agent_and_location($agent_id, $location_id){
515 if($this->is_new_record()) return false;
516 return OsConnectorHelper::has_connection(['service_id' => $this->id, 'agent_id' => $agent_id, 'location_id' => $location_id]);
517 }
518
519 public function count_number_of_connected_locations($agent_id = false){
520 if($this->is_new_record()) return 0;
521 $args = ['service_id' => $this->id];
522 if($agent_id) $args['agent_id'] = $agent_id;
523 return OsConnectorHelper::count_connections($args, 'location_id');
524 }
525
526
527 protected function properties_to_validate(){
528 $validations = array(
529 'name' => array('presence'),
530 'duration' => array('presence'),
531 );
532 return $validations;
533 }
534 }