Natknąłem się na różne sposoby programowego tworzenia przesyłki. Oni są
//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
Jaka jest różnica między tymi metodami. Jedna z trzech metod, która jest właściwą metodą do tworzenia przesyłek i dodawania numerów śledzenia.
magento-1.7
orders
shipment
blakcaps
źródło
źródło
Odpowiedzi:
Spróbuję. Weźmy je pojedynczo:
Metoda 1
$converter
powyżej jest ładowany z klasyMage_Sales_Model_Convert_Order
, która korzysta z pomocnika rdzenia wywoływanegocopyFieldset
do kopiowania szczegółów zamówienia do obiektu wysyłki. $ order musi być typu tablica lubVarien_Object
.Ta metoda jest właściwie rdzeniem metody 3, ponieważ jest używana
Mage::getModel('sales/convert_order')
w wywołaniu konstruktora.Kluczowy wyróżnik tej metody - może pobrać tablicę lub obiekt
$order
i wygenerować$shipment
obiekt podstawowy . Jest to metoda niższego poziomu używana wyłącznie przez metody przedstawione w Metodzie 2, Metodzie 3.Metoda 2
Wydaje się, że jest to najpopularniejszy sposób generowania przesyłki w rdzeniu Magento, ponieważ jest ona używana zarówno w kontrolerach przesyłek, jak i fakturach.
$order
jest używany jako argument konstruktora do wystąpieniaMage_Sales_Model_Service_Order
, ustawiając go jako chronioną właściwość obiektu.Następnie dzwonisz
prepareShipment
i przekazujesz ilość. Ponieważ ta metoda wykorzystuje klasę konwertera z metody 1, nietrzeba określać więcej szczegółów, takich jak zamówienie zamówieniaprzekazuje szczegółowe informacje dotyczące wysyłki przedmiotu wprepareShipment
argumencie, wywoływanym tutaj za pomocą$this->_getItemQtys
. Aby użyć tego we własnym kontekście, wystarczy przekazać liczbę elementów w tablicy o następującym formacie:Kluczowy wyróżnik tej metody - daje z powrotem obiekt wysyłki $, ale z wszystkimi konwertowanymi na nim przedmiotami. To plug-and-play.
Metoda 3
Nie mogłem znaleźć dowodów na użycie tej metody w rdzeniu. Szczerze mówiąc, wygląda to na hack. Oto metoda:
Krok 1 jest dokładnie taki sam jak metoda 2 powyżej. Bez różnicy. Jednak
$shipment
odzyskujesz obiekt, który jest zastępowany przez bezpośrednie insantiation ofMage_Sales_Model_Order_Shipment_Api
. To jest niestandardowe. Najlepszym sposobem na uzyskanie obiektu Api do wysyłki byłoby zadzwonienieMage::getModel('sales/order_shipment_api')
.Następnie używa tego zastąpionego, nowego obiektu API przesyłki do utworzenia przesyłki ze
$orderId
zmiennej, która nie została zdefiniowana w kodzie. Znowu wydaje się to obejściem.Patrząc na
Mage_Sales_Model_Order_Shipment_Api::create()
to, wydaje się, że jest to punkt kompleksowej obsługi do generowania przesyłki, ponieważ najbardziej podstawowe szczegóły potrzebne do utworzenia przesyłki to tylko zamówienieincrement_id
.Jest to hack, którego nie powinien używać żaden moduł ani rozszerzenie. Ten interfejs API jest przeznaczony do korzystania z funkcji udostępnianych za pośrednictwem żądań interfejsu API RPC / SOAP XML i jest celowo podstawowy w celu wyeliminowania wieloetapowych żądań interfejsu API.
Ostatecznie jednak Metoda 3 przechodzi do drobiazgów i poprzez wywołanie Mage_Sales_Model_Order, wywołuje
prepareShipment
, co jest abstrakcją wyższego rzędu dla znanej powyżej Metody 2:Kluczowy wyróżnik tutaj - jeśli potrzebujesz przesyłki, nie przejmuj się hackami i masz tylko increment_id - skorzystaj z tej metody. Przydatne informacje, jeśli wolisz obsługiwać to za pośrednictwem interfejsu API SOAP.
Mam nadzieję że to pomogło.
źródło
Kluczową kwestią jest to, że metody 1 i 2 nie działają ...
Zgadzam się z @philwinkle, metoda 3 jest hacky. Funkcje API tak naprawdę nie powinny być wywoływane w kontekście innym niż API. Nigdy nie wiadomo, jakie przyszłe wydania mogą przynieść złamanie tego rodzaju kodu.
Co to pozostawia? Cóż, metody 1 i 2 nie są dokładnie złamane. Po prostu wykonują tylko część pracy. Oto jak powinny wyglądać:
Uwaga: dla zwięzłości następujące fragmenty kodu dodadzą wszystkie kwalifikujące się elementy do przesyłki. Jeśli chcesz tylko wysłać część zamówienia, musisz zmodyfikować niektóre części kodu - mam jednak nadzieję, że dałem ci wystarczająco dużo, aby kontynuować.
Metoda 1
Jeśli spojrzeć na kod w
app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
(stosowany w metodzie 3) zobaczysz, że oprócz$convertor->toShipment($order)
niego wzywa także$item = $convertor->itemToShipmentItem($orderItem)
,$item->setQty($qty)
i$shipment->addItem($item)
dla każdego kwalifikującego się przedmiotu zamówienia. Tak, Magento jest naprawdę tak leniwy, że trzeba go nakłonić do każdego. Pojedynczy. Krok. Następnie musisz przeskoczyć jeszcze kilka obręczy, aby faktycznie zapisać przesyłkę w bazie danych.Więc metoda 1 powinna wyglądać następująco:
Metoda 2
Po pierwsze, masz wywołanie, do
$this->_getItemQtys()
którego oczywiście będzie działać tylko w niektórych klasach (tych, które mają lub dziedziczą funkcję _getItemQtys, natch). To musi się zmienić i podobnie jak w metodzie 1, musisz także dopracować proces.Patrząc na
app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
to jest nieco lepsza sytuacja z tym podejściem - wydaje się, że elementy są konwertowane wraz z samym transportem. Ale nadal dostajesz po prostu obiekt przejściowy, który musisz sam zapisać do bazy danych:Polecam również dodanie trochę sprawdzania błędów, np. Aby upewnić się, że Twoja przesyłka rzeczywiście zawiera jakieś elementy przed tobą
register()
.Który jest najlepszy
Powiedziałbym, że to kwestia opinii. Nie wykonałem żadnych testów porównawczych, ale jestem pewien, że różnica prędkości między tymi dwiema metodami byłaby znikoma. Jeśli chodzi o rozmiar i czytelność kodu, nie ma między nimi wiele.
Podoba mi się metoda 2 polegająca na tym, że nie muszę jawnie konwertować wszystkich pozycji w kolejności, ale nadal wymaga przejścia przez nie w celu wyodrębnienia ilości. Dla małego śladu kodu metoda 3 byłaby moim ulubionym! Ale jako inżynier oprogramowania nie mogę tego polecić. Więc wybiorę dla metody 2.
źródło
Chłopaki Żadne z powyższych nie działało w moim wydaniu. Poniższe działało dla mnie. Odłóż go tutaj, na wypadek, gdyby pomógł komukolwiek z was.
źródło