active_shipping 0.12.4 → 0.12.5
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/lib/active_shipping.rb +2 -1
- data/lib/active_shipping/shipping/base.rb +2 -2
- data/lib/active_shipping/shipping/carrier.rb +16 -13
- data/lib/active_shipping/shipping/carriers/benchmark_carrier.rb +3 -4
- data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +1 -3
- data/lib/active_shipping/shipping/carriers/canada_post.rb +33 -44
- data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +72 -81
- data/lib/active_shipping/shipping/carriers/fedex.rb +118 -109
- data/lib/active_shipping/shipping/carriers/kunaki.rb +33 -32
- data/lib/active_shipping/shipping/carriers/new_zealand_post.rb +9 -16
- data/lib/active_shipping/shipping/carriers/shipwire.rb +36 -35
- data/lib/active_shipping/shipping/carriers/stamps.rb +39 -51
- data/lib/active_shipping/shipping/carriers/ups.rb +280 -116
- data/lib/active_shipping/shipping/carriers/ups.rb.orig +456 -0
- data/lib/active_shipping/shipping/carriers/usps.rb +145 -100
- data/lib/active_shipping/shipping/carriers/usps.rb.orig +616 -0
- data/lib/active_shipping/shipping/errors.rb +1 -1
- data/lib/active_shipping/shipping/label_response.rb +25 -0
- data/lib/active_shipping/shipping/location.rb +18 -16
- data/lib/active_shipping/shipping/package.rb +51 -54
- data/lib/active_shipping/shipping/rate_estimate.rb +10 -12
- data/lib/active_shipping/shipping/rate_response.rb +3 -7
- data/lib/active_shipping/shipping/response.rb +6 -9
- data/lib/active_shipping/shipping/shipment_event.rb +2 -4
- data/lib/active_shipping/shipping/shipment_packer.rb +32 -17
- data/lib/active_shipping/shipping/shipping_response.rb +2 -4
- data/lib/active_shipping/shipping/tracking_response.rb +3 -5
- data/lib/active_shipping/version.rb +1 -1
- data/lib/vendor/quantified/lib/quantified/attribute.rb +79 -80
- data/lib/vendor/quantified/lib/quantified/length.rb +5 -5
- data/lib/vendor/quantified/lib/quantified/mass.rb +4 -4
- data/lib/vendor/quantified/test/length_test.rb +19 -15
- data/lib/vendor/quantified/test/mass_test.rb +14 -14
- data/lib/vendor/quantified/test/test_helper.rb +1 -2
- data/lib/vendor/test_helper.rb +0 -1
- data/lib/vendor/xml_node/benchmark/bench_generation.rb +2 -4
- data/lib/vendor/xml_node/lib/xml_node.rb +54 -55
- data/lib/vendor/xml_node/test/test_generating.rb +23 -28
- data/lib/vendor/xml_node/test/test_parsing.rb +5 -8
- metadata +6 -25
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1976e71d35364954a7b796b394000fa996d3e0b1
|
4
|
+
data.tar.gz: 0c143eefaaf19b10cfaba63e01110164024b3bae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 312abbbb1fd246d4f6221cbf4fa7f70101465d118ff18bc2c588be8f276904e90ee9a9666d90b745a3d29c6abe1cc615230f188e7a6acb759374977a88ce2838
|
7
|
+
data.tar.gz: db9d8dccf1c806d521188f99fff5b72eb7704da60359bb4239fa293e21be21e646373a0d42fd5df901b597e224bcb5ccd7d7a0c617607c2375242456df1a8843
|
data/lib/active_shipping.rb
CHANGED
@@ -25,7 +25,7 @@ $:.unshift File.dirname(__FILE__)
|
|
25
25
|
|
26
26
|
begin
|
27
27
|
require 'active_support/all'
|
28
|
-
rescue LoadError
|
28
|
+
rescue LoadError
|
29
29
|
require 'rubygems'
|
30
30
|
gem "activesupport", ">= 2.3.5"
|
31
31
|
require "active_support/all"
|
@@ -42,6 +42,7 @@ require 'active_shipping/shipping/response'
|
|
42
42
|
require 'active_shipping/shipping/rate_response'
|
43
43
|
require 'active_shipping/shipping/tracking_response'
|
44
44
|
require 'active_shipping/shipping/shipping_response'
|
45
|
+
require 'active_shipping/shipping/label_response'
|
45
46
|
require 'active_shipping/shipping/package'
|
46
47
|
require 'active_shipping/shipping/location'
|
47
48
|
require 'active_shipping/shipping/rate_estimate'
|
@@ -3,9 +3,9 @@ module ActiveMerchant
|
|
3
3
|
module Base
|
4
4
|
mattr_accessor :mode
|
5
5
|
self.mode = :production
|
6
|
-
|
6
|
+
|
7
7
|
def self.carrier(name)
|
8
|
-
ActiveMerchant::Shipping::Carriers.all.find {|c| c.name.downcase == name.to_s.downcase} ||
|
8
|
+
ActiveMerchant::Shipping::Carriers.all.find { |c| c.name.downcase == name.to_s.downcase } ||
|
9
9
|
raise(NameError, "unknown carrier #{name}")
|
10
10
|
end
|
11
11
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module ActiveMerchant
|
2
2
|
module Shipping
|
3
3
|
class Carrier
|
4
|
-
|
5
4
|
include RequiresParameters
|
6
5
|
include PostsData
|
7
6
|
include Quantified
|
8
|
-
|
7
|
+
|
9
8
|
attr_reader :last_request
|
10
9
|
attr_accessor :test_mode
|
11
10
|
alias_method :test_mode?, :test_mode
|
12
|
-
|
11
|
+
|
13
12
|
# Credentials should be in options hash under keys :login, :password and/or :key.
|
14
13
|
def initialize(options = {})
|
15
|
-
requirements.each {|key| requires!(options, key)}
|
14
|
+
requirements.each { |key| requires!(options, key) }
|
16
15
|
@options = options
|
17
16
|
@last_request = nil
|
18
17
|
@test_mode = @options[:test]
|
@@ -22,33 +21,37 @@ module ActiveMerchant
|
|
22
21
|
def requirements
|
23
22
|
[]
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
# Override with whatever you need to get the rates
|
27
26
|
def find_rates(origin, destination, packages, options = {})
|
28
27
|
end
|
29
|
-
|
28
|
+
|
29
|
+
# Override with whatever you need to get a shipping label
|
30
|
+
def create_shipment(origin, destination, packages, options = {})
|
31
|
+
end
|
32
|
+
|
30
33
|
# Validate credentials with a call to the API. By default this just does a find_rates call
|
31
34
|
# with the orgin and destination both as the carrier's default_location. Override to provide
|
32
35
|
# alternate functionality, such as checking for test_mode to use test servers, etc.
|
33
36
|
def valid_credentials?
|
34
37
|
location = self.class.default_location
|
35
|
-
find_rates(location,location,Package.new(100, [5,15,30]), :test => test_mode)
|
38
|
+
find_rates(location, location, Package.new(100, [5, 15, 30]), :test => test_mode)
|
36
39
|
rescue ActiveMerchant::Shipping::ResponseError
|
37
40
|
false
|
38
41
|
else
|
39
42
|
true
|
40
43
|
end
|
41
|
-
|
44
|
+
|
42
45
|
def maximum_weight
|
43
46
|
Mass.new(150, :pounds)
|
44
47
|
end
|
45
|
-
|
48
|
+
|
46
49
|
protected
|
47
|
-
|
50
|
+
|
48
51
|
def node_text_or_nil(xml_node)
|
49
52
|
xml_node ? xml_node.text : nil
|
50
53
|
end
|
51
|
-
|
54
|
+
|
52
55
|
# Override in subclasses for non-U.S.-based carriers.
|
53
56
|
def self.default_location
|
54
57
|
Location.new( :country => 'US',
|
@@ -60,7 +63,7 @@ module ActiveMerchant
|
|
60
63
|
:phone => '1-310-285-1013',
|
61
64
|
:fax => '1-310-275-8159')
|
62
65
|
end
|
63
|
-
|
66
|
+
|
64
67
|
# Use after building the request to save for later inspection. Probably won't ever be overridden.
|
65
68
|
def save_request(r)
|
66
69
|
@last_request = r
|
@@ -72,7 +75,7 @@ module ActiveMerchant
|
|
72
75
|
days.times do
|
73
76
|
begin
|
74
77
|
date = date + 1
|
75
|
-
end
|
78
|
+
end while [0, 6].include?(date.wday)
|
76
79
|
end
|
77
80
|
date
|
78
81
|
end
|
@@ -7,7 +7,7 @@ module ActiveMerchant
|
|
7
7
|
class BenchmarkCarrier < Carrier
|
8
8
|
cattr_reader :name
|
9
9
|
@@name = "Benchmark Carrier"
|
10
|
-
|
10
|
+
|
11
11
|
def find_rates(origin, destination, packages, options = {})
|
12
12
|
origin = Location.from(origin)
|
13
13
|
destination = Location.from(destination)
|
@@ -18,17 +18,16 @@ module ActiveMerchant
|
|
18
18
|
bogus_estimate = RateEstimate.new(
|
19
19
|
origin, destination, @@name,
|
20
20
|
"Free Benchmark Shipping", :total_price => 0, :currency => 'USD',
|
21
|
-
|
21
|
+
:packages => packages, :delivery_range => [Time.now.utc.strftime("%Y-%d-%m"), Time.now.utc.strftime("%Y-%d-%m")]
|
22
22
|
)
|
23
23
|
RateResponse.new(true, "Success (delayed #{delay_time} seconds)", {:rate => 'free'}, :rates => [bogus_estimate], :xml => "<rate>free</rate>")
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
private
|
27
27
|
|
28
28
|
def generate_simulated_lag(max_delay = 30)
|
29
29
|
sleep Random.rand * max_delay
|
30
30
|
end
|
31
|
-
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
@@ -3,14 +3,12 @@ module ActiveMerchant
|
|
3
3
|
class BogusCarrier < Carrier
|
4
4
|
cattr_reader :name
|
5
5
|
@@name = "Bogus Carrier"
|
6
|
-
|
7
|
-
|
6
|
+
|
8
7
|
def find_rates(origin, destination, packages, options = {})
|
9
8
|
origin = Location.from(origin)
|
10
9
|
destination = Location.from(destination)
|
11
10
|
packages = Array(packages)
|
12
11
|
end
|
13
|
-
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
@@ -2,37 +2,32 @@ require 'cgi'
|
|
2
2
|
|
3
3
|
module ActiveMerchant
|
4
4
|
module Shipping
|
5
|
-
|
6
5
|
class CanadaPost < Carrier
|
7
|
-
|
8
6
|
# NOTE!
|
9
7
|
# A Merchant CPC Id must be assigned to you by Canada Post
|
10
8
|
# CPC_DEMO_XML is just a public domain account for testing
|
11
|
-
|
9
|
+
|
12
10
|
class CanadaPostRateResponse < RateResponse
|
13
|
-
|
14
11
|
attr_reader :boxes, :postal_outlets
|
15
|
-
|
12
|
+
|
16
13
|
def initialize(success, message, params = {}, options = {})
|
17
14
|
@boxes = options[:boxes]
|
18
15
|
@postal_outlets = options[:postal_outlets]
|
19
16
|
super
|
20
17
|
end
|
21
|
-
|
22
18
|
end
|
23
|
-
|
19
|
+
|
24
20
|
cattr_reader :name, :name_french
|
25
21
|
@@name = "Canada Post"
|
26
22
|
@@name_french = "Postes Canada"
|
27
|
-
|
23
|
+
|
28
24
|
Box = Struct.new(:name, :weight, :expediter_weight, :length, :width, :height, :packedItems)
|
29
25
|
PackedItem = Struct.new(:quantity, :description)
|
30
26
|
PostalOutlet = Struct.new(:sequence_no, :distance, :name, :business_name, :postal_address, :business_hours)
|
31
|
-
|
32
|
-
DEFAULT_TURN_AROUND_TIME = 24
|
27
|
+
|
33
28
|
URL = "http://sellonline.canadapost.ca:30000"
|
34
|
-
DOCTYPE = '<!DOCTYPE eparcel SYSTEM "http://sellonline.canadapost.ca/DevelopersResources/protocolV3/eParcel.dtd">'
|
35
|
-
|
29
|
+
DOCTYPE = '<!DOCTYPE eparcel SYSTEM "http://sellonline.canadapost.ca/DevelopersResources/protocolV3/eParcel.dtd">'
|
30
|
+
|
36
31
|
RESPONSE_CODES = {
|
37
32
|
'1' => "All calculation was done",
|
38
33
|
'2' => "Default shipping rates are returned due to a problem during the processing of the request.",
|
@@ -78,25 +73,24 @@ module ActiveMerchant
|
|
78
73
|
'-6002' => "Unable to write to the database",
|
79
74
|
'-50000' => "Internal problem - Please contact Sell Online Help Desk"
|
80
75
|
}
|
81
|
-
|
76
|
+
|
82
77
|
NON_ISO_COUNTRY_NAMES = {
|
83
78
|
'Russian Federation' => 'Russia'
|
84
79
|
}
|
85
80
|
|
86
|
-
|
87
81
|
def requirements
|
88
82
|
[:login]
|
89
83
|
end
|
90
|
-
|
84
|
+
|
91
85
|
def find_rates(origin, destination, line_items = [], options = {})
|
92
86
|
rate_request = build_rate_request(origin, destination, line_items, options)
|
93
87
|
commit(rate_request, origin, destination, options)
|
94
88
|
end
|
95
|
-
|
89
|
+
|
96
90
|
def maximum_weight
|
97
91
|
Mass.new(30, :kilograms)
|
98
92
|
end
|
99
|
-
|
93
|
+
|
100
94
|
def self.default_location
|
101
95
|
{
|
102
96
|
:country => 'CA',
|
@@ -108,15 +102,15 @@ module ActiveMerchant
|
|
108
102
|
end
|
109
103
|
|
110
104
|
protected
|
111
|
-
|
105
|
+
|
112
106
|
def commit(request, origin, destination, options = {})
|
113
|
-
|
107
|
+
parse_rate_response(ssl_post(URL, request), origin, destination, options)
|
114
108
|
end
|
115
|
-
|
109
|
+
|
116
110
|
private
|
117
|
-
|
111
|
+
|
118
112
|
def build_rate_request(origin, destination, line_items = [], options = {})
|
119
|
-
line_items = [line_items]
|
113
|
+
line_items = [line_items] unless line_items.is_a?(Array)
|
120
114
|
origin = origin.is_a?(Location) ? origin : Location.new(origin)
|
121
115
|
destination = destination.is_a?(Location) ? destination : Location.new(destination)
|
122
116
|
|
@@ -126,14 +120,14 @@ module ActiveMerchant
|
|
126
120
|
|
127
121
|
request << XmlNode.new('merchantCPCID', @options[:login])
|
128
122
|
request << XmlNode.new('fromPostalCode', origin.postal_code)
|
129
|
-
request << XmlNode.new('turnAroundTime', options[:turn_around_time]
|
123
|
+
request << XmlNode.new('turnAroundTime', options[:turn_around_time]) if options[:turn_around_time]
|
130
124
|
request << XmlNode.new('itemsPrice', dollar_amount(line_items.map(&:value).compact.sum))
|
131
125
|
|
132
|
-
#line items
|
126
|
+
# line items
|
133
127
|
request << build_line_items(line_items)
|
134
128
|
|
135
|
-
#delivery info
|
136
|
-
#NOTE: These tags MUST be after line items
|
129
|
+
# delivery info
|
130
|
+
# NOTE: These tags MUST be after line items
|
137
131
|
request << XmlNode.new('city', destination.city)
|
138
132
|
request << XmlNode.new('provOrState', destination.province)
|
139
133
|
request << XmlNode.new('country', handle_non_iso_country_names(destination.country))
|
@@ -157,11 +151,11 @@ module ActiveMerchant
|
|
157
151
|
service_code = product.attribute('id').to_s
|
158
152
|
|
159
153
|
rate_estimates << RateEstimate.new(origin, destination, @@name, service_name,
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
154
|
+
:service_code => service_code,
|
155
|
+
:total_price => product.get_text('rate').to_s,
|
156
|
+
:currency => 'CAD',
|
157
|
+
:shipping_date => product.get_text('shippingDate').to_s,
|
158
|
+
:delivery_range => [product.get_text('deliveryDate').to_s] * 2
|
165
159
|
)
|
166
160
|
end
|
167
161
|
|
@@ -190,14 +184,14 @@ module ActiveMerchant
|
|
190
184
|
postal_outlet.name = outlet.get_text('outletName').to_s
|
191
185
|
postal_outlet.business_name = outlet.get_text('businessName').to_s
|
192
186
|
|
193
|
-
postal_outlet.postal_address = Location.new(
|
187
|
+
postal_outlet.postal_address = Location.new(
|
194
188
|
:address1 => outlet.get_text('postalAddress/addressLine').to_s,
|
195
189
|
:postal_code => outlet.get_text('postalAddress/postal_code').to_s,
|
196
190
|
:city => outlet.get_text('postalAddress/municipality').to_s,
|
197
191
|
:province => outlet.get_text('postalAddress/province').to_s,
|
198
192
|
:country => 'Canada',
|
199
193
|
:phone_number => outlet.get_text('phoneNumber').to_s
|
200
|
-
|
194
|
+
)
|
201
195
|
|
202
196
|
postal_outlet.business_hours = outlet.elements.collect('businessHours') do |hour|
|
203
197
|
{ :day_of_week => hour.get_text('dayOfWeek').to_s, :time => hour.get_text('time').to_s }
|
@@ -216,7 +210,7 @@ module ActiveMerchant
|
|
216
210
|
value = xml.get_text('eparcel/ratesAndServicesResponse/statusCode').to_s
|
217
211
|
value == '1' || value == '2'
|
218
212
|
end
|
219
|
-
|
213
|
+
|
220
214
|
def response_message(xml)
|
221
215
|
if response_success?(xml)
|
222
216
|
xml.get_text('eparcel/ratesAndServicesResponse/statusMessage').to_s
|
@@ -224,7 +218,7 @@ module ActiveMerchant
|
|
224
218
|
xml.get_text('eparcel/error/statusMessage').to_s
|
225
219
|
end
|
226
220
|
end
|
227
|
-
|
221
|
+
|
228
222
|
# <!-- List of items in the shopping -->
|
229
223
|
# <!-- cart -->
|
230
224
|
# <!-- Each item is defined by : -->
|
@@ -233,12 +227,10 @@ module ActiveMerchant
|
|
233
227
|
# <!-- - weight (mandatory) -->
|
234
228
|
# <!-- - description (mandatory) -->
|
235
229
|
# <!-- - ready to ship (optional) -->
|
236
|
-
|
230
|
+
|
237
231
|
def build_line_items(line_items)
|
238
|
-
|
239
|
-
|
232
|
+
XmlNode.new('lineItems') do |line_items_node|
|
240
233
|
line_items.each do |line_item|
|
241
|
-
|
242
234
|
line_items_node << XmlNode.new('item') do |item|
|
243
235
|
item << XmlNode.new('quantity', 1)
|
244
236
|
item << XmlNode.new('weight', line_item.kilograms)
|
@@ -247,19 +239,16 @@ module ActiveMerchant
|
|
247
239
|
item << XmlNode.new('height', line_item.cm(:height).to_s)
|
248
240
|
item << XmlNode.new('description', line_item.options[:description] || ' ')
|
249
241
|
item << XmlNode.new('readyToShip', line_item.options[:ready_to_ship] || nil)
|
250
|
-
|
251
242
|
# By setting the 'readyToShip' tag to true, Sell Online will not pack this item in the boxes defined in the merchant profile.
|
252
243
|
end
|
253
244
|
end
|
254
245
|
end
|
255
|
-
|
256
|
-
xml_line_items
|
257
246
|
end
|
258
|
-
|
247
|
+
|
259
248
|
def dollar_amount(cents)
|
260
249
|
"%0.2f" % (cents / 100.0)
|
261
250
|
end
|
262
|
-
|
251
|
+
|
263
252
|
def handle_non_iso_country_names(country)
|
264
253
|
NON_ISO_COUNTRY_NAMES[country.to_s] || country
|
265
254
|
end
|
@@ -2,7 +2,6 @@ require 'cgi'
|
|
2
2
|
|
3
3
|
module ActiveMerchant
|
4
4
|
module Shipping
|
5
|
-
|
6
5
|
class CanadaPostPWS < Carrier
|
7
6
|
@@name = "Canada Post PWS"
|
8
7
|
|
@@ -38,14 +37,14 @@ module ActiveMerchant
|
|
38
37
|
RATE_MIMETYPE = "application/vnd.cpc.ship.rate+xml"
|
39
38
|
TRACK_MIMETYPE = "application/vnd.cpc.track+xml"
|
40
39
|
REGISTER_MIMETYPE = "application/vnd.cpc.registration+xml"
|
41
|
-
|
40
|
+
|
42
41
|
LANGUAGE = {
|
43
42
|
'en' => 'en-CA',
|
44
43
|
'fr' => 'fr-CA'
|
45
44
|
}
|
46
|
-
|
47
|
-
SHIPPING_OPTIONS = [:d2po, :d2po_office_id, :cov, :cov_amount, :cod, :cod_amount, :cod_includes_shipping,
|
48
|
-
:cod_method_of_payment, :so, :dc, :dns, :pa18, :pa19, :hfp, :lad,
|
45
|
+
|
46
|
+
SHIPPING_OPTIONS = [:d2po, :d2po_office_id, :cov, :cov_amount, :cod, :cod_amount, :cod_includes_shipping,
|
47
|
+
:cod_method_of_payment, :so, :dc, :dns, :pa18, :pa19, :hfp, :lad,
|
49
48
|
:rase, :rts, :aban]
|
50
49
|
|
51
50
|
RATES_OPTIONS = [:cov, :cov_amount, :cod, :so, :dc, :dns, :pa18, :pa19, :hfp, :lad]
|
@@ -61,11 +60,11 @@ module ActiveMerchant
|
|
61
60
|
@customer_number = options[:customer_number]
|
62
61
|
super(options)
|
63
62
|
end
|
64
|
-
|
63
|
+
|
65
64
|
def requirements
|
66
65
|
[:api_key, :secret]
|
67
66
|
end
|
68
|
-
|
67
|
+
|
69
68
|
def find_rates(origin, destination, line_items = [], options = {}, package = nil, services = [])
|
70
69
|
url = endpoint + "rs/ship/price"
|
71
70
|
request = build_rates_request(origin, destination, line_items, options, package, services)
|
@@ -74,7 +73,7 @@ module ActiveMerchant
|
|
74
73
|
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
|
75
74
|
error_response(e.response.body, CPPWSRateResponse)
|
76
75
|
end
|
77
|
-
|
76
|
+
|
78
77
|
def find_tracking_info(pin, options = {})
|
79
78
|
response = ssl_get(tracking_url(pin), headers(options, TRACK_MIMETYPE))
|
80
79
|
parse_tracking_response(response)
|
@@ -82,12 +81,12 @@ module ActiveMerchant
|
|
82
81
|
if e.response
|
83
82
|
error_response(e.response.body, CPPWSTrackingResponse)
|
84
83
|
else
|
85
|
-
CPPWSTrackingResponse.new(false, e.message, {},
|
84
|
+
CPPWSTrackingResponse.new(false, e.message, {}, :carrier => @@name)
|
86
85
|
end
|
87
|
-
rescue InvalidPinFormatError
|
88
|
-
CPPWSTrackingResponse.new(false, "Invalid Pin Format", {},
|
86
|
+
rescue InvalidPinFormatError
|
87
|
+
CPPWSTrackingResponse.new(false, "Invalid Pin Format", {}, :carrier => @@name)
|
89
88
|
end
|
90
|
-
|
89
|
+
|
91
90
|
# line_items should be a list of PackageItem's
|
92
91
|
def create_shipment(origin, destination, package, line_items = [], options = {})
|
93
92
|
request_body = build_shipment_request(origin, destination, package, line_items, options)
|
@@ -95,20 +94,20 @@ module ActiveMerchant
|
|
95
94
|
parse_shipment_response(response)
|
96
95
|
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
|
97
96
|
error_response(e.response.body, CPPWSShippingResponse)
|
98
|
-
rescue MissingCustomerNumberError
|
99
|
-
CPPWSShippingResponse.new(false, "Missing Customer Number", {},
|
97
|
+
rescue MissingCustomerNumberError
|
98
|
+
CPPWSShippingResponse.new(false, "Missing Customer Number", {}, :carrier => @@name)
|
100
99
|
end
|
101
100
|
|
102
101
|
def retrieve_shipment(shipping_id, options = {})
|
103
102
|
response = ssl_post(shipment_url(shipping_id, options), nil, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
|
104
|
-
|
103
|
+
parse_shipment_response(response)
|
105
104
|
end
|
106
105
|
|
107
106
|
def find_shipment_receipt(shipping_id, options = {})
|
108
107
|
response = ssl_get(shipment_receipt_url(shipping_id, options), headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
|
109
|
-
|
108
|
+
parse_shipment_receipt_response(response)
|
110
109
|
end
|
111
|
-
|
110
|
+
|
112
111
|
def retrieve_shipping_label(shipping_response, options = {})
|
113
112
|
raise MissingShippingNumberError unless shipping_response && shipping_response.shipping_id
|
114
113
|
ssl_get(shipping_response.label_url, headers(options, "application/pdf"))
|
@@ -116,7 +115,7 @@ module ActiveMerchant
|
|
116
115
|
|
117
116
|
def register_merchant(options = {})
|
118
117
|
url = endpoint + "ot/token"
|
119
|
-
response = ssl_post(url, nil, headers({}, REGISTER_MIMETYPE, REGISTER_MIMETYPE).merge(
|
118
|
+
response = ssl_post(url, nil, headers({}, REGISTER_MIMETYPE, REGISTER_MIMETYPE).merge("Content-Length" => "0"))
|
120
119
|
parse_register_token_response(response)
|
121
120
|
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
|
122
121
|
error_response(e.response.body, CPPWSRegisterResponse)
|
@@ -154,7 +153,7 @@ module ActiveMerchant
|
|
154
153
|
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
|
155
154
|
error_response(e.response.body, CPPWSRateResponse)
|
156
155
|
end
|
157
|
-
|
156
|
+
|
158
157
|
def maximum_weight
|
159
158
|
Mass.new(MAX_WEIGHT, :kilograms)
|
160
159
|
end
|
@@ -163,8 +162,8 @@ module ActiveMerchant
|
|
163
162
|
|
164
163
|
def parse_services_response(response)
|
165
164
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
166
|
-
service_nodes = doc.elements['services'].elements.collect('service') {|node| node }
|
167
|
-
|
165
|
+
service_nodes = doc.elements['services'].elements.collect('service') { |node| node }
|
166
|
+
service_nodes.inject({}) do |result, node|
|
168
167
|
service_code = node.get_text("service-code").to_s
|
169
168
|
service_name = node.get_text("service-name").to_s
|
170
169
|
service_link = node.elements["link"].attributes['href']
|
@@ -176,7 +175,6 @@ module ActiveMerchant
|
|
176
175
|
}
|
177
176
|
result
|
178
177
|
end
|
179
|
-
services
|
180
178
|
end
|
181
179
|
|
182
180
|
def parse_service_options_response(response)
|
@@ -186,7 +184,7 @@ module ActiveMerchant
|
|
186
184
|
service_name = service_node.get_text("service-name").to_s
|
187
185
|
options_node = service_node.elements['options']
|
188
186
|
unless options_node.blank?
|
189
|
-
option_nodes = options_node.elements.collect('option') {|node| node}
|
187
|
+
option_nodes = options_node.elements.collect('option') { |node| node }
|
190
188
|
options = option_nodes.inject([]) do |result, node|
|
191
189
|
option = {
|
192
190
|
:code => node.get_text("option-code").to_s,
|
@@ -209,7 +207,7 @@ module ActiveMerchant
|
|
209
207
|
:min_height => dimensions_node.elements["height"].attributes['min'].to_f,
|
210
208
|
:max_height => dimensions_node.elements["height"].attributes['max'].to_f,
|
211
209
|
:min_width => dimensions_node.elements["width"].attributes['min'].to_f,
|
212
|
-
:max_width => dimensions_node.elements["width"].attributes['max'].to_f
|
210
|
+
:max_width => dimensions_node.elements["width"].attributes['max'].to_f
|
213
211
|
}
|
214
212
|
|
215
213
|
{
|
@@ -223,8 +221,8 @@ module ActiveMerchant
|
|
223
221
|
def parse_option_response(response)
|
224
222
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
225
223
|
option_node = doc.elements['option']
|
226
|
-
conflicts = option_node.elements['conflicting-options'].elements.collect('option-code') {|node| node.get_text.to_s} unless option_node.elements['conflicting-options'].blank?
|
227
|
-
prereqs = option_node.elements['prerequisite-options'].elements.collect('option-code') {|node| node.get_text.to_s} unless option_node.elements['prerequisite-options'].blank?
|
224
|
+
conflicts = option_node.elements['conflicting-options'].elements.collect('option-code') { |node| node.get_text.to_s } unless option_node.elements['conflicting-options'].blank?
|
225
|
+
prereqs = option_node.elements['prerequisite-options'].elements.collect('option-code') { |node| node.get_text.to_s } unless option_node.elements['prerequisite-options'].blank?
|
228
226
|
option = {
|
229
227
|
:code => option_node.get_text('option-code').to_s,
|
230
228
|
:name => option_node.get_text('option-name').to_s,
|
@@ -262,7 +260,7 @@ module ActiveMerchant
|
|
262
260
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
263
261
|
raise ActiveMerchant::Shipping::ResponseError, "No Quotes" unless doc.elements['price-quotes']
|
264
262
|
|
265
|
-
quotes = doc.elements['price-quotes'].elements.collect('price-quote') {|node| node }
|
263
|
+
quotes = doc.elements['price-quotes'].elements.collect('price-quote') { |node| node }
|
266
264
|
rates = quotes.map do |node|
|
267
265
|
service_name = node.get_text("service-name").to_s
|
268
266
|
service_code = node.get_text("service-code").to_s
|
@@ -279,14 +277,13 @@ module ActiveMerchant
|
|
279
277
|
CPPWSRateResponse.new(true, "", {}, :rates => rates)
|
280
278
|
end
|
281
279
|
|
282
|
-
|
283
280
|
# tracking
|
284
|
-
|
281
|
+
|
285
282
|
def parse_tracking_response(response)
|
286
283
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
287
284
|
raise ActiveMerchant::Shipping::ResponseError, "No Tracking" unless root_node = doc.elements['tracking-detail']
|
288
285
|
|
289
|
-
events = root_node.elements['significant-events'].elements.collect('occurrence') {|node| node }
|
286
|
+
events = root_node.elements['significant-events'].elements.collect('occurrence') { |node| node }
|
290
287
|
|
291
288
|
shipment_events = build_tracking_events(events)
|
292
289
|
change_date = root_node.get_text('changed-expected-date').to_s
|
@@ -307,7 +304,7 @@ module ActiveMerchant
|
|
307
304
|
:destination => destination,
|
308
305
|
:customer_number => root_node.get_text('mailed-by-customer-number').to_s
|
309
306
|
}
|
310
|
-
|
307
|
+
|
311
308
|
CPPWSTrackingResponse.new(true, "", {}, options)
|
312
309
|
end
|
313
310
|
|
@@ -320,12 +317,11 @@ module ActiveMerchant
|
|
320
317
|
time = Time.utc(timestamp.utc.year, timestamp.utc.month, timestamp.utc.day, timestamp.utc.hour, timestamp.utc.min, timestamp.utc.sec)
|
321
318
|
message = event.get_text('event-description').to_s
|
322
319
|
location = [event.get_text('event-retail-name'), event.get_text('event-site'), event.get_text('event-province')].compact.join(", ")
|
323
|
-
name = event.get_text('event-identifier').to_s
|
320
|
+
name = event.get_text('event-identifier').to_s
|
324
321
|
ShipmentEvent.new(name, time, location, message)
|
325
322
|
end
|
326
323
|
end
|
327
324
|
|
328
|
-
|
329
325
|
# shipping
|
330
326
|
|
331
327
|
# options
|
@@ -334,7 +330,7 @@ module ActiveMerchant
|
|
334
330
|
# :packing_instructions
|
335
331
|
# :show_postage_rate
|
336
332
|
# :cod, :cod_amount, :insurance, :insurance_amount, :signature_required, :pa18, :pa19, :hfp, :dns, :lad
|
337
|
-
#
|
333
|
+
#
|
338
334
|
def build_shipment_request(origin, destination, package, line_items = [], options = {})
|
339
335
|
origin = sanitize_location(origin)
|
340
336
|
destination = sanitize_location(destination)
|
@@ -368,11 +364,10 @@ module ActiveMerchant
|
|
368
364
|
node << XmlNode.new('contact-phone', location.phone)
|
369
365
|
node << XmlNode.new('address-details') do |innernode|
|
370
366
|
innernode << XmlNode.new('address-line-1', location.address1)
|
371
|
-
|
372
|
-
innernode << XmlNode.new('address-line-2', address2) unless address2.blank?
|
367
|
+
innernode << XmlNode.new('address-line-2', location.address2_and_3) unless location.address2_and_3.blank?
|
373
368
|
innernode << XmlNode.new('city', location.city)
|
374
|
-
innernode << XmlNode.new('prov-state', location.province)
|
375
|
-
#innernode << XmlNode.new('country-code', location.country_code)
|
369
|
+
innernode << XmlNode.new('prov-state', location.province)
|
370
|
+
# innernode << XmlNode.new('country-code', location.country_code)
|
376
371
|
innernode << XmlNode.new('postal-zip-code', location.postal_code)
|
377
372
|
end
|
378
373
|
end
|
@@ -385,8 +380,7 @@ module ActiveMerchant
|
|
385
380
|
node << XmlNode.new('client-voice-number', location.phone)
|
386
381
|
node << XmlNode.new('address-details') do |innernode|
|
387
382
|
innernode << XmlNode.new('address-line-1', location.address1)
|
388
|
-
|
389
|
-
innernode << XmlNode.new('address-line-2', address2) unless address2.blank?
|
383
|
+
innernode << XmlNode.new('address-line-2', location.address2_and_3) unless location.address2_and_3.blank?
|
390
384
|
innernode << XmlNode.new('city', location.city)
|
391
385
|
innernode << XmlNode.new('prov-state', location.province) unless location.province.blank?
|
392
386
|
innernode << XmlNode.new('country-code', location.country_code)
|
@@ -412,7 +406,7 @@ module ActiveMerchant
|
|
412
406
|
def shipment_preferences_node(options)
|
413
407
|
XmlNode.new('preferences') do |node|
|
414
408
|
node << XmlNode.new('show-packing-instructions', options[:packing_instructions] || true)
|
415
|
-
node << XmlNode.new('show-postage-rate', options[:show_postage_rate] || false)
|
409
|
+
node << XmlNode.new('show-postage-rate', options[:show_postage_rate] || false)
|
416
410
|
node << XmlNode.new('show-insured-value', true)
|
417
411
|
end
|
418
412
|
end
|
@@ -428,17 +422,17 @@ module ActiveMerchant
|
|
428
422
|
|
429
423
|
XmlNode.new('customs') do |node|
|
430
424
|
currency = options[:currency] || "CAD"
|
431
|
-
node << XmlNode.new('currency',currency)
|
432
|
-
node << XmlNode.new('conversion-from-cad',options[:conversion_from_cad].to_s) if currency != 'CAD' && options[:conversion_from_cad]
|
433
|
-
node << XmlNode.new('reason-for-export','SOG') # SOG - Sale of Goods
|
434
|
-
node << XmlNode.new('other-reason',options[:customs_other_reason]) if
|
435
|
-
node << XmlNode.new('additional-customs-info',options[:customs_addition_info]) if options[:customs_addition_info]
|
425
|
+
node << XmlNode.new('currency', currency)
|
426
|
+
node << XmlNode.new('conversion-from-cad', options[:conversion_from_cad].to_s) if currency != 'CAD' && options[:conversion_from_cad]
|
427
|
+
node << XmlNode.new('reason-for-export', 'SOG') # SOG - Sale of Goods
|
428
|
+
node << XmlNode.new('other-reason', options[:customs_other_reason]) if options[:customs_reason_for_export] && options[:customs_other_reason]
|
429
|
+
node << XmlNode.new('additional-customs-info', options[:customs_addition_info]) if options[:customs_addition_info]
|
436
430
|
node << XmlNode.new('sku-list') do |sku|
|
437
431
|
line_items.each do |line_item|
|
438
432
|
sku << XmlNode.new('item') do |item|
|
439
433
|
item << XmlNode.new('hs-tariff-code', line_item.hs_code) if line_item.hs_code && !line_item.hs_code.empty?
|
440
434
|
item << XmlNode.new('sku', line_item.sku) if line_item.sku && !line_item.sku.empty?
|
441
|
-
item << XmlNode.new('customs-description', line_item.name.slice(0,44))
|
435
|
+
item << XmlNode.new('customs-description', line_item.name.slice(0, 44))
|
442
436
|
item << XmlNode.new('unit-weight', '%#2.3f' % sanitize_weight_kg(line_item.kg))
|
443
437
|
item << XmlNode.new('customs-value-per-unit', '%.2f' % sanitize_price_from_cents(line_item.value))
|
444
438
|
item << XmlNode.new('customs-number-of-units', line_item.quantity)
|
@@ -447,20 +441,20 @@ module ActiveMerchant
|
|
447
441
|
end
|
448
442
|
end
|
449
443
|
end
|
450
|
-
|
444
|
+
|
451
445
|
end
|
452
446
|
end
|
453
447
|
|
454
|
-
def shipment_parcel_node(package, options ={})
|
448
|
+
def shipment_parcel_node(package, options = {})
|
455
449
|
weight = sanitize_weight_kg(package.kilograms.to_f)
|
456
450
|
XmlNode.new('parcel-characteristics') do |el|
|
457
451
|
el << XmlNode.new('weight', "%#2.3f" % weight)
|
458
452
|
pkg_dim = package.cm
|
459
|
-
if pkg_dim && !pkg_dim.select{|x| x != 0}.empty?
|
453
|
+
if pkg_dim && !pkg_dim.select { |x| x != 0 }.empty?
|
460
454
|
el << XmlNode.new('dimensions') do |dim|
|
461
|
-
dim << XmlNode.new('length', '%.1f' % ((pkg_dim[2]*10).round / 10.0)) if pkg_dim.size >= 3
|
462
|
-
dim << XmlNode.new('width', '%.1f' % ((pkg_dim[1]*10).round / 10.0)) if pkg_dim.size >= 2
|
463
|
-
dim << XmlNode.new('height', '%.1f' % ((pkg_dim[0]*10).round / 10.0)) if pkg_dim.size >= 1
|
455
|
+
dim << XmlNode.new('length', '%.1f' % ((pkg_dim[2] * 10).round / 10.0)) if pkg_dim.size >= 3
|
456
|
+
dim << XmlNode.new('width', '%.1f' % ((pkg_dim[1] * 10).round / 10.0)) if pkg_dim.size >= 2
|
457
|
+
dim << XmlNode.new('height', '%.1f' % ((pkg_dim[0] * 10).round / 10.0)) if pkg_dim.size >= 1
|
464
458
|
end
|
465
459
|
end
|
466
460
|
el << XmlNode.new('document', false)
|
@@ -469,10 +463,9 @@ module ActiveMerchant
|
|
469
463
|
end
|
470
464
|
end
|
471
465
|
|
472
|
-
|
473
466
|
def parse_shipment_response(response)
|
474
467
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
475
|
-
raise ActiveMerchant::Shipping::ResponseError, "No Shipping" unless root_node = doc.elements['non-contract-shipment-info']
|
468
|
+
raise ActiveMerchant::Shipping::ResponseError, "No Shipping" unless root_node = doc.elements['non-contract-shipment-info']
|
476
469
|
options = {
|
477
470
|
:shipping_id => root_node.get_text('shipment-id').to_s,
|
478
471
|
:tracking_number => root_node.get_text('tracking-pin').to_s,
|
@@ -485,7 +478,7 @@ module ActiveMerchant
|
|
485
478
|
|
486
479
|
def parse_register_token_response(response)
|
487
480
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
488
|
-
raise ActiveMerchant::Shipping::ResponseError, "No Registration Token" unless root_node = doc.elements['token']
|
481
|
+
raise ActiveMerchant::Shipping::ResponseError, "No Registration Token" unless root_node = doc.elements['token']
|
489
482
|
options = {
|
490
483
|
:token_id => root_node.get_text('token-id').to_s
|
491
484
|
}
|
@@ -526,13 +519,13 @@ module ActiveMerchant
|
|
526
519
|
:expected_transit_days => service_standard_node.get_text("expected-transit-time").to_s.to_i,
|
527
520
|
:expected_delivery_date => service_standard_node.get_text("expected-delivery-date").to_s
|
528
521
|
}
|
529
|
-
option_nodes = root.elements['priced-options'].elements.collect('priced-option') {|node| node} unless root.elements['priced-options'].blank?
|
522
|
+
option_nodes = root.elements['priced-options'].elements.collect('priced-option') { |node| node } unless root.elements['priced-options'].blank?
|
530
523
|
|
531
524
|
receipt[:priced_options] = if option_nodes
|
532
525
|
option_nodes.inject({}) do |result, node|
|
533
526
|
result[node.get_text("option-code").to_s] = node.get_text("option-price").to_s.to_f
|
534
527
|
result
|
535
|
-
|
528
|
+
end
|
536
529
|
else
|
537
530
|
[]
|
538
531
|
end
|
@@ -542,10 +535,10 @@ module ActiveMerchant
|
|
542
535
|
|
543
536
|
def error_response(response, response_klass)
|
544
537
|
doc = REXML::Document.new(REXML::Text::unnormalize(response))
|
545
|
-
messages = doc.elements['messages'].elements.collect('message') {|node| node }
|
546
|
-
message = messages.map {|m| m.get_text('description').to_s }.join(", ")
|
547
|
-
code = messages.map {|m| m.get_text('code').to_s }.join(", ")
|
548
|
-
response_klass.new(false, message, {},
|
538
|
+
messages = doc.elements['messages'].elements.collect('message') { |node| node }
|
539
|
+
message = messages.map { |m| m.get_text('description').to_s }.join(", ")
|
540
|
+
code = messages.map { |m| m.get_text('code').to_s }.join(", ")
|
541
|
+
response_klass.new(false, message, {}, :carrier => @@name, :code => code)
|
549
542
|
end
|
550
543
|
|
551
544
|
def log(msg)
|
@@ -556,7 +549,7 @@ module ActiveMerchant
|
|
556
549
|
|
557
550
|
def tracking_url(pin)
|
558
551
|
case pin.length
|
559
|
-
when 12,13,16
|
552
|
+
when 12, 13, 16
|
560
553
|
endpoint + "vis/track/pin/%s/detail" % pin
|
561
554
|
when 15
|
562
555
|
endpoint + "vis/track/dnc/%s/detail" % pin
|
@@ -574,7 +567,7 @@ module ActiveMerchant
|
|
574
567
|
end
|
575
568
|
end
|
576
569
|
|
577
|
-
def shipment_url(shipping_id, options={})
|
570
|
+
def shipment_url(shipping_id, options = {})
|
578
571
|
raise MissingCustomerNumberError unless customer_number = options[:customer_number]
|
579
572
|
if @platform_id.present?
|
580
573
|
endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}"
|
@@ -583,7 +576,7 @@ module ActiveMerchant
|
|
583
576
|
end
|
584
577
|
end
|
585
578
|
|
586
|
-
def shipment_receipt_url(shipping_id, options={})
|
579
|
+
def shipment_receipt_url(shipping_id, options = {})
|
587
580
|
raise MissingCustomerNumberError unless customer_number = options[:customer_number]
|
588
581
|
if @platform_id.present?
|
589
582
|
endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}/receipt"
|
@@ -592,7 +585,7 @@ module ActiveMerchant
|
|
592
585
|
end
|
593
586
|
end
|
594
587
|
|
595
|
-
def services_url(country=nil, service_code=nil)
|
588
|
+
def services_url(country = nil, service_code = nil)
|
596
589
|
url = endpoint + "rs/ship/service"
|
597
590
|
url += "/#{service_code}" if service_code
|
598
591
|
url += "?country=#{country}" if country
|
@@ -610,11 +603,11 @@ module ActiveMerchant
|
|
610
603
|
"Basic %s" % Base64.encode64("#{@options[:api_key]}:#{@options[:secret]}")
|
611
604
|
end
|
612
605
|
end
|
613
|
-
|
606
|
+
|
614
607
|
def headers(customer_credentials, accept = nil, content_type = nil)
|
615
608
|
headers = {
|
616
609
|
'Authorization' => encoded_authorization(customer_credentials),
|
617
|
-
'Accept-Language' => language
|
610
|
+
'Accept-Language' => language
|
618
611
|
}
|
619
612
|
headers['Accept'] = accept if accept
|
620
613
|
headers['Content-Type'] = content_type if content_type
|
@@ -638,17 +631,17 @@ module ActiveMerchant
|
|
638
631
|
XmlNode.new("expected-mailing-date", date_as_string)
|
639
632
|
end
|
640
633
|
|
641
|
-
def parcel_node(line_items, package = nil, options ={})
|
634
|
+
def parcel_node(line_items, package = nil, options = {})
|
642
635
|
weight = sanitize_weight_kg(package && !package.kilograms.zero? ? package.kilograms.to_f : line_items.sum(&:kilograms).to_f)
|
643
636
|
XmlNode.new('parcel-characteristics') do |el|
|
644
637
|
el << XmlNode.new('weight', "%#2.3f" % weight)
|
645
638
|
if package
|
646
639
|
pkg_dim = package.cm
|
647
|
-
if pkg_dim && !pkg_dim.select{|x| x != 0}.empty?
|
640
|
+
if pkg_dim && !pkg_dim.select { |x| x != 0 }.empty?
|
648
641
|
el << XmlNode.new('dimensions') do |dim|
|
649
|
-
dim << XmlNode.new('length', '%.1f' % ((pkg_dim[2]*10).round / 10.0)) if pkg_dim.size >= 3
|
650
|
-
dim << XmlNode.new('width', '%.1f' % ((pkg_dim[1]*10).round / 10.0)) if pkg_dim.size >= 2
|
651
|
-
dim << XmlNode.new('height', '%.1f' % ((pkg_dim[0]*10).round / 10.0)) if pkg_dim.size >= 1
|
642
|
+
dim << XmlNode.new('length', '%.1f' % ((pkg_dim[2] * 10).round / 10.0)) if pkg_dim.size >= 3
|
643
|
+
dim << XmlNode.new('width', '%.1f' % ((pkg_dim[1] * 10).round / 10.0)) if pkg_dim.size >= 2
|
644
|
+
dim << XmlNode.new('height', '%.1f' % ((pkg_dim[0] * 10).round / 10.0)) if pkg_dim.size >= 1
|
652
645
|
end
|
653
646
|
end
|
654
647
|
end
|
@@ -691,7 +684,7 @@ module ActiveMerchant
|
|
691
684
|
|
692
685
|
def services_node(services)
|
693
686
|
XmlNode.new('services') do |node|
|
694
|
-
services.each {|code| node << XmlNode.new('service-code', code)}
|
687
|
+
services.each { |code| node << XmlNode.new('service-code', code) }
|
695
688
|
end
|
696
689
|
end
|
697
690
|
|
@@ -731,7 +724,7 @@ module ActiveMerchant
|
|
731
724
|
end
|
732
725
|
end
|
733
726
|
end
|
734
|
-
|
727
|
+
|
735
728
|
def expected_date_from_node(node)
|
736
729
|
if service = node.elements['service-standard']
|
737
730
|
expected_date = service.get_text("expected-delivery-date").to_s
|
@@ -753,17 +746,17 @@ module ActiveMerchant
|
|
753
746
|
|
754
747
|
def sanitize_zip(hash)
|
755
748
|
[:postal_code, :zip].each do |attr|
|
756
|
-
hash[attr].gsub!(/\s+/,'') if hash[attr]
|
749
|
+
hash[attr].gsub!(/\s+/, '') if hash[attr]
|
757
750
|
end
|
758
751
|
hash
|
759
752
|
end
|
760
753
|
|
761
754
|
def sanitize_weight_kg(kg)
|
762
|
-
|
755
|
+
kg == 0 ? 0.001 : kg
|
763
756
|
end
|
764
757
|
|
765
758
|
def sanitize_price_from_cents(value)
|
766
|
-
|
759
|
+
value == 0 ? 0.01 : value.round / 100.0
|
767
760
|
end
|
768
761
|
|
769
762
|
def origin_hash_for(root_node)
|
@@ -819,14 +812,13 @@ module ActiveMerchant
|
|
819
812
|
end
|
820
813
|
|
821
814
|
def delivered?
|
822
|
-
!
|
815
|
+
!delivered_event.nil?
|
823
816
|
end
|
824
817
|
|
825
818
|
def actual_delivery_time
|
826
819
|
delivered_event.time if delivered?
|
827
820
|
end
|
828
821
|
|
829
|
-
|
830
822
|
private
|
831
823
|
|
832
824
|
def delivered_event
|
@@ -878,6 +870,5 @@ module ActiveMerchant
|
|
878
870
|
class MissingCustomerNumberError < StandardError; end
|
879
871
|
class MissingShippingNumberError < StandardError; end
|
880
872
|
class MissingTokenIdError < StandardError; end
|
881
|
-
|
882
873
|
end
|
883
874
|
end
|