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

WC_Cart   C

Complexity

Total Complexity 72

Size/Duplication

Total Lines 521
Duplicated Lines 1.92 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
dl 10
loc 521
rs 5.5667
c 0
b 0
f 0
wmc 72
lcom 1
cbo 10

39 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A add_item() 0 15 2
A add_fee() 0 21 2
C add_coupon() 0 31 7
A get_cart() 0 9 3
A get_fees() 0 3 1
A get_coupons() 0 3 1
A is_empty() 0 3 1
A empty_cart() 0 8 1
A set_quantity() 0 9 3
A remove_cart_item() 0 3 1
A remove_coupon() 0 3 1
A remove_coupons() 0 3 1
A get_cart_item() 0 3 1
A restore_cart_item() 0 3 1
A get_cart_item_tax_classes() 0 3 1
A get_cart_contents_weight() 0 3 1
A get_cart_contents_count() 0 3 1
A has_coupon() 0 4 2
B needs_shipping() 0 15 6
A needs_shipping_address() 0 3 2
A get_shipping_packages() 0 15 1
A calculate_shipping() 0 3 2
A get_chosen_shipping_methods() 0 13 3
A calculate_totals() 0 20 1
A needs_payment() 0 3 1
A get_subtotal() 0 7 2
A get_total() 0 3 1
A get_taxes() 0 3 1
A get_tax_totals() 10 10 2
B get_taxes_total() 0 10 5
A get_tax_total() 0 3 1
A get_shipping_tax_total() 0 3 1
A get_shipping_total() 0 7 2
A get_cart_discount_total() 0 3 1
A get_cart_discount_tax_total() 0 3 1
A get_item_totals() 0 3 1
A get_coupon_discount_amount() 0 11 4
A get_coupon_discount_tax_amount() 0 5 2

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 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, and based on these observations, apply Extract Interface, too.

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * @todo
8
 *
9
 * - Handle checkout
10
 * - Item types
11
 * - Coupon totals
12
 * - Orers same system
13
 * - Apply backend coupons
14
 * - Unit tests
15
 */
16
include_once( WC_ABSPATH . 'includes/class-wc-cart-coupons.php' );
17
include_once( WC_ABSPATH . 'includes/class-wc-cart-fees.php' );
18
include_once( WC_ABSPATH . 'includes/class-wc-cart-item.php' );
19
include_once( WC_ABSPATH . 'includes/class-wc-cart-items.php' );
20
include_once( WC_ABSPATH . 'includes/class-wc-cart-session.php' );
21
include_once( WC_ABSPATH . 'includes/class-wc-cart-totals.php' );
22
23
/**
24
 * Main cart class.
25
 *
26
 * @version		2.7.0
27
 * @package		WooCommerce/Classes
28
 * @category	Class
29
 * @author 		WooThemes
30
 */
31
class WC_Cart extends WC_Cart_Session {
32
33
	/**
34
	 * This stores the chosen shipping methods for the cart item packages.
35
	 * @var array
36
	 */
37
	protected $shipping_methods;
38
39
	/**
40
	 * Constructor for the cart class.
41
	 */
42
	public function __construct() {
43
		parent::__construct();
44
45
		add_action( 'woocommerce_add_to_cart', array( $this, 'calculate_totals' ), 20, 0 );
46
		add_action( 'woocommerce_applied_coupon', array( $this, 'calculate_totals' ), 20, 0 );
47
		add_action( 'woocommerce_cart_item_removed', array( $this, 'calculate_totals' ), 20, 0 );
48
		add_action( 'woocommerce_cart_item_restored', array( $this, 'calculate_totals' ), 20, 0 );
49
	}
50
51
	/**
52
	 * Add an item to the cart.
53
	 */
54
	public function add_item( $args ) {
55
		$item_key   = $this->items->generate_key( $args );
56
		$cart_items = $this->items->get_items();
57
58
		if ( $item = $this->items->get_item_by_key( $item_key ) ) {
59
			$item->set_quantity( $item->get_quantity() + $args['quantity']  );
60
		} else {
61
			$item                    = new WC_Item_Product( $args );
62
			$cart_items[ $item_key ] = apply_filters( 'woocommerce_add_cart_item', $item, $item_key );
63
		}
64
65
		$this->items->set_items( $cart_items );
66
67
		return $item_key;
68
	}
69
70
	/**
71
	 * Add additional fee to the cart.
72
	 *
73
	 * @param string $name Unique name for the fee. Multiple fees of the same name cannot be added.
74
	 * @param float $amount Fee amount.
75
	 * @param bool $taxable (default: false) Is the fee taxable?
76
	 * @param string $tax_class (default: '') The tax class for the fee if taxable. A blank string is standard tax class.
77
	 */
78
	public function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) {
79
		$fee_key = $this->fees->generate_key( $name );
80
		$fees    = $this->fees->get_fees();
81
82
		// Only add each fee once
83
		if ( isset( $fees[ $fee_key ] ) ) {
84
			return;
85
		}
86
87
		$fees[ $fee_key ] = (object) array(
88
			'id'        => $fee_key,
89
			'name'      => wc_clean( $name ),
90
			'amount'    => (float) $amount,
91
			'tax_class' => $tax_class,
92
			'taxable'   => (bool) $taxable,
93
		);
94
95
		$this->fees->set_fees( $fees );
96
97
		return $fee_key;
98
	}
99
100
	/**
101
	 * Applies a coupon code.
102
	 * @since 2.7.0
103
	 * @param string $coupon_code - The code to apply
104
	 * @return bool	True if the coupon is applied, false if it does not exist or cannot be applied
105
	 */
106
	public function add_coupon( $coupon_code ) {
107
		if ( ! wc_coupons_enabled() ) {
108
			return false;
109
		}
110
		try {
111
			$coupon  = new WC_Coupon( $coupon_code );
112
			$coupons = array_keys( $this->get_coupons() );
113
114
			if ( ! $coupon->is_valid() ) {
115
				throw new Exception( $coupon->get_error_message() );
116
			}
117
118
			if ( $this->has_coupon( $coupon_code ) ) {
119
				throw new Exception( '', WC_Coupon::E_WC_COUPON_ALREADY_APPLIED );
120
			}
121
122
			if ( $coupon->get_individual_use() ) {
123
				$coupons = apply_filters( 'woocommerce_apply_individual_use_coupon', array(), $coupon, $coupons );
124
			}
125
126
			$coupons[] = $coupon_code;
127
128
			$this->coupons->set_coupons( $coupons );
129
130
			do_action( 'woocommerce_applied_coupon', $coupon_code, $coupon );
131
		} catch ( Exception $e ) {
132
			wc_add_notice( $e->getCode() ? WC_Coupon::get_coupon_error( $e->getCode() ) : $e->getMessage(), 'error' );
133
			return false;
134
		}
135
		return true;
136
	}
137
138
	/**
139
	 * Returns the contents of the cart in an array.
140
	 * @return array contents of the cart
141
	 */
142
	public function get_cart() {
143
		if ( ! did_action( 'wp_loaded' ) ) {
144
			_doing_it_wrong( __FUNCTION__, __( 'Get cart should not be called before the wp_loaded action.', 'woocommerce' ), '2.3' );
145
		}
146
		if ( ! did_action( 'woocommerce_cart_loaded_from_session' ) ) {
147
			$this->get_cart_from_session();
148
		}
149
		return $this->items->get_items();
150
	}
151
152
	/**
153
	 * Get array of fees.
154
	 * @return array of fees
155
	 */
156
	public function get_fees() {
157
		return $this->fees->get_fees();
158
	}
159
160
	/**
161
	 * Get array of applied coupon objects and codes.
162
	 * @return array of applied coupons
163
	 */
164
	public function get_coupons() {
165
		return $this->coupons->get_coupons();
166
	}
167
168
	/**
169
	* Checks if the cart is empty.
170
	* @return bool
171
	*/
172
	public function is_empty() {
173
		return ! sizeof( $this->get_cart() );
174
	}
175
176
	/**
177
	 * Empties the cart and optionally the persistent cart too.
178
	 */
179
	public function empty_cart() {
180
		$this->items->set_items( false );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
181
		$this->fees->set_fees( false );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array<integer,object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
182
		$this->coupons->set_coupons( false );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
183
		$this->shipping_methods = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $shipping_methods.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
184
		$this->totals = new WC_Cart_Totals;
185
		do_action( 'woocommerce_cart_emptied' );
186
	}
187
188
	/**
189
	 * Set the quantity for an item in the cart.
190
	 * @param string	$cart_item_key	contains the id of the cart item
0 ignored issues
show
Documentation introduced by
There is no parameter named $cart_item_key. Did you maybe mean $item_key?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
191
	 * @param int		$quantity		contains the quantity of the item
192
	 */
193
	public function set_quantity( $item_key, $quantity = 1, $deprecated = true ) {
0 ignored issues
show
Unused Code introduced by
The parameter $deprecated is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
194
		if ( $quantity <= 0 ) {
195
			$this->items->remove_item( $item_key );
196
		} elseif ( $item = $this->items->get_item_by_key( $item_key ) ) {
197
			$old_quantity = $item->get_quantity();
198
			$item->set_quantity( $quantity );
199
			do_action( 'woocommerce_after_cart_item_quantity_update', $item_key, $quantity, $old_quantity );
200
		}
201
	}
202
203
	/**
204
	 * Remove item from cart.
205
	 * @param string $item_key Cart item key.
206
	 */
207
	public function remove_cart_item( $item_key ) {
208
		$this->items->remove_item( $item_key );
209
	}
210
211
	/**
212
	 * Remove a single coupon by code.
213
	 * @param  string $coupon_code Code of the coupon to remove
214
	 * @return bool
215
	 */
216
	public function remove_coupon( $coupon_code ) {
217
		return $this->coupons->remove_coupon( $coupon_code );
218
	}
219
220
	/**
221
	 * Remove all coupons.
222
	 */
223
	public function remove_coupons() {
224
		return $this->coupons->set_coupons( false );
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
225
	}
226
227
	/**
228
	 * Returns a specific item in the cart.
229
	 *
230
	 * @param string $item_key Cart item key.
231
	 * @return array Item data
232
	 */
233
	public function get_cart_item( $item_key ) {
234
		 return $this->items->get_item_by_key( $item_key );
235
	}
236
237
	/**
238
	 * Restore item from cart.
239
	 * @param string $item_key Cart item key.
240
	 */
241
	public function restore_cart_item( $item_key ) {
242
		$this->items->restore_item( $item_key );
243
	}
244
245
	/**
246
	 * Get all tax classes for items in the cart.
247
	 * @return array
248
	 */
249
	public function get_cart_item_tax_classes() {
250
		return $this->items->get_tax_classes();
251
	}
252
253
	/**
254
	 * Get weight of items in the cart.
255
	 * @return int
256
	 */
257
	public function get_cart_contents_weight() {
258
		return $this->items->get_weight();
259
	}
260
261
	/**
262
	 * Get number of items in the cart.
263
	 * @return int
264
	 */
265
	public function get_cart_contents_count() {
266
		return $this->items->get_quantity();
267
	}
268
269
	/**
270
	 * Returns whether or not a coupon has been applied.
271
	 * @param string $coupon_code
272
	 * @return bool
273
	 */
274
	public function has_coupon( $coupon_code = '' ) {
275
		$coupons = array_keys( $this->get_coupons() );
276
		return $coupon_code ? in_array( wc_format_coupon_code( $coupon_code ), $coupons ) : sizeof( $coupons );
277
	}
278
279
	/*
280
	|--------------------------------------------------------------------------
281
	| Cart shipping calculation.
282
	|--------------------------------------------------------------------------
283
	*/
284
285
	/**
286
	 * Looks through the cart to see if shipping is actually required.
287
	 * @return bool whether or not the cart needs shipping
288
	 */
289
	public function needs_shipping() {
290
		if ( ! wc_shipping_enabled() || 0 === wc_get_shipping_method_count( true ) ) {
291
			return false;
292
		}
293
		$needs_shipping = false;
294
295
		foreach ( $this->get_cart() as $cart_item_key => $item ) {
296
			$product = $item->get_product();
297
			if ( $product && $product->needs_shipping() ) {
298
				$needs_shipping = true;
299
				break;
300
			}
301
		}
302
		return apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
303
	}
304
305
	/**
306
	 * Should the shipping address form be shown.
307
	 * @return bool
308
	 */
309
	public function needs_shipping_address() {
310
		return apply_filters( 'woocommerce_cart_needs_shipping_address', $this->needs_shipping() && ! wc_ship_to_billing_address_only() );
311
	}
312
313
	/**
314
	 * Get packages to calculate shipping for.
315
	 *
316
	 * This lets us calculate costs for carts that are shipped to multiple locations.
317
	 *
318
	 * Shipping methods are responsible for looping through these packages.
319
	 *
320
	 * By default we pass the cart itself as a package - plugins can change this.
321
	 * through the filter and break it up.
322
	 *
323
	 * @since 1.5.4
324
	 * @return array of cart items
325
	 */
326
	public function get_shipping_packages() {
327
		return apply_filters( 'woocommerce_cart_shipping_packages',
328
			array(
329
				array(
330
					'contents'        => $this->items->get_items_needing_shipping(),
331
					'contents_cost'   => array_sum( wc_list_pluck( $this->items->get_items_needing_shipping(), 'get_price' ) ),
332
					'applied_coupons' => array_keys( $this->get_coupons() ),
333
					'user'            => array(
334
						'ID' => get_current_user_id(),
335
					),
336
					'destination' => WC()->customer->get_shipping(),
337
				)
338
			)
339
		);
340
	}
341
342
	/**
343
	 * Uses the shipping class to calculate shipping then gets the totals when its finished.
344
	 */
345
	public function calculate_shipping() {
346
		return $this->shipping_methods = $this->needs_shipping() ? $this->get_chosen_shipping_methods( WC()->shipping->calculate_shipping( $this->get_shipping_packages() ) ) : array();
347
	}
348
349
	/**
350
	 * Given a set of packages with rates, get the chosen ones only.
351
	 * @since 2.7.0
352
	 * @param array $calculated_shipping_packages
353
	 * @return array
354
	 */
355
	protected function get_chosen_shipping_methods( $calculated_shipping_packages ) {
356
		$chosen_methods = array();
357
358
		// Get chosen methods for each package to get our totals.
359
		foreach ( $calculated_shipping_packages as $key => $package ) {
360
			$chosen_method          = wc_get_chosen_shipping_method_for_package( $key, $package );
361
			if ( $chosen_method ) {
362
				$chosen_methods[ $key ] = $package['rates'][ $chosen_method ];
363
			}
364
		}
365
366
		return $chosen_methods;
367
	}
368
369
	/*
370
	|--------------------------------------------------------------------------
371
	| Cart Totals.
372
	|--------------------------------------------------------------------------
373
	*/
374
375
	/**
376
	 * Calculate totals for the items in the cart.
377
	 */
378
	public function calculate_totals() {
379
		do_action( 'woocommerce_before_calculate_totals', $this );
380
381
		// Calculate line item totals
382
		$this->totals->set_coupons( $this->get_coupons() );
383
		$this->totals->set_items( $this->get_cart() );
384
		$this->totals->set_calculate_tax( ! WC()->customer->get_is_vat_exempt() );
385
		$this->totals->calculate_item_totals();
386
387
		// Calculate fees
388
		$this->totals->set_fees( $this->fees->calculate_fees() );
389
390
		// Calculate shipping costs
391
		$this->totals->set_shipping( $this->calculate_shipping() );
392
393
		// Calc grand totals
394
		$this->totals->calculate_totals();
395
396
		do_action( 'woocommerce_after_calculate_totals', $this );
397
	}
398
399
	/**
400
	 * Looks at the totals to see if payment is actually required.
401
	 *
402
	 * @return bool
403
	 */
404
	public function needs_payment() {
405
		return apply_filters( 'woocommerce_cart_needs_payment', $this->get_total() > 0, $this );
406
	}
407
408
	/**
409
	 * Gets the order subtotal with or without tax.
410
	 * @param bool $including_tax
411
	 * @return string formatted price
412
	 */
413
	public function get_subtotal( $including_tax = false ) {
414
		$subtotal = $this->totals->get_items_subtotal();
415
		if ( $including_tax ) {
416
			$subtotal += $this->totals->get_items_subtotal_tax();
417
		}
418
		return apply_filters( 'woocommerce_cart_subtotal', $subtotal, $including_tax );
419
	}
420
421
	/**
422
	 * Gets the order total (after calculation).
423
	 * @return string formatted price
424
	 */
425
	public function get_total() {
426
		return apply_filters( 'woocommerce_cart_total', $this->totals->get_total() );
427
	}
428
429
	/**
430
	 * Gets all taxes.
431
	 * @return array of taxes
432
	 */
433
	public function get_taxes() {
434
		return apply_filters( 'woocommerce_cart_get_taxes', $this->totals->get_taxes() );
435
	}
436
437
	/**
438
	 * Gets all taxes which will be output.
439
	 * @return array
440
	 */
441 View Code Duplication
	public function get_tax_totals() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
442
		$taxes = $this->get_taxes();
443
444
		if ( apply_filters( 'woocommerce_cart_hide_zero_taxes', true ) ) {
445
			$zero_amounts = array_filter( wp_list_pluck( $taxes, 'amount' ) );
446
			$taxes        = array_intersect_key( $taxes, $zero_amounts );
447
		}
448
449
		return apply_filters( 'woocommerce_cart_formatted_tax_totals', $taxes );
450
	}
451
452
	/**
453
	 * Get tax row amounts with or without compound taxes includes.
454
	 *
455
	 * @param  bool $compound True if getting compound taxes
456
	 * @param  bool $round  True if getting total to display
457
	 * @return float price
458
	 */
459
	public function get_taxes_total( $compound = true, $round = true ) {
460
		$total = 0;
461
		foreach ( $this->get_taxes() as $key => $tax ) {
462
			if ( ! $compound && $tax->get_compound() ) {
463
				continue;
464
			}
465
			$total += $tax;
466
		}
467
		return apply_filters( 'woocommerce_cart_taxes_total', $round ? wc_round_tax_total( $total ) : $total, $compound, $display, $this );
468
	}
469
470
	/**
471
	 * Get the total tax on the cart.
472
	 * @return float
473
	 */
474
	public function get_tax_total() {
475
		return $this->totals->get_tax_total();
476
	}
477
478
	/**
479
	 * Get the total tax on shipping.
480
	 * @return float
481
	 */
482
	public function get_shipping_tax_total() {
483
		return $this->totals->get_shipping_tax_total();
484
	}
485
486
	/**
487
	 * Get the total cost of shipping, with or without taxes included.
488
	 * @param  bool $including_tax
489
	 * @return float
490
	 */
491
	public function get_shipping_total( $including_tax = false ) {
492
		$shipping_total = $this->totals->get_shipping_total();
493
		if ( $including_tax ) {
494
			$shipping_total += $this->totals->get_shipping_tax_total();
495
		}
496
		return $shipping_total;
497
	}
498
499
	/**
500
	 * Return the total amount of discount granted by coupons.
501
	 * @return float
502
	 */
503
	public function get_cart_discount_total() {
504
		return $this->totals->get_discount_total();
0 ignored issues
show
Bug introduced by
The method get_discount_total() does not seem to exist on object<WC_Cart_Totals>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
505
	}
506
507
	/**
508
	 * Return the tax on the total amount of discount granted by coupons.
509
	 * @return float
510
	 */
511
	public function get_cart_discount_tax_total() {
512
		return $this->totals->get_discount_total_tax();
0 ignored issues
show
Bug introduced by
The method get_discount_total_tax() does not seem to exist on object<WC_Cart_Totals>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
513
	}
514
515
	/**
516
	 * Get item totals from totals class.
517
	 * @return array
518
	 */
519
	public function get_item_totals() {
520
		return $this->totals->get_item_totals();
521
	}
522
523
	/**
524
	 * Get the total discount amount for a specific coupon code.
525
	 * @param string $code
526
	 * @param bool $ex_tax
527
	 * @return float
528
	 */
529
	public function get_coupon_discount_amount( $code, $ex_tax = true ) {
530
		$totals     = $this->totals->get_coupon_totals();
531
		$tax_totals = $this->totals->get_coupon_tax_totals();
532
		$amount     = isset( $totals[ $code ] ) ? $totals[ $code ] : 0;
533
534
		if ( ! $ex_tax ) {
535
			$amount += isset( $tax_totals[ $code ] ) ? $tax_totals[ $code ] : 0;
536
		}
537
538
		return wc_cart_round_discount( $amount, wc_get_price_decimals() );
539
	}
540
541
	/**
542
	 * Get the total discount tax amount for a specific coupon code.
543
	 * @param string $code
544
	 * @return float
545
	 */
546
	public function get_coupon_discount_tax_amount( $code ) {
547
		$tax_totals = $this->totals->get_coupon_tax_totals();
548
		$amount     = isset( $tax_totals[ $code ] ) ? $tax_totals[ $code ] : 0;
549
		return wc_cart_round_discount( $amount, wc_get_price_decimals() );
550
	}
551
}
552