lightspeed_pos 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +57 -29
- data/bin/console +15 -7
- data/lib/lightspeed/account.rb +44 -43
- data/lib/lightspeed/accounts.rb +22 -0
- data/lib/lightspeed/categories.rb +5 -5
- data/lib/lightspeed/category.rb +16 -7
- data/lib/lightspeed/client.rb +37 -26
- data/lib/lightspeed/collection.rb +218 -0
- data/lib/lightspeed/employee.rb +25 -0
- data/lib/lightspeed/employees.rb +8 -0
- data/lib/lightspeed/{errors.rb → error.rb} +2 -1
- data/lib/lightspeed/image.rb +35 -0
- data/lib/lightspeed/images.rb +16 -0
- data/lib/lightspeed/inventories.rb +8 -0
- data/lib/lightspeed/inventory.rb +12 -0
- data/lib/lightspeed/item.rb +54 -18
- data/lib/lightspeed/item_attribute_set.rb +13 -0
- data/lib/lightspeed/item_attribute_sets.rb +8 -0
- data/lib/lightspeed/item_matrices.rb +4 -3
- data/lib/lightspeed/item_matrix.rb +48 -10
- data/lib/lightspeed/items.rb +4 -7
- data/lib/lightspeed/order.rb +34 -0
- data/lib/lightspeed/orders.rb +10 -0
- data/lib/lightspeed/prices.rb +43 -0
- data/lib/lightspeed/request.rb +74 -28
- data/lib/lightspeed/request_throttler.rb +31 -0
- data/lib/lightspeed/resource.rb +221 -0
- data/lib/lightspeed/sale.rb +57 -0
- data/lib/lightspeed/sale_line.rb +52 -0
- data/lib/lightspeed/sale_lines.rb +9 -0
- data/lib/lightspeed/sales.rb +10 -0
- data/lib/lightspeed/shop.rb +30 -0
- data/lib/lightspeed/shops.rb +8 -0
- data/lib/lightspeed/special_order.rb +22 -0
- data/lib/lightspeed/special_orders.rb +10 -0
- data/lib/lightspeed/vendor.rb +23 -0
- data/lib/lightspeed/vendors.rb +9 -0
- data/lib/lightspeed/version.rb +1 -1
- data/lib/lightspeed_pos.rb +2 -4
- data/lightspeed_pos.gemspec +3 -3
- data/script/buildkite +11 -0
- data/script/docker_tests +29 -0
- metadata +63 -24
- data/lib/lightspeed/account_resources.rb +0 -103
- data/lib/lightspeed/base.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3960f7c39629798ffae0406f84fb2cbcf897390
|
4
|
+
data.tar.gz: f900f23a42324bf61268b0ab4f43ac0528971c38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e7e1f10edaa984d5e232c9706f32e3b6d13bb8cae0cb3c5e00f773335493a3372085e7d85c7411ccb425f20fe8ab341d98075273d39f5e418d839b32cf99478
|
7
|
+
data.tar.gz: 856a6628c9c7c4dd36b10e25a253bc394230600e5632c3e961242a285e9154d34b99564fb063e06ebf376feb7ffd74ddd7397faaa9a2e20a08206f4e7a02e474
|
data/README.markdown
CHANGED
@@ -1,23 +1,13 @@
|
|
1
1
|
# Lightspeed POS
|
2
2
|
|
3
|
-
[
|
4
|
-
[![Code Climate](https://codeclimate.com/github/radar/lightspeed-pos/badges/gpa.svg)](https://codeclimate.com/github/radar/lightspeed-pos)
|
3
|
+
An _unofficial_ gem for interacting with [Lightspeed's Point of Sale API](http://www.lightspeedpos.com/retail/help/developers/api/basics/), ([documentation](http://cloud-docs.lightspeedapp.com/API/APIHelp.help)).
|
5
4
|
|
6
|
-
|
7
|
-
An _unofficial_ gem for interacting with [Lightspeed's Point of Sale API](http://www.lightspeedpos.com/retail/help/developers/api/basics/). Works with API keys for the time being.
|
8
|
-
|
9
|
-
Most definitely not production ready yet, but you can help by submitting pull requests!
|
5
|
+
Not all endpoints are implemented yet, but you can help by submitting pull requests!
|
10
6
|
|
11
7
|
## Getting Started
|
12
8
|
|
13
9
|
First, intialize a new client:
|
14
10
|
|
15
|
-
```ruby
|
16
|
-
client = Lightspeed::Client.new(api_key: "YOUR_API_KEY_HERE")
|
17
|
-
```
|
18
|
-
|
19
|
-
**OR** you may also choose to pass through an OAuth access token if you have one:
|
20
|
-
|
21
11
|
```ruby
|
22
12
|
client = Lightspeed::Client.new(oauth_token: "YOUR_ACCESS_TOKEN_HERE")
|
23
13
|
```
|
@@ -25,22 +15,33 @@ client = Lightspeed::Client.new(oauth_token: "YOUR_ACCESS_TOKEN_HERE")
|
|
25
15
|
Next, make a request for your accounts:
|
26
16
|
|
27
17
|
```ruby
|
28
|
-
accounts = client.accounts
|
18
|
+
accounts = client.accounts.all
|
29
19
|
```
|
30
20
|
|
31
21
|
Pick the account you want to use, and then start using it:
|
32
22
|
|
33
23
|
```ruby
|
34
24
|
account = accounts.first
|
35
|
-
account.items
|
25
|
+
account.items.first
|
36
26
|
```
|
37
27
|
|
38
|
-
##
|
28
|
+
## Resources
|
39
29
|
|
40
|
-
|
30
|
+
resources share a common API. Resources that are currently supported by this library are:
|
41
31
|
|
32
|
+
* Accounts
|
42
33
|
* Categories
|
34
|
+
* Employees
|
43
35
|
* Items
|
36
|
+
* Item Matrices
|
37
|
+
* Item Attribute Sets
|
38
|
+
* Images
|
39
|
+
* Inventories
|
40
|
+
* Orders
|
41
|
+
* Sales
|
42
|
+
* Shops
|
43
|
+
* Special Orders
|
44
|
+
* Vendors
|
44
45
|
|
45
46
|
To work with account resources, you first need to fetch an account. The examples below are for items, but will also work with other types listed above.
|
46
47
|
|
@@ -52,6 +53,28 @@ You can fetch a list of items with this:
|
|
52
53
|
account.items.all
|
53
54
|
```
|
54
55
|
|
56
|
+
You can pass query parameters to this by using the `params` keyword:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
account.items.all(params: { itemMatrixID: 0 })
|
60
|
+
```
|
61
|
+
|
62
|
+
You can enumerate over a group of 100 resources at a time (the max in a single request) using `each_page`
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
account.items.each_page! do |items|
|
66
|
+
# ItemImporter.import(items)
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Or enumerate over each resource using #each (this still only does a request for each 100 items)
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
account.items.each do |item|
|
74
|
+
# ItemImporter.import(item)
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
55
78
|
### Show
|
56
79
|
|
57
80
|
You can fetch a particular item by its ID by doing this:
|
@@ -59,15 +82,19 @@ You can fetch a particular item by its ID by doing this:
|
|
59
82
|
```ruby
|
60
83
|
account.items.find(1)
|
61
84
|
```
|
85
|
+
If item with id of `1` is not there, this will raise `Lightspeed::Error::NotFound`
|
86
|
+
|
87
|
+
You can fetch the first item using `first`
|
88
|
+
```ruby
|
89
|
+
account.items.first
|
90
|
+
```
|
62
91
|
|
63
92
|
### Create
|
64
93
|
|
65
94
|
You can create a particular item by calling `create`:
|
66
95
|
|
67
96
|
```ruby
|
68
|
-
account.items.create(
|
69
|
-
description: "Onesie"
|
70
|
-
})
|
97
|
+
account.items.create(description: "Onesie")
|
71
98
|
```
|
72
99
|
|
73
100
|
### Update
|
@@ -75,24 +102,25 @@ account.items.create({
|
|
75
102
|
You can update a particular item by calling `update`, passing that item's ID and providing a list of attributes to update:
|
76
103
|
|
77
104
|
```ruby
|
78
|
-
account.items.update(1,
|
79
|
-
|
80
|
-
|
105
|
+
account.items.update(1, description: "Onesie")
|
106
|
+
# OR
|
107
|
+
account.items.find(1)
|
108
|
+
item.update(description: "Onesie")
|
81
109
|
```
|
82
110
|
|
83
|
-
This method isn't available on items themselves because I couldn't work out how to share the account ID easily there.
|
84
|
-
|
85
111
|
### Destroy
|
86
112
|
|
87
113
|
You can destroy a particular item by calling `destroy` and passing that item's ID:
|
88
114
|
|
89
115
|
```ruby
|
90
|
-
account.
|
116
|
+
account.images.destroy(1)
|
117
|
+
# OR
|
118
|
+
account.images.find(1)
|
119
|
+
item.destroy
|
91
120
|
```
|
92
121
|
|
93
|
-
For the `
|
122
|
+
For the `Item` resource, `destroy` is aliased to `archive`:
|
94
123
|
|
95
|
-
|
96
|
-
account.items.archive(1)
|
97
|
-
```
|
124
|
+
## Rate Limiting
|
98
125
|
|
126
|
+
This gem respects the `X-LS-API-Bucket-Level` header by pausing before a request that would otherwise overrun the API rate limit. It calls `Kernel.sleep` with the minimum number of seconds needed to avoid hitting the limit, which suspends the current thread during that time. If you need to make API calls across multiple Lightspeed accounts using this gem, its recommended to make requests against each account in a separate thread.
|
data/bin/console
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'dotenv'
|
5
|
+
require 'lightspeed_pos'
|
6
|
+
Lightspeed::Request.verbose = true
|
5
7
|
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
8
|
# require "pry"
|
11
9
|
# Pry.start
|
10
|
+
Dotenv.load
|
11
|
+
def client
|
12
|
+
token = ENV['LIGHTSPEED_OAUTH_TOKEN']
|
13
|
+
raise 'set LIGHTSPEED_OAUTH_TOKEN as an envorinment variable to use this' unless token
|
14
|
+
@client ||= Lightspeed::Client.new(oauth_token: token)
|
15
|
+
end
|
16
|
+
|
17
|
+
def account
|
18
|
+
client.accounts.first
|
19
|
+
end
|
12
20
|
|
13
|
-
require
|
21
|
+
require 'irb'
|
14
22
|
IRB.start
|
data/lib/lightspeed/account.rb
CHANGED
@@ -1,48 +1,49 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require 'uri'
|
2
|
+
require_relative 'categories'
|
3
|
+
require_relative 'employees'
|
4
|
+
require_relative 'items'
|
5
|
+
require_relative 'item_matrices'
|
6
|
+
require_relative 'item_attribute_sets'
|
7
|
+
require_relative 'images'
|
8
|
+
require_relative 'inventories'
|
9
|
+
require_relative 'orders'
|
10
|
+
require_relative 'sales'
|
11
|
+
require_relative 'shops'
|
12
|
+
require_relative 'special_orders'
|
13
|
+
require_relative 'vendors'
|
5
14
|
|
6
15
|
module Lightspeed
|
7
|
-
class Account < Lightspeed::
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def category_proxy
|
41
|
-
@category_proxy ||= Lightspeed::Categories.new(self)
|
42
|
-
end
|
43
|
-
|
44
|
-
def item_matrices_proxy
|
45
|
-
@item_matrices_proxy ||= Lightspeed::ItemMatrices.new(self)
|
16
|
+
class Account < Lightspeed::Resource
|
17
|
+
fields(
|
18
|
+
accountID: :id,
|
19
|
+
name: :string,
|
20
|
+
link: :hash
|
21
|
+
)
|
22
|
+
relationships(
|
23
|
+
:Categories,
|
24
|
+
:Employees,
|
25
|
+
:Images,
|
26
|
+
:Inventories,
|
27
|
+
:ItemMatrices,
|
28
|
+
:ItemAttributeSets,
|
29
|
+
:Items,
|
30
|
+
:Orders,
|
31
|
+
:Sales,
|
32
|
+
:Shops,
|
33
|
+
:SpecialOrders,
|
34
|
+
:Vendors
|
35
|
+
)
|
36
|
+
|
37
|
+
def account
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def link
|
42
|
+
if @link.is_a?(Hash)
|
43
|
+
@link['@attributes']['href']
|
44
|
+
else
|
45
|
+
@link
|
46
|
+
end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'collection'
|
2
|
+
require_relative 'account'
|
3
|
+
|
4
|
+
module Lightspeed
|
5
|
+
class Accounts < Lightspeed::Collection
|
6
|
+
def base_path
|
7
|
+
'/Account'
|
8
|
+
end
|
9
|
+
|
10
|
+
def account
|
11
|
+
first_loaded || first
|
12
|
+
end
|
13
|
+
|
14
|
+
def page(n, *args)
|
15
|
+
# turns out lightspeed doesn't respect pagination for accounts.
|
16
|
+
# so page(1) is identical to page(0).
|
17
|
+
# they should be different, thus.
|
18
|
+
# if someone has more than 100 store accounts, well, good for them.
|
19
|
+
n.zero? ? super : []
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'category'
|
2
|
+
require_relative 'collection'
|
3
3
|
|
4
4
|
module Lightspeed
|
5
|
-
class Categories < Lightspeed::
|
6
|
-
def
|
7
|
-
|
5
|
+
class Categories < Lightspeed::Collection
|
6
|
+
def load_relations_default
|
7
|
+
nil
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
data/lib/lightspeed/category.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
-
|
2
|
-
class Category < Base
|
3
|
-
attr_accessor :name, :nodeDepth, :fullPathName, :leftNode, :rightNode, :timeStamp, :parentID,
|
4
|
-
:createTime
|
1
|
+
require_relative 'resource'
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Lightspeed
|
4
|
+
class Category < Lightspeed::Resource
|
5
|
+
fields(
|
6
|
+
categoryID: :id,
|
7
|
+
name: :string,
|
8
|
+
nodeDepth: :integer,
|
9
|
+
fullPathName: :string,
|
10
|
+
leftNode: :integer,
|
11
|
+
rightNode: :integer,
|
12
|
+
createTime: :datetime,
|
13
|
+
timeStamp: :datetime,
|
14
|
+
parentID: :id,
|
15
|
+
Category: :hash
|
16
|
+
)
|
17
|
+
relationships Parent: :Category
|
9
18
|
end
|
10
19
|
end
|
data/lib/lightspeed/client.rb
CHANGED
@@ -1,45 +1,56 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
|
3
|
+
require_relative 'accounts'
|
4
|
+
require_relative 'request'
|
5
|
+
require_relative 'request_throttler'
|
3
6
|
|
4
7
|
module Lightspeed
|
5
8
|
class Client
|
6
|
-
attr_accessor :
|
9
|
+
attr_accessor :oauth_token, :throttler
|
7
10
|
|
8
|
-
def initialize(
|
9
|
-
@api_key = api_key
|
11
|
+
def initialize(oauth_token: nil)
|
10
12
|
@oauth_token = oauth_token
|
11
|
-
|
12
|
-
|
13
|
-
def request(**args)
|
14
|
-
Lightspeed::Request.new(self, **args)
|
13
|
+
@throttler = Lightspeed::RequestThrottler.new
|
15
14
|
end
|
16
15
|
|
17
16
|
# Returns a list of accounts that you have access to.
|
18
17
|
def accounts
|
19
|
-
|
20
|
-
response = request.perform
|
21
|
-
instantiate(response["Account"], Lightspeed::Account)
|
18
|
+
@accounts ||= Lightspeed::Accounts.new(context: self)
|
22
19
|
end
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
def load_json(json)
|
22
|
+
data = JSON.parse(json)
|
23
|
+
Array.wrap(data).map do |resource|
|
24
|
+
resource = resource_class.new(context: self, attributes: resource)
|
25
|
+
@resources[resource.id] = resource
|
29
26
|
end
|
30
27
|
end
|
31
28
|
|
29
|
+
def get(**args)
|
30
|
+
perform_request(args.merge(method: :get))
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(**args)
|
34
|
+
perform_request(args.merge(method: :post))
|
35
|
+
end
|
36
|
+
|
37
|
+
def put(**args)
|
38
|
+
perform_request(args.merge(method: :put))
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(**args)
|
42
|
+
perform_request(args.merge(method: :delete))
|
43
|
+
end
|
44
|
+
|
32
45
|
private
|
33
46
|
|
34
|
-
|
35
|
-
|
36
|
-
# or an array of objects.
|
37
|
-
#
|
38
|
-
# The compact is becuase it may return nothing at all.
|
39
|
-
# In the example of fetching categories resource where there are no categories,
|
40
|
-
# response["Category"] will not be present.
|
41
|
-
def splat(thing)
|
42
|
-
(thing.is_a?(Array) ? thing : [thing]).compact
|
47
|
+
def perform_request(**args)
|
48
|
+
@throttler.perform_request request(**args)
|
43
49
|
end
|
50
|
+
|
51
|
+
def request **args
|
52
|
+
Lightspeed::Request.new(self, **args)
|
53
|
+
end
|
54
|
+
|
44
55
|
end
|
45
56
|
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'active_support/core_ext/string'
|
2
|
+
require 'active_support/core_ext/array/wrap'
|
3
|
+
require 'active_support/json'
|
4
|
+
require 'active_support/core_ext/object/json'
|
5
|
+
|
6
|
+
module Lightspeed
|
7
|
+
class Collection
|
8
|
+
PER_PAGE = 100 # the max page of records returned in a request
|
9
|
+
|
10
|
+
attr_accessor :context, :resources
|
11
|
+
|
12
|
+
def initialize(context:, attributes: nil)
|
13
|
+
self.context = context
|
14
|
+
instantiate(attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def account
|
18
|
+
context.account
|
19
|
+
end
|
20
|
+
|
21
|
+
def unload
|
22
|
+
@resources = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_json(json)
|
26
|
+
instantiate(JSON.parse(json))
|
27
|
+
end
|
28
|
+
|
29
|
+
def client
|
30
|
+
return context if context.is_a?(Lightspeed::Client)
|
31
|
+
account.client
|
32
|
+
end
|
33
|
+
|
34
|
+
def first(params: {})
|
35
|
+
params = params.merge(limit: 1)
|
36
|
+
instantiate(get(params: params)).first
|
37
|
+
end
|
38
|
+
|
39
|
+
def size(params: {})
|
40
|
+
params = params.merge(limit: 1, load_relations: nil)
|
41
|
+
get(params: params)['@attributes']['count'].to_i
|
42
|
+
end
|
43
|
+
alias_method :length, :size
|
44
|
+
|
45
|
+
def each_loaded
|
46
|
+
@resources ||= {}
|
47
|
+
@resources.each_value
|
48
|
+
end
|
49
|
+
|
50
|
+
def all_loaded
|
51
|
+
each_loaded.to_a
|
52
|
+
end
|
53
|
+
|
54
|
+
def first_loaded
|
55
|
+
each_loaded.first
|
56
|
+
end
|
57
|
+
|
58
|
+
def size_loaded
|
59
|
+
@resources.size
|
60
|
+
end
|
61
|
+
|
62
|
+
def all(params: {})
|
63
|
+
enum_page(params: params).to_a.flatten(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
def each_page(per_page: PER_PAGE, params: {}, &block)
|
67
|
+
enum_page(per_page: per_page, params: params).each(&block)
|
68
|
+
end
|
69
|
+
|
70
|
+
def enum_page(per_page: PER_PAGE, params: {})
|
71
|
+
Enumerator.new do |yielder|
|
72
|
+
loop.with_index do |_, n|
|
73
|
+
resources = page(n, per_page: per_page, params: params)
|
74
|
+
yielder << resources
|
75
|
+
raise StopIteration if resources.length < per_page
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def enum(per_page: PER_PAGE, params: {})
|
81
|
+
Enumerator.new do |yielder|
|
82
|
+
each_page(per_page: per_page, params: params) do |page|
|
83
|
+
page.each { |resource| yielder << resource }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def each(per_page: PER_PAGE, params: {}, &block)
|
89
|
+
enum(per_page: per_page, params: params).each(&block)
|
90
|
+
end
|
91
|
+
|
92
|
+
def find(id)
|
93
|
+
first(params: { resource_class.id_field => id }) || handle_not_found(id)
|
94
|
+
end
|
95
|
+
|
96
|
+
def create(attributes = {})
|
97
|
+
instantiate(post(body: attributes.to_json)).first
|
98
|
+
end
|
99
|
+
|
100
|
+
def update(id, attributes = {})
|
101
|
+
instantiate(put(id, body: attributes.to_json)).first
|
102
|
+
end
|
103
|
+
|
104
|
+
def destroy(id)
|
105
|
+
instantiate(delete(id)).first
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.collection_name
|
109
|
+
name.demodulize
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.resource_name
|
113
|
+
collection_name.singularize
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.resource_class
|
117
|
+
"Lightspeed::#{resource_name}".constantize
|
118
|
+
end
|
119
|
+
|
120
|
+
def base_path
|
121
|
+
"#{account.base_path}/#{resource_name}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def inspect
|
125
|
+
"#<#{self.class.name} API#{base_path}>"
|
126
|
+
end
|
127
|
+
|
128
|
+
def as_json(*args)
|
129
|
+
return if all_loaded.empty?
|
130
|
+
{ resource_name => all_loaded.as_json(*args) }
|
131
|
+
end
|
132
|
+
alias_method :to_h, :as_json
|
133
|
+
|
134
|
+
def to_json(*args)
|
135
|
+
as_json.to_json(*args)
|
136
|
+
end
|
137
|
+
|
138
|
+
def page(n, per_page: PER_PAGE, params: {})
|
139
|
+
params = params.merge(limit: per_page, offset: per_page * n)
|
140
|
+
instantiate(get(params: params))
|
141
|
+
end
|
142
|
+
|
143
|
+
def load_relations_default
|
144
|
+
'all'
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def handle_not_found(id)
|
150
|
+
raise Lightspeed::Error::NotFound, "Could not find a #{resource_name} with #{resource_class.id_field}=#{id}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def context_params
|
154
|
+
if context.class.respond_to?(:id_field) &&
|
155
|
+
resource_class.method_defined?(context.class.id_field.to_sym)
|
156
|
+
{ context.class.id_field => context.id }
|
157
|
+
else
|
158
|
+
{}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def instantiate(response)
|
163
|
+
return [] unless response.is_a?(Hash)
|
164
|
+
@resources ||= {}
|
165
|
+
Array.wrap(response[resource_name]).map do |resource|
|
166
|
+
resource = resource_class.new(context: self, attributes: resource)
|
167
|
+
@resources[resource.id] = resource
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def resource_class
|
172
|
+
self.class.resource_class
|
173
|
+
end
|
174
|
+
|
175
|
+
def resource_name
|
176
|
+
self.class.resource_name
|
177
|
+
end
|
178
|
+
|
179
|
+
def get(params: {})
|
180
|
+
params = { load_relations: load_relations_default }
|
181
|
+
.merge(context_params)
|
182
|
+
.merge(params)
|
183
|
+
.reject { |_, v| v.nil? }
|
184
|
+
client.get(
|
185
|
+
path: collection_path,
|
186
|
+
params: params
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
def post(body:)
|
191
|
+
client.post(
|
192
|
+
path: collection_path,
|
193
|
+
body: body
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
def put(id, body:)
|
198
|
+
client.put(
|
199
|
+
path: resource_path(id),
|
200
|
+
body: body
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
def delete(id)
|
205
|
+
client.delete(
|
206
|
+
path: resource_path(id)
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
def collection_path
|
211
|
+
"#{base_path}.json"
|
212
|
+
end
|
213
|
+
|
214
|
+
def resource_path(id)
|
215
|
+
"#{base_path}/#{id}.json"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|