Update USPS International driver to V2 API and fix insurance.

This commit is contained in:
Colin Kuskie 2014-11-10 14:48:02 -05:00
parent 386e718c8a
commit 720284f947
2 changed files with 82 additions and 43 deletions

View file

@ -48,9 +48,10 @@ result by the quantity, rather than doing several identical checks.
sub buildXML { sub buildXML {
my ($self, $cart, @packages) = @_; my ($self, $cart, @packages) = @_;
tie my %xmlHash, 'Tie::IxHash'; tie my %xmlHash, 'Tie::IxHash';
%xmlHash = ( IntlRateRequest => {}, ); %xmlHash = ( IntlRateV2Request => {}, );
my $xmlTop = $xmlHash{IntlRateRequest}; my $xmlTop = $xmlHash{IntlRateV2Request};
$xmlTop->{USERID} = $self->get('userId'); $xmlTop->{USERID} = $self->get('userId');
$xmlTop->{Revision} = ['2'];
$xmlTop->{Package} = []; $xmlTop->{Package} = [];
##Do a request for each package. ##Do a request for each package.
my $packageIndex; my $packageIndex;
@ -86,10 +87,20 @@ sub buildXML {
$packageData{Ounces} = [ $ounces ]; $packageData{Ounces} = [ $ounces ];
$packageData{Machinable} = [ 'true' ]; $packageData{Machinable} = [ 'true' ];
$packageData{MailType} = [ 'Package' ]; $packageData{MailType} = [ 'Package' ];
if ($self->get('addInsurance')) { $packageData{ValueOfContents} = [ $value ];
$packageData{ValueOfContents} = [ $value ];
}
$packageData{Country} = [ $country ]; $packageData{Country} = [ $country ];
$packageData{Container} = [ 'RECTANGULAR' ];
$packageData{Size} = [ 'REGULAR' ];
$packageData{Width} = [ '1.0' ];
$packageData{Length} = [ '1.0' ];
$packageData{Height} = [ '1.0' ];
$packageData{Girth} = [ '4.0' ];
if ($self->get('addInsurance')) {
$packageData{ExtraServices} = [
{ ExtraService => [ '1' ], },
];
}
push @{ $xmlTop->{Package} }, \%packageData; push @{ $xmlTop->{Package} }, \%packageData;
} }
my $xml = XMLout(\%xmlHash, my $xml = XMLout(\%xmlHash,
@ -168,7 +179,7 @@ Processed XML data from an XML rate request, processed in perl data structure.
have this structure: have this structure:
{ {
IntlRateResponse => { IntlRateV2Response => {
Package => [ Package => [
{ {
ID => 0, ID => 0,
@ -189,7 +200,7 @@ The set of shippable units, which are required to do quantity lookups.
sub _calculateFromXML { sub _calculateFromXML {
my ($self, $xmlData, @shippableUnits) = @_; my ($self, $xmlData, @shippableUnits) = @_;
my $cost = 0; my $cost = 0;
foreach my $package (@{ $xmlData->{IntlRateResponse}->{Package} }) { foreach my $package (@{ $xmlData->{IntlRateV2Response}->{Package} }) {
my $id = $package->{ID}; my $id = $package->{ID};
##Error check for invalid index ##Error check for invalid index
if ($id < 0 || $id > $#shippableUnits || $id !~ /^\d+$/) { if ($id < 0 || $id > $#shippableUnits || $id !~ /^\d+$/) {
@ -203,11 +214,9 @@ sub _calculateFromXML {
SERVICE: foreach my $service (@{ $package->{Service} }) { SERVICE: foreach my $service (@{ $package->{Service} }) {
next SERVICE unless $service->{ID} eq $self->get('shipType'); next SERVICE unless $service->{ID} eq $self->get('shipType');
$rate = $service->{Postage}; $rate = $service->{Postage};
#print Dumper $service;
if ($self->get('addInsurance')) { if ($self->get('addInsurance')) {
if (exists $service->{InsComment}) { $rate += $service->{ExtraServices}->{ExtraService}->{Price};
WebGUI::Error::Shop::RemoteShippingRate->throw(error => "No insurance because of: ".$service->{InsComment});
}
$rate += $service->{Insurance};
} }
} }
if (!$rate) { if (!$rate) {
@ -357,7 +366,7 @@ sub _doXmlRequest {
$userAgent->env_proxy; $userAgent->env_proxy;
$userAgent->agent('WebGUI'); $userAgent->agent('WebGUI');
$userAgent->timeout('45'); $userAgent->timeout('45');
my $url = 'http://production.shippingapis.com/ShippingAPI.dll?API=IntlRate&XML='; my $url = 'http://production.shippingapis.com/ShippingAPI.dll?API=IntlRateV2&XML=';
$url .= $xml; $url .= $xml;
my $request = HTTP::Request->new(GET => $url); my $request = HTTP::Request->new(GET => $url);
my $response = $userAgent->request($request); my $response = $userAgent->request($request);

View file

@ -25,7 +25,7 @@ use WebGUI::Test; # Must use this before any other WebGUI modules
use WebGUI::Session; use WebGUI::Session;
use WebGUI::Shop::ShipDriver::USPSInternational; use WebGUI::Shop::ShipDriver::USPSInternational;
plan tests => 40; plan tests => 41;
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Init # Init
@ -284,7 +284,7 @@ $rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $
my @shippableUnits = $driver->_getShippableUnits($cart); my @shippableUnits = $driver->_getShippableUnits($cart);
my $xml = $driver->buildXML($cart, @shippableUnits); my $xml = $driver->buildXML($cart, @shippableUnits);
like($xml, qr/<IntlRateRequest USERID="[^"]+"/, 'buildXML: checking userId is an attribute of the IntlRateRequest tag'); like($xml, qr/<IntlRateV2Request USERID="[^"]+"/, 'buildXML: checking userId is an attribute of the IntlRateV2Request tag');
like($xml, qr/<Package ID="0"/, 'buildXML: checking ID is an attribute of the Package tag'); like($xml, qr/<Package ID="0"/, 'buildXML: checking ID is an attribute of the Package tag');
my $xmlData = XMLin($xml, my $xmlData = XMLin($xml,
@ -294,14 +294,18 @@ my $xmlData = XMLin($xml,
cmp_deeply( cmp_deeply(
$xmlData, $xmlData,
{ {
IntlRateRequest => { IntlRateV2Request => {
USERID => $userId, USERID => $userId,
Revision => '2',
Package => [ Package => [
{ {
ID => 0, ID => 0,
Pounds => '1', Ounces => '8.0', Pounds => '1', Ounces => '8.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '7.50',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
], ],
} }
@ -309,7 +313,7 @@ cmp_deeply(
'buildXML: 1 item in cart' 'buildXML: 1 item in cart'
); );
like($xml, qr/IntlRateRequest USERID.+?Package ID=.+?Pounds.+?Ounces.+?Machinable.+?MailType.+?Country.+?/, '... and tag order'); like($xml, qr/IntlRateV2Request USERID.+?Package ID=.+?Pounds.+?Ounces.+?Machinable.+?MailType.+?Country.+?/, '... and tag order');
SKIP: { SKIP: {
@ -327,31 +331,26 @@ SKIP: {
AreasServed => ignore(), Prohibitions => ignore(), AreasServed => ignore(), Prohibitions => ignore(),
ExpressMail => ignore(), CustomsForms => ignore(), ExpressMail => ignore(), CustomsForms => ignore(),
Observations => ignore(), Restrictions => ignore(), Observations => ignore(), Restrictions => ignore(),
AdditionalRestrictions => ignore(),
Service => superbagof( Service => superbagof(
{ superhashof({
ID => ignore(), ID => 1,
MaxWeight => ignore(), Ounces => '8.0',
MaxDimensions => ignore(),
MailType => 'Package',
Ounces => '8',
Pounds => '1', Pounds => '1',
Country => 'NETHERLANDS', Country => 'NETHERLANDS',
Machinable => 'true',
Postage => num(100,99), Postage => num(100,99),
SvcCommitments => ignore(), }),
SvcDescription => ignore(),
},
), ),
}, },
], ],
}, },
'... returned data from USPS in correct format. If this test fails, the driver may need to be updated' '... returned data from USPS in correct format. If this test fails, the driver may need to be updated'
) or diag Dumper $xmlData; ) or diag $xml."\n".$response->content."\n".Dumper($xmlData);
} }
my $cost = $driver->_calculateFromXML( my $cost = $driver->_calculateFromXML(
{ {
IntlRateResponse => { IntlRateV2Response => {
Package => [ Package => [
{ {
ID => 0, ID => 0,
@ -388,20 +387,27 @@ $xmlData = XMLin( $xml,
cmp_deeply( cmp_deeply(
$xmlData, $xmlData,
{ {
IntlRateRequest => { IntlRateV2Request => {
USERID => $userId, USERID => $userId,
Revision => '2',
Package => [ Package => [
{ {
ID => 0, ID => 0,
Pounds => '2', Ounces => '0.0', Pounds => '2', Ounces => '0.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '22.50',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
{ {
ID => 1, ID => 1,
Pounds => '1', Ounces => '8.0', Pounds => '1', Ounces => '8.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '7.50',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
], ],
} }
@ -419,7 +425,7 @@ SKIP: {
$cost = $driver->_calculateFromXML( $cost = $driver->_calculateFromXML(
{ {
IntlRateResponse => { IntlRateV2Response => {
Package => [ Package => [
{ {
ID => 0, ID => 0,
@ -464,7 +470,7 @@ $bibleItem->setQuantity(2);
$cost = $driver->_calculateFromXML( $cost = $driver->_calculateFromXML(
{ {
IntlRateResponse => { IntlRateV2Response => {
Package => [ Package => [
{ {
ID => 0, ID => 0,
@ -516,26 +522,36 @@ $xmlData = XMLin( $xml,
cmp_deeply( cmp_deeply(
$xmlData, $xmlData,
{ {
IntlRateRequest => { IntlRateV2Request => {
USERID => $userId, USERID => $userId,
Revision => '2',
Package => [ Package => [
{ {
ID => 0, ID => 0,
Pounds => '2', Ounces => '0.0', Pounds => '2', Ounces => '0.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '22.50',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
{ {
ID => 1, ID => 1,
Pounds => '12', Ounces => '0.0', Pounds => '12', Ounces => '0.0',
Machinable => 'true', Country => 'Australia', Machinable => 'true', Country => 'Australia',
MailType => 'Package', MailType => 'Package', ValueOfContents => '19.99',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
{ {
ID => 2, ID => 2,
Pounds => '1', Ounces => '8.0', Pounds => '1', Ounces => '8.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '7.50',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
], ],
} }
@ -571,14 +587,18 @@ $xmlData = XMLin($xml,
cmp_deeply( cmp_deeply(
$xmlData, $xmlData,
{ {
IntlRateRequest => { IntlRateV2Request => {
USERID => $userId, USERID => $userId,
Revision => '2',
Package => [ Package => [
{ {
ID => 0, ID => 0,
Pounds => '0', Ounces => '0.1', Pounds => '0', Ounces => '0.1',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', MailType => 'Package', ValueOfContents => '0.01',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
}, },
], ],
} }
@ -635,6 +655,7 @@ SKIP: {
$cart->empty; $cart->empty;
$properties = $driver->get(); $properties = $driver->get();
$properties->{shipType} = '9'; $properties->{shipType} = '9';
$properties->{addInsurance} = 0;
$driver->update($properties); $driver->update($properties);
$rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $bigHammer)); $rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $bigHammer));
@ -653,21 +674,30 @@ SKIP: {
cmp_deeply( cmp_deeply(
$xmlData, $xmlData,
{ {
IntlRateRequest => { IntlRateV2Request => {
USERID => $userId, USERID => $userId,
Revision => '2',
Package => [ Package => [
{ {
ID => 0, ID => 0,
Pounds => '12', Ounces => '0.0', Pounds => '12', Ounces => '0.0',
Machinable => 'true', Country => 'Netherlands', Machinable => 'true', Country => 'Netherlands',
MailType => 'Package', ValueOfContents => '19.99', MailType => 'Package', ValueOfContents => '19.99',
Size => 'REGULAR', Container => 'RECTANGULAR',
Length => '1.0', Width => '1.0',
Height => '1.0', Girth => '4.0',
ExtraServices => {ExtraService => 1},
}, },
], ],
} }
}, },
'buildXML: 1 item in cart' 'buildXML: 1 item in cart'
); );
like($xml, qr/IntlRateRequest USERID.+?Package ID=.+?Pounds.+?Ounces.+?Machinable.+?MailType.+?ValueOfContents.+?Country.+?/, '... and tag order'); like($xml, qr/IntlRateV2Request USERID.+?Package ID=.+?Pounds.+?Ounces.+?Machinable.+?MailType.+?ValueOfContents.+?Country.+?/, '... and tag order');
my $response = $driver->_doXmlRequest($xml);
ok($response->is_success, '_doXmlRequest to USPS successful');
my $xmlData = XMLin($response->content, ForceArray => [qw/Package/],);
my $insuredCost = $driver->calculate($cart); my $insuredCost = $driver->calculate($cart);
cmp_ok $noInsuranceCost, '<', $insuredCost, 'insured cost is higher than uninsured cost'; cmp_ok $noInsuranceCost, '<', $insuredCost, 'insured cost is higher than uninsured cost';
@ -693,7 +723,7 @@ $rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $
$cost = eval { $driver->_calculateFromXML( $cost = eval { $driver->_calculateFromXML(
{ {
IntlRateResponse => { IntlRateV2Response => {
Package => [ Package => [
{ {
ID => 11, ID => 11,