Anyhow, it's simple! For osC 2.2-MS2, here's all you need to do:
Copy the following code (a customization of /catalog/includes/modules/shipping/table.php):
<?php
/*
$Id: c1e.php,v 1.27 2003/02/05 22:41:52 hpdl Exp $
osCommerce, Open Source E-Commerce Solutions
http://www.oscommerce.com
Copyright (c) 2003 osCommerce
Released under the GNU General Public License
*/
class c1e {
var $code, $title, $description, $icon, $enabled;
// class constructor
function c1e() {
global $order;
$this->code = 'c1e';
$this->title = MODULE_SHIPPING_C1E_TEXT_TITLE;
$this->description = MODULE_SHIPPING_C1E_TEXT_DESCRIPTION;
$this->sort_order = MODULE_SHIPPING_C1E_SORT_ORDER;
$this->icon = '';
$this->tax_class = MODULE_SHIPPING_C1E_TAX_CLASS;
$this->enabled = ((MODULE_SHIPPING_C1E_STATUS == 'True') ? true : false);
if ( ($this->enabled == true) && ((int)MODULE_SHIPPING_C1E_ZONE > 0) ) {
$check_flag = false;
$check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_SHIPPING_C1E_ZONE . "' and zone_country_id = '" . $order->delivery['country']['id'] . "' order by zone_id");
while ($check = tep_db_fetch_array($check_query)) {
if ($check['zone_id'] < 1) {
$check_flag = true;
break;
} elseif ($check['zone_id'] == $order->delivery['zone_id']) {
$check_flag = true;
break;
}
}
if ($check_flag == false) {
$this->enabled = false;
}
}
}
// class methods
function quote($method = '') {
global $order, $cart, $shipping_weight, $shipping_num_boxes;
if (MODULE_SHIPPING_C1E_MODE == 'price') {
$order_total = $cart->show_total();
} else {
$order_total = $shipping_weight;
}
$c1e_cost = split("[:,]" , MODULE_SHIPPING_C1E_COST);
$size = sizeof($c1e_cost);
for ($i=0, $n=$size; $i<$n; $i+=2) {
if ($order_total <= $c1e_cost[$i]) {
$shipping = $c1e_cost[$i+1];
break;
}
}
if (MODULE_SHIPPING_C1E_MODE == 'weight') {
$shipping = $shipping * $shipping_num_boxes;
}
$this->quotes = array('id' => $this->code,
'module' => MODULE_SHIPPING_C1E_TEXT_TITLE,
'methods' => array(array('id' => $this->code,
'title' => MODULE_SHIPPING_C1E_TEXT_WAY,
'cost' => $shipping + MODULE_SHIPPING_C1E_HANDLING)));
if ($this->tax_class > 0) {
$this->quotes['tax'] = tep_get_tax_rate($this->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
}
if (tep_not_null($this->icon)) $this->quotes['icon'] = tep_image($this->icon, $this->title);
return $this->quotes;
}
function check() {
if (!isset($this->_check)) {
$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_SHIPPING_C1E_STATUS'");
$this->_check = tep_db_num_rows($check_query);
}
return $this->_check;
}
function install() {
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) VALUES ('Enable Table Method', 'MODULE_SHIPPING_C1E_STATUS', 'True', 'Do you want to offer table rate shipping?', '6', '0', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Shipping Table', 'MODULE_SHIPPING_C1E_COST', '25:8.50,50:5.50,10000:0.00', 'The shipping cost is based on the total cost or weight of items. Example: 25:8.50,50:5.50,etc.. Up to 25 charge 8.50, from there to 50 charge 5.50, etc', '6', '0', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Table Method', 'MODULE_SHIPPING_C1E_MODE', 'weight', 'The shipping cost is based on the order total or the total weight of the items ordered.', '6', '0', 'tep_cfg_select_option(array(\'weight\', \'price\'), ', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Handling Fee', 'MODULE_SHIPPING_C1E_HANDLING', '0', 'Handling fee for this shipping method.', '6', '0', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Tax Class', 'MODULE_SHIPPING_C1E_TAX_CLASS', '0', 'Use the following tax class on the shipping fee.', '6', '0', 'tep_get_tax_class_title', 'tep_cfg_pull_down_tax_classes(', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Shipping Zone', 'MODULE_SHIPPING_C1E_ZONE', '0', 'If a zone is selected, only enable this shipping method for that zone.', '6', '0', 'tep_get_zone_class_title', 'tep_cfg_pull_down_zone_classes(', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort Order', 'MODULE_SHIPPING_C1E_SORT_ORDER', '0', 'Sort order of display.', '6', '0', now())");
}
function remove() {
tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}
function keys() {
return array('MODULE_SHIPPING_C1E_STATUS', 'MODULE_SHIPPING_C1E_COST', 'MODULE_SHIPPING_C1E_MODE', 'MODULE_SHIPPING_C1E_HANDLING', 'MODULE_SHIPPING_C1E_TAX_CLASS', 'MODULE_SHIPPING_C1E_ZONE', 'MODULE_SHIPPING_C1E_SORT_ORDER');
}
}
?>
Paste it into a new blank file, and save it as, say, /catalog/includes/modules/shipping/usa1.php
With 'match case' enabled in your search, look for c1e and replace all instances with usa1.
Then do a second 'match case' search for C1E and replace all instances with USA1.
Now copy this code (a customization of /catalog/includes/languages/english/modules/shipping/table.php):
<?php
/*
$Id: c1e.php,v 1.5 2002/11/19 01:48:08 dgw_ Exp $
osCommerce, Open Source E-Commerce Solutions
http://www.oscommerce.com
Copyright (c) 2002 osCommerce
Released under the GNU General Public License
*/
define('MODULE_SHIPPING_C1E_TEXT_TITLE', 'Canada Xpress Post: Region 1');
define('MODULE_SHIPPING_C1E_TEXT_DESCRIPTION', 'Canada Xpress Post: Region 1');
define('MODULE_SHIPPING_C1E_TEXT_WAY', '2-3 business days');
define('MODULE_SHIPPING_C1E_TEXT_WEIGHT', 'Weight');
define('MODULE_SHIPPING_C1E_TEXT_AMOUNT', 'Amount');
?>
Paste it into a new blank file, change the text to the way you want it, and save it as, say, /catalog/includes/languages/english/modules/shipping/usa1.php
With 'match case' enabled in your search, look for c1e and replace all instances with usa1.
Then do a second 'match case' search for C1E and replace all instances with USA1.
Upload the files to your server, then go to your admin screen -> modules -> shipping and install the new module. Then edit prices, etc. and you should be set.
For additional table methods, just repeat the steps above but with new search criteria (i.e. change c1e to usa2, C1E to USA2, etc. (or whatever you want to call them).
Something else to keep in mind...
In my store, I wanted to include delivery timeframes for each of my shipping methods. Using zone shipping, I couldn't find a way to specify a different comment for each zone, so my solution was to create 20+ different table rates to cover all of the situations. After installing the first 10, my shipping modules kept breaking on me. After two days of trying to find the error (recreating files, uninstalling and reinstalling, etc.), I finally thought to check my database to see if there was something wrong there. Bingo!
For shipping modules, the database table keeps track of all the shipping module file names in a field with a maximum of 255 characters. My initial file names were 15 characters or so each (including the .php extension at the end), and the total exceeded the allowable number of characters. By renaming all of my modules to
3-character names, I was able to fit all of them in, with a bit of room to spare!
HTH,
Terry










