Dodatkowe dane Magento 2 do metody wysyłki

12

Wprowadzam nową metodę wysyłki i muszę dodać nową kolumnę, aby sprawdzić stawki wysyłki. Dane pochodzą z niestandardowych ustawień metody wysyłki, na przykład opisu metody. Lub jakieś pole wejściowe, w którym klient może dodać informacje (dane prawdopodobnie zostaną zapisane w ofercie, a później w kolejności).

Prawdopodobnie najłatwiejszą częścią jest wdrożenie szablonu przy użyciu

Magento_Checkout/web/template/shipping.html

Po prostu tego potrzebuje

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

Problem w tym, że nie mogę wymyślić, jak dodać niestandardowe dane. Nie wystarczy dodać to:

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;
}

Dane do html pochodzą z js rate (), który pobiera dane z 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>

Po tym jest wiele kroków, podczas gdy coś faktycznie się zbiera. znalazłem

Magento \ Quote \ Model \ Cart \ ShippingMethodConverter modelToDataObject ()

wyglądało to najbardziej obiecująco, ale jeśli spróbuję dodać do niego mój atrybut, nic się nie stanie.

Więc moje pytanie brzmi: czy rzeczywiście istnieje sposób na dodanie nowych danych do stawek wysyłki? W M1 było to możliwe. Byłoby szalone, gdyby M2 nie było możliwe.

Jest wiele powodów, dla których powinno to być możliwe. Na przykład, jeśli chciałbym wybrać metodę odbioru w sklepie z rozwijanymi wieloma sklepami lub coś podobnego.

Artis Z
źródło
Cześć. Jeśli masz rozwiązanie, możesz je udostępnić?
konika
Cóż, jakieś rozwiązanie tego?
Piyush Dangre,
Czekam na tę odpowiedź.
Diego Queiroz,

Odpowiedzi:

6

Musisz to zrobić, dodając opis jako atrybut rozszerzenia, jak poniżej:

/etc/extension_attributes.xml powinno wyglądać tak:

<?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>

W pliku etc / di.xml dodaj wtyczkę do przesłonięcia modelToDataObject () w Magento \ Quote \ Model \ Cart \ ShippingMethodConverter jak poniżej:

<?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>

Plik wtyczki Vendor \ module \ Plugin \ Carrier \ Description.php powinien wyglądać tak:

<?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;
    }
}

Po tym wszystkim otrzymasz ten opis na fronend, jak poniżej:

<div data-bind="text: method.extension_attributes.method_description"></div>
VIPIN ROY
źródło
To nie działa.
Dhaduk Mitesh
3

Odpowiedź najwyżej oceniana nie działa, ponieważ zapomniał ustawić wartość „opis” w klasie \ Magento \ Quote \ Model \ Quote \ Address \ Rate . Jeśli nie utworzymy wtyczki, aby ustawić wartość Opis dla tej klasy, wówczas $ rateModel-> getMethodDescription () zawsze zwróci pusty. Oto w pełni działająca wersja rozwiązania:

[Sprzedawca] / [Moduł] /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>

[Sprzedawca] / [Moduł] /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>

[Sprzedawca] / [Moduł] /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;
    }
}

I w końcu:

[Sprzedawca] / [Moduł] /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;
    }
}

Nie zapomnij uruchomić instalatora bin / magento: di: compile, w przeciwnym razie rozszerzony atrybut nie zostanie wygenerowany.

Możesz powiązać dane ze swoim szablonem za pomocą:

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

Lub jako komentarz, jak poniżej:

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

Nie zapomnij także użyć metody $ method-> setDescription („Twój niestandardowy opis tutaj”) lub $ method-> setData („opis”, „Twój niestandardowy opis tutaj”) wewnątrz niestandardowego rozszerzenia Carrier (spójrz na oryginalne pytanie dotyczące odniesienie).

Andresa Martins
źródło
0

Musisz zadeklarować nazwy metod w pliku interfejsu, ścieżka do tego pliku to

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

Przykład:
Stała deklaracji u góry

const KEY_DESCRIPTION = 'description';  

następnie zdefiniuj metodę w następujący sposób

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

Następnie musisz przypisać wartości do następującego pliku

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

następująco

public function getDescription()
{
  return $this->_get(self::KEY_DESCRIPTION);
}
public function setDescription($desc)
{
  return $this->setData(self::KEY_DESCRIPTION, $desc);
}   
Ranjith Kumar
źródło
Dodanie metody do publicznego interfejsu API (vendor / magento / module-quote / Api / Data / ShippingMethodInterface.php) ??? Nigdy tego nie rób.
Pete Jaworski