PHP Magento Tips

Create Custom shipping Method Based on Product Attribute in Magento

Rate this posting:
{[['']]}

In this article, I will demonstrate how to Create custom shipping Method in Magento, or to be more precise, two of them: standard shipping and express shipping, which is only available if your shopping cart grand total exceeds specified price threshold. Lets start by explaining how Magento handles shipping, and what would be needed to achieve our goal.

here we will create our custom shipping Method in which first we will create custom shipping price product attribute with install script. After that we will check grand total of your shopping cart. if it is exceeds to some specified price threshold then it will be considered as a express shipping with zero cost, otherwise it will check product's custom shipping attribute and if it is blank then it will take default shipping price.

let's start to create our basic module structure.

Step 1: Create file in app/etc/modules/Mycompany_Customshipping.xml and add below code:

<?xml version="1.0"?>
<config>
    <modules>
        <Mycompany_Customshipping>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Shipping />
            </depends>
        </Mycompany_Customshipping>
    </modules>
</config>

Step 2: Create Config and system.xml file.

a:) Create file in app/code/local/Mycompany/Customshipping/etc/config.xml and add below code:

<?xml version="1.0"?>
<config>
    <modules>
        <Mycompany_Customshipping>
            <version>1.0.0</version>
        </Mycompany_Customshipping>
    </modules>
    <global>
     <resources>
            <mycompany_customshipping_setup>
                <setup>
                    <module>Mycompany_Customshipping</module>
                    <class>Mycompany_Customshipping_Model_Resource_Setup</class>
                </setup>
                <connection>
                      <use>core_setup</use>
                </connection>
            </mycompany_customshipping_setup>
            <mycompany_customshipping_write>
                <connection>
                  <use>core_write</use>
                </connection>
             </mycompany_customshipping_write>
        </resources>
        <models>
            <mycompany_customshipping>
                <class>Mycompany_Customshipping_Model</class>
                <resourceModel>mycompany_customshipping_resource</resourceModel>
            </mycompany_customshipping>
            <mycompany_customshipping_resource>
                <class>Mycompany_Customshipping_Model_Resource</class>
                <entities>
                    <mytest>
                        <table>Mycompany_Customshipping_entity</table>
                    </mytest>
                </entities>
            </mycompany_customshipping_resource>
        </models>
        <helpers>
            <mycompany_customshipping>
                <class>Mycompany_Customshipping_Helper</class>
            </mycompany_customshipping>
        </helpers>
    </global>
    <default>
        <carriers>
            <mycompany_customshipping>
                <active>1</active>
                <sort_order>10</sort_order>
                <model>mycompany_customshipping/carrier</model>
                <title>Custom Shipping Carrier</title>
                <sort_order>10</sort_order>
                <sallowspecific>1</sallowspecific>
                <express_max_price>200</express_max_price>
                <default_shipping_price>1</default_shipping_price>
            </mycompany_customshipping>
        </carriers>
    </default>
    <adminhtml>
    <fieldsets>
      <mycompany_customshipping_attribute>
        <create>1</create>
        <update>1</update>
      </mycompany_customshipping_attribute>
    </fieldsets>
  </adminhtml>
</config>

b:) Create file in app/code/local/Mycompany/Customshipping/etc/system.xml and add below code in it.

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <sections>
        <carriers>
            <groups>
                <mycompany_customshipping translate="label">
                    <label>Custom Shipping Carrier</label>
                    <sort_order>2</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>0</show_in_website>
                    <show_in_store>0</show_in_store>
                    <fields>
                        <active translate="label">
                            <label>Enabled</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>1</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </active>
                        <title translate="label">
                            <label>Carrier title</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>20</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </title>
                        <sallowspecific translate="label">
                            <label>Available for specific countries only</label>
                            <frontend_type>select</frontend_type>
                            <frontend_class>shipping-applicable-country</frontend_class>
                            <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </sallowspecific>
                        <specificcountry translate="label">
                            <label>Ship to Specific Countries</label>
                            <frontend_type>multiselect</frontend_type>
                            <sort_order>31</sort_order>
                            <source_model>adminhtml/system_config_source_country</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                            <can_be_empty>1</can_be_empty>
                        </specificcountry>
                        <default_shipping_price translate="label">
                            <label>Default Shipping Price</label>
                            <comment>Default Shipping Price of Product.(If Custom Shipping price is not added.)</comment>
                            <frontend_type>text</frontend_type>
                            <sort_order>40</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </default_shipping_price>
                        <express_max_price translate="label">
                            <label>Max Total Price</label>
                            <comment>Maximum total price of cart for express rate</comment>
                            <frontend_type>text</frontend_type>
                            <sort_order>50</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </express_max_price>
                    </fields>
                </mycompany_customshipping>
            </groups>
        </carriers>
    </sections>
</config>

Step 3: Create sql install script to add new product attribute. Create file in app/code/local/Mycompany/Customshipping/sql/mycompany_customshipping_setup/install-1.0.0.php and add below code in it.

<?php
$installer = Mage::getResourceModel ( 'catalog/setup', 'catalog/setup' );
$installer->startSetup();
$installer->addAttributeGroup('catalog_product', 'Default', 'Prices', 20000);
// addAttribute uses _prepareValues()
$data = array (
  'label' => 'Custom Shipping Price',
  'type' => 'decimal', // multiselect uses comma sep storage
  'input' => 'price',
  'backend' => 'eav/entity_attribute_backend_array',
  'frontend' => '',
  'required' => 0,
  'user_defined' => 1,
  'group' => 'Prices',
  'unique' => 0, // eav_attribute.is_unique unique value required
  'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL, // catalog_eav_attribute.is_global (products only) scope
  'visible' => 1, // catalog_eav_attribute.is_visible (products only) visible on admin, setting to false stops import of this attribute
  'visible_on_front' => 1, // catalog_eav_attribute.is_visible_on_front (products only) visible on frontend (store) attribute table
  'used_in_product_listing' => 0, // catalog_eav_attribute.used_in_product_listing (products only) made available in product listing
  'searchable' => 0, // catalog_eav_attribute.is_searchable (products only) searchable via basic search
  'visible_in_advanced_search' => 0, // catalog_eav_attribute.is_visible_in_advanced_search (products only) searchable via advanced search
  'filterable' => 0, // catalog_eav_attribute.is_filterable (products only) use in layered nav
  'filterable_in_search' => 0, // catalog_eav_attribute.is_filterable_in_search (products only) use in search results layered nav
  'comparable' => 0, // catalog_eav_attribute.is_comparable (products only) comparable on frontend
  'is_html_allowed_on_front' => 0, // catalog_eav_attribute.is_visible_on_front (products only) seems obvious, but also see visible
  'apply_to' => 'simple,bundle,grouped,configurable', // catalog_eav_attribute.apply_to (products only) which product types to apply to
  'is_configurable' => 0, // catalog_eav_attribute.is_configurable (products only) used for configurable products or not
  'used_for_sort_by' => 0, // catalog_eav_attribute.used_for_sort_by (products only) available in the 'sort by' menu
  'position' => 0, // catalog_eav_attribute.position (products only) position in layered naviagtion
  'used_for_promo_rules' => 0
);
$installer->addAttribute ( 'catalog_product', 'custom_shipping_price', $data );
// Done:
$installer->endSetup ();

Step 4: Create Model files for New attribute.

a:) Create file in app/code/local/Mycompany/Customshipping/Model/Mytest.php and add below code in it.

<?php
// app/code/local/Mycompany/Customshipping/Model/Mytest.php
class Mycompany_Customshipping_Model_Mytest extends Mage_Core_Model_Abstract
{
    public function _construct()
    {
        parent::_construct();
        $this->_init('mycompany_customshipping/mytest');
    }   
} 


b:) Create file in app/code/local/Mycompany/Customshipping/Model/Resource/Mytest.php and add below code in it.



<?php
// app/code/local/Mycompany/Customshipping/Model/Resource/Mytest.php
class Mycompany_Customshipping_Model_Resource_Mytest extends Mage_Core_Model_Resource_Db_Abstract
{
    protected function _construct()
    {
        $this->_init('mycompany_customshipping/mytest', 'entity_id');
    }
}


C:) create file in app/code/local/Mycompany/Customshipping/Model/Resource/Setup.php and add below code in it.



<?php
// app/code/local/Mycompany/Customshipping/Model/Resource/Setup.php
class Mycompany_Customshipping_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
{
}


d:) Create file in app/code/local/Mycompany/Customshipping/Model/Resource/Mytest/Collection.php and add below code in it.


<?php
 
// app/code/local/Mycompany/Customshipping/Model/Resource/Mytest/Collection.php
class Mycompany_Customshipping_Model_Resource_Mytest_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
    protected $_joinedFields = array();
     
    protected function _construct()
    {
        parent::_construct();
        $this->_init('mycompany_customshipping/mytest');
    }
    protected function _toOptionArray($valueField='mytest', $labelField='name', $additional=array())
    {
        return parent::_toOptionArray($valueField, $labelField, $additional);
    }
    protected function _toOptionHash($valueField='mytest', $labelField='name')
    {
        return parent::_toOptionHash($valueField, $labelField);
    }
    public function getSelectCountSql()
    {
        $countSelect = parent::getSelectCountSql();
        $countSelect->reset(Zend_Db_Select::GROUP);
        return $countSelect;
    }
}

Step 5: Create Helper file. Create file in app/code/local/Mycompany/Customshipping/Helper/Data.php and add below code in it.


<?php

class Mycompany_Customshipping_Helper_Data extends Mage_Core_Helper_Abstract
{
    
}

Step 6: Create Shipping Carrier file. Create file in app/code/local/Mycompany/Customshipping/Model/Carrier.php and add below code in it:


<?php

class Mycompany_Customshipping_Model_Carrier extends Mage_Shipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface
{
    /**
     * Carrier's code, as defined in parent class
     *
     * @var string
     */
    protected $_code = 'mycompany_customshipping';

    /**
     * Returns available shipping rates for Mycompany Customshipping carrier
     *
     * @param Mage_Shipping_Model_Rate_Request $request
     * @return Mage_Shipping_Model_Rate_Result
     */
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        /** @var Mage_Shipping_Model_Rate_Result $result */
        $result = Mage::getModel('shipping/rate_result');

        /** @var Mycompany_Customshipping_Helper_Data $expressMaxPrice */        
        $expressMaxPrice = Mage::getStoreConfig('carriers/mycompany_customshipping/express_max_price',Mage::app()->getStore());
        $defaultShippingPrice = Mage::getStoreConfig('carriers/mycompany_customshipping/default_shipping_price',Mage::app()->getStore());
        
        $expressAvailable = false;
        $standardAvailable = false;       
        
        $quote = Mage::getModel('checkout/session')->getQuote();
        $quoteData= $quote->getData();
        $grandTotal= floatval ($quoteData['grand_total']);
        
        foreach ($request->getAllItems() as $item) {
         if ($item->getProduct ()->isVirtual () || $item->getParentItem ()) {
          continue;
         }
         
         if ($item->getHasChildren () && $item->isShipSeparately ()) {
          foreach ( $item->getChildren () as $child ) {
           if ($child->getFreeShipping () && ! $child->getProduct ()->isVirtual ()) {
            $product_id = $child->getProductId ();
            $productObj = Mage::getModel ( 'catalog/product' )->load ( $product_id );
            $ship_price = $productObj->getData ( 'custom_shipping_price' ); // our shipping attribute code
            if ($ship_price == NULL) {
             $price += ( float ) $defaultShippingPrice;
            } else {
             $price += ( float ) $ship_price;
            }
         
           }
          }
         } else {
          $product_id = $item->getProductId ();
          $productObj = Mage::getModel ( 'catalog/product' )->load ( $product_id );
          $ship_price = $productObj->getData ( 'custom_shipping_price' ); // our shipping attribute code
          if ($ship_price == NULL) {
           $price += ( float ) $defaultShippingPrice;
          } else {
           $price += ( float ) $ship_price;
          }
         
         }
        }        
        //Mage::log($expressMaxPrice, null, 'totalprice.log', true);
        if ($grandTotal > intval($expressMaxPrice)) {
         $expressAvailable = true;
        } else {
         $standardAvailable = true;
        }
        
        if ($expressAvailable) {
            $result->append($this->_getExpressRate());
        } else {
         $result->append($this->_getStandardRate($price));
        }
        return $result;
    }

    /**
     * Returns Allowed shipping methods
     *
     * @return array
     */
    public function getAllowedMethods()
    {
        return array(
            'standard'    =>  'Standard delivery',
            'express'     =>  'Express delivery',
        );
    }

    /**
     * Get Standard rate object
     *
     * @return Mage_Shipping_Model_Rate_Result_Method
     */
    protected function _getStandardRate($price)
    {
        /** @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('standard');
        $rate->setMethodTitle('Standard delivery');
        $rate->setPrice($price);
        $rate->setCost(0);

        return $rate;
    }

    /**
     * Get Express rate object
     *
     * @return Mage_Shipping_Model_Rate_Result_Method
     */
    protected function _getExpressRate()
    {
        /** @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('express');
        $rate->setMethodTitle('Express delivery');
        $rate->setPrice(0);
        $rate->setCost(0);

        return $rate;
    }
}
By adding above code you will find your new custom shipping method display in checkout/cart and checkout/onepage pages.

If you want to hide that Estimate Shipping and Tax Block from checkout/cart page or just want to hide that custom shipping method from checkout/cart page then follow below tricks.

1) If you want to hide shipping Method Block from Cart page you can edit checkout.xml layout file, you can find that file in frontend/your_package/your_theme/layout/checkout.xml, then look for the

<checkout_cart_index translate="label">


tag and remove or comment the following line within reference name content

<block type="checkout/cart_shipping" name="checkout.cart.shipping" as="shipping" template="checkout/cart/shipping.phtml"/>


2) You can hide specific shipping method on magento cart by editing cart's shipping.phtml. It's located in frontend/your_package/your_theme/template/checkout/cart/shipping.phtml

Find the following lines:

<?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>

<form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>" class="co-shipping-method-form">

    <dl class="sp-methods">

        <?php foreach ($_shippingRateGroups as $code => $_rates): ?>


and add below code after the foreach loop to skip shipping method you want

<?php if ($code == 'mycompany_customshipping') continue; ?>


p.s. If files located in base package default theme, make sure to copy that file to your package theme first.

Download Whole Module from Github: https://github.com/vijayrami/Customshipping_method_product_Attribute
Tag : Magento
0 Comments On "Create Custom shipping Method Based on Product Attribute in Magento"

Back To Top