Magento 1.8 – Best Way to Delete an Order

magento-1.8orders

Synopsis

I would like to delete test orders from my Magento store because they affect the statistics and reports of sales. Would the following code delete all records from:

  • sales/order_invoice
  • sales/order_invoice_grid
  • sales/order_shipment
  • sales/order_shipment_grid
  • sales/order_creditmemo
  • sales/order_creditmemo_grid
  • sales/order_payment_transaction
  • sales/order
  • sales/order_grid

Code Snippet

$orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('entity_id', (array) $orderIds);

foreach ($orders as $order) {
    // XXX - Possible cascade delete?
    $order->delete();
}

Or would I need to delete each of the records individually?

Best Answer

As stated in the comments the script you have should work nicely for magento version 1.4+.
In the 1.4 version the sales entities were mapped to flat tables that have constraints so everything should cascade nicely.

For versions prior to 1.4 all the entities related to sales (orders, invoices, shipments and creditmemos) were EAV and kept in the same tables. So nothing cascade.
For version prior to 1.4 you can try this script.
This should work for later versions also but I don't think it's needed.

$orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('entity_id', (array) $orderIds);
foreach ($orders as $o) {
    //load order object - I know it's not ok to use load in a loop but it should be ok since it's a one time script
    $order = Mage::getModel('sales/order')->load($o->getId());

    $invoices = $order->getInvoiceCollection();
    foreach ($invoices as $invoice){
        //delete all invoice items
        $items = $invoice->getAllItems(); 
        foreach ($items as $item) {
            $item->delete();
        }
        //delete invoice
        $invoice->delete();
    }
    $creditnotes = $order->getCreditmemosCollection();
    foreach ($creditnotes as $creditnote){
        //delete all creditnote items
        $items = $creditnote->getAllItems(); 
        foreach ($items as $item) {
            $item->delete();
        }
        //delete credit note
        $creditnote->delete();
    }
    $shipments = $order->getShipmentsCollection();
    foreach ($shipments as $shipment){
        //delete all shipment items
        $items = $shipment->getAllItems(); 
        foreach ($items as $item) {
            $item->delete();
        }
        //delete shipment
        $shipment->delete();
    }
    //delete all order items
    $items = $order->getAllItems(); 
    foreach ($items as $item) {
        $item->delete();
    }
    //delete payment - not sure about this one
    $order->getPayment()->delete();
    //delete quote - this can be skipped
    if ($order->getQuote()) {
        foreach ($order->getQuote()->getAllItems() as $item) {
            $item->delete();
        }
        $order->getQuote()->delete();
    }
    //delete order
    $order->delete();
}