8

I'm trying to mark a "Processing" order as Complete when I get a certain response back from a third party service. I've got everything set up for this, but the only problem is that orders are staying in the Processing state.

I'm generating an invoice (I don't think I need this though, as each item is marked as "invoiced" in the Magento backend) and a shipment like so:

$order = Mage::getModel('sales/order')... (etc)
$shipment = $order->prepareShipment($quantities);
$shipment->register();
$shipment->setOrder($order);
$shipment->save();

$invoice = $order->prepareInvoice($quantities);
$invoice->register();
$invoice->setOrder($order);
$invoice->save();

This doesn't seem to be doing it though - I get no errors back from this code, but the order remains as processing. In the backend I can still see the "Ship" button at the top of the order, and each item is in the "invoiced" state.

Any tips would be greatly appreciated.

gregdev
  • 1,863
  • 3
  • 23
  • 28

6 Answers6

17

Try

$order->setStateUnprotected('complete',
    'complete',
    'Order marked as complete automatically',
    false);

This method is in app/code/local/Mage/Sales/Model/Order.php (in v1.6.1)

938:    public function setStateUnprotected($state, $status = false, $comment = '', $isCustomerNotified = null)

In Magento 1.7.0.0 this method has been removed. Try this instead:

    $order->setData('state', "complete");
    $order->setStatus("complete");
    $history = $order->addStatusHistoryComment('Order marked as complete automatically.', false);
    $history->setIsCustomerNotified(false);
    $order->save();
Community
  • 1
  • 1
Max
  • 8,671
  • 4
  • 33
  • 46
5

You can take a look at this article (in Russian).

Here is the code from the article:

$order = $observer->getEvent()->getOrder();

if (!$order->getId()) {
    return false;
}

if (!$order->canInvoice()) {
    return false;
}

$savedQtys = array();
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($savedQtys);
if (!$invoice->getTotalQty()) {
    return false;
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->register();

$invoice->getOrder()->setCustomerNoteNotify(false);
$invoice->getOrder()->setIsInProcess(true);

$transactionSave = Mage::getModel('core/resource_transaction')
    ->addObject($invoice)
    ->addObject($invoice->getOrder());

$transactionSave->save();
Jon Surrell
  • 9,444
  • 8
  • 48
  • 54
Roman Snitko
  • 3,655
  • 24
  • 29
  • Thanks, the code in the article did the trick after I changed to to a shipment rather than an invoice. – gregdev Jan 18 '12 at 22:36
  • Unfortunately, the link is now broken. – Mike May 09 '12 at 19:40
  • Would be really nice to have an updated link. archive.org still has a version of the link in case anyone is interested. http://web.archive.org/web/20110414102634/http://snowcore.net/magento-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F-%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B0%D1%86%D0%B8%D1%8F-%D0%B7%D0%B0%D0%BA%D0%B0%D0%B7%D0%B0. Use google chrome to get a translation. – shaune May 11 '12 at 20:06
  • @Mike domain will be available in few days, so you can check later – Roman Snitko May 12 '12 at 12:39
  • @gregdev can you share your solution? (shipment rather than invoice) – Jon Surrell Jan 14 '15 at 10:57
3

I'm doing this that way:

$order->setState('complete', true, $this->__('Your Order History Message Here.'))
      ->save();
user487772
  • 8,800
  • 5
  • 47
  • 72
  • 3
    Thanks for the response. This brought up the error "The Order State "complete" must not be set manually." – gregdev Jan 18 '12 at 22:57
1

Code for processing order programmatically. Can be put on success event or cron

$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

$order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
$order->setStatus(Mage_Sales_Model_Order::STATE_COMPLETE);

$history = $order->addStatusHistoryComment('Order is complete', false);
$history->setIsCustomerNotified(false);

$order->save();
  • Why are you setting state and status to the same value? – Marcus Wolschon Apr 19 '19 at 11:36
  • @MarcusWolschon : For better understanding take a look of "sales_order_status" table . Status is a representation of state and based on it , status label is displayed. – Ahmad Vaqas Khan Apr 20 '19 at 18:14
  • The names of the shop-specific status codes (and their translated labels) are usually different from the fixed Magento state values. A status is assigned to a state and one status may be assinged as the default status for a Magento state. So the question remains. Why set status and state to the same value. The status is Shop-specific and should not come from a Magento constant for a state. – Marcus Wolschon Apr 24 '19 at 09:45
0

Magento will automatically mark an order as complete if:

  • Payment has been made.
  • An invoice exists.
  • A shipment exists.

If you cannot do that, try to create a custom 'state' and set that. In the meantime, to set the order to processing, try this:

 $order = Mage::getModel('sales/order')->load($id);
 $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();

Should work without errors. Tested in Magento 1.7.0.2

Jongosi
  • 2,305
  • 1
  • 28
  • 31
0

In my case, I needed the end users to see completed in the order grid, but the order state really made no difference. So I did just went to

System->Order Status Create a new Status called Completed (note the d so it's easy to differentiate) Assign that status to the state Processing/pending, whatever.

This worked for our client -- but wouldn't work if you heavily depend on order state (Different than order status).

espradley
  • 2,138
  • 2
  • 17
  • 15