[ic] ups_cache expires
Steve Graham
icdev at mrlock.com
Mon Feb 6 16:22:20 EST 2006
At 10:06 AM 2/3/2006, you wrote:
>>Patches are always welcome! 8-)
>>
>> >
>> > I know this is not really an issue on 1 day cache expire, but with
>> > expire set to 30+ days - it will add up.
>>
>>It also cuts down unnecessary traffic. +1.
>>
>>--
>>Mike Heins
Hello List,
Here is the QueryUPS.pm complete file with suggested modifications:
Changes I suggest:
1 - make sure the weight is rounded up to next whole value - UPS &
our cache table need whole numbers.
2 - Only store & search the cache table for the 1st three digits of
the zip code. (Saves alot of data entry)
3 - If the cache result is old, and for some reason www UPS fails to
return data - then use the old value.
4 - If the zip code is not in the cache, and UPS returns data, but
the shipping amount < 0.00 then don't store it in the table.
I do have a record of this happening.
Comments???
Steve Graham
Code Starts after this line >>>>>
package Vend::Ship::QueryUPS;
use Vend::Util;
use Vend::Interpolate;
use Vend::Data;
use Vend::Ship;
use Business::UPS;
sub calculate {
my ($mode, $weight, $row, $opt, $tagopt, $extra) = @_;
my $tmp_weight;
my $zip5;
# force weight up to next pound.
# At present UPS only uses weights rounded to next pound.
$tmp_weight = int($weight);
if ($tmp_weight < $weight) {
$weight = $tmp_weight + 1;
}
$opt->{service} ||= $opt->{table};
if(! $opt->{service} and $extra =~ /^\w+$/) {
$opt->{service} = $extra;
}
$opt->{service} ||= $opt->{table} || $mode;
$opt->{origin} ||= $::Variable->{UPS_ORIGIN};
$opt->{country_field} ||= $::Variable->{UPS_COUNTRY_FIELD}
|| 'country';
$opt->{geo} ||=
$::Variable->{UPS_POSTCODE_FIELD} || 'zip';
my $origin = $opt->{origin};
my $country = $opt->{country} || $::Values->{$opt->{country_field}};
$country ||= $opt->{default_country} || 'US';
my $zip = $opt->{zip} || $::Values->{$opt->{geo}};
$zip ||= $opt->{default_geo};
my $modulo = $opt->{aggregate};
if($modulo and $modulo <= 1) {
$modulo = $::Variable->{UPS_QUERY_MODULO} || 150;
}
elsif(! $modulo) {
$modulo = 9999999;
}
$country = uc $country;
my %exception = ( UK => 'GB');
if(! $::Variable->{UPS_COUNTRY_REMAP} ) {
# do nothing
}
elsif ($::Variable->{UPS_COUNTRY_REMAP} =~ /=/) {
my $new =
Vend::Util::get_option_hash($::Variable->{UPS_COUNTRY_REMAP});
Vend::Util::get_option_hash(\%exception, $new);
}
else {
Vend::Util::hash_string($::Variable->{UPS_COUNTRY_REMAP},
\%exception);
}
$country = $exception{$country} if $exception{$country};
# In the U.S., UPS only wants the 5-digit base ZIP code, not ZIP+4
$country eq 'US' and $zip =~ /^(\d{5})/ and $zip = $1;
$zip5 = $zip;
$country eq 'US' and $zip =~ /^(\d{3})/ and $zip = $1;
#::logDebug("calling QueryUPS with: " . join("|", $opt->{service},
$origin, $zip, $weight, $country,$modulo));
my $cache;
my $cache_code;
my $db;
my $now;
my $updated;
my %cline;
my $shipping;
my $tmp_shipping;
my $zone;
my $error;
my $ctable = $opt->{cache_table} || 'ups_cache';
if($Vend::Database{$ctable}) {
$Vend::WriteDatabase{$ctable} = 1;
CACHE: {
$db = dbref($ctable)
or last CACHE;
my $tname = $db->name();
$cache = 1;
%cline = (
weight => $weight,
origin => $origin,
country => $country,
zip => $zip,
shipmode => $opt->{service},
);
my @items;
# reverse sort makes zip first
for(reverse sort keys %cline) {
push @items, "$_ = " .
$db->quote($cline{$_}, $_);
}
my $string = join " AND ", @items;
my $q = qq{SELECT code,cost,updated from
$tname WHERE $string};
my $ary = $db->query($q);
#::logDebug("query cache: " . ::uneval($ary));
if($ary and $ary->[0] and $cache_code =
$ary->[0][0]) {
$shipping = $ary->[0][1];
$updated = $ary->[0][2];
$now = time();
if($now - $updated > 1204000) {
$tmp_shipping = $shipping;
undef $shipping;
$updated = $now;
}
elsif($shipping <= 0) {
$error = $shipping;
$updated = $now;
$shipping = 0;
}
}
#::logDebug("shipping is: " . (defined $shipping ? $shipping : 'undef'));
}
}
my $w = $weight;
my $maxcost;
my $tmpcost;
unless(defined $shipping) {
$shipping = 0;
while($w > $modulo) {
$w -= $modulo;
if($maxcost) {
$shipping += $maxcost;
next;
}
($maxcost, $zone, $error)
= getUPS( $opt->{service}, $origin,
$zip5, $modulo, $country);
if($error) {
do_error( "Ship mode %s: Error
calling UPS service %s",
$mode,
$opt->{service}, );
return 0;
}
$shipping += $maxcost;
}
undef $error;
#::logDebug("calling getUPS( $opt->{service}, $origin, $zip5, $w, $country)");
($tmpcost, $zone, $error)
= getUPS( $opt->{service}, $origin, $zip5,
$w, $country);
$shipping += $tmpcost;
# Only store it if shipping >0
# I have found a few entries with the shipping amount
missing for some reason.
# with no error returned from UPS. Only store if shipping>0
if ($shipping > 0){
if($cache) {
$cline{updated} = $now || time();
$cline{cost} = $shipping || $error;
$db->set_slice($cache_code, \%cline);
}
}
}
if($error) {
do_error( "Ship mode %s: Error calling UPS service %s",
$mode,
$opt->{service}, );
$shipping = 0;
}
if ($shipping <=0) {
# if for some reason ups www fails, as it does occasionally
# and we have an old cache_value - Use it!!
if ($tmp_shipping>0) {
$shipping = $tmp_shipping; }
}
return $shipping;
}
More information about the interchange-users
mailing list