Làm thế nào để có được bộ sưu tập các đơn đặt hàng có thể được vận chuyển?


8

Tôi cần các đơn đặt hàng chưa được vận chuyển hoặc được vận chuyển một phần. Tôi đang sử dụng mã dưới đây để có được đơn đặt hàng có thể được vận chuyển.

foreach ($orderIds as $orderId) {
    $order = Mage::getModel('sales/order')->load($orderId);
    if ($order->canShip()) {
        echo "Shipping Pending";
    }
}

Nhưng tôi không muốn sử dụng foreach. Tôi cần một cái gì đó như dưới đây.

Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status','can_ship');

Câu trả lời:


8

Hãy xem xét canShipphương pháp để xem cách tính toán:

/**
 * 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;
}

Các phương thức đặt hàng có thể được thay thế như sau

  1. có thể ()

    order->state === 'holded'
  2. isPaymentReview ()

    order->state === 'payment_review'
  3. getIsVirtual ()

    order->is_virtual === 1
  4. bị hủy ()

    order->state === 'canceled'
  5. getActionFlag ()

    Cờ hành động được đặt trong quá trình bán hàng, không liên quan để lấy đơn đặt hàng từ cơ sở dữ liệu

  6. get ALLItems ()

    Ở đây chúng ta cần phải tham gia vào các mục đặt hàng. is_virtuallocked_do_shiplà các cột của sale_flat_order_itembảng.

    1. getQtyToShip ()

      Điều này một lần nữa được tính toán dựa trên các thuộc tính khác

      /**
       * Retrieve item qty available for ship
       *
       * @return float|integer
       */
      public function getQtyToShip()
      {
          if ($this->isDummy(true)) {
              return 0;
          }
      
          return $this->getSimpleQtyToShip();
      }

      isDummytrả về là đúng nếu parent_id === nullvà sản phẩm có tùy chọn "ship riêng biệt" HOẶC nếu parent_id !== nullvà sản phẩm không có tùy chọn "ship riêng biệt".

      getSimpleQtyToShiptrả lại qty_ordered - qty_shipped - qty_refunded - qty_canceled.

Mật mã

Với thông tin này, chúng tôi có thể chuẩn bị một bộ sưu tập:

$collection = Mage::getModel('sales/order')->getCollection();

Đầu tiên, chúng tôi tham gia các mục thuộc về mỗi đơn hàng:

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

Sau đó, chúng tôi lọc các trạng thái đơn hàng không thể được vận chuyển ("nin" = "không trong"):

$collection
    ->addFieldToFilter('status', array('nin' => array(
        'holded', 'payment_review', 'canceled'
    )))
    ->addFieldToFilter('main_table.is_virtual', '0');

Sau đó, chúng tôi tạo một biểu thức SQL cho số lượng các mặt hàng có thể được vận chuyển:

  • chúng tôi tổng hợp số lượng shippable trên các mục đặt hàng
  • đối với các mục ảo kết quả là 0
  • đối với các mục "bị khóa", kết quả là 0
  • đối với tất cả những người khác, kết quả bằng qty_ordered - qty_shipped - qty_refunded - qty_canceled

TODO: đưa tùy chọn sản phẩm "gửi riêng vào tài khoản. Truy vấn này sẽ tính tất cả các mục cha mẹ và con, do đó sẽ có kết quả dương tính giả. Tôi sẽ để nó như một bài tập cho người đọc để tính kết quả của isDummy()SQL.

Tổng số sẽ có sẵn với bí danh "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'));

Cuối cùng, chúng tôi chỉ lọc các đơn hàng có số lượng mặt hàng có thể chuyển đổi tích cực. Chúng tôi phải sử dụng "HAVING" thay vì "WHERE" vì cột được tính bằng hàm tổng hợp:

$collection->getSelect()->having('shippable_items > 0'));

giải thích tốt. Tôi sẽ kiểm tra. + 1
Amit Bera

2

Không thể because of lot of conditionskiểm tra và bất cứ khi nào we use canShip()chức năng. Quá phức tạp để làm điều đó.

not only depend one /two order fields dependgiống như

  1. order status hold or not.
  2. order status cancel or not.
  3. order virtual or not.
  4. Order item is capable to do ship order

Vân vân

Vì vậy, nó phụ thuộc vào một số logic / điều kiện phức tạp như:

Xem chế độ xem trên lớp Mage_Sales_Model_Order và bạn có thể hiểu điều đó.

 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;
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.