active_shipping 0.9.7 → 0.9.8

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ * New Zealand Post [AbleTech]
1
2
  * Include address name for rate requests to Shipwire if provided [dennis]
2
3
  * Add support for address name to Location [dennis]
3
4
  * Add fix for updated USPS API to strip any encoded html and trailing asterisks from rate names [dennis]
data/README.markdown CHANGED
@@ -17,6 +17,7 @@ Active Shipping is currently being used and improved in a production environment
17
17
  * [USPS](http://www.usps.com)
18
18
  * [FedEx](http://www.fedex.com)
19
19
  * [Canada Post](http://www.canadapost.ca)
20
+ * [New Zealand Post](http://www.nzpost.co.nz)
20
21
  * more soon!
21
22
 
22
23
  ## Prerequisites
@@ -5,13 +5,14 @@ require 'active_shipping/shipping/carriers/fedex'
5
5
  require 'active_shipping/shipping/carriers/shipwire'
6
6
  require 'active_shipping/shipping/carriers/kunaki'
7
7
  require 'active_shipping/shipping/carriers/canada_post'
8
+ require 'active_shipping/shipping/carriers/new_zealand_post'
8
9
 
9
10
  module ActiveMerchant
10
11
  module Shipping
11
12
  module Carriers
12
13
  class <<self
13
14
  def all
14
- [BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki, CanadaPost]
15
+ [BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki, CanadaPost, NewZealandPost]
15
16
  end
16
17
  end
17
18
  end
@@ -122,7 +122,7 @@ module ActiveMerchant
122
122
  request << XmlNode.new('merchantCPCID', @options[:login])
123
123
  request << XmlNode.new('fromPostalCode', origin.postal_code)
124
124
  request << XmlNode.new('turnAroundTime', options[:turn_around_time] ? options[:turn_around_time] : DEFAULT_TURN_AROUND_TIME)
125
- request << XmlNode.new('itemsPrice', line_items.sum(&:value))
125
+ request << XmlNode.new('itemsPrice', dollar_amount(line_items.sum(&:value)))
126
126
 
127
127
  #line items
128
128
  request << build_line_items(line_items)
@@ -206,8 +206,9 @@ module ActiveMerchant
206
206
  end
207
207
 
208
208
  def date_for(string)
209
- return if !string
210
- return Time.parse(string)
209
+ string && Time.parse(string)
210
+ rescue ArgumentError
211
+ nil
211
212
  end
212
213
 
213
214
  def response_success?(xml)
@@ -249,6 +250,10 @@ module ActiveMerchant
249
250
 
250
251
  xml_line_items
251
252
  end
253
+
254
+ def dollar_amount(cents)
255
+ "%0.2f" % (cents / 100.0)
256
+ end
252
257
  end
253
258
  end
254
259
  end
@@ -237,11 +237,12 @@ module ActiveMerchant
237
237
  is_saturday_delivery = rated_shipment.get_text('AppliedOptions').to_s == 'SATURDAY_DELIVERY'
238
238
  service_type = is_saturday_delivery ? "#{service_code}_SATURDAY_DELIVERY" : service_code
239
239
 
240
+ currency = handle_uk_currency(rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Currency').to_s)
240
241
  rate_estimates << RateEstimate.new(origin, destination, @@name,
241
242
  self.class.service_name_for_code(service_type),
242
243
  :service_code => service_code,
243
244
  :total_price => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').to_s.to_f,
244
- :currency => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Currency').to_s,
245
+ :currency => currency,
245
246
  :packages => packages,
246
247
  :delivery_date => rated_shipment.get_text('DeliveryTimestamp').to_s)
247
248
  end
@@ -317,7 +318,10 @@ module ActiveMerchant
317
318
  def commit(request, test = false)
318
319
  ssl_post(test ? TEST_URL : LIVE_URL, request.gsub("\n",''))
319
320
  end
320
-
321
+
322
+ def handle_uk_currency(currency)
323
+ currency =~ /UKL/i ? 'GBP' : currency
324
+ end
321
325
  end
322
326
  end
323
327
  end
@@ -0,0 +1,139 @@
1
+ module ActiveMerchant
2
+ module Shipping
3
+ class NewZealandPost < Carrier
4
+
5
+ # class NewZealandPostRateResponse < RateResponse
6
+ # end
7
+
8
+ cattr_reader :name
9
+ @@name = "New Zealand Post"
10
+
11
+ URL = "http://workshop.nzpost.co.nz/api/v1/rate.xml"
12
+
13
+ # Override to return required keys in options hash for initialize method.
14
+ def requirements
15
+ [:key]
16
+ end
17
+
18
+ # Override with whatever you need to get the rates
19
+ def find_rates(origin, destination, packages, options = {})
20
+ packages = Array(packages)
21
+ rate_responses = []
22
+ packages.each do |package|
23
+ if package.tube?
24
+ request_hash = build_tube_request_params(origin, destination, package, options)
25
+ else
26
+ request_hash = build_rectangular_request_params(origin, destination, package, options)
27
+ end
28
+ url = URL + '?' + request_hash.to_param
29
+ response = ssl_get(url)
30
+ rate_responses << parse_rate_response(origin, destination, package, response, options)
31
+ end
32
+ combine_rate_responses(rate_responses, packages)
33
+ end
34
+
35
+ def maximum_weight
36
+ Mass.new(20, :kilograms)
37
+ end
38
+
39
+ protected
40
+
41
+ # Override in subclasses for non-U.S.-based carriers.
42
+ def self.default_location
43
+ Location.new(:postal_code => '6011')
44
+ end
45
+
46
+ private
47
+
48
+ def build_rectangular_request_params(origin, destination, package, options = {})
49
+ params = {
50
+ :postcode_src => origin.postal_code,
51
+ :postcode_dest => destination.postal_code,
52
+ :api_key => @options[:key],
53
+ :height => "#{package.centimetres(:height) * 10}",
54
+ :thickness => "#{package.centimetres(:width) * 10}",
55
+ :length => "#{package.centimetres(:length) * 10}",
56
+ :weight =>"%.1f" % (package.weight.amount / 1000.0)
57
+ }
58
+ end
59
+
60
+ def build_tube_request_params(origin, destination, package, options = {})
61
+ params = {
62
+ :postcode_src => origin.postal_code,
63
+ :postcode_dest => destination.postal_code,
64
+ :api_key => @options[:key],
65
+ :diameter => "#{package.centimetres(:width) * 10}",
66
+ :length => "#{package.centimetres(:length) * 10}",
67
+ :weight => "%.1f" % (package.weight.amount / 1000.0)
68
+ }
69
+ end
70
+
71
+ def parse_rate_response(origin, destination, package, response, options={})
72
+ xml = REXML::Document.new(response)
73
+ if response_success?(xml)
74
+ rate_estimates = []
75
+ xml.elements.each('hash/products/product') do |prod|
76
+ if( prod.get_text('packaging') == 'postage_only' )
77
+ rate_estimates << RateEstimate.new(origin,
78
+ destination,
79
+ @@name,
80
+ prod.get_text('service-group-description').to_s,
81
+ :total_price => prod.get_text('cost').to_s.to_f,
82
+ :currency => 'NZD',
83
+ :service_code => prod.get_text('code').to_s,
84
+ :package => package)
85
+ end
86
+ end
87
+
88
+ RateResponse.new(true, "Success", Hash.from_xml(response), :rates => rate_estimates, :xml => response)
89
+ else
90
+ error_message = response_message(xml)
91
+ RateResponse.new(false, error_message, Hash.from_xml(response), :rates => rate_estimates, :xml => response)
92
+ end
93
+ end
94
+
95
+ def combine_rate_responses(rate_responses, packages)
96
+ #if there are any failed responses, return on that response
97
+ rate_responses.each do |r|
98
+ return r if !r.success?
99
+ end
100
+
101
+ #group rate estimates by delivery type so that we can exclude any incomplete delviery types
102
+ rate_estimate_delivery_types = {}
103
+ rate_responses.each do |rr|
104
+ rr.rate_estimates.each do |re|
105
+ (rate_estimate_delivery_types[re.service_code] ||= []) << re
106
+ end
107
+ end
108
+ rate_estimate_delivery_types.delete_if{ |type, re| re.size != packages.size }
109
+
110
+ #combine cost estimates for remaining packages
111
+ combined_rate_estimates = []
112
+ rate_estimate_delivery_types.each do |type, re|
113
+ total_price = re.sum(&:total_price)
114
+ r = re.first
115
+ combined_rate_estimates << RateEstimate.new(r.origin, r.destination, r.carrier,
116
+ r.service_name,
117
+ :total_price => total_price,
118
+ :currency => r.currency,
119
+ :service_code => r.service_code,
120
+ :packages => packages)
121
+ end
122
+ RateResponse.new(true, "Success", {}, :rates => combined_rate_estimates)
123
+ end
124
+
125
+ def response_success?(xml)
126
+ xml.get_text('hash/status').to_s == 'success'
127
+ end
128
+
129
+ def response_message(xml)
130
+ if response_success?(xml)
131
+ 'Success'
132
+ else
133
+ xml.get_text('hash/message').to_s
134
+ end
135
+ end
136
+
137
+ end
138
+ end
139
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveShipping
2
- VERSION = "0.9.7"
2
+ VERSION = "0.9.8"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_shipping
3
3
  version: !ruby/object:Gem::Version
4
- hash: 53
4
+ hash: 43
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 7
10
- version: 0.9.7
9
+ - 8
10
+ version: 0.9.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - James MacAulay
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-01-14 00:00:00 +01:00
21
+ date: 2011-02-14 00:00:00 +01:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -76,6 +76,7 @@ files:
76
76
  - lib/active_shipping/shipping/carriers/canada_post.rb
77
77
  - lib/active_shipping/shipping/carriers/fedex.rb
78
78
  - lib/active_shipping/shipping/carriers/kunaki.rb
79
+ - lib/active_shipping/shipping/carriers/new_zealand_post.rb
79
80
  - lib/active_shipping/shipping/carriers/shipwire.rb
80
81
  - lib/active_shipping/shipping/carriers/ups.rb
81
82
  - lib/active_shipping/shipping/carriers/usps.rb