1

I am trying to invoice a single product of an order. I have found exactly the same question here. So i have written a observer of sales_order_save_commit_after event and then integrate that code into my observer. But it seems like it is not working for me. Because When i place an order, it stucks in a loop. Am i making a mistake?

class Emmagento_Autoinvoice_Model_Observer {

public $order;
public $incrementid;

function afterSalesOrderSaveCommitAfter(&$event) {

    return $this->__process($event);
}

protected function __process($event) {

    $this->order = $event->getEvent()->getOrder();
    $order = Mage::getModel('sales/order')->load($this->order->getId());
    $this->incrementid = $order->getIncrementId();
    if (!$this->order->getId()) {
        return $this;
    }
    else {

        $this->createInvoice();
    }
}

protected function createInvoice() {
 $orderState = $this->order->getState();
 $order = Mage::getModel('sales/order')->loadByIncrementId($this->incrementid);
 $items = $order->getAllItems();
 $qtys = array();
                foreach ($items as $item) {
                    $_sku = $item->getSku();
                    $_catalog = Mage::getModel('catalog/product');
                    $_productId = $_catalog->getIdBySku($_sku);
                    $_product = Mage::getModel('catalog/product')->load($_productId);
                    if ($_product->getAutoinvoice() == "1") {
                        $qty_to_invoice = $item->getQtyOrdered(); 
                    } else {
                        $qty_to_invoice = 0;
                    }
                    $qtys[$item->getId()] = $qty_to_invoice;
                }
 $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($qtys);
 $amount = $invoice->getGrandTotal();
                    $invoice->register()->pay();
                    $invoice->getOrder()->setIsInProcess(true);

                    $history = $invoice->getOrder()->addStatusHistoryComment(
                        'Partial amount of $' . $amount . ' captured automatically.', false
                    );

                    $history->setIsCustomerNotified(true);

                    $order->save();

                    Mage::getModel('core/resource_transaction')
                        ->addObject($invoice)
                        ->addObject($invoice->getOrder())
                        ->save();
                    $invoice->save();
                    $invoice->sendEmail(true, ''); //set this to false to not send the invoice via email
}
  • Check your **increment id **, where is this t coming from? – Adarsh Khatri Jun 13 '15 at 2:41
  • Adarsh you may check now. i have written complete code now – umair ayub Jun 13 '15 at 8:28
1

In observer you can get order by calling $observer->getEvent()->getOrder();, why not use this method.

Try this code:

<?php
class Emmagento_Autoinvoice_Model_Observer {

public function afterSalesOrderSaveCommitAfter($observer) {
 $order = $observer->getEvent()->getOrder();
 $orderState = $order->getState();
 $items = $order->getAllItems();
 $qtys = array();
                foreach ($items as $item) {
                    $_sku = $item->getSku();
                    $_catalog = Mage::getModel('catalog/product');
                    $_productId = $_catalog->getIdBySku($_sku);
                    $_product = Mage::getModel('catalog/product')->load($_productId);
                    if ($_product->getAutoinvoice() == "1") {
                        $qty_to_invoice = $item->getQtyOrdered(); 
                    } else {
                        $qty_to_invoice = 0;
                    }
                    $qtys[$item->getId()] = $qty_to_invoice;
                }
 $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($qtys);
 $amount = $invoice->getGrandTotal();
                    $invoice->register()->pay();
                    $invoice->getOrder()->setIsInProcess(true);

                    $history = $invoice->getOrder()->addStatusHistoryComment(
                        'Partial amount of $' . $amount . ' captured automatically.', false
                    );

                    $history->setIsCustomerNotified(true);

                    $order->save();

                    Mage::getModel('core/resource_transaction')
                        ->addObject($invoice)
                        ->addObject($invoice->getOrder())
                        ->save();
                    $invoice->save();
                    $invoice->sendEmail(true, ''); //set this to false to not send the invoice via email
}

I haven't tested it, however have referenced bottom part (codes after getting $order) to your provided link, and this should work.

| improve this answer | |
  • i tried this code. The output is same. I figured it out that it stucks in a loop. May be in this code, i am calling the same event each time. – umair ayub Jun 13 '15 at 12:27
  • Looking to your code, I don't see any if statement to tell magento to do, aren't you trying to invoice only one item? – Adarsh Khatri Jun 13 '15 at 12:29
  • You can find if ($_product->getAutoinvoice() == "1") inside createInvoice function. – umair ayub Jun 14 '15 at 18:52
  • Where this getAutoinvoice() data coming from? is it custom column? – Adarsh Khatri Jun 14 '15 at 23:27
  • It is product attribute. – umair ayub Jun 15 '15 at 7:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.