Anthony McLin

Magento Custom Shipping Part 2: Order Handling Fees

So now that we've built the basic framework for a custom shipping module in Magento Custom Shipping Part 1, its now time to move on to the special business logic that my client needs.

My client isn't shipping the usual pre-packaged electronics and other consumer goods you usually find online. Instead, they ship a product priced in standard units of volume. And since shipping is by semi truck, there's a maximum and minimum quantity that can be shipped.

Setting the Maximum and Minimum are fairly easy using the built-in Cart and Product tools from Magento. But now we need to calculate shipping costs. My client's shipping is calculated using this simple formula:

Quantity of Material x Handling Fee (per unit) + Delivery Charge (per region)

The first part of this, the handling fee, is pretty easy. Read More to see how we add the handling charges to our module

The shipping module we built already copies Magento's handling procedures. All we need to do is refactor our code to add a third way of calculating handling. We do this by changing the list of options, and then in LocalDelivery.php we'll add code to act on each option.

Magento probably goes a little overboard in normalizing its object-oriented structure. On one hand, they make it very easy to hook into some standard, pre-defined value lists for form inputs, but on the other hand, this makes it a bit more difficult to build your own list of values. Let's take a look at our module's system.xml file and find the tag for the handling_type:


	
	select
	shipping/source_handlingType
	10
	1
	1
	0

Currently the tag cluster "Calculate Handling Fee" lets the site admin pick from the system-defined list, which are only Fixed and Percent. This list is defined using the tag <source_model>shipping/source_handlingType</source_model>. In this case, the "source_model" values can be found in /app/code/core/Mage/Shipping/Model/Source/HandlingType.php

class Mage_Shipping_Model_Source_HandlingType
{
    public function toOptionArray()
    {
        return array(
            array('value' => Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED, 'label' => Mage::helper('shipping')->__('Fixed')),
            array('value' => Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT, 'label' => Mage::helper('shipping')->__('Percent')),
        );
    }
}

So in order to add another handling type (without affecting the core) we need to copy this over to our module. Add the following file to your custom module.

/app/code/local/AMC/Shipping/Model/Source/HandlingType.php

class AMC_Shipping_Model_Source_HandlingType
{
    public function toOptionArray()
    {
        return array(
            array('value' => Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_FIXED, 'label' => Mage::helper('shipping')->__('Fixed')),
            array('value' => Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT, 'label' => Mage::helper('shipping')->__('Percent')),
            array('value' => 'each', 'label' => Mage::helper('shipping')->__('Per Unit')),
        );
    }
}

Notice the third handling type is the one we are adding. The previous two are the standard built-ins and are stored as system constants; we're simply copying them over. By the way, the built in values are 0 for per-order handling, and P for percentage-based fee. We are adding each as our third per-unit fee.

Jump back to our system.xml file, and we'll replace the <source_model> tag:


	
	select
	AMC_Shipping_Model_Source_HandlingType
	10
	1
	1
	0

Now, let's add the necessary logic to LocalDelivery.php. We're going to replacing the entire handling section with this new block of code. A simple switch statement lets us easily discern between the 3 different ways of calculating the handling fee. We're keeping the two existing methods, and adding a new one for Quantity of items.

$result = Mage::getModel('shipping/rate_result');
        
        //Get the base handling fee
        $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
        //Calculate the proper handling charge based on type
        switch( Mage::getStoreConfig('carriers/'.$this->_code.'/handling_type')) {
        	//Percentage of order value total
        	case 'P':
        		$handling = $request->getPackageValue() * $handling;
        		break;
        	//Handling per unit of items
        	case 'each':
        		$handling = $request->getPackageQty() * $handling;
    			break;
    		//Fixed per-order handling (the default)
        	case 0:
        	default:
        		break;
    	}

Now save your work, clear your Magento caches, and you should find that in the shipping configuration, you should now have a third handling fee option available.


Categories: 

Comments

Do you know how to manipulate the UPS shipping module to include insurance?

- Chanjay (not verified)

Add new comment