diff --git a/changelog/fix-198-mccy-fedex-conversion b/changelog/fix-198-mccy-fedex-conversion new file mode 100644 index 00000000000..7fecbc49b87 --- /dev/null +++ b/changelog/fix-198-mccy-fedex-conversion @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Fix FedEx insurance rates with different currencies. + + diff --git a/includes/multi-currency/Compatibility/WooCommerceFedEx.php b/includes/multi-currency/Compatibility/WooCommerceFedEx.php index 8a38d058e40..15c25b4ba27 100644 --- a/includes/multi-currency/Compatibility/WooCommerceFedEx.php +++ b/includes/multi-currency/Compatibility/WooCommerceFedEx.php @@ -8,13 +8,25 @@ namespace WCPay\MultiCurrency\Compatibility; use WCPay\MultiCurrency\MultiCurrency; -use WCPay\MultiCurrency\Utils; /** * Class that controls Multi Currency Compatibility with WooCommerce FedEx Plugin. */ class WooCommerceFedEx extends BaseCompatibility { + /** + * Calls to look for in the backtrace when determining whether + * to return store currency or skip converting product prices. + */ + private const WC_SHIPPING_FEDEX_CALLS = [ + 'WC_Shipping_Fedex->set_settings', + 'WC_Shipping_Fedex->per_item_shipping', + 'WC_Shipping_Fedex->box_shipping', + 'WC_Shipping_Fedex->get_fedex_api_request', + 'WC_Shipping_Fedex->get_fedex_requests', + 'WC_Shipping_Fedex->process_result', + ]; + /** * Init the class. * @@ -23,10 +35,31 @@ class WooCommerceFedEx extends BaseCompatibility { public function init() { // Add needed actions and filters if FedEx is active. if ( class_exists( 'WC_Shipping_Fedex_Init' ) ) { + add_filter( MultiCurrency::FILTER_PREFIX . 'should_convert_product_price', [ $this, 'should_convert_product_price' ] ); add_filter( MultiCurrency::FILTER_PREFIX . 'should_return_store_currency', [ $this, 'should_return_store_currency' ] ); } } + /** + * Checks to see if the product's price should be converted. + * + * @param bool $return Whether to convert the product's price or not. Default is true. + * + * @return bool True if it should be converted. + */ + public function should_convert_product_price( bool $return ): bool { + // If it's already false, return it. + if ( ! $return ) { + return $return; + } + + if ( $this->utils->is_call_in_backtrace( self::WC_SHIPPING_FEDEX_CALLS ) ) { + return false; + } + + return $return; + } + /** * Determine whether to return the store currency or not. * @@ -40,15 +73,7 @@ public function should_return_store_currency( bool $return ): bool { return $return; } - $calls = [ - 'WC_Shipping_Fedex->set_settings', - 'WC_Shipping_Fedex->per_item_shipping', - 'WC_Shipping_Fedex->box_shipping', - 'WC_Shipping_Fedex->get_fedex_api_request', - 'WC_Shipping_Fedex->get_fedex_requests', - 'WC_Shipping_Fedex->process_result', - ]; - if ( $this->utils->is_call_in_backtrace( $calls ) ) { + if ( $this->utils->is_call_in_backtrace( self::WC_SHIPPING_FEDEX_CALLS ) ) { return true; } diff --git a/tests/unit/multi-currency/compatibility/test-class-woocommerce-fedex.php b/tests/unit/multi-currency/compatibility/test-class-woocommerce-fedex.php index 60e130390fd..e52927230ca 100644 --- a/tests/unit/multi-currency/compatibility/test-class-woocommerce-fedex.php +++ b/tests/unit/multi-currency/compatibility/test-class-woocommerce-fedex.php @@ -35,6 +35,20 @@ class WCPay_Multi_Currency_WooCommerceFedEx_Tests extends WCPAY_UnitTestCase { */ private $woocommerce_fedex; + /** + * Calls to check in the backtrace. + * + * @var array + */ + private $woocommerce_fedex_calls = [ + 'WC_Shipping_Fedex->set_settings', + 'WC_Shipping_Fedex->per_item_shipping', + 'WC_Shipping_Fedex->box_shipping', + 'WC_Shipping_Fedex->get_fedex_api_request', + 'WC_Shipping_Fedex->get_fedex_requests', + 'WC_Shipping_Fedex->process_result', + ]; + /** * Pre-test setup */ @@ -54,37 +68,45 @@ public function test_should_return_store_currency_returns_true_if_true_passed() // If the calls are found, it should return true. public function test_should_return_store_currency_returns_true_if_calls_found() { - $calls = [ - 'WC_Shipping_Fedex->set_settings', - 'WC_Shipping_Fedex->per_item_shipping', - 'WC_Shipping_Fedex->box_shipping', - 'WC_Shipping_Fedex->get_fedex_api_request', - 'WC_Shipping_Fedex->get_fedex_requests', - 'WC_Shipping_Fedex->process_result', - ]; $this->mock_utils ->expects( $this->once() ) ->method( 'is_call_in_backtrace' ) - ->with( $calls ) + ->with( $this->woocommerce_fedex_calls ) ->willReturn( true ); + $this->assertTrue( $this->woocommerce_fedex->should_return_store_currency( false ) ); } - // If the calls are found, it should return true. + // If the calls are not found, it should return false. public function test_should_return_store_currency_returns_false_if_no_calls_found() { - $calls = [ - 'WC_Shipping_Fedex->set_settings', - 'WC_Shipping_Fedex->per_item_shipping', - 'WC_Shipping_Fedex->box_shipping', - 'WC_Shipping_Fedex->get_fedex_api_request', - 'WC_Shipping_Fedex->get_fedex_requests', - 'WC_Shipping_Fedex->process_result', - ]; $this->mock_utils ->expects( $this->once() ) ->method( 'is_call_in_backtrace' ) - ->with( $calls ) + ->with( $this->woocommerce_fedex_calls ) ->willReturn( false ); + $this->assertFalse( $this->woocommerce_fedex->should_return_store_currency( false ) ); } + + // If true is passed to should_convert_product_price and no calls are found, it should return true. + public function test_should_convert_product_price_returns_true_if_true_passed_and_no_calls_found() { + $this->mock_utils + ->expects( $this->once() ) + ->method( 'is_call_in_backtrace' ) + ->with( $this->woocommerce_fedex_calls ) + ->willReturn( false ); + + $this->assertTrue( $this->woocommerce_fedex->should_convert_product_price( true ) ); + } + + // If calls are found, should_convert_product_price should return false even if true was passed. + public function test_should_convert_product_price_returns_false_if_calls_found() { + $this->mock_utils + ->expects( $this->once() ) + ->method( 'is_call_in_backtrace' ) + ->with( $this->woocommerce_fedex_calls ) + ->willReturn( true ); + + $this->assertFalse( $this->woocommerce_fedex->should_convert_product_price( true ) ); + } }