プログラムによるシップメントの作成


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

これらの方法の違いは何ですか。出荷を作成し、追跡番号を追加する適切な方法である3つの方法のうち。


Accept and Bounty Awardを保証するために私の回答に必要な詳細はありますか?あなたが望むなら、私は批判や説明を受け入れます。
-philwinkle

回答:


47

試してみます。一度に1つずつ取り上げましょう。

方法1

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

$converter上記は、からMage_Sales_Model_Convert_Order呼び出さcopyFieldsetれたコアヘルパーを使用して注文の詳細を出荷オブジェクトにコピーするクラスからロードされます。$ orderは配列またはでなければなりませんVarien_Object

このメソッドはMage::getModel('sales/convert_order')、コンストラクター呼び出しで使用するため、実際には方法3の中核にあります。

このメソッドの主な差別化要因 -配列またはオブジェクト$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
)

このメソッドの主な差別化要因 -$ shipmentオブジェクトを返しますが、すべてのアイテムが変換されます。プラグアンドプレイです。

方法3

Coreでこの方法を使用した証拠を見つけることができませんでした。正直に言うと、ハックのように見えます。メソッドは次のとおりです。

$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ます。これは非標準です。出荷Apiオブジェクトを取得するベストプラクティスの方法は、を呼び出すことMage::getModel('sales/order_shipment_api')です。

次に、上書きされた新しいShipment APIオブジェクトを使用$orderIdして、コードで定義されていない変数から出荷を作成します。繰り返しますが、これは回避策のようです。

を見るとMage_Sales_Model_Order_Shipment_Api::create()、貨物を作成するために必要な最も基本的な詳細は注文のみであるため、貨物を生成するためのワンストップショップのようincrement_idです。

これは、モジュールや拡張機能で使用すべきではないハックです。このAPIは、XML RPC / SOAP APIリクエストを介して公開される機能によって使用されることを意図しており、複数ステップのAPIリクエストを排除するための意図的な基本です。

最終的に、方法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のコア出荷と倉庫出荷の間に出荷の不一致が生じます。また良い答えOP :)
リッキーオーディンマシューズ

7

ここで重要なことは、方法1と2が機能しないことです...

@philwinkleには同意しますが、方法3はハッキーです。API関数は、非APIコンテキストで実際に呼び出されるべきではありません。この種のコードを破壊するために、将来のリリースがもたらす可能性のあることは決してわかりません。

それで、それは何を残すのでしょうか?さて、方法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)すべての適格なオーダー項目について。ええ、Magentoは本当に怠け者です。シングル。ステップ。次に、実際に貨物をデータベースに保存するために、さらにいくつかのフープをジャンプする必要があります。

したがって、方法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つの方法の速度の違いは無視できると確信しています。コードのサイズと読みやすさに関しては、それほど大きな違いはありません。

順序内のすべてのアイテムを明示的に変換する必要がないため、方法2が好きですが、数量を抽出するためにそれらを通過する必要があります。素敵な小さなコードフットプリントの場合、方法3が私のお気に入りです!しかし、ソフトウェアエンジニアとしてはお勧めできません。そこで、方法2を準備します。


1

Guys上記のどれも私の問題に取り組みませんでした。次は私のために働いた。あなたがそこにいるのを助けるならば、それをここに置く。

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

このメソッドでqty_shippedがsales_flat_order_itemテーブルに入力されないのはなぜですか?
クリエイティブアプリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.