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.
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?
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!
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?
Very well indeed. This is a great solution for developers. While for merchants who know little about programming, i would like to suggest Trackingmore shipment tracking extension. Check here: https://marketplace.magento.com/trackingmore-trackingmore-detrack.html#product.info.details.release_notes