Ich habe verschiedene Möglichkeiten gefunden, Sendungen programmatisch zu erstellen. 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 ist die richtige Methode, um Sendungen zu erstellen und Tracking-Nummern hinzuzufügen.
magento-1.7
orders
shipment
blakcaps
quelle
quelle
Antworten:
Ich versuche es mal. Nehmen wir sie nacheinander:
Methode 1
$converter
Oben wird aus der Klasse geladenMage_Sales_Model_Convert_Order
, die einen Core-Helper verwendet, der aufgerufen wirdcopyFieldset
, um Bestelldetails in ein Sendungsobjekt zu kopieren. $ order muss vom Typ array oder seinVarien_Object
.Diese Methode bildet den Kern von Methode 3, wie sie
Mage::getModel('sales/convert_order')
in ihrem Konstruktoraufruf verwendet wird.Hauptunterscheidungsmerkmal dieser Methode: Sie kann ein Array oder ein Objekt aufnehmen
$order
und ein Basisobjekt generieren$shipment
. Es handelt sich um eine Methode auf niedrigerer Ebene, die ausschließlich von den Methoden verwendet wird, die Sie in Methode 2, Methode 3 beschrieben haben.Methode 2
Dies scheint die beliebteste Methode im Kern von Magento zu sein, um eine Sendung zu generieren, da sie sowohl in Sendungs- als auch in Rechnungsprüfern verwendet wird.
$order
wird als Konstruktorargument für die Instanziierung von verwendetMage_Sales_Model_Service_Order
und als geschützte Eigenschaft für das Objekt festgelegt.Dann rufst du an
prepareShipment
und übergibst eine Menge. Da diese Methode die Konverterklasse von Methode 1 verwendet, müssen Sie in dem hier mit aufgerufenen Argumentkeine weiteren Details angeben, z. Um dies in Ihrem eigenen Kontext zu verwenden, müssen Sie lediglich die Anzahl der Elemente in einem Array mit dem folgenden Format übergeben:prepareShipment
$this->_getItemQtys
Das wichtigste Unterscheidungsmerkmal dieser Methode: Sie erhalten ein $ -Versandobjekt zurück, auf dem jedoch alle Elemente konvertiert sind. Es ist Plug-and-Play.
Methode 3
Ich konnte keine Beweise für die Verwendung dieser Methode im Core finden. Es sieht aus wie ein Hack, um ehrlich zu sein. Hier ist die Methode:
Schritt 1 entspricht genau der obigen Methode 2. Kein Unterschied. Sie erhalten jedoch ein
$shipment
Objekt zurück, das durch eine direkte Insantiation von ersetzt wirdMage_Sales_Model_Order_Shipment_Api
. Dies ist kein Standard. Die beste Methode zum Abrufen eines Versand-API-Objekts ist der AufrufMage::getModel('sales/order_shipment_api')
.Anschließend wird dieses überschriebene neue Versand-API-Objekt verwendet, um einen Versand aus einer
$orderId
Variablen zu erstellen , die in Ihrem Code nicht definiert wurde. Auch dies scheint eine Problemumgehung zu sein.Auf den ersten Blick
Mage_Sales_Model_Order_Shipment_Api::create()
scheint es ein One-Stop-Shop für das Generieren einer Sendung zu sein, da die grundlegendsten Details, die zum Erstellen der Sendung benötigt werden, nur eine Bestellung sindincrement_id
.Dies ist ein Hack, der von keinem Modul oder keiner Erweiterung verwendet werden sollte. Diese API soll von Funktionen genutzt werden, die über XML-RPC / SOAP-API-Anforderungen verfügbar gemacht werden, und ist absichtlich grundlegend, um API-Anforderungen mit mehreren Schritten zu eliminieren.
Schließlich kommt Methode 3 jedoch auf den Punkt und ruft über einen Aufruf von Mage_Sales_Model_Order auf
prepareShipment
, was eine Abstraktion höherer Ordnung für die bekannte Methode 2 oben ist:Hauptunterscheidungsmerkmal hier - wenn Sie eine Sendung benötigen, keine Hacks und nur eine increment_id haben - verwenden Sie diese Methode. Auch nützliche Informationen, wenn Sie dies lieber über die SOAP-API erledigen möchten.
Ich hoffe das hilft.
quelle
Der Schlüssel hier ist, dass die Methoden 1 und 2 nicht funktionieren ...
Ich stimme jedoch mit @philwinkle überein, Methode 3 ist hacky. Die API-Funktionen sollten eigentlich nicht in einem Nicht-API-Kontext aufgerufen werden. Sie wissen nie, welche zukünftigen Releases dazu führen können, dass ein derartiger Code kaputt geht.
Was bleibt also übrig? Nun, Methoden 1 und 2 sind nicht genau gebrochen. Es ist nur so, dass sie nur einen Teil der Arbeit erledigen. So sollten sie aussehen:
Hinweis: Der Kürze halber werden mit den folgenden Codefragmenten alle in Frage kommenden Artikel zur Sendung hinzugefügt. Wenn Sie nur einen Teil einer Bestellung versenden möchten, müssen Sie bestimmte Teile des Codes ändern - hoffentlich habe ich Ihnen jedoch genug gegeben, um fortzufahren.
Methode 1
Wenn Sie den Code anschauen in
app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
(wie in Methode 3 verwendet) Sie werden sehen , dass zusätzlich zu dem$convertor->toShipment($order)
sie auch nennen$item = $convertor->itemToShipmentItem($orderItem)
,$item->setQty($qty)
und$shipment->addItem($item)
für jede qualifizierte Auftragsposition. Ja, Magento ist wirklich so faul, dass man es durch jeden hindurch locken muss. Single. Schritt. Dann müssen Sie ein paar weitere Reifen durchspringen, um die Sendung tatsächlich in der Datenbank zu speichern.Methode 1 sollte also so aussehen:
Methode 2
Zunächst einmal haben Sie einen Aufruf,
$this->_getItemQtys()
der natürlich nur in bestimmten Klassen funktioniert (solche, die eine _getItemQtys-Funktion haben oder erben, natch). Das muss sich also ändern, und wie bei Methode 1 müssen Sie auch den Prozess konkretisieren.Suchen Sie in
app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
es ist eine etwas bessere Situation mit diesem Ansatz - es scheint , werden die Elemente zusammen mit der Sendung selbst umgewandelt. Sie erhalten jedoch nur ein vorübergehendes Objekt zurück, das Sie selbst in der Datenbank speichern müssen.Ich würde auch empfehlen, dort eine kleine Fehlerüberprüfung hinzuzufügen, um beispielsweise sicherzustellen, dass Ihre Sendung tatsächlich Artikel enthält, bevor Sie
register()
diese erhalten.Welches das Beste ist?
Ich würde sagen, es ist Ansichtssache. Ich habe noch keine Benchmark-Tests durchgeführt, bin aber ziemlich zuversichtlich, dass der Geschwindigkeitsunterschied zwischen den beiden Methoden vernachlässigbar ist. In Bezug auf Codegröße und Lesbarkeit gibt es nicht viel zwischen ihnen.
Ich mag Methode 2, weil nicht alle Artikel in der Bestellung explizit konvertiert werden müssen, aber Sie müssen sie trotzdem durchgehen, um die Mengen zu extrahieren. Für einen schönen kleinen Code-Footprint wäre Methode 3 mein Favorit! Aber als Softwareentwickler kann ich es nicht empfehlen. Also werde ich mich für Methode 2 entscheiden.
quelle
Jungs Keiner der oben genannten hat an meinem Problem funktioniert. Folgendes hat bei mir funktioniert. Stellen Sie es hier ab, falls es irgendjemandem von Ihnen da draußen hilft.
quelle