[ic] Shipping... please help! ;-)

Interchange user interchange-users@icdevgroup.org
Mon Feb 17 13:04:01 2003


On Sunday 16 February 2003 12:40 pm, you wrote:
> I posted a question a while back but received no responses; perhaps I
> wasn't being clear enough.
>
> All I want to do is select the correct price for shipping based on:
>
> a)  Country (either UK or non-UK)
> b)  Weight (set prices within given boundaries, eg. £2 for < 1kg)
>
> I have tried searching the archives and reading the docs but couldn't find
> anything directly relevant.  If anybody has done anything at all similar,
> perhaps you could just send me the relevant file or something?
>
> Cheers,
>
> Jon


Yep, I've done something like that. I coded the following UserTag to do the 
job:


UserTag calc_shipping Order weight country
UserTag calc_shipping Routine <<EOF
sub {
    my ($weight, $country) = @_;

    my $zone = $Tag->query( { sql => "SELECT zone FROM country WHERE code = 
'$country'",
                              wantarray => 1 } );
    $zone = 'zone'.$zone->[0]->[0];

    my %qty_req_packtype;

    for (@$Items) {
      my $packtype = $Tag->query( { sql => "SELECT packaging_type FROM 
products WHERE sku = '$_->{code}'",
                                    wantarray => 1 } );
      $packtype = $packtype->[0]->[0];

      $qty_req_packtype{$packtype} += $_->{quantity};
    }

    my $packaging_charge = 0;

    for (keys %qty_req_packtype) {
      my $price = $Tag->query( { sql => "SELECT price FROM packaging WHERE 
description = '$_'",
                                 wantarray => 1 } );
      $price = $price->[0]->[0];

      my $pack_weight = $Tag->query( { sql => "SELECT weight FROM packaging 
WHERE description = '$_'",
                                  wantarray => 1 } );
      $pack_weight = $pack_weight->[0]->[0];

      my $items_per_packtype = $Tag->query( { sql => "SELECT items FROM 
packaging WHERE description = '$_'",
                                              wantarray => 1 } );
      $items_per_packtype = $items_per_packtype->[0]->[0];

      my $required = $qty_req_packtype{$_} / $items_per_packtype;
      if($qty_req_packtype{$_} % $items_per_packtype)
      {
        $required++;
        $required = int($required);
      }
      $packaging_charge += $required * $price;

      $weight += $required * $pack_weight;
    }

    my $shipping_charge = 0;

    if ($country eq 'UK') {    
      if ($weight>1000) {
        my $tmp = $weight - 1000;
        my $counter = $tmp / 250;
        if($tmp % 250)
        {
          $counter++;
          $counter = int($counter);
        }
        $shipping_charge = 3.49 + $counter * 0.85;
      }
      else {
        $shipping_charge = $Tag->query( { sql => "SELECT $zone FROM shipping 
WHERE $weight >= min_weight AND $weight <= max_weight",
                                          wantarray => 1 } );
        $shipping_charge = $shipping_charge->[0]->[0];
      }
    }
    else {
        $shipping_charge = $Tag->query( { sql => "SELECT $zone FROM 
int_shipping WHERE $weight >= min_weight AND $weight <= max_weight",
                                          wantarray => 1 } );
        $shipping_charge = $shipping_charge->[0]->[0];
    }

    return $shipping_charge + $packaging_charge;
    }
EOF


Of course, you'll also need to update your products/shipping.asc file, create 
the new database tables 'shipping', 'int_shipping' & 'packaging', and add 
'zone' and 'packaging_type' columns to the country and products tables, 
respectively. Also update the definition files in dbconf/ so the admin 
interface will use the changes.

Hope that helps (so you don't have to suffer the blood, sweat, and tears that 
I went through!).