Me deparei com diferentes maneiras de criar remessas programaticamente. Eles são
//Type 1
$converter=Mage::getModel('sales/convert_order');
$shipment=$converter->toShipment($order);
// snip
//Type 2
$shipment = Mage::getModel('sales/service_order', $order)
->prepareShipment($this->_getItemQtys($order));
// snip
//Type 3
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($orderId);
// snip
Quais são as diferenças entre esses métodos. Dos três métodos, é o método adequado para criar remessas e adicionar números de rastreamento.
magento-1.7
orders
shipment
blakcaps
fonte
fonte
Respostas:
Vou tentar. Vamos levá-los um de cada vez:
Método 1
$converter
acima é carregado da classeMage_Sales_Model_Convert_Order
, que usa um auxiliar central chamadocopyFieldset
para copiar detalhes do pedido em um objeto de remessa. $ order deve ser do tipo array ouVarien_Object
.Na verdade, esse método está no centro do método 3, como ele usa
Mage::getModel('sales/convert_order')
em sua chamada de construtor.Diferenciador chave deste método - ele pode pegar uma matriz ou um objeto
$order
e gerar um$shipment
objeto básico . É um método de nível inferior usado exclusivamente pelos métodos apresentados no método 2, método 3.Método 2
Essa parece ser a maneira mais popular no Core do Magento de gerar uma remessa, pois é usada nos controladores de remessa e fatura.
$order
é usado como um argumento construtor para a instanciação deMage_Sales_Model_Service_Order
, configurando-o como uma propriedade protegida no objeto.Você está ligando
prepareShipment
e passando uma quantidade. Como esse método usa a classe converter do Método 1, vocênão precisa especificar mais detalhes, como itens de pedido, quepassam os detalhes da quantidade de remessa deitensnoprepareShipment
argumento, chamado aqui com$this->_getItemQtys
. Para usar isso em seu próprio contexto, tudo o que você precisa fazer é passar a quantidade de itens em uma matriz com o seguinte formato:Diferenciador chave deste método - ele devolve um objeto $ shipment, mas com todos os itens convertidos nele. É plug-and-play.
Método 3
Não consegui encontrar evidências do uso desse método no Core. Parece um truque, para ser sincero. Aqui está o método:
O passo 1 é exatamente o mesmo que o método 2 acima. Não faz diferença. No entanto, você recebe de volta um
$shipment
objeto, que é substituído por uma insatiação direta deMage_Sales_Model_Order_Shipment_Api
. Isso não é padrão. A melhor maneira de obter um objeto Api de remessa seria chamarMage::getModel('sales/order_shipment_api')
.Em seguida, ele usa esse novo objeto de API de remessa substituído para criar uma remessa a partir de uma
$orderId
variável que não foi definida no seu código. Novamente, isso parece uma solução alternativa.Observando
Mage_Sales_Model_Order_Shipment_Api::create()
, parece um balcão único para gerar uma remessa, pois os detalhes mais básicos necessários para criar a remessa são apenas um pedidoincrement_id
.Este é um hack que não deve ser usado por nenhum módulo ou extensão. Essa API deve ser consumida por recursos expostos por meio de solicitações XML RPC / SOAP API e é intencionalmente básica para eliminar solicitações de várias etapas da API.
Eventualmente, o Método 3 chega ao âmago da questão, porém, e por meio de uma chamada para Mage_Sales_Model_Order, ele chama
prepareShipment
, que é uma abstração de ordem superior para o familiar Método 2 acima:O principal diferencial aqui - se você precisar de uma remessa, não se importe com hacks e tenha apenas um increment_id - use esse método. Informações também úteis, se você preferir lidar com isso por meio da API SOAP.
Espero que ajude.
fonte
O principal aqui é que os métodos 1 e 2 não funcionam ...
Eu concordo com @philwinkle, porém, o método 3 é hacky. As funções da API não devem realmente ser chamadas em um contexto que não seja da API. Você nunca sabe quais lançamentos futuros podem trazer para quebrar esse tipo de código.
Então, o que isso deixa? Bem, os métodos 1 e 2 não são quebrados exatamente. Só que eles fazem parte do trabalho. Aqui está como eles devem ser:
Nota: por questões de brevidade, os seguintes trechos de código adicionarão todos os itens elegíveis à remessa. Se você quiser apenas enviar parte de um pedido, precisará modificar algumas partes do código - espero que tenha lhe dado o suficiente para continuar.
Método 1
Se você olhar para o código
app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
(como o usado no método 3), você verá que, além de$convertor->toShipment($order)
também chama$item = $convertor->itemToShipmentItem($orderItem)
,$item->setQty($qty)
e$shipment->addItem($item)
para cada item da ordem elegíveis. Sim, o Magento é realmente tão preguiçoso, você precisa persuadi-lo a todos. Solteiro. Degrau. Em seguida, você precisará percorrer mais alguns obstáculos para realmente salvar a remessa no banco de dados.Portanto, o método 1 deve ficar assim:
Método 2
Primeiro, você tem uma chamada para a
$this->_getItemQtys()
qual, obviamente, só funcionará em determinadas classes (aquelas que possuem ou herdam uma função _getItemQtys, natch). Portanto, isso precisa mudar e, como no método 1, você também precisa aprimorar o processo.Olhando para
app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
ela, é uma situação um pouco melhor com essa abordagem - parece que os itens são convertidos junto com a remessa. Mas você ainda recebe de volta um objeto transitório, que precisa salvar no banco de dados, assim:Também recomendo adicionar um pouco de verificação de erros, por exemplo, para garantir que sua remessa realmente contenha itens antes de você
register()
.Qual é melhor?
Eu diria que é uma questão de opinião. Eu não fiz nenhum teste de benchmark, mas estou bastante confiante de que a diferença de velocidade entre os dois métodos seria insignificante. Quanto ao tamanho e legibilidade do código, não há muito entre eles.
Eu gosto do método 2 por não ter que converter explicitamente todos os itens do pedido, mas ainda é necessário que você os revise para extrair as quantidades. Para uma boa pegada de código pequeno, o método 3 seria o meu favorito! Mas, como engenheiro de software, não posso recomendar. Então, eu vou insistir no método 2.
fonte
Caras Nenhuma das opções acima funcionou no meu problema. O seguinte funcionou para mim. Colocando aqui em baixo, caso isso ajude algum de vocês lá fora.
fonte