2

I create one plugin Vendor\Test\Plugin\Shipping for model Magento\Shipping\Model\Shipping.php using di.xml

app/code/Vendor/Test/etc/di.xml

<type name="Magento\Shipping\Model\Shipping">
    <plugin name="shipping_test" type="Vendor\Test\Plugin\Shipping" sortOrder="1"/>
</type>

app/code/Vendor/Test/Plugin/Shipping.php

<?php

namespace Vendor\Test\Plugin;

use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Model\Quote\Address\RateRequest;
//use Magento\Shipping\Model\Rate\Result;
use Magento\Checkout\Model\Cart;
use Vendor\Test\Helper\Data;
use Magento\Quote\Model\Quote\Address\RateResult\Error;
use Magento\Shipping\Model\Shipment\Request;
use Magento\Sales\Model\Order\Shipment;
use Magento\Quote\Model\Quote\Address\RateCollectorInterface;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Shipping
{

    protected $_code='Shipping';

    protected $_rateResultFactory;

    protected $_rateMethodFactory;

    protected $_result;

    protected $_rateCollector;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Framework\App\Filesystem\DirectoryList $directory_list,
        \Vendor\Test\Helper\Data $helper,
        \Magento\Framework\App\ResourceConnection $resourceConnection,
        RateCollectorInterface $rateCollector,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        $this->directory_list = $directory_list;
        $this->cart = $cart;
        $this->helper = $helper;
        $this->resourceConnection = $resourceConnection;
        $this->_rateCollector = $rateCollector;
    }

    public function getAllowedMethods()
    {
        $group_info=$this->helper->getAllMethods();
        $carriers=array();
        foreach ($group_info as &$carrier) {
            $carriers[$group_info['label']]=$group_info['label'];
        }
        return $carriers;
    }

    public function afterCollectRates(RateRequest $request)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerSession = $objectManager->create('Magento\Customer\Model\Session');

        if ($customerSession->isLoggedIn()) {
            $gid=$customerSession->getCustomerGroupId();
            $group_info=$this->helper->getGroupData($gid);
        }

        $err = null;
        $result = $this->_rateCollector->create()->collectRates($request)->get‌​Result();
        $method = $this->_rateMethodFactory->create();
        $method->setCarrier('Shipping');
        $method->setCarrierTitle('sdtgd');
        $method->setMethod('Shipping');
        $method->setMethodTitle('dryfyu');
        $amount=0;

        return $result;
    }

}

?>

But i got the below error. What is issue in this code ?

<b>Fatal error</b>:  Uncaught TypeError: Argument 1 passed to Vendor\Test\Plugin\Shipping
::afterCollectRates() must be an instance of Magento\Quote\Model\Quote\Address\RateRequest, instance
 of Magento\Shipping\Model\Shipping\Interceptor given, called in /var/www/html/magento/m2/mage2
/vendor/magento/framework/Interception/Interceptor.php on line 152 and defined in /var/www/html/magento/m2/mage2/app/code/Vendor/Test/Plugin/Shipping.php:103
Stack trace:
#0 /var/www/html/magento/m2/mage2/vendor/magento/framework/Interception/Interceptor.php(152
): Vendor\Test\Plugin\Shipping-&gt;afterCollectRates(Object(Magento\Shipping\Model\Shipping
\Interceptor), Object(Magento\Shipping\Model\Shipping\Interceptor))
#1 /var/www/html/magento/m2/mage2/var/generation/Magento/Shipping/Model/Shipping/Interceptor
.php(78): Magento\Shipping\Model\Shipping\Interceptor-&gt;___callPlugins('collectRates', Array, Array
)
#2 /var/www/html/magento/m2/mage2/vendor/magento/modul in <b>/var/www/html/magento/m2/mage2
/app/code/Vendor/Test/Plugin/Shipping.php</b> on line <b>103</b>
2

Your code should be like this:

use Magento\Quote\Model\Quote\Address\RateCollectorInterface;
use Magento\Quote\Model\Quote\Address\RateRequest;

class Shipping
{
    /**
     * @var string
     */
    protected $_code = 'Shipping';

    /**
     * @var \Magento\Shipping\Model\Rate\ResultFactory
     */
    protected $_rateResultFactory;

    /**
     * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
     */
    protected $_rateMethodFactory;

    /**
     * @var
     */
    protected $_result;

    /**
     * @var RateCollectorInterface
     */
    protected $_rateCollector;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Framework\App\Filesystem\DirectoryList $directory_list,
        \Magento\Framework\App\ResourceConnection $resourceConnection,
        RateCollectorInterface $rateCollector,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        $this->directory_list = $directory_list;
        $this->cart = $cart;
        $this->resourceConnection = $resourceConnection;
        $this->_rateCollector = $rateCollector;
    }

    /**
     * @param \Magento\Shipping\Model\Shipping $subject
     * @param $collectRatesResult
     * @return RateCollectorInterface
     */
    public function afterCollectRates(
        $subject,
        $collectRatesResult
    ) {
        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $collectRatesResult->getResult();

        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();

        $method->setCarrier('shipping');
        $method->setCarrierTitle('Title');
        $method->setMethod('shipping');
        $method->setMethodTitle('Method Title');

        $amount = 100;
        $method->setPrice($amount);
        $method->setCost($amount);

        $result->append($method);

        return $collectRatesResult;
    }
}

Result on cart page:

Result on cart page

Both parameters: $subject and $collectRatesResult are instances of the \Magento\Shipping\Model\Shipping class. There is no need to create a new result object using factory, because it already exists inside the $collectRatesResult object:

debug

You should just add your method to the existing result.

NOTE: important thing is you need to have the normal carrier with code you are using in the $method->setCarrier('shipping'); (in the example the code is shipping)

  • It's working fine.. Thank you @SiarheyUchukhlebau – Payal Patel Sep 16 '16 at 8:58
  • 1
    @PayalPatel I was glad to help :) – Siarhey Uchukhlebau Sep 16 '16 at 8:59
  • 1
    @PayalPatel Please, check new note at the end of the answer. It is important to have a normal carrier to make it work. – Siarhey Uchukhlebau Sep 16 '16 at 9:15
  • Ok, I got it @SiarheyUchukhlebau – Payal Patel Sep 16 '16 at 9:22
0

you need to define your method like this:

public function afterCollectRates(
    \Magento\Shipping\Model\Shipping $subject,
    RateRequest $request
) {
    //your code here.
}
  • I already did @Marius, When i put 2 arguments in afterCollectRates method i got error Uncaught TypeError: Argument 2 passed – Payal Patel Sep 16 '16 at 8:16
0

For creating an After plugin you will need to pass 2 parameter.

So in your case for the method afterCollectRatesit should take to 2 parameters:

public function afterCollectRates(
    \Magento\Shipping\Model\Shipping $subject,
    \Magento\Quote\Model\Quote\Address\RateRequest $request
) {
    //your code here.
}

Here:

  • $subject is the object of the \Magento\Shipping\Model\Shipping class through which you can access public properties/methods of the class
  • $request is the instance returned by the \Magento\Shipping\Model\Shipping::collectRates()

And always remember to flush the magento cache whenever creating or modifying Plugins (Interceptors)

php bin/magento cache:flush

Devdoc Reference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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