Remind customers to place their first order in Magento

Inchoo OrderReminder

Sometimes customers need a little encouragement to place their first order after creating an account. There are many reasons this is the case, for example customers may forget to bookmark your site, thus they might have difficulties finding your store second time around. In this article I’ll present one way of keeping an eye on your customers orders count and sending first order reminder emails, trough free Magento extension named Inchoo_OrderReminder.

Introduction

Source code for Inchoo_OrderReminder is available from its GitHub repository page, as usual here I’ll just present it’s features and some code snippets. So here are the features of Inchoo_OrderReminder:

  • Can send reminder emails to customers who haven’t placed any orders yet, on configurable interval in days.
  • Maximum number of email reminders is also configurable, as well as action to take after sending last email reminder (move to different customer group or delete an account).
  • Regular and last order reminder email templates are configurable trough Magento’s transactional email templates feature.
  • Configurable reminder email sender identity as well as sending reminder emails to additional email addresses as copy or Bcc

Here’s the screenshot of configuration options available at System -> Configuration -> Sales Emails -> Order Reminders inside your Magento admin area:

Inchoo OrderReminder Options

Background

In this section I’ll present some code and basic logic behind Inchoo_OrderReminder. Inchoo_OrderReminder_Model_Observer::processOrderReminders() function is configured to be triggered by cron daily to process customers according to the configuration options. Here’s the config.xml code snippet for that purpose:

<config>
    <crontab>
        <jobs>
            <inchoo_orderreminder>
                <!-- Daily at 1 am -->
                <schedule><cron_expr>0 1 * * *</cron_expr></schedule>
                <run><model>inchoo_orderreminder/observer::processOrderReminders</model></run>
            </inchoo_orderreminder>
        </jobs>
    </crontab>
</config>

When triggered, this function will derive dates from Number of Reminders and Reminder Interval configuration options, taking Magento timezone configuration option into an account, and then grab all customers whose account has been created on that date, for every derived date. This function will then send emails to customers without any orders using proper transactional email template. It’ll also take actions of moving to another group or deleting customers who have been sent their last email reminder, if instructed to do so by system config options.

Here’s the code snippet of class Inchoo_OrderReminder_Model_Observer’s protected function for sending transactional emails:

/**
 * Send transactional emails.
 * 
 * @param Varien_Object $customer Customer object
 * @param int $reminderLimit Number of days for last reminder
 * @param int $reminderKey Number of days since customer account was created
 * @param string $template Email template
 */
protected function _sendOrderReminderEmail(Varien_Object $customer, $reminderLimit, $reminderKey, $template)
{
    $this->_log('Preparing email...');
 
    // Get necessary vars
    $copyTo = $this->_getStoreConfigCopyTo();
    $copyMethod = $this->_getStoreConfigCopyMethod();
    $storeId = Mage::app()->getStore()->getId();
 
    // Uses code from Mage_Sales_Model_Order::sendNewOrderEmail()
    $mailer = Mage::getModel('core/email_template_mailer');
    $emailInfo = Mage::getModel('core/email_info');
    $emailInfo->addTo($customer->getEmail(), $customer->getName());
    if ($copyTo && $copyMethod == 'bcc') {
        // Add bcc to customer email
        foreach ($copyTo as $email) {
            $emailInfo->addBcc($email);
 
            $this->_log(sprintf('Add %s to Bcc.', $email));
        }
    }
    $mailer->addEmailInfo($emailInfo);
 
    // Email copies are sent as separated emails if their copy method is 'copy'
    if ($copyTo && $copyMethod == 'copy') {
        foreach ($copyTo as $email) {
            $emailInfo = Mage::getModel('core/email_info');
            $emailInfo->addTo($email);
            $mailer->addEmailInfo($emailInfo);
 
            $this->_log(sprintf('Will send a copy to  %s.', $email));
        }
    }
 
    // Set all required params and send emails
    $mailer->setSender($this->_getStoreConfigIdentity(), $storeId);
    $mailer->setStoreId($storeId);
    $mailer->setTemplateId($template);
    $mailer->setTemplateParams(
        array(
            // Customer object
            'customer' => $customer,
 
            // Reminder for number of days
            'reminder_days' => $reminderKey,
 
            // Last reminder number of days
            'reminder_limit' => $reminderLimit
        )
    );
 
    // Send
    $mailer->send();
 
    $this->_log('Email sent.');
}

What to do next?

For more details about Inchoo_OrderReminder you can always checkout and download up-to-date code from Inchoo_OrderReminder’s GitHub repository page. Cheers and happy coding!


17 comments

  1. Hello. I have an entry in the log that the “Email sent.”. But they are not sent. I am the recipient and I did not get the emails. I use magento 1.4.1.0 and copied the Mailer and Info models into Mage\Core\Model\Email from last version.

  2. installed this extension. but don’t know how to run it. it does not work. please guide me how to run it. i have created an account. put reminder interval 1 but cannot get any email after one day. what else has to be done to run this extension?

  3. Thanks for the code but I had some trouble getting it working on 1.9. I also wanted to have a custom customer attribute so I could log the date the e-mail was sent & not just the last 3 days worth of new customers (for historical purposes).

    Here’s the modified function in your helper:

    public function processOrderReminders()
    {
    
    	$this->_log('Beginning...');
    
    	$customers = Mage::getResourceModel('customer/customer_collection')
    			->addNameToSelect()
    			->addAttributeToSelect('reminder_email')
    			->addAttributeToFilter(
    				'reminder_email',
    				array('null' => true),
    				'left'
    			)
    			->setPageSize(50);
    
    	foreach ($customers AS $customer) {
    
    		$this->_log($customer->getEmail());
    
    		$orders = Mage::getResourceModel('sales/order_collection')
    					->addFieldToFilter(
    						'customer_id',
    						array(
    							'eq' => $customer->getId()
    						)
    					);
    
    		$this->_log(
    			sprintf(
    				'Processing %s <%s> account.',
    				$customer->getName(),
    				$customer->getEmail()
    			)
    		);
    
    		$this->_log($customer->getData('reminder_email'));
    
    		// If there are orders
    		$success = false;
    		if ($orders->getSize() > 0) {
    			$customer->setData('reminder_email', date("Y-m-d 00:00:00"));
    			$customer->save();
    			$this->_log('Existing orders found, skip this account.');
    		} else {
    			// send email
    			$emailTemplate = Mage::getModel('core/email_template')
    						->loadDefault($this->_getStoreConfigLastTemplate());
    			$emailTemplateVariables = array();
    			$processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
    			$success = $emailTemplate->sendTransactional(1, array('name' => 'Your Name', 'email' => 'Your e-mail'), $customer->getData('email'), $customer->getName());
    
    			// set reminder e-mail flag
    			if ($success) {
    				$customer->setData('reminder_email', date("Y-m-d 00:00:00"));
    				$customer->save();
    				$this->_log('E-mail successfully sent');
    			} else {
    				$this->_log('Error sending e-mail');
    			}
    		}
    	}
    
    }
  4. Hi Marko,

    Ive installed this without edits, and went into the config panel to setup the sales emails. Unfortunately the changes in config is not being reflected in the xml, and not appearing in the cron. Any reason you could think of?

  5. Hi Marko,

    I have tried with my own triggers…and it appears to work:
    [in db]

    id | job | status | messages
    139 | inchoo_orderreminder | success | NULL

    but no email is sent, and messages has a NULL value.

    What could be some of the reasons for it to not send?

  6. Hi Jav,
    if by “enabled set to 0” you’re refering to config.xml, that’s just an entry telling Magento the default state for Enabled dropdown accessible at System -> Configuration -> Sales Emails -> Order Reminders in Magento admin. That’s where you should enable Order Reminder and emails should be sent out if Magento installation and server hosting it is properly configured.

    You should monitor Magento’s var/log/system.log because Order Reminder will write some lines starting with “Inchoo_OrderReminder” every time processOrderReminders is run by cron. If there are no lines there, then function isn’t being triggered and your cron isn’t properly configured. For more info about setting up cron you can take a look at related Magento Wiki entry:

    Alternatively you can also create Magento controller to trigger this function manually for testing if you can’t wait for cron to kick in.

    Regards,
    Marko

  7. Hi Marko,

    Finally got it into the cron_schedule…but it does not seem to want to send the email

    in the config it is set to this (as is):


    0

    is that correct?

  8. Hi Marko,

    Thanks for your reply have sorted the earlier question, I cant seem to get the processOrderReminders to appear in my cron schedule table (which would mean the cron isnt being executed am I right?)

  9. @Jav:

    Hello. Unfortunately there are multiple reasons why this error might occure. If it happens that you have more detailed error message containing line of code affected I might be able to assist.

    Cheers!

  10. Hi while using it I encountered varien_object not found; this is when Observer.php is ran.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.