Magento 1.9 – Create Custom Shipping Module with Multiple Carriers

magento-1.9moduleshipping

I would like to create a custom shipping module. As per my understanding a custom shipping module is created for single carrier. Am i correct ?

Is it possible manage multiple carriers using a single custom module? Or do i have to create different modules for each of the carriers? If i have to create different custom module for each of the carriers, then is it possible to write a function that executes before the code for each of the carriers are executed?

My aim is to do some validation and pick the carriers based on the validations result. For example i need to identify if carrier will ship a particular type of product. If they will carry that product, check whether they have pickup from seller location and delivery at the customers location. If its passes both this validation then include them in the results or otherwise remove it from the rest of the process.

Best Answer

If you want to add multiple shipping carriers, you need to setup the normal configuration: app/code/YourPackage/YourModule/etc/config.xml


<default>
    <carriers>
        <your_carrier_code>
            <active>0</active>
            <model>YourPackage_YourModule_Model_Carrier_YourCarrier</model>
            <title>Carrier Title</title>
            <name>Carrier Name</name>
            <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
        </your_carrier_code>
     </carriers>
</default

In your system.xml app/code/YourPackage/YourModule/etc/system.xml Please note the "source_model" tag. You need to define this class in your module as well.


<sections>
    <carriers>
        <groups>
            <your_carrier_code translate="label" module="yourmodule">
                ...
                <fields><!-- You need this field, so you can enable/disable different carriers -->
                    <allowed_methods translate="label">
                        <label>Allowed Methods</label>
                        <frontend_type>multiselect</frontend_type>
                        <source_model>yourmodule/shipping_source_method</source_model>
                        <sort_order>170</sort_order>
                        <show_in_default>1</show_in_default>
                        <show_in_website>1</show_in_website>
                        <show_in_store>0</show_in_store>
                        <can_be_empty>1</can_be_empty>
                    </allowed_methods>
                </fields>
            </your_carrier_code>
        </groups>
    </carriers>
</sections>>

Then, in your source model: YourPackage_YourModule_Model_Shipping_Source_Method (Note, this class no needs to extend any class, you just need the method: toOptionArray)


//You just need this method here:
public function toOptionArray()
{
    //You can fetch them from a database, or define them here.
    $shippingRates = array(
        0 => array(
            'code' => 'carrier_1_code',
            'title' => 'Carrier 1 Title'
        ),
        1 => array(
            'code' => 'carrier_2_code',
            'title' => 'Carrier 2 Title'
        ),
    );
    foreach ($shippingRates as $shippingRate) {
        $arr[] = array('value'=>$shippingRate['code'], 'label'=>$shippingRate['title']);
    }
    return $arr;
}

Then, in your carrier model: YourPackage_YourModule_Model_Carrier_YourCarrier


//Define the allowed methods
public function getAllowedMethods()
{
    //Fetch the methods from the config.
    $allowed = array(
        0 => array(
            'code' => 'carrier_1_code',
            'title' => 'Carrier 1 Title'
        ),
        1 => array(
            'code' => 'carrier_2_code',
            'title' => 'Carrier 2 Title'
        ),
    );
    $arr = array();
    foreach ($allowed as $rate) {
        $arr[$rate['code']] = $rate['title'];
    }
    return $arr;
}

//Then in your collectRates method:
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
    if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
        return false;
    }
    $result = Mage::getModel('shipping/rate_result');

    //Fetch the methods.
    $allowedMethods = $this->getAllowedMethods();
    foreach ($allowedMethods as $key => $title) {
        //Here check your method(carrier) if it is valid.
        //if is valid:

        $method = Mage::getModel('shipping/rate_result_method');
        $method->setCarrier('your_carrier_code');
        $method->setCarrierTitle($this->getConfigData('title'));
        $method->setMethod($key);
        $method->setMethodTitle($title);
        $method->setMethodDescription($title);

        //Calculate shipping price for rate:
        //$shippingPrice = $this->_calculateShippingPrice($key); //You need to implement this method.
        $method->setCost($shippingPrice);
        $method->setPrice($shippingPrice);

        //Finally add the method to the result.
        $result->append($method);
    }
}

This way, when you enable this carrier from the System Configuration, it will show all methods (carriers) that are enabled as radio buttons on checkout, but they will also be shown in the Promotions rules, so you can setup different promotions depending on the shipping carrier.

Related Topic