Completed
Pull Request — master (#11889)
by Mike
12:12
created

WC_Cart_Totals   D

Complexity

Total Complexity 101

Size/Duplication

Total Lines 757
Duplicated Lines 2.38 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 18
loc 757
rs 4.4444
c 0
b 0
f 0
wmc 101
lcom 1
cbo 3

56 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A get_default_totals() 0 19 1
A get_default_item_props() 0 12 1
A get_default_coupon_props() 0 7 1
A get_default_fee_props() 0 6 1
A get_default_shipping_props() 0 7 1
A format_item_totals() 0 5 1
B calculate_item_totals() 0 27 5
C calculate_item_subtotals() 0 22 7
B calculate_fee_totals() 0 12 5
A calculate_totals() 0 20 2
B sort_items_callback() 0 8 5
A calc_discounts_sequentially() 0 3 1
A get_undiscounted_price() 0 7 2
C get_discounted_price() 0 57 11
A adjust_non_base_location_price() 0 15 2
A set_calculate_tax() 0 3 1
A set_totals() 0 4 1
A set_items() 0 13 3
A set_coupons() 0 7 2
A set_fees() 0 9 2
A set_shipping() 0 13 3
A set_taxes() 0 3 1
A set_tax_total() 0 3 1
A set_shipping_total() 0 3 1
A set_shipping_tax_total() 0 3 1
A set_item_totals() 0 3 1
A set_items_subtotal() 0 3 1
A set_items_subtotal_tax() 0 3 1
A set_items_total() 0 3 1
A set_items_total_tax() 0 3 1
A set_coupon_totals() 0 3 1
A set_coupon_tax_totals() 0 3 1
A set_coupon_counts() 0 3 1
A set_fees_total() 0 3 1
A set_fees_total_tax() 0 3 1
A set_total() 0 3 1
A get_totals() 0 3 1
A get_taxes() 0 3 1
A get_tax_total() 0 3 1
A get_shipping_total() 0 3 1
A get_shipping_tax_total() 0 3 1
A get_items_subtotal() 0 3 1
A get_items_subtotal_tax() 0 3 1
A get_items_total() 0 3 1
A get_items_total_tax() 0 3 1
A get_coupon_totals() 0 3 1
A get_coupon_tax_totals() 0 3 1
A get_coupon_counts() 0 3 1
A get_fees_total() 0 3 1
A get_fees_total_tax() 0 3 1
A get_total() 0 3 1
A get_item_totals() 0 3 1
A get_calculate_tax() 0 3 2
A get_item_tax_rates() 0 4 2
C get_merged_taxes() 18 25 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WC_Cart_Totals often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WC_Cart_Totals, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit; // Exit if accessed directly
5
}
6
7
/**
8
 * Handles cart totals calculations.
9
 *
10
 * @class 		WC_Cart_Totals
11
 * @version		2.7.0
12
 * @package		WooCommerce/Classes
13
 * @category	Class
14
 * @author 		WooThemes
15
 */
16
class WC_Cart_Totals {
17
18
	/**
19
	 * Should tax be calculated?
20
	 * @var boolean
21
	 */
22
	private $calculate_tax  = true;
23
24
	/**
25
	 * Stores totals.
26
	 * @var array
27
	 */
28
	private $totals         = null;
29
30
	/**
31
	 * Coupons to calculate.
32
	 * @var array
33
	 */
34
	private $coupons        = array();
35
36
	/**
37
	 * Line items to calculate.
38
	 * @var array
39
	 */
40
	private $items          = array();
41
42
	/**
43
	 * Fees to calculate.
44
	 * @var array
45
	 */
46
	private $fees           = array();
47
48
	/**
49
	 * Shipping to calculate.
50
	 * @var array
51
	 */
52
	private $shipping_lines = array();
53
54
	/**
55
	 * Constructor.
56
	 */
57
	public function __construct() {
58
		$this->set_totals( $this->get_default_totals() );
59
	}
60
61
	/*
62
	|--------------------------------------------------------------------------
63
	| Default item props.
64
	|--------------------------------------------------------------------------
65
	*/
66
67
	/**
68
	 * Get default totals.
69
	 * @return array
70
	 */
71
	private function get_default_totals() {
72
		return array(
73
			'fees_total'         => 0,
74
			'fees_total_tax'     => 0,
75
			'items_subtotal'     => 0,
76
			'items_subtotal_tax' => 0,
77
			'items_total'        => 0,
78
			'items_total_tax'    => 0,
79
			'item_totals'        => array(),
80
			'coupon_counts'      => array(),
81
			'coupon_totals'      => array(),
82
			'coupon_tax_totals'  => array(),
83
			'total'              => 0,
84
			'taxes'              => array(),
85
			'tax_total'          => 0,
86
			'shipping_total'     => 0,
87
			'shipping_tax_total' => 0,
88
		);
89
	}
90
91
	/**
92
	 * Get default blank set of props used per item.
93
	 * @return array
94
	 */
95
	private function get_default_item_props() {
96
		return (object) array(
97
			'price_includes_tax' => wc_prices_include_tax(),
98
			'subtotal'           => 0,
99
			'subtotal_tax'       => 0,
100
			'subtotal_taxes'     => array(),
101
			'total'              => 0,
102
			'total_tax'          => 0,
103
			'taxes'              => array(),
104
			'discounted_price'   => 0,
105
		);
106
	}
107
108
	/**
109
	 * Get default blank set of props used per coupon.
110
	 * @return array
111
	 */
112
	private function get_default_coupon_props() {
113
		return (object) array(
114
			'count'     => 0,
115
			'total'     => 0,
116
			'total_tax' => 0,
117
		);
118
	}
119
120
	/**
121
	 * Get default blank set of props used per fee.
122
	 * @return array
123
	 */
124
	private function get_default_fee_props() {
125
		return (object) array(
126
			'total_tax' => 0,
127
			'taxes'     => array(),
128
		);
129
	}
130
131
	/**
132
	 * Get default blank set of props used per shipping row.
133
	 * @return array
134
	 */
135
	private function get_default_shipping_props() {
136
		return (object) array(
137
			'total'     => 0,
138
			'total_tax' => 0,
139
			'taxes'     => array(),
140
		);
141
	}
142
143
	/*
144
	|--------------------------------------------------------------------------
145
	| Calculation methods.
146
	|--------------------------------------------------------------------------
147
	*/
148
149
	/**
150
	 * Removes data we don't want to expose in the item totals.
151
	 * @param object $item
152
	 * @return array
153
	 */
154
	private function format_item_totals( $item ) {
155
		unset( $item->product );
156
		unset( $item->values );
157
		return $item;
158
	}
159
160
	/**
161
	 * Totals are costs after discounts.
162
	 */
163
	public function calculate_item_totals() {
164
		$this->calculate_item_subtotals();
165
		uasort( $this->items, array( $this, 'sort_items_callback' ) );
166
167
		foreach ( $this->items as $item ) {
168
			$item->discounted_price = $this->get_discounted_price( $item );
169
			$item->total            = $item->discounted_price * $item->quantity;
170
			$item->total_tax        = 0;
171
172
			if ( $this->get_calculate_tax() && $item->product->is_taxable() ) {
173
				$item->taxes     = WC_Tax::calc_tax( $item->total, $this->get_item_tax_rates( $item ), $item->price_includes_tax );
174
				$item->total_tax = array_sum( $item->taxes );
175
176
				if ( $item->price_includes_tax ) {
177
					$item->total = $item->total - $item->total_tax;
178
				} else {
179
					$item->total = $item->total;
180
				}
181
			}
182
		}
183
		$this->set_items_total( array_sum( array_values( wp_list_pluck( $this->items, 'total' ) ) ) );
184
		$this->set_items_total_tax( array_sum( array_values( wp_list_pluck( $this->items, 'total_tax' ) ) ) );
185
		$this->set_coupon_totals( wp_list_pluck( $this->coupons, 'total' ) );
186
		$this->set_coupon_tax_totals( wp_list_pluck( $this->coupons, 'total_tax' ) );
187
		$this->set_coupon_counts( wp_list_pluck( $this->coupons, 'count' ) );
188
		$this->set_item_totals( array_map( array( $this, 'format_item_totals' ), $this->items ) );
189
	}
190
191
	/**
192
	 * Subtotals are costs before discounts.
193
	 *
194
	 * To prevent rounding issues we need to work with the inclusive price where possible.
195
	 * otherwise we'll see errors such as when working with a 9.99 inc price, 20% VAT which would.
196
	 * be 8.325 leading to totals being 1p off.
197
	 *
198
	 * Pre tax coupons come off the price the customer thinks they are paying - tax is calculated.
199
	 * afterwards.
200
	 *
201
	 * e.g. $100 bike with $10 coupon = customer pays $90 and tax worked backwards from that.
202
	 */
203
	private function calculate_item_subtotals() {
204
		foreach ( $this->items as $item ) {
205
			$item->subtotal     = $item->price * $item->quantity;
206
			$item->subtotal_tax = 0;
207
208
			if ( $item->price_includes_tax && apply_filters( 'woocommerce_adjust_non_base_location_prices', false ) ) {
209
				$item           = $this->adjust_non_base_location_price( $item );
210
				$item->subtotal = $item->price * $item->quantity;
211
			}
212
213
			if ( $this->get_calculate_tax() && $item->product->is_taxable() ) {
214
				$item->subtotal_taxes = WC_Tax::calc_tax( $item->subtotal, $this->get_item_tax_rates( $item ), $item->price_includes_tax );
215
				$item->subtotal_tax      = array_sum( $item->subtotal_taxes );
216
217
				if ( $item->price_includes_tax ) {
218
					$item->subtotal = $item->subtotal - $item->subtotal_tax;
219
				}
220
			}
221
		}
222
		$this->set_items_subtotal( array_sum( array_values( wp_list_pluck( $this->items, 'subtotal' ) ) ) );
223
		$this->set_items_subtotal_tax( array_sum( array_values( wp_list_pluck( $this->items, 'subtotal_tax' ) ) ) );
224
	}
225
226
	/**
227
	 * Calculate any fees taxes.
228
	 */
229
	private function calculate_fee_totals() {
230
		if ( ! empty( $this->fees ) ) {
231
			foreach ( $this->fees as $fee_key => $fee ) {
232
				if ( $this->get_calculate_tax() && $fee->taxable ) {
233
					$fee->taxes     = WC_Tax::calc_tax( $fee->total, $tax_rates, false );
234
					$fee->total_tax = array_sum( $fee->taxes );
235
				}
236
			}
237
		}
238
		$this->set_fees_total( array_sum( array_values( wp_list_pluck( $this->fees, 'total' ) ) ) );
239
		$this->set_fees_total_tax( array_sum( array_values( wp_list_pluck( $this->fees, 'total_tax' ) ) ) );
240
	}
241
242
	/**
243
	 * Main cart totals.
244
	 */
245
	public function calculate_totals() {
246
		$this->calculate_fee_totals();
247
		$this->set_shipping_total( array_sum( array_values( wp_list_pluck( $this->shipping_lines, 'total' ) ) ) );
248
		$this->set_taxes( $this->get_merged_taxes() );
249
250
		// Total up/round taxes and shipping taxes
251
		if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) {
252
			$this->set_tax_total( WC_Tax::get_tax_total( wc_list_pluck( $this->get_taxes(), 'get_tax_total' ) ) );
253
			$this->set_shipping_tax_total( WC_Tax::get_tax_total( wc_list_pluck( $this->get_taxes(), 'get_shipping_tax_total' ) ) );
254
		} else {
255
			$this->set_tax_total( array_sum( wc_list_pluck( $this->get_taxes(), 'get_tax_total' ) ) );
256
			$this->set_shipping_tax_total( array_sum( wc_list_pluck( $this->get_taxes(), 'get_shipping_tax_total' ) ) );
257
		}
258
259
		// Allow plugins to hook and alter totals before final total is calculated
260
		do_action( 'woocommerce_calculate_totals', WC()->cart );
261
262
		// Grand Total - Discounted product prices, discounted tax, shipping cost + tax
263
		$this->set_total( apply_filters( 'woocommerce_calculated_total', round( $this->get_items_total() + $this->get_fees_total() + $this->get_shipping_total() + $this->get_tax_total() + $this->get_shipping_tax_total(), wc_get_price_decimals() ), WC()->cart ) );
264
	}
265
266
	/**
267
	 * Sort items by the subtotal.
268
	 */
269
	private function sort_items_callback( $a, $b ) {
270
		$first_item_subtotal  = isset( $a->subtotal ) ? $a->subtotal : 0;
271
		$second_item_subtotal = isset( $b->subtotal ) ? $b->subtotal : 0;
272
		if ( $first_item_subtotal === $second_item_subtotal ) {
273
			return 0;
274
		}
275
		return ( $first_item_subtotal < $second_item_subtotal ) ? 1 : -1;
276
	}
277
278
	/**
279
	 * Should discounts be applied sequentially?
280
	 * @return bool
281
	 */
282
	private function calc_discounts_sequentially() {
283
		return 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' );
284
	}
285
286
	/**
287
	 * Get an items price to discount (undiscounted price).
288
	 * @param  object $item
289
	 * @return float
290
	 */
291
	private function get_undiscounted_price( $item ) {
292
		if ( $item->price_includes_tax ) {
293
			return ( $item->subtotal + $item->subtotal_tax ) / $item->quantity;
294
		} else {
295
			return $item->subtotal / $item->quantity;
296
		}
297
	}
298
299
	/**
300
	 * Get an individual items price after discounts are applied.
301
	 * @param  object $item
302
	 * @return float
303
	 */
304
	private function get_discounted_price( $item ) {
305
		$price = $this->get_undiscounted_price( $item );
306
307
		foreach ( $this->coupons as $code => $coupon ) {
308
			if ( $coupon->coupon->is_valid_for_product( $item->product ) || $coupon->coupon->is_valid_for_cart() ) {
309
				$price_to_discount = $this->calc_discounts_sequentially() ? $price : $this->get_undiscounted_price( $item );
310
311
				if ( $coupon->coupon->is_type( 'fixed_product' ) ) {
312
					$discount = min( $coupon->coupon->get_amount(), $price_to_discount );
313
314
				} elseif ( $coupon->coupon->is_type( array( 'percent_product', 'percent' ) ) ) {
315
					$discount = $coupon->coupon->get_amount() * ( $price_to_discount / 100 );
316
317
				/**
318
				 * This is the most complex discount - we need to divide the discount between rows based on their price in
319
				 * proportion to the subtotal. This is so rows with different tax rates get a fair discount, and so rows
320
				 * with no price (free) don't get discounted. Get item discount by dividing item cost by subtotal to get a %.
321
				 *
322
				 * Uses price inc tax if prices include tax to work around https://github.com/woothemes/woocommerce/issues/7669 and https://github.com/woothemes/woocommerce/issues/8074.
323
				 */
324
				} elseif ( $coupon->coupon->is_type( 'fixed_cart' ) ) {
325
					$discount_percent = ( $item->subtotal + $item->subtotal_tax ) / array_sum( array_merge( array_values( wp_list_pluck( $this->items, 'subtotal' ) ), array_values( wp_list_pluck( $this->items, 'subtotal_tax' ) ) ) );
326
					$discount         = ( $coupon->coupon->get_amount() * $discount_percent ) / $item->quantity;
327
				}
328
329
				// Discount cannot be greater than the price we are discounting.
330
				$discount_amount = min( $price_to_discount, $discount );
331
332
				// Reduce the price so the next coupon discounts the new amount.
333
				$price           = max( $price - $discount_amount, 0 );
334
335
				// Store how much each coupon has discounted in total.
336
				$coupon->count += $item->quantity;
337
				$coupon->total += $discount_amount * $item->quantity;
338
339
				// If taxes are enabled, we should also note how much tax would have been paid if it was not discounted.
340
				if ( $this->get_calculate_tax() ) {
341
					$tax_amount    = WC_Tax::get_tax_total( WC_Tax::calc_tax( $discount_amount, $this->get_item_tax_rates( $item ), $item->price_includes_tax ) );
342
					$coupon->total_tax += $tax_amount * $item->quantity;
343
					$coupon->total = $item->price_includes_tax ? $coupon->total - ( $tax_amount * $item->quantity ) : $coupon->total;
344
				}
345
			}
346
347
			// If the price is 0, we can stop going through coupons because there is nothing more to discount for this product.
348
			if ( 0 >= $price ) {
349
				break;
350
			}
351
		}
352
353
		/**
354
		 * woocommerce_get_discounted_price filter.
355
		 * @param float $price the price to return.
356
		 * @param array $item->values Cart item values. Used in legacy cart class function.
357
		 * @param object WC()->cart. Used in legacy cart class function.
358
		 */
359
		return apply_filters( 'woocommerce_get_discounted_price', $price, $item->values, WC()->cart );
360
	}
361
362
	/**
363
	 * Only ran if woocommerce_adjust_non_base_location_prices is true.
364
	 *
365
	 * If the customer is outside of the base location, this removes the base taxes.
366
	 *
367
	 * Pre 2.7, this was on by default. From 2.7 onwards this is off by default meaning
368
	 * that if a product costs 10 including tax, all users will pay 10 regardless of location and taxes. This was experiemental from 2.4.7.
369
	 */
370
	private function adjust_non_base_location_price( $item ) {
371
		$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->tax_class );
372
		$item_tax_rates = $this->get_item_tax_rates( $item );
373
374
		if ( $item_tax_rates !== $base_tax_rates ) {
375
			// Work out a new base price without the shop's base tax
376
			$taxes                    = WC_Tax::calc_tax( $item->price, $base_tax_rates, true, true );
377
378
			// Now we have a new item price (excluding TAX)
379
			$item->price              = $item->price - array_sum( $taxes );
380
			$item->price_includes_tax = false;
381
		}
382
383
		return $item;
384
	}
385
386
	/*
387
	|--------------------------------------------------------------------------
388
	| Setters.
389
	|--------------------------------------------------------------------------
390
	*/
391
392
	/**
393
	 * Should we calc tax?
394
	 * @param bool
395
	 */
396
	public function set_calculate_tax( $value ) {
397
		$this->calculate_tax = (bool) $value;
398
	}
399
400
	/**
401
	 * Set all totals.
402
	 * @param array $value
403
	 */
404
	public function set_totals( $value ) {
405
		$value = wp_parse_args( $value, $this->get_default_totals() );
406
		$this->totals = $value;
407
	}
408
409
	/**
410
	 * Sets items and adds precision which lets us work with integers.
411
	 * @param array $items
412
	 */
413
	public function set_items( $items ) {
414
		foreach ( $items as $item_key => $maybe_item ) {
415
			if ( ! is_a( $maybe_item, 'WC_Item_Product' ) ) {
416
				continue;
417
			}
418
			$item                     = $this->get_default_item_props();
419
			$item->product            = $maybe_item->get_product();
420
			$item->values             = $maybe_item;
421
			$item->quantity           = $maybe_item->get_quantity();
422
			$item->price              = $item->product->get_price();
423
			$this->items[ $item_key ] = $item;
424
		}
425
	}
426
427
	/**
428
	 * Set coupons.
429
	 * @param array $coupons
430
	 */
431
	public function set_coupons( $coupons ) {
432
		foreach ( $coupons as $code => $coupon_object ) {
433
			$coupon                 = $this->get_default_coupon_props();
434
			$coupon->coupon         = $coupon_object;
435
			$this->coupons[ $code ] = $coupon;
436
		}
437
	}
438
439
	/**
440
	 * Set fees.
441
	 * @param array $fees
442
	 */
443
	public function set_fees( $fees ) {
444
		foreach ( $fees as $fee_key => $fee_object ) {
445
			$fee                    = $this->get_default_fee_props();
446
			$fee->total             = $fee_object->amount;
447
			$fee->taxable           = $fee_object->taxable;
448
			$fee->tax_class         = $fee_object->tax_class;
449
			$this->fees[ $fee_key ] = $fee;
450
		}
451
	}
452
453
	/**
454
	 * Set shipping lines.
455
	 * @param array
456
	 */
457
	public function set_shipping( $shipping_objects ) {
458
		$this->shipping_lines = array();
459
460
		if ( is_array( $shipping_objects ) ) {
461
			foreach ( $shipping_objects as $key => $shipping_object ) {
462
				$shipping                     = $this->get_default_shipping_props();
463
				$shipping->total              = $shipping_object->cost;
464
				$shipping->taxes              = $shipping_object->taxes;
465
				$shipping->total_tax          = array_sum( $shipping_object->taxes );
466
				$this->shipping_lines[ $key ] = $shipping;
467
			}
468
		}
469
	}
470
471
	/**
472
	 * Set taxes.
473
	 * @param array $value
474
	 */
475
	private function set_taxes( $value ) {
476
		$this->totals['taxes'] = $value;
477
	}
478
479
	/**
480
	 * Set tax total.
481
	 * @param float $value
482
	 */
483
	private function set_tax_total( $value ) {
484
		$this->totals['tax_total'] = $value;
485
	}
486
487
	/**
488
	 * Set shipping total.
489
	 * @param float $value
490
	 */
491
	private function set_shipping_total( $value ) {
492
		$this->totals['shipping_total'] = $value;
493
	}
494
495
	/**
496
	 * Set shipping tax total.
497
	 * @param float $value
498
	 */
499
	private function set_shipping_tax_total( $value ) {
500
		$this->totals['shipping_tax_total'] = $value;
501
	}
502
503
	/**
504
	 * Set item totals.
505
	 * @param array $value
506
	 */
507
	private function set_item_totals( $value ) {
508
		$this->totals['item_totals'] = $value;
509
	}
510
511
	/**
512
	 * Set items subtotal.
513
	 * @param float $value
514
	 */
515
	private function set_items_subtotal( $value ) {
516
		$this->totals['items_subtotal'] = $value;
517
	}
518
519
	/**
520
	 * Set items subtotal tax.
521
	 * @param float $value
522
	 */
523
	private function set_items_subtotal_tax( $value ) {
524
		$this->totals['items_subtotal_tax'] = $value;
525
	}
526
527
	/**
528
	 * Set items total.
529
	 * @param float $value
530
	 */
531
	private function set_items_total( $value ) {
532
		$this->totals['items_total'] = $value;
533
	}
534
535
	/**
536
	 * Set items total tax.
537
	 * @param float $value
538
	 */
539
	private function set_items_total_tax( $value ) {
540
		$this->totals['items_total_tax'] = $value;
541
	}
542
543
	/**
544
	 * Set discount total.
545
	 * @param array $value
546
	 */
547
	private function set_coupon_totals( $value ) {
548
		$this->totals['coupon_totals'] = (array) $value;
549
	}
550
551
	/**
552
	 * Set discount total tax.
553
	 * @param array $value
554
	 */
555
	private function set_coupon_tax_totals( $value ) {
556
		$this->totals['coupon_tax_totals'] = (array) $value;
557
	}
558
559
	/**
560
	 * Set counts.
561
	 * @param array $value
562
	 */
563
	private function set_coupon_counts( $value ) {
564
		$this->totals['coupon_tax_totals'] = (array) $value;
565
	}
566
567
	/**
568
	 * Set fees total.
569
	 * @param float $value
570
	 */
571
	private function set_fees_total( $value ) {
572
		$this->totals['fees_total'] = $value;
573
	}
574
575
	/**
576
	 * Set fees total tax.
577
	 * @param float $value
578
	 */
579
	private function set_fees_total_tax( $value ) {
580
		$this->totals['fees_total_tax'] = $value;
581
	}
582
583
	/**
584
	 * Set total.
585
	 * @param float $value
586
	 */
587
	private function set_total( $value ) {
588
		$this->totals['total'] = max( 0, $value );
589
	}
590
591
	/*
592
	|--------------------------------------------------------------------------
593
	| Getters.
594
	|--------------------------------------------------------------------------
595
	*/
596
597
	/**
598
	 * Get all totals.
599
	 * @return array.
0 ignored issues
show
Documentation introduced by
The doc-type array. could not be parsed: Unknown type name "array." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
600
	 */
601
	public function get_totals() {
602
		return $this->totals;
603
	}
604
605
	/**
606
	 * Get shipping and item taxes.
607
	 * @return array
608
	 */
609
	public function get_taxes() {
610
		return $this->totals['taxes'];
611
	}
612
613
	/**
614
	 * Get tax total.
615
	 * @return float
616
	 */
617
	public function get_tax_total() {
618
		return $this->totals['tax_total'];
619
	}
620
621
	/**
622
	 * Get shipping total.
623
	 * @return float
624
	 */
625
	public function get_shipping_total() {
626
		return $this->totals['shipping_total'];
627
	}
628
629
	/**
630
	 * Get shipping tax total.
631
	 * @return float
632
	 */
633
	public function get_shipping_tax_total() {
634
		return $this->totals['shipping_tax_total'];
635
	}
636
637
	/**
638
	 * Get the items subtotal.
639
	 * @return float
640
	 */
641
	public function get_items_subtotal() {
642
		return $this->totals['items_subtotal'];
643
	}
644
645
	/**
646
	 * Get the items subtotal tax.
647
	 * @return float
648
	 */
649
	public function get_items_subtotal_tax() {
650
		return $this->totals['items_subtotal_tax'];
651
	}
652
653
	/**
654
	 * Get the items total.
655
	 * @return float
656
	 */
657
	public function get_items_total() {
658
		return $this->totals['items_total'];
659
	}
660
661
	/**
662
	 * Get the items total tax.
663
	 * @return float
664
	 */
665
	public function get_items_total_tax() {
666
		return $this->totals['items_total_tax'];
667
	}
668
669
	/**
670
	 * Get the total discount amount.
671
	 * @return array
672
	 */
673
	public function get_coupon_totals() {
674
		return $this->totals['coupon_totals'];
675
	}
676
677
	/**
678
	 * Get the total discount amount.
679
	 * @return array
680
	 */
681
	public function get_coupon_tax_totals() {
682
		return $this->totals['coupon_tax_totals'];
683
	}
684
685
	/**
686
	 * Get couppon counts.
687
	 * @return array
688
	 */
689
	public function get_coupon_counts() {
690
		return $this->totals['coupon_counts'];
691
	}
692
693
	/**
694
	 * Get the total fees amount.
695
	 * @return float
696
	 */
697
	public function get_fees_total() {
698
		return $this->totals['fees_total'];
699
	}
700
701
	/**
702
	 * Get the total fee tax amount.
703
	 * @return float
704
	 */
705
	public function get_fees_total_tax() {
706
		return $this->totals['fees_total_tax'];
707
	}
708
709
	/**
710
	 * Get the total.
711
	 * @return float
712
	 */
713
	public function get_total() {
714
		return $this->totals['total'];
715
	}
716
717
	/**
718
	 * Returns an array of item totals.
719
	 * @return array
720
	 */
721
	public function get_item_totals() {
722
		return $this->totals['item_totals'];
723
	}
724
725
	/**
726
	 * Should we calc tax?
727
	 * @param bool
728
	 */
729
	private function get_calculate_tax() {
730
		return wc_tax_enabled() && $this->calculate_tax;
731
	}
732
733
	/**
734
	 * Get tax rates for an item. Caches rates in class to avoid multiple look ups.
735
	 * @param  object $item
736
	 * @return array of taxes
737
	 */
738
	private function get_item_tax_rates( $item ) {
739
		$tax_class = $item->product->get_tax_class();
740
		return isset( $this->item_tax_rates[ $tax_class ] ) ? $this->item_tax_rates[ $tax_class ] : $this->item_tax_rates[ $tax_class ] = WC_Tax::get_rates( $item->product->get_tax_class() );
741
	}
742
743
	/**
744
	 * Get all tax rows for a set of items and shipping methods.
745
	 * @return array
746
	 */
747
	private function get_merged_taxes() {
748
		$taxes = array();
749
750 View Code Duplication
		foreach ( $this->items as $item ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
751
			foreach ( $item->taxes as $rate_id => $rate ) {
752
				if ( ! isset( $taxes[ $rate_id ] ) ) {
753
					$taxes[ $rate_id ] = new WC_Item_Tax();
754
				}
755
				$taxes[ $rate_id ]->set_rate( $rate_id );
756
				$taxes[ $rate_id ]->set_tax_total( $taxes[ $rate_id ]->get_tax_total() + $rate );
757
			}
758
		}
759
760 View Code Duplication
		foreach ( $this->shipping_lines as $item ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
761
			foreach ( $item->taxes as $rate_id => $rate ) {
762
				if ( ! isset( $taxes[ $rate_id ] ) ) {
763
					$taxes[ $rate_id ] = new WC_Item_Tax();
764
				}
765
				$taxes[ $rate_id ]->set_rate( $rate_id );
766
				$taxes[ $rate_id ]->set_shipping_tax_total( $taxes[ $rate_id ]->get_shipping_tax_total() + $rate );
767
			}
768
		}
769
770
		return $taxes;
771
	}
772
}
773