WordPress at Your Fingertips
function is not described

WC_Cart_Totals::calculate_item_subtotals() protected WC 3.2.0

Subtotals are costs before discounts.

To prevent rounding issues we need to work with the inclusive price where possible otherwise we'll see errors such as when working with a 9.99 inc price, 20% VAT which would be 8.325 leading to totals being 1p off.

Pre tax coupons come off the price the customer thinks they are paying - tax is calculated afterwards.

e.g. $100 bike with $10 coupon = customer pays $90 and tax worked backwards from that.

{} It's a method of the class: WC_Cart_Totals{}

Return

null. Nothing.

Usage

// protected - for code of main (parent) or child class
$result = $this->calculate_item_subtotals();

Changelog

Since 3.2.0 Introduced.

Code of WC_Cart_Totals::calculate_item_subtotals() WC 5.9.0

protected function calculate_item_subtotals() {
	$merged_subtotal_taxes = array(); // Taxes indexed by tax rate ID for storage later.

	$adjust_non_base_location_prices = apply_filters( 'woocommerce_adjust_non_base_location_prices', true );
	$is_customer_vat_exempt          = $this->cart->get_customer()->get_is_vat_exempt();

	foreach ( $this->items as $item_key => $item ) {
		if ( $item->price_includes_tax ) {
			if ( $is_customer_vat_exempt ) {
				$item = $this->remove_item_base_taxes( $item );
			} elseif ( $adjust_non_base_location_prices ) {
				$item = $this->adjust_non_base_location_price( $item );
			}
		}

		$item->subtotal = $item->price;

		if ( $this->calculate_tax && $item->product->is_taxable() ) {
			$item->subtotal_taxes = WC_Tax::calc_tax( $item->subtotal, $item->tax_rates, $item->price_includes_tax );
			$item->subtotal_tax   = array_sum( array_map( array( $this, 'round_line_tax' ), $item->subtotal_taxes ) );

			if ( $item->price_includes_tax ) {
				// Use unrounded taxes so we can re-calculate from the orders screen accurately later.
				$item->subtotal = $item->subtotal - array_sum( $item->subtotal_taxes );
			}

			foreach ( $item->subtotal_taxes as $rate_id => $rate ) {
				if ( ! isset( $merged_subtotal_taxes[ $rate_id ] ) ) {
					$merged_subtotal_taxes[ $rate_id ] = 0;
				}
				$merged_subtotal_taxes[ $rate_id ] += $this->round_line_tax( $rate );
			}
		}

		$this->cart->cart_contents[ $item_key ]['line_tax_data']     = array( 'subtotal' => wc_remove_number_precision_deep( $item->subtotal_taxes ) );
		$this->cart->cart_contents[ $item_key ]['line_subtotal']     = wc_remove_number_precision( $item->subtotal );
		$this->cart->cart_contents[ $item_key ]['line_subtotal_tax'] = wc_remove_number_precision( $item->subtotal_tax );
	}

	$items_subtotal = $this->get_rounded_items_total( $this->get_values_for_total( 'subtotal' ) );

	// Prices are not rounded here because they should already be rounded based on settings in `get_rounded_items_total` and in `round_line_tax` method calls.
	$this->set_total( 'items_subtotal', $items_subtotal );
	$this->set_total( 'items_subtotal_tax', array_sum( $merged_subtotal_taxes ), 0 );

	$this->cart->set_subtotal( $this->get_total( 'items_subtotal' ) );
	$this->cart->set_subtotal_tax( $this->get_total( 'items_subtotal_tax' ) );
}