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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f4f1610144f6b41f51175256c47cc12601216ef
4
- data.tar.gz: ce74fa151c3ae1483368330c88970a0631d82cf3
3
+ metadata.gz: 1fd6c7d9c3034275ed5d1256c1b96d86f909be32
4
+ data.tar.gz: 649f6a67c3161c234757a340238445e74a729e23
5
5
  SHA512:
6
- metadata.gz: f11e65c4c3fc7efc64ca6d3715f8ec83ae978c44c617b39855c7f5ba3793ba24ba1fd8ba5631d44ead849e289b18bbeceb47694f82d3c1a19ca0353f28276180
7
- data.tar.gz: f8f765528c38f1a08e8e72d59bb562452148dc471b2904ebd08798e8bb3e8812378610155e6b09bc52a3daa37c4c219ee25cdb64fb4d9b154de3c0d7bfe74514
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.at('price-details/due').text
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
@@ -1,3 +1,3 @@
1
1
  module ActiveShipping
2
- VERSION = "1.12.1"
2
+ VERSION = "1.13.0"
3
3
  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.12.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-13 00:00:00.000000000 Z
11
+ date: 2017-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: quantified