プログラムで出荷を作成します
-
16-10-2019 - |
質問
プログラムで出荷を作成するためのさまざまな方法に出会いました。彼らです
//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つの方法のアウトは、出荷を作成して追跡番号を追加する適切な方法です。
解決
私はそれにショットを与えます。一度にそれらを1つ持ってみましょう:
方法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
. 。これは標準以外です。出荷APIオブジェクトを取得する最適な方法は、呼び出すことです Mage::getModel('sales/order_shipment_api')
.
次に、上書きの新しい出荷APIオブジェクトを使用して、から出荷を作成します $orderId
コードで定義されていない変数。繰り返しますが、これは回避策のようです。
見つめている Mage_Sales_Model_Order_Shipment_Api::create()
, 、出荷を作成するために必要な最も基本的な詳細は注文のみであるため、貨物を生成するためのワンストップショップのようです increment_id
.
これは、モジュールや拡張機能では使用しないハックです。このAPIは、XML RPC / SOAP APIリクエストを介して公開される機能によって消費されることを意図しており、複数のステップAPIリクエストを排除するために意図的に基本的です。
最終的には、方法3はnitty-grittyに到達し、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と2が機能しないということです...
私は@PhilWinkleに同意しますが、方法3はハッキーです。 API関数は、API以外のコンテキストで実際に呼び出されるべきではありません。この種のコードを破るために将来のリリースが何をもたらすかは決してわかりません。
それで、それは何を去りますか?さて、方法1と2は正確に壊れていません。彼らが仕事の一部しかしないということです。これが彼らがどのように見えるべきかです:
注:Brevityのために、次のコードスニペットは、資格のあるすべてのアイテムを出荷に追加します。注文の一部を出荷したい場合は、コードの特定の部分を変更する必要があります。
方法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)
適格な注文アイテムごとに。うん、マゼントは本当に怠zyなので、あなたはそれをすべてに包み込む必要があります。独身。ステップ。次に、データベースの出荷を実際に保存するには、さらにいくつかのフープを飛び越えなければなりません。
したがって、方法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でふっくらします。
みんな上記のいずれも私の問題に取り組んでいませんでした。以下は私のために働きました。それがあなたの誰かを助けてくれるので、ここにそれを置く。
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();
}
}