1
|
|
|
<?php |
2
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
3
|
|
|
exit; |
4
|
|
|
} |
5
|
|
|
|
6
|
|
|
include_once( 'abstract-wc-legacy-order.php' ); |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Abstract Order |
10
|
|
|
* |
11
|
|
|
* Handles generic order data and database interaction which is extended by both |
12
|
|
|
* WC_Order (regular orders) and WC_Order_Refund (refunds are negative orders). |
13
|
|
|
* |
14
|
|
|
* @class WC_Abstract_Order |
15
|
|
|
* @version 2.7.0 |
16
|
|
|
* @package WooCommerce/Classes |
17
|
|
|
* @category Class |
18
|
|
|
* @author WooThemes |
19
|
|
|
*/ |
20
|
|
|
abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Order Data array, with defaults. This is the core order data exposed |
24
|
|
|
* in APIs since 2.7.0. |
25
|
|
|
* |
26
|
|
|
* Notes: |
27
|
|
|
* order_tax = Sum of all taxes. |
28
|
|
|
* cart_tax = cart_tax is the new name for the legacy 'order_tax' which is the tax for items only, not shipping. |
29
|
|
|
* |
30
|
|
|
* @since 2.7.0 |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
protected $_data = array( |
34
|
|
|
'id' => 0, |
35
|
|
|
'parent_id' => 0, |
36
|
|
|
'status' => '', |
37
|
|
|
'order_key' => '', |
38
|
|
|
'currency' => '', |
39
|
|
|
'version' => '', |
40
|
|
|
'prices_include_tax' => false, |
41
|
|
|
'date_created' => '', |
42
|
|
|
'date_modified' => '', |
43
|
|
|
'customer_id' => 0, |
44
|
|
|
'discount_total' => 0, |
45
|
|
|
'discount_tax' => 0, |
46
|
|
|
'shipping_total' => 0, |
47
|
|
|
'shipping_tax' => 0, |
48
|
|
|
'cart_tax' => 0, |
49
|
|
|
'total' => 0, |
50
|
|
|
'total_tax' => 0, |
51
|
|
|
); |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Data stored in meta keys, but not considered "meta" for an order. |
55
|
|
|
* @since 2.7.0 |
56
|
|
|
* @var array |
57
|
|
|
*/ |
58
|
|
|
protected $_internal_meta_keys = array( |
59
|
|
|
'_customer_user', '_order_key', '_order_currency', '_cart_discount', |
60
|
|
|
'_cart_discount_tax', '_order_shipping', '_order_shipping_tax', |
61
|
|
|
'_order_tax', '_order_total', '_order_version', '_prices_include_tax', |
62
|
|
|
'_payment_tokens', |
63
|
|
|
); |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Order items will be stored here, sometimes before they persist in the DB. |
67
|
|
|
* @since 2.7.0 |
68
|
|
|
* @var array |
69
|
|
|
*/ |
70
|
|
|
protected $_items = array( |
71
|
|
|
'line_items' => null, |
72
|
|
|
'coupon_lines' => null, |
73
|
|
|
'shipping_lines' => null, |
74
|
|
|
'fee_lines' => null, |
75
|
|
|
'tax_lines' => null, |
76
|
|
|
); |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Order items that need deleting are stored here. |
80
|
|
|
* @since 2.7.0 |
81
|
|
|
* @var array |
82
|
|
|
*/ |
83
|
|
|
protected $_items_to_delete = array(); |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Internal meta type used to store order data. |
87
|
|
|
* @var string |
88
|
|
|
*/ |
89
|
|
|
protected $_meta_type = 'post'; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Stores meta in cache for future reads. |
93
|
|
|
* A group must be set to to enable caching. |
94
|
|
|
* @var string |
95
|
|
|
*/ |
96
|
|
|
protected $_cache_group = 'order'; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Get the order if ID is passed, otherwise the order is new and empty. |
100
|
|
|
* This class should NOT be instantiated, but the get_order function or new WC_Order_Factory. |
101
|
|
|
* should be used. It is possible, but the aforementioned are preferred and are the only. |
102
|
|
|
* methods that will be maintained going forward. |
103
|
|
|
* |
104
|
|
|
* @param int|object|WC_Order $order Order to init. |
105
|
|
|
*/ |
106
|
|
|
public function __construct( $order = 0 ) { |
107
|
|
|
if ( is_numeric( $order ) && $order > 0 ) { |
108
|
|
|
$this->read( $order ); |
109
|
|
|
} elseif ( $order instanceof self ) { |
110
|
|
|
$this->read( absint( $order->get_id() ) ); |
111
|
|
|
} elseif ( ! empty( $order->ID ) ) { |
112
|
|
|
$this->read( absint( $order->ID ) ); |
113
|
|
|
} |
114
|
|
|
// Set default status if none were read. |
115
|
|
|
if ( ! $this->get_status() ) { |
116
|
|
|
$this->set_status( apply_filters( 'woocommerce_default_order_status', 'pending' ) ); |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/* |
121
|
|
|
|-------------------------------------------------------------------------- |
122
|
|
|
| CRUD methods |
123
|
|
|
|-------------------------------------------------------------------------- |
124
|
|
|
| |
125
|
|
|
| Methods which create, read, update and delete orders from the database. |
126
|
|
|
| Written in abstract fashion so that the way orders are stored can be |
127
|
|
|
| changed more easily in the future. |
128
|
|
|
| |
129
|
|
|
| A save method is included for convenience (chooses update or create based |
130
|
|
|
| on if the order exists yet). |
131
|
|
|
| |
132
|
|
|
*/ |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Get internal type (post type.) |
136
|
|
|
* @return string |
137
|
|
|
*/ |
138
|
|
|
public function get_type() { |
139
|
|
|
return 'shop_order'; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Get a title for the new post type. |
144
|
|
|
*/ |
145
|
|
|
protected function get_post_title() { |
146
|
|
|
return sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Insert data into the database. |
151
|
|
|
* @since 2.7.0 |
152
|
|
|
*/ |
153
|
|
|
public function create() { |
154
|
|
|
$this->set_order_key( 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ) ); |
155
|
|
|
$this->set_date_created( current_time( 'timestamp' ) ); |
156
|
|
|
|
157
|
|
|
$order_id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', array( |
158
|
|
|
'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ), |
159
|
|
|
'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ), |
160
|
|
|
'post_type' => $this->get_type(), |
161
|
|
|
'post_status' => 'wc-' . ( $this->get_status() ? $this->get_status() : apply_filters( 'woocommerce_default_order_status', 'pending' ) ), |
162
|
|
|
'ping_status' => 'closed', |
163
|
|
|
'post_author' => 1, |
164
|
|
|
'post_title' => $this->get_post_title(), |
165
|
|
|
'post_password' => uniqid( 'order_' ), |
166
|
|
|
'post_parent' => $this->get_parent_id(), |
167
|
|
|
) ), true ); |
168
|
|
|
|
169
|
|
|
if ( $order_id ) { |
170
|
|
|
$this->set_id( $order_id ); |
171
|
|
|
|
172
|
|
|
// Set meta data |
173
|
|
|
$this->update_post_meta( '_customer_user', $this->get_customer_id() ); |
174
|
|
|
$this->update_post_meta( '_order_currency', $this->get_currency() ); |
175
|
|
|
$this->update_post_meta( '_order_key', $this->get_order_key() ); |
176
|
|
|
$this->update_post_meta( '_cart_discount', $this->get_discount_total( true ) ); |
177
|
|
|
$this->update_post_meta( '_cart_discount_tax', $this->get_discount_tax( true ) ); |
178
|
|
|
$this->update_post_meta( '_order_shipping', $this->get_shipping_total( true ) ); |
179
|
|
|
$this->update_post_meta( '_order_shipping_tax', $this->get_shipping_tax( true ) ); |
180
|
|
|
$this->update_post_meta( '_order_tax', $this->get_cart_tax( true ) ); |
181
|
|
|
$this->update_post_meta( '_order_total', $this->get_total( true ) ); |
182
|
|
|
$this->update_post_meta( '_order_version', $this->get_version() ); |
183
|
|
|
$this->update_post_meta( '_prices_include_tax', $this->get_prices_include_tax() ); |
184
|
|
|
$this->save_meta_data(); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Read from the database. |
190
|
|
|
* @since 2.7.0 |
191
|
|
|
* @param int $id ID of object to read. |
192
|
|
|
*/ |
193
|
|
|
public function read( $id ) { |
194
|
|
|
if ( empty( $id ) || ! ( $post_object = get_post( $id ) ) ) { |
195
|
|
|
return; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
// Map standard post data |
199
|
|
|
$this->set_id( $post_object->ID ); |
200
|
|
|
$this->set_parent_id( $post_object->post_parent ); |
201
|
|
|
$this->set_date_created( $post_object->post_date ); |
202
|
|
|
$this->set_date_modified( $post_object->post_modified ); |
203
|
|
|
$this->set_status( $post_object->post_status ); |
204
|
|
|
$this->set_customer_id( get_post_meta( $this->get_id(), '_customer_user', true ) ); |
205
|
|
|
$this->set_order_key( get_post_meta( $this->get_id(), '_order_key', true ) ); |
206
|
|
|
$this->set_currency( get_post_meta( $this->get_id(), '_order_currency', true ) ); |
207
|
|
|
$this->set_discount_total( get_post_meta( $this->get_id(), '_cart_discount', true ) ); |
208
|
|
|
$this->set_discount_tax( get_post_meta( $this->get_id(), '_cart_discount_tax', true ) ); |
209
|
|
|
$this->set_shipping_total( get_post_meta( $this->get_id(), '_order_shipping', true ) ); |
210
|
|
|
$this->set_shipping_tax( get_post_meta( $this->get_id(), '_order_shipping_tax', true ) ); |
211
|
|
|
$this->set_cart_tax( get_post_meta( $this->get_id(), '_order_tax', true ) ); |
212
|
|
|
$this->set_total( get_post_meta( $this->get_id(), '_order_total', true ) ); |
213
|
|
|
|
214
|
|
|
// Orders store the state of prices including tax when created. |
215
|
|
|
$this->set_prices_include_tax( metadata_exists( 'post', $this->get_id(), '_prices_include_tax' ) ? 'yes' === get_post_meta( $this->get_id(), '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); |
216
|
|
|
|
217
|
|
|
// Load meta data |
218
|
|
|
$this->read_meta_data(); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* Post meta update wrapper. Sets or deletes based on value. |
223
|
|
|
* @since 2.7.0 |
224
|
|
|
* @return bool Was it changed? |
225
|
|
|
*/ |
226
|
|
|
protected function update_post_meta( $key, $value ) { |
227
|
|
|
if ( '' !== $value ) { |
228
|
|
|
return update_post_meta( $this->get_id(), $key, $value ); |
229
|
|
|
} else { |
230
|
|
|
return delete_post_meta( $this->get_id(), $key ); |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* Update data in the database. |
236
|
|
|
* @since 2.7.0 |
237
|
|
|
*/ |
238
|
|
|
public function update() { |
239
|
|
|
global $wpdb; |
240
|
|
|
|
241
|
|
|
$order_id = $this->get_id(); |
242
|
|
|
|
243
|
|
|
$wpdb->update( |
244
|
|
|
$wpdb->posts, |
245
|
|
|
array( |
246
|
|
|
'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ), |
247
|
|
|
'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ), |
248
|
|
|
'post_status' => 'wc-' . ( $this->get_status() ? $this->get_status() : apply_filters( 'woocommerce_default_order_status', 'pending' ) ), |
249
|
|
|
'post_parent' => $this->get_parent_id(), |
250
|
|
|
), |
251
|
|
|
array( |
252
|
|
|
'ID' => $order_id |
253
|
|
|
) |
254
|
|
|
); |
255
|
|
|
|
256
|
|
|
// Update meta data |
257
|
|
|
$this->update_post_meta( '_customer_user', $this->get_customer_id() ); |
258
|
|
|
$this->update_post_meta( '_order_currency', $this->get_currency() ); |
259
|
|
|
$this->update_post_meta( '_order_key', $this->get_order_key() ); |
260
|
|
|
$this->update_post_meta( '_cart_discount', $this->get_discount_total( true ) ); |
261
|
|
|
$this->update_post_meta( '_cart_discount_tax', $this->get_discount_tax( true ) ); |
262
|
|
|
$this->update_post_meta( '_order_shipping', $this->get_shipping_total( true ) ); |
263
|
|
|
$this->update_post_meta( '_order_shipping_tax', $this->get_shipping_tax( true ) ); |
264
|
|
|
$this->update_post_meta( '_order_tax', $this->get_cart_tax( true ) ); |
265
|
|
|
$this->update_post_meta( '_order_total', $this->get_total( true ) ); |
266
|
|
|
$this->update_post_meta( '_prices_include_tax', $this->get_prices_include_tax() ); |
267
|
|
|
$this->save_meta_data(); |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Delete data from the database. |
272
|
|
|
* @since 2.7.0 |
273
|
|
|
*/ |
274
|
|
|
public function delete() { |
275
|
|
|
wp_delete_post( $this->get_id() ); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Save data to the database. |
280
|
|
|
* @since 2.7.0 |
281
|
|
|
* @return int order ID |
282
|
|
|
*/ |
283
|
|
|
public function save() { |
284
|
|
|
$this->set_version( WC_VERSION ); |
285
|
|
|
|
286
|
|
|
if ( ! $this->get_id() ) { |
287
|
|
|
$this->create(); |
288
|
|
|
} else { |
289
|
|
|
$this->update(); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
$this->save_items(); |
293
|
|
|
clean_post_cache( $this->get_id() ); |
294
|
|
|
wc_delete_shop_order_transients( $this->get_id() ); |
295
|
|
|
|
296
|
|
|
return $this->get_id(); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* Save all order items which are part of this order. |
301
|
|
|
*/ |
302
|
|
|
protected function save_items() { |
303
|
|
|
// remove items |
304
|
|
|
foreach ( $this->_items_to_delete as $item ) { |
305
|
|
|
$item->delete(); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
$this->_items_to_delete = array(); |
309
|
|
|
|
310
|
|
|
// Add/save items |
311
|
|
|
foreach ( $this->_items as $item_group => $items ) { |
312
|
|
|
if ( is_array( $items ) ) { |
313
|
|
|
foreach ( $items as $item_key => $item ) { |
314
|
|
|
$item->set_order_id( $this->get_id() ); |
315
|
|
|
$item_id = $item->save(); |
316
|
|
|
|
317
|
|
|
// If ID changed (new item saved to DB)... |
318
|
|
|
if ( $item_id !== $item_key ) { |
319
|
|
|
$this->_items[ $item_group ][ $item_id ] = $item; |
320
|
|
|
unset( $this->_items[ $item_group ][ $item_key ] ); |
321
|
|
|
|
322
|
|
|
// Legacy action handler |
323
|
|
|
switch ( $item_group ) { |
324
|
|
|
case 'fee_lines' : |
325
|
|
|
if ( isset( $item->legacy_fee, $item->legacy_fee_key ) ) { |
326
|
|
|
wc_do_deprecated_action( 'woocommerce_add_order_fee_meta', array( $this->get_id(), $item_id, $item->legacy_fee, $item->legacy_fee_key ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
327
|
|
|
} |
328
|
|
|
break; |
329
|
|
|
case 'shipping_lines' : |
330
|
|
|
if ( isset( $item->legacy_package_key ) ) { |
331
|
|
|
wc_do_deprecated_action( 'woocommerce_add_shipping_order_item', array( $item_id, $item->legacy_package_key ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
332
|
|
|
} |
333
|
|
|
break; |
334
|
|
|
case 'line_items' : |
335
|
|
|
if ( isset( $item->legacy_values, $item->legacy_cart_item_key ) ) { |
336
|
|
|
wc_do_deprecated_action( 'woocommerce_add_order_item_meta', array( $item_id, $item->legacy_values, $item->legacy_cart_item_key ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
337
|
|
|
} |
338
|
|
|
break; |
339
|
|
|
} |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/* |
347
|
|
|
|-------------------------------------------------------------------------- |
348
|
|
|
| Getters |
349
|
|
|
|-------------------------------------------------------------------------- |
350
|
|
|
| |
351
|
|
|
| Methods for getting data from the order object. |
352
|
|
|
| |
353
|
|
|
*/ |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Get all class data in array format. |
357
|
|
|
* @since 2.7.0 |
358
|
|
|
* @return array |
359
|
|
|
*/ |
360
|
|
|
public function get_data() { |
361
|
|
|
return array_merge( |
362
|
|
|
$this->_data, |
363
|
|
|
array( |
364
|
|
|
'number' => $this->get_order_number(), |
365
|
|
|
'meta_data' => $this->get_meta_data(), |
366
|
|
|
'line_items' => $this->get_items( 'line_item' ), |
367
|
|
|
'tax_lines' => $this->get_items( 'tax' ), |
368
|
|
|
'shipping_lines' => $this->get_items( 'shipping' ), |
369
|
|
|
'fee_lines' => $this->get_items( 'fee' ), |
370
|
|
|
'coupon_lines' => $this->get_items( 'coupon' ), |
371
|
|
|
) |
372
|
|
|
); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* Get order ID. |
377
|
|
|
* @since 2.7.0 |
378
|
|
|
* @return integer |
379
|
|
|
*/ |
380
|
|
|
public function get_id() { |
381
|
|
|
return $this->_data['id']; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* Get parent order ID. |
386
|
|
|
* @since 2.7.0 |
387
|
|
|
* @return integer |
388
|
|
|
*/ |
389
|
|
|
public function get_parent_id() { |
390
|
|
|
return $this->_data['parent_id']; |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
/** |
394
|
|
|
* get_order_number function. |
395
|
|
|
* |
396
|
|
|
* Gets the order number for display (by default, order ID). |
397
|
|
|
* |
398
|
|
|
* @return string |
399
|
|
|
*/ |
400
|
|
|
public function get_order_number() { |
401
|
|
|
return apply_filters( 'woocommerce_order_number', $this->get_id(), $this ); |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* Get order key. |
406
|
|
|
* @since 2.7.0 |
407
|
|
|
* @return string |
408
|
|
|
*/ |
409
|
|
|
public function get_order_key() { |
410
|
|
|
return $this->_data['order_key']; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Gets order currency. |
415
|
|
|
* @return string |
416
|
|
|
*/ |
417
|
|
|
public function get_currency() { |
418
|
|
|
return apply_filters( 'woocommerce_get_currency', $this->_data['currency'], $this ); |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
/** |
422
|
|
|
* Get order_version |
423
|
|
|
* @return string |
424
|
|
|
*/ |
425
|
|
|
public function get_version() { |
426
|
|
|
return $this->_data['version']; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
/** |
430
|
|
|
* Get prices_include_tax |
431
|
|
|
* @return bool |
432
|
|
|
*/ |
433
|
|
|
public function get_prices_include_tax() { |
434
|
|
|
return $this->_data['prices_include_tax']; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* Get date_created |
439
|
|
|
* @return int |
440
|
|
|
*/ |
441
|
|
|
public function get_date_created() { |
442
|
|
|
return $this->_data['date_created']; |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
/** |
446
|
|
|
* Get date_modified |
447
|
|
|
* @return int |
448
|
|
|
*/ |
449
|
|
|
public function get_date_modified() { |
450
|
|
|
return $this->_data['date_modified']; |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* Get customer_id |
455
|
|
|
* @return int |
456
|
|
|
*/ |
457
|
|
|
public function get_customer_id() { |
458
|
|
|
return $this->_data['customer_id']; |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* Return the order statuses without wc- internal prefix. |
463
|
|
|
* @return string |
464
|
|
|
*/ |
465
|
|
|
public function get_status() { |
466
|
|
|
return apply_filters( 'woocommerce_order_get_status', 'wc-' === substr( $this->_data['status'], 0, 3 ) ? substr( $this->_data['status'], 3 ) : $this->_data['status'], $this ); |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
/** |
470
|
|
|
* Alias for get_customer_id(). |
471
|
|
|
* @since 2.2 |
472
|
|
|
* @return int |
473
|
|
|
*/ |
474
|
|
|
public function get_user_id() { |
475
|
|
|
return $this->get_customer_id(); |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Get the user associated with the order. False for guests. |
480
|
|
|
* |
481
|
|
|
* @since 2.2 |
482
|
|
|
* @return WP_User|false |
483
|
|
|
*/ |
484
|
|
|
public function get_user() { |
485
|
|
|
return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* Get discount_total |
490
|
|
|
* @param bool $raw Gets raw unfiltered value. |
491
|
|
|
* @return string |
492
|
|
|
*/ |
493
|
|
|
public function get_discount_total( $raw = false ) { |
494
|
|
|
$value = wc_format_decimal( $this->_data['discount_total'] ); |
495
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_discount_total', $value, $this ); |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
/** |
499
|
|
|
* Get discount_tax |
500
|
|
|
* @param bool $raw Gets raw unfiltered value. |
501
|
|
|
* @return string |
502
|
|
|
*/ |
503
|
|
|
public function get_discount_tax( $raw = false ) { |
504
|
|
|
$value = wc_format_decimal( $this->_data['discount_tax'] ); |
505
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_discount_tax', $value, $this ); |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
/** |
509
|
|
|
* Get shipping_total |
510
|
|
|
* @param bool $raw Gets raw unfiltered value. |
511
|
|
|
* @return string |
512
|
|
|
*/ |
513
|
|
|
public function get_shipping_total( $raw = false ) { |
514
|
|
|
$value = wc_format_decimal( $this->_data['shipping_total'] ); |
515
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_shipping_total', $value, $this ); |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
/** |
519
|
|
|
* Get shipping_tax. |
520
|
|
|
* @param bool $raw Gets raw unfiltered value. |
521
|
|
|
* @return string |
522
|
|
|
*/ |
523
|
|
|
public function get_shipping_tax( $raw = false ) { |
524
|
|
|
$value = wc_format_decimal( $this->_data['shipping_tax'] ); |
525
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_shipping_tax', $value, $this ); |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
/** |
529
|
|
|
* Gets cart tax amount. |
530
|
|
|
* @param bool $raw Gets raw unfiltered value. |
531
|
|
|
* @return float |
532
|
|
|
*/ |
533
|
|
|
public function get_cart_tax( $raw = false ) { |
534
|
|
|
$value = wc_format_decimal( $this->_data['cart_tax'] ); |
535
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_cart_tax', $value, $this ); |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
/** |
539
|
|
|
* Gets order grand total. incl. taxes. Used in gateways. Filtered. |
540
|
|
|
* @param bool $raw Gets raw unfiltered value. |
541
|
|
|
* @return float |
542
|
|
|
*/ |
543
|
|
|
public function get_total( $raw = false ) { |
544
|
|
|
$value = wc_format_decimal( $this->_data['total'], wc_get_price_decimals() ); |
545
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_total', $value, $this ); |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* Get total tax amount. Alias for get_order_tax(). |
550
|
|
|
* |
551
|
|
|
* @since 2.7.0 woocommerce_order_amount_total_tax filter has been removed to avoid |
552
|
|
|
* these values being modified and then saved back to the DB. There are |
553
|
|
|
* other, later hooks available to change totals on display. e.g. |
554
|
|
|
* woocommerce_get_order_item_totals. |
555
|
|
|
* @param bool $raw Gets raw unfiltered value. |
556
|
|
|
* @return float |
557
|
|
|
*/ |
558
|
|
|
public function get_total_tax( $raw = false ) { |
559
|
|
|
$value = wc_format_decimal( $this->_data['total_tax'] ); |
560
|
|
|
return $raw ? $value : apply_filters( 'woocommerce_order_amount_total_tax', $value, $this ); |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
/** |
564
|
|
|
* Gets the total discount amount. |
565
|
|
|
* @param bool $ex_tax Show discount excl any tax. |
566
|
|
|
* @return float |
567
|
|
|
*/ |
568
|
|
|
public function get_total_discount( $ex_tax = true ) { |
569
|
|
|
if ( $ex_tax ) { |
570
|
|
|
$total_discount = $this->get_discount_total(); |
571
|
|
|
} else { |
572
|
|
|
$total_discount = $this->get_discount_total() + $this->get_discount_tax(); |
573
|
|
|
} |
574
|
|
|
return apply_filters( 'woocommerce_order_amount_total_discount', round( $total_discount, WC_ROUNDING_PRECISION ), $this ); |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
/** |
578
|
|
|
* Gets order subtotal. |
579
|
|
|
* @return float |
580
|
|
|
*/ |
581
|
|
|
public function get_subtotal() { |
582
|
|
|
$subtotal = 0; |
583
|
|
|
|
584
|
|
|
foreach ( $this->get_items() as $item ) { |
585
|
|
|
$subtotal += $item->get_subtotal(); |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
return apply_filters( 'woocommerce_order_amount_subtotal', (double) $subtotal, $this ); |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* Get taxes, merged by code, formatted ready for output. |
593
|
|
|
* |
594
|
|
|
* @return array |
595
|
|
|
*/ |
596
|
|
|
public function get_tax_totals() { |
597
|
|
|
$tax_totals = array(); |
598
|
|
|
|
599
|
|
|
foreach ( $this->get_items( 'tax' ) as $key => $tax ) { |
600
|
|
|
$code = $tax->get_rate_code(); |
601
|
|
|
|
602
|
|
View Code Duplication |
if ( ! isset( $tax_totals[ $code ] ) ) { |
|
|
|
|
603
|
|
|
$tax_totals[ $code ] = new stdClass(); |
604
|
|
|
$tax_totals[ $code ]->amount = 0; |
605
|
|
|
} |
606
|
|
|
|
607
|
|
|
$tax_totals[ $code ]->id = $key; |
608
|
|
|
$tax_totals[ $code ]->rate_id = $tax->get_rate_id(); |
609
|
|
|
$tax_totals[ $code ]->is_compound = $tax->is_compound(); |
610
|
|
|
$tax_totals[ $code ]->label = $tax->get_label(); |
611
|
|
|
$tax_totals[ $code ]->amount += $tax->get_tax_total() + $tax->get_shipping_tax_total(); |
612
|
|
|
$tax_totals[ $code ]->formatted_amount = wc_price( wc_round_tax_total( $tax_totals[ $code ]->amount ), array( 'currency' => $this->get_currency() ) ); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
View Code Duplication |
if ( apply_filters( 'woocommerce_order_hide_zero_taxes', true ) ) { |
|
|
|
|
616
|
|
|
$amounts = array_filter( wp_list_pluck( $tax_totals, 'amount' ) ); |
617
|
|
|
$tax_totals = array_intersect_key( $tax_totals, $amounts ); |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
return apply_filters( 'woocommerce_order_tax_totals', $tax_totals, $this ); |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/* |
624
|
|
|
|-------------------------------------------------------------------------- |
625
|
|
|
| Setters |
626
|
|
|
|-------------------------------------------------------------------------- |
627
|
|
|
| |
628
|
|
|
| Functions for setting order data. These should not update anything in the |
629
|
|
|
| database itself and should only change what is stored in the class |
630
|
|
|
| object. However, for backwards compatibility pre 2.7.0 some of these |
631
|
|
|
| setters may handle both. |
632
|
|
|
| |
633
|
|
|
*/ |
634
|
|
|
|
635
|
|
|
/** |
636
|
|
|
* Set order ID. |
637
|
|
|
* @since 2.7.0 |
638
|
|
|
* @param int $value |
639
|
|
|
*/ |
640
|
|
|
public function set_id( $value ) { |
641
|
|
|
$this->_data['id'] = absint( $value ); |
642
|
|
|
} |
643
|
|
|
|
644
|
|
|
/** |
645
|
|
|
* Set parent order ID. |
646
|
|
|
* @since 2.7.0 |
647
|
|
|
* @param int $value |
648
|
|
|
*/ |
649
|
|
|
public function set_parent_id( $value ) { |
650
|
|
|
$this->_data['parent_id'] = absint( $value ); |
651
|
|
|
} |
652
|
|
|
|
653
|
|
|
/** |
654
|
|
|
* Set order status. |
655
|
|
|
* @since 2.7.0 |
656
|
|
|
* @param string $new_status Status to change the order to. No internal wc- prefix is required. |
657
|
|
|
* @param array details of change |
658
|
|
|
*/ |
659
|
|
|
public function set_status( $new_status ) { |
660
|
|
|
$old_status = $this->get_status(); |
661
|
|
|
$new_status = 'wc-' === substr( $new_status, 0, 3 ) ? substr( $new_status, 3 ) : $new_status; |
662
|
|
|
|
663
|
|
|
// Only allow valid new status |
664
|
|
|
if ( ! in_array( 'wc-' . $new_status, array_keys( wc_get_order_statuses() ) ) ) { |
665
|
|
|
$new_status = 'pending'; |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
$this->_data['status'] = 'wc-' . $new_status; |
669
|
|
|
|
670
|
|
|
// If the old status is set but unknown (e.g. draft) assume its pending for action usage. |
671
|
|
|
if ( $old_status && ! in_array( 'wc-' . $old_status, array_keys( wc_get_order_statuses() ) ) ) { |
672
|
|
|
$old_status = 'pending'; |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
return array( |
676
|
|
|
'from' => $old_status, |
677
|
|
|
'to' => $new_status |
678
|
|
|
); |
679
|
|
|
} |
680
|
|
|
|
681
|
|
|
/** |
682
|
|
|
* Set order_key. |
683
|
|
|
* @param string $value Max length 20 chars. |
684
|
|
|
*/ |
685
|
|
|
public function set_order_key( $value ) { |
686
|
|
|
$this->_data['order_key'] = substr( $value, 0, 20 ); |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
/** |
690
|
|
|
* Set order_version |
691
|
|
|
* @param string $value |
692
|
|
|
*/ |
693
|
|
|
public function set_version( $value ) { |
694
|
|
|
$this->_data['version'] = $value; |
695
|
|
|
} |
696
|
|
|
|
697
|
|
|
/** |
698
|
|
|
* Set order_currency |
699
|
|
|
* @param string $value |
700
|
|
|
*/ |
701
|
|
|
public function set_currency( $value ) { |
702
|
|
|
if ( $value && ! in_array( $value, array_keys( get_woocommerce_currencies() ) ) ) { |
|
|
|
|
703
|
|
|
//$this->throw_exception( 'invalid_currency', 'Invalid currency code' ); |
|
|
|
|
704
|
|
|
} |
705
|
|
|
$this->_data['currency'] = $value; |
706
|
|
|
} |
707
|
|
|
|
708
|
|
|
/** |
709
|
|
|
* Set prices_include_tax |
710
|
|
|
* @param bool $value |
711
|
|
|
*/ |
712
|
|
|
public function set_prices_include_tax( $value ) { |
713
|
|
|
$this->_data['prices_include_tax'] = (bool) $value; |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
/** |
717
|
|
|
* Set date_created |
718
|
|
|
* @param string $timestamp Timestamp |
719
|
|
|
*/ |
720
|
|
|
public function set_date_created( $timestamp ) { |
721
|
|
|
$this->_data['date_created'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); |
722
|
|
|
} |
723
|
|
|
|
724
|
|
|
/** |
725
|
|
|
* Set date_modified |
726
|
|
|
* @param string $timestamp |
727
|
|
|
*/ |
728
|
|
|
public function set_date_modified( $timestamp ) { |
729
|
|
|
$this->_data['date_modified'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Set customer_id |
734
|
|
|
* @param int $value |
735
|
|
|
*/ |
736
|
|
|
public function set_customer_id( $value ) { |
737
|
|
|
$this->_data['customer_id'] = absint( $value ); |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
/** |
741
|
|
|
* Set discount_total |
742
|
|
|
* @param string $value |
743
|
|
|
*/ |
744
|
|
|
public function set_discount_total( $value ) { |
745
|
|
|
$this->_data['discount_total'] = wc_format_decimal( $value ); |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
/** |
749
|
|
|
* Set discount_tax |
750
|
|
|
* @param string $value |
751
|
|
|
*/ |
752
|
|
|
public function set_discount_tax( $value ) { |
753
|
|
|
$this->_data['discount_tax'] = wc_format_decimal( $value ); |
754
|
|
|
} |
755
|
|
|
|
756
|
|
|
/** |
757
|
|
|
* Set shipping_total |
758
|
|
|
* @param string $value |
759
|
|
|
*/ |
760
|
|
|
public function set_shipping_total( $value ) { |
761
|
|
|
$this->_data['shipping_total'] = wc_format_decimal( $value ); |
762
|
|
|
} |
763
|
|
|
|
764
|
|
|
/** |
765
|
|
|
* Set shipping_tax |
766
|
|
|
* @param string $value |
767
|
|
|
*/ |
768
|
|
|
public function set_shipping_tax( $value ) { |
769
|
|
|
$this->_data['shipping_tax'] = wc_format_decimal( $value ); |
770
|
|
|
$this->set_total_tax( $this->get_cart_tax() + $this->get_shipping_tax() ); |
771
|
|
|
} |
772
|
|
|
|
773
|
|
|
/** |
774
|
|
|
* Set cart tax |
775
|
|
|
* @param string $value |
776
|
|
|
*/ |
777
|
|
|
public function set_cart_tax( $value ) { |
778
|
|
|
$this->_data['cart_tax'] = wc_format_decimal( $value ); |
779
|
|
|
$this->set_total_tax( $this->get_cart_tax() + $this->get_shipping_tax() ); |
780
|
|
|
} |
781
|
|
|
|
782
|
|
|
/** |
783
|
|
|
* Sets order tax (sum of cart and shipping tax). Used internaly only. |
784
|
|
|
* @param string $value |
785
|
|
|
*/ |
786
|
|
|
protected function set_total_tax( $value ) { |
787
|
|
|
$this->_data['total_tax'] = wc_format_decimal( $value ); |
788
|
|
|
} |
789
|
|
|
|
790
|
|
|
/** |
791
|
|
|
* Set total |
792
|
|
|
* @param string $value |
793
|
|
|
* @param string $deprecated Function used to set different totals based on this. |
794
|
|
|
*/ |
795
|
|
|
public function set_total( $value, $deprecated = '' ) { |
796
|
|
|
if ( $deprecated ) { |
797
|
|
|
_deprecated_argument( 'total_type', '2.7', 'Use dedicated total setter methods instead.' ); |
798
|
|
|
return $this->legacy_set_total( $value, $deprecated ); |
799
|
|
|
} |
800
|
|
|
$this->_data['total'] = wc_format_decimal( $value, wc_get_price_decimals() ); |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
/* |
804
|
|
|
|-------------------------------------------------------------------------- |
805
|
|
|
| Order Item Handling |
806
|
|
|
|-------------------------------------------------------------------------- |
807
|
|
|
| |
808
|
|
|
| Order items are used for products, taxes, shipping, and fees within |
809
|
|
|
| each order. |
810
|
|
|
| |
811
|
|
|
*/ |
812
|
|
|
|
813
|
|
|
/** |
814
|
|
|
* Prefixes an item key with a string so arrays are associative rather than numeric. |
815
|
|
|
* @param int $id |
816
|
|
|
* @return string |
817
|
|
|
*/ |
818
|
|
|
protected function prefix_item_id( $id ) { |
819
|
|
|
return 'item-' . $id; |
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
/** |
823
|
|
|
* Remove all line items (products, coupons, shipping, taxes) from the order. |
824
|
|
|
* @param string $type Order item type. Default null. |
825
|
|
|
*/ |
826
|
|
|
public function remove_order_items( $type = null ) { |
827
|
|
|
global $wpdb; |
828
|
|
|
if ( ! empty( $type ) ) { |
829
|
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id AND items.order_id = %d AND items.order_item_type = %s", $this->get_id(), $type ) ); |
830
|
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s", $this->get_id(), $type ) ); |
831
|
|
|
if ( $group = $this->type_to_group( $type ) ) { |
832
|
|
|
$this->_items[ $group ] = null; |
833
|
|
|
} |
834
|
|
|
} else { |
835
|
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id and items.order_id = %d", $this->get_id() ) ); |
836
|
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $this->get_id() ) ); |
837
|
|
|
$this->_items = array( |
838
|
|
|
'line_items' => null, |
839
|
|
|
'coupon_lines' => null, |
840
|
|
|
'shipping_lines' => null, |
841
|
|
|
'fee_lines' => null, |
842
|
|
|
'tax_lines' => null, |
843
|
|
|
); |
844
|
|
|
} |
845
|
|
|
} |
846
|
|
|
|
847
|
|
|
/** |
848
|
|
|
* Convert a type to a types group. |
849
|
|
|
* @param string $type |
850
|
|
|
* @return string group |
851
|
|
|
*/ |
852
|
|
|
protected function type_to_group( $type ) { |
853
|
|
|
$type_to_group = array( |
854
|
|
|
'line_item' => 'line_items', |
855
|
|
|
'tax' => 'tax_lines', |
856
|
|
|
'shipping' => 'shipping_lines', |
857
|
|
|
'fee' => 'fee_lines', |
858
|
|
|
'coupon' => 'coupon_lines', |
859
|
|
|
); |
860
|
|
|
return isset( $type_to_group[ $type ] ) ? $type_to_group[ $type ] : ''; |
861
|
|
|
} |
862
|
|
|
|
863
|
|
|
/** |
864
|
|
|
* Return an array of items/products within this order. |
865
|
|
|
* @param string|array $types Types of line items to get (array or string). |
866
|
|
|
* @return Array of WC_Order_item |
867
|
|
|
*/ |
868
|
|
|
public function get_items( $types = 'line_item' ) { |
869
|
|
|
$items = array(); |
870
|
|
|
$types = array_filter( (array) $types ); |
871
|
|
|
|
872
|
|
|
foreach ( $types as $type ) { |
873
|
|
|
if ( $group = $this->type_to_group( $type ) ) { |
874
|
|
|
if ( is_null( $this->_items[ $group ] ) ) { |
875
|
|
|
$this->_items[ $group ] = $this->get_items_from_db( $type ); |
876
|
|
|
} |
877
|
|
|
$items = array_merge( $items, $this->_items[ $group ] ); |
878
|
|
|
} |
879
|
|
|
} |
880
|
|
|
|
881
|
|
|
return apply_filters( 'woocommerce_order_get_items', $items, $this ); |
882
|
|
|
} |
883
|
|
|
|
884
|
|
|
/** |
885
|
|
|
* Gets items from the database by type. |
886
|
|
|
* @param string $type |
887
|
|
|
* @return array |
888
|
|
|
*/ |
889
|
|
|
protected function get_items_from_db( $type ) { |
890
|
|
|
global $wpdb; |
891
|
|
|
|
892
|
|
|
$get_items_sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s ORDER BY order_item_id;", $this->get_id(), $type ) ; |
893
|
|
|
$items = $wpdb->get_results( $get_items_sql ); |
894
|
|
|
|
895
|
|
|
if ( ! empty( $items ) ) { |
896
|
|
|
$items = array_map( array( $this, 'get_item' ), array_combine( array_map( array( $this, 'prefix_item_id' ), wp_list_pluck( $items, 'order_item_id' ) ), $items ) ); |
897
|
|
|
} else { |
898
|
|
|
$items = array(); |
899
|
|
|
} |
900
|
|
|
|
901
|
|
|
return $items; |
902
|
|
|
} |
903
|
|
|
|
904
|
|
|
/** |
905
|
|
|
* Return an array of fees within this order. |
906
|
|
|
* @return array |
907
|
|
|
*/ |
908
|
|
|
public function get_fees() { |
909
|
|
|
return $this->get_items( 'fee' ); |
910
|
|
|
} |
911
|
|
|
|
912
|
|
|
/** |
913
|
|
|
* Return an array of taxes within this order. |
914
|
|
|
* @return array |
915
|
|
|
*/ |
916
|
|
|
public function get_taxes() { |
917
|
|
|
return $this->get_items( 'tax' ); |
918
|
|
|
} |
919
|
|
|
|
920
|
|
|
/** |
921
|
|
|
* Return an array of shipping costs within this order. |
922
|
|
|
* @return array |
923
|
|
|
*/ |
924
|
|
|
public function get_shipping_methods() { |
925
|
|
|
return $this->get_items( 'shipping' ); |
926
|
|
|
} |
927
|
|
|
|
928
|
|
|
/** |
929
|
|
|
* Gets formatted shipping method title. |
930
|
|
|
* @return string |
931
|
|
|
*/ |
932
|
|
|
public function get_shipping_method() { |
933
|
|
|
$names = array(); |
934
|
|
|
foreach ( $this->get_shipping_methods() as $shipping_method ) { |
935
|
|
|
$names[] = $shipping_method->get_name(); |
936
|
|
|
} |
937
|
|
|
return apply_filters( 'woocommerce_order_shipping_method', implode( ', ', $names ), $this ); |
938
|
|
|
} |
939
|
|
|
|
940
|
|
|
/** |
941
|
|
|
* Get coupon codes only. |
942
|
|
|
* @return array |
943
|
|
|
*/ |
944
|
|
|
public function get_used_coupons() { |
945
|
|
|
$coupon_codes = array(); |
946
|
|
|
if ( $coupons = $this->get_items( 'coupon' ) ) { |
947
|
|
|
foreach ( $coupons as $coupon ) { |
948
|
|
|
$coupon_codes[] = $coupon->get_code(); |
949
|
|
|
} |
950
|
|
|
} |
951
|
|
|
return $coupon_codes; |
952
|
|
|
} |
953
|
|
|
|
954
|
|
|
/** |
955
|
|
|
* Gets the count of order items of a certain type. |
956
|
|
|
* |
957
|
|
|
* @param string $item_type |
958
|
|
|
* @return string |
959
|
|
|
*/ |
960
|
|
|
public function get_item_count( $item_type = '' ) { |
961
|
|
|
$items = $this->get_items( empty( $item_type ) ? 'line_item' : $item_type ); |
962
|
|
|
$count = 0; |
963
|
|
|
|
964
|
|
|
foreach ( $items as $item ) { |
965
|
|
|
$count += $item->get_quantity(); |
966
|
|
|
} |
967
|
|
|
|
968
|
|
|
return apply_filters( 'woocommerce_get_item_count', $count, $item_type, $this ); |
969
|
|
|
} |
970
|
|
|
|
971
|
|
|
/** |
972
|
|
|
* Get an order item object, based on it's type. |
973
|
|
|
* @since 2.7.0 |
974
|
|
|
* @param int $item_id |
975
|
|
|
* @return WC_Order_Item |
976
|
|
|
*/ |
977
|
|
|
public function get_item( $item_id ) { |
978
|
|
|
return WC_Order_Factory::get_order_item( $item_id ); |
979
|
|
|
} |
980
|
|
|
|
981
|
|
|
/** |
982
|
|
|
* Get key for where a certain item type is stored in _items. |
983
|
|
|
* @since 2.7.0 |
984
|
|
|
* @param $item object Order item (product, shipping, fee, coupon, tax) |
985
|
|
|
* @return string |
986
|
|
|
*/ |
987
|
|
|
protected function get_items_key( $item ) { |
988
|
|
|
if ( is_a( $item, 'WC_Order_Item_Product' ) ) { |
989
|
|
|
return 'line_items'; |
990
|
|
|
} elseif ( is_a( $item, 'WC_Order_Item_Fee' ) ) { |
991
|
|
|
return 'fee_lines'; |
992
|
|
|
} elseif ( is_a( $item, 'WC_Order_Item_Shipping' ) ) { |
993
|
|
|
return 'shipping_lines'; |
994
|
|
|
} elseif ( is_a( $item, 'WC_Order_Item_Tax' ) ) { |
995
|
|
|
return 'tax_lines'; |
996
|
|
|
} elseif ( is_a( $item, 'WC_Order_Item_Coupon' ) ) { |
997
|
|
|
return 'coupon_lines'; |
998
|
|
|
} else { |
999
|
|
|
return ''; |
1000
|
|
|
} |
1001
|
|
|
} |
1002
|
|
|
|
1003
|
|
|
/** |
1004
|
|
|
* Remove item from the order. |
1005
|
|
|
* @param int $item_id |
1006
|
|
|
*/ |
1007
|
|
|
public function remove_item( $item_id ) { |
1008
|
|
|
$item = $this->get_item( $item_id ); |
1009
|
|
|
|
1010
|
|
|
if ( ! $item || ! ( $items_key = $this->get_items_key( $item ) ) ) { |
1011
|
|
|
return false; |
1012
|
|
|
} |
1013
|
|
|
|
1014
|
|
|
// Unset and remove later |
1015
|
|
|
$this->_items_to_delete[] = $item; |
1016
|
|
|
unset( $this->_items[ $items_key ][ $this->prefix_item_id( $item->get_id() ) ] ); |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
/** |
1020
|
|
|
* Adds an order item to this order. The order item will not persist until save. |
1021
|
|
|
* @param object Order item (product, shipping, fee, coupon, tax) |
1022
|
|
|
*/ |
1023
|
|
|
public function add_item( $item ) { |
1024
|
|
|
if ( ! $items_key = $this->get_items_key( $item ) ) { |
1025
|
|
|
return false; |
1026
|
|
|
} |
1027
|
|
|
|
1028
|
|
|
// Make sure existing items are loaded so we can append this new one. |
1029
|
|
|
if ( is_null( $this->_items[ $items_key ] ) ) { |
1030
|
|
|
$this->_items[ $items_key ] = $this->get_items( $item->get_type() ); |
1031
|
|
|
} |
1032
|
|
|
|
1033
|
|
|
// Append new row with generated temporary ID |
1034
|
|
|
if ( $item->get_id() ) { |
1035
|
|
|
$this->_items[ $items_key ][ $this->prefix_item_id( $item->get_id() ) ] = $item; |
1036
|
|
|
} else { |
1037
|
|
|
$this->_items[ $items_key ][ 'new:' . md5( json_encode( $item ) ) ] = $item; |
1038
|
|
|
} |
1039
|
|
|
} |
1040
|
|
|
|
1041
|
|
|
/** |
1042
|
|
|
* Add a product line item to the order. |
1043
|
|
|
* @param \WC_Product $product |
1044
|
|
|
* @param int $qty |
1045
|
|
|
* @param array $args |
1046
|
|
|
* @return int order item ID |
1047
|
|
|
*/ |
1048
|
|
|
public function add_product( $product, $qty = 1, $args = array() ) { |
1049
|
|
|
$args = wp_parse_args( $args, array( |
1050
|
|
|
'quantity' => $qty, |
1051
|
|
|
'name' => $product ? $product->get_title() : '', |
1052
|
|
|
'tax_class' => $product ? $product->get_tax_class() : '', |
1053
|
|
|
'product_id' => $product ? $product->get_id() : '', |
1054
|
|
|
'variation_id' => $product && isset( $product->variation_id ) ? $product->variation_id : 0, |
1055
|
|
|
'variation' => $product && isset( $product->variation_id ) ? $product->get_variation_attributes() : array(), |
|
|
|
|
1056
|
|
|
'subtotal' => $product ? $product->get_price_excluding_tax( $qty ) : '', |
1057
|
|
|
'total' => $product ? $product->get_price_excluding_tax( $qty ) : '', |
1058
|
|
|
'subtotal_tax' => 0, |
1059
|
|
|
'total_tax' => 0, |
1060
|
|
|
'taxes' => array( |
1061
|
|
|
'subtotal' => array(), |
1062
|
|
|
'total' => array(), |
1063
|
|
|
), |
1064
|
|
|
) ); |
1065
|
|
|
|
1066
|
|
|
// BW compatibility with old args |
1067
|
|
View Code Duplication |
if ( isset( $args['totals'] ) ) { |
|
|
|
|
1068
|
|
|
foreach ( $args['totals'] as $key => $value ) { |
1069
|
|
|
if ( 'tax' === $key ) { |
1070
|
|
|
$args['total_tax'] = $value; |
1071
|
|
|
} elseif ( 'tax_data' === $key ) { |
1072
|
|
|
$args['taxes'] = $value; |
1073
|
|
|
} else { |
1074
|
|
|
$args[ $key ] = $value; |
1075
|
|
|
} |
1076
|
|
|
} |
1077
|
|
|
} |
1078
|
|
|
|
1079
|
|
|
$item = new WC_Order_Item_Product( $args ); |
1080
|
|
|
$item->set_backorder_meta(); |
1081
|
|
|
$item->set_order_id( $this->get_id() ); |
1082
|
|
|
$item->save(); |
1083
|
|
|
$this->add_item( $item ); |
1084
|
|
|
wc_do_deprecated_action( 'woocommerce_order_add_product', array( $this->get_id(), $item->get_id(), $product, $qty, $args ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
1085
|
|
|
return $item->get_id(); |
1086
|
|
|
} |
1087
|
|
|
|
1088
|
|
|
/** |
1089
|
|
|
* Add coupon code to the order. |
1090
|
|
|
* @param string $code |
1091
|
|
|
* @param int $discount tax amount. |
1092
|
|
|
* @param int $discount_tax amount. |
1093
|
|
|
* @return int order item ID |
1094
|
|
|
*/ |
1095
|
|
|
public function add_coupon( $code = array(), $discount = 0, $discount_tax = 0 ) { |
1096
|
|
|
$item = new WC_Order_Item_Coupon( array( |
|
|
|
|
1097
|
|
|
'code' => $code, |
1098
|
|
|
'discount' => $discount, |
1099
|
|
|
'discount_tax' => $discount_tax, |
1100
|
|
|
) ); |
1101
|
|
|
$item->set_order_id( $this->get_id() ); |
1102
|
|
|
$item->save(); |
1103
|
|
|
$this->add_item( $item ); |
1104
|
|
|
wc_do_deprecated_action( 'woocommerce_order_add_coupon', array( $this->get_id(), $item->get_id(), $code, $discount, $discount_tax ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
1105
|
|
|
return $item->get_id(); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
/** |
1109
|
|
|
* Add a tax row to the order. |
1110
|
|
|
* @param array $args |
1111
|
|
|
* @param int $deprecated1 2.7.0 tax_rate_id, amount, shipping amount. |
1112
|
|
|
* @param int $deprecated2 2.7.0 tax_rate_id, amount, shipping amount. |
1113
|
|
|
* @return int order item ID |
1114
|
|
|
*/ |
1115
|
|
|
public function add_tax( $args = array(), $deprecated1 = 0, $deprecated2 = 0 ) { |
1116
|
|
|
if ( ! is_array( $args ) ) { |
1117
|
|
|
_deprecated_argument( 'tax_rate_id', '2.7', 'Pass only an array of args' ); |
1118
|
|
|
$args = array( |
1119
|
|
|
'rate_id' => $args, |
1120
|
|
|
'tax_total' => $deprecated1, |
1121
|
|
|
'shipping_tax_total' => $deprecated2, |
1122
|
|
|
); |
1123
|
|
|
} |
1124
|
|
|
$args = wp_parse_args( $args, array( |
1125
|
|
|
'rate_id' => '', |
1126
|
|
|
'tax_total' => 0, |
1127
|
|
|
'shipping_tax_total' => 0, |
1128
|
|
|
'rate_code' => isset( $args['rate_id'] ) ? WC_Tax::get_rate_code( $args['rate_id'] ) : '', |
1129
|
|
|
'label' => isset( $args['rate_id'] ) ? WC_Tax::get_rate_label( $args['rate_id'] ) : '', |
1130
|
|
|
'compound' => isset( $args['rate_id'] ) ? WC_Tax::is_compound( $args['rate_id'] ) : '', |
1131
|
|
|
) ); |
1132
|
|
|
$item = new WC_Order_Item_Tax( $args ); |
1133
|
|
|
$item->set_order_id( $this->get_id() ); |
1134
|
|
|
$item->save(); |
1135
|
|
|
$this->add_item( $item ); |
1136
|
|
|
wc_do_deprecated_action( 'woocommerce_order_add_tax', array( $this->get_id(), $item->get_id(), $args['rate_id'], $args['tax_total'], $args['shipping_tax_total'] ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
1137
|
|
|
return $item->get_id(); |
1138
|
|
|
} |
1139
|
|
|
|
1140
|
|
|
/** |
1141
|
|
|
* Add a shipping row to the order. |
1142
|
|
|
* @param WC_Shipping_Rate shipping_rate |
1143
|
|
|
* @return int order item ID |
1144
|
|
|
*/ |
1145
|
|
|
public function add_shipping( $shipping_rate ) { |
1146
|
|
|
$item = new WC_Order_Item_Shipping( array( |
|
|
|
|
1147
|
|
|
'method_title' => $shipping_rate->label, |
1148
|
|
|
'method_id' => $shipping_rate->id, |
1149
|
|
|
'total' => wc_format_decimal( $shipping_rate->cost ), |
1150
|
|
|
'taxes' => $shipping_rate->taxes, |
1151
|
|
|
'meta_data' => $shipping_rate->get_meta_data(), |
1152
|
|
|
) ); |
1153
|
|
|
$item->set_order_id( $this->get_id() ); |
1154
|
|
|
$item->save(); |
1155
|
|
|
$this->add_item( $item ); |
1156
|
|
|
wc_do_deprecated_action( 'woocommerce_order_add_shipping', array( $this->get_id(), $item->get_id(), $shipping_rate ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
1157
|
|
|
return $item->get_id(); |
1158
|
|
|
} |
1159
|
|
|
|
1160
|
|
|
/** |
1161
|
|
|
* Add a fee to the order. |
1162
|
|
|
* Order must be saved prior to adding items. |
1163
|
|
|
* @param object $fee |
1164
|
|
|
* @return int updated order item ID |
1165
|
|
|
*/ |
1166
|
|
|
public function add_fee( $fee ) { |
1167
|
|
|
$item = new WC_Order_Item_Fee( array( |
|
|
|
|
1168
|
|
|
'name' => $fee->name, |
1169
|
|
|
'tax_class' => $fee->taxable ? $fee->tax_class : 0, |
1170
|
|
|
'total' => $fee->amount, |
1171
|
|
|
'total_tax' => $fee->tax, |
1172
|
|
|
'taxes' => array( |
1173
|
|
|
'total' => $fee->tax_data, |
1174
|
|
|
), |
1175
|
|
|
) ); |
1176
|
|
|
$item->set_order_id( $this->get_id() ); |
1177
|
|
|
$item->save(); |
1178
|
|
|
$this->add_item( $item ); |
1179
|
|
|
wc_do_deprecated_action( 'woocommerce_order_add_fee', array( $this->get_id(), $item->get_id(), $fee ), '2.7', 'Use woocommerce_new_order_item action instead.' ); |
1180
|
|
|
return $item->get_id(); |
1181
|
|
|
} |
1182
|
|
|
|
1183
|
|
|
/* |
1184
|
|
|
|-------------------------------------------------------------------------- |
1185
|
|
|
| Payment Token Handling |
1186
|
|
|
|-------------------------------------------------------------------------- |
1187
|
|
|
| |
1188
|
|
|
| Payment tokens are hashes used to take payments by certain gateways. |
1189
|
|
|
| |
1190
|
|
|
*/ |
1191
|
|
|
|
1192
|
|
|
/** |
1193
|
|
|
* Add a payment token to an order |
1194
|
|
|
* |
1195
|
|
|
* @since 2.6 |
1196
|
|
|
* @param WC_Payment_Token $token Payment token object |
1197
|
|
|
* @return boolean|int The new token ID or false if it failed. |
1198
|
|
|
*/ |
1199
|
|
|
public function add_payment_token( $token ) { |
1200
|
|
|
if ( empty( $token ) || ! ( $token instanceof WC_Payment_Token ) ) { |
1201
|
|
|
return false; |
1202
|
|
|
} |
1203
|
|
|
|
1204
|
|
|
$token_ids = get_post_meta( $this->get_id(), '_payment_tokens', true ); |
1205
|
|
|
|
1206
|
|
|
if ( empty ( $token_ids ) ) { |
1207
|
|
|
$token_ids = array(); |
1208
|
|
|
} |
1209
|
|
|
|
1210
|
|
|
$token_ids[] = $token->get_id(); |
1211
|
|
|
|
1212
|
|
|
update_post_meta( $this->get_id(), '_payment_tokens', $token_ids ); |
1213
|
|
|
do_action( 'woocommerce_payment_token_added_to_order', $this->get_id(), $token->get_id(), $token, $token_ids ); |
1214
|
|
|
return $token->get_id(); |
1215
|
|
|
} |
1216
|
|
|
|
1217
|
|
|
/** |
1218
|
|
|
* Returns a list of all payment tokens associated with the current order |
1219
|
|
|
* |
1220
|
|
|
* @since 2.6 |
1221
|
|
|
* @return array An array of payment token objects |
1222
|
|
|
*/ |
1223
|
|
|
public function get_payment_tokens() { |
1224
|
|
|
return WC_Payment_Tokens::get_order_tokens( $this->get_id() ); |
1225
|
|
|
} |
1226
|
|
|
|
1227
|
|
|
/* |
1228
|
|
|
|-------------------------------------------------------------------------- |
1229
|
|
|
| Calculations. |
1230
|
|
|
|-------------------------------------------------------------------------- |
1231
|
|
|
| |
1232
|
|
|
| These methods calculate order totals and taxes based on the current data. |
1233
|
|
|
| |
1234
|
|
|
*/ |
1235
|
|
|
|
1236
|
|
|
/** |
1237
|
|
|
* Calculate shipping total. |
1238
|
|
|
* |
1239
|
|
|
* @since 2.2 |
1240
|
|
|
* @return float |
1241
|
|
|
*/ |
1242
|
|
|
public function calculate_shipping() { |
1243
|
|
|
$shipping_total = 0; |
1244
|
|
|
|
1245
|
|
|
foreach ( $this->get_shipping_methods() as $shipping ) { |
1246
|
|
|
$shipping_total += $shipping->get_total(); |
1247
|
|
|
} |
1248
|
|
|
|
1249
|
|
|
$this->set_shipping_total( $shipping_total ); |
1250
|
|
|
$this->save(); |
1251
|
|
|
|
1252
|
|
|
return $this->get_shipping_total(); |
1253
|
|
|
} |
1254
|
|
|
|
1255
|
|
|
/** |
1256
|
|
|
* Get all tax classes for items in the order. |
1257
|
|
|
* |
1258
|
|
|
* @since 2.6.3 |
1259
|
|
|
* @return array |
1260
|
|
|
*/ |
1261
|
|
|
public function get_items_tax_classes() { |
1262
|
|
|
$found_tax_classes = array(); |
1263
|
|
|
|
1264
|
|
|
foreach ( $this->get_items() as $item ) { |
1265
|
|
|
if ( $_product = $this->get_product_from_item( $item ) ) { |
|
|
|
|
1266
|
|
|
$found_tax_classes[] = $_product->get_tax_class(); |
|
|
|
|
1267
|
|
|
} |
1268
|
|
|
} |
1269
|
|
|
|
1270
|
|
|
return array_unique( $found_tax_classes ); |
1271
|
|
|
} |
1272
|
|
|
|
1273
|
|
|
/** |
1274
|
|
|
* Calculate taxes for all line items and shipping, and store the totals and tax rows. |
1275
|
|
|
* |
1276
|
|
|
* Will use the base country unless customer addresses are set. |
1277
|
|
|
* @param $args array Added in 2.7.0 to pass things like location. |
1278
|
|
|
*/ |
1279
|
|
|
public function calculate_taxes( $args = array() ) { |
1280
|
|
|
$tax_based_on = get_option( 'woocommerce_tax_based_on' ); |
1281
|
|
|
$args = wp_parse_args( $args, array( |
1282
|
|
|
'country' => 'billing' === $tax_based_on ? $this->get_billing_country() : $this->get_shipping_country(), |
|
|
|
|
1283
|
|
|
'state' => 'billing' === $tax_based_on ? $this->get_billing_state() : $this->get_shipping_state(), |
|
|
|
|
1284
|
|
|
'postcode' => 'billing' === $tax_based_on ? $this->get_billing_postcode() : $this->get_shipping_postcode(), |
|
|
|
|
1285
|
|
|
'city' => 'billing' === $tax_based_on ? $this->get_billing_city() : $this->get_shipping_city(), |
|
|
|
|
1286
|
|
|
) ); |
1287
|
|
|
|
1288
|
|
|
// Default to base |
1289
|
|
|
if ( 'base' === $tax_based_on || empty( $args['country'] ) ) { |
1290
|
|
|
$default = wc_get_base_location(); |
1291
|
|
|
$args['country'] = $default['country']; |
1292
|
|
|
$args['state'] = $default['state']; |
1293
|
|
|
$args['postcode'] = ''; |
1294
|
|
|
$args['city'] = ''; |
1295
|
|
|
} |
1296
|
|
|
|
1297
|
|
|
// Calc taxes for line items |
1298
|
|
|
foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) { |
1299
|
|
|
$tax_class = $item->get_tax_class(); |
1300
|
|
|
$tax_status = $item->get_tax_status(); |
1301
|
|
|
|
1302
|
|
|
if ( '0' !== $tax_class && 'taxable' === $tax_status ) { |
1303
|
|
|
$tax_rates = WC_Tax::find_rates( array( |
1304
|
|
|
'country' => $args['country'], |
1305
|
|
|
'state' => $args['state'], |
1306
|
|
|
'postcode' => $args['postcode'], |
1307
|
|
|
'city' => $args['city'], |
1308
|
|
|
'tax_class' => $tax_class, |
1309
|
|
|
) ); |
1310
|
|
|
|
1311
|
|
|
$total = $item->get_total(); |
1312
|
|
|
$taxes = WC_Tax::calc_tax( $total, $tax_rates, false ); |
1313
|
|
|
|
1314
|
|
|
if ( $item->is_type( 'line_item' ) ) { |
1315
|
|
|
$subtotal = $item->get_subtotal(); |
1316
|
|
|
$subtotal_taxes = WC_Tax::calc_tax( $subtotal, $tax_rates, false ); |
1317
|
|
|
$subtotal_tax = max( 0, array_sum( $subtotal_taxes ) ); |
1318
|
|
|
$item->set_subtotal_tax( $subtotal_tax ); |
1319
|
|
|
$item->set_taxes( array( 'total' => $taxes, 'subtotal' => $subtotal_taxes ) ); |
1320
|
|
|
} else { |
1321
|
|
|
$item->set_taxes( array( 'total' => $taxes ) ); |
1322
|
|
|
} |
1323
|
|
|
$item->save(); |
1324
|
|
|
} |
1325
|
|
|
} |
1326
|
|
|
|
1327
|
|
|
// Calc taxes for shipping |
1328
|
|
|
foreach ( $this->get_shipping_methods() as $item_id => $item ) { |
1329
|
|
|
$shipping_tax_class = get_option( 'woocommerce_shipping_tax_class' ); |
1330
|
|
|
|
1331
|
|
|
// Inherit tax class from items |
1332
|
|
|
if ( '' === $shipping_tax_class ) { |
1333
|
|
|
$tax_rates = array(); |
1334
|
|
|
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() ); |
1335
|
|
|
$found_tax_classes = $this->get_items_tax_classes(); |
1336
|
|
|
|
1337
|
|
|
foreach ( $tax_classes as $tax_class ) { |
1338
|
|
|
$tax_class = sanitize_title( $tax_class ); |
1339
|
|
|
if ( in_array( $tax_class, $found_tax_classes ) ) { |
1340
|
|
|
$tax_rates = WC_Tax::find_shipping_rates( array( |
1341
|
|
|
'country' => $args['country'], |
1342
|
|
|
'state' => $args['state'], |
1343
|
|
|
'postcode' => $args['postcode'], |
1344
|
|
|
'city' => $args['city'], |
1345
|
|
|
'tax_class' => $tax_class, |
1346
|
|
|
) ); |
1347
|
|
|
break; |
1348
|
|
|
} |
1349
|
|
|
} |
1350
|
|
|
} else { |
1351
|
|
|
$tax_rates = WC_Tax::find_shipping_rates( array( |
1352
|
|
|
'country' => $args['country'], |
1353
|
|
|
'state' => $args['state'], |
1354
|
|
|
'postcode' => $args['postcode'], |
1355
|
|
|
'city' => $args['city'], |
1356
|
|
|
'tax_class' => 'standard' === $shipping_tax_class ? '' : $shipping_tax_class, |
1357
|
|
|
) ); |
1358
|
|
|
} |
1359
|
|
|
$item->set_taxes( array( 'total' => WC_Tax::calc_tax( $item->get_total(), $tax_rates, false ) ) ); |
1360
|
|
|
$item->save(); |
1361
|
|
|
} |
1362
|
|
|
$this->update_taxes(); |
1363
|
|
|
} |
1364
|
|
|
|
1365
|
|
|
/** |
1366
|
|
|
* Update tax lines for the order based on the line item taxes themselves. |
1367
|
|
|
*/ |
1368
|
|
|
public function update_taxes() { |
1369
|
|
|
$cart_taxes = array(); |
1370
|
|
|
$shipping_taxes = array(); |
1371
|
|
|
|
1372
|
|
|
foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) { |
1373
|
|
|
$taxes = $item->get_taxes(); |
1374
|
|
View Code Duplication |
foreach ( $taxes['total'] as $tax_rate_id => $tax ) { |
|
|
|
|
1375
|
|
|
$cart_taxes[ $tax_rate_id ] = isset( $cart_taxes[ $tax_rate_id ] ) ? $cart_taxes[ $tax_rate_id ] + $tax : $tax; |
1376
|
|
|
} |
1377
|
|
|
} |
1378
|
|
|
|
1379
|
|
|
foreach ( $this->get_shipping_methods() as $item_id => $item ) { |
1380
|
|
|
$taxes = $item->get_taxes(); |
1381
|
|
View Code Duplication |
foreach ( $taxes['total'] as $tax_rate_id => $tax ) { |
|
|
|
|
1382
|
|
|
$shipping_taxes[ $tax_rate_id ] = isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] + $tax : $tax; |
1383
|
|
|
} |
1384
|
|
|
} |
1385
|
|
|
|
1386
|
|
|
// Remove old existing tax rows. |
1387
|
|
|
$this->remove_order_items( 'tax' ); |
1388
|
|
|
|
1389
|
|
|
// Now merge to keep tax rows. |
1390
|
|
|
foreach ( array_keys( $cart_taxes + $shipping_taxes ) as $tax_rate_id ) { |
1391
|
|
|
$this->add_tax( array( |
1392
|
|
|
'rate_id' => $tax_rate_id, |
1393
|
|
|
'tax_total' => isset( $cart_taxes[ $tax_rate_id ] ) ? $cart_taxes[ $tax_rate_id ] : 0, |
1394
|
|
|
'shipping_tax_total' => isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0, |
1395
|
|
|
) ); |
1396
|
|
|
} |
1397
|
|
|
|
1398
|
|
|
// Save tax totals |
1399
|
|
|
$this->set_shipping_tax( WC_Tax::round( array_sum( $shipping_taxes ) ) ); |
1400
|
|
|
$this->set_cart_tax( WC_Tax::round( array_sum( $cart_taxes ) ) ); |
1401
|
|
|
$this->save(); |
1402
|
|
|
} |
1403
|
|
|
|
1404
|
|
|
/** |
1405
|
|
|
* Calculate totals by looking at the contents of the order. Stores the totals and returns the orders final total. |
1406
|
|
|
* |
1407
|
|
|
* @since 2.2 |
1408
|
|
|
* @param bool $and_taxes Calc taxes if true. |
1409
|
|
|
* @return float calculated grand total. |
1410
|
|
|
*/ |
1411
|
|
|
public function calculate_totals( $and_taxes = true ) { |
1412
|
|
|
$cart_subtotal = 0; |
1413
|
|
|
$cart_total = 0; |
1414
|
|
|
$fee_total = 0; |
1415
|
|
|
$cart_subtotal_tax = 0; |
1416
|
|
|
$cart_total_tax = 0; |
1417
|
|
|
|
1418
|
|
|
if ( $and_taxes && wc_tax_enabled() ) { |
1419
|
|
|
$this->calculate_taxes(); |
1420
|
|
|
} |
1421
|
|
|
|
1422
|
|
|
// line items |
1423
|
|
|
foreach ( $this->get_items() as $item ) { |
1424
|
|
|
$cart_subtotal += wc_format_decimal( $item->get_subtotal() ); |
1425
|
|
|
$cart_total += wc_format_decimal( $item->get_total() ); |
1426
|
|
|
$cart_subtotal_tax += wc_format_decimal( $item->get_subtotal_tax() ); |
1427
|
|
|
$cart_total_tax += wc_format_decimal( $item->get_total_tax() ); |
1428
|
|
|
} |
1429
|
|
|
|
1430
|
|
|
$this->calculate_shipping(); |
1431
|
|
|
|
1432
|
|
|
foreach ( $this->get_fees() as $item ) { |
1433
|
|
|
$fee_total += $item->get_total(); |
1434
|
|
|
} |
1435
|
|
|
|
1436
|
|
|
$grand_total = round( $cart_total + $fee_total + $this->get_shipping_total() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals() ); |
1437
|
|
|
|
1438
|
|
|
$this->set_discount_total( $cart_subtotal - $cart_total ); |
1439
|
|
|
$this->set_discount_tax( $cart_subtotal_tax - $cart_total_tax ); |
1440
|
|
|
$this->set_total( $grand_total ); |
1441
|
|
|
$this->save(); |
1442
|
|
|
|
1443
|
|
|
return $grand_total; |
1444
|
|
|
} |
1445
|
|
|
|
1446
|
|
|
/** |
1447
|
|
|
* Get item subtotal - this is the cost before discount. |
1448
|
|
|
* |
1449
|
|
|
* @param object $item |
1450
|
|
|
* @param bool $inc_tax (default: false). |
1451
|
|
|
* @param bool $round (default: true). |
1452
|
|
|
* @return float |
1453
|
|
|
*/ |
1454
|
|
View Code Duplication |
public function get_item_subtotal( $item, $inc_tax = false, $round = true ) { |
|
|
|
|
1455
|
|
|
$subtotal = 0; |
1456
|
|
|
|
1457
|
|
|
if ( is_callable( array( $item, 'get_subtotal' ) ) ) { |
1458
|
|
|
if ( $inc_tax ) { |
1459
|
|
|
$subtotal = ( $item->get_subtotal() + $item->get_subtotal_tax() ) / max( 1, $item->get_quantity() ); |
1460
|
|
|
} else { |
1461
|
|
|
$subtotal = ( $item->get_subtotal() / max( 1, $item->get_quantity() ) ); |
1462
|
|
|
} |
1463
|
|
|
|
1464
|
|
|
$subtotal = $round ? number_format( (float) $subtotal, wc_get_price_decimals(), '.', '' ) : $subtotal; |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
|
|
return apply_filters( 'woocommerce_order_amount_item_subtotal', $subtotal, $this, $item, $inc_tax, $round ); |
1468
|
|
|
} |
1469
|
|
|
|
1470
|
|
|
/** |
1471
|
|
|
* Get line subtotal - this is the cost before discount. |
1472
|
|
|
* |
1473
|
|
|
* @param object $item |
1474
|
|
|
* @param bool $inc_tax (default: false). |
1475
|
|
|
* @param bool $round (default: true). |
1476
|
|
|
* @return float |
1477
|
|
|
*/ |
1478
|
|
View Code Duplication |
public function get_line_subtotal( $item, $inc_tax = false, $round = true ) { |
|
|
|
|
1479
|
|
|
$subtotal = 0; |
1480
|
|
|
|
1481
|
|
|
if ( is_callable( array( $item, 'get_subtotal' ) ) ) { |
1482
|
|
|
if ( $inc_tax ) { |
1483
|
|
|
$subtotal = $item->get_subtotal() + $item->get_subtotal_tax(); |
1484
|
|
|
} else { |
1485
|
|
|
$subtotal = $item->get_subtotal(); |
1486
|
|
|
} |
1487
|
|
|
|
1488
|
|
|
$subtotal = $round ? round( $subtotal, wc_get_price_decimals() ) : $subtotal; |
1489
|
|
|
} |
1490
|
|
|
|
1491
|
|
|
return apply_filters( 'woocommerce_order_amount_line_subtotal', $subtotal, $this, $item, $inc_tax, $round ); |
1492
|
|
|
} |
1493
|
|
|
|
1494
|
|
|
/** |
1495
|
|
|
* Calculate item cost - useful for gateways. |
1496
|
|
|
* |
1497
|
|
|
* @param object $item |
1498
|
|
|
* @param bool $inc_tax (default: false). |
1499
|
|
|
* @param bool $round (default: true). |
1500
|
|
|
* @return float |
1501
|
|
|
*/ |
1502
|
|
View Code Duplication |
public function get_item_total( $item, $inc_tax = false, $round = true ) { |
|
|
|
|
1503
|
|
|
$total = 0; |
1504
|
|
|
|
1505
|
|
|
if ( is_callable( array( $item, 'get_total' ) ) ) { |
1506
|
|
|
if ( $inc_tax ) { |
1507
|
|
|
$total = ( $item->get_total() + $item->get_total_tax() ) / max( 1, $item->get_quantity() ); |
1508
|
|
|
} else { |
1509
|
|
|
$total = $item->get_total() / max( 1, $item->get_quantity() ); |
1510
|
|
|
} |
1511
|
|
|
|
1512
|
|
|
$total = $round ? round( $total, wc_get_price_decimals() ) : $total; |
1513
|
|
|
} |
1514
|
|
|
|
1515
|
|
|
return apply_filters( 'woocommerce_order_amount_item_total', $total, $this, $item, $inc_tax, $round ); |
1516
|
|
|
} |
1517
|
|
|
|
1518
|
|
|
/** |
1519
|
|
|
* Calculate line total - useful for gateways. |
1520
|
|
|
* |
1521
|
|
|
* @param object $item |
1522
|
|
|
* @param bool $inc_tax (default: false). |
1523
|
|
|
* @param bool $round (default: true). |
1524
|
|
|
* @return float |
1525
|
|
|
*/ |
1526
|
|
View Code Duplication |
public function get_line_total( $item, $inc_tax = false, $round = true ) { |
|
|
|
|
1527
|
|
|
$total = 0; |
1528
|
|
|
|
1529
|
|
|
if ( is_callable( array( $item, 'get_total' ) ) ) { |
1530
|
|
|
// Check if we need to add line tax to the line total. |
1531
|
|
|
$total = $inc_tax ? $item->get_total() + $item->get_total_tax() : $item->get_total(); |
1532
|
|
|
|
1533
|
|
|
// Check if we need to round. |
1534
|
|
|
$total = $round ? round( $total, wc_get_price_decimals() ) : $total; |
1535
|
|
|
} |
1536
|
|
|
|
1537
|
|
|
return apply_filters( 'woocommerce_order_amount_line_total', $total, $this, $item, $inc_tax, $round ); |
1538
|
|
|
} |
1539
|
|
|
|
1540
|
|
|
/** |
1541
|
|
|
* Get item tax - useful for gateways. |
1542
|
|
|
* |
1543
|
|
|
* @param mixed $item |
1544
|
|
|
* @param bool $round (default: true). |
1545
|
|
|
* @return float |
1546
|
|
|
*/ |
1547
|
|
|
public function get_item_tax( $item, $round = true ) { |
1548
|
|
|
$tax = 0; |
1549
|
|
|
|
1550
|
|
|
if ( is_callable( array( $item, 'get_total_tax' ) ) ) { |
1551
|
|
|
$tax = $item->get_total_tax() / max( 1, $item->get_quantity() ); |
1552
|
|
|
$tax = $round ? wc_round_tax_total( $tax ) : $tax; |
1553
|
|
|
} |
1554
|
|
|
|
1555
|
|
|
return apply_filters( 'woocommerce_order_amount_item_tax', $tax, $item, $round, $this ); |
1556
|
|
|
} |
1557
|
|
|
|
1558
|
|
|
/** |
1559
|
|
|
* Get line tax - useful for gateways. |
1560
|
|
|
* |
1561
|
|
|
* @param mixed $item |
1562
|
|
|
* @return float |
1563
|
|
|
*/ |
1564
|
|
|
public function get_line_tax( $item ) { |
1565
|
|
|
return apply_filters( 'woocommerce_order_amount_line_tax', is_callable( array( $item, 'get_total_tax' ) ) ? wc_round_tax_total( $item->get_total_tax() ) : 0, $item, $this ); |
1566
|
|
|
} |
1567
|
|
|
|
1568
|
|
|
/** |
1569
|
|
|
* Gets line subtotal - formatted for display. |
1570
|
|
|
* |
1571
|
|
|
* @param array $item |
1572
|
|
|
* @param string $tax_display |
1573
|
|
|
* @return string |
1574
|
|
|
*/ |
1575
|
|
|
public function get_formatted_line_subtotal( $item, $tax_display = '' ) { |
1576
|
|
|
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); |
1577
|
|
|
|
1578
|
|
|
if ( 'excl' == $tax_display ) { |
1579
|
|
|
$ex_tax_label = $this->get_prices_include_tax() ? 1 : 0; |
1580
|
|
|
|
1581
|
|
|
$subtotal = wc_price( $this->get_line_subtotal( $item ), array( 'ex_tax_label' => $ex_tax_label, 'currency' => $this->get_currency() ) ); |
|
|
|
|
1582
|
|
|
} else { |
1583
|
|
|
$subtotal = wc_price( $this->get_line_subtotal( $item, true ), array('currency' => $this->get_currency()) ); |
|
|
|
|
1584
|
|
|
} |
1585
|
|
|
|
1586
|
|
|
return apply_filters( 'woocommerce_order_formatted_line_subtotal', $subtotal, $item, $this ); |
1587
|
|
|
} |
1588
|
|
|
|
1589
|
|
|
/** |
1590
|
|
|
* Gets order total - formatted for display. |
1591
|
|
|
* @return string |
1592
|
|
|
*/ |
1593
|
|
|
public function get_formatted_order_total() { |
1594
|
|
|
$formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) ); |
1595
|
|
|
return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this ); |
1596
|
|
|
} |
1597
|
|
|
|
1598
|
|
|
/** |
1599
|
|
|
* Gets subtotal - subtotal is shown before discounts, but with localised taxes. |
1600
|
|
|
* |
1601
|
|
|
* @param bool $compound (default: false). |
1602
|
|
|
* @param string $tax_display (default: the tax_display_cart value). |
1603
|
|
|
* @return string |
1604
|
|
|
*/ |
1605
|
|
|
public function get_subtotal_to_display( $compound = false, $tax_display = '' ) { |
1606
|
|
|
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); |
1607
|
|
|
$subtotal = 0; |
1608
|
|
|
|
1609
|
|
|
if ( ! $compound ) { |
1610
|
|
|
foreach ( $this->get_items() as $item ) { |
1611
|
|
|
$subtotal += $item->get_subtotal(); |
1612
|
|
|
|
1613
|
|
|
if ( 'incl' === $tax_display ) { |
1614
|
|
|
$subtotal += $item->get_subtotal_tax(); |
1615
|
|
|
} |
1616
|
|
|
} |
1617
|
|
|
|
1618
|
|
|
$subtotal = wc_price( $subtotal, array( 'currency' => $this->get_currency() ) ); |
1619
|
|
|
|
1620
|
|
|
if ( 'excl' === $tax_display && $this->get_prices_include_tax() ) { |
1621
|
|
|
$subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>'; |
1622
|
|
|
} |
1623
|
|
|
|
1624
|
|
|
} else { |
1625
|
|
|
if ( 'incl' === $tax_display ) { |
1626
|
|
|
return ''; |
1627
|
|
|
} |
1628
|
|
|
|
1629
|
|
|
foreach ( $this->get_items() as $item ) { |
1630
|
|
|
$subtotal += $item->get_subtotal(); |
1631
|
|
|
} |
1632
|
|
|
|
1633
|
|
|
// Add Shipping Costs. |
1634
|
|
|
$subtotal += $this->get_shipping_total(); |
1635
|
|
|
|
1636
|
|
|
// Remove non-compound taxes. |
1637
|
|
|
foreach ( $this->get_taxes() as $tax ) { |
1638
|
|
|
if ( $this->is_compound() ) { |
|
|
|
|
1639
|
|
|
continue; |
1640
|
|
|
} |
1641
|
|
|
$subtotal = $subtotal + $tax->get_tax_total() + $tax->get_shipping_tax_total(); |
1642
|
|
|
} |
1643
|
|
|
|
1644
|
|
|
// Remove discounts. |
1645
|
|
|
$subtotal = $subtotal - $this->get_total_discount(); |
1646
|
|
|
$subtotal = wc_price( $subtotal, array( 'currency' => $this->get_currency() ) ); |
1647
|
|
|
} |
1648
|
|
|
|
1649
|
|
|
return apply_filters( 'woocommerce_order_subtotal_to_display', $subtotal, $compound, $this ); |
1650
|
|
|
} |
1651
|
|
|
|
1652
|
|
|
/** |
1653
|
|
|
* Gets shipping (formatted). |
1654
|
|
|
* |
1655
|
|
|
* @return string |
1656
|
|
|
*/ |
1657
|
|
|
public function get_shipping_to_display( $tax_display = '' ) { |
1658
|
|
|
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); |
1659
|
|
|
|
1660
|
|
|
if ( $this->get_shipping_total() != 0 ) { |
1661
|
|
|
|
1662
|
|
|
if ( $tax_display == 'excl' ) { |
1663
|
|
|
|
1664
|
|
|
// Show shipping excluding tax. |
1665
|
|
|
$shipping = wc_price( $this->get_shipping_total(), array('currency' => $this->get_currency()) ); |
1666
|
|
|
|
1667
|
|
View Code Duplication |
if ( $this->get_shipping_tax() != 0 && $this->get_prices_include_tax() ) { |
|
|
|
|
1668
|
|
|
$shipping .= apply_filters( 'woocommerce_order_shipping_to_display_tax_label', ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>', $this, $tax_display ); |
1669
|
|
|
} |
1670
|
|
|
|
1671
|
|
|
} else { |
1672
|
|
|
|
1673
|
|
|
// Show shipping including tax. |
1674
|
|
|
$shipping = wc_price( $this->get_shipping_total() + $this->get_shipping_tax(), array('currency' => $this->get_currency()) ); |
1675
|
|
|
|
1676
|
|
View Code Duplication |
if ( $this->get_shipping_tax() != 0 && ! $this->get_prices_include_tax() ) { |
|
|
|
|
1677
|
|
|
$shipping .= apply_filters( 'woocommerce_order_shipping_to_display_tax_label', ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>', $this, $tax_display ); |
1678
|
|
|
} |
1679
|
|
|
|
1680
|
|
|
} |
1681
|
|
|
|
1682
|
|
|
$shipping .= apply_filters( 'woocommerce_order_shipping_to_display_shipped_via', ' <small class="shipped_via">' . sprintf( __( 'via %s', 'woocommerce' ), $this->get_shipping_method() ) . '</small>', $this ); |
1683
|
|
|
|
1684
|
|
|
} elseif ( $this->get_shipping_method() ) { |
1685
|
|
|
$shipping = $this->get_shipping_method(); |
1686
|
|
|
} else { |
1687
|
|
|
$shipping = __( 'Free!', 'woocommerce' ); |
1688
|
|
|
} |
1689
|
|
|
|
1690
|
|
|
return apply_filters( 'woocommerce_order_shipping_to_display', $shipping, $this ); |
1691
|
|
|
} |
1692
|
|
|
|
1693
|
|
|
/** |
1694
|
|
|
* Get the discount amount (formatted). |
1695
|
|
|
* @since 2.3.0 |
1696
|
|
|
* @return string |
1697
|
|
|
*/ |
1698
|
|
|
public function get_discount_to_display( $tax_display = '' ) { |
1699
|
|
|
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); |
1700
|
|
|
return apply_filters( 'woocommerce_order_discount_to_display', wc_price( $this->get_total_discount( 'excl' === $tax_display && 'excl' === get_option( 'woocommerce_tax_display_cart' ) ), array( 'currency' => $this->get_currency() ) ), $this ); |
1701
|
|
|
} |
1702
|
|
|
|
1703
|
|
|
/** |
1704
|
|
|
* Get totals for display on pages and in emails. |
1705
|
|
|
* |
1706
|
|
|
* @param mixed $tax_display |
1707
|
|
|
* @return array |
1708
|
|
|
*/ |
1709
|
|
|
public function get_order_item_totals( $tax_display = '' ) { |
1710
|
|
|
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); |
1711
|
|
|
$total_rows = array(); |
1712
|
|
|
|
1713
|
|
|
if ( $subtotal = $this->get_subtotal_to_display( false, $tax_display ) ) { |
1714
|
|
|
$total_rows['cart_subtotal'] = array( |
1715
|
|
|
'label' => __( 'Subtotal:', 'woocommerce' ), |
1716
|
|
|
'value' => $subtotal, |
1717
|
|
|
); |
1718
|
|
|
} |
1719
|
|
|
|
1720
|
|
|
if ( $this->get_total_discount() > 0 ) { |
1721
|
|
|
$total_rows['discount'] = array( |
1722
|
|
|
'label' => __( 'Discount:', 'woocommerce' ), |
1723
|
|
|
'value' => '-' . $this->get_discount_to_display( $tax_display ), |
1724
|
|
|
); |
1725
|
|
|
} |
1726
|
|
|
|
1727
|
|
|
if ( $this->get_shipping_method() ) { |
1728
|
|
|
$total_rows['shipping'] = array( |
1729
|
|
|
'label' => __( 'Shipping:', 'woocommerce' ), |
1730
|
|
|
'value' => $this->get_shipping_to_display( $tax_display ), |
1731
|
|
|
); |
1732
|
|
|
} |
1733
|
|
|
|
1734
|
|
|
if ( $fees = $this->get_fees() ) { |
1735
|
|
|
foreach ( $fees as $id => $fee ) { |
1736
|
|
|
if ( apply_filters( 'woocommerce_get_order_item_totals_excl_free_fees', empty( $fee['line_total'] ) && empty( $fee['line_tax'] ), $id ) ) { |
1737
|
|
|
continue; |
1738
|
|
|
} |
1739
|
|
|
$total_rows[ 'fee_' . $fee->get_id() ] = array( |
1740
|
|
|
'label' => $fee->get_name() . ':', |
1741
|
|
|
'value' => wc_price( 'excl' === $tax_display ? $fee->get_total() : $fee->get_total() + $fee->get_total_tax(), array('currency' => $this->get_currency()) ) |
1742
|
|
|
); |
1743
|
|
|
} |
1744
|
|
|
} |
1745
|
|
|
|
1746
|
|
|
// Tax for tax exclusive prices. |
1747
|
|
|
if ( 'excl' === $tax_display ) { |
1748
|
|
|
|
1749
|
|
|
if ( get_option( 'woocommerce_tax_total_display' ) == 'itemized' ) { |
1750
|
|
|
|
1751
|
|
|
foreach ( $this->get_tax_totals() as $code => $tax ) { |
1752
|
|
|
|
1753
|
|
|
$total_rows[ sanitize_title( $code ) ] = array( |
1754
|
|
|
'label' => $tax->label . ':', |
1755
|
|
|
'value' => $tax->formatted_amount, |
1756
|
|
|
); |
1757
|
|
|
} |
1758
|
|
|
|
1759
|
|
|
} else { |
1760
|
|
|
|
1761
|
|
|
$total_rows['tax'] = array( |
1762
|
|
|
'label' => WC()->countries->tax_or_vat() . ':', |
1763
|
|
|
'value' => wc_price( $this->get_total_tax(), array( 'currency' => $this->get_currency() ) ), |
1764
|
|
|
); |
1765
|
|
|
} |
1766
|
|
|
} |
1767
|
|
|
|
1768
|
|
|
if ( $this->get_total() > 0 && $this->get_payment_method_title() ) { |
|
|
|
|
1769
|
|
|
$total_rows['payment_method'] = array( |
1770
|
|
|
'label' => __( 'Payment Method:', 'woocommerce' ), |
1771
|
|
|
'value' => $this->get_payment_method_title(), |
|
|
|
|
1772
|
|
|
); |
1773
|
|
|
} |
1774
|
|
|
|
1775
|
|
|
if ( $refunds = $this->get_refunds() ) { |
|
|
|
|
1776
|
|
|
foreach ( $refunds as $id => $refund ) { |
1777
|
|
|
$total_rows[ 'refund_' . $id ] = array( |
1778
|
|
|
'label' => $refund->get_refund_reason() ? $refund->get_refund_reason() : __( 'Refund', 'woocommerce' ) . ':', |
1779
|
|
|
'value' => wc_price( '-' . $refund->get_refund_amount(), array( 'currency' => $this->get_currency() ) ), |
1780
|
|
|
); |
1781
|
|
|
} |
1782
|
|
|
} |
1783
|
|
|
|
1784
|
|
|
$total_rows['order_total'] = array( |
1785
|
|
|
'label' => __( 'Total:', 'woocommerce' ), |
1786
|
|
|
'value' => $this->get_formatted_order_total( $tax_display ), |
|
|
|
|
1787
|
|
|
); |
1788
|
|
|
|
1789
|
|
|
return apply_filters( 'woocommerce_get_order_item_totals', $total_rows, $this ); |
1790
|
|
|
} |
1791
|
|
|
|
1792
|
|
|
/* |
1793
|
|
|
|-------------------------------------------------------------------------- |
1794
|
|
|
| Conditionals |
1795
|
|
|
|-------------------------------------------------------------------------- |
1796
|
|
|
| |
1797
|
|
|
| Checks if a condition is true or false. |
1798
|
|
|
| |
1799
|
|
|
*/ |
1800
|
|
|
|
1801
|
|
|
/** |
1802
|
|
|
* Checks the order status against a passed in status. |
1803
|
|
|
* |
1804
|
|
|
* @return bool |
1805
|
|
|
*/ |
1806
|
|
|
public function has_status( $status ) { |
1807
|
|
|
return apply_filters( 'woocommerce_order_has_status', ( is_array( $status ) && in_array( $this->get_status(), $status ) ) || $this->get_status() === $status ? true : false, $this, $status ); |
1808
|
|
|
} |
1809
|
|
|
|
1810
|
|
|
/** |
1811
|
|
|
* Check whether this order has a specific shipping method or not. |
1812
|
|
|
* |
1813
|
|
|
* @param string $method_id |
1814
|
|
|
* @return bool |
1815
|
|
|
*/ |
1816
|
|
|
public function has_shipping_method( $method_id ) { |
1817
|
|
|
foreach ( $this->get_shipping_methods() as $shipping_method ) { |
1818
|
|
|
if ( $shipping_method->get_method_id() === $method_id ) { |
1819
|
|
|
return true; |
1820
|
|
|
} |
1821
|
|
|
} |
1822
|
|
|
return false; |
1823
|
|
|
} |
1824
|
|
|
|
1825
|
|
|
/** |
1826
|
|
|
* Check if an order key is valid. |
1827
|
|
|
* |
1828
|
|
|
* @param mixed $key |
1829
|
|
|
* @return bool |
1830
|
|
|
*/ |
1831
|
|
|
public function key_is_valid( $key ) { |
1832
|
|
|
return $key === $this->get_order_key(); |
1833
|
|
|
} |
1834
|
|
|
|
1835
|
|
|
/** |
1836
|
|
|
* Returns true if the order contains a free product. |
1837
|
|
|
* @since 2.5.0 |
1838
|
|
|
* @return bool |
1839
|
|
|
*/ |
1840
|
|
|
public function has_free_item() { |
1841
|
|
|
foreach ( $this->get_items() as $item ) { |
1842
|
|
|
if ( ! $item->get_total() ) { |
1843
|
|
|
return true; |
1844
|
|
|
} |
1845
|
|
|
} |
1846
|
|
|
return false; |
1847
|
|
|
} |
1848
|
|
|
} |
1849
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.