php shipping by weight

1 view
Skip to first unread message

jasdix

unread,
May 12, 2009, 10:29:06 AM5/12/09
to phpShop
Hi All,

really struggling to get the shipping sorted on phpshop,

I'd like to ship by weight of products in the cart

you know if weight is 3 kg shipping price £10
6kg £20

if possible by two zones uk and rest of the world

where do i start, i have tried modifying the ps checkout.inc

can anyone help me with the code on this and where to modify the
existing

many thanks in advance for any info you could provide me with

jasdix

Jeff Newman

unread,
May 12, 2009, 3:41:13 PM5/12/09
to php...@googlegroups.com
i'll be honest - i don't use the shipping mechanism as it doesn't really
ever seem to be the way people want to charge for it. however, i can
probably help.

i'm going to review then spell out the solution.

review.

the basket sums up the quantity of items purchased. this is passed to the
checkout process, where it's used to find the zone the customer is in, and
multiplies the per-item shipping cost (from the zone info) times the number
of items purchased. that's checked against the zone upper limit, and
adjusted if necessary.

spelled out.

i say we use the system as is, but convert it for our own needs.

first, lets add the weight of the products to the cart so we don't have to
keep finding it later:

in "shop/lib/ps_cart.inc", function add_item:

add product_weight to the SELECT statement, and assign a $weight value (else
statement)
[code]
$q = "SELECT product_name,product_publish, product_weight FROM product WHERE
product_id='$product_id'";
$db->query($q);
$db->next_record();
// if the product isn't publishable, don't allow the add or update
if ('N' == $db->f("product_publish") ) {
// set your "not available" error message here
$d["error"] = "We're sorry but ".$db->f("product_name")." is not
available at this time.";
// when in ps_cart->update, you probably want to uncomment
// the line below to remove the product from the cart
//$this->delete($d);
return False;
} else {
$weight = $db->f("product_weight");
} //end if prodcut_publish
[/code]

add the weight to the cart at the end of the function:
[code]
if (!$updated) {
$cart[$cart["idx"]]["product_id"] = $product_id;
$cart[$cart["idx"]]["quantity"] = $quantity;
$cart[$cart["idx"]]["weight"] = $weight;
$cart["idx"]++;
}
[/code]

in "shop/html/basket.ihtml", search for zone_quantity. you'll see it sums
up the cart quantities:

[code]
$zone_qty += $cart[$i]["quantity"];
[/code]

change it to:

[code]
$zone_qty += $cart[$i]["quantity"] * $cart[$i]["weight"];
[/code]

this will give us the total weight of the order.

in "checkout/lib/ps_checkout.inc", calc_order_shipping function:

comment out the last IF statement - this will disable the "upper limit"
check.
[code]
/**********************
if($cost_low < $db3->f("zone_limit")) {
return $cost_low;
} else {
return $db3->f("zone_limit");
}
**********************/
[/code]

now, the only things left to do is fix the zones within the system and
assign the zones..

log in as admin.

edit the default zone, and enter your per-pound price for non-UK shipping.
might as well enter it in both fields.

edit zone1 - change the pricing here to your "UK" pricing. same number,
both fields.

now go to Assign Zones, and make sure every country is set to default, then
set the UK to zone1. save your changes.

that should do it.
NOTE: for products that have no weight assigned to them, shipping will be
free. that makes it an easy way to do "Free Shipping!" as needed, and you
could even throw a little check in the flypage and browse pages to check for
"no weight" and a have it display a little banner or blurb or something.

NOTE: using the weight is also a great way to do this because you can use a
set shipping costs, but then adjust shipping on a per-item basis just by
playing with the weight. have a large box that weighs almost nothing, but
still costs $30 to ship? just jack up the weight, and the shipping price
gets adjusted as well.
--------------------------------------------------------------------------------



No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.329 / Virus Database: 270.12.26/2110 - Release Date: 05/12/09
06:22:00

Jeff Newman

unread,
May 16, 2009, 11:19:35 AM5/16/09
to php...@googlegroups.com
there are a couple of additions that need to be made to these instructions:

1. the "basket.ihtml" modification needs to be done to the "ro_basket.ihtml
file as well".

2. need to make one more modification to "ro_basket.ihtml":

[code]
$order_shipping = $ps_zone->get_rate($vars);
[/code]

needs to be changed to:

[code]
$order_shipping = $ps_zone->get_rate($vars) * $zone_qty;
[/code]


----- Updated Instructions -----
in "shop/html/basket.ihtml" and "shop/html/ro_basket.ihtml" files, search
for zone_quantity.
you'll see it sums up the cart quantities:

[code]
$zone_qty += $cart[$i]["quantity"];
[/code]

change it to:

[code]
$zone_qty += $cart[$i]["quantity"] * $cart[$i]["weight"];
[/code]

this will give us the total weight of the order.
do the same modification to "shop/html/ro_basket.ihtml" as above.
then one more modification needs to be made to "ro_basket.ihtml", near the
end of the file:

[code]
$order_shipping = $ps_zone->get_rate($vars);
[/code]

needs to be changed to:

[code]
$order_shipping = $ps_zone->get_rate($vars) * $zone_qty;
[/code]

Jeff Newman

unread,
May 16, 2009, 11:50:46 AM5/16/09
to php...@googlegroups.com
i'm going to make a comment here about the "by weight" method.

it pointed out that the ps_zone->get_rate function and the
ps_checkout->calc_order_shipping functions are identical - they both find
the same thing, the shipping cost. the problem is that i didn't catch this
call, so it wasn't updated. it should have the same fixes applied to it
that cal_order_shipping had to it.

however, with the instructions and updates i gave, by entering the same
per-weight cost in both of the zone fields, it will still work, because the
same value will be returned either way, and the final shipping cost will be
calc'd correctly.

that said, i'm going to issue these final instructions, and call them good.
they modify both function calls, and remove the " * $zone_qty" that i added
to the ro_basket file.

it's the way it should be done, but there are always two paths to a final
destination. i just end up on the bumpy route, thats all.

----- Final, The-Real-Deal Instructions -----

review.

spelled out.

change it to:

in "checkout/lib/ps_checkout.inc", calc_order_shipping function:

comment out the last IF statement - this will disable the "upper limit"
check.
[code]
/**********************
if($cost_low < $db3->f("zone_limit")) {
return $cost_low;
} else {
return $db3->f("zone_limit");
}
**********************/
[/code]

do the same modification to "zone/lib/ps_zone.inc", the get_rate function as
above.

Jeff Newman

unread,
May 18, 2009, 8:53:50 AM5/18/09
to php...@googlegroups.com
okay, found an error in my editing.

in ps_zone.inc and ps_checkout.inc, when you comment out the last if
statement from the get_rate and calc_order_shipping functions respectively,
you do need to copy out the following statement and place it outside the
comments just before the end of the function:

return $cost_low;

otherwise, the function returns nothing, and shipping will always be zero!

so it should read:

[code]
/**********************
if($cost_low < $db3->f("zone_limit")) {
return $cost_low;
} else {
return $db3->f("zone_limit");
}
**********************/

return $cost_low;
[/code]

sorry for the error.
--------------------------------------------------------------------------------



No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.329 / Virus Database: 270.12.32/2117 - Release Date: 05/15/09
17:55:00

Reply all
Reply to author
Forward
0 new messages