Magento 2 дополнительные данные к способу доставки

10

Я делаю новый способ доставки, и мне нужно добавить новый столбец, чтобы проверить стоимость доставки. Данные будут поступать из пользовательских настроек способа доставки, например, описание метода. Или какое-то поле ввода, в которое клиент может добавить информацию (данные, вероятно, будут сохранены в цитате, а затем по порядку).

Вероятно, самая простая часть всего - реализовать шаблон с помощью

Magento_Checkout/web/template/shipping.html

Это просто нужно

<div data-bind="text: method.description"></div>

Проблема в том, что я не могу понять, как добавить пользовательские данные. Недостаточно добавить это:

public function collectRates(RateRequest $request)
{
    if (!$this->isActive()) return false;

    $method = $this->rateMethodFactory->create();
    $method->setData('carrier', $this->getCarrierCode());
    $method->setData('carrier_title', $this->getConfigData('title'));
    $method->setData('method_title', $this->getConfigData('title'));
    $method->setData('method', $this->getCarrierCode());
    $method->setPrice($this->_price);
    $method->setData('cost', $this->_price);

    // custom
    $method->setData('description', $this->getConfigData('description'));

    $result = $this->rateResultFactory->create();
    $result->append($method);

    return $result;
}

Данные для html поступают из js rate (), которая получает данные из API:

<route url="/V1/carts/:cartId/shipping-methods" method="GET">
    <service class="Magento\Quote\Api\ShippingMethodManagementInterface" method="getList"/>
    <resources>
        <resource ref="Magento_Cart::manage" />
    </resources>
</route>

После этого есть много шагов, в то время как что-то действительно собирается. я нашел

Magento \ Цитата \ Модель \ Корзина \ ShippingMethodConverter modelToDataObject ()

это выглядело многообещающе, но если я попытаюсь добавить свой атрибут, ничего не произойдет.

Таким образом, мой вопрос, есть ли способ добавить новые данные к стоимости доставки? В М1 это было возможно. Было бы сумасшествием, если бы М2 это было невозможно.

Есть много причин, почему это должно быть возможно. Например, если я хотел сделать метод «забрать в магазине» с выпадающим списком нескольких магазинов или что-то подобное.

Artis Z
источник
Привет, если у вас есть решение, не могли бы вы поделиться?
Коника
Ну, какое-нибудь решение этого?
Пиюш Дангре
Я жду этот ответ.
Диего Кейроз

Ответы:

5

Вы должны сделать это, добавив описание в качестве атрибута расширения, как показано ниже:

/etc/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\Quote\Api\Data\ShippingMethodInterface">
        <attribute code="method_description" type="string" />
    </extension_attributes>
</config>

В файле etc / di.xml добавьте плагин для переопределения modelToDataObject () в Magento \ Quote \ Model \ Cart \ ShippingMethodConverter, как показано ниже:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Cart\ShippingMethodConverter">
        <plugin name="add_description_to_carrier" type="<Vendor>\<module>\Plugin\Carrier\Description" disabled="false" sortOrder="30"/>
    </type>
</config>

Файл плагина Vendor \ module \ Plugin \ Carrier \ Description.php должен выглядеть следующим образом:

<?php

namespace Vendor\module\Plugin\Carrier;

use Magento\Quote\Api\Data\ShippingMethodExtensionFactory;

/**
 * Class Description
 * 
 */
class Description
{
    /**
     * @var ShippingMethodExtensionFactory
     */
    protected $extensionFactory;

    /**
     * Description constructor.
     * @param ShippingMethodExtensionFactory $extensionFactory
     */
    public function __construct(
        ShippingMethodExtensionFactory $extensionFactory
    )
    {
        $this->extensionFactory = $extensionFactory;
    }

    /**
     * @param $subject
     * @param $result
     * @param $rateModel
     * @return mixed
     */
    public function afterModelToDataObject($subject, $result, $rateModel)
    {
        $extensionAttribute = $result->getExtensionAttributes() ?
            $result->getExtensionAttributes()
            :
            $this->extensionFactory->create()
        ;
        $extensionAttribute->setMethodDescription($rateModel->getMethodDescription());
        $result->setExtensionAttributes($extensionAttribute);
        return $result;
    }
}

После всего этого вы получите это описание на сайте, как показано ниже:

<div data-bind="text: method.extension_attributes.method_description"></div>
VIPIN A ROY
источник
Это не работает.
Дхадук Митеш
2

Ответ с самым высоким рейтингом не работает, потому что он забыл установить значение "description" внутри класса \ Magento \ Quote \ Model \ Quote \ Address \ Rate . Если мы не создадим плагин для установки значения Description для этого класса, то $ rateModel-> getMethodDescription () всегда будет возвращать пустое значение. Вот полная версия решения:

[Продавец] / [Модуль] /etc/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\Quote\Api\Data\ShippingMethodInterface">
        <attribute code="description" type="string" />
    </extension_attributes>
</config>

[Продавец] / [Модуль] /etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Cart\ShippingMethodConverter">
        <plugin name="add_description_to_method" type="<Vendor>\<module>\Plugin\Carrier\Description" disabled="false" sortOrder="30"/>
    </type>

<type name="Magento\Quote\Model\Quote\Address\Rate">
        <plugin name="add_description_to_method_rate" type="<Vendor>\<module>\Plugin\Quote\Address\Rate" disabled="false" sortOrder="3"/>
    </type>
</config>

[Продавец] / [Модуль] /Plugin/Carrier/Description.php

<?php

namespace Vendor\module\Plugin\Carrier;

use Magento\Quote\Api\Data\ShippingMethodExtensionFactory;


class Description
{
    /**
     * @var ShippingMethodExtensionFactory
     */
    protected $extensionFactory;

    /**
     * Description constructor.
     * @param ShippingMethodExtensionFactory $extensionFactory
     */
    public function __construct(
        ShippingMethodExtensionFactory $extensionFactory
    )
    {
        $this->extensionFactory = $extensionFactory;
    }

    /**
     * @param $subject
     * @param $result
     * @param $rateModel
     * @return mixed
     */
    public function afterModelToDataObject($subject, $result, $rateModel)
    {
        $extensionAttribute = $result->getExtensionAttributes() ?
            $result->getExtensionAttributes()
            :
            $this->extensionFactory->create()
        ;
        $extensionAttribute->setDescription($rateModel->getDescription());
        $result->setExtensionAttributes($extensionAttribute);
        return $result;
    }
}

И наконец:

[Продавец] / [Модуль] /Plugin/Quote/Address/Rate.php

<?php
namespace <Vendor>\<Module>\Plugin\Quote\Address;

class Rate
{
    /**
     * @param \Magento\Quote\Model\Quote\Address\AbstractResult $rate
     * @return \Magento\Quote\Model\Quote\Address\Rate
     */
    public function afterImportShippingRate($subject, $result, $rate)
    {
        if ($rate instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
            $result->setDescription(
                $rate->getDescription()
            );
        }

        return $result;
    }
}

Не забудьте запустить установку bin / magento: di: compile, иначе расширенный атрибут не будет сгенерирован.

Вы можете привязать данные к вашему шаблону, используя это:

<div data-bind="text: method.extension_attributes.description"></div>

Или как комментарий, как это:

<!-- ko text: $data.extension_attributes.description --><!-- /ko -->

Также не забудьте использовать $ method-> setDescription («Ваше пользовательское описание здесь») или $ method-> setData («description», «Ваше пользовательское описание здесь») внутри вашего собственного расширения Carrier (посмотрите на оригинальный вопрос для ссылка).

Андреса Мартинс
источник
-1

Вам необходимо объявить имена методов в файле интерфейса, путь к этому файлу

vendor/magento/module-quote/Api/Data/ShippingMethodInterface.php 

Пример:
объявить константу сверху

const KEY_DESCRIPTION = 'description';  

затем определите метод следующим образом

public function getDescription();
public function setDescription($desc);

Затем вам нужно присвоить значения следующему файлу

vendor/magento/module-quote/Model/Cart/ShippingMethod.php 

следующее

public function getDescription()
{
  return $this->_get(self::KEY_DESCRIPTION);
}
public function setDescription($desc)
{
  return $this->setData(self::KEY_DESCRIPTION, $desc);
}   
Ранджит Кумар
источник
Добавление метода к общедоступному API (vendor / magento / module-quote / Api / Data / ShippingMethodInterface.php) ??? Никогда не делай этого.
Пит Яворский