Domanda

Mi sono imbattuto in diversi modi per creare la spedizione di programmazione. Sono

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

Quali sono le differenze tra queste methods.Out dei tre metodi che è il metodo corretto per creare le spedizioni e aggiungere i numeri di inseguimento.

È stato utile?

Soluzione

Ti do un colpo. Diamo loro uno alla volta:

Metodo 1

$converter=Mage::getModel('sales/convert_order');
$shipment=$converter->toShipment($order);

$converter precedentemente viene caricata dal Mage_Sales_Model_Convert_Order classe, che utilizza un helper nucleo chiamato copyFieldset copiare dettagli dell'ordine in un oggetto spedizione. $ Ordine deve essere di tipo array o Varien_Object.

Questo metodo è effettivamente alla base del metodo 3, in quanto utilizza Mage::getModel('sales/convert_order') nella chiamata del costruttore.

elemento chiave di differenziazione di questo metodo - si può prendere un array o un oggetto $order e generare un oggetto $shipment base. Si tratta di un metodo di livello inferiore utilizzato esclusivamente dai metodi mettere avanti nel metodo 2, il metodo 3.

Metodo 2

 $shipment = Mage::getModel('sales/service_order', $order)
                            ->prepareShipment($this->_getItemQtys($order));

Questo sembra essere il modo più popolare nel Nucleo di generare una spedizione in quanto viene utilizzato sia in Spedizione e controllori fattura di Magento. $order è usato come un argomento del costruttore per l'istanza di Mage_Sales_Model_Service_Order, impostandola come una proprietà protetta sull'oggetto.

Si sta quindi chiamando prepareShipment e passando quantità. Dato che questo metodo utilizza la classe convertitore dal metodo 1, è necessità di non specificare ulteriori dettagli, come gli articoli di ordine articolo passare i dettagli della spedizione Qty in l'argomento prepareShipment, chiamato qui con $this->_getItemQtys. Per utilizzare questo sul proprio contesto, tutto quello che dovete fare è passare la quantità di articoli in un array con il seguente formato:

array(
  'order_item_id'=>$qty,
  'order_item_id'=>$qty,
  'order_item_id'=>$qty
)

elemento chiave di differenziazione di questo metodo - ti dà indietro un oggetto $ spedizione, ma con tutti gli elementi convertiti su di esso. E 'plug-and-play.

Metodo 3

Non ho potuto trovare le prove di utilizzo di questo metodo nel Nucleo. Sembra un hack, ad essere onesti. Ecco il metodo:

$itemQty =  $order->getItemsCollection()->count();
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($orderId);

Fase 1 è esattamente lo stesso come metodo 2 di cui sopra. Nessuna differenza. Tuttavia, si ritorna un oggetto $shipment, che viene sostituito da un insantiation diretta di Mage_Sales_Model_Order_Shipment_Api. Questo è non-standard. Il modo migliore-pratica di ottenere un oggetto di spedizione Api sarebbe alla chiamata Mage::getModel('sales/order_shipment_api').

Avanti, che utilizza, nuovo oggetto spedizione API sovrascritto per creare una spedizione da una variabile $orderId che non è stato definito nel codice. Ancora una volta, questa sembra una soluzione.

Guardando Mage_Sales_Model_Order_Shipment_Api::create(), sembra come un one-stop-shop per la generazione di una spedizione come la maggior parte dei dettagli di base necessari per creare la spedizione è solo una increment_id ordine.

Questo è un hack che non deve essere utilizzato da qualsiasi modulo o estensione. Questa API è destinato a essere consumato da caratteristiche esposte tramite RPC XML / SOAP richieste API ed è volutamente semplice per eliminare le richieste multiple passo API.

Alla fine Metodo 3 arriva al nocciolo, però, e tramite una chiamata a Mage_Sales_Model_Order, chiama prepareShipment, che è un'astrazione di ordine superiore per il familiare Metodo 2 di cui sopra:

public function prepareShipment($qtys = array())
{
    $shipment = Mage::getModel('sales/service_order', $this)->prepareShipment($qtys);
    return $shipment;
}

elemento chiave di differenziazione qui - se avete bisogno di una spedizione, non importa hack, e hanno solo un increment_id - utilizzare questo metodo. Inoltre informazioni utili se si preferisce gestire questo tramite l'API SOAP.

Mi auguro che aiuta.

Altri suggerimenti

La cosa fondamentale è che i metodi 1 e 2 non funzionano ...

Sono d'accordo con se @philwinkle, metodo 3 è hacky. Le funzioni API non dovrebbe davvero essere chiamato in un contesto non-API. Non si sa mai quello che le future versioni potrebbero portare a rompere questo tipo di codice.

Così che cosa rimane? Beh, i metodi 1 e 2 non sono rotti esattamente. E 'solo che lo fanno solo una parte del lavoro. Ecco quello che dovrebbe essere simile:

Nota: per brevità, i seguenti frammenti di codice si aggiungono tutti gli elementi idonei alla spedizione. Se si desidera solo per nave parte di un ordine, dovrete modificare alcuni parti del codice - Spero di aver dato abbastanza per andare avanti, anche se

.

Metodo 1

Se si guarda il codice a app/code/core/Mage/Sales/Model/Order/Shipment/Api.php (come quello usato nel metodo 3) vedrai che, oltre a $convertor->toShipment($order) chiama anche $item = $convertor->itemToShipmentItem($orderItem), $item->setQty($qty) e $shipment->addItem($item) per ogni articolo dell'ordine ammissibili. Sì, Magento è davvero così pigro, si deve convincere che attraverso ogni. Singolo. Passo. Poi si deve passare attraverso un paio di cerchi effettivamente salvare la spedizione nel database.

Quindi, il metodo 1 dovrebbe essere simile a questo:

$convertor = Mage::getModel('sales/convert_order');
$shipment = $convertor->toShipment($order);
foreach ($order->getAllItems() as $orderItem) {
    if ($orderItem->getQtyToShip() && !$orderItem->getIsVirtual()) {
        $item = $convertor->itemToShipmentItem($orderItem);
        $item->setQty($orderItem->getQtyToShip());
        $shipment->addItem($item);
    }
}
$shipment->register();
$order->setIsInProcess(true);
Mage::getModel('core/resource_transaction')
         ->addObject($shipment)
         ->addObject($order))
         ->save();

Metodo 2

Prima di tutto, si dispone di una chiamata a $this->_getItemQtys() che sarà ovviamente il lavoro solo in alcune classi (quelli che hanno o ereditare un _getItemQtys funzionare, natch). In modo che ha bisogno di cambiare, e come con il metodo 1, è inoltre necessario per rimpolpare il processo.

Guardando in app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php è una situazione leggermente migliore con questo approccio - sembra che gli articoli siano convertiti insieme con la spedizione stessa. Ma si fa ancora solo tornare un oggetto transitorio, che si deve salvare nel database da soli, in questo modo:

$itemQtys = array();
foreach ($order->getAllItems() as $orderItem) {
    if ($orderItem->getQtyToShip() && !$orderItem->getIsVirtual()) {
        $itemQtys[$orderItem->getId()] = $orderItem->getQtyToShip();
    }
}
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQtys);
$shipment->register();
$order->setIsInProcess(true);
Mage::getModel('core/resource_transaction')
         ->addObject($shipment)
         ->addObject($order)
         ->save();

Consiglio anche l'aggiunta di un po 'di controllo degli errori in là, per esempio per assicurarsi che la spedizione contiene in realtà tutti gli elementi prima di register() esso.

Che è meglio?

Direi che è una questione di opinione. Non ho fatto alcun test di benchmark ma sono abbastanza sicuro che la differenza di velocità tra i due metodi sarebbe trascurabile. Per quanto riguarda le dimensioni del codice e la leggibilità non c'è molto tra di loro.

Mi piace il metodo 2 per non dover convertire in modo esplicito tutti gli elementi in ordine, ma lo fa ancora richiedono di passare attraverso di loro per estrarre le quantità. Per una bella impronta di codice piccolo, il metodo 3 sarebbe il mio preferito! Ma, come un ingegnere del software, non posso consigliarlo. Quindi io grassoccio per il metodo 2.

Ragazzi Nessuno dei precedenti ha lavorato sul mio problema. Di seguito ha lavorato per me. Mettere qui in caso aiuta qualcuno di voi là fuori.

public function _createShipment($orderIncrementId = '100310634'){
    // Load Product ..
    $order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

    // Create Qty array
    $shipmentItems = array();
    foreach ($order->getAllItems() as $item) {
        $shipmentItems [$item->getId()] = $item->getQtyToShip();
    }

    // Prepear shipment and save ....
    if ($order->getId() && !empty($shipmentItems) && $order->canShip()) {
        $shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($shipmentItems);
        $shipment->save();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top