I use as follows:
1 - app/code/loca/Packagename/Modulename/etc/config.xml
<config>
<global>
<models>
<sales>
<rewrite>
<order>Packagename_Modulename_Model_Rewrite_Order</order>
</rewrite>
</sales>
<sales_resource>
<rewrite>
<quote>Packagename_Modulename_Model_Rewrite_Resource_Sales_Quote</quote>
</rewrite>
</sales_resource>
<modelrewrite>
<class>Packagename_Modulename_Model_Rewrite</class>
</modelrewrite>
</models>
<events>
<packagename_modulename_order_status_change>
<observers>
<packagename_modulename_model_rewrite>
<type>singleton</type>
<class>modelrewrite/observer</class>
<method>changeStateOrder</method>
</packagename_modulename_model_rewrite>
</observers>
</packagename_modulename_order_status_change>
</events>
<resources>
<modulename_setup>
<setup>
<module>Packagename_Modulename</module>
<class>Mage_Sales_Model_Resource_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</modulename_setup>
</resources>
</global>
<crontab>
<!-- here I am listing only major routines -->
<jobs>
<Packagename_Modulename_Model_Rewrite_SendOrderToERP>
<schedule>
<cron_expr>12 * * * *</cron_expr>
</schedule>
<run>
<model>modelrewrite/observer::runSendOrderToERP</model>
</run>
</Packagename_Modulename_Model_Rewrite_SendOrderToERP>
<Packagename_Modulename_Model_Rewrite_ReceiveERPStatusOrder>
<schedule>
<cron_expr>*/5 * * * *</cron_expr>
</schedule>
<run>
<model>modelrewrite/observer::runReceiveERPStatusOrder</model>
</run>
</Packagename_Modulename_Model_Rewrite_ReceiveERPStatusOrder>
</jobs>
</crontab>
2 - app/code/loca/Packagename/Modulename/Model/Rewrite/Order.php
class Packagename_Modulename_Model_Rewrite_Order extends Mage_Sales_Model_Order{
public function _setState($state, $status = false, $comment = '', $isCustomerNotified = null, $shouldProtectState = false){
// attempt to set the specified state
// tenta definir o status especificado
if ($shouldProtectState) {
if ($this->isStateProtected($state)) {
Mage::throwException(
Mage::helper('sales')->__('The Order State "%s" must not be set manually.', $state)
);
}
}
$this->setData('state', $state);
// add status history
if ($status) {
if ($status === true) {
$status = $this->getConfig()->getStateDefaultStatus($state);
}
$this->setStatus($status);
$history = $this->addStatusHistoryComment($comment, false); // no sense to set $status again
$history->setIsCustomerNotified($isCustomerNotified); // for backwards compatibility
}
Mage::dispatchEvent('packagename_modulename_order_status_change', array('order' => $this, 'state' => $state, 'status' => $status, 'comment' => $comment, 'isCustomerNotified' => $isCustomerNotified));
Mage::log("Packagename_Modulename_Model_Rewrite_Order Changing order to STATE ".$state." STATUS ".$status);
return $this;
}
}
3 - app/code/loca/Packagename/Modulename/Model/Rewrite/Observer.php
class Packagename_modulename_Model_Rewrite_Observer{
public function implementOrderStatus($event){
$order = $event->getOrder();
$state = $event->getState();
$status = $event->getStatus();
return $this;
}
public function changeStateOrder($observer){
Mage::log('changeStateOrder');
$order = $observer->getEvent()->getOrder();
if($order->getStatus() == "processing_paid"){
$this->autoInvoicing($order);
}
else if($order->getStatus() == "processing_shipped"){
$this->autoShipment($order);
}
// use your necessary ifs
$this->sendTransactionalEmail($order);
return $this;
}
public function autoShipment(Mage_Sales_Model_Order $order){
//...
}
public function autoInvoicing(Mage_Sales_Model_Order $order){
//...
//return $this;
}
public function sendTransactionalEmail(Mage_Sales_Model_Order $order){
switch ($order->getStatus()) {
case "processing":
$templateId = 1;
break;
case "pending_payment":
$templateId = 0;
break;
//...
default:
$templateId = 0;
break;
}
//...
}
public function runSendOrderToERP($schedule){
//...
}
public function runReceiveERPStatusOrder($schedule){
//...
}
//And much more another methods can be used after change state / status order: refund, calcel, etc
Thats kind of a hard thing you want to archive there.
The problem is, after the shipping got created, the order calculates the order status new (some of this happens in Model_Order->_checkState() ) so regardless what you set in the after shipping save event, it gets overwritten.
The Question becomes, why it is important to not have the state complete after this.
A possible Solution would be, to have a different complete status, which you can make the default, so you always have to set the complete/complete separate.
But this maybe does not fit your needs.
Best Answer
Solution 1
Working with an existing invoice
To change an existing invoice status from
paid
topending
is actually quite simple despite all the complexity built around it.To do this, pay no attention to the invoice
status
but focus solely on the invoicestate
. All you have to do is change the invoicestate
to the new desired state and thestatus
gets updated as well.Since the invoice has already been paid for, you probably want to reset the
total_paid
andbase_total_paid
fields of the particular order the invoice was for so you at some point later on mark it as paid.This should do just that:
To later mark it as paid on shipping, all you need do is simply get the invoice and call the
pay
method on it.Solution 2
Working with a new invoice
In order to create a
pending
invoice, the payment method you use for the order must allow you to do such. For that you need to override the payment method model and add these membere:For example if you want to do this for Check/money order or Cash On Delivery you need to override either app/code/core/Mage/Payment/Model/Method/Checkmo.php or app/code/core/Mage/Payment/Model/Method/Cashondelivery.php and add the above attribute.
After this when you create an invoice you will have an option near the save button to set the invoice status. To create a pending invoice select
Not capture
as seen below.If you want to mark it later as paid edit the invoice and between the buttons on to one called
Capture
.Since what you want to do is mark it as paid on shipping, all you need do is simply get the invoice and call the
pay
method on it.Hope it helps someone.