I built a module a couple of weeks ago for a client who needed to be able to change the status of orders at any time, as well as having a couple of custom order statuses. It appeared that the best way to change the status or state was by using the setState() method on the order object. Before we get into that, let’s take a look at how Magento sets up the default states and statuses:
Magento sets them up in this file in the Sales model config file: app/code/core/Mage/Sales/etc/config.xml under global > sales > order. There in the ‘statuses’ tag, you’ll see the 8 default statuses (some of which you probably didn’t know existed). In the ‘states’ tag, you’ll see that Magento is setting up 7 different order states. There is also a ‘statuses’ tag as a child of the states. Here is where which statuses are able to be a part of each state. For example, under the ‘processing’ state, the only available status is ‘processing’ (as you can see, you can set the default status for any particular state by adding default=”1″ to the status).
Knowing which statuses are a part of which states is very important. When using the setState() method, you need to make sure that the status/state you are trying to change the order to. Another important thing to take note of is that the ‘complete’ and ‘closed’ states are protected, and you cannot use setState() to change an order to either of those states without overriding the order model to allow the passing of false (setState() passes your parameters to a protected function _setState() which hard-codes true into the ‘shouldProtectState’ parameter).
Ok, now on to the setState() method. This method not only allows you to change the state and status, it also adds the change to the order’s Comments History and allows you to notify the customer. This method can take up to 4 parameters, which I’ll list in order:
- $state (string): This is the state you would like to change the order to. Must match the xml tag in config.xml
- $status (string or true): This is the status you would like to change the order to. Since by default Magento only has one status per state it either has to be the correct status name, or if you pass true it will just get the default status for the state you are passing.
- $comment (string): If you want to pass in a string to add to the comments, you can do so. By default it just passes a blank string
- $isCustomerNotified (bool): Leave this parameter off if you do not want the customer to be notified, otherwise pass in true
So, if I wanted to change the order status to “Cancelled”, and I don’t want the customer notified, this is how I would do it:
$order->setState('cancelled', true, 'Cancelled order due to bad credit card');
Other statuses and states can be added by creating your own module and adding them via your config.xml. You can also add statuses to the other states. This would allow you to change the statuses of your orders right from the order view in the admin.