active_shipping 1.12.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|