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
order_intent_model.php
538 lines
| 1 | <?php |
| 2 | /* |
| 3 | * Copyright (c) 2024 LatePoint LLC. All rights reserved. |
| 4 | */ |
| 5 | |
| 6 | class OsOrderIntentModel extends OsModel { |
| 7 | var $id, |
| 8 | $intent_key, |
| 9 | $customer_id, |
| 10 | $booking_form_page_url, |
| 11 | $cart_items_data, |
| 12 | $restrictions_data, |
| 13 | $presets_data, |
| 14 | $payment_data = '', |
| 15 | $payment_data_arr, |
| 16 | $other_data, |
| 17 | $charge_amount, |
| 18 | $specs_charge_amount, |
| 19 | $coupon_code, |
| 20 | $coupon_discount, |
| 21 | $total, |
| 22 | $subtotal, |
| 23 | $price_breakdown, |
| 24 | $order_id, |
| 25 | $tax_total, |
| 26 | $status, |
| 27 | $updated_at, |
| 28 | $created_at; |
| 29 | |
| 30 | function __construct( $id = false ) { |
| 31 | parent::__construct(); |
| 32 | $this->table_name = LATEPOINT_TABLE_ORDER_INTENTS; |
| 33 | |
| 34 | if ( $id ) { |
| 35 | $this->load_by_id( $id ); |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | |
| 40 | protected function params_to_sanitize() { |
| 41 | return [ |
| 42 | 'charge_amount' => 'money', |
| 43 | 'total' => 'money', |
| 44 | 'subtotal' => 'money', |
| 45 | 'tax_total' => 'money', |
| 46 | ]; |
| 47 | } |
| 48 | |
| 49 | |
| 50 | public function delete_meta_by_key( $meta_key ) { |
| 51 | if ( $this->is_new_record() ) { |
| 52 | return false; |
| 53 | } |
| 54 | |
| 55 | $meta = new OsOrderIntentMetaModel(); |
| 56 | |
| 57 | return $meta->delete_by_key( $meta_key, $this->id ); |
| 58 | } |
| 59 | |
| 60 | public function get_meta_by_key( $meta_key, $default = false ) { |
| 61 | if ( $this->is_new_record() ) { |
| 62 | return $default; |
| 63 | } |
| 64 | |
| 65 | $meta = new OsOrderIntentMetaModel(); |
| 66 | |
| 67 | return $meta->get_by_key( $meta_key, $this->id, $default ); |
| 68 | } |
| 69 | |
| 70 | public function save_meta_by_key( $meta_key, $meta_value ) { |
| 71 | if ( $this->is_new_record() ) { |
| 72 | return false; |
| 73 | } |
| 74 | |
| 75 | $meta = new OsOrderIntentMetaModel(); |
| 76 | |
| 77 | return $meta->save_by_key( $meta_key, $meta_value, $this->id ); |
| 78 | } |
| 79 | |
| 80 | public function get_customer() { |
| 81 | if ( $this->customer_id ) { |
| 82 | if ( ! isset( $this->customer ) || ( isset( $this->customer ) && ( $this->customer->id != $this->customer_id ) ) ) { |
| 83 | $this->customer = new OsCustomerModel( $this->customer_id ); |
| 84 | } |
| 85 | } else { |
| 86 | $this->customer = new OsCustomerModel(); |
| 87 | } |
| 88 | |
| 89 | return $this->customer; |
| 90 | } |
| 91 | |
| 92 | public function build_cart_object(): OsCartModel { |
| 93 | $cart = new OsCartModel(); |
| 94 | $cart->total = $this->total; |
| 95 | $cart->subtotal = $this->subtotal; |
| 96 | $cart->coupon_code = $this->coupon_code; |
| 97 | $cart->coupon_discount = $this->coupon_discount; |
| 98 | $cart->tax_total = $this->tax_total; |
| 99 | |
| 100 | // add items from intent |
| 101 | $intent_cart_items = json_decode( $this->cart_items_data, true ); |
| 102 | foreach ( $intent_cart_items as $cart_item_data ) { |
| 103 | $cart->add_item( OsCartsHelper::create_cart_item_from_item_data( $cart_item_data ), false ); |
| 104 | } |
| 105 | |
| 106 | // restore payment info |
| 107 | $payment_data = json_decode( $this->payment_data, true ); |
| 108 | $cart->payment_method = $payment_data['method']; |
| 109 | $cart->payment_time = $payment_data['time']; |
| 110 | $cart->payment_portion = $payment_data['portion']; |
| 111 | $cart->payment_token = $payment_data['token']; |
| 112 | $cart->payment_processor = $payment_data['processor']; |
| 113 | |
| 114 | return $cart; |
| 115 | } |
| 116 | |
| 117 | public function get_payment_data_value( string $key ): string { |
| 118 | if ( ! isset( $this->payment_data_arr ) ) { |
| 119 | $this->payment_data_arr = json_decode( $this->payment_data, true ); |
| 120 | } |
| 121 | |
| 122 | return $this->payment_data_arr[ $key ] ?? ''; |
| 123 | } |
| 124 | |
| 125 | public function set_payment_data_value( string $key, string $value, bool $save = true ) { |
| 126 | $this->payment_data_arr = json_decode( $this->payment_data, true ); |
| 127 | $this->payment_data_arr[ $key ] = $value; |
| 128 | $this->payment_data = wp_json_encode( $this->payment_data_arr ); |
| 129 | if ( $save ) { |
| 130 | $this->update_attributes( [ 'payment_data' => $this->payment_data ] ); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | public function is_bookable(): bool { |
| 135 | $cart = $this->build_cart_object(); |
| 136 | // loop items and check if bookings are still available |
| 137 | foreach ( $cart->get_items() as $cart_item ) { |
| 138 | switch ( $cart_item->variant ) { |
| 139 | case LATEPOINT_ITEM_VARIANT_BOOKING: |
| 140 | $booking = $cart_item->build_original_object_from_item_data(); |
| 141 | if ( ! $booking->is_bookable( false ) ) { |
| 142 | $this->add_error( 'send_to_step', $booking->get_error_messages(), 'booking__datepicker' ); |
| 143 | |
| 144 | return false; |
| 145 | } |
| 146 | break; |
| 147 | case LATEPOINT_ITEM_VARIANT_BUNDLE: |
| 148 | break; |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | return true; |
| 153 | } |
| 154 | |
| 155 | public function is_processing(): bool { |
| 156 | return $this->status == LATEPOINT_ORDER_INTENT_STATUS_PROCESSING; |
| 157 | } |
| 158 | |
| 159 | public function convert_to_order() { |
| 160 | if($this->is_converted()){ |
| 161 | return $this->order_id; |
| 162 | } |
| 163 | |
| 164 | if($this->is_processing()){ |
| 165 | $this->add_error( 'order_error', 'Can not convert to order, because order intent conversion is being processed' ); |
| 166 | return false; |
| 167 | } |
| 168 | |
| 169 | $this->mark_as_processing(); |
| 170 | |
| 171 | try { |
| 172 | |
| 173 | // process is cart -> order intent -> order |
| 174 | if ( ! $this->is_bookable() ) { |
| 175 | $this->mark_as_new(); |
| 176 | return false; |
| 177 | } |
| 178 | |
| 179 | // process payment if there is amount due |
| 180 | $transaction = OsPaymentsHelper::process_payment_for_order_intent( $this ); |
| 181 | |
| 182 | // payment processing can take a while, make sure to check if the intent wasn't converted already in the meantime |
| 183 | $converted_order_id = OsOrderIntentHelper::is_converted( $this->id ); |
| 184 | if ( $converted_order_id ) { |
| 185 | $order = new OsOrderModel($converted_order_id); |
| 186 | $this->mark_as_converted($order); |
| 187 | return $converted_order_id; |
| 188 | } |
| 189 | |
| 190 | if ( $this->get_error() ) { |
| 191 | OsDebugHelper::log( 'Error converting intent to an order', 'order_error', $this->get_error_messages() ); |
| 192 | |
| 193 | $this->mark_as_new(); |
| 194 | return false; |
| 195 | } |
| 196 | |
| 197 | |
| 198 | $cart_from_intent = $this->build_cart_object(); |
| 199 | |
| 200 | $order = new OsOrderModel(); |
| 201 | $order->customer_id = $this->customer_id; |
| 202 | $order->total = $this->total; |
| 203 | $order->subtotal = $this->subtotal; |
| 204 | $order->coupon_code = $this->coupon_code; |
| 205 | $order->coupon_discount = $this->coupon_discount; |
| 206 | $order->tax_total = $this->tax_total; |
| 207 | $order->source_url = $this->booking_form_page_url; |
| 208 | $order->customer_comment = $this->customer->notes; |
| 209 | $order_initial_payment_data_arr = json_decode( $this->payment_data, true ); |
| 210 | $order_initial_payment_data_arr['charge_amount'] = $this->charge_amount; |
| 211 | $order->initial_payment_data = wp_json_encode($order_initial_payment_data_arr); |
| 212 | // order's price breakdown should only hold cart items, and never holds total, subtotal, balance variables because those are stored on order model itself and/or generated on the fly |
| 213 | $order->price_breakdown = wp_json_encode( $cart_from_intent->generate_price_breakdown_rows(['balance', 'total', 'subtotal'])); |
| 214 | |
| 215 | /** |
| 216 | * Filters order right before it's about to be saved when converting from an order intent |
| 217 | * |
| 218 | * @param {OsOrderModel} $order Order to be filtered |
| 219 | * @returns {OsOrderModel} The filtered order |
| 220 | * |
| 221 | * @since 5.0.0 |
| 222 | * @hook latepoint_before_order_save_from_order_intent |
| 223 | * |
| 224 | */ |
| 225 | $order = apply_filters( 'latepoint_before_order_save_from_order_intent', $order ); |
| 226 | |
| 227 | |
| 228 | if ( $order->save() ) { |
| 229 | $this->mark_as_converted( $order ); |
| 230 | OsInvoicesHelper::create_invoices_for_new_order($order); |
| 231 | |
| 232 | |
| 233 | foreach ( $cart_from_intent->get_items() as $cart_item ) { |
| 234 | $order_item = OsOrdersHelper::create_order_item_from_cart_item( $cart_item ); |
| 235 | $order_item->order_id = $order->id; |
| 236 | $order_item->save(); |
| 237 | } |
| 238 | |
| 239 | if ( $transaction ) { |
| 240 | $transaction->order_id = $order->id; |
| 241 | $invoice = OsInvoicesHelper::get_matching_invoice_for_transaction($transaction); |
| 242 | if(!$invoice->is_new_record()) $transaction->invoice_id = $invoice->id; |
| 243 | if ( $transaction->save() ) { |
| 244 | |
| 245 | /** |
| 246 | * Transaction was created |
| 247 | * |
| 248 | * @param {OsTransactionModel} $transaction instance of transaction model that was created |
| 249 | * |
| 250 | * @since 5.1.0 |
| 251 | * @hook latepoint_transaction_created |
| 252 | * |
| 253 | */ |
| 254 | do_action( 'latepoint_transaction_created', $transaction ); |
| 255 | if(!$invoice->is_new_record()){ |
| 256 | $old_invoice = clone $invoice; |
| 257 | $invoice->update_attributes(['status' => LATEPOINT_INVOICE_STATUS_PAID]); |
| 258 | /** |
| 259 | * Invoice was updated |
| 260 | * |
| 261 | * @param {OsInvoiceModel} $invoice instance of invoice model after it was updated |
| 262 | * @param {OsInvoiceModel} $old_invoice instance of invoice model before it was updated |
| 263 | * |
| 264 | * @since 5.1.0 |
| 265 | * @hook latepoint_invoice_updated |
| 266 | * |
| 267 | */ |
| 268 | do_action( 'latepoint_invoice_updated', $invoice, $old_invoice ); |
| 269 | // update other invoices with this paid amount, for example if we charge a deposit - then this transaction should also be reflected in draft invoices for the remaining amount that were created earlier |
| 270 | $other_invoices = new OsInvoiceModel(); |
| 271 | $other_invoices = $other_invoices->where(['status' => LATEPOINT_INVOICE_STATUS_DRAFT, 'order_id' => $order->id])->get_results_as_models(); |
| 272 | if($other_invoices){ |
| 273 | foreach($other_invoices as $invoice){ |
| 274 | $data = json_decode($invoice->data, true); |
| 275 | $data['totals']['payments'] = $order->get_total_amount_paid_from_transactions(true); |
| 276 | $invoice->update_attributes(['data' => json_encode($data)]); |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | } |
| 281 | |
| 282 | } else { |
| 283 | OsDebugHelper::log( 'Error creating transaction', 'transaction_error', $transaction->get_error_messages() ); |
| 284 | } |
| 285 | } |
| 286 | $order_bookings = $order->get_bookings_from_order_items(true); |
| 287 | if ( $order_bookings ) { |
| 288 | foreach ( $order_bookings as $order_item_id => $order_booking ) { |
| 289 | $order_booking->order_item_id = $order_item_id; |
| 290 | $order_booking->customer_id = $order->customer_id; |
| 291 | $order_booking->end_time = $order_booking->calculate_end_time(); |
| 292 | $order_booking->end_date = $order_booking->calculate_end_date(); |
| 293 | $order_booking->set_utc_datetimes(); |
| 294 | $service = new OsServiceModel( $order_booking->service_id ); |
| 295 | $order_booking->buffer_before = $service->buffer_before; |
| 296 | $order_booking->buffer_after = $service->buffer_after; |
| 297 | $order_booking->customer_comment = $order->customer->notes; |
| 298 | if ( $order_booking->save() ) { |
| 299 | |
| 300 | /** |
| 301 | * Booking was created |
| 302 | * |
| 303 | * @param {OsBookingModel} $booking instance of booking model that was created |
| 304 | * |
| 305 | * @since 5.0.0 |
| 306 | * @hook latepoint_booking_created |
| 307 | * |
| 308 | */ |
| 309 | do_action( 'latepoint_booking_created', $order_booking ); |
| 310 | // set booking id to the one that was created for item data property |
| 311 | $order_item = new OsOrderItemModel( $order_item_id ); |
| 312 | $item_data = json_decode( $order_item->item_data, true ); |
| 313 | $item_data['id'] = $order_booking->id; |
| 314 | $order_item->update_attributes( [ 'item_data' => wp_json_encode( $item_data ) ] ); |
| 315 | } else { |
| 316 | OsDebugHelper::log( 'Unable to save booking', 'booking_save_error', $order_booking->get_error_messages() ); |
| 317 | } |
| 318 | } |
| 319 | } |
| 320 | // update connected cart with created order id |
| 321 | $carts = new OsCartModel(); |
| 322 | $carts = $carts->where( [ 'order_intent_id' => $this->id ] )->get_results_as_models(); |
| 323 | if ( ! empty( $carts ) ) { |
| 324 | foreach ( $carts as $cart ) { |
| 325 | $cart->order_id = $order->id; |
| 326 | $cart->save(); |
| 327 | } |
| 328 | } |
| 329 | $order->determine_payment_status(); |
| 330 | // update with latest info |
| 331 | $order->get_items(true); |
| 332 | |
| 333 | /** |
| 334 | * Order was created |
| 335 | * |
| 336 | * @param {OsOrderModel} $order instance of order model that was created |
| 337 | * |
| 338 | * @since 5.0.0 |
| 339 | * @hook latepoint_order_created |
| 340 | * |
| 341 | */ |
| 342 | do_action( 'latepoint_order_created', $order ); |
| 343 | |
| 344 | return $order->id; |
| 345 | } else { |
| 346 | $this->add_error( 'order_error', $order->get_error_messages() ); |
| 347 | |
| 348 | $this->mark_as_new(); |
| 349 | return false; |
| 350 | } |
| 351 | } catch ( Exception $e ) { |
| 352 | $this->mark_as_new(); |
| 353 | // translators: %s is the error description |
| 354 | $this->add_error( 'order_error', sprintf(__('Error: %s', 'latepoint'), $e->getMessage() )); |
| 355 | OsDebugHelper::log( 'Error converting intent to an order', 'order_error', $e->getMessage() ); |
| 356 | return false; |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | public function get_by_intent_key( $intent_key ) { |
| 361 | return $this->where( [ 'intent_key' => $intent_key ] )->set_limit( 1 )->get_results_as_models(); |
| 362 | } |
| 363 | |
| 364 | public function mark_as_converted( OsOrderModel $order ) { |
| 365 | if ( empty( $order->id ) ) { |
| 366 | return false; |
| 367 | } |
| 368 | |
| 369 | $this->update_attributes( [ 'order_id' => $order->id, 'status' => LATEPOINT_ORDER_INTENT_STATUS_CONVERTED ] ); |
| 370 | /** |
| 371 | * Order intent is converted to order |
| 372 | * |
| 373 | * @param {OsOrderIntentModel} $order_intent Instance of order intent model that has been converted to order |
| 374 | * @param {OsOrderModel} $order Instance of order model that order intent was converted to |
| 375 | * |
| 376 | * @since 5.0.0 |
| 377 | * @hook latepoint_order_intent_converted |
| 378 | * |
| 379 | */ |
| 380 | do_action( 'latepoint_order_intent_converted', $this, $order ); |
| 381 | } |
| 382 | |
| 383 | public function mark_as_processing() { |
| 384 | $this->update_attributes( [ 'status' => LATEPOINT_ORDER_INTENT_STATUS_PROCESSING ] ); |
| 385 | /** |
| 386 | * Order intent is marked as processing |
| 387 | * |
| 388 | * @param {OsOrderIntentModel} $order_intent Instance of order intent model that has started processing |
| 389 | * |
| 390 | * @since 5.0.0 |
| 391 | * @hook latepoint_order_intent_processing |
| 392 | * |
| 393 | */ |
| 394 | do_action( 'latepoint_order_intent_processing', $this ); |
| 395 | } |
| 396 | |
| 397 | public function mark_as_new() { |
| 398 | $this->update_attributes( [ 'status' => LATEPOINT_ORDER_INTENT_STATUS_NEW ] ); |
| 399 | /** |
| 400 | * Order intent is marked as new |
| 401 | * |
| 402 | * @param {OsOrderIntentModel} $order_intent Instance of order intent model that is being marked as new |
| 403 | * |
| 404 | * @since 5.0.0 |
| 405 | * @hook latepoint_order_intent_new |
| 406 | * |
| 407 | */ |
| 408 | do_action( 'latepoint_order_intent_new', $this ); |
| 409 | } |
| 410 | |
| 411 | // Determines if order intent has been converted into a order already |
| 412 | public function is_converted() : bool { |
| 413 | if ( empty( $this->order_id ) ) { |
| 414 | return false; |
| 415 | } else { |
| 416 | return true; |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | public function generate_data_vars(): array { |
| 421 | $vars = [ |
| 422 | 'id' => $this->id, |
| 423 | 'intent_key' => $this->intent_key, |
| 424 | 'customer_id' => $this->customer_id, |
| 425 | 'booking_form_page_url' => $this->booking_form_page_url, |
| 426 | 'cart_items_data' => !empty($this->cart_items_data) ? json_decode( $this->cart_items_data, true ) : [], |
| 427 | 'restrictions_data' => !empty($this->restrictions_data) ? json_decode( $this->restrictions_data, true ) : [], |
| 428 | 'presets_data' => !empty($this->presets_data) ? json_decode( $this->presets_data, true ) : [], |
| 429 | 'payment_data' => !empty($this->payment_data) ? json_decode( $this->payment_data, true ) : [], |
| 430 | 'other_data' => !empty($this->other_data) ? json_decode( $this->other_data, true ) : [], |
| 431 | 'order_id' => $this->order_id, |
| 432 | 'coupon_code' => $this->coupon_code, |
| 433 | 'coupon_discount' => $this->coupon_discount, |
| 434 | 'tax_total' => $this->tax_total, |
| 435 | 'updated_at' => $this->updated_at, |
| 436 | 'created_at' => $this->created_at, |
| 437 | ]; |
| 438 | |
| 439 | return $vars; |
| 440 | } |
| 441 | |
| 442 | public function get_page_url_with_intent() { |
| 443 | $booking_page_url = $this->booking_form_page_url; |
| 444 | $existing_var_position = strpos( $booking_page_url, 'latepoint_order_intent_key=' ); |
| 445 | if ( $existing_var_position === false ) { |
| 446 | // no intent variable in url |
| 447 | $question_position = strpos( $booking_page_url, '?' ); |
| 448 | if ( $question_position === false ) { |
| 449 | // no ?query params |
| 450 | $hash_position = strpos( $booking_page_url, '#' ); |
| 451 | if ( $hash_position === false ) { |
| 452 | // no hashtag in url |
| 453 | $booking_page_url = $booking_page_url . '?latepoint_order_intent_key=' . $this->intent_key; |
| 454 | } else { |
| 455 | // hashtag in url and no ?query, prepend the hashtag with query |
| 456 | $booking_page_url = substr_replace( $booking_page_url, '?latepoint_order_intent_key=' . $this->intent_key . '#', $hash_position, 1 ); |
| 457 | } |
| 458 | } else { |
| 459 | // ?query string exists, add intent key to it |
| 460 | $booking_page_url = substr_replace( $booking_page_url, '?latepoint_order_intent_key=' . $this->intent_key . '&', $question_position, 1 ); |
| 461 | } |
| 462 | } else { |
| 463 | // intent key variable exist in url |
| 464 | preg_match( '/latepoint_order_intent_key=([\d,\w]*)/', $booking_page_url, $matches ); |
| 465 | if ( isset( $matches[1] ) ) { |
| 466 | $booking_page_url = str_replace( 'latepoint_order_intent_key=' . $matches[1], 'latepoint_order_intent_key=' . $this->intent_key, $booking_page_url ); |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | return $booking_page_url; |
| 471 | } |
| 472 | |
| 473 | |
| 474 | protected function before_create() { |
| 475 | if ( empty( $this->intent_key ) ) { |
| 476 | $this->intent_key = bin2hex( openssl_random_pseudo_bytes( 10 ) ); |
| 477 | } |
| 478 | if ( empty( $this->status ) ) { |
| 479 | $this->status = LATEPOINT_ORDER_INTENT_STATUS_NEW; |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | protected function allowed_params( $role = 'admin' ) { |
| 484 | $allowed_params = array( |
| 485 | 'customer_id', |
| 486 | 'cart_items_data', |
| 487 | 'restrictions_data', |
| 488 | 'presets_data', |
| 489 | 'payment_data', |
| 490 | 'other_data', |
| 491 | 'booking_form_page_url', |
| 492 | 'intent_key', |
| 493 | 'order_id', |
| 494 | 'coupon_code', |
| 495 | 'coupon_discount', |
| 496 | 'tax_total', |
| 497 | 'status', |
| 498 | ); |
| 499 | |
| 500 | return $allowed_params; |
| 501 | } |
| 502 | |
| 503 | |
| 504 | protected function params_to_save( $role = 'admin' ) { |
| 505 | $params_to_save = array( |
| 506 | 'customer_id', |
| 507 | 'cart_items_data', |
| 508 | 'restrictions_data', |
| 509 | 'presets_data', |
| 510 | 'payment_data', |
| 511 | 'other_data', |
| 512 | 'booking_form_page_url', |
| 513 | 'intent_key', |
| 514 | 'total', |
| 515 | 'subtotal', |
| 516 | 'charge_amount', |
| 517 | 'specs_charge_amount', |
| 518 | 'price_breakdown', |
| 519 | 'order_id', |
| 520 | 'coupon_code', |
| 521 | 'coupon_discount', |
| 522 | 'tax_total', |
| 523 | 'status', |
| 524 | ); |
| 525 | |
| 526 | return $params_to_save; |
| 527 | } |
| 528 | |
| 529 | |
| 530 | protected function properties_to_validate() { |
| 531 | $validations = array( |
| 532 | 'customer_id' => array( 'presence' ), |
| 533 | ); |
| 534 | |
| 535 | return $validations; |
| 536 | } |
| 537 | } |
| 538 |