Magento 1 sales/order collection returning duplicate order

308 Views Asked by At

Using Magento 1.14.3.4, I am trying to export all new orders and order items as follows:

$orders = Mage::getModel('sales/order')
    ->getCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter('created_at', array('from' => $date_from,'to' => $date_to))
    ->addAttributeToFilter('status', array('nin' => array('canceled', 'pending_payment', 'holded')))
    ->load();

I want to loop through the orders foreach($orders as $order) and within that loop I want to then loop through the products foreach($order['items'] as $item))

I can't figure out why this is returning multiple copies of the same order in the collection. The number of duplicate orders seems to correlate to the number of products in the order - so an order with 9 products purchased in it will have 9 duplicates in the collection.

It appears to me that I am loading the order items instead of the orders with item data within - although if this were the case, it doesn't make sense to me that the whole order is being duplicated.

Any advice would be appreciated.

EDIT - Collection source output

Below is an extracted and reduced output of the collection structure.

array(164) {
    [115]=>
        array(32) {
            ["id"]=>string(9) "100083056"
            ...
            ["account"]=>array(12) {...}
            ["billing_address"]=>array(13) {...}
            ["shipping_address"]=>array(13) {...}
            ["items"]=>
                array(1) {
                    [0]=>
                        array(22) {
                            ["item_id"]=>string(6) "194844"
                            ...
                    }
                }
            }
        }
    [116]=>
        array(32) {
            ["id"]=>string(9) "100083056"
            ...
            ["account"]=>array(12) {...}
            ["billing_address"]=>array(13) {...}
            ["shipping_address"]=>array(13) {...}
            ["items"]=>
                array(2) {
                    [0]=>
                        array(22) {
                            ["item_id"]=>
                                string(6) "194844"
                                ...
                        }
                    [1]=>
                        array(22) {
                            ["item_id"]=>
                            string(6) "194845"
                            ...
                        }
                    }
                }
    [117]=>
        array(32) {
            ["id"]=>string(9) "100083056"
            ...
            ["account"]=>array(12) {...}
            ["billing_address"]=>array(13) {...}
            ["shipping_address"]=>array(13) {...}
            ["items"]=>
                array(3) {
                    [0]=>
                        array(22) {
                            ["item_id"]=>
                                string(6) "194844"
                                ...
                        }
                    [1]=>
                        array(22) {
                            ["item_id"]=>
                                string(6) "194845"
                                ...
                        }
                    [2]=>
                        array(22) {
                            ["item_id"]=>
                                string(6) "194846"
                                ...
                        }
                    }
                }
        }

Now that I have formatted this, I realise that each repeated order is not in fact a duplicate order record but has an additional product item added to the items array.

1

There are 1 best solutions below

0
On

I would suggest you not to use load() directly since you don't know how big the collection actually is. You can load the items of this collection step by step, like so (which is easier on memory):

$orders = Mage::getModel('sales/order')
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('created_at', array('from' => $date_from,'to' => $date_to))
->addAttributeToFilter('status', array('nin' => array('canceled', 'pending_payment', 'holded')));
$orders->setPageSize(100); //N orders per loop



$pages = $orders->getLastPageNumber();
$currentPage = 1;
do{
    $orders->setCurPage($currentPage);
    $orders->load();
    foreach ($orders as $order){
        //here you can do things with a single order
    }
    $orders->clear();
    $currentPage++;
} while ($currentPage <= $pages);

Next I would load the order items with the actual getter method getAllItems() and then look from there:

foreach($order->getAllItems() as $orderItem) {
 // $orderItem->getName() ...
}