OpenMage / magento-lts

Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes! Download the source code for free or contribute to OpenMage LTS | Security vulnerability patches, bug fixes, performance improvements and more.
https://www.openmage.org
Open Software License 3.0
865 stars 436 forks source link

Tablerate calculates wrong rates #1433

Open ulbiopro opened 3 years ago

ulbiopro commented 3 years ago

Preconditions (*)

  1. OpenMage LTS 20.0.6 (I'm pretty sure in every Magento version, at least since CE 1.9.2.4)
  2. (MySQL 5.7.31 / PHP 7.4.9 / Apache 2.4.38 )

Steps to reproduce (*)

I reproduced this on fresh OpenMage LTS 20.0.6 and used the default tax-classes and zones. Nevertheless it happens with custom configuration, too.

  1. Setup: Configure shipping method tablerates with tablerate data below (works with other countries too, but USA is less work to reproduce). Anything less than $50 should include a $3.95 shipping fee, a cart with more than $50 comes with free shipping.

    Country,Region/State,"Zip/Postal Code","Order Subtotal (and above)","Shipping Price"
    USA,*,*,0.0000,3.9500
    USA,*,*,50.0000,0.0000
  2. Setup: Use default item, simple product with a price of 50.00 $, Tax Class = taxable goods (an existing default value)

  3. Setup: Configuration -> Sales -> Tax -> Calculation Settings -> Catalog Prices: Including Tax

  4. Add product to cart. In default Layout you can use the "estimate shipping and tax" box. Since we're using default values, please use state "california" because we have configured tax zones and rates for this state by default.

    Bildschirmfoto 2021-01-28 um 12 51 43

    As expected, shipping costs are $0.

  5. Proceed to checkout.

  6. Checkout as guest

  7. Fill in billing information. Make sure to use California again and select "Ship to this address"

    Bildschirmfoto 2021-01-28 um 13 01 37
  8. Continue -> Shipping Information form will be skipped. 9. Shipping fee is now $3.95!

    Bildschirmfoto 2021-01-28 um 13 01 48
  9. Click "Back"

    Bildschirmfoto 2021-01-28 um 13 01 55
  10. Click "Continue"

  11. Shipping fee is now $0 again.

    Bildschirmfoto 2021-01-28 um 13 02 00

Shipping fee is also $0, if you select "Ship to different address" in the Billing information.

Expected result (*)

I'm not sure if shipping costs are calculated on prices including or excluding taxes. Either way, the result should be the same, if you ship to the same address.

Actual result (*)

Shipping costs differ, although both times the sipping address was the same.

Notice

Maybe this information helps, finding the bug: In step 7 ("ship to this address") Mage_Shipping_Model_Carrier_Tablerate::collectRates() is called 2 times. The 1. time $request->getPackageValue() returns 50. (Price incl. tax) The 2. time $request->getPackageValue() returns 46.19. (Price excl. tax)

If you checkout with "ship to different address", Mage_Shipping_Model_Carrier_Tablerate::collectRates() is called only once. $request->getPackageValue() returns 50.

ulbiopro commented 3 years ago

Maybe this can help too:

when saving billing address, the saveBillingAction is called and therefore Mage_Checkout_Model_Type_Onepage::saveBilling().

In both Mage_Checkout_Model_Type_Onepage::saveBilling() as in Mage_Checkout_Model_Type_Onepage::saveShipping() totals will be collected on the quote.

Mage_Checkout_Model_Type_Onepage

        $this->getQuote()->collectTotals();

Mage_Checkout_Model_Type_Onepage

        $this->getQuote()->collectTotals()->save();

In both cases, PackageValue in Mage_Shipping_Model_Carrier_Tablerate returns the amount including tax (50), because the address object data "base_subtotal" is 50. This seems fine to me.

But: On Mage_Checkout_Model_Type_Onepage::saveBilling() there are these additional lines:

Mage_Checkout_Model_Type_Onepage

        if (!$this->getQuote()->isVirtual() && $this->getCheckout()->getStepData('shipping', 'complete') == true) {
            //Recollect Shipping rates for shipping methods
            $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
        }

setCollectShippingRates(true) leads to the fact, that Mage_Sales_Model_Quote_Address::requestShippingRates() is called again, when loading the shipping methods checkout template. But this time the address object data "base_subtotal" is excl. tax (46.19).

If Magento now proceeds to collect the shipping amount it will return 3.95.

So I wonder why, we have to recollect shipping rates for shipping methods, in Mage_Checkout_Model_Type_Onepage::saveBilling()? If we don't do it, it seems to work fine for me.

But since I don't know why Magento behaves that way, I'm afraid to change it rashly. Maybe anyone knows a little better?

Thank you for you help guys!

ADDISON74 commented 3 years ago

I faced a similar problem in a store that had taxes (VAT) which still runs Magento CE 1.9.2.4 . Although all store settings were made correctly, the values that were displayed in the shopping cart and in the checkout process were incorrect. I had to look for a solution and found one on Stack Exchange. I had to modify the files named:

by creating a copy in /app/code/local folder and changing one template file in order to get the correct values.

If I get some time I will look for the changes I made almost 6 years ago and post them here.

kanevbg commented 1 year ago

@ADDISON74 can you share, please?