When can you deliver? (FedEx)

When can you deliver? (FedEx)

As a customer, there are two things prioritizing choices of shipping methods. First one, of course, is shipping price and other is delivery date. Since Magento is already showing us shipping prices on the checkout we don’t need to worry about that.

Magento offers us a lot of different shipping possibilities and each one has its own way of communicating and returning shipping details so there is not one single solution for all of them, but for now, we can show you how to do this for FedEx.

2016-04-14 11_18_53-Settings

Changing FedEx API

Biggest problem we encounter with getting delivery date is that shipping provider as FedEx is not returning that date back to us. To resolve this, we need to request this data from Fedex and to do so, we need to change our API request.

That is why we want to overwrite _formRateRequest method in Mage_Usa_Model_Shipping_Carrier_Fedex class and add “ReturnTransitAndCommit” in API call.

protected function _formRateRequest($purpose)
{
   $ratesRequest = parent::_formRateRequest($purpose);
   $ratesRequest['ReturnTransitAndCommit'] = true;
   return $ratesRequest;
}

Adding this attribute in call will request that Transit Time information is included in the reply from Fedex.

Fedex will return to us delivery timestamp for each method, but to make this more readable and accessible to shipping rate we will overwrite _prepareRateResponse method in same class and split it into date and time.

protected function _prepareRateResponse($response)
{
   $costArr = array();
   $priceArr = array();
   $errorTitle = 'Unable to retrieve tracking';
 
   if (is_object($response)) {
       if ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') {
           if (is_array($response->Notifications)) {
               $notification = array_pop($response->Notifications);
               $errorTitle = (string)$notification->Message;
           } else {
               $errorTitle = (string)$response->Notifications->Message;
           }
       } elseif (isset($response->RateReplyDetails)) {
           $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
 
           if (is_array($response->RateReplyDetails)) {
               foreach ($response->RateReplyDetails as $rate) {
                   $serviceName = (string)$rate->ServiceType;
                   if (in_array($serviceName, $allowedMethods)) {
                       $amount = $this->_getRateAmountOriginBased($rate);
                       $costArr[$serviceName]  = $amount;
                       $priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
                       $deliveryTimestamp[$serviceName] = $rate->DeliveryTimestamp;
                   }
               }
               asort($priceArr);
           } else {
               $rate = $response->RateReplyDetails;
               $serviceName = (string)$rate->ServiceType;
               if (in_array($serviceName, $allowedMethods)) {
                   $amount = $this->_getRateAmountOriginBased($rate);
                   $costArr[$serviceName]  = $amount;
                   $priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
               }
           }
       }
   }
 
   $result = Mage::getModel('shipping/rate_result');
   if (empty($priceArr)) {
       $error = Mage::getModel('shipping/rate_result_error');
       $error->setCarrier($this->_code);
       $error->setCarrierTitle($this->getConfigData('title'));
       $error->setErrorMessage($errorTitle);
       $error->setErrorMessage($this->getConfigData('specificerrmsg'));
       $result->append($error);
   } else {
       foreach ($priceArr as $method=>$price) {
           $rate = Mage::getModel('shipping/rate_result_method');
           $rate->setCarrier($this->_code);
           $rate->setCarrierTitle($this->getConfigData('title'));
           $rate->setMethod($method);
           $rate->setMethodTitle($this->getCode('method', $method));
           $rate->setDeliveryDate(date("l, F d",strtotime($deliveryTimestamp[$method])));
           $rate->setDeliveryTime(date("h:i A", strtotime($deliveryTimestamp[$method])));
           $rate->setCost($costArr[$method]);
           $rate->setPrice($price);
           $result->append($rate);
       }
   }
   return $result;
}

Now we made sure that Fedex is returning transit data.

Displaying delivery data

Before we can use this on a template we need to add it to shipping rate. To do this we will overwrite importShippingRate method in Mage_Sales_Model_Quote_Address_Rate class and append our new data to shipping.

public function importShippingRate(Mage_Shipping_Model_Rate_Result_Abstract $rate)
{
   $shippingRate = parent::importShippingRate($rate);
   if($rate->getDeliveryDate()){
       $shippingRate->setDeliveryDate($rate->getDeliveryDate());
       $shippingRate->setDeliveryTime($rate->getDeliveryTime());
   }
   return $shippingRate;
}

Now we can simply access this in checkout\onepage\shipping_method\available.phtml template as $_rate attribute and create our delivery message.

<label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
<?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
<?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
<?php echo $_excl; ?>
<?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
   (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
<?php endif; ?>
   <?php if($_rate->getDeliveryDate()): ?>
   <?php echo "Delivery on " . $_rate->getDeliveryDate(). " in " . $_rate->getDeliveryTime(); ?>
   <?php endif ?>
</label>

This was a simple modification on an existing call and it gave us one useful feature that makes it easier for a customer to decide what shipping method to use. But there are many cool things that Fedex Api offers that are not used in Magento. I invite you to play with it and give a little more flexibility to your shipping methods.

If you find this useful and would like this functionality on some other shipping method please comment below.

 

You made it all the way down here so you must have enjoyed this post! You may also like:

3 best open-source eCommerce platforms in 2021 Zrinka Antolovic
Zrinka Antolovic, | 7

3 best open-source eCommerce platforms in 2021

How to install Magento 2 Ivan Veres
Ivan Veres, | 23

How to install Magento 2

Prevent PO Boxes in shipping address field on Checkout Nikola Stojiljkovic
Nikola Stojiljkovic, | 8

Prevent PO Boxes in shipping address field on Checkout

8 comments

  1. Thank you for share this awesome bog.
    I want to customize the same thing for Magento 2. Can you please tell me how can I do the same thing for Magento 2.

  2. That’s a good idea to show your customers shipping information. I would think that would be a good way to let them know when to expect the package. I would think it would be nice to know so that you could make sure that you get it inside the house before package thieves do.

  3. I am having a bit of a hard time getting this to work.

    Can you possible post a download of the modified files? It would be greatly appreciated.

    Thank you

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>.

Tell us about your project

Drop us a line. We'd love to know more about your project.