Frage

Ich kam auf unterschiedliche Weise zu erstellen, Versand programmgesteuert.Sie sind

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

Was sind die Unterschiede zwischen diesen Methoden.Von den drei Methoden die richtige Methode zum erstellen von Sendungen und hinzufügen tracking zahlen.

War es hilfreich?

Lösung

Ich werde give it a shot.Nehmen wir Sie einzeln:

Methode 1

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

$converter oben geladen wird, die von der Klasse Mage_Sales_Model_Convert_Order, verwendet einen core-Helfer genannt copyFieldset kopieren, um die details in eine Versand-Objekt.$Auftrag muss vom Typ array bzw. Varien_Object.

Diese Methode ist eigentlich der Kern der Methode 3, als dass es nutzt Mage::getModel('sales/convert_order') in seinem Konstruktor-Aufruf.

Hauptunterscheidungsmerkmal dieser Methode kann ein array oder ein Objekt $order und erzeugen eine grundlegende $shipment Objekt.Es ist eine niedrigere-level-Methode, die ausschließlich von den Methoden her gestellt in Methode 2 Methode 3.

Methode 2

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

Dies scheint die beliebteste Art und Weise, in Magento-Core-Erzeugung eines der Versand, wenn es ist verwendet in sowohl Versand und Rechnung Controller. $order verwendet wird als Konstruktor-argument, um die Instanziierung der Mage_Sales_Model_Service_Order, Einstellung es als eine geschützte Eigenschaft auf dem Objekt.

Sie sind dann so aufrufen prepareShipment und übergeben eine Menge.Wie diese Methode verwendet die Wandler der Klasse von Methode 1, Sie nicht brauchen, geben Sie weitere details wie die Bestellung von Artikeln pass-item-Versand Menge in den details prepareShipment argument, hier genannt mit $this->_getItemQtys.Verwenden Sie diese auf Ihrem eigenen Kontext, alle Sie tun müssen, ist pass die Menge der Elemente in einem array mit dem folgenden format:

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

Hauptunterscheidungsmerkmal dieser Methode - es gibt Ihnen einen $shipment-Objekt, das aber alle Elemente umgewandelt, die auf es.Es ist plug-und-spielen.

Methode 3

Ich konnte keine Beweise finden, der mit dieser Methode in den Mittelpunkt.Es sieht aus wie ein hack, um ehrlich zu sein.Hier ist die Methode:

$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);

Schritt 1 ist genau das gleiche wie Methode 2 über.Kein Unterschied.Jedoch, erhalten Sie eine $shipment Objekt, das ersetzt wird durch eine direkte insantiation von Mage_Sales_Model_Order_Shipment_Api.Dies ist nicht standard.Die best practice Weg, um eine Sendung Api-Objekt wäre zu nennen Mage::getModel('sales/order_shipment_api').

Neben, es verwendet, überschrieben, neu-Versand-API-Objekt zum erstellen einer Sendung von einem $orderId variable, die nicht definiert wurden, die in Ihrem code.Wieder, dies scheint eine Problemumgehung.

Suche in Mage_Sales_Model_Order_Shipment_Api::create(), es scheint wie ein one-stop-shop für die Erstellung einer Sendung wie die grundlegenden details die benötigt wird, um die Sendung, ist nur eine Bestellung increment_id.

Dies ist ein hack, der sollte nicht verwendet werden von jedem Modul oder Erweiterung.Diese API soll verzehrt werden, die von features exposed via XML-RPC / SOAP-API-Anforderungen und ist absichtlich basic zu beseitigen mehrere Schritt API-Anfragen.

Schließlich Methode 3 bekommt, um die nitty-gritty, und zwar über einen Aufruf Mage_Sales_Model_Order, ruft es prepareShipment, die einer höheren Abstraktion nach der gewohnten Methode 2 oben:

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

Hauptunterscheidungsmerkmal hier - wenn Sie benötigen eine Lieferung, don ' T mind hacks und nur ein increment_id - verwenden Sie diese Methode.Ebenfalls nützliche Informationen, wenn Sie es vorziehen, dies zu behandeln, die über die SOAP-API.

Ich hoffe, das hilft.

Andere Tipps

Das Wichtigste hier ist, dass die Methoden 1 und 2 nicht funktionieren ...

Ich stimme @Philwinkle zu, Methode 3 ist Hacky. Die API-Funktionen sollten nicht wirklich in einem Nicht-API-Kontext aufgerufen werden. Sie wissen nie, welche zukünftigen Veröffentlichungen diese Art von Code brechen könnten.

Was macht das? Nun, Methoden 1 und 2 sind nicht genau gebrochen. Es ist nur so, dass sie nur einen Teil des Jobs machen. So sollten sie aussehen:

Hinweis: Für die Kürze fügt die folgenden Code -Snippets alle förderfähigen Elemente zur Sendung hinzu. Wenn Sie nur einen Teil einer Bestellung versenden möchten, müssen Sie bestimmte Teile des Codes ändern - hoffentlich habe ich Ihnen genug gegeben, um weiterzumachen.

Methode 1

Wenn Sie sich den Code in ansehen app/code/core/Mage/Sales/Model/Order/Shipment/Api.php (wie in Methode 3 verwendet) Sie sehen dies zusätzlich zu $convertor->toShipment($order) es ruft auch an $item = $convertor->itemToShipmentItem($orderItem), $item->setQty($qty) und $shipment->addItem($item) Für jeden berechtigten Bestellelement. Ja, Magento ist wirklich so faul, du musst es über jeden überreden. Single. Schritt. Dann müssen Sie durch ein paar weitere Reifen springen, um die Sendung tatsächlich in der Datenbank zu speichern.

Methode 1 sollte also so aussehen:

$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();

Methode 2

Zunächst einmal haben Sie einen Anruf bei $this->_getItemQtys() Dies funktioniert natürlich nur in bestimmten Klassen (solche, die eine _getItemqtys -Funktion haben oder erben, natch). Das muss sich also ändern, und wie bei Methode 1 müssen Sie den Prozess auch ausfleischig.

Hereinschauen app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php Mit diesem Ansatz ist es eine etwas bessere Situation - es scheint, dass die Gegenstände zusammen mit der Sendung selbst umgewandelt werden. Aber Sie erhalten immer noch ein transientes Objekt, das Sie selbst in der Datenbank speichern müssen, so:

$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();

Ich würde auch empfehlen, dort ein wenig Fehler zu überprüfen, z. B. um sicherzustellen, dass Ihre Sendung tatsächlich alle Artikel vor Ihnen enthält register() es.

Welches das Beste ist?

Ich würde sagen, es ist eine Frage der Meinung. Ich habe keine Benchmark -Tests durchgeführt, aber ich bin ziemlich zuversichtlich, dass der Geschwindigkeitsunterschied zwischen den beiden Methoden vernachlässigbar wäre. Was die Codegröße und -lesbarkeit betrifft, da ist nicht viel zwischen ihnen.

Ich mag Methode 2, dass ich nicht alle Elemente in der Reihenfolge explizit konvertieren muss, aber es erfordert immer noch, dass Sie sie durchgehen, um die Mengen zu extrahieren. Für einen schönen kleinen Code -Fußabdruck wäre Methode 3 mein Favorit! Aber als Software -Ingenieur kann ich es nicht empfehlen. Also werde ich für Methode 2 plumpen.

Jungs, keiner der oben genannten Arbeiten haben an meinem Problem gearbeitet. Das Folgende funktionierte für mich. Wenn Sie es hier runterlegen, falls es einem von euch da draußen hilft.

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();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top