Entradas

¿Cómo crear un método de envío personalizado en Magento 2X?

, ,

A menudo hemos topado con el escenario en el cual un cliente va a trabajar con un operador logístico que no posee integración con Magento. Cuando esto sucede, lo más práctico es crear un método de envío que integre toda su operativa al máximo posible, para que el flujo diario sea transparente para el cliente.

Incluso en los casos que el operador no tenga un Api al cual conectar, nos puede venir bien hacer un método personalizado para tener nuestro cálculo de portes, ya que es posible que ninguno de los módulos de envío genéricos de Magento nos acople al 100%.

Vamos a hacer un método de envío sencillo, y explicaremos las funciones mínimas para integrar el servicio en Magento.

Estructura del módulo

app/code/ Gsoft / Cps /etc/ config.xml
app/code/ Gsoft / Cps /etc/adminhtml/system.xml
app/code/ Gsoft / Cps /Model/Carrier/Shipping.php
app/code/ Gsoft / Cps /composer.php
app/code/ Gsoft / Cps /registration.php

Solo con estos archivos ya tenemos un módulo de envío plenamente funcional. Vamos a ver el contenido de cada uno de ellos:

Los 2 primeros archivos son de sobra conocidos, y son requeridos en todos los módulos:

app/code/ Gsoft / Cps /registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
‘Gsoft_Cps’,
__DIR__
);

app/code/ Gsoft / Cps /composer.php

{
«name»: «gsoft/cps»,
«description»: «»,
«require»: {
«php»: «~5.5.0|~5.6.0|~7.0.0»,

«magento/magento-composer-installer»: «*»
},
«suggest»: {

},
«type»: «magento2-module»,
«version»: «0.1.0»,
«license»: [

],
«autoload»: {
«files»: [
«registration.php»
],
«psr-4»: {
«Gsoft\\Cps\\»: «»
}
},
«extra»: {
«map»: [
[
«*»,
«Gsoft/Cps»
]
]
}
}

app/code/ Gsoft / Cps /etc/adminhtml/System/config.xml

<?xml version=»1.0″?>
<config xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» xsi:noNamespaceSchemaLocation=»urn:magento:module:Magento_Config:etc/system_file.xsd»>
<system>
<section id=»carriers» translate=»label» type=»text» sortOrder=»320″ showInDefault=»1″ showInWebsite=»1″ showInStore=»1″>
<group id=»cps» translate=»label» type=»text» sortOrder=»0″ showInDefault=»1″ showInWebsite=»1″ showInStore=»1″>
<label>CPS Shipping Method</label>
<field id=»active» translate=»label» type=»select» sortOrder=»1″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″ canRestore=»1″>
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id=»name» translate=»label» type=»text» sortOrder=»3″ showInDefault=»1″ showInWebsite=»1″ showInStore=»1″ canRestore=»1″>
<label>Method Name</label>
</field>
<field id=»handling_type» translate=»label» type=»select» sortOrder=»7″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″ canRestore=»1″>
<label>Calculate Handling Fee</label>
<source_model>Magento\Shipping\Model\Source\HandlingType</source_model>
</field>
<field id=»handling_fee» translate=»label» type=»text» sortOrder=»8″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″>
<label>Handling Fee</label>
<validate>validate-number validate-zero-or-greater</validate>
</field>
<field id=»sort_order» translate=»label» type=»text» sortOrder=»100″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″>
<label>Sort Order</label>
</field>
<field id=»title» translate=»label» type=»text» sortOrder=»2″ showInDefault=»1″ showInWebsite=»1″ showInStore=»1″ canRestore=»1″>
<label>Title</label>
</field>
<field id=»sallowspecific» translate=»label» type=»select» sortOrder=»90″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″ canRestore=»1″>
<label>Ship to Applicable Countries</label>
<frontend_class>shipping-applicable-country</frontend_class>
<source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
</field>
<field id=»specificcountry» translate=»label» type=»multiselect» sortOrder=»91″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″>
<label>Ship to Specific Countries</label>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<can_be_empty>1</can_be_empty>
</field>
<field id=»showmethod» translate=»label» type=»select» sortOrder=»92″ showInDefault=»1″ showInWebsite=»1″ showInStore=»0″>
<label>Show Method if Not Applicable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<frontend_class>shipping-skip-hide</frontend_class>
</field>
<field id=»specificerrmsg» translate=»label» type=»textarea» sortOrder=»80″ showInDefault=»1″ showInWebsite=»1″ showInStore=»1″ canRestore=»1″>
<label>Displayed Error Message</label>
</field>
</group>
</section>
</system>
</config>

 

Este fichero define todas las opciones disponibles que tendrá el módulo dentro del apartado ventas > métodos de envío de Magento:

métodos de envío Magento

 

app/code/ Gsoft / Cps /etc/config.xml

 

<?xml version=»1.0″?>
<config xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance» xsi:noNamespaceSchemaLocation=»urn:magento:module:Magento_Store:etc/config.xsd»>
<default>
<carriers>
<cps>
<active>1</active>
<sallowspecific>0</sallowspecific>
<model>Gsoft\Cps\Model\Carrier\Shipping</model>
<name>Envío personalizado</name>
<title>Cps</title>
<specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
<handling_type>F</handling_type>
</cps>
</carriers>
</default>
</config>

 

Este fichero declara nuestro módulo, y preasigna el valor de las opciones definidas en el fichero system.xml

app/code/ Gsoft / Cps /Model/Carrier/Shipping.php

 

<?php
namespace Gsoft\Cps\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

class Shipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
\Magento\Shipping\Model\Carrier\CarrierInterface
{
/**
* @var string
*/
protected $_code = ‘cps’;

/**
* @var \Magento\Shipping\Model\Rate\ResultFactory
*/
protected $_rateResultFactory;

/**
* @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
*/
protected $_rateMethodFactory;

protected $quote;

/**
* Shipping constructor.
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface          $scopeConfig
* @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory  $rateErrorFactory
* @param \Magento\Shipping\Model\Rate\ResultFactory                  $rateResultFactory
* @param array                                                       $data
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
\Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,            array $data = []
) {
$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}

/**
* get allowed methods
* @return array
*/
public function getAllowedMethods()
{
$methods=[‘custom’=>’Custom’];
return $methods;
}

/**
* @return float
*/
private function getShippingPrice(RateRequest $request)
{
//Esta función es la que se encargará de calcular la tarifa, en función de los parámetros recibidos en $request
$shippingPrice = 5;//precio fijo a 5

return $shippingPrice;
}

/**
* @param RateRequest $request
* @return bool|Result
*/
public function collectRates(RateRequest $request)
{
if (!$this->getConfigFlag(‘active’)) {
return false;
}

/** @var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->_rateResultFactory->create();
foreach($this->getAllowedMethods() as $code=>$name) {

/** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
$method = $this->_rateMethodFactory->create();
$method->setCarrier($this->_code);
$method->setCarrierTitle($this->getConfigData(‘title’));

$method->setMethod($code);
$method->setMethodTitle($name);

$amount = $this->getShippingPrice($request);
if ($amount === false) return false;
$method->setPrice($amount);
$method->setCost($amount);

$result->append($method);
}

return $result;
}    public function isTrackingAvailable(){  return false;    }
}

 

Este fichero contiene la funcionalidad de nuestro método de envío. La función getShippingPrice es la que se encarga de hacer el cálculo de la tarifa en base a los parámetros recibidos en la variable $request. Esta variable contiene todos los datos de destino del pedido, así como el peso del pedido.

Si pudiéramos hacer una integración con el operador logístico, querríamos que el tracking se pudiera sincronizar con Magento, para poder enviarle los emails al cliente con su código de tracking incorporado. Para ello, deberíamos devolver true en la función “isTrackingAvailable”,  y añadir una nueva función:

public function getTrackingInfo($tracking)
{

$info = array();

$result = {FUNCION QUE CONECTA AL API Y OBTIENE TODO EL TRACKING LOG}
    if ($result instanceof Mage_Shipping_Model_Tracking_Result) {
if ($trackings = $result->getAllTrackings()) {
return $trackings[0];
}
} elseif (is_string($result) && !empty($result)) {
return $result;
}

return false;

}

 

Esta función devuelve un array con todos los cambios de estado de la mercancía, y Magento la utilizará para mostrar el historial del tracking en el pedido, tanto en la zona de cliente como en el backend.

Sólo con estos ficheros ya tenemos un módulo de envío personalizado operativo para Magento 2X. Magento te facilita mucho la operativa, pero que te puedas concentrar en la complejidad que requiera el cálculo de tarifas o la integración con el operador logístico.

Si necesitas integrar un operador logístico con tu Magento 1 o Magento 2, contacta con Gsoft Innova. Tenemos múltiples módulos ya desarrollados, ampliamente testeados y en funcionamiento desde hace tiempo para operadores como GLS o Spring entre otros.

La logística en el ecommerce: descubre por qué y cómo te puede ayudar a crecer

,

La idea de la satisfacción del cliente es tan antigua como el negocio mismo. Un cliente feliz vuelve, y si lo has hecho bien, trae a sus amigos.

La logística en el ecommerce

El desafío para las empresas de comercio electrónico es mayor, ya que no tienen interacción directa con sus clientes a lo largo de todo el proceso de compra.

Esta es la razón por la cual los aspectos tangibles de tu negocio son cruciales, siendo la entrega la principal entre ellos. Es el punto donde tu negocio y las expectativas de tus clientes se encuentran físicamente.

Para las empresas de comercio electrónico, eso significa entrega a tiempo. Asegurarte de que el paquete llegue a tiempo podría ser la diferencia entre un cliente perdido y un embajador de marca a largo plazo.

La triste realidad de los negocios es que cuando las personas tienen una buena experiencia, tienden a quedársela para sí mismos. Pero ¿y si tienen una mala? Se lo dicen a todos. Entregas retrasadas incluidas. Según  algunos estudios las personas que han tenido una mala experiencia con una empresa tienen un 50% más de probabilidades de compartirla en las redes sociales que aquellas que tuvieron una buena experiencia.

Si bien la proliferación de los medios sociales ha supuesto una oportunidad para las empresas para conectar con sus clientes, también ha proporcionado a los clientes una amplia plataforma para desahogar las frustraciones y propagar la negatividad. Estos foros se han convertido en fuentes fiables de información para otros clientes potenciales y, en cierta medida, su reputación se basa en ellos.

Una buena política de envíos y devoluciones favorece la mejora de la confianza de los usuarios. Sin embargo, sino se respalda con una buena logística en el ecommerce no tiene sentido. Se trata de trabajar para que no haya demora desde el momento en que tu cliente completa su pedido hasta el paquete llega a su puerta.

Logística en el ecommerce: el problema con las devoluciones

Las devoluciones de producto (80%) solo se ven superadas porque el producto llegue en perfectas condiciones (89%) en la lista de razones para elegir un ecommerce.

Las devoluciones son siempre una molestia para las tiendas online, ya que cuesta mucho tiempo y dinero procesarlas. Pero también para el usuario.

Un pedido no constituye una venta

En términos prácticos, un pedido por Internet no constituye un ingreso comercial, sino que muestra el interés de los clientes en realizar una compra. Por lo tanto, a lo sumo representa una oportunidad de venta. Desde esta perspectiva, la logística en el ecommerce vuelve a ser fundamental. Que el producto llegue a tiempo, en perfectas condiciones, que el cliente pueda rastrear el estado del pedido, las alertas de progreso de entrega a través de SMS o correo electrónico en tiempo real directamente al consumidor… son algunas de las características que harán que tu pedido se convierta en una venta.

¿Y si al final no es así? La logística en el ecommerce es de nuevo la clave. Puede que hoy no te compre pero si se ha quedado con un buen sabor de boca, volverá. Haz que la devolución sea una experiencia sencilla y rápida y así promoverás su lealtad.