4

I have created a custom shipping module with a custom carrier, however, the custom carrier is not showing up when grabbing the carriers... To Grab the carriers I am using the following snippet

$validCarriers = Mage::getModel('sales/order_shipment_api')->getCarriers($order->getIncrementId());

I define my custom carrier with the following xml

<default>
    <carriers>
        <vmr_customrate>
            <active>1</active>
            <model>vmr_shipping/carrier_customrate</model>
            <title>Shipping Options</title>
            <name>Default Rate</name>
        </vmr_customrate>
    </carriers>
</default>

Any ideas on what I might be doing wrong?

  • Please include your shipping method class definition. – benmarks Feb 18 '13 at 19:01
7

Your carrier shipping object (Mage::getModel('vmr_shipping/carrier_customrate ');) either returns false for the isTrackingAvailable method, or can't be instantiated. The rest of this post will trace your method call above and give you multiple debug points. This should give you enough to solve the problem.

If we look at the definition for getCarriers

#File: app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
public function getCarriers($orderIncrementId)
{
    $order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

    /**
      * Check order existing
      */
    if (!$order->getId()) {
        $this->_fault('order_not_exists');
    }

    return $this->_getCarriers($order);
}

and follow that to _getCarriers

#File: app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
protected function _getCarriers($object)
{
    $carriers = array();
    $carrierInstances = Mage::getSingleton('shipping/config')->getAllCarriers(
        $object->getStoreId()
    );

    $carriers['custom'] = Mage::helper('sales')->__('Custom Value');
    foreach ($carrierInstances as $code => $carrier) {
        if ($carrier->isTrackingAvailable()) {
            $carriers[$code] = $carrier->getConfigData('title');
        }
    }

    return $carriers;
}

You can see the API method calls Mage::getSingleton('shipping/config')->getAllCarriers($store_id); to get a list of carrier objects, and then only returns the ones where isTrackingAvailable returns true. So step 1 should be to make sure your object returns true for this method.

Of course, it might be that getAllCarriers never returns your method, and never has a chance to call it. Let's take a look at that method.

#File: app/code/core/Mage/Shipping/Model/Config.php
public function getAllCarriers($store = null)
{
    $carriers = array();
    $config = Mage::getStoreConfig('carriers', $store);
    foreach ($config as $code => $carrierConfig) {
        $model = $this->_getCarrier($code, $carrierConfig, $store);
        if ($model) {
            $carriers[$code] = $model;
        }
    }
    return $carriers;
}

So this goes through all the top level carriers configuration nodes. It looks like yours is setup correctly, but adding a

var_dump($code);
Mage::log($code);

to the above loop and looking for vmr_customrate couldn't hurt. If you jump to this class's _getCarrier method.

#File: app/code/core/Mage/Shipping/Model/Config.php
protected function _getCarrier($code, $config, $store = null)
{
    if (!isset($config['model'])) {
        return false;
    }
    $modelName = $config['model'];

    /**
     * Added protection from not existing models usage.
     * Related with module uninstall process
     */
    try {
        $carrier = Mage::getModel($modelName);
    } catch (Exception $e) {
        Mage::logException($e);
        return false;
    }
    $carrier->setId($code)->setStore($store);
    self::$_carriers[$code] = $carrier;
    return self::$_carriers[$code];
}

You'll see the carrier is instantiated by taking the value from the <model/> node and using it in a call to getModel

$carrier = Mage::getModel('vmr_shipping/carrier_customrate');

It may be Magento can't instantiate your model for some reason. Check the exception log, or try instantiating the model yourself in a stand alone script/controller action.

| improve this answer | |
  • adding isTrackingAvailable worked like a charm! Thank you! You did a great job of explaining how to solve future problems like this one, thank you! – Jeffrey L. Roberts Feb 19 '13 at 4:49
1

Just in case anybody get a carriers drop-down with a blank field...

Besides of adding

public function isTrackingAvailable()
    {
        return true;
    }

to your model, make sure you also declare a protected $_code = '{carrier_code}';

The value in there must be equal to what you have declared in your module config.xml under

<default>
   <carriers>
       <{carrier_code}>
           ...
          <title>{carrier_title}</title>
           ...
       </{carrier_code}>
   </carriers>
</default>
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.