Dados adicionais do Magento 2 para o método de envio

10

Estou criando um novo método de envio e preciso adicionar uma nova coluna às taxas de envio da finalização da compra. Os dados viriam de configurações personalizadas do método de envio, por exemplo, descrição do método. Ou algum campo de entrada em que o cliente pode adicionar informações (os dados provavelmente seriam salvos em cotação e posteriormente em ordem).

Provavelmente, a parte mais fácil de tudo é implementar modelo usando

Magento_Checkout/web/template/shipping.html

Só precisa disso

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

O problema é que não consigo descobrir como adicionar dados personalizados. Não basta adicionar isso:

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

Os dados para html são provenientes de js rates (), que obtém dados da 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>

Depois disso, existem muitas etapas enquanto algo é coletado. eu encontrei

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

isso parecia o mais promissor, mas se eu tentar adicionar meu atributo a ele, nada acontece.

Então, minha pergunta é: se existe realmente uma maneira de adicionar novos dados às taxas de remessa? No M1 foi possível. Seria louco se M2 não fosse possível.

Existem muitas razões pelas quais isso deve ser possível. Por exemplo, se eu quisesse usar o método pick in store com várias lojas suspensas ou algo semelhante.

Artis Z
fonte
Olá, Se você conseguiu a solução, poderia compartilhar?
22717 konika
Bem, alguma solução para isso?
Piyush Dangre
Eu estou esperando esta resposta.
Diego Queiroz

Respostas:

5

Você precisa fazer isso adicionando descrição como um atributo de extensão, como abaixo:

/etc/extension_attributes.xml deve ser assim:

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

No arquivo etc / di.xml, adicione um plug-in para substituir modelToDataObject () em Magento \ Quote \ Model \ Cart \ Shipping \ ShippingMethodConverter como abaixo:

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

O arquivo de plug-in Vendor \ module \ Plugin \ Carrier \ Description.php deve ser assim:

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

Depois de tudo isso, você receberá essa descrição como abaixo:

<div data-bind="text: method.extension_attributes.method_description"></div>
VIPIN A ROY
fonte
Isto não está a funcionar.
Dhaduk Mitesh
1

A resposta com a melhor classificação não funciona porque ele esqueceu de definir o valor "description" dentro da classe \ Magento \ Quote \ Model \ Quote \ Address \ Rate . Se não criarmos um plug-in para definir o valor Descrição nessa classe, $ rateModel-> getMethodDescription () sempre retornará vazio. Aqui está uma versão completa da solução:

[Fornecedor] / [Módulo] /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>

[Fornecedor] / [Módulo] /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>

[Fornecedor] / [Módulo] /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;
    }
}

E finalmente:

[Fornecedor] / [Módulo] /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;
    }
}

Não se esqueça de executar o bin / magento setup: di: compile, caso contrário o atributo estendido não será gerado.

Você pode vincular os dados ao seu modelo usando este:

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

Ou como um comentário, como este:

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

Também não se esqueça de usar $ method-> setDescription ('Sua descrição personalizada aqui') ou $ method-> setData ('description', 'Sua descrição personalizada aqui') dentro de sua extensão de operadora personalizada (consulte a pergunta original para referência).

Andresa Martins
fonte
-1

Você precisa declarar os nomes dos métodos no arquivo de interface, o caminho para este arquivo é

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

Exemplo:
declarar constante na parte superior

const KEY_DESCRIPTION = 'description';  

defina o método da seguinte maneira

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

Então você precisa atribuir valores ao seguinte arquivo

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

do seguinte modo

public function getDescription()
{
  return $this->_get(self::KEY_DESCRIPTION);
}
public function setDescription($desc)
{
  return $this->setData(self::KEY_DESCRIPTION, $desc);
}   
Ranjith Kumar
fonte
Adicionando método à API pública (vendor / magento / module-quote / Api / Data / ShippingMethodInterface.php) ??? Nunca faça isso.
Pete Jaworski