active_shipping 0.12.6 → 1.0.0.pre1

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