Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do order statuses/states work in Magento 1.4.x

As far as I understand Magento have various order statuses under global/sales/order/statuses which can be altered by either copying app/code/core/Mage/Sales/etc/config.xml to local scope or overriding it with your custom module.

There are also global/sales/order/states defined in the same file and as far as I understand states are something like statuses groups. Only states (not statuses) can be set at the order status in magento and statuses are something like states subdivisions. So in administrator interface you can change statuses of a placed order but you can't change state from the order status drop-down (you can change it by either invoicing the client or canceling the order).

As far as I understand you can easily add a new status to your Magento but can't add new state as states are somehow hardcoded with the rest or Magento order processing logic. I really hope that I'm wrong.

Please correct me if I'm wrong in any point as these are just my thoughts and it might be quite far from real Magento 1.4.x flow.

like image 300
user487772 Avatar asked Jul 15 '11 11:07

user487772


2 Answers

I'm quite sure that 'state' is free data, it can be set to ANY value using the setData option on an order instance. So if you write a custom module that can load an order, set data to one of your new 'states' and test with what ever custom logic you require.

$order = Mage::getModel('sales/order')->load(1);
$order->setData('state','myCustomState');
$order->setData('status','onCustomState');
echo $order->getState()
// Returns myCustomState

its worth bearing in mine that CLOSED/CANCELLED are protected states, so trying to use $order->setState('my_state') will fail on those order, but shouldn't fail on setData so you can overwrite a closed or cancelled order with this method.

if you were to overwrite the order model with a custom one you could add your own logic such as isOnCustomState() and allow the order to be handled in any way just by loading by id.

To add 'custom logic' to your order you could do something copy app\code\core\Mage\Sales\Model\Order.php into your local folder, then you can add functions into that model,

public function isActive(){ if($this->getState() == 'active'){ return true; } else { return false; }
public function isInActive(){ if($this->getState() == 'deactivated'){ return true; } else { return false; }

public function activate(){
    if(!$this->isActive()){
        $this->setData('state','active');
        $this->setData('status','Active Subscription');

        // some custom code to start a recuring payment

        return $this;
    }
}

public function deactiveate(){
    if(!$this->isInActive()){
        $this->setData('state','deactivated');
        $this->sendOrderUpdateEmail(true,'Your subscription has been deactivated.');

        // some custom code to stop a recuring payment

        return $this;
    }
}

now you can load an order and set activate or deactivate on that order to fire your custom code,

$order = Mage::getModel('sales/order')->load(1)->activate();

this code is all untested and just an example of somethings you could try, please don't just dump this code in your model and expect it to work perfectly. in code\core\Mage\Sales\etc\config.xml in the nodes sales/order/states add

<activated translate="label">
   <label>Active Subscription</label>
   <statuses>
      <pending default="1"/>
   </statuses>
   <visible_on_front/>
</activated>
like image 115
Alan Cole Avatar answered Nov 15 '22 04:11

Alan Cole


Magento Order is a finite state machine.

Therefore when you define status it would automatically try to define its state. Altering state directly is not recommended.

When you define status it checks various flags for shipment and invoices and depending in all those it would get the right state. Once order is in approved state however you can easily change status regardless of if there is invoice or any flag etc.

like image 1
Nasaralla Avatar answered Nov 15 '22 03:11

Nasaralla