active_shipping 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.markdown +10 -0
- data/lib/active_shipping.rb +1 -0
- data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +14 -7
- data/lib/active_shipping/shipping/carriers/fedex.rb +8 -2
- data/lib/active_shipping/shipping/carriers/ups.rb +19 -1
- data/lib/active_shipping/shipping/carriers/usps.rb +18 -2
- data/lib/active_shipping/shipping/errors.rb +9 -0
- data/lib/active_shipping/shipping/rate_estimate.rb +2 -0
- data/lib/active_shipping/shipping/shipment_packer.rb +4 -1
- data/lib/active_shipping/version.rb +1 -1
- data/lib/vendor/quantified/Rakefile +1 -9
- data/lib/vendor/quantified/lib/quantified/attribute.rb +4 -0
- data/lib/vendor/quantified/test/length_test.rb +5 -7
- data/lib/vendor/quantified/test/mass_test.rb +10 -2
- data/lib/vendor/quantified/test/test_helper.rb +10 -0
- metadata +24 -7
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### v0.10.1
|
2
|
+
- Canada Post PWS: Makes wrapper act more consistently with the rest of the API [jnormore]
|
3
|
+
- UPS: Adds insurance charge to package object declarations [pbonnell]
|
4
|
+
- USPS: Improves how unavailable delivery information is handled [cyu]
|
5
|
+
- Shipment Packer: Prevents packing errors and consistently return an array when packing [christianblais]
|
6
|
+
- General: Improves tests such that they work with ruby 2.0 [Sirupsen]
|
7
|
+
|
8
|
+
|
1
9
|
2011/04/21:
|
2
10
|
* USPS updated to use new APIs [james]
|
3
11
|
* new :gift boolean option for Package [james]
|
data/README.markdown
CHANGED
@@ -122,6 +122,16 @@ After you've pushed your well-tested changes to your github fork, make a pull re
|
|
122
122
|
* Cody Fauser (<http://codyfauser.com>)
|
123
123
|
* Jimmy Baker (<http://jimmyville.com/>)
|
124
124
|
* William Lang (<http://williamlang.net/>)
|
125
|
+
* Cameron Fowler
|
126
|
+
* Christopher Saunders (<http://christophersaunders.ca>)
|
127
|
+
* Denis Odorcic
|
128
|
+
* Dennis O'Connor
|
129
|
+
* Dennis Theisen
|
130
|
+
* Edward Ocampo-Gooding
|
131
|
+
* Isaac Kearse
|
132
|
+
* John Duff
|
133
|
+
* Nigel Ramsay
|
134
|
+
* Philip Arndt
|
125
135
|
|
126
136
|
## Legal Mumbo Jumbo
|
127
137
|
|
data/lib/active_shipping.rb
CHANGED
@@ -237,6 +237,7 @@ module ActiveMerchant
|
|
237
237
|
# rating
|
238
238
|
|
239
239
|
def build_rates_request(origin, destination, line_items = [], options = {}, package = nil, services = [])
|
240
|
+
line_items = Array(line_items)
|
240
241
|
xml = XmlNode.new('mailing-scenario', :xmlns => "http://www.canadapost.ca/ws/ship/rate") do |node|
|
241
242
|
node << customer_number_node(options)
|
242
243
|
node << contract_id_node(options)
|
@@ -329,9 +330,9 @@ module ActiveMerchant
|
|
329
330
|
# :show_postage_rate
|
330
331
|
# :cod, :cod_amount, :insurance, :insurance_amount, :signature_required, :pa18, :pa19, :hfp, :dns, :lad
|
331
332
|
#
|
332
|
-
def build_shipment_request(
|
333
|
-
origin =
|
334
|
-
destination =
|
333
|
+
def build_shipment_request(origin, destination, package, line_items = [], options = {})
|
334
|
+
origin = sanitize_location(origin)
|
335
|
+
destination = sanitize_location(destination)
|
335
336
|
|
336
337
|
xml = XmlNode.new('non-contract-shipment', :xmlns => "http://www.canadapost.ca/ws/ncshipment") do |root_node|
|
337
338
|
root_node << XmlNode.new('delivery-spec') do |node|
|
@@ -652,13 +653,13 @@ module ActiveMerchant
|
|
652
653
|
end
|
653
654
|
end
|
654
655
|
|
655
|
-
def origin_node(
|
656
|
-
origin =
|
656
|
+
def origin_node(location)
|
657
|
+
origin = sanitize_location(location)
|
657
658
|
XmlNode.new("origin-postal-code", origin.zip)
|
658
659
|
end
|
659
660
|
|
660
|
-
def destination_node(
|
661
|
-
destination =
|
661
|
+
def destination_node(location)
|
662
|
+
destination = sanitize_location(location)
|
662
663
|
case destination.country_code
|
663
664
|
when 'CA'
|
664
665
|
XmlNode.new('destination') do |node|
|
@@ -739,6 +740,12 @@ module ActiveMerchant
|
|
739
740
|
DateTime.strptime((options[:shipping_date] || Time.now).to_s, "%Y-%m-%d")
|
740
741
|
end
|
741
742
|
|
743
|
+
def sanitize_location(location)
|
744
|
+
location_hash = location.is_a?(Location) ? location.to_hash : location
|
745
|
+
location_hash = sanitize_zip(location_hash)
|
746
|
+
Location.new(location_hash)
|
747
|
+
end
|
748
|
+
|
742
749
|
def sanitize_zip(hash)
|
743
750
|
[:postal_code, :zip].each do |attr|
|
744
751
|
hash[attr].gsub!(/\s+/,'') if hash[attr]
|
@@ -265,7 +265,7 @@ module ActiveMerchant
|
|
265
265
|
rate_estimates = []
|
266
266
|
success, message = nil
|
267
267
|
|
268
|
-
xml =
|
268
|
+
xml = build_document(response)
|
269
269
|
root_node = xml.elements['RateReply']
|
270
270
|
|
271
271
|
success = response_success?(xml)
|
@@ -330,7 +330,7 @@ module ActiveMerchant
|
|
330
330
|
end
|
331
331
|
|
332
332
|
def parse_tracking_response(response, options)
|
333
|
-
xml =
|
333
|
+
xml = build_document(response)
|
334
334
|
root_node = xml.elements['TrackReply']
|
335
335
|
|
336
336
|
success = response_success?(xml)
|
@@ -462,6 +462,12 @@ module ActiveMerchant
|
|
462
462
|
|
463
463
|
Location.new(args)
|
464
464
|
end
|
465
|
+
|
466
|
+
def build_document(xml)
|
467
|
+
REXML::Document.new(xml)
|
468
|
+
rescue REXML::ParseException => e
|
469
|
+
raise ActiveMerchant::Shipping::ResponseContentError.new(e, xml)
|
470
|
+
end
|
465
471
|
end
|
466
472
|
end
|
467
473
|
end
|
@@ -208,6 +208,9 @@ module ActiveMerchant
|
|
208
208
|
package_weight << XmlNode.new("UnitOfMeasurement") do |units|
|
209
209
|
units << XmlNode.new("Code", imperial ? 'LBS' : 'KGS')
|
210
210
|
end
|
211
|
+
if package.value.present? && package.currency.present?
|
212
|
+
add_insured_node( package_node, currency:package.currency, value:(package.value.to_i/100) )
|
213
|
+
end
|
211
214
|
|
212
215
|
value = ((imperial ? package.lbs : package.kgs).to_f*1000).round/1000.0 # 3 decimals
|
213
216
|
package_weight << XmlNode.new("Weight", [value,0.1].max)
|
@@ -273,6 +276,21 @@ module ActiveMerchant
|
|
273
276
|
end
|
274
277
|
end
|
275
278
|
|
279
|
+
def add_insured_node(*args)
|
280
|
+
params, package_node = args.extract_options!, args[0]
|
281
|
+
currency, value = params[:currency], params[:value].to_i
|
282
|
+
package_node << XmlNode.new("PackageServiceOptions") do |package_service_options|
|
283
|
+
package_service_options << XmlNode.new("DeclaredValue") do |declared_value|
|
284
|
+
declared_value << XmlNode.new("CurrencyCode", currency)
|
285
|
+
declared_value << XmlNode.new("MonetaryValue", (value.to_i))
|
286
|
+
end
|
287
|
+
package_service_options << XmlNode.new("InsuredValue") do |declared_value|
|
288
|
+
declared_value << XmlNode.new("CurrencyCode", currency)
|
289
|
+
declared_value << XmlNode.new("MonetaryValue", (value.to_i))
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
276
294
|
def parse_rate_response(origin, destination, packages, response, options={})
|
277
295
|
rates = []
|
278
296
|
|
@@ -287,10 +305,10 @@ module ActiveMerchant
|
|
287
305
|
service_code = rated_shipment.get_text('Service/Code').to_s
|
288
306
|
days_to_delivery = rated_shipment.get_text('GuaranteedDaysToDelivery').to_s.to_i
|
289
307
|
days_to_delivery = nil if days_to_delivery == 0
|
290
|
-
|
291
308
|
rate_estimates << RateEstimate.new(origin, destination, @@name,
|
292
309
|
service_name_for(origin, service_code),
|
293
310
|
:total_price => rated_shipment.get_text('TotalCharges/MonetaryValue').to_s.to_f,
|
311
|
+
:insurance_price => rated_shipment.get_text('ServiceOptionsCharges/MonetaryValue').to_s.to_f,
|
294
312
|
:currency => rated_shipment.get_text('TotalCharges/CurrencyCode').to_s,
|
295
313
|
:service_code => service_code,
|
296
314
|
:packages => packages,
|
@@ -125,6 +125,18 @@ module ActiveMerchant
|
|
125
125
|
"WS" => "Western Samoa"
|
126
126
|
}
|
127
127
|
|
128
|
+
STATUS_NODE_PATTERNS = %w(
|
129
|
+
*/*/TrackSummary
|
130
|
+
Error/Description
|
131
|
+
*/TrackInfo/Error/Description
|
132
|
+
)
|
133
|
+
|
134
|
+
RESPONSE_ERROR_MESSAGES = [
|
135
|
+
/There is no record of that mail item/,
|
136
|
+
/This Information has not been included in this Test Server\./,
|
137
|
+
/Delivery status information is not available/
|
138
|
+
]
|
139
|
+
|
128
140
|
def find_tracking_info(tracking_number, options={})
|
129
141
|
options = @options.update(options)
|
130
142
|
tracking_request = build_tracking_request(tracking_number, options)
|
@@ -584,12 +596,16 @@ module ActiveMerchant
|
|
584
596
|
end
|
585
597
|
|
586
598
|
def response_status_node(document)
|
587
|
-
|
599
|
+
STATUS_NODE_PATTERNS.each do |pattern|
|
600
|
+
if node = document.elements[pattern]
|
601
|
+
return node
|
602
|
+
end
|
603
|
+
end
|
588
604
|
end
|
589
605
|
|
590
606
|
def response_success?(document)
|
591
607
|
summary = response_status_node(document).get_text.to_s
|
592
|
-
!
|
608
|
+
!RESPONSE_ERROR_MESSAGES.detect { |re| summary =~ re }
|
593
609
|
end
|
594
610
|
|
595
611
|
def response_message(document)
|
@@ -14,6 +14,7 @@ module ActiveMerchant #:nodoc:
|
|
14
14
|
attr_reader :delivery_date # Usually only available for express shipments
|
15
15
|
attr_reader :delivery_range # Min and max delivery estimate in days
|
16
16
|
attr_reader :negotiated_rate
|
17
|
+
attr_reader :insurance_price
|
17
18
|
|
18
19
|
def initialize(origin, destination, carrier, service_name, options={})
|
19
20
|
@origin, @destination, @carrier, @service_name = origin, destination, carrier, service_name
|
@@ -29,6 +30,7 @@ module ActiveMerchant #:nodoc:
|
|
29
30
|
@delivery_range = options[:delivery_range] ? options[:delivery_range].map { |date| date_for(date) }.compact : []
|
30
31
|
@shipping_date = date_for(options[:shipping_date])
|
31
32
|
@delivery_date = @delivery_range.last
|
33
|
+
@insurance_price = Package.cents_from(options[:insurance_price])
|
32
34
|
end
|
33
35
|
|
34
36
|
def total_price
|
@@ -10,8 +10,11 @@ module ActiveMerchant
|
|
10
10
|
# maximum_weight - maximum weight in grams
|
11
11
|
# currency - ISO currency code
|
12
12
|
def self.pack(items, dimensions, maximum_weight, currency)
|
13
|
-
items = items.map(&:symbolize_keys).map { |item| [item] * item[:quantity].to_i }.flatten
|
14
13
|
packages = []
|
14
|
+
|
15
|
+
return packages if items.empty?
|
16
|
+
|
17
|
+
items = items.map(&:symbolize_keys).map { |item| [item] * item[:quantity].to_i }.flatten
|
15
18
|
state = :package_empty
|
16
19
|
|
17
20
|
while state != :packing_finished
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
3
|
|
5
4
|
desc 'Default: run unit tests.'
|
6
5
|
task :default => :test
|
@@ -8,14 +7,7 @@ task :default => :test
|
|
8
7
|
desc 'Test the plugin.'
|
9
8
|
Rake::TestTask.new(:test) do |t|
|
10
9
|
t.libs << 'lib'
|
10
|
+
t.libs << 'test'
|
11
11
|
t.pattern = 'test/**/*_test.rb'
|
12
12
|
t.verbose = true
|
13
13
|
end
|
14
|
-
|
15
|
-
desc 'Generate documentation for the calculations plugin.'
|
16
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = 'Quantified'
|
19
|
-
rdoc.options << '--line-numbers --inline-source'
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'test_helper'
|
2
2
|
require 'quantified/length'
|
3
3
|
|
4
4
|
class LengthTest < Test::Unit::TestCase
|
@@ -40,17 +40,15 @@ class LengthTest < Test::Unit::TestCase
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_convert_yards_to_millimetres
|
43
|
-
|
43
|
+
assert_in_epsilon Length.new(914.4, :millimetres).to_f, Length.new(1, :yards).to_millimetres.to_f
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_convert_millimetres_to_yards
|
47
|
-
|
47
|
+
assert_in_epsilon Length.new(1, :yards).to_f, Length.new(914.4, :millimetres).to_yards.to_f
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_convert_metres_to_inches
|
51
|
-
|
52
|
-
assert 1.inches.eql?((0.0254).metres.to_inches)
|
53
|
-
assert 1.inches.eql?((0.0254).metres.in_inches)
|
51
|
+
assert_in_epsilon 1.inches.to_f, (0.0254).metres.to_inches.to_f
|
54
52
|
end
|
55
53
|
|
56
54
|
def test_comparison_with_numeric
|
@@ -89,4 +87,4 @@ class LengthTest < Test::Unit::TestCase
|
|
89
87
|
assert_equal :metric, 2.centimetres.system
|
90
88
|
assert_equal :imperial, 2.feet.system
|
91
89
|
end
|
92
|
-
end
|
90
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'test_helper'
|
2
2
|
require 'quantified/mass'
|
3
3
|
|
4
4
|
class MassTest < Test::Unit::TestCase
|
@@ -85,4 +85,12 @@ class MassTest < Test::Unit::TestCase
|
|
85
85
|
assert_equal [:grams, :milligrams, :kilograms], Mass.units(:metric)
|
86
86
|
assert_equal [:ounces, :pounds, :stones, :short_tons], Mass.units(:imperial)
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
|
+
def test_right_side_comparison_with_fixnum
|
90
|
+
assert Mass.new(14, :grams) < 20
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_left_side_comparison_with_fixnum
|
94
|
+
assert 20 > Mass.new(14, :grams)
|
95
|
+
end
|
96
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'test/unit'
|
2
|
+
|
2
3
|
begin
|
3
4
|
require 'active_support/inflector'
|
4
5
|
rescue LoadError => e
|
@@ -8,3 +9,12 @@ rescue LoadError => e
|
|
8
9
|
end
|
9
10
|
|
10
11
|
require File.dirname(__FILE__) + '/../lib/quantified'
|
12
|
+
|
13
|
+
|
14
|
+
class Test::Unit::TestCase
|
15
|
+
EPSILON = 0.00001
|
16
|
+
|
17
|
+
def assert_in_epsilon(expected, actual, msg = nil)
|
18
|
+
assert_in_delta expected, actual, EPSILON, msg
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: active_shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.10.
|
5
|
+
version: 0.10.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- James MacAulay
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-08-23 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
prerelease: false
|
@@ -94,6 +94,22 @@ dependencies:
|
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: 1.5.1
|
96
96
|
none: false
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
prerelease: false
|
99
|
+
name: minitest
|
100
|
+
type: :development
|
101
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ~>
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 4.7.5
|
106
|
+
none: false
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 4.7.5
|
112
|
+
none: false
|
97
113
|
- !ruby/object:Gem::Dependency
|
98
114
|
prerelease: false
|
99
115
|
name: rake
|
@@ -116,15 +132,15 @@ dependencies:
|
|
116
132
|
type: :development
|
117
133
|
version_requirements: !ruby/object:Gem::Requirement
|
118
134
|
requirements:
|
119
|
-
- -
|
135
|
+
- - ~>
|
120
136
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
137
|
+
version: 0.14.0
|
122
138
|
none: false
|
123
139
|
requirement: !ruby/object:Gem::Requirement
|
124
140
|
requirements:
|
125
|
-
- -
|
141
|
+
- - ~>
|
126
142
|
- !ruby/object:Gem::Version
|
127
|
-
version:
|
143
|
+
version: 0.14.0
|
128
144
|
none: false
|
129
145
|
- !ruby/object:Gem::Dependency
|
130
146
|
prerelease: false
|
@@ -179,6 +195,7 @@ files:
|
|
179
195
|
- lib/active_shipping/shipping/carriers/usps.rb
|
180
196
|
- lib/active_shipping/shipping/carriers/usps.rb.orig
|
181
197
|
- lib/active_shipping/shipping/carriers.rb
|
198
|
+
- lib/active_shipping/shipping/errors.rb
|
182
199
|
- lib/active_shipping/shipping/location.rb
|
183
200
|
- lib/active_shipping/shipping/package.rb
|
184
201
|
- lib/active_shipping/shipping/rate_estimate.rb
|
@@ -225,7 +242,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
225
242
|
- !ruby/object:Gem::Version
|
226
243
|
segments:
|
227
244
|
- 0
|
228
|
-
hash:
|
245
|
+
hash: 4495588430750097686
|
229
246
|
version: '0'
|
230
247
|
none: false
|
231
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|