Magento 2 додаткові дані до способу доставки


12

Я створюю новий спосіб доставки, і мені потрібно додати новий стовпець, щоб замовити тарифи на доставку. Дані надходять із налаштованих методів доставки, наприклад, опис методу. Або якесь поле введення, де клієнт може додати інформацію (дані, ймовірно, будуть збережені в котируванні та пізніше в порядку).

Мабуть, найпростіша частина всіх - це шаблон реалізації за допомогою

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 \ Цитата \ Модель \ Кошик \ ДоставкаМетодКонвертор модельToDataObject ()

це виглядало найбільш перспективно, але якщо я спробую додати до нього свій атрибут, нічого не станеться.

Отже, моє запитання: чи дійсно є спосіб додати нові дані до тарифів на доставку? У М1 це було можливо. Було б божевільно, якби M2 це було неможливо.

Є багато причин, чому це має бути можливим. Наприклад, якщо я хотів отримати метод магазину з декількома магазинами, що падають, або щось подібне.


Привіт, Якщо ви отримали рішення, можете поділитися?
Коніка

Ну, яке рішення для цього?
Піюш Дангре

Я чекаю цієї відповіді.
Дієго Квейроз

Відповіді:


6

Для цього потрібно додати опис як атрибут розширення, як показано нижче:

/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 додайте плагін для переосмислення моделіToDataObject () в 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;
    }
}

Після всього цього ви отримаєте цей опис на fronend як нижче:

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

Це не працює.
Дахук Мітеш

3

Відповідь з найвищим рейтингом не працює, оскільки він забув встановити значення "опис" всередині класу \ Magento \ Quote \ Model \ Quote \ Address \ Rate \ . Якщо ми не створимо плагін для встановлення значення опису для цього класу, то $ 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 setup: di: compile, інакше розширений атрибут не буде створений.

Ви можете прив’язати дані до вашого шаблону за допомогою цього:

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

Або як коментар, як це:

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

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


0

Вам потрібно оголосити імена методів у файлі інтерфейсу, шлях до цього файлу

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) ??? Ніколи цього не роби.
Піт Яворський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.