5

I'm using Magento 2.4.1 and I want to retrieve the current quote in collectRates function in my Carrier model, but sometimes it will prompt an infinite loop error like this:

enter image description here

this is how i retrieve the current quote in My Carrier Model

class Standard extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
    \Magento\Shipping\Model\Carrier\CarrierInterface
{
   public function collectRates(RateRequest $request)
   { 
     $quote = $this->checkoutSession->getQuote();
     $subTotal = $quote->getData('subtotal_with_discount');
     $ddate = $quote->getShippingDeliveryDate(); // this is a custom column i made in quote table
   }
}

The reason to get quotes is that I need to retrieve the quote attribute value to do some calculation in the collect rates function

1
  • Good to see that you have resolved your issue :) Commented Jun 21, 2021 at 10:49

3 Answers 3

9

You can not directly get quote in collect rate.

The $this->checkoutSession->getQuote() will call your collectRates function at the end, so you will end up getting infinite loop.

the $request variable will also give you almost all the data you need, like

  • $request->getAllItems()
  • $request->getOrderSubtotal();
  • $request->getDestCity();
  • etc

So there is no direct way to get quote. This is not the end, you have an alternative, may be it will work for you. Try this code:

    /**
     * Do not use checkoutSession->getQuote()!!! it will cause infinite loop for
     * quotes with trigger_recollect = 1, see Quote::_afterLoad()
     */
    $items = $request->getAllItems();
    if (empty($items)) {
        return false;
    }

    /** @var \Magento\Quote\Model\Quote\Item $firstItem */
    $firstItem = reset($items);
    if (!$firstItem) {
        return false;
    }

    $quote = $firstItem->getQuote();
    if (!($quote instanceof \Magento\Quote\Model\Quote)) {
        return false;
    }

Hope this will help you.

1

Warning : Do not use $this->checkoutSession->getQuote(); cause it recursively calls your get collect method and you will have infinite loop.

You can also get current quote in collect rate method by load cart model, it always gives you quote of current session.

use  \Magento\Checkout\Model\Cart;

class CarrierExample extends AbstractCarrier implements CarrierInterface{
    protected $cart;

    public function __construct(
             Cart $cart
         ){
             $this->cart= $cart;
    }           
    
    public function collectRates(RateRequest $request){
        $quote = $this->cart->getQuote();
        $subTotal = $quote->getData('subtotal_with_discount');
        $ddate = $quote->getShippingDeliveryDate(); // this is a custom column i made in quote table
    }
}
1
  • For Magento 2.3.7 users: Another answer below mentions using Magento\Quote\Model\Quote, but on my version of Magento 2.3, only Magento\Checkout\Model\Cart::getQuote() works for me, the Quote accessed directly from collectRates is empty. Just putting this here for clarification, I assume the 2022 answer below is for M2.4. Commented Dec 13, 2022 at 12:38
0

Updated answer 2022, because the class Magento\Checkout\Model\Cart is deprecated, you have to use Magento\Quote\Model\Quote.

use Magento\Quote\Model\Quote;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Psr\Log\LoggerInterface;

class Standard extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements \Magento\Shipping\Model\Carrier\CarrierInterface 
{
    /** @var Quote */
    private $quote;

    public function __construct(
        Quote $quote,
        ScopeConfigInterface $scopeConfig,
        ErrorFactory $rateErrorFactory,
        LoggerInterface $logger,
        array $data = []
    ) {
          parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
          $this->quote = $quote;
    }

    public function collectRates(RateRequest $request)
    { 
        $subTotal = $this->quote->getData('subtotal_with_discount');
        $ddate = $this->quote->getShippingDeliveryDate();
    }
}
3
  • @jwswgtr, is this for Magento 2.4? I tried it on Magento 2.3 version and $this->quote has no data when called inside collectRates. Commented Dec 13, 2022 at 12:18
  • read the question again brother its for 2.4.1. Commented Dec 14, 2022 at 3:15
  • Ok thanks, just wanted confirmation. Added Magento 2.3 information on other comments. Commented Dec 14, 2022 at 9:18

Your Answer

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

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