One shipping module to control two shipping methods?

By | July 13, 2009

I was set a challenge by one of my clients to set up a method whereby he could use just one shipping module, but offer two different methods of shipping…

For weights under 5kgs he wanted to use Royal Mail.
For weights in excess of 5kgs he wanted to use a Courier Service.

Here is the breakdown in prices;

Royal Mail

0-100g £1.40
101-250g £1.75
251-500g £2.60
501-1Kg £3.25
1-2Kg £4.50
2-5Kg £5.95

Courier

£7.50 for each 25kgs or part thereof (example, a 32kg package would be £15)

How did I do this?

The first step was to quickly create a brand new shipping module. Shipping modules are the absolute easiest thing in osCommerce to work with…I have covered this in the past on this blog. I then hardcoded the “cost” logic in order to test the theory. My hardcoding looked like this (to cover Royal Mail):

[php]if ($shipping_weight <= .1) $cost = 1.40; if (($shipping_weight > .1)&&($shipping_weight <= .25)) $cost = 1.75; if (($shipping_weight > .25)&&($shipping_weight <= .5)) $cost = 2.60; if (($shipping_weight > .5)&&($shipping_weight <= 1)) $cost = 3.25; if (($shipping_weight > 1)&&($shipping_weight <= 2)) $cost = 4.50; if (($shipping_weight > 2)&&($shipping_weight < 5)) $cost = 5.95;[/php] pretty straightforward, a range of weights, with a price attached to each. Thus if the total weight is (say) 1.2kgs, the cost is £4.50 - as 1.2 comes in the weight range "greater than 1 but less than 2"...easy as 123, eh? And like this to cover Courier: [php]if ($shipping_weight >= 5) $cost = (ceil($shipping_weight/25)) * 7.50;[/php]

This is a bit more complicated as I am using the ceil function of PHP. The ceil function rounds up the value of an equation to the next full number. Thus if the total weight is (say) 10kgs, the equation goes like this: 10/25 = 0.4 – this is rounded up to 1 by “ceil”, then it is multiplied by 7.50 to work out the cost. Why 25? If you remember, the Courier charges £7.50 per 25kgs or part thereof…

I then tested a variety of different weights in order to make sure that the breakdown of price points was working. It didn’t work. CRAP! Every weight I tried was 3kgs too much – ahhhhh – I forgot to remove the TARE weight. So, I set it to zero and tried again. not working! CRAP! Everything was 10% too high – ahhhhh – I forgot to set the % increase to zero. Tried again – now it’s working!

Now, because I had hard coded all the weights and prices directly into the shipping module, it would make it very hard for the shop owner to update. He’d have to know which file to FTP, amend the figures correctly, then re-upload it. So I set out to store the weights and prices in the database – and create an easy to administer form where the shop owner can update whenever he needs to.

This is actually fairly simple, and is done by adding extra database queries in the shipping module, like this:

[php]tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values (‘Max Weight For Iteration 1’, ‘MODULE_CODPK_SHIPPING_TABLE_COST_ONE_WEIGHT’, ‘0.1’, ‘Iteration 1 – Max Weight’, ‘6’, ‘0’, now())”);
tep_db_query(“insert into ” . TABLE_CONFIGURATION . ” (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values (‘Price For Iteration 1’, ‘MODULE_CODPK_SHIPPING_TABLE_COST_ONE’, ‘1.40’, ‘The shipping cost for Iteration 1’, ‘6’, ‘0’, now())”);[/php]

The important bits are these; MODULE_CODPK_SHIPPING_TABLE_COST_ONE_WEIGHT and MODULE_CODPK_SHIPPING_TABLE_COST_ONE which is what I will use to determine the max weight for a price. Repeat for as many price breaks as is required!

Then recode the cost section as so;

[php]if ($shipping_weight <= MODULE_CODPK_SHIPPING_TABLE_COST_ONE_WEIGHT) $cost = MODULE_CODPK_SHIPPING_TABLE_COST_ONE; if (($shipping_weight > MODULE_CODPK_SHIPPING_TABLE_COST_ONE_WEIGHT)&&($shipping_weight <= MODULE_CODPK_SHIPPING_TABLE_COST_TWO_WEIGHT)) $cost = MODULE_CODPK_SHIPPING_TABLE_COST_TWO; if (($shipping_weight > MODULE_CODPK_SHIPPING_TABLE_COST_TWO_WEIGHT)&&($shipping_weight <= MODULE_CODPK_SHIPPING_TABLE_COST_THREE_WEIGHT))$cost = MODULE_CODPK_SHIPPING_TABLE_COST_THREE; if (($shipping_weight > MODULE_CODPK_SHIPPING_TABLE_COST_THREE_WEIGHT)&&($shipping_weight <= MODULE_CODPK_SHIPPING_TABLE_COST_FOUR_WEIGHT))$cost = MODULE_CODPK_SHIPPING_TABLE_COST_FOUR; if (($shipping_weight > MODULE_CODPK_SHIPPING_TABLE_COST_FOUR_WEIGHT)&&($shipping_weight <= MODULE_CODPK_SHIPPING_TABLE_COST_FIVE_WEIGHT))$cost = MODULE_CODPK_SHIPPING_TABLE_COST_FIVE; if (($shipping_weight > MODULE_CODPK_SHIPPING_TABLE_COST_FIVE_WEIGHT)&&($shipping_weight < MODULE_CODPK_SHIPPING_TABLE_COST_SIX_WEIGHT))$cost = MODULE_CODPK_SHIPPING_TABLE_COST_SIX;[/php] and [php]if ($shipping_weight >= MODULE_CODPK_SHIPPING_TABLE_COST_SIX_WEIGHT) $cost = (ceil($shipping_weight/25)) * MODULE_CODPK_SHIPPING_TABLE_COST;[/php]

Now, deactivate and reactivate the module and it is possible for the Shop Owner to set up a range of 6 weights/costs for Royal Mail and 1 cost for Courier.

Sweet! Then I thought it would be extra nice to differentiate between whether the order is going to be sent by Royal Mail or by Courier.

So, I added this:

[php]$way = “Royal Mail”;[/php]

and this:

[php]$way = “Courier”;[/php]

at appropriate points in the module. Then I changed this line of code:

[php]’title’ => MODULE_CODPK_SHIPPING_TABLE_TEXT_WAY[/php]

to

[php]’title’ => $way[/php]

and now everything works as it should do. The weights and costs work out correctly and both the client and the shop owner can see if the order should be sent Royal Mail or Courier.

One thought on “One shipping module to control two shipping methods?

  1. Liuk

    swiss post shipping module in oscommerce.com does something similar.

Leave a Reply

Your email address will not be published.