Magento 2 datos adicionales al método de envío

10

Estoy haciendo un nuevo método de envío y necesito agregar una nueva columna para pagar las tarifas de envío. Los datos provendrían de la configuración del método de envío personalizado, por ejemplo, la descripción del método. O algún campo de entrada donde el cliente puede agregar información (los datos probablemente se guardarían entre comillas y luego en orden).

Probablemente la parte más fácil de todo es implementar una plantilla usando

Magento_Checkout/web/template/shipping.html

Solo necesita esto

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

El problema es que no puedo entender cómo agregar datos personalizados. No es suficiente agregar esto:

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

Los datos para html provienen de js rates (), que obtiene datos de 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>

Después de esto, hay muchos pasos mientras que algo realmente se recopila. encontré

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

parecía lo más prometedor, pero si trato de agregarle mi atributo, no pasa nada.

Entonces, mi pregunta es, si realmente hay una manera de agregar nuevos datos a las tarifas de envío. En M1 fue posible. Sería una locura si M2 no fuera posible.

Hay muchas razones por las cuales esto debería ser posible. Por ejemplo, si quisiera hacer un método de recoger en la tienda con múltiples tiendas desplegables o algo similar.

Artis Z
fuente
Hola, si tienes la solución, ¿podrías compartir?
konika
Bueno, ¿alguna solución para esto?
Piyush Dangre
Estoy esperando esta respuesta.
Diego Queiroz

Respuestas:

5

Debe hacer esto agregando la descripción como un atributo de extensión como se muestra a continuación:

/etc/extension_attributes.xml debería ser así:

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

En el archivo etc / di.xml, agregue un complemento para anular modelToDataObject () en Magento \ Quote \ Model \ Cart \ ShippingMethodConverter como se muestra a continuación:

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

El archivo de complemento Vendor \ module \ Plugin \ Carrier \ Descripción.php debería ser así:

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

Después de todo esto, obtendrá esa descripción el viernes de la siguiente manera:

<div data-bind="text: method.extension_attributes.method_description"></div>
VIPIN A ROY
fuente
Esto no está funcionando.
Dhaduk Mitesh
1

La respuesta mejor calificada no funciona porque olvidó establecer el valor de "descripción" dentro de la clase \ Magento \ Quote \ Model \ Quote \ Address \ Rate . Si no creamos un complemento para establecer el valor de Descripción en esta clase, entonces $ rateModel-> getMethodDescription () siempre volverá vacío. Aquí hay una versión completa de la solución:

[Proveedor] / [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>

[Proveedor] / [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>

[Proveedor] / [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;
    }
}

Y finalmente:

[Proveedor] / [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;
    }
}

No olvide ejecutar bin / magento setup: di: compile, de lo contrario no se generará el atributo extendido.

Puede vincular los datos a su plantilla usando esto:

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

O como comentario, así:

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

Además, no olvide utilizar $ method-> setDescription ('Su descripción personalizada aquí') o $ method-> setData ('descripción', 'Su descripción personalizada aquí') dentro de su extensión Carrier personalizada (consulte la pregunta original para referencia).

Andresa Martins
fuente
-1

Debe declarar los nombres de los métodos en el archivo de interfaz, la ruta para este archivo es

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

Ejemplo:
declarar constante en la parte superior

const KEY_DESCRIPTION = 'description';  

luego defina el método de la siguiente manera

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

Luego debe asignar valores al siguiente archivo

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

como sigue

public function getDescription()
{
  return $this->_get(self::KEY_DESCRIPTION);
}
public function setDescription($desc)
{
  return $this->setData(self::KEY_DESCRIPTION, $desc);
}   
Ranjith Kumar
fuente
Agregar método a la API pública (vendor / magento / module-quote / Api / Data / ShippingMethodInterface.php) ??? Nunca hagas eso.
Pete Jaworski el