gun_broker 1.3.2 → 1.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37428cdf48dee77029ac60d1d952c99f4a3cc8bb
4
- data.tar.gz: 67b8e2d282ba3d25e79cbd942c9100892e54bb68
3
+ metadata.gz: c7c5d35e48c658ec3bb20f91f9324d87689576eb
4
+ data.tar.gz: 190619c274d40d9ca6c5ebc3b4a006262d8655ee
5
5
  SHA512:
6
- metadata.gz: 4f7fb34d4e93485b7f326df30229ff2f0126fc1703acc2dd5e56180ac7f170f238244822b0f61231dd5f60b2b23a2cf4e3fcacd6eb7127738e892a3bdf5f9d8e
7
- data.tar.gz: 3ff24c0755be1b05abe2ac403534fb9c59ea92acb56e76819f05dc83445ac6474471ce135aad5afc3bc132938d70d13478150e10cd531f40ed8304105ab456b5
6
+ metadata.gz: 560eab3e870fb03dd1f02909b89506a9e9f85b39199475081761811f23ce8b3c15eaa0a98bac1e6e32776949e679aa995aa62898da3be94956b20021e0a09688
7
+ data.tar.gz: 298d96e0ceb32d73c4b397a6049db34b0544aa411d19b07e3895fe821f7e2f9564721cd0d03960ecb8b9f5291248bca54792ae4b3d2dc827ca0ee279890bfb8c
@@ -6,6 +6,8 @@ require 'gun_broker/error'
6
6
  require 'gun_broker/feedback'
7
7
  require 'gun_broker/item'
8
8
  require 'gun_broker/items_as_page'
9
+ require 'gun_broker/order'
10
+ require 'gun_broker/orders_as_page'
9
11
  require 'gun_broker/response'
10
12
  require 'gun_broker/user'
11
13
 
@@ -15,8 +15,8 @@ module GunBroker
15
15
  # Used to return the maximum number of results from paginated responses.
16
16
  PAGE_SIZE = 300
17
17
 
18
- # Defaults to 12 (View Last 30 Days), so we need to specify 1 (View All Completed) to get everything.
19
- TIME_FRAME_FOR_ALL_RESULTS = 1
18
+ MAX_ITEMS_TIME_FRAME = 1
19
+ MAX_ORDERS_TIME_FRAME = 7
20
20
 
21
21
  USER_AGENT = "gun_broker rubygems.org/gems/gun_broker v(#{GunBroker::VERSION})"
22
22
 
@@ -0,0 +1,106 @@
1
+ module GunBroker
2
+ # Represents a GunBroker order (listing).
3
+ class Order
4
+
5
+ # TODO: Refactor this, #attributes, and #[] into a module.
6
+ # @return [Hash] Attributes parsed from the JSON response.
7
+ attr_reader :attrs
8
+
9
+ # @param order_id [Integer, String] The ID of the Order to find.
10
+ # @return [Order] An Order instance or `nil` if no Order with `order_id` exists.
11
+ def self.find(order_id, params = {}, headers = {})
12
+ find!(order_id, params, headers)
13
+ rescue GunBroker::Error::NotFound
14
+ nil
15
+ end
16
+
17
+ # Same as {.find} but raises GunBroker::Error::NotFound if no Order is found.
18
+ # @param (see .find)
19
+ # @raise [GunBroker::Error::NotFound] If no Order with `order_id` exists.
20
+ # @return (see .find)
21
+ def self.find!(order_id, params = {}, headers = {})
22
+ response = GunBroker::API.get("/Orders/#{order_id}", params, headers)
23
+ new(response.body)
24
+ end
25
+
26
+ # @param attrs [Hash] The JSON attributes from the API response.
27
+ def initialize(attrs = {})
28
+ @attrs = attrs
29
+ end
30
+
31
+ # @return [Hash] Attributes parsed from the JSON response.
32
+ def attributes
33
+ @attrs
34
+ end
35
+
36
+ # @return [Integer] The Order ID.
37
+ def id
38
+ @attrs['orderID']
39
+ end
40
+
41
+ # @return [String] FFL Number (if applicable) for this Order.
42
+ def ffl_number
43
+ @attrs['fflNumber']
44
+ end
45
+
46
+ # @return [Array] Item IDs of associated items for this Order.
47
+ def item_ids
48
+ @attrs['itemIDs']
49
+ end
50
+
51
+ # @return [Hash] Billing info for this Order.
52
+ def bill_to
53
+ {
54
+ name: @attrs['billToName'],
55
+ address_1: @attrs['billToAddress1'],
56
+ address_2: @attrs['billToAddress2'],
57
+ city: @attrs['billToCity'],
58
+ state: @attrs['billToState'],
59
+ zip: @attrs['billToPostalCode'],
60
+ email: @attrs['billToEmail'],
61
+ phone: @attrs['billToPhone']
62
+ }
63
+ end
64
+
65
+ # @return [Hash] Shipping info for this Order.
66
+ def ship_to
67
+ {
68
+ name: @attrs['shipToName'],
69
+ address_1: @attrs['shipToAddress1'],
70
+ address_2: @attrs['shipToAddress2'],
71
+ city: @attrs['shipToCity'],
72
+ state: @attrs['shipToState'],
73
+ zip: @attrs['shipToPostalCode'],
74
+ email: @attrs['shipToEmail'],
75
+ phone: @attrs['shipToPhone']
76
+ }
77
+ end
78
+
79
+ # @return [Float] Total shipping amount for this Order.
80
+ def shipping_total
81
+ @attrs['shipCost']
82
+ end
83
+
84
+ # @return [Float] Total sales tax for this Order.
85
+ def sales_tax_toal
86
+ @attrs['salesTaxTotal']
87
+ end
88
+
89
+ # @return [Float] Total sales amount for this Order.
90
+ def order_total
91
+ @attrs['orderTotal']
92
+ end
93
+
94
+ # @return [String] Payment methods used for this Order.
95
+ def payment_methods
96
+ @attrs['paymentMethod'].values
97
+ end
98
+
99
+ # @param key [String] An Order attribute name (from the JSON response).
100
+ # @return The value of the given `key` or `nil`.
101
+ def [](key)
102
+ @attrs[key]
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,22 @@
1
+ module GunBroker
2
+ # Represents a page of GunBroker orders.
3
+ class OrdersAsPage
4
+
5
+ # @param attrs [Hash] The attributes required to fetch orders from the API.
6
+ def initialize(attributes = {})
7
+ @attributes = attributes
8
+ end
9
+
10
+ # @return [Array<Order>]
11
+ def fetch_orders
12
+ @attributes[:params].merge!({
13
+ 'PageIndex' => @attributes[:page_index],
14
+ 'PageSize' => @attributes[:page_size],
15
+ })
16
+ response = GunBroker::API.get(@attributes[:endpoint], @attributes[:params], @attributes[:token_header])
17
+
18
+ response['results'].map { |result| GunBroker::Order.new(result) }
19
+ end
20
+
21
+ end
22
+ end
@@ -1,6 +1,8 @@
1
1
  require 'gun_broker/token_header'
2
2
  require 'gun_broker/user/items_delegate'
3
3
  require 'gun_broker/user/items_as_pages_delegate'
4
+ require 'gun_broker/user/orders_delegate'
5
+ require 'gun_broker/user/orders_as_pages_delegate'
4
6
 
5
7
  module GunBroker
6
8
  # Represents a GunBroker User.
@@ -94,6 +96,20 @@ module GunBroker
94
96
  @items_as_pages_delegate ||= ItemsAsPagesDelegate.new(self, options)
95
97
  end
96
98
 
99
+ # (see OrdersDelegate)
100
+ # See the {OrdersDelegate} docs.
101
+ # @return [OrdersDelegate]
102
+ def orders
103
+ @orders_delegate ||= OrdersDelegate.new(self)
104
+ end
105
+
106
+ # (see OrdersAsPagesDelegate)
107
+ # See the {OrdersAsPagesDelegate} docs.
108
+ # @return [OrdersAsPagesDelegate]
109
+ def orders_as_pages(options = {})
110
+ @orders_as_pages_delegate ||= OrdersAsPagesDelegate.new(self, options)
111
+ end
112
+
97
113
  private
98
114
 
99
115
  # @return [Boolean] `true` if `@username` is present and either `@password` *or* `@token` is present.
@@ -99,7 +99,7 @@ module GunBroker
99
99
  when :sellername
100
100
  { 'SellerName' => @user.username }
101
101
  when :timeframe
102
- { 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS }
102
+ { 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME }
103
103
  else
104
104
  raise GunBroker::Error.new 'Unrecognized `params_for` key.'
105
105
  end
@@ -180,7 +180,7 @@ module GunBroker
180
180
  when :sellername
181
181
  { 'SellerName' => @user.username }
182
182
  when :timeframe
183
- { 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS }
183
+ { 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME }
184
184
  when :itemid
185
185
  { 'ItemID' => (options[:item_id] || options["ItemID"]) }
186
186
  else
@@ -0,0 +1,56 @@
1
+ require 'gun_broker/token_header'
2
+
3
+ module GunBroker
4
+ class User
5
+ # Used to scope {OrdersAsPage} actions by {User}.
6
+ class OrdersAsPagesDelegate
7
+
8
+ include GunBroker::TokenHeader
9
+
10
+ # @param user [User] A {User} instance to scope order pages by.
11
+ # @param options [Hash] { orders_per_page => <number of desired orders per page> (Integer) }.
12
+ def initialize(user, options = {})
13
+ max_page_size = GunBroker::API::PAGE_SIZE
14
+ @user = user
15
+ @orders_per_page = options.fetch(:orders_per_page, max_page_size)
16
+
17
+ if @orders_per_page > max_page_size
18
+ raise ArgumentError.new("`orders_per_page` may not exceed #{max_page_size}")
19
+ end
20
+ end
21
+
22
+ # Returns pages for orders the User has sold.
23
+ # @note {API#get! GET} /OrdersSold
24
+ # @return [Array<OrdersAsPage>]
25
+ def sold
26
+ @sold ||= build_pages_for(:OrdersSold, { 'TimeFrame' => GunBroker::API::MAX_ORDERS_TIME_FRAME })
27
+ end
28
+
29
+ private
30
+
31
+ def build_pages_for(endpoint, params = {})
32
+ endpoint = ['/', endpoint.to_s].join
33
+ _token_header = token_header(@user.token)
34
+ response = GunBroker::API.get(endpoint, params.merge({ 'PageSize' => 1 }), _token_header)
35
+ number_of_pages = (response['count'] / @orders_per_page.to_f).ceil
36
+ orders_as_pages = []
37
+
38
+ number_of_pages.times do |page_number|
39
+ page_number += 1
40
+ attrs = {
41
+ page_size: @orders_per_page,
42
+ page_index: page_number,
43
+ endpoint: endpoint,
44
+ params: params,
45
+ token_header: _token_header
46
+ }
47
+
48
+ orders_as_pages << GunBroker::OrdersAsPage.new(attrs)
49
+ end
50
+
51
+ orders_as_pages
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,94 @@
1
+ require 'gun_broker/token_header'
2
+
3
+ module GunBroker
4
+ class User
5
+ # Used to scope {Order} actions by {User}.
6
+ class OrdersDelegate
7
+
8
+ include GunBroker::TokenHeader
9
+
10
+ # @param user [User] A {User} instance to scope orders by.
11
+ def initialize(user)
12
+ @user = user
13
+ end
14
+
15
+ # Finds a specific User's Order by ID. Calls {Order.find} to get full Order details.
16
+ # @raise (see #sold)
17
+ # @return [Order] Returns the Order or `nil` if no Order found.
18
+ def find(order_id)
19
+ GunBroker::Order.find(order_id, {}, token_header(@user.token))
20
+ end
21
+
22
+ # Same as {#find} but raises GunBroker::Error::NotFound if no order is found.
23
+ # @raise [GunBroker::Error::NotFound] If the User has no Order with `order_id`.
24
+ # @return [Order] Returns the Order.
25
+ def find!(order_id)
26
+ order = find(order_id)
27
+ raise GunBroker::Error::NotFound.new("Couldn't find order with ID '#{order_id}'") if order.nil?
28
+ order
29
+ end
30
+
31
+ # Sold Orders for the User.
32
+ # @param options [Hash] {ItemID=>ItemID}
33
+ # @note {API#get! GET} /OrdersSold
34
+ # @return [Array<Order>]
35
+ def sold(options = {})
36
+ params = [
37
+ *params_for(:timeframe),
38
+ *params_for(:itemid, options)
39
+ ].to_h
40
+
41
+ @sold ||= fetch_orders(:OrdersSold, params)
42
+ end
43
+
44
+ private
45
+
46
+ def fetch_orders(endpoint, params = {})
47
+ cleanup_nil_params(params)
48
+ params.merge!('PageSize' => GunBroker::API::PAGE_SIZE)
49
+
50
+ endpoint = ['/', endpoint.to_s].join
51
+ response = GunBroker::API.get(endpoint, params, token_header(@user.token))
52
+ number_of_pages = (response['count'] / GunBroker::API::PAGE_SIZE.to_f).ceil
53
+
54
+ if number_of_pages > 1
55
+ _orders_from_results = orders_from_results(response['results'])
56
+
57
+ number_of_pages.times do |page_number|
58
+ page_number += 1
59
+ next if page_number == 1
60
+
61
+ params.merge!({ 'PageIndex' => page_number })
62
+ response = GunBroker::API.get(endpoint, params, token_header(@user.token))
63
+ _orders_from_results.concat(orders_from_results(response['results']))
64
+ end
65
+
66
+ _orders_from_results
67
+ else
68
+ orders_from_results(response['results'])
69
+ end
70
+ end
71
+
72
+ def orders_from_results(results)
73
+ # TODO: Ignore non-US orders.
74
+ results.map { |result| GunBroker::Order.new(result) }
75
+ end
76
+
77
+ def params_for(key, options = {})
78
+ case key
79
+ when :timeframe
80
+ { 'TimeFrame' => GunBroker::API::MAX_ORDERS_TIME_FRAME }
81
+ when :itemid
82
+ { 'ItemID' => (options[:item_id] || options["ItemID"]) }
83
+ else
84
+ raise GunBroker::Error.new 'Unrecognized `params_for` key.'
85
+ end
86
+ end
87
+
88
+ def cleanup_nil_params(params)
89
+ params.delete_if { |k, v| v.nil? }
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module GunBroker
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -160,7 +160,7 @@ describe GunBroker::User::ItemsDelegate do
160
160
  headers: headers('X-AccessToken' => token),
161
161
  query: {
162
162
  'PageSize' => GunBroker::API::PAGE_SIZE,
163
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
163
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
164
164
  }
165
165
  )
166
166
  .to_return(body: response_fixture('items'))
@@ -178,7 +178,7 @@ describe GunBroker::User::ItemsDelegate do
178
178
  headers: headers('X-AccessToken' => token),
179
179
  query: {
180
180
  'PageSize' => GunBroker::API::PAGE_SIZE,
181
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
181
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
182
182
  }
183
183
  )
184
184
  .to_return(body: response_fixture('not_authorized'), status: 401)
@@ -199,7 +199,7 @@ describe GunBroker::User::ItemsDelegate do
199
199
  headers: headers('X-AccessToken' => token),
200
200
  query: {
201
201
  'PageSize' => GunBroker::API::PAGE_SIZE,
202
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
202
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
203
203
  }
204
204
  )
205
205
  .to_return(body: response_fixture('items'))
@@ -216,7 +216,7 @@ describe GunBroker::User::ItemsDelegate do
216
216
  query: {
217
217
  'PageSize' => GunBroker::API::PAGE_SIZE,
218
218
  'ItemID' => '123',
219
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
219
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
220
220
  }
221
221
  )
222
222
  .to_return(body: response_fixture('item_id'))
@@ -234,7 +234,7 @@ describe GunBroker::User::ItemsDelegate do
234
234
  headers: headers('X-AccessToken' => token),
235
235
  query: {
236
236
  'PageSize' => GunBroker::API::PAGE_SIZE,
237
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
237
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
238
238
  }
239
239
  )
240
240
  .to_return(body: response_fixture('not_authorized'), status: 401)
@@ -255,7 +255,7 @@ describe GunBroker::User::ItemsDelegate do
255
255
  headers: headers('X-AccessToken' => token),
256
256
  query: {
257
257
  'PageSize' => GunBroker::API::PAGE_SIZE,
258
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
258
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
259
259
  }
260
260
  )
261
261
  .to_return(body: response_fixture('items'))
@@ -273,7 +273,7 @@ describe GunBroker::User::ItemsDelegate do
273
273
  headers: headers('X-AccessToken' => token),
274
274
  query: {
275
275
  'PageSize' => GunBroker::API::PAGE_SIZE,
276
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
276
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
277
277
  }
278
278
  )
279
279
  .to_return(body: response_fixture('not_authorized'), status: 401)
@@ -294,7 +294,7 @@ describe GunBroker::User::ItemsDelegate do
294
294
  headers: headers('X-AccessToken' => token),
295
295
  query: {
296
296
  'PageSize' => GunBroker::API::PAGE_SIZE,
297
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
297
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
298
298
  }
299
299
  )
300
300
  .to_return(body: response_fixture('items'))
@@ -312,7 +312,7 @@ describe GunBroker::User::ItemsDelegate do
312
312
  headers: headers('X-AccessToken' => token),
313
313
  query: {
314
314
  'PageSize' => GunBroker::API::PAGE_SIZE,
315
- 'TimeFrame' => GunBroker::API::TIME_FRAME_FOR_ALL_RESULTS,
315
+ 'TimeFrame' => GunBroker::API::MAX_ITEMS_TIME_FRAME,
316
316
  }
317
317
  )
318
318
  .to_return(body: response_fixture('not_authorized'), status: 401)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gun_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Campbell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-22 00:00:00.000000000 Z
11
+ date: 2018-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -137,11 +137,15 @@ files:
137
137
  - lib/gun_broker/item.rb
138
138
  - lib/gun_broker/item/constants.rb
139
139
  - lib/gun_broker/items_as_page.rb
140
+ - lib/gun_broker/order.rb
141
+ - lib/gun_broker/orders_as_page.rb
140
142
  - lib/gun_broker/response.rb
141
143
  - lib/gun_broker/token_header.rb
142
144
  - lib/gun_broker/user.rb
143
145
  - lib/gun_broker/user/items_as_pages_delegate.rb
144
146
  - lib/gun_broker/user/items_delegate.rb
147
+ - lib/gun_broker/user/orders_as_pages_delegate.rb
148
+ - lib/gun_broker/user/orders_delegate.rb
145
149
  - lib/gun_broker/version.rb
146
150
  - spec/fixtures/authenticate.json
147
151
  - spec/fixtures/categories.json