Sending shipment email when tracking info is added

From the topic of this blog post, it’s clear that we are going to discuss on ‘How to send shipment email when tracking info is added to the system?’
This may be useful if carrier tracking info is pushed to Magento by some third party system and want to send shipment email.

As usual, instead of rewriting core classes we will be using event-observer pattern.
And events used here will be:

  • sales_order_shipment_save_before
  • sales_order_shipment_save_after

1. Register the events: sales_order_shipment_save_before & sales_order_shipment_save_after
File: app/code/local/MagePsycho/Shipmentemail/etc/config.xml


...
<global>
    <events>
        <sales_order_shipment_save_before>
            <observers>
                <magepsycho_shipmentemail_sales_order_shipment_save_before>
                    <type>singleton</type>
                    <class>magepsycho_shipmentemail/observer</class>
                    <method>salesOrderShipmentSaveBefore</method>
                </magepsycho_shipmentemail_sales_order_shipment_save_before>
            </observers>
        </sales_order_shipment_save_before>
        <sales_order_shipment_save_after>
            <observers>
                <magepsycho_shipmentemail_sales_order_shipment_save_after>
                    <type>singleton</type>
                    <class>magepsycho_shipmentemail/observer</class>
                    <method>salesOrderShipmentSaveAfter</method>
                </magepsycho_shipmentemail_sales_order_shipment_save_after>
            </observers>
        </sales_order_shipment_save_after>
    </events>
</global>
...

2. Send email using observer model
File: app/code/local/MagePsycho/Shipmentemail/Model/Observer.php


<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Shipmentemail
 * @author     [email protected]
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class MagePsycho_Shipmentemail_Model_Observer
{
    protected function _isValidForShipmentEmail($shipment)
    {
        $trackingNumbers = array();
        foreach ($shipment->getAllTracks() as $track) {
            $trackingNumbers[] = $track->getNumber();
        };
        // send shipment email only when carrier tracking info is added
        if (count($trackingNumbers) > 0) {
            return true;
        } else {
            return false;
        }
    }
    
    public function salesOrderShipmentSaveBefore(Varien_Event_Observer $observer)
    {
        if (Mage::registry('salesOrderShipmentSaveBeforeTriggered')) {
            return $this;
        }

        /* @var $shipment Mage_Sales_Model_Order_Shipment */
        $shipment = $observer->getEvent()->getShipment();
        if ($shipment) {
            if ($this->_isValidForShipmentEmail($shipment)) {
                $shipment->setEmailSent(true);
                Mage::register('salesOrderShipmentSaveBeforeTriggered', true);
            }
        }
        return $this;
    }
    
    public function salesOrderShipmentSaveAfter(Varien_Event_Observer $observer)
    {
        if (Mage::registry('salesOrderShipmentSaveAfterTriggered')) {
            return $this;
        }
       
        /* @var $shipment Mage_Sales_Model_Order_Shipment */
        $shipment = $observer->getEvent()->getShipment();
        if ($shipment) {
            if ($this->_isValidForShipmentEmail($shipment)) {
                $shipment->sendEmail();
                Mage::register('salesOrderShipmentSaveAfterTriggered', true);
            }
        }
        return $this;
    }
}

Notes:

  • We have used both events: sales_order_shipment_save_before & sales_order_shipment_save_after. _before is used to set the email_sent flag to true and _after event to send email.
  • If you combine methods: $shipment->setEmailSent(true) and $shipment->sendEmail() in _before event, you will get shipment email but without shipment number.
  • If you combine methods: $shipment->setEmailSent(true) and $shipment->sendEmail() in _after event, it will go in recursive infinite loop sending you the millions of email.

Thanks for reading & sharing.

4 thoughts on “Sending shipment email when tracking info is added”

  1. Hello thanks for this post, so the only thing I need to do is to make the missing files;
    MagePsycho/Shipmentemail/Model/Observer.php
    MagePsycho/Shipmentemail/etc/config.xml
    And then I should work? Or do I need to set something in admin?

    Reply
  2. Getting:

    Mage registry key “_singleton/magepsycho_shipmentemail/observer” already exists

    when manually triggering shipment email. Which would mean it’s not automatically doing it on the normal event observer. What am I missing? Help is greatly appreciated!

    Reply
  3. Hi Raj, thanks for this post. It looks like this code need to be called by one of the existing functions within API.PHP is that correct?

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.