WC_Cart_Totals::calculate_item_subtotals()protectedWC 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.

Метод класса: WC_Cart_Totals{}

Хуки из метода

Возвращает

null. Ничего (null).

Использование

// protected - в коде основоного (родительского) или дочернего класса
$result = $this->calculate_item_subtotals();

Список изменений

С версии 3.2.0 Введена.

Код WC_Cart_Totals::calculate_item_subtotals() WC 8.7.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' ) );
}