Question

Virtuemart - shipping per item

Asked by: kennedypd1

Hi

I have been looking in google for this answer for hours and have found lots of people with the same problem but can't find any solution.

My question is how do I setup a shipping module in virtuemart to enable charging for shipping on a per item basis.
eg 1 product = $3 shipping
   2 products = $6 shipping

Also different products have different shipping rates

so product a is $4 and product b is $8
customer buys 3 x Product A and 1 x Product B then shipping = $20

Any assistance much appreciated

Cheers
Paul

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-06-15 at 03:24:49ID24491681
Topics

Joomla

,

Stores & Carts

,

PHP and Databases

,

PHP Scripting Language

,

Web Languages/Standards

Participating Experts
1
Points
500
Comments
22

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Calculate Shipping on the Fly
    I am designing a site where my company can take orders online. Products range from low-priced mice to high-priced complete computer systems. I would like to know what would be the best way to calculate shipping on the fly. Should we set a minimum freight charge and then add t...
  2. How To Calculate Shipping Charges
    I am writing my first actual ecommerce website and the client wants it to automatically calculate shipping charges.. How can I do this? Can I somehow link up with a Fedex site? As per credit card processing, I'm just giving them a report to print out so they can do it by ...
  3. Paypal Shipping calculation with second item being reduced…
    I have tried to incorporate the paypal shipping cart into my website. However my problem is that I have a fixed rate of postage for the first item purchased £1.95 uk and £4.95 international. If a customer buys 2 or more items each extra item is charged at 0.95p. I cannot find...
  4. Calculating shipping and handling charges
    The code below was the tax calculation that peh803 had helped me fix so that taxes are automatically added into customer's total purchase for an ecommerce site. The sub is in global.asa file Sub Application_OnStart 'Tax percentage to add to order total 'change to match yo...
  5. How to determine customer is international and charge mor…
    Hello, I am working on a site that is using paypal to process all transactions. The site using two flat rate shipping costs, one for domestic and one for international. We want to avoid have the customer enter any billing or shipping information into our site and use paypals ...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: kennedypd1Posted on 2009-06-16 at 06:02:34ID: 24637468

I have found a couple of modules that work fine and if someone can please have a look at what I am doing wrong here it would be appreciated.

I have found this code that lets me bill per item based on SKU.
I works fine except I cant differentiate between domestic and international.
I have adatped the table for this code to have an extra field that is called i_amount that has the international freight charges per SKU and amont that has the domestic freight charges.

So I need to get the code in file 24637468a.txt (attached below) to differentiate the country of delivery.

The code in file 24637468b.txt (attached below) works well for doing domestic and international transactions so I need to cut the code from this one that works out the country of origin

Any help much appreciated

  • 24637468b.txt
    • 11 KB

    24637468b (second code) uploaded by Netminder 17 June 2009

  • 24637468a.txt
    • 7 KB

    24637468a (first code) uploaded by Netminder 17 June 2009

 

by: kennedypd1Posted on 2009-06-17 at 02:41:34ID: 24646423

I think I have got along way towards getting this sorted and just need a bit of assistance with the last bit that I am stumped on and am fairly sure it is just a matter of code in wrong place.

The code below works well except that the $rate variable is always at the international rate so is not picking up if the user is domestic. I can echo country and it comes up correctly and matches what is in the config file.

Any help appreciated.

Cheers


class item_ship
{
 
 
 
var $classname = "item_ship";
 
function list_rates( &$d ) {
global $total, $tax_total, $CURRENCY_DISPLAY;
$db =& new ps_DB;
$dbv =& new ps_DB;
 
$cart = $_SESSION['cart'];
 
/** Read current Configuration ***/
require_once(CLASSPATH ."shipping/".$this->classname.".cfg.php");
 
if ( $_SESSION['auth']['show_price_including_tax'] != 1 ) {
$taxrate = 1;
$order_total = $total + $tax_total;
}
else
{
$taxrate = $this->get_tax_rate() + 1;
$order_total = $total;
}
 
 
/* Get Shipping/Billing Country from Database */
$database = new ps_DB();
$q = "SELECT country FROM #__{vm}_user_info WHERE user_info_id='".$d['ship_to_info_id']."'" ;
$database->query($q);
$database->next_record();
$country = $database->f("country");
 
 
 
$rate = $this->get_rate($d);
 
$shipping_rate_id = urlencode($this->classname."|STD|Standard Shipping|" . $rate . '|' . $rate);
 
$html = "Rate $rate";
$html .= "\n<input type=\"radio\" name=\"shipping_rate_id\" checked=\"checked\" value=\"$shipping_rate_id\" />\n";
$html .= "Standard Shipping: ".$CURRENCY_DISPLAY->getFullValue($rate);
$_SESSION[$shipping_rate_id] = 1;
 
echo $html;
return true;
 
 
}
 
function get_rate( &$d )
{
$db =& new ps_DB;
$total = 0.00;
 
foreach($_SESSION['cart'] as $key=>$value)
{
//Query for that products shipping amount
//Multiply by quantity and add to sum
if ($key !== "idx")
{
if ( $country == FLEX2_SHIPPING_COUNTRY )
{
$product_id = $value['product_id'];
$quantity = $value['quantity'];
$sql = "Select amount from #__{vm}_product_shipping, ".
"#__{vm}_product where #__{vm}_product.product_sku = " .
"#__{vm}_product_shipping.product_sku and #__{vm}_product.product_id="
. $product_id;
 
$db->query($sql);
$db->next_record();
 
$shipping_amt = $db->f('amount');
 
$total += round(($shipping_amt*$quantity), 2);
}
 
 
else
{
$product_id = $value['product_id'];
$quantity = $value['quantity'];
$sql = "Select i_amount from #__{vm}_product_shipping, ".
"#__{vm}_product where #__{vm}_product.product_sku = " .
"#__{vm}_product_shipping.product_sku and #__{vm}_product.product_id="
. $product_id;
 
$db->query($sql);
$db->next_record();
 
$shipping_amt = $db->f('i_amount');
 
$total += round(($shipping_amt*$quantity), 2);
 
 
}
}
}
 
return $total;
}
 
function get_tax_rate()
{
 
/** Read current Configuration ***/
require_once(CLASSPATH ."shipping/".$this->classname.".cfg.php");
 
if( intval(SHIPPRODUCT_TAX_CLASS)== 0 )
return( 0 );
else {
require_once( CLASSPATH. "ps_tax.php" );
$tax_rate = ps_tax::get_taxrate_by_id( intval(SHIPPRODUCT_TAX_CLASS) );
return $tax_rate;
}
}
 
/* Validate this Shipping method by checking if the SESSION contains the key
* @returns boolean False when the Shipping method is not in the SESSION
*/
function validate( $d ) {
 
$shipping_rate_id = $d["shipping_rate_id"];
 
if( array_key_exists( $shipping_rate_id, $_SESSION ))
return true;
else
return false;
}
/**
* Show all configuration parameters for this Shipping method
* @returns boolean False when the Shipping method has no configration
*/
function show_configuration()
{
$db =& new ps_DB;
global $PHPSHOP_LANG;
 
/** Read current Configuration ***/
require_once(CLASSPATH ."shipping/".$this->classname.".cfg.php");
 
// Determine if the appropriate configuration table exists
// if not, create it
 
$sql = "Select product_sku, amount, i_amount from #__{vm}_product_shipping";
$db->query($sql);
 
if (!$db->next_record())
{
//There is no current configuration or the table doesn't exist
//Therefore, we will create an initial table
$sql = "CREATE TABLE `#__{vm}_product_shipping` " .
"(`product_sku` varchar(64) NOT NULL, `amount` float NOT NULL, `i_amount` float NOT NULL, " .
"PRIMARY KEY (`product_sku`) )";
$db->query($sql);
 
echo "No records";
}
 
/** Read current Configuration ***/
 
echo "<table>";
 
$sql = "Select product_sku, amount, i_amount from #__{vm}_product_shipping";
$db->query($sql);
 
while ($db->next_record())
{
echo '<tr><td>Shipping Amount for ' .
$db->f('product_sku') .
'</td><td><input type="text" size="4" name="' .
$db->f('product_sku') .
'" value="' .
$db->f('amount') .
'"></td><td><input type="text" size="4" name="' .
$db->f('product_sku') .
'" value="' .
$db->f('i_amount') .
'"></td>' .
'<td>' . vmToolTip("Enter a new amount, or leave the amount blank to remove a value shipping record") . '</td>' .
'</tr>';
}
 
//display a box to input new entries
 
echo '<tr><td>New Product: <input type="text" name="__new_product" size="20"></td>';
echo '<td>Domestic Amount: <input type="text" name="__new_product_amount" size="4"></td>';
echo '<td>International Amount: <input type="text" name="__new_product_i_amount" size="4"></td>';
 
echo '<td>' . vmToolTip("Enter a product SKU then domestic amount then international amount to create a new value shipping record") . '</td>';
 
echo '</tr>';
 
?>
<tr>
<td><strong><?php echo $PHPSHOP_LANG->_PHPSHOP_UPS_TAX_CLASS ?></strong></td>
<td>
<?php
require_once(CLASSPATH.'ps_tax.php');
ps_tax::list_tax_value("SHIPPRODUCT_TAX_CLASS", SHIPPRODUCT_TAX_CLASS) ?>
</td>
<td><?php echo vmToolTip("Use the following tax class on the shipping charge. The shipping charge values above will then be inclusive of this tax rate.") ?><td>
</tr>
<?php
echo "</table>";
return true;
}
 
 
/**
* Returns the "is_writeable" status of the configuration file
* @param void
* @returns boolean True when the configuration file is writeable, false when not
*/
function configfile_writeable()
{
return is_writeable( CLASSPATH."shipping/".$this->classname.".cfg.php" );
}
 
/**
* Writes the configuration file for this shipping method
* @param array An array of objects
* @returns boolean True when writing was successful
*/
function write_configuration( &$d )
{
//if there is a new item, insert it:
$db =& new ps_DB;
 
if (isset($d['__new_product']) &&
isset($d['__new_product_amount']) &&
isset($d['__new_product_i_amount']) &&
$d['__new_product'] != '' &&
$d['__new_product_amount'] != '' &&
$d['__new_product_i_amount'] != '')
{
 
$product = $d['__new_product'];
$amount = round(floatval($d['__new_product_amount']), 2);
$i_amount = round(floatval($d['__new_product_i_amount']), 2);
 
$sql = "Insert into #__{vm}_product_shipping values(" .
"'$product', '$amount', '$i_amount')";
$db->query($sql);
}
 
//lookup all existing records, iterate through items and
//update as necassary, removing items whose price is now blank or null
 
$sql = "Select product_sku, amount from #__{vm}_product_shipping";
$db->query($sql);
$sqlstmts = array();
 
while ($db->next_record())
{
$product_sku = $db->f('product_sku');
$amount = $db->f('amount');
 
//first case, we have a changed shipping amount
if (isset($d[$product_sku]) &&
$d[$product_sku] != '' && $d[$product_sku] != $amount)
{
$new_amount = round(floatval($d[$product_sku]),2);
$sqlstmts[] = "Update #__{vm}_product_shipping set amount = $new_amount ".
"where product_sku = '$product_sku'";
}
//second case, we have an existing product that has been blanked
elseif (isset($d[$product_sku]) && $d[$product_sku] == '')
{
$sqlstmts[] = "Delete from #__{vm}_product_shipping ".
"where product_sku = '$product_sku'";
 
}
}
 
foreach($sqlstmts as $sql)
{
$db->query($sql);
}
 
$my_config_array = array(
"SHIPPRODUCT_TAX_CLASS" => $d['SHIPPRODUCT_TAX_CLASS']
);
$config = "<?php\n";
$config .= "if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' ); \n\n";
foreach( $my_config_array as $key => $value )
{
$config .= "define ('$key', '$value');\n";
}
 
$config .= "?>";
 
if ($fp = fopen(CLASSPATH ."shipping/".$this->classname.".cfg.php", "w"))
{
fputs($fp, $config, strlen($config));
fclose ($fp);
return true;
}
else
{
$vmLogger->err( "Error writing to configuration file" );
return true;
}
}
 
 
}
 
 
?>

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:

Select allOpen in new window

 

by: kennedypd1Posted on 2009-06-17 at 04:03:00ID: 24646782

Hi

The problem I think revolves around this statement.

I have boldeded the if statement that does not appear to work.
The result is always false  (runs the else query)

The only difference between the 2 is that one pulls the domestic rate [amount]
and the false pulls the international amount [i_amount]. If I switch the false statement to reflect the domestic rate then the shipping cart work out the domestic rate fine. So I assume it is in the bolded if staement as everything else appears to work perfectly.

I have echoed the variable $country on my form and it displays NZL


function get_rate( &$d )
{
$db =& new ps_DB;
$total = 0.00;

foreach($_SESSION['cart'] as $key=>$value)
{
//Query for that products shipping amount
//Multiply by quantity and add to sum


if ($key !== "idx")
{
if ($country == "NZL")
{
$product_id = $value['product_id'];
$quantity = $value['quantity'];
$sql = "Select amount from #__{vm}_product_shipping, ".
"#__{vm}_product where #__{vm}_product.product_sku = " .
"#__{vm}_product_shipping.product_sku and #__{vm}_product.product_id="
. $product_id;

$db->query($sql);
$db->next_record();

$shipping_amt = $db->f('amount');

$total += round(($shipping_amt*$quantity), 2);
}

else
{
$product_id = $value['product_id'];
$quantity = $value['quantity'];
$sql = "Select i_amount from #__{vm}_product_shipping, ".
"#__{vm}_product where #__{vm}_product.product_sku = " .
"#__{vm}_product_shipping.product_sku and #__{vm}_product.product_id="
. $product_id;

$db->query($sql);
$db->next_record();

$shipping_amt = $db->f('i_amount');

$total += round(($shipping_amt*$quantity), 2);


}
}
}

return $total;
}

 

by: RQuadlingPosted on 2009-06-17 at 04:54:50ID: 24647139

Try ...

var_dump($country);

What  does this ouput?

 

by: kennedypd1Posted on 2009-06-17 at 11:49:54ID: 24651263

Hi RQuadling
Thanks for having a look at this for me

I put var_dump($country) in the html and it produced
var_dump(NZL)

Is that what you were looking for.

Cheers

 

by: kennedypd1Posted on 2009-06-17 at 22:28:41ID: 24654661

Hi RQuadling
Thanks for having a look at this for me

I put var_dump($country) in php and it produced
string(3) "NZL"

I think this is more what you were looking for.

Cheers

 

by: RQuadlingPosted on 2009-06-18 at 02:35:10ID: 24655765

Yes. Making sure it was just 3 letters and not "NLZ " (or something else).

 

by: RQuadlingPosted on 2009-06-18 at 03:50:14ID: 24656129

There is $country coming from?

Is it $value['country'] that you should be using or $_SESSION['country']?

function get_rate( &$d ) 
	{ 
	$db =& new ps_DB;
	$total = 0.00;
	
	foreach($_SESSION['cart'] as $key=>$value)
		{
		//Query for that products shipping amount
		//Multiply by quantity and add to sum
		
		
		if ($key !== "idx")
			{
			// $country is not defined.
			// Is it $value['country'] that you should be using or $_SESSION['country']?
			$rate = ($country == "NZL") ? 'amount' : 'i_amount';
			
			$sql = "
			Select
				$rate
			from
				#__{vm}_product_shipping,
				#__{vm}_product
			where
				#__{vm}_product.product_sku = #__{vm}_product_shipping.product_sku
				and
				#__{vm}_product.product_id = {$value['product_id']}";
			
			$db->query($sql);
			$db->next_record();
			
			$total += round(($db->f($rate) * $value['quantity']), 2);
			}
		}
	
	return $total;
	}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

Select allOpen in new window

 

by: kennedypd1Posted on 2009-06-18 at 04:11:39ID: 24656257

Hi

I put the code in that you have above but still coming up with i_amount.

I am trying to use the country that is pulled in the sql at the beginning of this code. I am a relative novice at php so not sure if I should be using $value or $_SESSION and not sure what you mean by defined as the $country is worked out (defined?) in the sql

 /* Get Shipping/Billing Country from Database */            
            $database = new ps_DB();
            $q  = "SELECT country FROM #__{vm}_user_info WHERE user_info_id='".$d['ship_to_info_id']."'" ;
            $database->query($q);
            $database->next_record();
            $country = $database->f("country");
      
      
      
            $rate = $this->get_rate($d);
            
        $shipping_rate_id = urlencode($this->classname."|STD|Standard Shipping|" . $rate . '|' . $rate);
        
        $html = "";
        $html .= "\n<input type=\"radio\" name=\"shipping_rate_id\" checked=\"checked\" value=\"$shipping_rate_id\" />\n";
        $html .= "Standard Shipping: ".$CURRENCY_DISPLAY->getFullValue($rate);
        $_SESSION[$shipping_rate_id] = 1;
 var_dump($country);
      echo $html;
      return true;
 

  }
      
  function get_rate( &$d )
  {      
        $db =& new ps_DB;
        $total = 0.00;
        
        foreach($_SESSION['cart'] as $key=>$value)
      {
            //Query for that products shipping amount
            //Multiply by quantity and add to sum
   
   
    if ($key !== "idx")
                  {
                  // $country is not defined.
                  // Is it $value['country'] that you should be using or $_SESSION['country']?
                  $rate = ($country == "NZL") ? 'amount' : 'i_amount';
                  
                  $sql = "
                  Select
                        $rate
                  from
                        #__{vm}_product_shipping,
                        #__{vm}_product
                  where
                        #__{vm}_product.product_sku = #__{vm}_product_shipping.product_sku
                        and
                        #__{vm}_product.product_id = {$value['product_id']}";
                  
                  $db->query($sql);
                  $db->next_record();
                  
                  $total += round(($db->f($rate) * $value['quantity']), 2);
                  }
            }
      
      return $total;
      }

 

by: RQuadlingPosted on 2009-06-18 at 04:36:21ID: 24656386

Change

 $rate = $this->get_rate($d);

to

 $rate = $this->get_rate($d, $country);


and

  function get_rate( &$d )

to

  function get_rate( &$d, $country )




You need to learn about scope. $country is outside the scope of the get_rate() function.

You can pass it as a parameter (like I've done) or you could use the line ...

global $country;

inside and at the top of get_rate() (but only if $country is really global)

or use

$GLOBALS['country'] rather than $country in get_rate() (but only if $country is really global).

Personally, pass it as a parameter.

 

by: RQuadlingPosted on 2009-06-18 at 04:37:51ID: 24656398

 

by: kennedypd1Posted on 2009-06-18 at 05:16:54ID: 24656613

Hi


I really appreciate you walking me through this and pointing me to that article. I will definetly do some reading.
Any other references you could point me would also be appreciated.

Thanks for that. It works mostly.

It works out the shipping cost great but is not passing it to the cart properly. Still getting the international rate there.

This error message comes up on the cart

Warning: Missing argument 2 for item_ship::get_rate(), called in /var/users/kwh_10862/orahoney.co.nz/htdocs/administrator/components/com_virtuemart/html/ro_basket.php on line 191 and defined in /var/users/kwh_10862/orahoney.co.nz/htdocs/administrator/components/com_virtuemart/classes/shipping/item_ship.php on line 69


I have highlighted line 191 below in the ro_basket.php and line 69 in item_ship is this:           function get_rate( &$d, $country )

/* SHOW SHIPPING COSTS */
if( !empty($shipping_rate_id) && !ps_checkout::noShippingMethodNecessary() && !is_null($ps_checkout->_SHIPPING) ) {
$shipping = true;
$vars["weight"] = $weight_total;
$shipping_total = round( $ps_checkout->_SHIPPING->get_rate ( $vars ), 5 );
$shipping_taxrate = $ps_checkout->_SHIPPING->get_tax_rate();

If you want to or need to try the cart out to see what I mean then let me know and I will supply you with login info etc.

 

by: RQuadlingPosted on 2009-06-18 at 05:39:33ID: 24656776

The get_rate() function needs 2 paramaters!!

"Change

get_rate($d)

to

get_rate($d, $country)" (previous post).

So ...

$shipping_total = round( $ps_checkout->_SHIPPING->get_rate ( $vars, $country ), 5 );


Assuming $country is available in this scope.

 

by: kennedypd1Posted on 2009-06-19 at 01:27:51ID: 24664617

Hi Rquadling

That has worked a treat but unfortunately has thrown up 1 more issue that I am sure will be the last.

The file we were working on puts the values into the link for next page ( this is what is shown)
http://www.orahoney.co.nz/index.php?page=checkout.index&payment_method_id=19&ship_to_info_id=daa0f8442b4a9f152b5321c20dea8fa8&shipping_rate_id=item_ship%257CSTD%257CStandard%2BShipping%257C14.5%257C14.5&checkout_stage=4&option=com_virtuemart&Itemid=1

The shipping cost should be $14.50 which is in the link fine.

I have attatched the next and I think last page of the cart process before credit card. This page shows the shipping at $55.50 which is the international rate. I would have thought that we would not need to go through the whole country of origin again as we dealt with it the page before. The shipping part starts on line 170

I also came across this which may be of use to you:
When activated in the Shop configuration, this payment module will be loaded on the shipping method selection screen, beside all other activated shipping modules.

The shipping rate, a user has selected during checkout is passed from step to step by the parameter shipping_rate_id.

This parameter follows a strcit syntax and must be a string build like this:

ShippingClassName|carrier_name|rate_name|totalshippingcosts|rate_id

For our example the shipping rate id for one rate could be:

myShipping|My Carrier|My Rate Name|45.00

The last field (rate_id) can be left empty. The shipping_rate_id parameter is always passed as an urlencoded string.



Thanks again for all your help
Paul

<?php
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/**
* This file is the CART handler. It calculates the totals and
* uses the basket templates to show the listing to the user
* 
* This version of the basket allows to change quantities and delete products from the cart
* The ro_basket (=read only) doesn't allow that.
* 
* @version $Id: basket.php 1578 2008-11-29 23:08:19Z soeren_nb $
* @package VirtueMart
* @subpackage html
* @copyright Copyright (C) 2004-2008 soeren - All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
*
* http://virtuemart.net
*/
mm_showMyFileName( __FILE__ );
 
require_once(CLASSPATH. 'ps_product.php' );
$ps_product = new ps_product;
require_once(CLASSPATH. 'ps_checkout.php' );
$ps_checkout = new ps_checkout;
require_once(CLASSPATH . 'ps_shipping_method.php' );
 
global $weight_total, $total, $tax_total, $order_tax_details, $discount_factor, $order_total;
 
/* make sure this is the checkout screen */
if ($cart["idx"] == 0) {
	$basket_html = $VM_LANG->_('PHPSHOP_EMPTY_CART');
	$checkout = False;
}
else {
	$checkout = True;
 
	$total = 0;
	// Added for the zone shipping module
	$vars["zone_qty"] = 0;
	$weight_total = 0;
	$weight_subtotal = 0;
	$tax_total = 0;
	$shipping_total = 0;
	$shipping_tax = 0;
	$order_total = 0;
	$discount_before=$discount_after=$show_tax=$shipping=false;
	$product_rows = Array();
 
	for ($i=0;$i<$cart["idx"];$i++) {
		// Added for the zone shipping module
		$vars["zone_qty"] += $cart[$i]["quantity"];
 
		if ($i % 2) $product_rows[$i]['row_color'] = "sectiontableentry2";
		else $product_rows[$i]['row_color'] = "sectiontableentry1";
 
		// Get product parent id if exists
		$product_parent_id=$ps_product->get_field($cart[$i]["product_id"],"product_parent_id");
 
		// Get flypage for this product
        $flypage_id = $product_parent_id;
        if($flypage_id == 0) {
            $flypage_id = $cart[$i]["product_id"];
        }
		$flypage = $ps_product->get_flypage($flypage_id);
        $category_id = vmGet( $cart[$i], 'category_id', 0 );
		// Build URL based on whether item or product
		if ($product_parent_id) {
			$url = $sess->url(URL . basename($_SERVER['PHP_SELF'])."?page=shop.product_details&flypage=$flypage&product_id=$product_parent_id&category_id=$category_id");
		}
		else {
			$url = $sess->url(URL . basename($_SERVER['PHP_SELF'])."?page=shop.product_details&flypage=$flypage&product_id=" . $_SESSION['cart'][$i]["product_id"]."&category_id=$category_id");
		}
 
		$product_rows[$i]['product_name'] = "<a href=\"$url\"><strong>"
		. shopMakeHtmlSafe($ps_product->get_field($_SESSION['cart'][$i]["product_id"], "product_name"))
		. "</strong></a><br />"
		. $ps_product->getDescriptionWithTax( $_SESSION['cart'][$i]["description"], $_SESSION['cart'][$i]["product_id"] );
 
		// Display attribute values if this an item
		$product_rows[$i]['product_attributes'] = "";
		if ($product_parent_id) {
			$db_detail=$ps_product->attribute_sql($cart[$i]["product_id"],$product_parent_id);
			while ($db_detail->next_record()) {
				$product_rows[$i]['product_attributes'] .= "<br />" . $db_detail->f("attribute_name") . "&nbsp;";
				$product_rows[$i]['product_attributes'] .= "(" . $db_detail->f("attribute_value") . ")";
			}
		}
		$product_rows[$i]['product_sku'] = $ps_product->get_field($cart[$i]["product_id"], "product_sku");
 
		/* WEIGHT CALCULATION */
		$weight_subtotal = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
		$weight_total += $weight_subtotal;
 
		/* Product PRICE */
		$my_taxrate = $ps_product->get_product_taxrate($cart[$i]["product_id"], $weight_subtotal);
		$tax = $my_taxrate * 100;
 
		$price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
		$price["product_price"] = $GLOBALS['CURRENCY']->convert( $price["product_price"], $price["product_currency"] );
		
		if( $auth["show_price_including_tax"] == 1 ) {
			$product_price = $price["product_price"] * ($my_taxrate+1);
		} else {
			$product_price = $price["product_price"];
		}
 
		$product_price = round( $product_price, 2 );
		$product_rows[$i]['product_price'] = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($product_price);
 
		/* SUBTOTAL CALCULATION */
		$subtotal = $product_price * $cart[$i]["quantity"];
 
		$total += $subtotal;
		$product_rows[$i]['subtotal'] = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($subtotal);
		$product_rows[$i]['subtotal_with_tax'] = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($subtotal * ($my_taxrate+1));
 
		if (!empty($my_taxrate) && MULTIPLE_TAXRATES_ENABLE=='1') {
 
			if( $auth["show_price_including_tax"] == 1 ) {
				eval( "\$message = \"".$VM_LANG->_('PHPSHOP_INCLUDING_TAX')."\";" );
				$product_rows[$i]['subtotal'] .= "&nbsp;".$message;
			}
			else {
				$product_rows[$i]['subtotal'] .= "&nbsp;(+ $tax% ".$VM_LANG->_('PHPSHOP_CART_TAX').")";
			}
		}
 
		// UPDATE CART / DELETE FROM CART 
		$action_url = $mm_action_url.basename($_SERVER['PHP_SELF']);
		$product_rows[$i]['update_form'] = '<form action="'. $action_url .'" method="post" style="display: inline;">
		<input type="hidden" name="option" value="com_virtuemart" />
		<input type="text" title="'. $VM_LANG->_('PHPSHOP_CART_UPDATE') .'" class="inputbox" size="4" maxlength="4" name="quantity" value="'.$cart[$i]["quantity"].'" />
		<input type="hidden" name="page" value="'. $page .'" />
    <input type="hidden" name="func" value="cartUpdate" />
    <input type="hidden" name="product_id" value="'. $_SESSION['cart'][$i]["product_id"] .'" />
    <input type="hidden" name="prod_id" value="'. $_SESSION['cart'][$i]["product_id"] .'" />
    <input type="hidden" name="Itemid" value="'. $sess->getShopItemid() .'" />
    <input type="hidden" name="description" value="'. stripslashes($cart[$i]["description"]).'" />
    <input type="image" name="update" title="'. $VM_LANG->_('PHPSHOP_CART_UPDATE') .'" src="'. VM_THEMEURL .'images/update_quantity_cart.png" alt="'. $VM_LANG->_('PHPSHOP_UPDATE') .'" align="middle" />
  </form>';
		$product_rows[$i]['delete_form'] = '<form action="'.$action_url.'" method="post" name="delete" style="display: inline;">
    <input type="hidden" name="option" value="com_virtuemart" />
    <input type="hidden" name="page" value="'. $page .'" />
    <input type="hidden" name="Itemid" value="'. $sess->getShopItemid() .'" />
    <input type="hidden" name="func" value="cartDelete" />
    <input type="hidden" name="product_id" value="'. $_SESSION['cart'][$i]["product_id"] .'" />
    <input type="hidden" name="description" value="'. $cart[$i]["description"].'" />
  	<input type="image" name="delete" title="'. $VM_LANG->_('PHPSHOP_CART_DELETE') .'" src="'. VM_THEMEURL .'images/remove_from_cart.png" alt="'. $VM_LANG->_('PHPSHOP_CART_DELETE') .'" align="middle" />
  </form>';
	} // End of for loop through the Cart
	
	vmRequest::setVar( 'zone_qty', $vars['zone_qty'] );
 
	$total = $total_undiscounted = round($total, 5);
	$vars["total"] = $total;
	$subtotal_display = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($total);
 
    if (!empty($_POST["do_coupon"]) || (in_array( strtolower($func), array( 'cartadd', 'cartupdate', 'cartdelete' )) && !empty($_SESSION['coupon_redeemed'])) ) {
        /* process the coupon */
		require_once( CLASSPATH . "ps_coupon.php" );
		$vars["total"] = $total;
		ps_coupon::process_coupon_code( $vars );
 
	}
 
	/* HANDLE SHIPPING COSTS */
	if( !empty($shipping_rate_id) && !ps_checkout::noShippingMethodNecessary() ) {
		$shipping = true;
		$vars["weight"] = $weight_total;
		$shipping_total = round( $ps_checkout->_SHIPPING->get_rate ( $vars ), 5 );
		$shipping_taxrate = $ps_checkout->_SHIPPING->get_tax_rate();
 
		// When the Shipping rate is shown including Tax
		// we have to extract the Tax from the Shipping Total
		if( $auth["show_price_including_tax"] == 1 ) {
			$shipping_tax = round($shipping_total- ($shipping_total / (1+$shipping_taxrate)), 5);
		}
		else {
			$shipping_tax = round($shipping_total * $shipping_taxrate, 5);
		}
 
		$shipping_display = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($shipping_total);
	}
	else {
		$shipping_total = $shipping_taxrate = 0;
		$shipping_display = "";
	}
 
	// COUPON DISCOUNT
	$coupon_display = '';
	if( PSHOP_COUPONS_ENABLE=='1' && @$_SESSION['coupon_redeemed']=="1" && PAYMENT_DISCOUNT_BEFORE=='1') {
 
		$total -= $_SESSION['coupon_discount'];
		$coupon_display = "- ".$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $_SESSION['coupon_discount'] );
		$discount_before=true;
	}
 
	
 
	/* COUPON DISCOUNT */
	if( PSHOP_COUPONS_ENABLE=='1' && @$_SESSION['coupon_redeemed']=="1" && PAYMENT_DISCOUNT_BEFORE != '1') {
		$discount_after=true;
		$total -= $_SESSION['coupon_discount'];
		$coupon_display = "- ".$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $_SESSION['coupon_discount'] );
	}
 
	// Attention: When show_price_including_tax is 1,
	// we already have an order_total including the Tax!
	if( $auth["show_price_including_tax"] == 0 ) {
		$order_total += $tax_total;
		$total_undiscounted += $tax_total;
	}
	$order_total += $shipping_total + $total;
	$total_undiscounted += $shipping_total;
 
 
 
	/* check if the minimum purchase order value has already been reached */
	if( !defined( '_MIN_POV_REACHED' )) {
		if (round($_SESSION['minimum_pov'], 2) > 0.00) {
			if ($total_undiscounted >= $GLOBALS['CURRENCY']->convert( $_SESSION['minimum_pov'] )) {
				// OKAY!
				define ('_MIN_POV_REACHED', '1');
			}
		} else {
			define ('_MIN_POV_REACHED', '1');
		}
	}
	
	$order_total_display = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($order_total);
	
	$tpl = new $GLOBALS['VM_THEMECLASS']();
	$tpl->set_vars( Array(
								'product_rows' => $product_rows,
								'subtotal_display' => $subtotal_display,
								'discount_before' => $discount_before,
								'discount_after' => $discount_after,
								'coupon_display' => $coupon_display,
								'shipping' => $shipping,
								'shipping_display' => $shipping_display,
								'show_tax' => $show_tax,
								'tax_display' => $tax_display,
								'order_total_display' => $order_total_display,
				));
	$basket_html = '';
	if( $show_basket ) {
		
		if( $auth["show_price_including_tax"] == 1) {
			$basket_html = $tpl->fetch( 'basket/basket_b2c.html.php');			
		}
		else {
			$basket_html = $tpl->fetch( 'basket/basket_b2b.html.php');
		}
	}
	/* Input Field for the Coupon Code */
	if( PSHOP_COUPONS_ENABLE=='1'
		&& !@$_SESSION['coupon_redeemed']
		//&& ($page == "shop.cart" )
	) {
		$basket_html .= $tpl->fetch( 'common/couponField.tpl.php' );
	}
}
 
?>

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:

Select allOpen in new window

 

by: RQuadlingPosted on 2009-06-19 at 01:37:34ID: 24664663

Nothing is remembered from 1 page to the next unless you do it. You should be logging all the calcs from each page so they don't need to be done each time.

But ..

$shipping_total = round( $ps_checkout->_SHIPPING->get_rate ( $vars ), 5 );

Is missing the country, so you need to supply that.

 

by: kennedypd1Posted on 2009-06-19 at 04:17:19ID: 24665333

Hi

Sorry if this is a dumb question but why would I need to supply that info when the shipping price is in the link.

I have bolded the correct price and the API states

The shipping rate, a user has selected during checkout is passed from step to step by the parameter shipping_rate_id.

This parameter follows a strcit syntax and must be a string build like this:

ShippingClassName|carrier_name|rate_name|totalshippingcosts|rate_id


http://www.orahoney.co.nz/index.php?page=checkout.index&payment_method_id=19&ship_to_info_id=daa0f8442b4a9f152b5321c20dea8fa8&shipping_rate_id=item_ship%257CSTD%257CStandard%2BShipping%257C14.5%257C14.5&checkout_stage=4&option=com_virtuemart&Itemid=1

Sorry to be a pain

 

by: RQuadlingPosted on 2009-06-19 at 04:26:44ID: 24665370

On the page processing the data, is it calling the get_rate() function?

If it is, then it is trying to recalculate the shipping value.

If this is all your own site, then store the data in the session. Much easier.

What would happen if I created a URL with the shipping value set to -10.00 (for example)?

 

by: RQuadlingPosted on 2009-07-12 at 00:41:08ID: 24833557

I'm waiting on a reply. I'd like to know where kennedypd1 is upto.

 

by: kennedypd1Posted on 2009-07-12 at 03:49:14ID: 24833923

Hi Sorry

I got very confussed about all of this and started learning a lot of PHP and adapting the files for the cart.
I was getting very close when the client made contact and changed their shipping charges which has changed everything again.

RQuadling was fantastic in pointing me in the right direction and I thank him for his help and guidence.

Cheers
Paul

 

by: RQuadlingPosted on 2009-07-13 at 03:45:29ID: 24838533

Ha. Clients and the art of shifting goal posts.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...