प्रोग्रामेटिक रूप से शिपमेंट बनाना


32

मैं अलग-अलग तरीके से शिपमेंट प्रोग्राम बनाने के लिए आया था। वो हैं

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

इन तरीकों में क्या अंतर है। तीन तरीकों में से जो शिपमेंट बनाने और ट्रैकिंग नंबर जोड़ने के लिए उचित तरीका है।


क्या किसी स्वीकार और अमानत पुरस्कार के लिए मेरे जवाब पर कोई और विवरण चाहिए? यदि आप चाहें तो मैं आलोचना या स्पष्टीकरण के लिए तैयार हूं।
philwinkle

जवाबों:


47

मैं इसे एक शॉट दूँगा। चलो उन्हें एक समय में एक लेते हैं:

विधि 1

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

$converterऊपर वर्ग से लोड किया गया है Mage_Sales_Model_Convert_Order, जो एक कोर हेल्पर का उपयोग करता है जिसे copyFieldsetऑर्डर ऑब्जेक्ट को शिपमेंट ऑब्जेक्ट में कॉपी करने के लिए कहा जाता है। $ आदेश को प्रकार सरणी का होना चाहिए या Varien_Object

यह विधि वास्तव में मेथड 3 के मूल में है, क्योंकि यह Mage::getModel('sales/convert_order')अपने कंस्ट्रक्टर कॉल में उपयोग करता है।

इस विधि का मुख्य अंतर - यह एक सरणी या एक वस्तु ले सकता है $orderऔर एक मूल $shipmentवस्तु उत्पन्न कर सकता है। यह एक निम्न-स्तरीय विधि है जो विशेष रूप से आपके द्वारा विधि 2, विधि 3 में दी गई विधियों द्वारा उपयोग की जाती है।

विधि 2

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

यह शिपमेंट बनाने के Magento के कोर में सबसे लोकप्रिय तरीका लगता है क्योंकि यह शिपमेंट और चालान दोनों नियंत्रकों में उपयोग किया जाता है। $orderके इंस्ट्रूमेंटेशन के लिए एक कंस्ट्रक्टर तर्क के रूप में उपयोग किया जाता है Mage_Sales_Model_Service_Order, इसे ऑब्जेक्ट पर संरक्षित संपत्ति के रूप में सेट किया जाता है।

आप तब कॉल कर रहे हैं prepareShipmentऔर एक मात्रा पास कर रहे हैं । चूंकि यह विधि विधि 1 से कनवर्टर वर्ग का उपयोग करती है, इसलिए आपको अधिक विवरण निर्दिष्ट करने की आवश्यकता नहीं है जैसे कि ऑर्डर आइटम पास आइटम शिपमेंट मात्रा विवरण को पास करते prepareShipmentहैं, जिसे यहां कहा जाता है $this->_getItemQtys। अपने स्वयं के संदर्भ में इसका उपयोग करने के लिए, आपको निम्नलिखित प्रारूप के साथ किसी सरणी में मदों की मात्रा को पास करना होगा:

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

इस विधि के प्रमुख अंतर - यह आपको एक $ शिपमेंट वस्तु देता है, लेकिन इस पर परिवर्तित सभी वस्तुओं के साथ। यह प्लग-एंड-प्ले है।

विधि 3

मुझे कोर में इस पद्धति का उपयोग करने के सबूत नहीं मिले। यह एक हैक की तरह दिखता है, ईमानदार होना। यहाँ विधि है:

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

चरण 1 बिलकुल ऊपर की विधि 2 जैसा ही है। कोई फर्क नहीं। हालांकि, आपको एक $shipmentवस्तु वापस मिल जाती है, जिसे प्रत्यक्ष बीमा के द्वारा बदल दिया जाता है Mage_Sales_Model_Order_Shipment_Api। यह अमानक है। शिपमेंट एपि वस्तु प्राप्त करने का सबसे अच्छा तरीका है कॉल करना Mage::getModel('sales/order_shipment_api')

इसके बाद, यह उस $orderIdचर का उपयोग करता है, जो कि आपके कोड में परिभाषित नहीं किए गए चर से शिपमेंट बनाने के लिए नई शिपमेंट एपीआई ऑब्जेक्ट है । फिर, यह एक समाधान की तरह लगता है।

देखते हुए Mage_Sales_Model_Order_Shipment_Api::create(), यह एक शिपमेंट को उत्पन्न करने के लिए वन-स्टॉप-शॉप की तरह लगता है क्योंकि शिपमेंट बनाने के लिए आवश्यक सबसे बुनियादी विवरण केवल एक आदेश है increment_id

यह एक हैक है जिसे किसी भी मॉड्यूल या एक्सटेंशन द्वारा उपयोग नहीं किया जाना चाहिए। यह एपीआई XML RPC / SOAP एपीआई अनुरोधों के माध्यम से उजागर होने वाली सुविधाओं से भस्म होने के लिए है और कई कदम एपीआई अनुरोधों को खत्म करने के लिए जानबूझकर बुनियादी है।

आखिरकार मेथड 3 मे नॉटी-ग्रिट्टी हो जाता है, हालांकि, और Mage_Sales_Model_Order को कॉल के माध्यम से, यह कॉल करता है prepareShipment, जो कि ऊपर दिए गए परिचित तरीके 2 के लिए एक उच्च-क्रम का अमूर्त है:

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

यहां महत्वपूर्ण अंतर - यदि आपको शिपमेंट की आवश्यकता है, तो हैक करने में कोई आपत्ति नहीं है, और केवल एक increment_id है - इस पद्धति का उपयोग करें। इसके अलावा उपयोगी जानकारी यदि आप SOAP API के माध्यम से इसे संभालना पसंद करते हैं।

मुझे आशा है कि वह मदद करेंगे।


1
Magestore Inventory Management का उपयोग करने वाले किसी भी व्यक्ति के लिए एक सिर: विधि 3 उनके हुक को ट्रिगर नहीं करता है ताकि आप Magento कोर शिपमेंट और वेयरहाउस शिपमेंट के बीच शिपमेंट विसंगतियों को समाप्त कर सकें। इसके अलावा अच्छा जवाब ओपी :)
रिकी ओडिन मैथ्यूज

7

यहाँ मुख्य बात यह है कि तरीके 1 और 2 काम नहीं करते हैं ...

मैं @ एफिलविंक से सहमत हूं, हालांकि, विधि 3 हैक है। एपीआई कार्यों को वास्तव में गैर-एपीआई संदर्भ में नहीं बुलाया जाना चाहिए। आप कभी नहीं जानते कि इस तरह के कोड को तोड़ने के लिए भविष्य के रिलीज क्या ला सकते हैं।

तो वह क्या छोड़ता है? ठीक है, तरीके 1 और 2 बिल्कुल नहीं टूटे हैं। यह सिर्फ इतना है कि वे केवल नौकरी का हिस्सा हैं। यहाँ वे क्या दिखना चाहिए:

नोट: संक्षिप्तता के लिए, निम्नलिखित कोड स्निपेट शिपमेंट में सभी पात्र वस्तुओं को जोड़ देगा। यदि आप केवल एक ऑर्डर का हिस्सा शिप करना चाहते हैं, तो आपको कोड के कुछ हिस्सों को संशोधित करना होगा - उम्मीद है कि मैंने आपको हालांकि, जाने के लिए पर्याप्त दिया है।

विधि 1

यदि आप कोड को देखते हैं app/code/core/Mage/Sales/Model/Order/Shipment/Api.php(जैसा कि विधि 3 में उपयोग किया गया है) तो आप देखेंगे कि इसके अलावा $convertor->toShipment($order)यह भी कॉल करता है $item = $convertor->itemToShipmentItem($orderItem), $item->setQty($qty)और$shipment->addItem($item) प्रत्येक पात्र ऑर्डर आइटम के लिए। हां, मैजेंटो वास्तव में यह है कि आलसी, आपको इसे हर के माध्यम से मनाना होगा। एक। चरण। फिर आपको डेटाबेस में शिपमेंट को बचाने के लिए कुछ और हुप्स के माध्यम से कूदना होगा।

तो विधि 1 इस तरह दिखना चाहिए:

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

विधि 2

सबसे पहले, आपको कॉल करना है $this->_getItemQtys() जो निश्चित रूप से केवल कुछ वर्गों में काम करेगा (जिनके पास _getItemQtys फ़ंक्शन, natch है या विरासत में मिली है)। ताकि बदलने की जरूरत है, और विधि 1 के रूप में, आपको प्रक्रिया को बाहर करने की भी आवश्यकता है।

में देख रहे हैं app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.phpयह इस दृष्टिकोण के साथ एक थोड़ा बेहतर स्थिति है - ऐसा लगता है आइटम शिपमेंट खुद के साथ बदल रहे हैं। लेकिन आप अभी भी एक क्षणिक वस्तु को वापस प्राप्त करते हैं, जिसे आपको डेटाबेस को स्वयं सहेजना होगा, जैसे:

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

मैं इसमें थोड़ी त्रुटि-जाँच जोड़ने की भी सलाह दूंगा, उदाहरण के लिए यह सुनिश्चित करने के लिए कि आपके शिपमेंट में वास्तव में आपके सामने कोई वस्तु है register() है।

कौन सा सबसे अच्छा है?

मैं कहूंगा कि यह राय का विषय है। मैंने कोई बेंचमार्क परीक्षण नहीं किया है, लेकिन मुझे पूरा विश्वास है कि दो तरीकों के बीच गति में अंतर नगण्य होगा। कोड आकार और पठनीयता के लिए उनके बीच बहुत कुछ नहीं है।

मैं सभी वस्तुओं को क्रम में स्पष्ट रूप से परिवर्तित नहीं करने के लिए विधि 2 पसंद करता हूं, लेकिन यह अभी भी आपको मात्रा निकालने के लिए उनके माध्यम से जाने की आवश्यकता है। एक अच्छा छोटे कोड पदचिह्न के लिए, विधि 3 मेरा पसंदीदा होगा! लेकिन एक सॉफ्टवेयर इंजीनियर के रूप में मैं इसकी सिफारिश नहीं कर सकता। तो मैं विधि 2 के लिए ललचाऊंगा।


1

दोस्तों उपरोक्त में से कोई भी मेरे मुद्दे पर काम नहीं किया। निम्नलिखित ने मेरे लिए काम किया। इसे नीचे रखने के मामले में यह वहाँ आप में से किसी को मदद करता है।

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

क्यूटी_शीप को इस पद्धति के साथ बिक्री_फ्लैट_ऑर्डर_मिट टेबल पर क्यों नहीं बसाया गया है?
क्रिएटिव एप्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.