Question

The basic problem is this: We've enabled the creation of invoices for free (zero subtotal) orders. This works fine, and the invoice is created, except the invoice email isn't sent.

I expected that I just needed to override the method wherever they get created, probably just to add an $invoice->sendEmail(), but I'm having trouble finding where exactly this would be.

Was it helpful?

Solution

Assuming you have setup the outbound email addresses properly in Menu > System > Configuration : Store Email Addresses :

Menu  loading= System > Configuration : Store Email Addresses Configuration">

Browse to the Sales : Sales Emails tab in the same interface as above and expand the Invoice accordion menu: Sales : Sales Emails tab Invoice Email Settings

You'll need to ensure :

  1. That Invoice Emails are Enabled
  2. That you have selected a From address based on the one you configured above. This example uses Sales Representative, but you can select any properly configured email address.
  3. That a template is selected for registered users (if you're testing registered users)
  4. That a template is selected for guest users (if you're testing guest users)

I took these screenshots on CE 1.9.1, but settings should be similar in EE. The version of Magento EE you're using doesn't utilize the new queue system, so as long as you've configured these settings properly, and you implement a custom observer similar to the code in this blog post, your invoice emails should be sent.

The key is to have your custom module attach an observer to the sales_order_invoice_save_after event - after the invoice is saved, you can query the contents of the invoice and fire off an email.

* IMPORTANT NOTES *

If your goal is to ensure that this functionality is applied to downloadable products in the Zero Subtotal Checkout Invoices like it might be for more regular products, as @xinqiu noted in the comments, you should probably attach your observer to the sales_order_invoice_save_commit_after event instead.

When sales_order_invoice_save_after is fired, the write operation containing the details of the purchased downloadable product link has not yet been saved to the database, even though other order/invoice and other line item information may have been.

Although this is an area in which I have zero direct experience, my understanding is that if there is some failure at the database level and the transaction is rolled back by MySQL, the url that was originally created for the unique downloadable product link would be regenerated by Magento when it retries the save/commit operation

Put more succinctly, one can't know that unique URL have been safely persisted in the database and committed successfully in a db transaction until the sales_order_invoice_save_commit_after event is fired (even if other high-level order details have been committed in MySQL already like totals, order / invoice number, etc...)

Although I haven't had a chance to try it our yet on my own, I can't seem to find a flaw in the logic of that strategy (though this may possibly be one of the areas in which I am much less experienced than I would prefer). I'm guessing you should be able to confirm that with after a little digging around and experimenting - when briefly experimenting on my own I must confess that I feel it might be more prudent to use sales_order_invoice_save_commit_after...

...no matter what kind of products you're dealing with on your Magento Store...Given its (later) sequence in the overall Magento Ordering / Invoicing Workflow, at a minimum you would at least know at this point that all relevant order and line item details had been stored and either generated an exception of some sort and been appropriately rolled back and retried / or its behaving as normally expected.

Assuming you want to include the link to your downloadable product in the template you're using to generate your Invoice email, you should modify the code I include below to attach to sales_order_invoice_save_commit_after which will ensure that all relevant info about the order and any downloadable products are saved in the database and committed in a transaction (if possible).

I can't see why using sales_order_invoice_save_commit_after might introduce any other problems, though please note the caveat that I have never done so myself and the code I provide below I have used several successfully a few times so I might be wrong & "Your Mileage May Vary."

* IMPORTANT NOTES *

The module code in that example is pretty simple. By default, the send Invoice email function is only triggered for $0.00 Invoice when you click the button in the Admin interface to manually send an email of the Invoice to the Customer (It's automatically sent if the total < 0).

The above code fires the same logic as the button, but is triggered when the event triggers the observer. The solution is 3 basic components :

Module config.xml :

<config>
  <modules>
    <Havsund_Autoorder>
      <version>1.0.0</version>
    </Havsund_Autoorder>
  </modules>
  <global>
  <events>
    <sales_order_invoice_save_after>
      <observers>
        <havsund_autoorder_observer>
          <type>singleton</type>
          <class>Havsund_Autoorder_Model_Observer</class>
          <method>automaticallyInvoiceShipCompleteOrder</method>
        </havsund_autoorder_observer>
       </observers>
     </sales_order_invoice_save_after>
    </events>
  </global>
</config>

Observer Code :

class Havsund_Autoorder_Model_Observer
{

/* @var Magento_Sales_Model_Order_Invoice */
var $_invoice;

/**
* Mage::dispatchEvent($this->_eventPrefix.'_save_after', $this->_getEventData());
* protected $_eventPrefix = 'sales_order';
* protected $_eventObject = 'order';
* event: sales_order_save_after
*/
public function automaticallyInvoiceShipCompleteOrder($observer)
{
   try {
      /* @var $order Magento_Sales_Model_Order_Invoice */
      $this->_invoice = $observer->getEvent()->getInvoice();
      $this->_invoice->sendEmail();

   } catch (Mage_Core_Exception $e) {
       Mage::log("HAVSUND AUTOORDER: Fehler #58 " . $e->getMessage());
   }

   return $this;
}

}

Module Activation Config :

<?xml version="1.0"?>
  <config>
    <modules>
      <Havsund_Autoorder>
        <active>true</active>
        <version>1.0.0</version>
        <codePool>local</codePool>
        <depends>
        </depends>
      </Havsund_Autoorder>
    </modules>
   </config>

NOTE: If you have compilation enabled, you'll have to disable / recompile after you deploy your customization for it to be executed, or you might get an error like:

Warning: get_class() expects parameter 1 to be object, boolean given in /app/code/core/Mage/Core/Model/App.php on line 1340

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top