canShip
メソッドを調べて、計算方法を見てみましょう。
/**
* Retrieve order shipment availability
*
* @return bool
*/
public function canShip()
{
if ($this->canUnhold() || $this->isPaymentReview()) {
return false;
}
if ($this->getIsVirtual() || $this->isCanceled()) {
return false;
}
if ($this->getActionFlag(self::ACTION_FLAG_SHIP) === false) {
return false;
}
foreach ($this->getAllItems() as $item) {
if ($item->getQtyToShip()>0 && !$item->getIsVirtual()
&& !$item->getLockedDoShip())
{
return true;
}
}
return false;
}
注文方法は次のように置き換えることができます
canUnhold()
order->state === 'holded'
isPaymentReview()
order->state === 'payment_review'
getIsVirtual()
order->is_virtual === 1
isCanceled()
order->state === 'canceled'
getActionFlag()
アクションフラグは販売プロセス中に設定され、データベースからの注文の取得には関係ありません。
getAllItems()
ここでは、注文アイテムを結合する必要があります。is_virtual
そして、locked_do_ship
の列ですsale_flat_order_item
テーブル。
getQtyToShip()
これも他の属性に基づいて計算されます
/**
* Retrieve item qty available for ship
*
* @return float|integer
*/
public function getQtyToShip()
{
if ($this->isDummy(true)) {
return 0;
}
return $this->getSimpleQtyToShip();
}
isDummy
parent_id === null
製品に「別個に出荷」オプションがある場合parent_id !== null
、または製品に「別個に出荷」オプションがない場合、returnsはtrueです。
getSimpleQtyToShip
を返しますqty_ordered - qty_shipped - qty_refunded - qty_canceled
。
コード
この情報を使用して、コレクションを準備できます。
$collection = Mage::getModel('sales/order')->getCollection();
まず、各注文に属するアイテムを結合します。
$collection->getSelect()
->joinLeft(
array('order_item' => $collection->getTable('sales/order_item')),
'main_table.entity_id=order_item.order_id', array('qty_ordered', 'qty_shipped', 'qty_refunded', 'qty_canceled', 'is_virtual', 'locked_do_ship'))
->group('main_table.entity_id');
次に、発送できない注文ステータスをフィルタリングします( "nin" = "not in"):
$collection
->addFieldToFilter('status', array('nin' => array(
'holded', 'payment_review', 'canceled'
)))
->addFieldToFilter('main_table.is_virtual', '0');
次に、出荷できるアイテム数のSQL式を作成します。
- 注文商品の出荷可能数量を合計します
- 仮想アイテムの場合、結果は0です
- 「ロックされた」アイテムの場合、結果は0です。
- 他のすべての場合、結果は
qty_ordered - qty_shipped - qty_refunded - qty_canceled
TODO:「個別に出荷する」という製品オプションを考慮に入れてください。このクエリでは、すべての親アイテムと子アイテムがカウントされるため、誤検知が発生isDummy()
します。SQLの結果も計算するための演習として残しておきます。
合計はエイリアス「shippable_items」で利用可能になります
$collection->addExpressionFieldToSelect(
'shippable_items',
'SUM(({{qty_ordered}} - {{qty_shipped}} - {{qty_refunded}} - {{qty_canceled}}) * !{{is_virtual}} * {{locked_do_ship}} IS NOT NULL)',
array(
'qty_ordered' => 'order_item.qty_ordered',
'qty_shipped' => 'order_item.qty_shipped',
'qty_refunded' => 'order_item.qty_refunded',
'qty_canceled' => 'order_item.qty_canceled',
'is_virtual' => 'order_item.is_virtual',
'locked_do_ship' => 'order_item.locked_do_ship'));
最後に、出荷可能なアイテムの数が正の注文のみをフィルタリングします。列は集計関数で計算されるため、「WHERE」ではなく「HAVING」を使用する必要があります。
$collection->getSelect()->having('shippable_items > 0'));