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