Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Shipping Rate Estimator On Product Page


Guest

Recommended Posts

I was thinking that it would be a cool feature to have a Shipping Rate Estimator on the Product Page that used the active Shipping Modules to provide the rate quotes.

 

I realize that there is already a "Ship-In-Cart" contribution that actually works really well... as long as someone places items in their Cart. If they dont add the item to their cart, then no shipping info will be displayed.

 

Just like the Ship-In-Cart contribution, all that would need to be displayed is the rate quote for the specific product that is being viewed... If the Customer is logged in, the shipping rate would use the Customers Zipcode from their account info. If they are not logged in, a dropdown box or text box for zip code would be displayed. No Order Totals or anything extra like that, just the rate calculator.

 

Now, one thing I have done is successfully integrated a HTML-based UPS Rate calculator into the Product page which basically provides the customer a text field to enter their zipcode, a dropdown to select the method(i.e. ground, next day, etc...) and a calculate button that opens a new browser window and displays the requested UPS Shipping Rate information. But... I would really like to take this an extra step and use osC's integrated functionality to display the rates right on the Product page, rather than having to open a new browser window.

 

I have started hacking at the code already and it seems like the the shipping information for the integrated modules are tied into the Cart and Order classe files. Since the shipping rate information to be displayed really has nothing to do with the Cart and Order classes, I need to figure out a way to make this process run independently.

 

Would anyone like to work on this with me? I have already started and would really like some help and make it a community effort. I think it would be a great feature to add to the product page.

 

Let me know.

 

-R

Link to comment
Share on other sites

I'm going around in circles and cannot get the quotes to display. I have tried to steer away from the Shopping Cart and Order Class files, but damn this code is convaluted. There has got to be something that I am missing.

 

I have referenced code from the "Ship-In-Cart" contribution, as well as the Checkout Shipping Page.

 

Here's what I have come up with so far for product_info.php with the integrated rate code. Maybe someone else could take a look at it and add some insight.

<?php
/*
 $Id: product_info.php,v 1.92 2003/02/14 05:51:21 hpdl Exp $

 osCommerce, Open Source E-Commerce Solutions
 http://www.oscommerce.com

 Copyright (c) 2003 osCommerce

 Released under the GNU General Public License
*/

 function rate() {
   global $shipping;

   $this->info = array('shipping_method' => $shipping['title'],
                         'shipping_cost' => $shipping['cost']);
                         
 }
                         
 require('includes/application_top.php');

 require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_PRODUCT_INFO);
?>
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html <?php echo HTML_PARAMS; ?>>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo CHARSET; ?>">
<title><?php echo TITLE; ?></title>
<base href="<?php echo (($request_type == 'SSL') ? HTTPS_SERVER : HTTP_SERVER) . DIR_WS_CATALOG; ?>">
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script language="javascript"><!--
function popupWindow(url) {
 window.open(url,'popupWindow','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,res
izable=yes,copyhistory=no,width=100,height=100,screenX=150,screenY=150,top=150,le
ft=150')
}
function rowOverEffect(object) {
 if (object.className == 'moduleRow') object.className = 'moduleRowOver';
}

function rowOutEffect(object) {
 if (object.className == 'moduleRowOver') object.className = 'moduleRow';
}
//--></script>
</head>
<body marginwidth="0" marginheight="0" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0">
<!-- header //-->
<?php require(DIR_WS_INCLUDES . 'header.php'); ?>
<!-- header_eof //-->

<!-- body //-->
<table border="0" width="100%" cellspacing="3" cellpadding="3">
 <tr>
   <td width="<?php echo BOX_WIDTH; ?>" valign="top"><table border="0" width="<?php echo BOX_WIDTH; ?>" cellspacing="0" cellpadding="2">
<!-- left_navigation //-->
<?php require(DIR_WS_INCLUDES . 'column_left.php'); ?>
<!-- left_navigation_eof //-->
   </table></td>
<!-- body_text //-->
   <td width="100%" valign="top"><?php echo tep_draw_form('cart_quantity', tep_href_link(FILENAME_PRODUCT_INFO, tep_get_all_get_params(array('action')) . 'action=add_product')); ?><table border="0" width="100%" cellspacing="0" cellpadding="0">
<?php
 $product_info_query = tep_db_query("select p.products_id, pd.products_name, pd.products_description, p.products_weight, p.products_model, p.products_quantity, p.products_image, pd.products_url, p.products_price, p.products_tax_class_id, p.products_date_added, p.products_date_available, p.manufacturers_id from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_status = '1' and p.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and pd.products_id = p.products_id and pd.language_id = '" . $languages_id . "'");
 if (!tep_db_num_rows($product_info_query)) { // product not found in database
?>
     <tr>
       <td class="main"><br><?php echo TEXT_PRODUCT_NOT_FOUND; ?></td>
     </tr>
     <tr>
       <td align="right"><br><a href="<?php echo tep_href_link(FILENAME_DEFAULT); ?>"><?php echo tep_image_button('button_continue.gif', IMAGE_BUTTON_CONTINUE); ?></a></td>
     </tr>
<?php
 } else {
   tep_db_query("update " . TABLE_PRODUCTS_DESCRIPTION . " set products_viewed = products_viewed+1 where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and language_id = '" . $languages_id . "'");
   $product_info = tep_db_fetch_array($product_info_query);

   if ($new_price = tep_get_products_special_price($product_info['products_id'])) {
     $products_price = '<s>' . $currencies->display_price($product_info['products_price'], tep_get_tax_rate($product_info['products_tax_class_id'])) . '</s> <span class="productSpecialPrice">' . $currencies->display_price($new_price, tep_get_tax_rate($product_info['products_tax_class_id'])) . '</span>';
   } else {
     $products_price = $currencies->display_price($product_info['products_price'], tep_get_tax_rate($product_info['products_tax_class_id']));
   }
?>
     <tr>
       <td><table border="0" width="100%" cellspacing="0" cellpadding="2">
         <tr height="40">
           <td class="pageHeading"><?php echo $product_info['products_name']; ?></td>
           <td align="right" class="pageHeading"><?php echo $products_price; ?></td>
         </tr>
<?php
   if (PRODUCT_LIST_MODEL > 0) {
     echo '          <tr>' . "\n" .
          '            <td colspan="2" class="pageHeading">' . $product_info['products_model'] . '</td>' . "\n" .
          '          </tr>' . "\n";
   }
?>
       </table></td>
     </tr>
     <tr>
       <td><?php echo tep_draw_separator('pixel_trans.gif', '100%', '10'); ?></td>
     </tr>
     <tr>
       <td class="main"><table border="0" cellspacing="0" cellpadding="2" align="right">
<?php
   if (tep_not_null($product_info['products_image'])) {
?>
         <tr>
           <td align="center" class="smallText">
<script language="javascript"><!--
document.write('<?php echo tep_image(DIR_WS_IMAGES . $product_info['products_image'], addslashes($product_info['products_name']), SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT, 'hspace="5" vspace="5"'); ?>');
//--></script>
<noscript>
<?php echo tep_image(DIR_WS_IMAGES . $product_info['products_image'], $product_info['products_name'], SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT, 'hspace="5" vspace="5"'); ?>
</noscript>
           </td>
         </tr>
<?php
   }
?>
       </table><p><?php echo stripslashes($product_info['products_description']); ?></p>
<?php
   $products_attributes_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib where patrib.products_id='" . (int)$HTTP_GET_VARS['products_id'] . "' and patrib.options_id = popt.products_options_id and popt.language_id = '" . $languages_id . "'");
   $products_attributes = tep_db_fetch_array($products_attributes_query);
   if ($products_attributes['total'] > 0) {
     echo '<b>' . TEXT_PRODUCT_OPTIONS . '</b><br>' .
          '<table border="0" cellpadding="0" cellspacing"0">';
     $products_options_name_query = tep_db_query("select distinct popt.products_options_id, popt.products_options_name from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib where patrib.products_id='" . (int)$HTTP_GET_VARS['products_id'] . "' and patrib.options_id = popt.products_options_id and popt.language_id = '" . $languages_id . "'");
     while ($products_options_name = tep_db_fetch_array($products_options_name_query)) {
       $selected = 0;
       $products_options_array = array();
       echo '<tr><td class="main">' . $products_options_name['products_options_name'] . ':</td><td>' . "\n";
       $products_options_query = tep_db_query("select pov.products_options_values_id, pov.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " pa, " . TABLE_PRODUCTS_OPTIONS_VALUES . " pov where pa.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and pa.options_id = '" . $products_options_name['products_options_id'] . "' and pa.options_values_id = pov.products_options_values_id and pov.language_id = '" . $languages_id . "'");
       while ($products_options = tep_db_fetch_array($products_options_query)) {
         $products_options_array[] = array('id' => $products_options['products_options_values_id'], 'text' => $products_options['products_options_values_name']);
         if ($products_options['options_values_price'] != '0') {
           $products_options_array[sizeof($products_options_array)-1]['text'] .= ' (' . $products_options['price_prefix'] . $currencies->display_price($products_options['options_values_price'], tep_get_tax_rate($product_info['products_tax_class_id'])) .') ';
         }
       }
       echo tep_draw_pull_down_menu('id[' . $products_options_name['products_options_id'] . ']', $products_options_array, $cart->contents[$HTTP_GET_VARS['products_id']]['attributes'][$products_options_name['products_options_id']]);
       echo '</td></tr>';
     }
     echo '</table>';
   }
?>
       </td>
     </tr>
     <tr>
       <td><br><table border="0" width="100%" cellspacing="0" cellpadding="0">
         <tr>
           <td class="main"><!---<a href="<?php echo tep_href_link(FILENAME_PRODUCT_REVIEWS, substr(tep_get_all_get_params(), 0, -1)); ?>"><?php echo tep_image_button('button_reviews.gif', IMAGE_BUTTON_REVIEWS); ?></a>---></td>
           <td align="right" class="main"><?php echo tep_draw_hidden_field('products_id', $product_info['products_id']) . tep_image_submit('button_in_cart.gif', IMAGE_BUTTON_IN_CART); ?></td>
         </tr>
       </table></td>
     </tr>
     <tr>
       <td><br>
<?php
   if ( (USE_CACHE == 'true') && !defined('SID')) {
     echo tep_cache_also_purchased(3600);
   } else {
     include(DIR_WS_MODULES . FILENAME_ALSO_PURCHASED_PRODUCTS);
   }
 }
?>
       </td></form>
     </tr>
     <tr>
       <td>
<?php
/*
 $rate_country_id = STORE_COUNTRY;
 tep_session_register('rate_country_id');
 $rate_zip_code = STORE_ORIGIN_ZIP;
 $country_info = tep_get_countries(STORE_COUNTRY,true);
 tep_session_register('rate_zip_code');
 $rate->delivery = array('postcode' => STORE_ORIGIN_ZIP,
                         'country' => array('id' => STORE_COUNTRY, 'title' => $country_info['countries_name'], 'iso_code_2' => $country_info['countries_iso_code_2'], 'iso_code_3' =>  $country_info['countries_iso_code_3']),
                         'country_id' => STORE_COUNTRY,
                         'format_id' => tep_get_address_format_id($HTTP_POST_VARS['country_id']));
*/
 tep_session_register('shipping');
 
 $total_weight = $product_info['products_weight'];
 $total_count = '1';

// load all enabled shipping modules
 require(DIR_WS_CLASSES . 'shipping.php');
 $shipping_modules = new shipping;
       
// get all available shipping quotes
 $quotes = $shipping_modules->quote();

 if ( !tep_session_is_registered('shipping') || ( tep_session_is_registered('shipping') && ($shipping == false) && (tep_count_shipping_modules() > 1) ) ) $shipping = $shipping_modules->cheapest();

 if (tep_not_null($module)){
   $selected_quote = $shipping_modules->quote($method, $module);
   if($selected_quote[0]['error'] || !tep_not_null($selected_quote[0]['methods'][0]['cost'])){
     $selected_shipping = $shipping_modules->cheapest();
     $rate->info['shipping_method'] = $selected_shipping['title'];
     $rate->info['shipping_cost'] = $selected_shipping['cost'];
     $rate->info['total']+= $selected_shipping['cost'];
   }else{
     $rate->info['shipping_method'] = $selected_quote[0]['module'].' ('.$selected_quote[0]['methods'][0]['title'].')';
     $rate->info['shipping_cost'] = $selected_quote[0]['methods'][0]['cost'];
     $rate->info['total']+= $selected_quote[0]['methods'][0]['cost'];
     $selected_shipping['title'] = $rate->info['shipping_method'];
     $selected_shipping['cost'] = $rate->info['shipping_cost'];
     $selected_shipping['id'] = $selected_quote[0]['id'].'_'.$selected_quote[0]['methods'][0]['id'];
   }
 }else{
   $selected_shipping = $shipping_modules->cheapest();
   $rate->info['shipping_method'] = $selected_shipping['title'];
   $rate->info['shipping_cost'] = $selected_shipping['cost'];
   $rate->info['total']+= $selected_shipping['cost'];
 }
   
 $shipping=$selected_shipping;
 
 $ShipTxt= tep_draw_form('estimator', tep_href_link(FILENAME_PRODUCT_INFO, '', 'NONSSL'), 'post'); //'onSubmit="return check_form();"'
 $ShipTxt.='<table>';
 if (sizeof($quotes)) {
   // shipping display
   $ShipTxt.='<tr><td></td><td class="main" align="left"><b>' . CART_SHIPPING_METHOD_TEXT . '</b></td><td class="main" align="center"><b>' . CART_SHIPPING_METHOD_RATES . '</b></td></tr>';
   $ShipTxt.='<tr><td colspan="3" class="main">'.tep_draw_separator().'</td></tr>';
   for ($i=0, $n=sizeof($quotes); $i<$n; $i++) {
     if(sizeof($quotes[$i]['methods'])==1){
       // simple shipping method
       $thisquoteid = $quotes[$i]['id'].'_'.$quotes[$i]['methods'][0]['id'];
       $ShipTxt.= '<tr class="'.$extra.'">';
       $ShipTxt.='<td class="main">'.$quotes[$i]['icon'].' </td>';
       if($quotes[$i]['error']){
         $ShipTxt.='<td colspan="2" class="main">'.$quotes[$i]['module'].' ';
         $ShipTxt.= '('.$quotes[$i]['error'].')</td></tr>';
       }else{
         if($selected_shipping['id'] == $thisquoteid){
           $ShipTxt.='<td class="main"><b>'.$quotes[$i]['module'].' ';
           $ShipTxt.= '('.$quotes[$i]['methods'][0]['title'].')</b></td><td align="right" class="main"><b>'.$currencies->format(tep_add_tax($quotes[$i]['methods'][0]['cost'], $quotes[$i]['tax'])).'<b></td><td class="main">[<a href="_"  onclick="return shipincart_submit(\''.$thisquoteid.'\');">'.CART_SELECT.'</a>]</td></tr>';
         }else{
           $ShipTxt.='<td class="main">'.$quotes[$i]['module'].' ';
           $ShipTxt.= '('.$quotes[$i]['methods'][0]['title'].')</td><td align="right" class="main">'.$currencies->format(tep_add_tax($quotes[$i]['methods'][0]['cost'], $quotes[$i]['tax'])).'</td><td class="main">[<a href="_" onclick="return shipincart_submit(\''.$thisquoteid.'\');">'.CART_SELECT.'</a>]</td></tr>';
         }
       }
     } else {
       // shipping method with sub methods (multipickup)
       for ($j=0, $n2=sizeof($quotes[$i]['methods']); $j<$n2; $j++) {
         $thisquoteid = $quotes[$i]['id'].'_'.$quotes[$i]['methods'][$j]['id'];
         $ShipTxt.= '<tr class="'.$extra.'">';
         $ShipTxt.='<td class="main">'.$quotes[$i]['icon'].' HERE!!!!!</td>';
         if($quotes[$i]['error']){
           $ShipTxt.='<td colspan="2" class="main">'.$quotes[$i]['module'].' ';
           $ShipTxt.= '('.$quotes[$i]['error'].')</td></tr>';
         }else{
           if($selected_shipping['id'] == $thisquoteid){
             $ShipTxt.='<td class="main"><b>'.$quotes[$i]['module'].' ';
             $ShipTxt.= '('.$quotes[$i]['methods'][$j]['title'].')</b></td><td align="right" class="main"><b>'.$currencies->format(tep_add_tax($quotes[$i]['methods'][$j]['cost'], $quotes[$i]['tax'])).'</b></td><td class="main">[<a href="_" onclick="return shipincart_submit(\''.$thisquoteid.'\');">'.CART_SELECT.'</a>]</td></tr>';
           }else{
             $ShipTxt.='<td class="main">'.$quotes[$i]['module'].' ';
             $ShipTxt.= '('.$quotes[$i]['methods'][$j]['title'].')</td><td align="right" class="main">'.$currencies->format(tep_add_tax($quotes[$i]['methods'][$j]['cost'], $quotes[$i]['tax'])).'</td><td class="main">[<a href="_" onclick="return shipincart_submit(\''.$thisquoteid.'\');">'.CART_SELECT.'</a>]</td></tr>';
           }
         }
       }
     }
   }
 } 
 $ShipTxt.= '</table></form>';

 $info_box_contents = array();
 $info_box_contents[] = array('text' => $ShipTxt);
 new infoBox($info_box_contents);
?>
       </td>     
     </tr>
   </table></td>

<!-- body_text_eof //-->
   <td width="<?php echo BOX_WIDTH; ?>" valign="top"><table border="0" width="<?php echo BOX_WIDTH; ?>" cellspacing="0" cellpadding="2">
<!-- right_navigation //-->
<?php require(DIR_WS_INCLUDES . 'column_right.php'); ?>
<!-- right_navigation_eof //-->
   </table></td>
 </tr>
</table>
<!-- body_eof //-->

<!-- footer //-->
<?php require(DIR_WS_INCLUDES . 'footer.php'); ?>
<!-- footer_eof //-->
<br>
</body>
</html>
<?php require(DIR_WS_INCLUDES . 'application_bottom.php'); ?>

Let me know.

 

-R

Link to comment
Share on other sites

HA!!! :lol:

 

I did it. I have successfuly written and added a UPS Shipping Rate Calculator, using the UPS XML app technology, to be displayed on the individual product pages.

 

The customer can select their destination Country and enter their Zip Code, with the results displayed in a new JavaScript popup window.

 

This is a great feature to provide customers, allowing them to view what the shipping costs will be before they even add the item to their cart.

 

 

-R

Link to comment
Share on other sites

  • 4 months later...

Congrats on the completion. I have recently installed ship in cart with is great for the shopping_cart.php page. I'd like to display the quote for the product being shown on product_info.php page as well. I began looking at shipping_estimator.php from ship in cart contribution but I immediately noticed everything was based on cart contents, which has me stuck.

Can you share your work? I and others are sure to benefit from this.

 

 

Chris

Link to comment
Share on other sites

  • 2 months later...

Well, this sounds great, ugottasallsa!

 

Question... is the freight total cumulative? ***

 

e.g. customer already has 5 pounds in the cart and then looks at another item. Would the freight estimate be a total of the cart plus the new item under consideration?

 

Wow. wouldn't it be really cool if it told the customer e.g. for only 75 cents more you can add this white elephant to your order. Like the free freight contribution does for free freight. Maybe you already have it doing thiis..

 

Anyway great sounding contrib. Got a screen shot?

 

 

*** forgive me if you explained this in your text. i'm slow.

 

joeiscoffee

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...