magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.5k stars 9.31k forks source link

Shopping Cart Price Rule for Free Shipping not working properly #8614

Closed i95devdivya closed 7 years ago

i95devdivya commented 7 years ago

Preconditions

  1. Magento CE 2.1.2, PHP Version 5.6.29, MYSQL Version 5.6.33

Steps to reproduce

  1. Enable Free Shipping Method and provide Minimum Order Amount as 9999999999 in Free Shipping method configuration
  2. Create Shopping Cart Price which will provide Free Shipping if subtotal greater than equal to $100
  3. Add any product of quantity 1 with price $80 to cart. Free shipping method will not display in Estimate Shipping and Tax as subtotal is $80 which is less than $100.
  4. Now update the same product's quantity to 2 in cart, now the cart subtotal is $160 which is greater than $100.In this case free shipping method displaying in Estimate Shipping and Tax.
  5. Now reduce the same product quantity to 1 in cart, now the subtotal is $80.

Expected result

  1. After reducing quantity to 1, Free Shipping method should not display in Estimate Shipping and Tax as subtotal is less than $100

Actual result

  1. Free Shipping displaying in Estimate Shipping and Tax even subtotal is less than $100
  2. Please check following screencast to get more clarity on this issue https://www.screencast.com/t/mifi3ZOXAA
i95devdivya commented 7 years ago

I resolved this issue by using checkout_cart_update_items_after, checkout_cart_save_after events. In that observer i wrote the following code inside execute() method. public function execute(\Magento\Framework\Event\Observer $observer) { $cart = $observer->getData('cart'); $quote = $cart->getData('quote'); $quote->getShippingAddress()->setFreeShipping(false); $quote->save(); }

Now it's working fine for me.

lbbrooks commented 7 years ago

Thank you @i95devdivya

2.1.5 and this is still needed in order to disqualify an order from free shipping when it previously qualified for free shipping and should not any longer.

leptoquark1 commented 7 years ago

I can confirm this Issue on 2.1.6.

@i95devdivya this workaround is fixing the issue temporary. Thank you.

Edit: You have missed handling the event sales_quote_remove_item since the issue remains when the "Remove Item" Link in cart was used.

gcampedelli commented 7 years ago

For me free shipping is not working properly either in 2.1.6.

My rules are only free shipping for some region, with any discount on product. But it display in every situation.

gcampedelli commented 7 years ago

It has a strange behavior. It was displaying all the time outside rules. It worked once and now it does not display. I'm not sure how to fix it. I read the fix, but I'm now really sure where to place the code. I don't have a module for it, because I see execute() method in many files. What exactly should I do to fix the issue?

oleg-onufer commented 7 years ago

Hi @i95devdivya. Thanks for reporting this issue. Internal ticket MAGETWO-70420 was created.

gcampedelli commented 7 years ago

I have a workaround for free shipping rule that works but there is a minor bug to adjust. Usually when we want to use free shipping we enable the method in backend. I set that disabled. I went to create a Cart rule for one region, 100% discount on product, matching products price is 0. Free shipping happens to appear following the specif rules. But when the user switch the zipcode, cart does not update rules, only when page is reloaded. But it is working better than when free shipping is enabled.

gcampedelli commented 7 years ago

Actually, the workaround solved my problem after setting priorities in cart rule.

Turv commented 7 years ago

Looks to be the same issue reported last year #6040

Adr79 commented 7 years ago

I can confirm this Issue in shopping cart price rule for free shipping not working properly 2.1.8

magento-engcom-team commented 7 years ago

@i95devdivya, thank you for your report. We were not able to reproduce this issue by following the steps you provided. If you'd like to update it, please reopen the issue. We tested the issue on 2.3.0-dev, 2.2.0, 2.1.9

srtrend commented 6 years ago

I have added cart rule for particular category https://aafiyat.in/all-islamic-books/all-deeniyat-books to free shipping now when i add non freeshipping product first and then free shipping product I don't see free shipping option which is perfect but when I add first freeshipping product and then non freeshipping product then both product goes for free shipping which is strange. please help

pemann commented 6 years ago

I can confirm, what @srtrend describes, occurs also in 2.2.3. I have free shipping cart rule "for matching items only", but I will get free shipping for whole order if the first item has free shipping rule applied. Problem is in OfflineShipping module at Model/Quote/Address/FreeShipping.php file at method isFreeShipping. Loop has logical problem here:

$addressFreeShipping = true;
$shippingAddress->setFreeShipping(0);

foreach ($items as $item) {
    ...
    $addressFreeShipping = $addressFreeShipping && $itemFreeShipping;

    if ($addressFreeShipping && !$item->getAddress()->getFreeShipping()) {
        $item->getAddress()->setFreeShipping(true);
    }
}

If the first items sets the free shipping, then it will never get cleared.

srtrend commented 6 years ago

@pemann Do you have any solution to it.

pemann commented 6 years ago

@srtrend no I don't have. The code where the free shipping is calculated is so... "unique"... that I cannot wrap my head around it :(

hunter-k commented 6 years ago

The following change worked for me:

foreach ($items as $item) {
...
$addressFreeShipping = $addressFreeShipping && $itemFreeShipping;

//if ($addressFreeShipping && !$item->getAddress()->getFreeShipping()) {
//     $item->getAddress()->setFreeShipping(true);
// }

$shippingAddress->setFreeShipping($addressFreeShipping && $itemFreeShipping);

}
pemann commented 6 years ago

Why was this closed? Is this fixed or forgotten? @magento-engcom-team

nickpiro commented 5 years ago

This is still not working in 2.2.5! Why is this closed?! I create a simple attribute "Free Shipping" with dropdown of 'Yes'. Create Cart Price Rule, set condition based on Free Shipping Attribute, Action Free Shipping for Matching Item Only, no free shipping. I've enabled and disabled 'Free Shipping' in Shipping Methods, I've let the system try the Free Shipping method from Fed-Ex. Nothing seems to work. This shouldn't have been closed.

rey8a commented 5 years ago

I am experiencing a similiar issue as nickpiro. I am using FedEx as my shipping merchant. I would like to only offer free shipping to the continental United States. I have enabled free shipping from Stores > Configuration >> Shipping Methods and created the Cart Rule

If ALL of these conditions are TRUE Shipping Country is United States Shipping State/Province is not Alaska Shipping State/Province is not Hawaii 

but it didn't work. It offers free shipping to all of the United Sates when it should only allow the continental United States. I then took a further step and added conditions for postal codes.

If ANY of these conditions are TRUE : Shipping Postcode greater than 00900 Shipping Postcode less than 96200 If ALL of these conditions are TRUE : Shipping Postcode equals or greater than 97000 Shipping Postcode less than 99500

Action Apply to Shipping Amount: Toggled to Yes Free Shipping: For shipment with matching items

Can someone please let me know how we can resolve this. This preventing us from going live.

bilalyounus commented 5 years ago

I was also facing this issue I fixed it using the following steps:

1- Move vendor/magento/module-tax/view/frontend/web/js/view/checkout/summary/shipping.js to your custom theme e.g. app/design/frontend/Vendor/Theme/Magento_Tax/web/js/view/checkout/summary/shipping.js.

2- Replace price = this.totals()['shipping_amount']; to price = quote.shippingMethod()['amount'];

3- Replace price = this.totals()['shipping_incl_tax']; to price = quote.shippingMethod()['price_incl_tax'];

Hope this solution would help you. :)

twistedatrocity commented 5 years ago

I wonder if this is part of the problem:

Next Exception: Report ID: webapi-5c379916d49a1; Message: Property "TriggerReload" does not have corresponding setter in class "Magento\Quote\Api\Data\AddressInterface"

I get this exception on checkout page when selecting the different shipping options AFTER one has been previously selected. Any further changes in shipping selections will not update the cart shipping price.

CE 2.1.16

KowsiganAtsayam commented 4 years ago

It is still not working. Can anybody tell what is the solution?

KowsiganAtsayam commented 4 years ago

I was also facing this issue I fixed it using the following steps:

1- Move vendor/magento/module-tax/view/frontend/web/js/view/checkout/summary/shipping.js to your custom theme e.g. app/design/frontend/Vendor/Theme/Magento_Tax/web/js/view/checkout/summary/shipping.js.

2- Replace price = this.totals()['shipping_amount']; to price = quote.shippingMethod()['amount'];

3- Replace price = this.totals()['shipping_incl_tax']; to price = quote.shippingMethod()['price_incl_tax'];

Hope this solution would help you. :)

Is it working for you? I replaced that code in the vendor files but not working.

KowsiganAtsayam commented 4 years ago

Kindly reopen this issue.

nickpiro commented 4 years ago

Yeah, this should be reopened.

Fresko112 commented 3 years ago

is there a solution?

apresources commented 2 years ago

I had the same problem and none of the above worked for me. The Free Shipping Rules we had set up were for if the Shipping Method was set to the default shipping method, and the was order above a certain amount according to the destination country.

There were 2 issues

It took a certain combination of steps for a customer to get free shipping, but it was possible.

The first issue was because the Shipping Method was not initially set when the rules were applied and therefore was not giving free shipping when it should have. The second issue was the the free shipping flag was not reset when the country was changed or the quantity updated.

Both were resolved with the same plugin, as follows

etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Quote\TotalsCollector">
        <plugin name="model_totals_collector_plugin" type="Vendor\Name\Plugin\Model\TotalsCollectorPlugin" sortOrder="1" disabled="false"/>
    </type>
</config>

and plugin code (uses Amasty Checkout config)

namespace Vendor\Name\Plugin\Model;

class TotalsCollectorPlugin
{
    /**
     * @param Amasty\Checkout\Model\Config
     */
    private $checkoutConfig;

    public function __construct(
        \Amasty\Checkout\Model\Config $checkoutConfig
    )
    {
        $this->checkoutConfig = $checkoutConfig;
    }

    public function beforeCollectAddressTotals(
        \Magento\Quote\Model\Quote\TotalsCollector $subject,
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Model\Quote\Address $address
    ) {
        if (!$address->getShippingMethod()) {
            $address->setShippingMethod($this->checkoutConfig->getDefaultShippingMethod());
        }
        $address->setFreeShipping("0");
        return [$quote, $address];
    }

}

Hope that helps someone