active_shipping 1.12.1 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/active_shipping/carriers/canada_post_pws.rb +21 -3
- data/lib/active_shipping/carriers/ups.rb +14 -6
- data/lib/active_shipping/version.rb +1 -1
- data/test/test_helper.rb +7 -1
- data/test/unit/carriers/canada_post_pws_rating_test.rb +21 -2
- data/test/unit/carriers/ups_test.rb +43 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fd6c7d9c3034275ed5d1256c1b96d86f909be32
|
4
|
+
data.tar.gz: 649f6a67c3161c234757a340238445e74a729e23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 510db67fcf7f0c7f49d0d79b385920719d766bff67fc234793209e68a2d0b2f04f8de73aa61a83e8d1df095358346759af8996741418f1cab879f76a5a195322
|
7
|
+
data.tar.gz: 0da3ec56e0d924538c1afd526190718ad5fdf306f0a91c1fb87e141a3815442bbd07fdf0054bc912bfd78ff0874fe9e12e9b83bd3fc20c7018c2f3cb51c359af
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# ActiveShipping CHANGELOG
|
2
2
|
|
3
|
+
### v1.13.0
|
4
|
+
- Add default location for CanadaPost PWS
|
5
|
+
- Patch UPS to use old Kosovo country code
|
6
|
+
- Add option to not include tax in rates for CP PWS
|
7
|
+
|
3
8
|
### v1.12.1
|
4
9
|
- Explicitly set ssl_version for USPS
|
5
10
|
- Strip 9 digit origin zip code for USPS world rate requests
|
@@ -64,11 +64,21 @@ module ActiveShipping
|
|
64
64
|
[:api_key, :secret]
|
65
65
|
end
|
66
66
|
|
67
|
+
def self.default_location
|
68
|
+
{
|
69
|
+
:country => 'CA',
|
70
|
+
:province => 'ON',
|
71
|
+
:city => 'Ottawa',
|
72
|
+
:address1 => '61A York St',
|
73
|
+
:postal_code => 'K1N5T2'
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
67
77
|
def find_rates(origin, destination, line_items = [], options = {}, package = nil, services = [])
|
68
78
|
url = endpoint + "rs/ship/price"
|
69
79
|
request = build_rates_request(origin, destination, line_items, options, package, services)
|
70
80
|
response = ssl_post(url, request, headers(options, RATE_MIMETYPE, RATE_MIMETYPE))
|
71
|
-
parse_rates_response(response, origin, destination)
|
81
|
+
parse_rates_response(response, origin, destination, !!options[:exclude_tax])
|
72
82
|
rescue ActiveUtils::ResponseError, ActiveShipping::ResponseError => e
|
73
83
|
error_response(e.response.body, CPPWSRateResponse)
|
74
84
|
end
|
@@ -263,7 +273,7 @@ module ActiveShipping
|
|
263
273
|
builder.to_xml
|
264
274
|
end
|
265
275
|
|
266
|
-
def parse_rates_response(response, origin, destination)
|
276
|
+
def parse_rates_response(response, origin, destination, exclude_tax)
|
267
277
|
doc = Nokogiri.XML(response)
|
268
278
|
doc.remove_namespaces!
|
269
279
|
raise ActiveShipping::ResponseError, "No Quotes" unless doc.at('price-quotes')
|
@@ -271,7 +281,7 @@ module ActiveShipping
|
|
271
281
|
rates = doc.root.xpath('price-quote').map do |node|
|
272
282
|
service_name = node.at("service-name").text
|
273
283
|
service_code = node.at("service-code").text
|
274
|
-
total_price = node
|
284
|
+
total_price = price_from_node(node, exclude_tax)
|
275
285
|
expected_date = expected_date_from_node(node)
|
276
286
|
options = {
|
277
287
|
:service_code => service_code,
|
@@ -284,6 +294,14 @@ module ActiveShipping
|
|
284
294
|
CPPWSRateResponse.new(true, "", {}, :rates => rates)
|
285
295
|
end
|
286
296
|
|
297
|
+
def price_from_node(node, exclude_tax)
|
298
|
+
price = node.at('price-details/due').text
|
299
|
+
return price unless exclude_tax
|
300
|
+
children = node.at('price-details/taxes').children
|
301
|
+
tax_total_cents = children.sum { |node| node.elem? ? Package.cents_from(node.text) : 0 }
|
302
|
+
Package.cents_from(price) - tax_total_cents
|
303
|
+
end
|
304
|
+
|
287
305
|
# tracking
|
288
306
|
|
289
307
|
def parse_tracking_response(response)
|
@@ -129,6 +129,10 @@ module ActiveShipping
|
|
129
129
|
|
130
130
|
IMPERIAL_COUNTRIES = %w(US LR MM)
|
131
131
|
|
132
|
+
COUNTRY_MAPPING = {
|
133
|
+
'XK' => 'KV'
|
134
|
+
}.freeze
|
135
|
+
|
132
136
|
DEFAULT_SERVICE_NAME_TO_CODE = Hash[UPS::DEFAULT_SERVICES.to_a.map(&:reverse)]
|
133
137
|
DEFAULT_SERVICE_NAME_TO_CODE['UPS 2nd Day Air'] = "02"
|
134
138
|
DEFAULT_SERVICE_NAME_TO_CODE['UPS 3 Day Select'] = "12"
|
@@ -672,7 +676,7 @@ module ActiveShipping
|
|
672
676
|
xml.StateProvinceCode(location.province) unless location.province.blank?
|
673
677
|
# StateProvinceCode required for negotiated rates but not otherwise, for some reason
|
674
678
|
xml.PostalCode(location.postal_code) unless location.postal_code.blank?
|
675
|
-
xml.CountryCode(location.country_code(:alpha2)) unless location.country_code(:alpha2).blank?
|
679
|
+
xml.CountryCode(mapped_country_code(location.country_code(:alpha2))) unless location.country_code(:alpha2).blank?
|
676
680
|
xml.ResidentialAddressIndicator(true) unless location.commercial? # the default should be that UPS returns residential rates for destinations that it doesn't know about
|
677
681
|
# not implemented: Shipment/(Shipper|ShipTo|ShipFrom)/Address/ResidentialAddressIndicator element
|
678
682
|
end
|
@@ -684,7 +688,7 @@ module ActiveShipping
|
|
684
688
|
xml.AddressArtifactFormat do
|
685
689
|
xml.PoliticalDivision2(location.city)
|
686
690
|
xml.PoliticalDivision1(location.province)
|
687
|
-
xml.CountryCode(location.country_code(:alpha2))
|
691
|
+
xml.CountryCode(mapped_country_code(location.country_code(:alpha2)))
|
688
692
|
xml.PostcodePrimaryLow(location.postal_code)
|
689
693
|
xml.ResidentialAddressIndicator(true) unless location.commercial?
|
690
694
|
end
|
@@ -787,7 +791,7 @@ module ActiveShipping
|
|
787
791
|
xml.ThirdParty do
|
788
792
|
xml.Address do
|
789
793
|
xml.PostalCode(options[:billing_zip])
|
790
|
-
xml.CountryCode(options[:billing_country])
|
794
|
+
xml.CountryCode(mapped_country_code(options[:billing_country]))
|
791
795
|
end
|
792
796
|
end
|
793
797
|
end
|
@@ -1002,7 +1006,7 @@ module ActiveShipping
|
|
1002
1006
|
xml.PoliticalDivision2(location.city)
|
1003
1007
|
xml.PoliticalDivision1(location.state)
|
1004
1008
|
xml.PostcodePrimaryLow(location.postal_code)
|
1005
|
-
xml.CountryCode(location.country_code)
|
1009
|
+
xml.CountryCode(mapped_country_code(location.country_code))
|
1006
1010
|
end
|
1007
1011
|
end
|
1008
1012
|
end
|
@@ -1024,7 +1028,7 @@ module ActiveShipping
|
|
1024
1028
|
if xml.at('AddressClassification/Code').present?
|
1025
1029
|
classification_code = xml.at('AddressClassification/Code').text
|
1026
1030
|
end
|
1027
|
-
|
1031
|
+
|
1028
1032
|
classification = case classification_code
|
1029
1033
|
when "1"
|
1030
1034
|
:commercial
|
@@ -1056,7 +1060,7 @@ module ActiveShipping
|
|
1056
1060
|
return nil unless address
|
1057
1061
|
country = address.at('CountryCode').try(:text)
|
1058
1062
|
country = 'US' if country == 'ZZ' # Sometimes returned by SUREPOST in the US
|
1059
|
-
|
1063
|
+
|
1060
1064
|
address_lines = address.css('AddressLine')
|
1061
1065
|
|
1062
1066
|
Location.new(
|
@@ -1203,5 +1207,9 @@ module ActiveShipping
|
|
1203
1207
|
origin.country_code == destination.country_code ||
|
1204
1208
|
[['US','PR'], ['PR','US']].include?([origin,destination].map(&:country_code))
|
1205
1209
|
end
|
1210
|
+
|
1211
|
+
def mapped_country_code(country_code)
|
1212
|
+
COUNTRY_MAPPING[country_code].presence || country_code
|
1213
|
+
end
|
1206
1214
|
end
|
1207
1215
|
end
|
data/test/test_helper.rb
CHANGED
@@ -267,8 +267,14 @@ module ActiveShipping::Test
|
|
267
267
|
:city => 'Melbourne',
|
268
268
|
:state => 'VIC',
|
269
269
|
:address1 => '192 George Street',
|
270
|
-
:postal_code => '3108')
|
270
|
+
:postal_code => '3108'),
|
271
|
+
:kosovo => Location.new(
|
272
|
+
:country => 'XK',
|
273
|
+
:city => 'Prishtinë',
|
274
|
+
:address1 => 'Ahmet Krasniqi',
|
275
|
+
:postal_code => '10000')
|
271
276
|
}
|
277
|
+
|
272
278
|
end
|
273
279
|
|
274
280
|
def line_item_fixture
|
@@ -112,6 +112,25 @@ class CanadaPostPwsRatingTest < Minitest::Test
|
|
112
112
|
assert_equal @dest.to_s, Location.new(rate.destination).to_s
|
113
113
|
end
|
114
114
|
|
115
|
+
def test_find_rates_excluding_tax
|
116
|
+
response = xml_fixture('canadapost_pws/rates_info')
|
117
|
+
expected_headers = {
|
118
|
+
'Authorization' => "#{@cp.send(:encoded_authorization)}",
|
119
|
+
'Accept-Language' => 'en-CA',
|
120
|
+
'Accept' => 'application/vnd.cpc.ship.rate+xml',
|
121
|
+
'Content-Type' => 'application/vnd.cpc.ship.rate+xml'
|
122
|
+
}
|
123
|
+
CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, expected_headers).returns(response).twice
|
124
|
+
|
125
|
+
rates_tax_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], {})
|
126
|
+
rates_no_tax_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], {exclude_tax: true})
|
127
|
+
|
128
|
+
expected = [139, 407, 139, 240] #taken from fixture, tax in centsÏ
|
129
|
+
assert_equal rates_no_tax_response.rates.size, rates_tax_response.rates.size
|
130
|
+
expected.zip(rates_no_tax_response.rates, rates_tax_response.rates).each do |expected, no_tax, tax|
|
131
|
+
assert_equal expected, tax.total_price - no_tax.total_price
|
132
|
+
end
|
133
|
+
end
|
115
134
|
# build rates
|
116
135
|
|
117
136
|
def test_build_rates_request
|
@@ -283,7 +302,7 @@ class CanadaPostPwsRatingTest < Minitest::Test
|
|
283
302
|
|
284
303
|
def test_parse_rates_response
|
285
304
|
body = xml_fixture('canadapost_pws/rates_info')
|
286
|
-
rates_response = @cp.parse_rates_response(body, @home, @dest)
|
305
|
+
rates_response = @cp.parse_rates_response(body, @home, @dest, false)
|
287
306
|
|
288
307
|
assert_equal 4, rates_response.rates.count
|
289
308
|
rate = rates_response.rates.first
|
@@ -297,7 +316,7 @@ class CanadaPostPwsRatingTest < Minitest::Test
|
|
297
316
|
def test_parse_rates_response_with_invalid_response_raises
|
298
317
|
body = xml_fixture('canadapost_pws/rates_info_error')
|
299
318
|
exception = assert_raises ActiveShipping::ResponseError do
|
300
|
-
@response = @cp.parse_rates_response(body, @home, @dest)
|
319
|
+
@response = @cp.parse_rates_response(body, @home, @dest, false)
|
301
320
|
end
|
302
321
|
assert_equal "No Quotes", exception.message
|
303
322
|
end
|
@@ -656,4 +656,47 @@ class UPSTest < Minitest::Test
|
|
656
656
|
assert_equal :invalid, response.validity
|
657
657
|
end
|
658
658
|
|
659
|
+
def test_kosovo_location_node
|
660
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
661
|
+
@carrier.send(:build_location_node,
|
662
|
+
xml,
|
663
|
+
"KosovoRequest",
|
664
|
+
location_fixtures[:kosovo],
|
665
|
+
{}
|
666
|
+
)
|
667
|
+
end
|
668
|
+
request = Nokogiri::XML(xml_builder.to_xml)
|
669
|
+
assert_equal 'KV', request.search('/KosovoRequest/Address/CountryCode').text
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_kosovo_build_address_artifact_format_location
|
673
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
674
|
+
@carrier.send(:build_address_artifact_format_location,
|
675
|
+
xml,
|
676
|
+
"KosovoRequest",
|
677
|
+
location_fixtures[:kosovo]
|
678
|
+
)
|
679
|
+
end
|
680
|
+
request = Nokogiri::XML(xml_builder.to_xml)
|
681
|
+
assert_equal 'KV', request.search('/KosovoRequest/AddressArtifactFormat/CountryCode').text
|
682
|
+
end
|
683
|
+
|
684
|
+
def test_kosovo_build_address_validation_request
|
685
|
+
xml = @carrier.send(:build_address_validation_request, location_fixtures[:kosovo])
|
686
|
+
request = Nokogiri::XML(xml)
|
687
|
+
assert_equal 'KV', request.search('/AddressValidationRequest/AddressKeyFormat/CountryCode').text
|
688
|
+
end
|
689
|
+
|
690
|
+
def test_kosovo_build_billing_info_node
|
691
|
+
options = {bill_third_party: true, bill_to_consignee: true, billing_account: 12345,
|
692
|
+
billing_zip: 12345, billing_country: 'XK'}
|
693
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
694
|
+
@carrier.send(:build_billing_info_node,
|
695
|
+
xml,
|
696
|
+
options
|
697
|
+
)
|
698
|
+
end
|
699
|
+
request = Nokogiri::XML(xml_builder.to_xml)
|
700
|
+
assert_equal 'KV', request.search('/BillThirdParty/BillThirdPartyConsignee/ThirdParty/Address/CountryCode').text
|
701
|
+
end
|
659
702
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: quantified
|