active_shipping 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
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