Commit 092c641ef4b for woocommerce
commit 092c641ef4be95632931a310b99db0b93f62c0dd
Author: Néstor Soriano <konamiman@konamiman.com>
Date: Thu Jul 30 20:17:33 2026 +0900
Revert the fixed end-prices order calculation changes (#63744 and #65535) (#67142)
* Revert "Fix admin order items subtotal subtracting fee tax for fixed end-prices (#65535)"
This reverts commit ca9c108df582ec362169b345e10e2f5f35807abc.
* Revert "Fix: `woocommerce_adjust_non_base_location_prices` not respected for manual backend orders (#63744)"
This reverts commit 1b320629104564c935f014fdc4a1ca6779c481a9.
The conflict in class-wc-order-item-fee.php was resolved keeping the
blank-fee-value float coercion introduced later in #66231.
* Add changelog entry
diff --git a/plugins/woocommerce/changelog/fix-revert-63744-net-amount-on-tax-inclusive-stores b/plugins/woocommerce/changelog/fix-revert-63744-net-amount-on-tax-inclusive-stores
new file mode 100644
index 00000000000..873d4cde312
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-revert-63744-net-amount-on-tax-inclusive-stores
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Revert the fixed end-prices order calculation changes from PR #63744, which caused tax-inclusive stores using the woocommerce_adjust_non_base_location_prices filter to charge the net amount on block/Store API checkout
diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
index b33ab3fad08..5192ba7e798 100644
--- a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
+++ b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php
@@ -1765,22 +1765,13 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
public function add_product( $product, $qty = 1, $args = array() ) {
if ( $product ) {
$order = ArrayUtil::get_value_or_default( $args, 'order' );
-
- if ( $this->has_fixed_end_prices() ) {
- // Note: storing inclusive price as-is relies on the filter being a
- // code-level constant. If the filter changes at runtime, existing
- // line totals will be misinterpreted on recalculate since the gross
- // price is reused without re-deriving from the product.
- $total = (float) $product->get_price() * $qty;
- } else {
- $total = wc_get_price_excluding_tax(
- $product,
- array(
- 'qty' => $qty,
- 'order' => $order,
- )
- );
- }
+ $total = wc_get_price_excluding_tax(
+ $product,
+ array(
+ 'qty' => $qty,
+ 'order' => $order,
+ )
+ );
$default_args = array(
'name' => $product->get_name(),
@@ -2022,9 +2013,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$is_vat_exempt = apply_filters( 'woocommerce_order_is_vat_exempt', 'yes' === $this->get_meta( 'is_vat_exempt' ), $this );
- if ( $this->has_fixed_end_prices() ) {
- $calculate_tax_for['prices_include_tax'] = true;
- }
+ // Trigger tax recalculation for all items.
foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) {
if ( ! $is_vat_exempt ) {
$item->calculate_taxes( $calculate_tax_for );
@@ -2167,30 +2156,6 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
);
}
- /**
- * Whether this store uses fixed end-prices across tax jurisdictions.
- * True when prices include tax and woocommerce_adjust_non_base_location_prices is false.
- *
- * @return bool
- */
- private function has_fixed_end_prices(): bool {
- /**
- * Filters if taxes should be removed from locations outside the store base location.
- *
- * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing
- * with out of base locations. e.g. If a product costs 10 including tax, all users will pay 10
- * regardless of location and taxes.
- *
- * @since 2.4.7
- *
- * @param bool $adjust_non_base_location_prices True by default.
- */
- $adjust_non_base_location_prices = apply_filters( 'woocommerce_adjust_non_base_location_prices', true );
-
- return 'yes' === get_option( 'woocommerce_prices_include_tax' )
- && ! $adjust_non_base_location_prices;
- }
-
/**
* Calculate totals by looking at the contents of the order. Stores the totals and returns the orders final total.
*
@@ -2236,11 +2201,6 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$this->calculate_taxes();
}
- // Re-read cart totals after calculate_taxes().
- // Negative fees may have been capped while calculating totals.
- $cart_subtotal = $this->get_cart_subtotal_for_order();
- $cart_total = (float) $this->get_cart_total_for_order();
-
// Sum taxes again so we can work out how much tax was discounted. This uses original values, not those possibly rounded to 2dp.
foreach ( $this->get_items() as $item ) {
$taxes = $item->get_taxes();
@@ -2254,12 +2214,6 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
}
}
- // Fixed end-price orders keep inclusive item totals; compare net values and add tax back below.
- if ( $this->has_fixed_end_prices() ) {
- $cart_subtotal = $cart_subtotal - $cart_subtotal_tax;
- $cart_total = $cart_total - $cart_total_tax;
- }
-
$this->set_discount_total( NumberUtil::round( $cart_subtotal - $cart_total, $price_decimals ) );
$this->set_discount_tax( wc_round_tax_total( $cart_subtotal_tax - $cart_total_tax ) );
$this->set_total( NumberUtil::round( $cart_total + $fees_total + (float) $this->get_shipping_total() + (float) $this->get_cart_tax() + (float) $this->get_shipping_tax(), $price_decimals ) );
@@ -2299,48 +2253,6 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
return apply_filters( 'woocommerce_order_amount_item_subtotal', $subtotal, $this, $item, $inc_tax, $round );
}
- /**
- * Get the items subtotal amount to display in the admin order screen.
- *
- * For stores with fixed end-prices (prices entered including tax with the
- * woocommerce_adjust_non_base_location_prices adjustment disabled), the
- * line-item subtotal tax is removed so the displayed subtotal matches the
- * ex-tax cart display. Only line-item taxes are subtracted, not the fee tax
- * that get_cart_tax() would also include.
- *
- * @return float
- */
- public function get_subtotal_amount_to_display() {
- if ( ! $this->has_fixed_end_prices() ) {
- return (float) $this->get_subtotal();
- }
-
- $subtotal_tax = 0;
- foreach ( $this->get_items() as $item ) {
- if ( $item instanceof WC_Order_Item_Product ) {
- $subtotal_tax += self::round_line_tax( (float) $item->get_subtotal_tax(), false );
- }
- }
-
- return (float) $this->get_subtotal() - wc_round_tax_total( $subtotal_tax );
- }
-
- /**
- * Get the per-unit item subtotal amount to display in the admin order screen.
- *
- * For stores with fixed end-prices (prices entered including tax with the
- * woocommerce_adjust_non_base_location_prices adjustment disabled), the item
- * tax is removed so the displayed amount matches the ex-tax cart display.
- *
- * @param object $item Item to get the subtotal from.
- * @return float
- */
- public function get_item_subtotal_to_display( $item ) {
- return ( $this->has_fixed_end_prices() && $item instanceof WC_Order_Item_Product && $item->get_quantity() )
- ? NumberUtil::round( ( (float) $item->get_subtotal() - (float) $item->get_subtotal_tax() ) / $item->get_quantity(), wc_get_price_decimals() )
- : $this->get_item_subtotal( $item, false, true );
- }
-
/**
* Get line subtotal - this is the cost before discount.
*
diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item.php
index 5348d3e88fc..88383ec4cbc 100644
--- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item.php
+++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item.php
@@ -80,10 +80,10 @@ $item_name = apply_filters( 'woocommerce_order_item_name', $item->get_name(), $i
</div>
</td>
<?php endif; ?>
- <td class="item_cost" width="1%" data-sort-value="<?php echo esc_attr( $order->get_item_subtotal_to_display( $item ) ); ?>">
+ <td class="item_cost" width="1%" data-sort-value="<?php echo esc_attr( $order->get_item_subtotal( $item, false, true ) ); ?>">
<div class="view">
<?php
- echo wc_price( $order->get_item_subtotal_to_display( $item ), $wc_price_arg ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo wc_price( $order->get_item_subtotal( $item, false, true ), $wc_price_arg ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>
</td>
diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-items.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-items.php
index 64d673a6acc..e99366440bd 100644
--- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-items.php
+++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-items.php
@@ -171,7 +171,7 @@ if ( wc_tax_enabled() ) {
<td class="label"><?php esc_html_e( 'Items Subtotal:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">
- <?php echo wc_price( $order->get_subtotal_amount_to_display(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+ <?php echo wc_price( $order->get_subtotal(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</td>
</tr>
<?php if ( 0 < $order->get_total_discount() ) : ?>
diff --git a/plugins/woocommerce/includes/class-wc-order-item-fee.php b/plugins/woocommerce/includes/class-wc-order-item-fee.php
index 3249ae98309..1e5caf0c649 100644
--- a/plugins/woocommerce/includes/class-wc-order-item-fee.php
+++ b/plugins/woocommerce/includes/class-wc-order-item-fee.php
@@ -98,7 +98,6 @@ class WC_Order_Item_Fee extends WC_Order_Item {
// Use regular calculation unless the fee is negative.
if ( 0 <= $total ) {
- unset( $calculate_tax_for['prices_include_tax'] );
return parent::calculate_taxes( $calculate_tax_for );
}
@@ -117,7 +116,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
$cart_discount_proportion = $total * $proportion;
$calculate_tax_for['tax_class'] = $tax_class;
$tax_rates = WC_Tax::find_rates( $calculate_tax_for );
- $discount_taxes = wc_array_merge_recursive_numeric( $discount_taxes, WC_Tax::calc_tax( $cart_discount_proportion, $tax_rates, ! empty( $calculate_tax_for['prices_include_tax'] ) ) );
+ $discount_taxes = wc_array_merge_recursive_numeric( $discount_taxes, WC_Tax::calc_tax( $cart_discount_proportion, $tax_rates ) );
}
}
$this->set_taxes( array( 'total' => $discount_taxes ) );
diff --git a/plugins/woocommerce/includes/class-wc-order-item.php b/plugins/woocommerce/includes/class-wc-order-item.php
index 3ad6b58ce9b..22858fcd59a 100644
--- a/plugins/woocommerce/includes/class-wc-order-item.php
+++ b/plugins/woocommerce/includes/class-wc-order-item.php
@@ -283,23 +283,19 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'] ) ) {
return false;
}
-
- $inc_tax = ! empty( $calculate_tax_for['prices_include_tax'] );
-
if ( '0' !== $this->get_tax_class() && ProductTaxStatus::TAXABLE === $this->get_tax_status() && wc_tax_enabled() ) {
$calculate_tax_for['tax_class'] = $this->get_tax_class();
$tax_rates = WC_Tax::find_rates( $calculate_tax_for );
- $taxes = WC_Tax::calc_tax( $this->get_total(), $tax_rates, $inc_tax );
+ $taxes = WC_Tax::calc_tax( $this->get_total(), $tax_rates, false );
if ( method_exists( $this, 'get_subtotal' ) ) {
- $subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, $inc_tax );
+ $subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, false );
$this->set_taxes(
array(
'total' => $taxes,
'subtotal' => $subtotal_taxes,
)
);
-
} else {
$this->set_taxes( array( 'total' => $taxes ) );
}
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-crud-orders.php b/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-crud-orders.php
index 1ab8e8a9276..dbd21a31a3d 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-crud-orders.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-crud-orders.php
@@ -2175,336 +2175,4 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
$this->assertEquals( 20.50, $order->get_total_fees() );
}
-
- /**
- * @testdox calculate_taxes() respects woocommerce_adjust_non_base_location_prices
- * for manual backend orders.
- */
- public function test_calculate_taxes_fixed_end_price_non_base_country(): void {
- $context = $this->create_manual_order_tax_context();
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context, '24' );
-
- try {
- $order->calculate_totals();
-
- $this->assertEquals( 24.00, round( (float) $order->get_total(), 2 ) );
- $this->assertEquals( 0.00, round( (float) $order->get_discount_total(), 2 ) );
-
- $item = $this->get_first_order_item( $order );
- $this->assertEquals(
- 1.98,
- round( (float) $item->get_subtotal_tax(), 2 ),
- 'Line subtotal tax must be 24/1.09*0.09 from the customer NL rate.'
- );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox calculate_taxes() without the filter still adjusts price for non-base
- * country (default WooCommerce behaviour must be preserved).
- */
- public function test_calculate_taxes_adjusts_price_without_filter(): void {
- $context = $this->create_manual_order_tax_context();
- $order = $this->create_manual_order_for_tax_context( $context );
-
- try {
- $order->calculate_totals();
-
- $this->assertGreaterThan( 24.00, (float) $order->get_total() );
- $this->assertEquals(
- 24.68,
- round( (float) $order->get_total(), 2 ),
- 'Without the filter, NL total should be ~24.68.'
- );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox calculate_taxes() with adjust_non_base_location_prices false is a
- * no-op for prices-exclusive-of-tax stores.
- */
- public function test_calculate_taxes_fixed_price_filter_noop_for_excl_tax_store(): void {
- $context = $this->create_manual_order_tax_context( 'no' );
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context );
-
- try {
- $order->calculate_totals();
-
- $this->assertEquals(
- 26.16,
- round( (float) $order->get_total(), 2 ),
- 'For excl-tax stores the filter must be a no-op; NL 9% applies on top of 24.'
- );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox calculate_totals() is idempotent, calling it twice produces
- * the same result when adjust_non_base_location_prices is false.
- */
- public function test_calculate_taxes_fixed_price_idempotent(): void {
- $context = $this->create_manual_order_tax_context();
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context, '24' );
-
- try {
- $order->calculate_totals();
- $total_first = $order->get_total();
-
- $order->calculate_totals();
- $total_second = $order->get_total();
-
- $this->assertEquals(
- round( (float) $total_first, 2 ),
- round( (float) $total_second, 2 ),
- 'Calling calculate_totals() twice must produce the same total.'
- );
- $this->assertEquals( 24.00, round( (float) $total_second, 2 ) );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox calculate_totals() keeps positive fees tax-exclusive in fixed end-price mode.
- */
- public function test_calculate_taxes_fixed_price_positive_fee_remains_tax_exclusive(): void {
- $context = $this->create_manual_order_tax_context();
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context, '24' );
-
- $fee = new WC_Order_Item_Fee();
- $fee->set_props(
- array(
- 'name' => 'Handling',
- 'tax_status' => ProductTaxStatus::TAXABLE,
- 'tax_class' => $context['tax_class_slug'],
- 'total' => 10,
- )
- );
- $order->add_item( $fee );
-
- try {
- $order->calculate_totals();
-
- $this->assertEquals( 34.90, round( (float) $order->get_total(), 2 ) );
- $this->assertEquals( 0.90, round( (float) $fee->get_total_tax(), 2 ) );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox calculate_totals() extracts tax from negative fees in fixed end-price mode.
- */
- public function test_calculate_taxes_fixed_price_negative_fee_uses_inclusive_tax(): void {
- $context = $this->create_manual_order_tax_context();
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context, '24' );
-
- $fee = new WC_Order_Item_Fee();
- $fee->set_props(
- array(
- 'name' => 'Manual discount',
- 'tax_status' => ProductTaxStatus::TAXABLE,
- 'tax_class' => $context['tax_class_slug'],
- 'total' => -10,
- )
- );
- $order->add_item( $fee );
-
- try {
- $order->calculate_totals();
-
- $this->assertEquals( -0.83, round( (float) $fee->get_total_tax(), 2 ) );
- $this->assertEquals( 1.15, round( (float) $order->get_cart_tax(), 2 ) );
- $this->assertEquals( 13.17, round( (float) $order->get_total(), 2 ) );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * @testdox get_subtotal_amount_to_display() excludes fee tax from the items subtotal in fixed end-price mode.
- */
- public function test_get_subtotal_amount_to_display_excludes_fee_tax_in_fixed_price_mode(): void {
- $context = $this->create_manual_order_tax_context();
- add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- $order = $this->create_manual_order_for_tax_context( $context, '24' );
-
- $fee = new WC_Order_Item_Fee();
- $fee->set_props(
- array(
- 'name' => 'Handling',
- 'tax_status' => ProductTaxStatus::TAXABLE,
- 'tax_class' => $context['tax_class_slug'],
- 'total' => 10,
- )
- );
- $order->add_item( $fee );
-
- try {
- $order->calculate_totals();
-
- $line_item = current( $order->get_items() );
-
- // Guard the precondition: the fee must be taxed, otherwise get_cart_tax()
- // would equal the item tax and the buggy code would also yield €22.02.
- $this->assertEquals( 0.90, round( (float) $fee->get_total_tax(), 2 ), 'Test setup must include taxable fee tax' );
-
- // The €24 tax-inclusive item carries €1.98 tax, so the ex-tax items subtotal is €22.02.
- // The €0.90 taxable-fee tax (also part of get_cart_tax()) must not be subtracted from it.
- $this->assertEquals( 22.02, round( (float) $order->get_subtotal_amount_to_display(), 2 ), 'Displayed items subtotal must exclude fee tax' );
- $this->assertEquals(
- round( (float) $order->get_item_subtotal_to_display( $line_item ), 2 ),
- round( (float) $order->get_subtotal_amount_to_display(), 2 ),
- 'Displayed items subtotal must match the per-item displayed subtotal'
- );
- } finally {
- $this->cleanup_manual_order_tax_context( $context, $order );
- }
- }
-
- /**
- * Creates tax rates and a product for manual order tax tests.
- *
- * @param string $prices_include_tax Whether prices include tax.
- * @return array<string,mixed>
- */
- private function create_manual_order_tax_context( string $prices_include_tax = 'yes' ): array {
- $tax_class_slug = 'books-vat';
- $tax_class_created = false;
-
- $context = array(
- 'original_prices_include_tax' => get_option( 'woocommerce_prices_include_tax' ),
- 'original_calc_taxes' => get_option( 'woocommerce_calc_taxes' ),
- 'original_tax_based_on' => get_option( 'woocommerce_tax_based_on' ),
- 'original_base_country' => get_option( 'woocommerce_default_country' ),
- 'tax_class_slug' => $tax_class_slug,
- );
-
- update_option( 'woocommerce_prices_include_tax', $prices_include_tax );
- update_option( 'woocommerce_calc_taxes', 'yes' );
- update_option( 'woocommerce_tax_based_on', 'billing' );
- update_option( 'woocommerce_default_country', 'BE' );
-
- if ( ! in_array( $tax_class_slug, WC_Tax::get_tax_class_slugs(), true ) ) {
- WC_Tax::create_tax_class( 'Books VAT', $tax_class_slug );
- $tax_class_created = true;
- }
-
- $context['tax_class_created'] = $tax_class_created;
- $context['be_rate_id'] = $this->insert_manual_order_tax_rate( 'BE', '6.0000', 'Belgium VAT', $tax_class_slug );
- $context['nl_rate_id'] = $this->insert_manual_order_tax_rate( 'NL', '9.0000', 'Netherlands VAT', $tax_class_slug );
-
- WC_Cache_Helper::invalidate_cache_group( 'taxes' );
-
- $product = WC_Helper_Product::create_simple_product();
- $product->set_price( '24' );
- $product->set_regular_price( '24' );
- $product->set_tax_status( ProductTaxStatus::TAXABLE );
- $product->set_tax_class( $tax_class_slug );
- $product->save();
-
- $context['product'] = $product;
-
- return $context;
- }
-
- /**
- * Inserts a tax rate for manual order tax tests.
- *
- * @param string $country Tax rate country.
- * @param string $rate Tax rate percentage.
- * @param string $name Tax rate name.
- * @param string $tax_class_slug Tax class slug.
- * @return int
- */
- private function insert_manual_order_tax_rate( string $country, string $rate, string $name, string $tax_class_slug ): int {
- return WC_Tax::_insert_tax_rate(
- array(
- 'tax_rate_country' => $country,
- 'tax_rate_state' => '',
- 'tax_rate' => $rate,
- 'tax_rate_name' => $name,
- 'tax_rate_priority' => '1',
- 'tax_rate_compound' => '0',
- 'tax_rate_shipping' => '1',
- 'tax_rate_order' => '1',
- 'tax_rate_class' => $tax_class_slug,
- )
- );
- }
-
- /**
- * Creates a manual order for the tax context.
- *
- * @param array<string,mixed> $context Tax test context.
- * @param string|null $line_total Optional line total override.
- * @return WC_Order
- */
- private function create_manual_order_for_tax_context( array $context, ?string $line_total = null ): WC_Order {
- $order = wc_create_order();
- $order->set_billing_country( 'NL' );
- $order->set_shipping_country( 'NL' );
- $item_id = $order->add_product( $context['product'], 1 );
-
- if ( null !== $line_total ) {
- $item = $order->get_item( $item_id );
- $item->set_subtotal( $line_total );
- $item->set_total( $line_total );
- $item->save();
- }
-
- $order->save();
-
- return $order;
- }
-
- /**
- * Cleans up manual order tax test data.
- *
- * @param array<string,mixed> $context Tax test context.
- * @param WC_Order|null $order Order to delete.
- */
- private function cleanup_manual_order_tax_context( array $context, ?WC_Order $order = null ): void {
- remove_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
- WC_Tax::_delete_tax_rate( $context['be_rate_id'] );
- WC_Tax::_delete_tax_rate( $context['nl_rate_id'] );
-
- if ( $context['tax_class_created'] ) {
- WC_Tax::delete_tax_class_by( 'slug', $context['tax_class_slug'] );
- }
-
- WC_Cache_Helper::invalidate_cache_group( 'taxes' );
- WC_Helper_Product::delete_product( $context['product']->get_id() );
-
- if ( $order ) {
- $order->delete( true );
- }
-
- update_option( 'woocommerce_prices_include_tax', $context['original_prices_include_tax'] );
- update_option( 'woocommerce_calc_taxes', $context['original_calc_taxes'] );
- update_option( 'woocommerce_tax_based_on', $context['original_tax_based_on'] );
- update_option( 'woocommerce_default_country', $context['original_base_country'] );
- }
-
- /**
- * Gets the first item from an order.
- *
- * @param WC_Order $order Order object.
- * @return WC_Order_Item
- */
- private function get_first_order_item( WC_Order $order ): WC_Order_Item {
- $items = $order->get_items();
- return reset( $items );
- }
}