Come ottenere la raccolta degli ordini che possono essere spediti?


8

Ho bisogno di ordini non ancora spediti o parzialmente spediti. Sto usando il codice qui sotto per ottenere gli ordini che possono essere spediti.

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

Ma non voglio usare foreach. Ho bisogno di qualcosa come sotto.

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

Risposte:


9

Esaminiamo il canShipmetodo per vedere come viene calcolato:

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

I metodi di ordine possono essere sostituiti come segue

  1. canUnhold ()

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

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

    order->is_virtual === 1
  4. isCanceled ()

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

    I flag di azione vengono impostati durante i processi di vendita, non rilevanti per il recupero degli ordini dal database

  6. getAllItems ()

    Qui dobbiamo fare un join sugli articoli dell'ordine. is_virtuale locked_do_shipsono colonne della sale_flat_order_itemtabella.

    1. getQtyToShip ()

      Questo viene nuovamente calcolato in base ad altri attributi

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

      isDummyil reso è vero se parent_id === nulle il prodotto ha l'opzione "spedisci separatamente" O se parent_id !== nulle il prodotto non ha l'opzione "spedisci separatamente".

      getSimpleQtyToShipritorna qty_ordered - qty_shipped - qty_refunded - qty_canceled.

Il codice

Con queste informazioni possiamo preparare una raccolta:

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

Innanzitutto, uniamo gli articoli che appartengono a ciascun ordine:

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

Quindi, filtriamo gli stati degli ordini che non possono essere spediti ("nin" = "non in"):

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

Quindi, creiamo un'espressione SQL per il numero di articoli che possono essere spediti:

  • sommiamo la quantità disponibile per gli articoli dell'ordine
  • per gli oggetti virtuali il risultato è 0
  • per gli elementi "bloccati" il risultato è 0
  • per tutti gli altri, il risultato è uguale qty_ordered - qty_shipped - qty_refunded - qty_canceled

TODO: prendi in considerazione l'opzione del prodotto "spedisci separatamente. Questa query conterà tutti gli articoli padre e figlio, quindi ci saranno falsi positivi. Lascerò come un esercizio al lettore per calcolare anche il risultato isDummy()in SQL.

La somma sarà disponibile con l'alias "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'));

Infine filtriamo solo gli ordini con un numero positivo di articoli spedibili. Dobbiamo usare "HAVING" invece di "WHERE" perché la colonna viene calcolata con una funzione aggregata:

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

buona spiegazione. Controllerò. + 1
Amit Bera

2

Non è possibile essere because of lot of conditionscontrolla e ogni volta che we use canShip()funziona. Troppo complesso per farlo.

È not only depend one /two order fields dependcome

  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

eccetera

Quindi, dipende da alcune logiche / condizioni complesse come:

Guarda una vista sulla classe Mage_Sales_Model_Order e puoi capirlo.

 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;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.