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 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