5

I am looking for a way to programmatically send an email to the user when a tracking number is assigned to an order. I need to be able to do this programmatically because I am using an outside source to populate the tracking information.

I guess what I am really looking for here is a specific trigger or event that I could use to fire off the email that would normally be sent when the admin clicks the "Send Tracking Information" button. I have skimmed through the core code and have not been able to put my finger on what action is actually being triggered when that button is pushed.

We are using a third party (eBridge) to connect with our sales tools. Once an order has been marked as shipped and a tracking number is input into the eBridge tool, it will talk to magento and input the tracking number into the order. The problem is that it doesn't tell magento to fire off an email to provide the customer with this newly inputted tracking number. What I am trying to do is, once the information is put into magento fire off an email from magentos side. Is this possible? What we want, in a nutshell, is to be able to have magento send off an email with the tracking information without having to manually go into each order and click the "Send Tracking Information" button.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Jen
  • 111
  • 1
  • 2
  • 9

3 Answers3

12

When you add a new shipment to an order via the control panel you can tick a box to send the e-mail. If you need to send this programmatically, the controller for the admin area simply calls the sendEmail method on the Mage_Sales_Model_Order_Shipment.

UPDATE: If the tracking number is being adding to the shipment via the 'standard' method, which is to say the addTrack method of the shipment api, then you would be able to hook into the sales_order_shipment_track_save_after event. Adding an observer that does something along the lines of...

public function sendTrackEmail($observer)
{
    $track = $observer->getEvent()->getTrack();
    $shipment = $track->getShipment(true);
    $shipment->sendEmail();
}
Peter O'Callaghan
  • 6,181
  • 3
  • 26
  • 27
  • Is there a specific listener/observer for when the tracking code is added to a shipment? – Jen Jan 09 '12 at 19:30
  • That would very much depend how the tracking code is being added. – Peter O'Callaghan Jan 09 '12 at 19:36
  • Does it help to say that the tracking code is being to the actual tracking code field in the shipping information as apposed to just being added as a comment? – Jen Jan 09 '12 at 19:47
  • So what class would I be extending in order to do this? Mage_Sales_Model_Order_Shipment_? – Jen Jan 09 '12 at 20:07
  • You don't need to extend any class, you simply need to create an observer for the event. You just need to add that method to a new model, and add the method as an event observer http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-1-introduction-to-magento#8 – Peter O'Callaghan Jan 09 '12 at 20:12
  • So my config for this "module" would basically look like this, correct: ` 0.1.1 singleton WR_Tracking_Email/observer sendTrackEmail ` – Jen Jan 09 '12 at 20:21
  • Hey @Cags i have a similar problem, the tracking info is uploaded thru the API, and it's sending the email without the tracking number, so i thought i can delay a bit the sending of the email till it sent the tracking number within it, how can i do that ? thanks a lot! – Abude May 21 '13 at 18:42
  • do you think you can answer this question ... http://magento.stackexchange.com/questions/148609/how-can-i-replicate-send-tracking-information-behaviour-in-magento-using-php – Umair Ayub Dec 02 '16 at 14:36
  • Hi @PeterO'Callaghan, Is the sendEmail() method available in magentoo 2.3.4 – Ramya Jun 24 '20 at 06:43
7

FYI there is an undocumented API call that does exactly this, sendInfo(). I don't know as of what version this was added in, as far as I can tell it's over a year old, I just had to solve this same problem myself and this is one of the first results on Google.

Note: If you're implementing this, you likely do not want to send the email flag to the sales_order_shipment.create() API call, as this will result in two emails going out for the same order, one without a tracking number, then one with it.

addTrack() is likely implemented already, you just need to follow it immediately with sendInfo().

sales_order_shipment.addTrack(sessionId, shipmentIncrementId, carrier, title, trackNumber)
sales_order_shipment.sendInfo(sessionId, comment)

The email sent out is the same that you would get by clicking the "Send Tracking Information" button in the Magento backend manually. Reference the Magento API for more explanation on addTrack and using the SOAP API in general.

As for sendInfo() specifically, take a look at the source code from magento/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php for help:

/**
 * Send email with shipment data to customer
 *
 * @param string $shipmentIncrementId
 * @param string $comment
 * @return bool
 */
public function sendInfo($shipmentIncrementId, $comment = '')
{
    /* @var $shipment Mage_Sales_Model_Order_Shipment */
    $shipment = Mage::getModel('sales/order_shipment')->loadByIncrementId($shipmentIncrementId);

    if (!$shipment->getId()) {
        $this->_fault('not_exists');
    }

    try {
        $shipment->sendEmail(true, $comment)
            ->setEmailSent(true)
            ->save();
        $historyItem = Mage::getResourceModel('sales/order_status_history_collection')
            ->getUnnotifiedForInstance($shipment, Mage_Sales_Model_Order_Shipment::HISTORY_ENTITY_NAME);
        if ($historyItem) {
            $historyItem->setIsCustomerNotified(1);
            $historyItem->save();
        }
    } catch (Mage_Core_Exception $e) {
        $this->_fault('data_invalid', $e->getMessage());
    }

    return true;
}
bsphil
  • 161
  • 2
  • 5
0

If you want an email containing the tracking informationto get sent when some program e.g. eBridge calls the salesOrderShipmentAddTrack V2 API, you can also extend Mage_Sales_Model_Order_Shipment_Api

e.g.

class PKS_Sales_Model_Order_Shipment_Api extends Mage_Sales_Model_Order_Shipment_Api
public function addTrack

by adding the call to send the email in the try block e.g.

try {
        $shipment->save();
        $track->save();
        $shipment->sendEmail(true, '')
            ->setEmailSent(true)
            ->save();  /* added email with null comment */
 }

You also have to provide an extension to the SOAP V2 e.g.

class PKS_Sales_Model_Order_Shipment_Api_V2 extends PKS_Sales_Model_Order_Shipment_Api

even if it has no methods :)

(example has my app/code/local/PKS/Sales module, substitute your company name for PKS, apologies re formatting)

app/code/local/PKS/Sales/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>   
<config>
<modules>
<PKS_Sales>
    <version>4.0.0.0</version>
    <depends>
        <Mage_Sales />
    </depends>
</PKS_Sales>
</modules>
<global>
<models>
<sales>
    <rewrite>
             <order_shipment_api>PKS_Sales_Model_Order_Shipment_Api</order_shipment_api>       
     <order_shipment_api_v2>PKS_Sales_Model_Order_Shipment_Api_V2</order_shipment_api_v2>
          </rewrite>
</sales>
</models>
</global>
</config>

It took more time figuring out how to write the required PKS/Sales/etc/api.xml (example has my app/code/local/PKS module, substitute your company name for PKS)

<config>
<api>
    <resources>
        <sales_order_shipment translate="title" module="PKS_Sales">
            <title>Modified Shipment API</title>
            <model>sales/order_shipment_api</model>
            <acl>sales/order/shipment</acl>
            <methods>
                <addTrack translate="title" module="PKS_Sales">
                    <title>Add new tracking number</title>
                    <acl>sales/order/shipment/track</acl>
                </addTrack>
            </methods>
            <faults module="PKS_Sales">
                <not_exists>
                    <code>100</code>
                    <message>Requested shipment does not exist.</message>
                </not_exists>
                <filters_invalid>
                    <code>101</code>
                    <message>Invalid filters given. Details in error message.</message>
                </filters_invalid>
                <data_invalid>
                    <code>102</code>
                    <message>Invalid data given. Details in error message.</message>
                </data_invalid>
                <order_not_exists>
                    <code>103</code>
                    <message>Requested order does not exist.</message>
                </order_not_exists>
                <track_not_exists>
                    <code>104</code>
                    <message>Requested tracking does not exist.</message>
                </track_not_exists>
                <track_not_deleted>
                    <code>105</code>
                    <message>Tracking not deleted. Details in error message.</message>
                </track_not_deleted>
            </faults>
        </sales_order_shipment>
    </resources>
    <resources_alias>
        <order>sales_order</order>
  <order_shipment>sales_order_shipment</order_shipment>
    </resources_alias>
    <v2>
        <resources_function_prefix>
            <order>salesOrder</order>
      <order_shipment>salesOrderShipment</order_shipment>
        </resources_function_prefix>
    </v2>
    </acl>
</api>
</config>

Please note that with this approach, and having System > Configuration > Sales > Sales Emails > Order and Shipment emails enabled, your customer will get - one email confirming a new order - a second email for the shipment with no tracking number - a third email for the shipment with the tracking number, from your API extension.

I've tried commenting out the Api.php create function's

$shipment->sendEmail($email, ($includeComment ? $comment : ''));

but that second email just keeps getting sent.

Nancy
  • 11