Eu desenvolvo o método de envio para alguma empresa de logística. Esta empresa possui muitos escritórios onde o cliente pode receber seu pedido. Posso obter a lista de escritórios por cidade na API mas agora não estou representando melhor essa etapa?
Por enquanto, acabei de definir um novo \Magento\Quote\Model\Quote\Address\RateResult\Method
em todos os escritórios da cidade, na cidade grande conta> 100 e acho que não é muito bom definir 100 linhas no checkout.
Será um módulo público para diferentes designs de checkout. Como posso renderizar perto do meu método de envio selecionado alguma lista suspensa com lista de escritórios e definir preço e método após o usuário selecionar um.
magento-2.1
checkout
shipping-methods
Jamess Moriarty
fonte
fonte
Respostas:
O Magento checkout não suporta nenhum tipo de formulário para dados adicionais do método de envio. Mas fornece
shippingAdditional
bloqueio no check-out que pode ser usado para isso. A solução a seguir funcionará no checkout padrão do magento.Primeiro vamos preparar nosso contêiner onde podemos colocar alguma forma. Para isso, crie um arquivo em
view/frontend/layout/checkout_index_index.xml
Agora crie um arquivo no
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
qual renderizará um modelo de knockout. Seu conteúdo fica assimEste arquivo usa um modelo de knockout que deve ser colocado em
Vendor/Module/view/frontend/web/template/checkout/shipping/form.html
Agora temos um campo de seleção que ficará visível quando nosso método (definido por seu código) for selecionado na tabela de métodos de envio. Hora de preenchê-lo com algumas opções. Como os valores dependem do endereço, a melhor maneira é criar o ponto de extremidade restante que fornecerá as opções disponíveis. Dentro
Vendor/Module/etc/webapi.xml
Agora defina a interface
Vendor/Module/Api/OfficeManagementInterface.php
comoDefinir interface para dados do escritório em
Vendor\Module\Api\Data\OfficeInterface.php
. Essa interface será usada pelo módulo webapi para filtrar dados para a saída, portanto, você precisa definir o que precisar adicionar à resposta.Hora das aulas reais. Comece com a criação de preferências para todas as interfaces no
Vendor/Module/etc/di.xml
Agora crie uma
Vendor\Module\Model\OfficeManagement.php
classe que realmente fará a lógica de buscar os dados.E, finalmente, aula para
OfficeInterface
emVendor/Module/Model/Office.php
Isso deve mostrar o campo de seleção e atualizá-lo quando o endereço for alterado. Mas estamos perdendo mais um elemento para manipulação de front-end. Precisamos criar uma função que chamará o terminal. A chamada para ele já está incluída
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
e é aVendor_Module/js/view/checkout/shipping/office-service
classe que deve seguirVendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.js
com o seguinte código:Ele usa mais 2 arquivos js.
Vendor_Module/js/view/checkout/shipping/model/resource-url-manager
cria um URL para o terminal e é bastante simplesVendor_Module/js/view/checkout/shipping/model/office-registry
é uma maneira de manter o resultado no armazenamento local. Seu código é:Ok, então todos nós devemos trabalhar no frontend. Mas agora há outro problema a ser resolvido. Como o checkout não sabe nada sobre este formulário, ele não envia o resultado da seleção para o back-end. Para fazer isso acontecer, precisamos usar
extension_attributes
recurso. Esta é uma maneira no magento2 de informar o sistema que alguns dados adicionais devem estar nas chamadas restantes. Sem ele, o magento filtraria esses dados e eles nunca alcançariam o código.Então, primeiro,
Vendor/Module/etc/extension_attributes.xml
defina:Este valor já está inserido na solicitação
form.js
porthis.selectedOffice.subscribe()
definição. Portanto, a configuração acima só passará na entrada. Para buscá-lo no código, crie um plugin noVendor/Module/etc/di.xml
Dentro dessa classe
Obviamente, onde você salvará o valor depende inteiramente de seus requisitos. O código acima exigiria a criação de coluna adicional
carrier_office
noquote_address
esales_address
mesas e um evento (emVendor/Module/etc/events.xml
)Isso copiaria os dados salvos no endereço de cotação no endereço de vendas.
Eu escrevi isso para o meu módulo para a operadora polonesa InPost, então mudei alguns nomes que podem quebrar o código, mas espero que isso lhe dê o que você precisa.
[EDITAR]
Modelo de transportadora solicitado por @sangan
fonte
Estou adicionando uma nova resposta para expandir o que já foi fornecido anteriormente, mas sem distorcê-lo.
Esta é a rota que
QuoteAddressPlugin
foi conectada:O último método foi chamar o
Magento\Quote\Model\Quote\Address::setShippingMethod()
que realmente era chamado peloMagento\Quote\Model\Quote\Address::__call()
qual eu usei. Agora eu encontrei um lugar melhor para o plugin, é oMagento\Quote\Model\ShippingAssignment::setShipping()
método. Portanto, a parte do plug-in pode ser reescrita para:e o próprio plugin:
fonte
@ Zefiryn, me deparei com o problema com:
quote.shippingAddress().extensionAttributes.carrier_office = office;
Quando entro no check-out pela primeira vez (nova janela privada) como hóspede (mas o mesmo ocorre com o cliente registrado), o escritório de atributos não é salvo no banco de dados após o primeiro "Avançar". Embora no console eu veja a saída correta para:
console.log(quote.shippingAddress().extensionAttributes.carrier_office);
Quando volto à primeira página de check-out e seleciono o escritório novamente, ele é salvo. Qual poderia ser a razão desse comportamento?
Eu tentei usar:
address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);
mas sem sucesso ...
fonte
@ Zefiryn, você pode explicar em poucas palavras como o seu plugin acima funciona? Estou um pouco confuso porque, como eu sei, o método __call é executado se tentarmos executar o método que não existe para um objeto específico. Parece ser verdade porque em app / code / Magento / Quote / Model / Quote / Address.php eu não vejo esse método - apenas comente:
/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)
$subject->setInpostMachine
e$subject->getCarrierOffice(null);
significa que o método do plug-in acima será executado novamente, pois não existe o método setInpostMachine () e getCarrierOffice () na classe Adress? Parece loop para mim.setShippingMethod()
? Como normalmente esse método é usado? Não consigo encontrar nenhuma interceptação semelhante no código Magento.fonte
setShippingMethod
chamada noAddressInterface
objeto e, como não existe esse método, tive que usar around__call para verificar sesetShippingMethod
foi chamado ou algum outro campo mágico. No momento, encontrei um lugar melhor e vou publicá-lo em nova resposta.