Configurando Restrições de Envio Avançadas no Magento 2

Publicados: 2017-05-17

Neste artigo, explicaremos como ocultar um método de envio quando determinadas condições forem aplicadas.

Em alguns cenários, os lojistas podem querer restringir as opções de envio porque:

  • um produto tem grandes dimensões e peso, portanto, não pode ser enviado de maneira padrão,
  • as condições de armazenamento congelado não permitem entregar um produto a tempo
  • o envio é restrito devido à localização do cliente (país, região, cidade )
  • o C art Total não permite que um comprador se qualifique para nenhuma oferta de frete,
  • etc.

A seleção padrão de opções de envio do Magento não oferece muita flexibilidade. Só é possível restringir o envio para determinados concelhos e regiões ou quando o Total do Carrinho for inferior ao valor definido.

Se você acha que isso não é suficiente, continue lendo.

Eu vou te dizer como criar seu próprio plugin que permitirá que você restrinja as opções de envio de acordo com seu modelo de negócios, objetivos e condições.

NOTA

Não vou passar pelas etapas específicas necessárias para criar uma extensão para o Magento 2. Você pode ver como fazer isso aqui ou aqui.

Para desabilitar dinamicamente qualquer método de envio, precisamos de um novo conjunto de classes em nossa extensão – são 2 plugins . O 1º se encarregará da validação dos métodos de envio, enquanto o 2º fará a filtragem dos mesmos.

Em poucas palavras, todo método que não passar na validação será marcado como “ is_disabled “, e na próxima etapa, todos os métodos “ is_disabled ” serão filtrados e excluídos da lista principal.

Vamos rolar.

* Como a abordagem que vou descrever é baseada nos princípios usados ​​na extensão Shipping Suite , usarei o nome do fornecedor 'Mageworx' e o nome da extensão 'ShippingRules'. NOTA! Para evitar erros, você precisa substituí-los por seus próprios nomes!

Primeiro, vamos criar um plugin (classe) que será usado para filtragem. Aqui está como:

 > MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\Append 
 namespace MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

classe Anexar
{
    /**
     * @var \Magento\Checkout\Model\Session|\Magento\Backend\Model\Session\Quote
     */
    sessão $ protegida;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Backend\Model\Session\Quote $backendQuoteSession
     * @param \Magento\Framework\App\State $state
     * @internal param Sessão $sessão
     */
    função pública __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Backend\Model\Session\Quote $backendQuoteSession,
        \Magento\Framework\App\State $state
    ) {
        if ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
            $this->session = $backendQuoteSession;
        } senão {
            $this->session = $checkoutSession;
        }
    }

    /**
     * Valide cada método de envio antes de anexar.
     * Aplique a ação de regras se a validação for bem-sucedida.
     * Pode marcar algumas regras como desativadas. As regras desativadas serão removidas da turma
     * @consulte MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates
     * verificando o valor desta marca no objeto taxa.
     *
     * NOTA: Se você tiver alguns problemas com as regras e os métodos de envio, comece a depurar a partir daqui.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result
     * @return array
     */
    função pública beforeAppend($assunto, $resultado)
    {
        if (!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
            retorno [$resultado];
        }

        $filtableMethods = [
            'flatrate_flatrate',
            'ups_XDM',
            'ups_XPR',
            'ups_WXS',
            'carrier_method',
            // ... adicione aqui seus códigos de método
        ];
        $methodCode = $result->getCarrier() . '_'. $resultado->getMethod();
        if (!in_array($methodCode, $filtableMethods)) {
            retorno [$resultado];
        }

        /** @var \Magento\Quote\Model\Quote $quote */
        $quote = $this->session->getQuote();
        $quoteItems = $quote->getAllItems();
        $pesoPesoFlag = false;
        foreach ($quoteItems as $item) {
            if ($item->getPeso() > 100) {
                $pesoPesoFlag = true;
                Prosseguir;
            }
        }

        if ($heavyWeightFlag == true) {
            $resultado->setIsDisabled(true);
        }

        retorno [$resultado];
    }
}

Executamos 3 verificações no corpo do nosso plugin:

1.

!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method

– garante que, no ponto de entrada, tenhamos o que precisamos: é uma instância de um método de envio. Caso não seja, apenas devolvemos como está.

2.

 !in_array($methodCode, $filtableMethods)

– em seguida, verificamos se o método atual está na lista de métodos para filtragem. Caso não seja, devolvemos como está.

3.

 $heavyWeightFlag == true

– é a última e principal verificação. Se o sinalizador for aplicado ao valor real, o método atual será desabilitado: $result->setIsDisabled(true);

Tentaremos filtrar pelo menos um produto adicionado ao carrinho e com peso superior a 100 unidades padrão (libras ou quilos).
Os métodos disponíveis para filtragem são 'flatrate_flatrate','ups_XDM','ups_XPR','ups_WXS','carrier_method' . Eles são codificados e armazenados no array $filtableMethods .

Operamos sobre o código usando todo o código do método de envio que, via de regra, consiste no código da transportadora ($result->getCarrier()) e no código do próprio método ($result->getMethod()) conectado com “ _” .

Os produtos necessários para a verificação são retirados diretamente da cotação do cliente atual.
NOTA

Um pequeno pedaço de código no construtor da classe array permitirá que você defina a cotação tanto no frontend quanto no backend (desde que um pedido tenha sido criado no painel Admin).

Usando \Magento\Framework\App\State podemos verificar em qual área estamos no momento, e selecionar o orçamento necessário:
1. \Magento\Backend\Model\Session\Quote for Admin
2. \Magento\Checkout\Model\Session para o Frontend

É isso!

Agora podemos validar os métodos de envio e prosseguir para a próxima etapa – criando um plugin para desabilitar métodos de envio inválidos (de acordo com nossas condições).

Isto é como:

 > MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates 
 /**
 * Copyright 2016 MageWorx. Todos os direitos reservados.
 * Consulte LICENSE.txt para obter detalhes da licença.
 */

namespace MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

class GetAllRates
{

    /**
     * Desative as taxas de envio marcadas.
     *
     * NOTA: Se você não conseguir ver algumas das taxas de envio, comece a depurar a partir daqui. Primeiro, verifique 'is_disabled'
     * param no objeto de taxa de envio.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param array $resultado
     * @return array
     */
    função pública afterGetAllRates($assunto, $resultado)
    {
        foreach ($resultado como $chave => $taxa) {
            if ($rate->getIsDisabled()) {
                unset($resultado[$chave]);
            }
        }

        retorna $resultado;
    }
}

Este plugin é usado para buscar todos os dados de métodos de envio disponíveis e verificar cada um deles. Se algum dos métodos tiver a marca “is_disabled” , apenas o excluímos da lista, o que nos permite ver apenas os métodos que correspondem às condições criadas no validador. Esses métodos são excluídos em qualquer página de um site, seja um bloco de envio estimado no carrinho de compras ou na página de checkout.

Agora, para verificar como os plugins funcionam, precisamos registrá-los no arquivo:

> MageWorx/ShippingRules/etc/di.xml 
 <?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Shipping\Model\Rate\Result">
        <plugin name="mageworx_shippingrules_update_rate_result"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\Append"
                sortOrder="10"
                desativado="falso"/>
        <plugin name="mageworx_shippingrules_update_disabled_or_enabled_rates"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates"
                sortOrder="11"
                desativado="falso"/>
    </tipo>
</config>

NOTA

Por razões descritivas, os plugins são divididos em 2 classes diferentes. Em um cenário comum, você pode usar apenas 1 classe para modificar 2 métodos diferentes da classe Magento\Shipping\Model\Rate\Result.

Por que funciona desta forma?

Magento\Shipping\Model\Rate\Result é a principal classe do Magento 2 que é responsável pela procissão dos métodos de envio. Seu método getAllRates é usado para buscar listas de métodos de envio.

Enquanto isso, adicionar métodos de envio geralmente é feito com a ajuda do método 'append'. Tendo validado métodos ao anexar e excluídos da coleção, podemos obter uma lista de métodos válidos.

A validação em si também pode ser modificada.

Nossa extensão possui uma grande classe especial que armazena uma coleção de filtros personalizados com diferentes condições (como store_id, customer_group_id, date from/to, days of the week, etc. ). ele também possui uma classe separada com uma coleção de ações que devem ser aplicadas a um método de envio (por exemplo , habilitá-lo ou desativá-lo, reescrever seu custo de acordo com diferentes condições, adicionar custos extras ou descontos, etc. )

O resultado do 1º plugin no debug se parece com isso (para um produto com o peso de 1 unidade):
1

É assim que aparece no carrinho de compras (ups_WXS ainda está disponível, pois o limite de peso não é excedido):

2

No entanto, se você alterar o peso do produto para 101, este método de envio ficará indisponível:

3

Ele fica disponível novamente se você o excluiu da lista:
4

5

No caixa:

f3d3cac03678318af2d569d757fc7e79

NOTA

Você pode obter a lista de todos os métodos de envio do sistema disponíveis diretamente no código da seguinte maneira:

 /**
 * Matriz de retorno de operadoras.
 * Se $isActiveOnlyFlag for definido como true, retornará apenas operadoras ativas
 *
 * @param bool $isActiveOnlyFlag
 * @return array
 */
função pública getAvailableMethods($isActiveOnlyFlag = false)
{
    $carriers = $this->shippingConfig->getAllCarriers();
    foreach ($carriers as $carrierCode => $carrierModel) {
        if (!$carrierModel->isActive() && (bool)$isActiveOnlyFlag === true) {
            Prosseguir;
        }
        $carrierMethods = $carrierModel->getAllowedMethods();
        if (!$carrierMethods) {
            Prosseguir;
        }
        foreach ($carrierMethods as $methodCode => $methodTitle) {
            $methods[] = $carrierCode . '_'. $methodCode;
        }
    }

    return !empty($methods) ? $métodos: [];
}

Onde `$this->shippingConfig` é uma instância da classe `Magento\Shipping\Model\Config` . Usando este código, você pode criar o modelo de origem para o seletor de métodos de envio nas configurações da extensão (assim, você não precisará codificá-lo no plug-in).

E por último mas não menos importante.

Se você não quiser criar sua própria extensão para desabilitar os métodos de envio, você pode usar nossa solução Shipping Suite para Magento 2 .

A extensão permite excluir qualquer método de envio sempre que necessário com apenas alguns cliques do mouse.
1. Crie uma nova regra de envio com a seguinte condição:

8

2. Selecione a ação Ocultar Método de Envio na lista e escolha quais métodos devem ser desabilitados:

9

NOTA

Se você não encontrar o atributo 'peso' na lista de condições, verifique se ele está habilitado para uso nas regras promocionais:

10

Se você tiver dúvidas ou ideias sobre como melhorar ainda mais nossa extensão , compartilhe sua opinião na seção de comentários abaixo.