Issue adding new shipping carriers for package tracking
-
08-10-2020 - |
Question
fairly new Magento dev here.. I'm adding two new carriers to our Magento EE instance, Apex and OnTrac. The carrier records are attached to the shipment by a separate process handled by our ERP system and then imported into Magento, so we don't need to worry about anything being customer facing. All I need is to enable tracking info for these carriers.
Under the below configuration, APEX and OnTrac now display in system>configuration, but only APEX shows in the Shipping and Tracking Information box in Sales>Shipments, and if shipments are imported into Magento from our ERP, that control is empty.
Here's my code, what am I missing?
app/etc/modules/Foo_Shipping.xml
<?xml version="1.0"?>
<config>
<modules>
<Foo_Shipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Shipping />
</depends>
</Foo_Shipping>
</modules>
</config>
app/code/local/Foo/Shipping/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Foo_Shipping>
<version>1.0</version>
</Foo_Shipping>
</modules>
<global>
<models>
<foo_shipping>
<class>Foo_Shipping_Model</class>
</foo_shipping>
</models>
<sales>
<shipping>
<carriers>
<ontrac>
<class>Foo_Shipping_Model_Carrier_OnTrac</class>
</ontrac>
<apex>
<class>Foo_Shipping_Model_Carrier_Apex</class>
</apex>
</carriers>
</shipping>
</sales>
</global>
<default>
<carriers>
<ontrac>
...
</ontrac>
<apex>
...
</apex>
</carriers>
</default>
</config>
app/code/local/Foo/Shipping/etc/system.xml
<?xml version="1.0"?>
<config>
<sections>
<carriers>
<groups>
<ontrac translate="label" module="shipping">
<label>OnTrac</label>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
...
</fields>
</ontrac>
<apex translate="label" module="shipping">
<label>APEX</label>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
...
</fields>
</apex>
</groups>
</carriers>
</sections>
</config>
app/code/local/Foo/Shipping/Model/Carrier/OnTrac.php
class Foo_Shipping_Model_Carrier_Ontrac
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'ontrac';
protected $_isFixed = true;
public function isTrackingAvailable()
{
return true;
}
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
return Mage::getModel('shipping/rate_result');
}
public function getAllowedMethods()
{
return array(); //shell, we won't use this logic for this carrier
}
}
app/code/local/Foo/Shipping/Model/Carrier/Apex.php
class Foo_Shipping_Model_Carrier_Apex
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'apex';
protected $_isFixed = true;
public function isTrackingAvailable()
{
return true;
}
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
return Mage::getModel('shipping/rate_result');
}
public function getAllowedMethods()
{
return array(); //shell, we won't use this logic for this carrier
}
}
Solution
In your collectRates()
method you are returning rate result object but without adding any actual rates. You need to add at least 1 to show it on front end:
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
$result = Mage::getModel('shipping/rate_result');
/** @var Mage_Shipping_Model_Rate_Result_Method $rate */
$rate = Mage::getModel('shipping/rate_result_method');
$rate->setCarrier($this->_code);
$rate->setCarrierTitle($this->getConfigData('title'));
$rate->setMethod('apex_main');
$rate->setMethodTitle($this->getConfigData('method_title'));
$rate->setPrice($this->getMethodPrice(0));
$rate->setCost(0);
$result->append($rate);
return $result;
}
/**
* Calculate price considering free shipping and handling fee
*
* @param string $cost
* @param string $method
* @return float|string
*/
public function getMethodPrice($cost)
{
return $method == $this->getConfigData($this->_freeMethod)
&& $this->getConfigFlag('free_shipping_enable')
&& $this->getConfigData('free_shipping_subtotal') <= $this->_rawRequest->getBaseSubtotalInclTax()
? '0.00'
: $this->getFinalPriceWithHandlingFee($cost);
}
You can simplify or extend logic of settings price and names according to your needs.
OTHER TIPS
I had to do the same ... add new carriers for internal use only (not visible on frontend)
For your carriers model this should be enough:
protected $_code = 'ontrac';
public function isTrackingAvailable()
{
return true;
}
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
return null;
}
public function getAllowedMethods()
{
return array();
}
/**
* @param string $tracking
* @return false|Mage_Core_Model_Abstract
*/
public function getTrackingInfo($tracking)
{
$trackData = array(
'carrier' => $this->getCarrierCode(),
'carrier_title' => $this->getConfigData('title'),
'tracking' => $tracking,
'url' => 'http://nolp.dhl.de/nextt-online-public/set_identcodes.do?lang=de&idc=' . $tracking // german DHL tracking URL
);
return Mage::getModel('shipping/tracking_result_status', $trackData);
}
In config.xml I just set carrier title and model (i've no need for backend settings):
<default>
<carriers>
<ontrac>
<title>Your title</title>
<model>foo_shipping/carrier_ontrac</model>
</ontrac>
...
</carriers>
</default>