1

When I get price data from Quote extension_attributes and then set this price to method price, getRates returns 0 for this shipping method instead price.

Magento CE 2.2.3

My code:

Setup extension attributes:

extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
        <attribute code="pickpoint_city" type="string"/>
        <attribute code="pickpoint_region" type="string"/>
        <attribute code="pickpoint_address" type="string"/>
        <attribute code="pickpoint_cost1" type="string"/>
        <attribute code="pickpoint_cost2" type="string"/>
        <attribute code="pickpoint_cost3" type="string"/>
        <attribute code="pickpoint_cost4" type="string"/>
        <attribute code="pickpoint_cost5" type="string"/>
        <attribute code="pickpoint_cost6" type="string"/>
        <attribute code="pickpoint_cost7" type="string"/>
        <attribute code="pickpoint_cost8" type="string"/>
        <attribute code="pickpoint_name" type="string"/>
        <attribute code="pickpoint_shop_id" type="string"/>
        <attribute code="pickpoint_operator_id" type="string"/>
        <attribute code="pickpoint_operator" type="string"/>
    </extension_attributes>
</config>

Save extension attributes

<?php
class ShippingInformationManagement
{
    protected $quoteRepository;
    protected $request;
    public function __construct(
        \Magento\Quote\Model\QuoteRepository $quoteRepository,
        \Magento\Quote\Model\Quote\Address\RateRequest $request
    ) {
        $this->quoteRepository = $quoteRepository;
        $this->request = $request;
    }
    /**
     * @param \Magento\Checkout\Model\ShippingInformationManagement $subject
     * @param $cartId
     * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
     */
    public function beforeSaveAddressInformation(
        \Magento\Checkout\Model\ShippingInformationManagement $subject,
        $cartId,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
    ) {
        $extAttributes = $addressInformation->getExtensionAttributes();

        $pickpointCity = $extAttributes->getPickpointCity();
        $pickpointRegion = $extAttributes->getPickpointRegion();
        $pickpointAddress = $extAttributes->getPickpointAddress();
        $pickpointCost1 = $extAttributes->getPickpointCost1();
        $pickpointCost2 = $extAttributes->getPickpointCost2();
        $pickpointCost3 = $extAttributes->getPickpointCost3();
        $pickpointCost4 = $extAttributes->getPickpointCost4();
        $pickpointCost5 = $extAttributes->getPickpointCost5();
        $pickpointCost6 = $extAttributes->getPickpointCost6();
        $pickpointCost7 = $extAttributes->getPickpointCost7();
        $pickpointCost8 = $extAttributes->getPickpointCost8();
        $pickpointName = $extAttributes->getPickpointName();
        $pickpointShopId = $extAttributes->getPickpointShopId();
        $pickpointOperatorId = $extAttributes->getPickpointOperatorId();
        $pickpointOperator = $extAttributes->getPickpointOperator();

        $quote = $this->quoteRepository->getActive($cartId);

        $quote->setPickpointCity($pickpointCity);
        $quote->setPickpointRegion($pickpointRegion);
        $quote->setPickpointAddress($pickpointAddress);
        $quote->setPickpointCost1($pickpointCost1);
        $quote->setPickpointCost2($pickpointCost2);
        $quote->setPickpointCost3($pickpointCost3);
        $quote->setPickpointCost4($pickpointCost4);
        $quote->setPickpointCost5($pickpointCost5);
        $quote->setPickpointCost6($pickpointCost6);
        $quote->setPickpointCost7($pickpointCost7);
        $quote->setPickpointCost8($pickpointCost8);
        $quote->setPickpointName($pickpointName);
        $quote->setPickpointShopId($pickpointShopId);
        $quote->setPickpointOperatorId($pickpointOperatorId);
        $quote->setPickpointOperator($pickpointOperator);
    }
}
?>

Get extension attribute in collectRates method:

<?php
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

class DeliverySvyaznoyEuroset extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
    \Magento\Shipping\Model\Carrier\CarrierInterface
{

    protected $_code = 'deliverysvyaznoyeuroset';

    protected $_isFixed = true;

    protected $_rateResultFactory;

    protected $_rateMethodFactory;

    protected $_checkoutSession;

    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\Session $checkoutSession,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        $this->_checkoutSession = $checkoutSession;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        $result = $this->_rateResultFactory->create();

        $method = $this->_rateMethodFactory->create();

        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));

        $method->setMethod($this->_code);
        $method->setMethodTitle($this->getConfigData('name'));

        $amount = $this->getPrice();

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

        $result->append($method);

        return $result;
    }

    public function getAllowedMethods()
    {
        return ['flatrate' => $this->getConfigData('name')];
    }

    public function getPrice() {
        $quote = $this->_checkoutSession->getQuote();
        $amount = $quote->getPickpointCost1(); //returns correct price, for example, 149
        return $amount;
    }
}
?>

Result:

Selected shipping method with 0 shipping price :(

getRates function from shipping-rates-processor/new-address.js returns data with 0 amount for this method:

amount: 0
available: true
base_amount: 0
carrier_code: "deliverysvyaznoyeuroset"
carrier_title: "Пункты самовывоза Евросеть / Связной"
error_message: ""
method_code: "deliverysvyaznoyeuroset"
method_title: "Пункты самовывоза Евросеть / Связной"
price_excl_tax: 0
price_incl_tax: 0

But saveShippingInformation function from shipping-save-information/default.js returns data with correct shipping price:

base_shipping_amount: 149
base_shipping_discount_amount: 0
base_shipping_incl_tax: 149
...
shipping_amount: 149
shipping_discount_amount: 0
shipping_incl_tax: 149

Please help!

0

Okay, I found the answer.

Its because getRates start and stop working BEFORE starts saveShippingInformation. So we have empty data while getRates (and collectRates method in shipping method) work.

We need to extend Magento\Quote\Api\Data\AddressInterface instead.

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.