[ic] Alternative shipping calculation (suitable for international shipping too)

Dmitrij Schmunk dmitrijs at online.sinor.ru
Tue Aug 19 20:45:18 EDT 2003


Hello interchange-users,

Here is the alternative solution that I've developed after long hours browsing this forum
and numerious attempts to make ups-type lookup working the way I needed:

- use more then one criteria in shipping cost calculation (e.g. weight _and_ subtotal)
- handle weights in 0.5 kg increments, not 1 kg or 1 lb


Put this in your catalog.cfg:
-----------------------------
# shipcalc UserTag to calculate shipping charges
# similar to UPS-type lookup
# - handles 0.5 kg increments
# - could be used in 'f formula' expressions in shipping.asc file
#
UserTag shipcalc Order destzip weight zonestab pricestab ziplen
UserTag shipcalc Routine <<EOR
sub {
    my($destzip,$weight,$zonestab,$pricestab,$ziplen) = @_;
        my($zone,$intweight,$out);
    my(@data);

    # search supplied zones table for destination zip code
    my $file = Vend::Util::catfile($Vend::Cfg->{ProductDir},$zonestab);
        my $zones = readfile($file);
        my @zdata = split /\n/, $zones;

        my $zip = substr($destzip, 0, $ziplen);

        for(@zdata) {
                @data = split /\t/, $_;
                next unless ($zip ge $data[0] and $zip le $data[1]);
                $zone = $data[2];
                return 0 unless $zone;
                last;
        }

    # extract pricing by weight
    $intweight = POSIX::ceil(2*$weight)/2;
    $out = $Tag->data($pricestab, $zone, $intweight);
    if (!$out) {  # if no line with fractional weight is found
        $intweight = POSIX::ceil($weight);
        $out = $Tag->data($pricestab, $zone, $intweight);
    }
    return $out;
}
EOR
-----------------------------
My usertag implementation might be not the best since my knowledge of Perl
and Interchange is very limited. Feel free to improve it.
All fields (destzip weight zonestab pricestab ziplen) should be present, there are
no default vaules!


Here is the example from my shipping.asc
-----------------------------
SPCOD: SPSR, Cash On Delivery
        criteria        weight

        min     0
        max     0
        cost    e Nothing to ship!

        min     0
        max     30
        cost    f my $add = [subtotal noformat=1] * 0.1; ($add < 3 ? 3 : $add) + [shipcalc destzip="[either][value zip][or][var SHIP_DEFAULT_ZIP][/either]" weight=@@TOTAL@@ zonestab="spsr_zones.tab" pricestab="SPSR" ziplen=4]

        min     30
        max     999999
        cost    e @@TOTAL@@ kg too heavy for SPSR
-----------------------------
The above extracts shipping charge basing on zone information(spsr_zones.tab),
similarly to UPS lookup and adds either $3 or 10% of subtotal, depending on what number
is higher.


spsr_zones.tab should be placed in /products subdirectory.
It contains tab-delimited (unlike comma-delimited ups zone files) fields.
First two columns are zip range, last column is correpondent zone
-----------------------------
1000    1399    23
1400    1499    3
1500    1500    5
1505    1529    15
1530    1530    5
1535    1559    7
1560    1560    9
1565    1579    4
1600    1600    6
... etc.
-----------------------------

You also have to add 'Database PRICETABLE PRICETABLE.csv CSV' into catalog.cfg.
Replace 'PRICETABLE' with the name of your weight:zone to price translation table (the same format
as used in UPS lookup):
-----------------------------
Exceed,1,2,3,4
0.5,7.8,10.2,13.08,17.16
1,8.4,11.4,14.4,20.04
2,10.32,13.08,17.16,23.04
3,11.88,14.88,14.88,25.8
etc...
-----------------------------


For international shippings I'm using the same scheme with isonum field from 'country' table
taken instead of zip. Like this:
[shipcalc destzip="[data table=country key='[default country US]' col=isonum]" weight=@@TOTAL@@ zonestab="xprr_zones.tab" pricestab="XPRR" ziplen=3]

'country' variable is from checkout.html
xprr_zones.tab contain isonum's in first two columns in this case:
-----------------------------
036     036     5
040     040     2
031     031     1
008     008     3
012     012     6
850     850     7
016     016     7
etc...
-----------------------------


Hopefully this was helpful...


-- 
Best regards,
 Dmitrij                          mailto:dmitrijs at online.sinor.ru
---
There are only 10 types of people in the world: those who understand binary and those who don't.



More information about the interchange-users mailing list