PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / trunk
LatePoint – Calendar Booking Plugin for Appointments and Events vtrunk
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 / process_model.php
latepoint / lib / models Last commit date
activity_model.php 3 months ago agent_meta_model.php 3 months ago agent_model.php 3 months ago booking_meta_model.php 3 months ago booking_model.php 19 hours ago bundle_meta_model.php 3 months ago bundle_model.php 1 week ago cart_item_model.php 3 months ago cart_meta_model.php 3 months ago cart_model.php 2 weeks ago connector_model.php 3 months ago customer_meta_model.php 3 months ago customer_model.php 1 month ago invoice_model.php 2 weeks ago join_bundles_services_model.php 3 months ago location_category_model.php 3 months ago location_model.php 3 months ago meta_model.php 3 months ago model.php 2 days ago off_period_model.php 3 months ago order_intent_meta_model.php 3 months ago order_intent_model.php 1 week ago order_item_model.php 3 months ago order_meta_model.php 3 months ago order_model.php 1 month ago otp_model.php 3 months ago payment_request_model.php 3 months ago process_job_model.php 3 months ago process_model.php 1 month ago recurrence_model.php 3 months ago service_category_model.php 3 months ago service_meta_model.php 3 months ago service_model.php 3 months ago session_model.php 3 months ago settings_model.php 3 months ago step_settings_model.php 3 months ago transaction_intent_model.php 3 months ago transaction_model.php 3 months ago transaction_refund_model.php 3 months ago work_period_model.php 3 months ago
process_model.php
267 lines
1 <?php
2 /*
3 * Copyright (c) 2022 LatePoint LLC. All rights reserved.
4 */
5
6 class OsProcessModel extends OsModel {
7 var $id,
8 $name,
9 $status = LATEPOINT_STATUS_ACTIVE,
10 $event_type, //'booking_created', 'booking_updated', 'booking_start', 'booking_end', 'customer_created', 'transaction_created'
11 $actions_json,
12 $trigger_conditions,
13 $actions,
14 $time_offset,
15 $updated_at,
16 $created_at;
17
18 function __construct( $id = false ) {
19 parent::__construct();
20 $this->table_name = LATEPOINT_TABLE_PROCESSES;
21
22 if ( $id ) {
23 $this->load_by_id( $id );
24 }
25 }
26
27 public function should_be_active() {
28 return $this->where( [ 'status' => LATEPOINT_STATUS_ACTIVE ] );
29 }
30
31 /**
32 * @param array $objects example format: ['model' => 'booking', 'id' => $booking->id, 'model_ready' => OsModel $booking]
33 * @return bool
34 */
35 public function check_if_objects_satisfy_trigger_conditions( array $objects ): bool {
36 if ( $this->event->trigger_conditions ) {
37 foreach ( $this->event->trigger_conditions as $condition ) {
38 foreach ( $objects as $object ) {
39 if ( $object['model'] == \LatePoint\Misc\ProcessEvent::get_object_from_property( $condition['property'] ) ) {
40 $attribute = \LatePoint\Misc\ProcessEvent::get_object_attribute_from_property( $condition['property'] );
41 $object_value = self::resolve_attribute_value( $object, $attribute );
42 switch ( $condition['operator'] ) {
43 case 'equal':
44 $value_arr = explode( ',', $condition['value'] );
45 if ( ! in_array( $object_value, $value_arr ) ) {
46 return false;
47 }
48 break;
49 case 'not_equal':
50 $value_arr = explode( ',', $condition['value'] );
51 if ( in_array( $object_value, $value_arr ) ) {
52 return false;
53 }
54 break;
55 case 'greater_than':
56 if ( ! ( (float) $object_value > (float) $condition['value'] ) ) {
57 return false;
58 }
59 break;
60 case 'less_than':
61 if ( ! ( (float) $object_value < (float) $condition['value'] ) ) {
62 return false;
63 }
64 break;
65 case 'greater_or_equal':
66 if ( ! ( (float) $object_value >= (float) $condition['value'] ) ) {
67 return false;
68 }
69 break;
70 case 'less_or_equal':
71 if ( ! ( (float) $object_value <= (float) $condition['value'] ) ) {
72 return false;
73 }
74 break;
75 // below cases are similar:
76 // this operator is only available for models prefixed with "old_", we need to iterate through other
77 // objects and find the matching one by stripping "old_" from the one that we are comparing change to
78 case 'not_changed':
79 foreach ( $objects as $object_to_compare ) {
80 if ( $object_to_compare['model'] == str_replace( 'old_', '', $object['model'] ) ) {
81 if ( $object_value != $object_to_compare['model_ready']->$attribute ) {
82 return false;
83 }
84 }
85 }
86 case 'changed':
87 foreach ( $objects as $object_to_compare ) {
88 if ( $object_to_compare['model'] == str_replace( 'old_', '', $object['model'] ) ) {
89 if ( $object_value == $object_to_compare['model_ready']->$attribute ) {
90 return false;
91 }
92 }
93 }
94 break;
95 }
96 }
97 }
98 }
99 }
100 return true;
101 }
102
103 /**
104 * Returns the value of the attribute on the model. Most attributes are
105 * read directly from the model instance, but a small number are computed
106 * (e.g. order_item_counts, which depends on related records and is not
107 * stored on the booking or order row itself).
108 */
109 private static function resolve_attribute_value( array $object, string $attribute ) {
110 if ( $attribute === 'order_item_counts' ) {
111 if ( $object['model'] === 'booking' ) {
112 return self::compute_order_item_counts_for_booking( $object['model_ready'] );
113 }
114 if ( $object['model'] === 'order' ) {
115 return self::compute_order_item_counts_for_order( $object['model_ready'] );
116 }
117 }
118 return $object['model_ready']->$attribute;
119 }
120
121 /**
122 * Counts how many bookings belong to the same transaction as the given
123 * booking. Falls back to 1 (= "single booking") for any degenerate input
124 * so the evaluator never crashes on missing related records.
125 *
126 * Order of preference:
127 * - recurrence_id sibling count (catches recurring sets and bundle
128 * scheduling)
129 * - order item count via order_item_id -> order (catches cart checkouts
130 * with multiple distinct services)
131 * - 1 (no transaction context)
132 */
133 private static function compute_order_item_counts_for_booking( \OsBookingModel $booking ): int {
134 if ( ! empty( $booking->order_item_id ) ) {
135 $order_item = new \OsOrderItemModel( $booking->order_item_id );
136
137 if ( ! empty( $order_item->order_id ) ) {
138 $order = new \OsOrderModel( $order_item->order_id );
139 $items = $order->get_items();
140 if ( ! empty( $items ) ) {
141 return count( $items );
142 }
143 }
144 }
145
146 return 0;
147 }
148
149 /**
150 * Counts how many items the given order has. Falls back to 1 for any
151 * degenerate input so the evaluator never crashes on missing related
152 * records. Used by the "Order Item Counts" condition on Order Created.
153 */
154 private static function compute_order_item_counts_for_order( \OsOrderModel $order ): int {
155 if ( empty( $order->id ) ) {
156 return 0;
157 }
158 $items = $order->get_items();
159 if ( empty( $items ) ) {
160 return 0;
161 }
162 return count( $items );
163 }
164
165 public function get_info() {
166 return [
167 'name' => $this->name,
168 'event_type' => $this->event_type,
169 ];
170 }
171
172 public function delete( $id = false ) {
173 if ( ! $id && isset( $this->id ) ) {
174 $id = $this->id;
175 }
176 if ( $id && $this->db->delete( $this->table_name, array( 'id' => $id ), array( '%d' ) ) ) {
177 $this->db->delete(
178 LATEPOINT_TABLE_PROCESS_JOBS,
179 array(
180 'process_id' => $id,
181 'status' => LATEPOINT_JOB_STATUS_SCHEDULED,
182 ),
183 array( '%d', '%s' )
184 );
185 do_action( 'latepoint_process_deleted', $id );
186 return true;
187 } else {
188 return false;
189 }
190 }
191
192 public function set_from_params( array $params ) {
193 $this->name = $params['name'];
194 if ( ! empty( $params['event'] ) ) {
195 $this->event_type = $params['event']['type'];
196 $this->event = new \LatePoint\Misc\ProcessEvent();
197 $this->event->set_from_params( $params['event'] );
198
199 }
200
201
202 if ( ! empty( $params['actions'] ) ) {
203 foreach ( $params['actions'] as $action_id => $action_params ) {
204 $action = new \LatePoint\Misc\ProcessAction();
205 $action->id = $action_id;
206 $action->set_from_params( $action_params );
207 $this->actions[] = $action;
208 }
209 }
210 }
211
212 public function build_from_json() {
213 $groups = empty( $this->actions_json ) ? [] : json_decode( $this->actions_json, true );
214 $this->trigger_conditions = OsProcessesHelper::extract_trigger_conditions_from_groups( $groups );
215 $this->actions = OsProcessesHelper::extract_actions_from_groups( $groups );
216 $this->time_offset = $groups[0]['time_offset'] ?? [];
217 }
218
219 protected function get_event(): \LatePoint\Misc\ProcessEvent {
220 $event_data = [];
221 if ( ! empty( $this->event_type ) ) {
222 $event_data['type'] = $this->event_type;
223 }
224 if ( ! empty( $this->trigger_conditions ) ) {
225 $event_data['trigger_conditions'] = $this->trigger_conditions;
226 }
227 if ( ! empty( $this->time_offset ) ) {
228 $event_data['time_offset'] = $this->time_offset;
229 }
230
231 $this->event = new \LatePoint\Misc\ProcessEvent( $event_data );
232 return $this->event;
233 }
234
235 protected function params_to_sanitize() {
236 return [];
237 }
238
239 protected function params_to_save( $role = 'admin' ) {
240 $params_to_save = [
241 'id',
242 'event_type',
243 'status',
244 'name',
245 'actions_json',
246 ];
247 return $params_to_save;
248 }
249
250 protected function allowed_params( $role = 'admin' ) {
251 $allowed_params = [
252 'id',
253 'event_type',
254 'status',
255 'name',
256 'actions_json',
257 ];
258 return $allowed_params;
259 }
260
261
262 protected function properties_to_validate() {
263 $validations = [];
264 return $validations;
265 }
266 }
267