1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
4
|
|
|
exit; // Exit if accessed directly |
5
|
|
|
} |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Order |
9
|
|
|
* |
10
|
|
|
* @class WC_Order |
11
|
|
|
* @version 2.2.0 |
12
|
|
|
* @package WooCommerce/Classes |
13
|
|
|
* @category Class |
14
|
|
|
* @author WooThemes |
15
|
|
|
*/ |
16
|
|
|
class WC_Order extends WC_Abstract_Order { |
17
|
|
|
|
18
|
|
|
/** @public string Order type */ |
19
|
|
|
public $order_type = 'simple'; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Gets order total - formatted for display. |
23
|
|
|
* |
24
|
|
|
* @return string |
25
|
|
|
*/ |
26
|
|
|
public function get_formatted_order_total( $tax_display = '', $display_refunded = true ) { |
27
|
|
|
$formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_order_currency() ) ); |
28
|
|
|
$order_total = $this->get_total(); |
29
|
|
|
$total_refunded = $this->get_total_refunded(); |
30
|
|
|
$tax_string = ''; |
31
|
|
|
|
32
|
|
|
// Tax for inclusive prices |
33
|
|
|
if ( wc_tax_enabled() && 'incl' == $tax_display ) { |
34
|
|
|
$tax_string_array = array(); |
35
|
|
|
|
36
|
|
|
if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) { |
37
|
|
|
foreach ( $this->get_tax_totals() as $code => $tax ) { |
38
|
|
|
$tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_order_currency() ) ) : $tax->formatted_amount; |
39
|
|
|
$tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); |
40
|
|
|
} |
41
|
|
|
} else { |
42
|
|
|
$tax_amount = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax(); |
43
|
|
|
$tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_order_currency() ) ), WC()->countries->tax_or_vat() ); |
44
|
|
|
} |
45
|
|
|
if ( ! empty( $tax_string_array ) ) { |
46
|
|
|
$tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); |
47
|
|
|
} |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
if ( $total_refunded && $display_refunded ) { |
51
|
|
|
$formatted_total = '<del>' . strip_tags( $formatted_total ) . '</del> <ins>' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_order_currency() ) ) . $tax_string . '</ins>'; |
52
|
|
|
} else { |
53
|
|
|
$formatted_total .= $tax_string; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this ); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Get order refunds. |
61
|
|
|
* @since 2.2 |
62
|
|
|
* @return array of WC_Order_Refund objects |
63
|
|
|
*/ |
64
|
|
|
public function get_refunds() { |
65
|
|
|
if ( empty( $this->refunds ) && ! is_array( $this->refunds ) ) { |
66
|
|
|
$this->refunds = wc_get_orders( array( |
67
|
|
|
'type' => 'shop_order_refund', |
68
|
|
|
'parent' => $this->id, |
69
|
|
|
'limit' => -1, |
70
|
|
|
) ); |
71
|
|
|
} |
72
|
|
|
return $this->refunds; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Get amount already refunded. |
77
|
|
|
* |
78
|
|
|
* @since 2.2 |
79
|
|
|
* @return string |
80
|
|
|
*/ |
81
|
|
View Code Duplication |
public function get_total_refunded() { |
|
|
|
|
82
|
|
|
global $wpdb; |
83
|
|
|
|
84
|
|
|
$total = $wpdb->get_var( $wpdb->prepare( " |
85
|
|
|
SELECT SUM( postmeta.meta_value ) |
86
|
|
|
FROM $wpdb->postmeta AS postmeta |
87
|
|
|
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) |
88
|
|
|
WHERE postmeta.meta_key = '_refund_amount' |
89
|
|
|
AND postmeta.post_id = posts.ID |
90
|
|
|
", $this->id ) ); |
91
|
|
|
|
92
|
|
|
return $total; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Get the total tax refunded. |
97
|
|
|
* |
98
|
|
|
* @since 2.3 |
99
|
|
|
* @return float |
100
|
|
|
*/ |
101
|
|
View Code Duplication |
public function get_total_tax_refunded() { |
|
|
|
|
102
|
|
|
global $wpdb; |
103
|
|
|
|
104
|
|
|
$total = $wpdb->get_var( $wpdb->prepare( " |
105
|
|
|
SELECT SUM( order_itemmeta.meta_value ) |
106
|
|
|
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta |
107
|
|
|
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) |
108
|
|
|
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' ) |
109
|
|
|
WHERE order_itemmeta.order_item_id = order_items.order_item_id |
110
|
|
|
AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount') |
111
|
|
|
", $this->id ) ); |
112
|
|
|
|
113
|
|
|
return abs( $total ); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get the total shipping refunded. |
118
|
|
|
* |
119
|
|
|
* @since 2.4 |
120
|
|
|
* @return float |
121
|
|
|
*/ |
122
|
|
View Code Duplication |
public function get_total_shipping_refunded() { |
|
|
|
|
123
|
|
|
global $wpdb; |
124
|
|
|
|
125
|
|
|
$total = $wpdb->get_var( $wpdb->prepare( " |
126
|
|
|
SELECT SUM( order_itemmeta.meta_value ) |
127
|
|
|
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta |
128
|
|
|
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) |
129
|
|
|
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' ) |
130
|
|
|
WHERE order_itemmeta.order_item_id = order_items.order_item_id |
131
|
|
|
AND order_itemmeta.meta_key IN ('cost') |
132
|
|
|
", $this->id ) ); |
133
|
|
|
|
134
|
|
|
return abs( $total ); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Gets the count of order items of a certain type that have been refunded. |
139
|
|
|
* @since 2.4.0 |
140
|
|
|
* @param string $item_type |
141
|
|
|
* @return string |
142
|
|
|
*/ |
143
|
|
View Code Duplication |
public function get_item_count_refunded( $item_type = '' ) { |
|
|
|
|
144
|
|
|
if ( empty( $item_type ) ) { |
145
|
|
|
$item_type = array( 'line_item' ); |
146
|
|
|
} |
147
|
|
|
if ( ! is_array( $item_type ) ) { |
148
|
|
|
$item_type = array( $item_type ); |
149
|
|
|
} |
150
|
|
|
$count = 0; |
151
|
|
|
|
152
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
153
|
|
|
foreach ( $refund->get_items( $item_type ) as $refunded_item ) { |
154
|
|
|
$count += empty( $refunded_item['qty'] ) ? 0 : $refunded_item['qty']; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
return apply_filters( 'woocommerce_get_item_count_refunded', $count, $item_type, $this ); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Get the total number of items refunded. |
163
|
|
|
* |
164
|
|
|
* @since 2.4.0 |
165
|
|
|
* @param string $item_type type of the item we're checking, if not a line_item |
166
|
|
|
* @return integer |
167
|
|
|
*/ |
168
|
|
|
public function get_total_qty_refunded( $item_type = 'line_item' ) { |
169
|
|
|
$qty = 0; |
170
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
171
|
|
|
foreach ( $refund->get_items( $item_type ) as $refunded_item ) { |
172
|
|
|
$qty += $refunded_item['qty']; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
return $qty; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Get the refunded amount for a line item. |
180
|
|
|
* |
181
|
|
|
* @param int $item_id ID of the item we're checking |
182
|
|
|
* @param string $item_type type of the item we're checking, if not a line_item |
183
|
|
|
* @return integer |
184
|
|
|
*/ |
185
|
|
|
public function get_qty_refunded_for_item( $item_id, $item_type = 'line_item' ) { |
186
|
|
|
$qty = 0; |
187
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
188
|
|
|
foreach ( $refund->get_items( $item_type ) as $refunded_item ) { |
189
|
|
|
if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { |
190
|
|
|
$qty += $refunded_item['qty']; |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
return $qty; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Get the refunded amount for a line item. |
199
|
|
|
* |
200
|
|
|
* @param int $item_id ID of the item we're checking |
201
|
|
|
* @param string $item_type type of the item we're checking, if not a line_item |
202
|
|
|
* @return integer |
203
|
|
|
*/ |
204
|
|
|
public function get_total_refunded_for_item( $item_id, $item_type = 'line_item' ) { |
205
|
|
|
$total = 0; |
206
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
207
|
|
|
foreach ( $refund->get_items( $item_type ) as $refunded_item ) { |
208
|
|
|
if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { |
209
|
|
|
switch ( $item_type ) { |
210
|
|
|
case 'shipping' : |
211
|
|
|
$total += $refunded_item['cost']; |
212
|
|
|
break; |
213
|
|
|
default : |
214
|
|
|
$total += $refunded_item['line_total']; |
215
|
|
|
break; |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
return $total * -1; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Get the refunded amount for a line item. |
225
|
|
|
* |
226
|
|
|
* @param int $item_id ID of the item we're checking |
227
|
|
|
* @param int $tax_id ID of the tax we're checking |
228
|
|
|
* @param string $item_type type of the item we're checking, if not a line_item |
229
|
|
|
* @return double |
230
|
|
|
*/ |
231
|
|
|
public function get_tax_refunded_for_item( $item_id, $tax_id, $item_type = 'line_item' ) { |
232
|
|
|
$total = 0; |
233
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
234
|
|
|
foreach ( $refund->get_items( $item_type ) as $refunded_item ) { |
235
|
|
|
if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { |
236
|
|
|
switch ( $item_type ) { |
237
|
|
View Code Duplication |
case 'shipping' : |
|
|
|
|
238
|
|
|
$tax_data = maybe_unserialize( $refunded_item['taxes'] ); |
239
|
|
|
if ( isset( $tax_data[ $tax_id ] ) ) { |
240
|
|
|
$total += $tax_data[ $tax_id ]; |
241
|
|
|
} |
242
|
|
|
break; |
243
|
|
View Code Duplication |
default : |
|
|
|
|
244
|
|
|
$tax_data = maybe_unserialize( $refunded_item['line_tax_data'] ); |
245
|
|
|
if ( isset( $tax_data['total'][ $tax_id ] ) ) { |
246
|
|
|
$total += $tax_data['total'][ $tax_id ]; |
247
|
|
|
} |
248
|
|
|
break; |
249
|
|
|
} |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
return wc_round_tax_total( $total ) * -1; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Get total tax refunded by rate ID. |
258
|
|
|
* |
259
|
|
|
* @param int $rate_id |
260
|
|
|
* |
261
|
|
|
* @return float |
262
|
|
|
*/ |
263
|
|
|
public function get_total_tax_refunded_by_rate_id( $rate_id ) { |
264
|
|
|
$total = 0; |
265
|
|
|
foreach ( $this->get_refunds() as $refund ) { |
266
|
|
|
foreach ( $refund->get_items( 'tax' ) as $refunded_item ) { |
267
|
|
|
if ( isset( $refunded_item['rate_id'] ) && $refunded_item['rate_id'] == $rate_id ) { |
268
|
|
|
$total += abs( $refunded_item['tax_amount'] ) + abs( $refunded_item['shipping_tax_amount'] ); |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
return $total; |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* How much money is left to refund? |
278
|
|
|
* @return string |
279
|
|
|
*/ |
280
|
|
|
public function get_remaining_refund_amount() { |
281
|
|
|
return wc_format_decimal( $this->get_total() - $this->get_total_refunded(), wc_get_price_decimals() ); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* How many items are left to refund? |
286
|
|
|
* @return int |
287
|
|
|
*/ |
288
|
|
|
public function get_remaining_refund_items() { |
289
|
|
|
return absint( $this->get_item_count() - $this->get_item_count_refunded() ); |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
|
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.