active_shipping 0.12.6 → 1.0.0.pre1

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/{CHANGELOG → CHANGELOG.md} +6 -2
  5. data/CONTRIBUTING.md +32 -0
  6. data/{README.markdown → README.md} +45 -61
  7. data/lib/active_shipping.rb +20 -28
  8. data/lib/active_shipping/carrier.rb +82 -0
  9. data/lib/active_shipping/carriers.rb +33 -0
  10. data/lib/active_shipping/carriers/benchmark_carrier.rb +31 -0
  11. data/lib/active_shipping/carriers/bogus_carrier.rb +12 -0
  12. data/lib/active_shipping/carriers/canada_post.rb +253 -0
  13. data/lib/active_shipping/carriers/canada_post_pws.rb +870 -0
  14. data/lib/active_shipping/carriers/fedex.rb +579 -0
  15. data/lib/active_shipping/carriers/kunaki.rb +164 -0
  16. data/lib/active_shipping/carriers/new_zealand_post.rb +262 -0
  17. data/lib/active_shipping/carriers/shipwire.rb +181 -0
  18. data/lib/active_shipping/carriers/stamps.rb +861 -0
  19. data/lib/active_shipping/carriers/ups.rb +648 -0
  20. data/lib/active_shipping/carriers/usps.rb +642 -0
  21. data/lib/active_shipping/errors.rb +7 -0
  22. data/lib/active_shipping/label_response.rb +23 -0
  23. data/lib/active_shipping/location.rb +149 -0
  24. data/lib/active_shipping/package.rb +241 -0
  25. data/lib/active_shipping/rate_estimate.rb +64 -0
  26. data/lib/active_shipping/rate_response.rb +13 -0
  27. data/lib/active_shipping/response.rb +41 -0
  28. data/lib/active_shipping/shipment_event.rb +17 -0
  29. data/lib/active_shipping/shipment_packer.rb +73 -0
  30. data/lib/active_shipping/shipping_response.rb +12 -0
  31. data/lib/active_shipping/tracking_response.rb +52 -0
  32. data/lib/active_shipping/version.rb +1 -1
  33. data/lib/vendor/quantified/test/length_test.rb +2 -2
  34. data/lib/vendor/xml_node/test/test_parsing.rb +1 -1
  35. metadata +58 -36
  36. metadata.gz.sig +0 -0
  37. data/lib/active_shipping/shipping/base.rb +0 -13
  38. data/lib/active_shipping/shipping/carrier.rb +0 -84
  39. data/lib/active_shipping/shipping/carriers.rb +0 -23
  40. data/lib/active_shipping/shipping/carriers/benchmark_carrier.rb +0 -33
  41. data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +0 -14
  42. data/lib/active_shipping/shipping/carriers/canada_post.rb +0 -257
  43. data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +0 -874
  44. data/lib/active_shipping/shipping/carriers/fedex.rb +0 -581
  45. data/lib/active_shipping/shipping/carriers/kunaki.rb +0 -166
  46. data/lib/active_shipping/shipping/carriers/new_zealand_post.rb +0 -262
  47. data/lib/active_shipping/shipping/carriers/shipwire.rb +0 -184
  48. data/lib/active_shipping/shipping/carriers/stamps.rb +0 -864
  49. data/lib/active_shipping/shipping/carriers/ups.rb +0 -650
  50. data/lib/active_shipping/shipping/carriers/usps.rb +0 -649
  51. data/lib/active_shipping/shipping/errors.rb +0 -9
  52. data/lib/active_shipping/shipping/label_response.rb +0 -25
  53. data/lib/active_shipping/shipping/location.rb +0 -152
  54. data/lib/active_shipping/shipping/package.rb +0 -243
  55. data/lib/active_shipping/shipping/rate_estimate.rb +0 -66
  56. data/lib/active_shipping/shipping/rate_response.rb +0 -15
  57. data/lib/active_shipping/shipping/response.rb +0 -43
  58. data/lib/active_shipping/shipping/shipment_event.rb +0 -19
  59. data/lib/active_shipping/shipping/shipment_packer.rb +0 -75
  60. data/lib/active_shipping/shipping/shipping_response.rb +0 -14
  61. data/lib/active_shipping/shipping/tracking_response.rb +0 -54
@@ -0,0 +1,13 @@
1
+ module ActiveShipping
2
+ class RateResponse < Response
3
+ attr_reader :rates
4
+
5
+ def initialize(success, message, params = {}, options = {})
6
+ @rates = Array(options[:estimates] || options[:rates] || options[:rate_estimates])
7
+ super
8
+ end
9
+
10
+ alias_method :estimates, :rates
11
+ alias_method :rate_estimates, :rates
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ module ActiveShipping #:nodoc:
2
+ class Error < ActiveUtils::ActiveUtilsError
3
+ end
4
+
5
+ class ResponseError < Error
6
+ attr_reader :response
7
+
8
+ def initialize(response = nil)
9
+ if response.is_a? Response
10
+ super(response.message)
11
+ @response = response
12
+ else
13
+ super(response)
14
+ end
15
+ end
16
+ end
17
+
18
+ class Response
19
+ attr_reader :params
20
+ attr_reader :message
21
+ attr_reader :test
22
+ attr_reader :xml
23
+ attr_reader :request
24
+
25
+ def initialize(success, message, params = {}, options = {})
26
+ @success, @message, @params = success, message, params.stringify_keys
27
+ @test = options[:test] || false
28
+ @xml = options[:xml]
29
+ @request = options[:request]
30
+ raise ResponseError.new(self) unless success
31
+ end
32
+
33
+ def success?
34
+ @success ? true : false
35
+ end
36
+
37
+ def test?
38
+ @test ? true : false
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveShipping
2
+ class ShipmentEvent
3
+ attr_reader :name, :time, :location, :message
4
+
5
+ def initialize(name, time, location, message = nil)
6
+ @name, @time, @location, @message = name, time, location, message
7
+ end
8
+
9
+ def delivered?
10
+ status == :delivered
11
+ end
12
+
13
+ def status
14
+ @status ||= name.downcase.gsub("\s", "_").to_sym
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,73 @@
1
+ module ActiveShipping
2
+ class ShipmentPacker
3
+ class OverweightItem < StandardError
4
+ end
5
+
6
+ EXCESS_PACKAGE_QUANTITY_THRESHOLD = 10_000
7
+ class ExcessPackageQuantity < StandardError; end
8
+
9
+ # items - array of hashes containing quantity, grams and price.
10
+ # ex. [{:quantity => 2, :price => 1.0, :grams => 50}]
11
+ # dimensions - [5.0, 15.0, 30.0]
12
+ # maximum_weight - maximum weight in grams
13
+ # currency - ISO currency code
14
+ def self.pack(items, dimensions, maximum_weight, currency)
15
+ return [] if items.empty?
16
+ packages = []
17
+
18
+ # Naive in that it assumes weight is equally distributed across all items
19
+ # Should raise early enough in most cases
20
+ total_weight = 0
21
+ items.map!(&:symbolize_keys).each do |item|
22
+ total_weight += item[:quantity].to_i * item[:grams].to_i
23
+
24
+ if item[:grams].to_i > maximum_weight
25
+ raise OverweightItem, "The item with weight of #{item[:grams]}g is heavier than the allowable package weight of #{maximum_weight}g"
26
+ end
27
+
28
+ if total_weight > maximum_weight * EXCESS_PACKAGE_QUANTITY_THRESHOLD
29
+ raise ExcessPackageQuantity, "Unable to pack more than #{EXCESS_PACKAGE_QUANTITY_THRESHOLD} packages"
30
+ end
31
+ end
32
+
33
+ items = items.map(&:dup).sort_by! { |i| i[:grams].to_i }
34
+
35
+ state = :package_empty
36
+ while state != :packing_finished
37
+ case state
38
+ when :package_empty
39
+ package_weight, package_value = 0, 0
40
+ state = :filling_package
41
+ when :filling_package
42
+ items.each do |item|
43
+ quantity = if item[:grams].to_i <= 0
44
+ item[:quantity].to_i
45
+ else
46
+ # Grab the max amount of this item we can fit into this package
47
+ # Or, if there are fewer than the max for this item, put
48
+ # what is left into this package
49
+ [(maximum_weight - package_weight) / item[:grams].to_i, item[:quantity].to_i].min
50
+ end
51
+
52
+ item_weight = quantity * item[:grams].to_i
53
+ item_value = quantity * Package.cents_from(item[:price])
54
+
55
+ package_weight += item_weight
56
+ package_value += item_value
57
+
58
+ item[:quantity] = item[:quantity].to_i - quantity
59
+ end
60
+
61
+ items.reject! { |i| i[:quantity].to_i == 0 }
62
+
63
+ state = :package_full
64
+ when :package_full
65
+ packages << ActiveShipping::Package.new(package_weight, dimensions, :value => package_value, :currency => currency)
66
+ state = items.any? ? :package_empty : :packing_finished
67
+ end
68
+ end
69
+
70
+ packages
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,12 @@
1
+ module ActiveShipping
2
+ class ShippingResponse < Response
3
+ attr_reader :shipping_id # string
4
+ attr_reader :tracking_number # string
5
+
6
+ def initialize(success, message, params = {}, options = {})
7
+ @shipping_id = options[:shipping_id]
8
+ @tracking_number = options[:tracking_number]
9
+ super
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,52 @@
1
+ module ActiveShipping
2
+ class TrackingResponse < Response
3
+ attr_reader :carrier # symbol
4
+ attr_reader :carrier_name # string
5
+ attr_reader :status # symbol
6
+ attr_reader :status_code # string
7
+ attr_reader :status_description # string
8
+ attr_reader :ship_time # time
9
+ attr_reader :scheduled_delivery_date # time
10
+ attr_reader :actual_delivery_date # time
11
+ attr_reader :delivery_signature # string
12
+ attr_reader :tracking_number # string
13
+ attr_reader :shipment_events # array of ShipmentEvents in chronological order
14
+ attr_reader :shipper_address, :origin, :destination # Location objects
15
+
16
+ def initialize(success, message, params = {}, options = {})
17
+ @carrier = options[:carrier].parameterize.to_sym
18
+ @carrier_name = options[:carrier]
19
+ @status = options[:status]
20
+ @status_code = options[:status_code]
21
+ @status_description = options[:status_description]
22
+ @ship_time = options[:ship_time]
23
+ @scheduled_delivery_date = options[:scheduled_delivery_date]
24
+ @actual_delivery_date = options[:actual_delivery_date]
25
+ @delivery_signature = options[:delivery_signature]
26
+ @tracking_number = options[:tracking_number]
27
+ @shipment_events = Array(options[:shipment_events])
28
+ @shipper_address = options[:shipper_address]
29
+ @origin = options[:origin]
30
+ @destination = options[:destination]
31
+ super
32
+ end
33
+
34
+ def latest_event
35
+ @shipment_events.last
36
+ end
37
+
38
+ def is_delivered?
39
+ @status == :delivered
40
+ end
41
+
42
+ def has_exception?
43
+ @status == :exception
44
+ end
45
+
46
+ alias_method(:exception_event, :latest_event)
47
+ alias_method(:delivered?, :is_delivered?)
48
+ alias_method(:exception?, :has_exception?)
49
+ alias_method(:scheduled_delivery_time, :scheduled_delivery_date)
50
+ alias_method(:actual_delivery_time, :actual_delivery_date)
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveShipping
2
- VERSION = "0.12.6"
2
+ VERSION = "1.0.0.pre1"
3
3
  end
@@ -75,10 +75,10 @@ class LengthTest < Test::Unit::TestCase
75
75
  end
76
76
 
77
77
  def test_numeric_methods_not_added_for_some_units
78
- assert_raises NoMethodError do
78
+ assert_raises(NoMethodError) do
79
79
  2.yards
80
80
  end
81
- assert_raises NoMethodError do
81
+ assert_raises(NoMethodError) do
82
82
  2.millimetres
83
83
  end
84
84
  end
@@ -6,7 +6,7 @@ require File.dirname(__FILE__) + "/../lib/xml_node"
6
6
 
7
7
  class TestXmlNode < Test::Unit::TestCase
8
8
  def test_parse_sanity
9
- assert_raise(ArgumentError) { XmlNode.parse }
9
+ assert_raises(ArgumentError) { XmlNode.parse }
10
10
  assert_nothing_raised { XmlNode.parse('<feed/>') }
11
11
  end
12
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_shipping
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.6
4
+ version: 1.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James MacAulay
@@ -10,8 +10,30 @@ authors:
10
10
  - Jimmy Baker
11
11
  autorequire:
12
12
  bindir: bin
13
- cert_chain: []
14
- date: 2015-06-03 00:00:00.000000000 Z
13
+ cert_chain:
14
+ - |
15
+ -----BEGIN CERTIFICATE-----
16
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZhZG1p
17
+ bnMxFzAVBgoJkiaJk/IsZAEZFgdzaG9waWZ5MRMwEQYKCZImiZPyLGQBGRYDY29t
18
+ MB4XDTE0MDUxNTIwMzM0OFoXDTE1MDUxNTIwMzM0OFowPzEPMA0GA1UEAwwGYWRt
19
+ aW5zMRcwFQYKCZImiZPyLGQBGRYHc2hvcGlmeTETMBEGCgmSJomT8ixkARkWA2Nv
20
+ bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0/81O3e1vh5smcwp2G
21
+ MpLQ6q0kejQLa65bPYPxdzWA1SYOKyGfw+yR9LdFzsuKpwWzKq6zX35lj1IckWS4
22
+ bNBEQzxmufUxU0XPM02haFB8fOfDJzdXsWte9Ge4IFwahwn68gpMqN+BvxL+KMYz
23
+ Iut9YmN44d4LZdsENEIO5vmybuG2vYDz7R56qB0PA+Q2P2CdhymsBad2DQs69FBo
24
+ uico9V6VMYYctL9lCYdzu9IXrOYNTt88suKIVzzAlHOKeN0Ng5qdztFoTR8sfxDr
25
+ Ydg3KHl5n47wlpgd8R0f/4b5gGxW+v9pyJCgQnLlRu7DedVSvv7+GMtj3g9r3nhJ
26
+ KqECAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFI/o
27
+ maf34HXbUOQsdoLHacEKQgunMB0GA1UdEQQWMBSBEmFkbWluc0BzaG9waWZ5LmNv
28
+ bTAdBgNVHRIEFjAUgRJhZG1pbnNAc2hvcGlmeS5jb20wDQYJKoZIhvcNAQEFBQAD
29
+ ggEBADkK9aj5T0HPExsov4EoMWFnO+G7RQ28C30VAfKxnL2UxG6i4XMHVs6Xi94h
30
+ qXFw1ec9Y2eDUqaolT3bviOk9BB197+A8Vz/k7MC6ci2NE+yDDB7HAC8zU6LAx8Y
31
+ Iqvw7B/PSZ/pz4bUVFlTATif4mi1vO3lidRkdHRtM7UePSn2rUpOi0gtXBP3bLu5
32
+ YjHJN7wx5cugMEyroKITG5gL0Nxtu21qtOlHX4Hc4KdE2JqzCPOsS4zsZGhgwhPs
33
+ fl3hbtVFTqbOlwL9vy1fudXcolIE/ZTcxQ+er07ZFZdKCXayR9PPs64heamfn0fp
34
+ TConQSX2BnZdhIEYW+cKzEC/bLc=
35
+ -----END CERTIFICATE-----
36
+ date: 2015-01-07 00:00:00.000000000 Z
15
37
  dependencies:
16
38
  - !ruby/object:Gem::Dependency
17
39
  name: activesupport
@@ -19,14 +41,14 @@ dependencies:
19
41
  requirements:
20
42
  - - ">="
21
43
  - !ruby/object:Gem::Version
22
- version: 2.3.5
44
+ version: '3.2'
23
45
  type: :runtime
24
46
  prerelease: false
25
47
  version_requirements: !ruby/object:Gem::Requirement
26
48
  requirements:
27
49
  - - ">="
28
50
  - !ruby/object:Gem::Version
29
- version: 2.3.5
51
+ version: '3.2'
30
52
  - !ruby/object:Gem::Dependency
31
53
  name: i18n
32
54
  requirement: !ruby/object:Gem::Requirement
@@ -47,14 +69,14 @@ dependencies:
47
69
  requirements:
48
70
  - - "~>"
49
71
  - !ruby/object:Gem::Version
50
- version: 2.2.0
72
+ version: 3.0.0.pre2
51
73
  type: :runtime
52
74
  prerelease: false
53
75
  version_requirements: !ruby/object:Gem::Requirement
54
76
  requirements:
55
77
  - - "~>"
56
78
  - !ruby/object:Gem::Version
57
- version: 2.2.0
79
+ version: 3.0.0.pre2
58
80
  - !ruby/object:Gem::Dependency
59
81
  name: builder
60
82
  requirement: !ruby/object:Gem::Requirement
@@ -89,14 +111,14 @@ dependencies:
89
111
  requirements:
90
112
  - - "~>"
91
113
  - !ruby/object:Gem::Version
92
- version: 4.7.5
114
+ version: '5.0'
93
115
  type: :development
94
116
  prerelease: false
95
117
  version_requirements: !ruby/object:Gem::Requirement
96
118
  requirements:
97
119
  - - "~>"
98
120
  - !ruby/object:Gem::Version
99
- version: 4.7.5
121
+ version: '5.0'
100
122
  - !ruby/object:Gem::Dependency
101
123
  name: rake
102
124
  requirement: !ruby/object:Gem::Requirement
@@ -160,35 +182,35 @@ executables: []
160
182
  extensions: []
161
183
  extra_rdoc_files: []
162
184
  files:
163
- - CHANGELOG
185
+ - CHANGELOG.md
186
+ - CONTRIBUTING.md
164
187
  - MIT-LICENSE
165
- - README.markdown
188
+ - README.md
166
189
  - lib/active_shipping.rb
167
- - lib/active_shipping/shipping/base.rb
168
- - lib/active_shipping/shipping/carrier.rb
169
- - lib/active_shipping/shipping/carriers.rb
170
- - lib/active_shipping/shipping/carriers/benchmark_carrier.rb
171
- - lib/active_shipping/shipping/carriers/bogus_carrier.rb
172
- - lib/active_shipping/shipping/carriers/canada_post.rb
173
- - lib/active_shipping/shipping/carriers/canada_post_pws.rb
174
- - lib/active_shipping/shipping/carriers/fedex.rb
175
- - lib/active_shipping/shipping/carriers/kunaki.rb
176
- - lib/active_shipping/shipping/carriers/new_zealand_post.rb
177
- - lib/active_shipping/shipping/carriers/shipwire.rb
178
- - lib/active_shipping/shipping/carriers/stamps.rb
179
- - lib/active_shipping/shipping/carriers/ups.rb
180
- - lib/active_shipping/shipping/carriers/usps.rb
181
- - lib/active_shipping/shipping/errors.rb
182
- - lib/active_shipping/shipping/label_response.rb
183
- - lib/active_shipping/shipping/location.rb
184
- - lib/active_shipping/shipping/package.rb
185
- - lib/active_shipping/shipping/rate_estimate.rb
186
- - lib/active_shipping/shipping/rate_response.rb
187
- - lib/active_shipping/shipping/response.rb
188
- - lib/active_shipping/shipping/shipment_event.rb
189
- - lib/active_shipping/shipping/shipment_packer.rb
190
- - lib/active_shipping/shipping/shipping_response.rb
191
- - lib/active_shipping/shipping/tracking_response.rb
190
+ - lib/active_shipping/carrier.rb
191
+ - lib/active_shipping/carriers.rb
192
+ - lib/active_shipping/carriers/benchmark_carrier.rb
193
+ - lib/active_shipping/carriers/bogus_carrier.rb
194
+ - lib/active_shipping/carriers/canada_post.rb
195
+ - lib/active_shipping/carriers/canada_post_pws.rb
196
+ - lib/active_shipping/carriers/fedex.rb
197
+ - lib/active_shipping/carriers/kunaki.rb
198
+ - lib/active_shipping/carriers/new_zealand_post.rb
199
+ - lib/active_shipping/carriers/shipwire.rb
200
+ - lib/active_shipping/carriers/stamps.rb
201
+ - lib/active_shipping/carriers/ups.rb
202
+ - lib/active_shipping/carriers/usps.rb
203
+ - lib/active_shipping/errors.rb
204
+ - lib/active_shipping/label_response.rb
205
+ - lib/active_shipping/location.rb
206
+ - lib/active_shipping/package.rb
207
+ - lib/active_shipping/rate_estimate.rb
208
+ - lib/active_shipping/rate_response.rb
209
+ - lib/active_shipping/response.rb
210
+ - lib/active_shipping/shipment_event.rb
211
+ - lib/active_shipping/shipment_packer.rb
212
+ - lib/active_shipping/shipping_response.rb
213
+ - lib/active_shipping/tracking_response.rb
192
214
  - lib/active_shipping/version.rb
193
215
  - lib/certs/eParcel.dtd
194
216
  - lib/vendor/quantified/MIT-LICENSE
Binary file
@@ -1,13 +0,0 @@
1
- module ActiveMerchant
2
- module Shipping
3
- module Base
4
- mattr_accessor :mode
5
- self.mode = :production
6
-
7
- def self.carrier(name)
8
- ActiveMerchant::Shipping::Carriers.all.find { |c| c.name.downcase == name.to_s.downcase } ||
9
- raise(NameError, "unknown carrier #{name}")
10
- end
11
- end
12
- end
13
- end
@@ -1,84 +0,0 @@
1
- module ActiveMerchant
2
- module Shipping
3
- class Carrier
4
- include RequiresParameters
5
- include PostsData
6
- include Quantified
7
-
8
- attr_reader :last_request
9
- attr_accessor :test_mode
10
- alias_method :test_mode?, :test_mode
11
-
12
- # Credentials should be in options hash under keys :login, :password and/or :key.
13
- def initialize(options = {})
14
- requirements.each { |key| requires!(options, key) }
15
- @options = options
16
- @last_request = nil
17
- @test_mode = @options[:test]
18
- end
19
-
20
- # Override to return required keys in options hash for initialize method.
21
- def requirements
22
- []
23
- end
24
-
25
- # Override with whatever you need to get the rates
26
- def find_rates(origin, destination, packages, options = {})
27
- end
28
-
29
- # Override with whatever you need to get a shipping label
30
- def create_shipment(origin, destination, packages, options = {})
31
- end
32
-
33
- # Validate credentials with a call to the API. By default this just does a find_rates call
34
- # with the orgin and destination both as the carrier's default_location. Override to provide
35
- # alternate functionality, such as checking for test_mode to use test servers, etc.
36
- def valid_credentials?
37
- location = self.class.default_location
38
- find_rates(location, location, Package.new(100, [5, 15, 30]), :test => test_mode)
39
- rescue ActiveMerchant::Shipping::ResponseError
40
- false
41
- else
42
- true
43
- end
44
-
45
- def maximum_weight
46
- Mass.new(150, :pounds)
47
- end
48
-
49
- protected
50
-
51
- def node_text_or_nil(xml_node)
52
- xml_node ? xml_node.text : nil
53
- end
54
-
55
- # Override in subclasses for non-U.S.-based carriers.
56
- def self.default_location
57
- Location.new( :country => 'US',
58
- :state => 'CA',
59
- :city => 'Beverly Hills',
60
- :address1 => '455 N. Rexford Dr.',
61
- :address2 => '3rd Floor',
62
- :zip => '90210',
63
- :phone => '1-310-285-1013',
64
- :fax => '1-310-275-8159')
65
- end
66
-
67
- # Use after building the request to save for later inspection. Probably won't ever be overridden.
68
- def save_request(r)
69
- @last_request = r
70
- end
71
-
72
- def timestamp_from_business_day(days)
73
- return unless days
74
- date = DateTime.now.utc
75
- days.times do
76
- begin
77
- date = date + 1
78
- end while [0, 6].include?(date.wday)
79
- end
80
- date
81
- end
82
- end
83
- end
84
- end