1

I need to set free shipping in observer, under certain very specific conditions. I can't have free shipping enabled in the back end because customers shouldn't be able to select it.

I already tried these things with no success:

1) set free shipping on address directly in observer. It changes to true but on next call it reverts back to false(0) when checked with getFreeShipping

$address = $quote->getShippingAddress();
$address->setFreeShipping(true);

2) Magento\Quote\Model\Quote\Address:985 requestShippingRates method. Hard-code

$request->setFreeShipping(true);

3) Magento\Quote\Model\Quote\Address\FreeShipping:16 Replace return false with true. This method looks unfinished by the way.

4) Magento\Quote\Model\Quote\Address\Total\Shipping:159. Hard-code:

$address->setFreeShipping(true);

It's equivalent to attempt number 3.

None of these worked. I would appreciate any suggestions. What can I try next? Which class to override?

This is a 'duplicate' of Magento 1 questions:

1 Answer 1

2
$address->setFreeShipping(true); 

should work if you apply it before the customer chooses the shipping method. otherwise, you have to play with order level or quote level

quote level

        $totals = 0;
        $quoteItems = $quote->getItemsCollection();
        foreach ($quoteItems as $_quoteItem) {
            $totals += $_quoteItem->getRowTotal();
        }

foreach ($quote->getAllAddresses() as $address) {
                    if ($address->getAddressType() == "shipping") {
                        $address->setShippingMethod('flatrate_flatrate');
                        $address->setCollectShippingRates(true);
                        $address->setSubtotal($totals);
                        $address->setBaseSubtotal($totals);
                        $address->setSubtotalInclTax($totals);
                        $address->setGrandTotal($totals);
                        $address->setShippingAmount(0);
                        $address->setBaseShippingAmount(0);
                        $address->setShippingInclTax(0);
                        $address->setBaseShippingInclTax(0);
                        $address->setBaseGrandTotal($totals);
                        $address->setDiscountAmount(0);
                        $address->setBaseDiscountAmount(0);
                        $address->save();
                    }

                }

or order level

if (($order->getBaseShippingAmount() > 0 ) {
                $order
                    ->setBaseTotalDue($order->getBaseTotalDue() - $order->getBaseShippingAmount())
                    ->setBaseGrandTotal($order->getBaseGrandTotal() - $order->getBaseShippingAmount())
                    ->setGrandTotal($order->getGrandTotal() - $order->getBaseShippingAmount())
                    ->setShippingAmount(0)
                    ->setShippingTaxAmount(0)
                    ->setBaseShippingAmount(0)
                    ->save();
            }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.