Delete test orders in Magento

Featured Image

You got a Magento project to develop, you created a Magento theme, you placed initial products and categories and you also placed some test orders to see if Shipping and Payment methods work as expected. Everything seems to be cool and the client wishes to launch the site. You launch it. When you enter the administration for the first time after the launch, you will see all your test orders there. You know those should be deleted. But how?
This is a new version of the same article.

If you try to delete orders in the backend, you will find out that you can only set the status to “cancelled” and the order is still there.  Unfortunately, Magento doesn’t enable us to delete those via administration, so you will not see any “Delete order” button. This can be quite frustrating both to developers and the merchants. People coming from an SAP world find the inability to delete to have some merit but there should be a status that removes the sales count from the reports i.e. sales, inventory, etc.

So, what to do?

You need to create php script in Magento root folder, copy this code into script and run script.

/**
 * @author Dejan Radic <dejan.radic@inchoo.net>
 */

if (version_compare(phpversion(), '5.2.0', '<')===true) {
    echo  '<div style="font:12px/1.35em arial, helvetica, sans-serif;"><div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;"><h3 style="margin:0; font-size:1.7em; font-weight:normal; text-transform:none; text-align:left; color:#2f2f2f;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.2.0 or newer. <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
    exit;
}

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);

$mageFilename = 'app/Mage.php';

if (!file_exists($mageFilename)) {
    echo $mageFilename." was not found";
    exit;
}

require_once $mageFilename;

Mage::app();

$executionPath = null;

/*
 * determine Magento Edition
 */
if (file_exists('LICENSE_EE.txt')) {
    $edition = 'EE';
}elseif (file_exists('LICENSE_PRO.html')) {
    $edition = 'PE';
} else {
    $edition = 'CE';
}

if(($edition=='EE' && version_compare(Mage::getVersion(), '1.11.0.0.', '<')===true)
        || ($edition=='PE' && version_compare(Mage::getVersion(), '1.11.0.0.', '<')===true)
        || ($edition=='CE' && version_compare(Mage::getVersion(), '1.6.0.0.', '<')===true)
  ){
   $executionPath = 'old';
} else {
   $executionPath = 'new';
}

$xpathEntity = 'global/models/sales_entity/entities//table';

if ($executionPath == 'old') {
    $xpathResource = 'global/models/sales_mysql4/entities//table';
} else {
    $xpathResource = 'global/models/sales_resource/entities//table';
}

$salesEntitiesConf = array_merge(
    Mage::getSingleton('core/config')->init()->getXpath($xpathEntity),
    Mage::getSingleton('core/config')->init()->getXpath($xpathResource)
);

$resource = Mage::getSingleton('core/resource');
$connection = $resource->getConnection('core_write');

/*
 * If you want delete System/Order Statuses (Status and State) you
 * should comments below lines (46-51)
 */
$skipTables = array (
        $resource->getTableName('sales_order_status'),
        $resource->getTableName('sales_order_status_state'),
        $resource->getTableName('sales_order_status_label')
    );
$salesEntitiesConf = array_diff($salesEntitiesConf, $skipTables);

/*

Multiple RDBMS Support in Magento CE 1.6+ / EE 1.11+

http://www.magentocommerce.com/images/uploads/RDBMS_Guide2.pdf

2.2. Adapters:

... The new Varien_DB_Adapter_Interface was added to sign a contract that all
developed adapters must execute in order to get Magento working on an actual
database. The interface describes the list of methods and constants that can be used by resource models...

Used below in the loop:

 * If $executionPath == 'old'
    * Varien_Db_Adapter_Pdo_Mysql::showTableStatus()
    * Varien_Db_Adapter_Pdo_Mysql::truncate()
 * Else
    * Varien_Db_Adapter_Interface::isTableExists()
    * Varien_Db_Adapter_Interface::truncateTable()

*/

while ($table = current($salesEntitiesConf) ){
    $table = $resource->getTableName($table);

    if ($executionPath == 'old') {
        $isTableExists = $connection->showTableStatus($table);
    } else {
        $isTableExists = $connection->isTableExists($table);
    }
    if ($isTableExists) {
        try {
            if ($executionPath == 'old') {
                $connection->truncate($table);
            } else {
                $connection->truncateTable($table);
            }

            printf('Successfully truncated the <i style="color:green;">%s</i> table.<br />', $table);
        } catch(Exception $e) {
            printf('Error <i style="color:red;">%s</i> occurred truncating the <i style="color:red;">%s</i> table.<br />', $e->getMessage(), $table);
        }
    }

    next($salesEntitiesConf);
}

exit('All done...');

After you have it executed, the test orders will not be in the database any more. Keep in mind that this will delete ALL orders, in the database. So, you should execute this queries immediately after launch.

This script is tested on following Magento versions: 1.6.1.0 CE, 1.6.0.0 CE, 1.5.1.0. CE, 1.11.0.2 EE, 1.10.0.2 EE, 1.9.0.0 EE, 1.11.0.0 PE, 1.10.0.2 PE and 1.9.0.0 PE.
You can download script here.

114
Top

Enjoyed this post?

Subscribe to our RSS Feed, Follow us on Twitter and spread it to your friends!

Author

Dejan Radic

Magento Certified Developer

At Inchoo, Dejan is a Magento back-end developer.

Other posts from this author

Discussion 114 Comments

1 2 3
Add Comment
  1. Great post.
    You save me some time with my future task.
    Thanks.

    ;-)

  2. Matthew

    Great post.

    Would it be possible to delete specific orders? Say for instance, if your store had been running for a little while with the original test orders still in place and you only found the above snippet now?

    Cheers,
    Matt

  3. Hello Matthew,
    That was the point of this post. It is currently impossible to do it with Magento administration. You would have to go to MySQL client and delete relevant entities manually starting with sales_order* tables.

  4. Vitor Braga

    Hey Tomislav Bilic,

    In the Dashboard, if u see Lifetime Sales, this show the value of urs sales yet =//

  5. Works like a charm. Thanks for the post!

    Paddy

  6. The one attribute this code doesn’t seem to address is Shopping Cart Reports.

    After running this code, if you visit backend and go to REPORTS>SHOPPING CART>PRODUCTS IN CARTS, you will see no items listed, but the counter will still list the number of test orders you’ve placed in carts.

    I’d suggest the fix myself, but am unsure which table or attribute controls this value – should just be a matter of adding two lines – one to truncate, and another to auto-increment.

  7. Matthew Mucklo

    Correct me if I’m wrong, but don’t you want to add these tables too?

    SET FOREIGN_KEY_CHECKS=0;
    TRUNCATE `sales_order_tax`;
    TRUNCATE `sales_flat_quote_shipping_rate`;
    TRUNCATE `sales_flat_quote_payment`;
    TRUNCATE `log_url_info`;
    TRUNCATE `log_url`;

    ALTER TABLE `sales_order_tax` AUTO_INCREMENT=1;
    ALTER TABLE `sales_flat_quote_shipping_rate` AUTO_INCREMENT=1;
    ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
    ALTER TABLE `log_url_info` AUTO_INCREMENT=1;
    SET FOREIGN_KEY_CHECKS=1;

  8. Matthew Mucklo

    Oh, and BTW, don’t worry about the PRODUCTS IN CARTS tally being wrong. It seems to be unrelated.

    It looks like the wrong reporting of the total in REPORTS>SHOPPING CART>PRODUCTS IN CARTS is an issue with the current version of Magento (at least as of 1.1.6), unrelated to the above queries. I think they may have grabbed the total from the wrong table(s) in the first place. Someone could test in a fresh install with a bunch of products loaded, but no items ever added to carts.

    This was pointed out in the Magento Forums, and from my research in code and DB queries, it seems to be the case.

    See:

    http://www.magentocommerce.com/bug-tracking/issue?issue=3899

  9. Hey there Tomislav!

    Great post here, very appreciated on behalf of the community!

    We did a bit further modification by the following:
    + resetting all dashboard data
    + setting prefix’s for the following numbers: orders, invoices, shipments, and credit memo’s

    Feel free to check it out here: http://eliasinteractive.com/blog/magento-ecommerce-how-to-reset-all-test-order-information-and-set-unique-prefix-for-orders-invoices-shipments-and-credit-memos/

    Thanks again for your contributions!
    Lee Taylor / Elias Interactive

  10. L. Nunes

    Thanks Tomislav!!
    It worked perfectly :)

    Cheers!

  11. Sam K

    Hi Tomislav,

    Thoroughly useful script. Exactly what I was looking for whilst developing out my Magento shop. A real time saver…

    Cheers!

  12. Is this SQL Query still valid for Magento? new Log_Visitor tables got added in version 1.3.1.1, so I don’t this this query will still do it all 100%, it certainly removes the test orders in 1.3.2.2. Just don’t want it missing anything.

    Please take a little look.
    Thanks,
    Rob.

  13. @Robert: We surely will, just when we manage to catch some free time. Hope you understand. Few days passed since your question and I was wondering if you managed to solve the issue already. If you did, feel free to post the update query to us and we’ll publish it. Thanks.

  14. sam

    trouble is that quite often post launch there are multiple test orders created, these then are un deletable

  15. AndrewT

    THANKS!

  16. Reforced

    Thanks mate! Works perfect in magento 1.3.2.2!
    No error in the reports > products in chart either!

    Perfect ;-)

  17. I confirm, works great under 1.3.2.2!
    thanks so much

  18. Well check this, a total solution for deleting Magento order “Delete Any Order”

    https://www.yireo.com/software/delete-any-order

  19. marumaru

    Thanks for the post.

    You also might want to truncate the following tables too:

    whishlist_item
    table that starts with catalogsearch

  20. Bman

    I don’t want to delete customers from magento. Can I leave the customer reset portion out and be okay?

    thanks..

  21. mattheoh

    Works perfectly on Magento ver. 1.3.2.3 !
    Thanks for this trick :-)

  22. David

    Also just tested on v1.3.2.3 and worked like a charm!
    Thanks for this. :)

  23. Thanks a lot!!!

  24. freshyseth

    Did it with version 1.3.2.4 and it worked like a champ! Thanks for the solution.

  25. Florian

    I comfirm that works with 1.3.2.4, thanks :)

  26. Mike

    Magento won’t let you delete orders or do a bunch of other stuff in its misguided attempt be your nanny in helping you to obey various accounting laws in certain countries.

    I wish there was a “scofflaw” switch you could se that lets you do this forbidden stuff. Those of us in the United States are stuck with the inconveniences of a superset of every piddling regulation of every country in the EU.

  27. Like others I was astonished to find this facility not present.

    I have php and sql knowledge and feel for those that have mentioned the inability to get around these things. I have made a simple form using the code discussed on this site and it is available for download at http://www.mycreateabook.com.au/magentoReset.zip for all who wants to use it.

    The only requirement would be that you need to know your sql database settings that should be available from your website administrator if you do not already know it.

    Thanks for the code in the firt place. It saved me heaps of time fishing through to work it out myself. I am still in the process of setting up my site with Magento. It is visible at the moment at http://webstore.mycreateabook.com.au

  28. center

    yes how about this?


    Matthew Mucklo Says

    November 11th, 2008 at 23:10

    Correct me if I’m wrong, but don’t you want to add these tables too?

    SET FOREIGN_KEY_CHECKS=0;
    TRUNCATE `sales_order_tax`;
    TRUNCATE `sales_flat_quote_shipping_rate`;
    TRUNCATE `sales_flat_quote_payment`;
    TRUNCATE `log_url_info`;
    TRUNCATE `log_url`;

    ALTER TABLE `sales_order_tax` AUTO_INCREMENT=1;
    ALTER TABLE `sales_flat_quote_shipping_rate` AUTO_INCREMENT=1;
    ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
    ALTER TABLE `log_url_info` AUTO_INCREMENT=1;
    SET FOREIGN_KEY_CHECKS=1;

  29. Hi Matthew.

    If you are referring to my post, it has been included already but I have it at the bottom of the file to keep it separate.

  30. Todd

    I too am using 1.3.2.4. I tried the reset script and got a “Table Reset Successful” message, however when I return to the dashboard all of the dummy orders are still there. Any ideas what may have gone wrong, and why it did not clear the dummy orders? Thanks.

  31. Very effective query. We had a lot of test data in our database, and we’re lauching into production today. Thanks for the help.

  32. David

    Brilliant, thanks

  33. Absolutely brilliant. Thanks so much for posting this – worked like a charm. Solid gold.

  34. Brilliant post, thanks.

    One point I would like to make though, just for others using this, if you don’t want product tags deleted etc, remove that line before running this in your db.

  35. Brilliant stuff, this worked without flaw on version 1.3.2.4 Thanks.

    please could you provide the sql query to delete the top and last 5 search terms?

  36. Is still valid in magento 1.4?

  37. Pingback: Elias Interactive » Magento eCommerce: How To Reset All Test Order Information and Set Unique Prefix For Orders, Invoices, Shipments, and Credit Memos

  38. Awesome solution. Thanks a lot!

  39. James

    Has anyone tried this with release 1.4.0.1 ?

  40. James,

    Yes, I just tried on 1.4.0.1. Worked perfectly!

  41. I delete specific orders like this (cobbed together from magento forums)

    first, set collation with this script:
    $value)
    {
    mysql_query(“ALTER TABLE $value COLLATE $db_collate”);
    echo $value.’ changed to ‘.$db_collate.’ ‘;
    }
    }
    echo “DB collation changed”;
    ?>

    Then I run this in phpmyAdmin (just change the order ID at the start):
    [it does seem to mess with the order ID in the URLs]

    ## SET FOREIGN_KEY_CHECKS = 1;
    ## WORKS ON VERSION 1.3.2.3

    SET @orderId = ’100000772′;

    SET FOREIGN_KEY_CHECKS = 1;

    SET @salesFlatQuoteId = (
    SELECT entity_id
    FROM sales_flat_quote
    WHERE reserved_order_id = @orderId
    );
    SET @salesOrderId = (
    SELECT entity_id
    FROM sales_order
    WHERE increment_id = @orderId
    );

    CREATE TEMPORARY TABLE del_sales(
    id INT AUTO_INCREMENT PRIMARY KEY,
    salesId INT(10)
    )
    COLLATE ‘utf8_unicode_ci’;

    CREATE TEMPORARY TABLE del_statusSales(
    id INT AUTO_INCREMENT PRIMARY KEY,
    salesId INT(10)
    )
    COLLATE ‘utf8_unicode_ci’;

    INSERT INTO del_statusSales (salesId)
    SELECT entity_id
    FROM sales_order_entity_int
    WHERE value = @salesOrderId
    AND attribute_id = ANY (
    SELECT attribute_id
    FROM eav_attribute
    WHERE attribute_code = ‘order_id’
    )
    AND entity_id = ANY (
    SELECT entity_id
    FROM sales_order_entity
    WHERE entity_type_id = ANY (
    SELECT entity_type_id
    FROM eav_entity_type
    WHERE entity_type_code = ‘invoice’
    OR entity_type_code = ‘shipment’
    OR entity_type_code = ‘creditmemo’
    )
    );

    INSERT INTO del_sales (salesId)
    SELECT entity_id
    FROM sales_order_entity
    WHERE parent_id = ANY (
    SELECT salesId
    FROM del_statusSales
    )
    AND entity_type_id = ANY (
    SELECT entity_type_id
    FROM eav_entity_type
    WHERE entity_type_code = ‘invoice_item’
    OR entity_type_code = ‘invoice_comment’
    OR entity_type_code = ‘shipment_item’
    OR entity_type_code = ‘shipment_comment’
    OR entity_type_code = ‘shipment_track’
    OR entity_type_code = ‘creditmemo_item’
    OR entity_type_code = ‘creditmemo_comment’
    );
    INSERT INTO del_sales (salesId)
    SELECT salesId
    FROM del_statusSales;

    INSERT INTO del_sales (salesId)
    SELECT entity_id
    FROM sales_order_entity
    WHERE parent_id = @salesOrderId;

    DELETE FROM sales_order_entity
    WHERE entity_id = ANY (
    SELECT salesId
    FROM del_sales
    );

    DELETE FROM sales_flat_quote
    WHERE reserved_order_id = @orderId;

    DELETE FROM sales_flat_order_item
    WHERE quote_item_id = @salesFlatQuoteId;

    DELETE FROM sales_order
    WHERE increment_id = @orderId;

    /* drop temp tables */
    DROP TEMPORARY TABLE del_sales;
    DROP TEMPORARY TABLE del_statusSales;

  42. Let’s try that first one again:

    $value)
    {
    mysql_query(“ALTER TABLE $value COLLATE $db_collate”);
    echo $value.’ changed to ‘.$db_collate.’ ‘;
    }
    }
    echo “DB collation changed”;
    ?>

  43. Adi

    great job. thanks

  44. Does not work anymore on version 1.4.1.0. Table structure has changed after upgrading as it seems..

    table sales_order is changed to sales_flat_order and a few others. This trick used to work on my previous Magento version.

  45. Is there any way for doing this in magento 1.4.1? Thanks ~

  46. Steve

    Thanks for the great tip!

    I’ve read some comments and I saw some other sites that linked to this URL. It should work with the version I have installed (v1.3.2.4), but I have something strange going on..

    I executed the SQL and i clearly see that the tables are actually empty.
    But all the data (the orders, ..) are still there. Really weird.
    I see an order with orderID 100000031, I do a search in phpmyadmin for %100000031% in all the tables and I cannot find anything.

    - I refreshed the cache through the admin and still the orders are there.
    - I removed /var/cache and /var/sessions through ftp and still the orders are there.

    Does anyone have a clue what is going on?

    I’m working on the correct database :)

  47. Cobay

    This is not working on Recent Magento v1.4.1
    Help me~~~~

  48. rameez

    Hi, Your post is awesome. works great. I am using it and works like a charm. Thanks for that man.
    Carry on.

  49. Because Magento uses foreign keys, it’s enaugh to run truncate on 2-3 tables `sales_flat_order` , `sales_flat_quote` (for 1.4.1.0 didn’t test to see if there are any but tables as sales_flat_order_… will also be truncated) also truncate will set your increment id to 1

  50. Pingback: Magento Blog - MagThemes.com

1 2 3

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top