qbo_api 1.7.1 → 1.8.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: 368838159586d1ffaf77d1618d13838cecbccbab
4
- data.tar.gz: 6caa3bae70dabfc99de0260fdd6845c21658f392
3
+ metadata.gz: 4c9489158fdcc87c75c395c4e51c4f6faa6850c5
4
+ data.tar.gz: a4ed41891faaa78efd78a540937b0e444287e88e
5
5
  SHA512:
6
- metadata.gz: 515b977dbe1ddd7ac9ba90fa9715d594a58307114141013b48a7c4d6ae9f6fb9995434c597a9a3e73ffe6316b2c3e5701936b7db66b079ba59a02793663f9414
7
- data.tar.gz: 41af9ba95cd96304e225d8f3d4b892f84475c6f1bb78d57c6be79d3ad178df1a185aba1a52808e966aa7ec2f1683535db643d1d6ae520784cd426e9b0ab8b84b
6
+ metadata.gz: 8f35f5150430bab828dc43853cd2640fd81ec1ce175e08600e286489abf79e85f9939e1cebde2ae825874865cd343b312f0b5d94d7e0e8d9be837301ccc16347
7
+ data.tar.gz: a58e610b9fef2f7f0756534b1898549beb66df6dabc955d75c349db6c391f17b33844fb9ece8b7c9c431d3eddf4178e7f9147ec4cd438d0af3f8edaa1d284768
data/lib/qbo_api.rb CHANGED
@@ -3,31 +3,24 @@ require 'json'
3
3
  require 'uri'
4
4
  require 'securerandom'
5
5
  require 'logger'
6
- require 'faraday'
7
- require 'faraday_middleware'
8
- require 'faraday/detailed_logger'
9
6
  require_relative 'qbo_api/configuration'
7
+ require_relative 'qbo_api/connection'
10
8
  require_relative 'qbo_api/supporting'
11
9
  require_relative 'qbo_api/error'
12
10
  require_relative 'qbo_api/raise_http_exception'
13
11
  require_relative 'qbo_api/entity'
14
12
  require_relative 'qbo_api/util'
15
13
  require_relative 'qbo_api/attachment'
16
- require_relative 'qbo_api/setter'
17
- require_relative 'qbo_api/builder'
18
- require_relative 'qbo_api/finder'
19
- require_relative 'qbo_api/all'
14
+ require_relative 'qbo_api/api_methods'
20
15
 
21
16
  class QboApi
22
17
  extend Configuration
18
+ include Connection
23
19
  include Supporting
24
20
  include Entity
25
21
  include Util
26
22
  include Attachment
27
- include Setter
28
- include Builder
29
- include Finder
30
- include All
23
+ include ApiMethods
31
24
 
32
25
  attr_reader :realm_id
33
26
 
@@ -38,6 +31,7 @@ class QboApi
38
31
  V3_ENDPOINT_BASE_URL = 'https://sandbox-quickbooks.api.intuit.com/v3/company/'
39
32
  PAYMENTS_API_BASE_URL = 'https://sandbox.api.intuit.com/quickbooks/v4/payments'
40
33
  APP_CONNECTION_URL = APP_CENTER_BASE + '/api/v1/connection'
34
+ LOG_TAG = "[QuickBooks]"
41
35
 
42
36
  def initialize(token: nil, token_secret: nil, access_token: nil, realm_id:,
43
37
  consumer_key: nil, consumer_secret: nil, endpoint: :accounting)
@@ -48,108 +42,15 @@ class QboApi
48
42
  @access_token = access_token
49
43
  @realm_id = realm_id
50
44
  @endpoint = endpoint
45
+ @endpoint_url = get_endpoint
51
46
  end
52
47
 
53
- def connection(url: get_endpoint)
54
- @connection ||= Faraday.new(url: url) do |faraday|
55
- faraday.headers['Content-Type'] = 'application/json;charset=UTF-8'
56
- faraday.headers['Accept'] = 'application/json'
57
- if @token != nil
58
- faraday.request :oauth, oauth_data
59
- elsif @access_token != nil
60
- faraday.request :oauth2, @access_token, token_type: 'bearer'
61
- else
62
- raise QboApi::Error.new error_body: 'Must set either the token or access_token'
63
- end
64
- faraday.request :url_encoded
65
- faraday.use FaradayMiddleware::RaiseHttpException
66
- faraday.response :detailed_logger, QboApi.logger if QboApi.log
67
- faraday.adapter Faraday.default_adapter
68
- end
69
- end
70
-
71
- def create(entity, payload:, params: nil)
72
- request(:post, entity: entity, path: entity_path(entity), payload: payload, params: params)
73
- end
74
-
75
- def update(entity, id:, payload:, params: nil)
76
- payload.merge!(set_update(entity, id))
77
- request(:post, entity: entity, path: entity_path(entity), payload: payload, params: params)
78
- end
79
-
80
- def delete(entity, id:)
81
- err_msg = "Delete is only for transaction entities. Use .deactivate instead"
82
- raise QboApi::NotImplementedError.new, err_msg unless is_transaction_entity?(entity)
83
- path = add_params_to_path(path: entity_path(entity), params: { operation: :delete })
84
- payload = set_update(entity, id)
85
- request(:post, entity: entity, path: path, payload: payload)
86
- end
87
-
88
- def deactivate(entity, id:)
89
- err_msg = "Deactivate is only for name list entities. Use .delete instead"
90
- raise QboApi::NotImplementedError.new, err_msg unless is_name_list_entity?(entity)
91
- payload = set_deactivate(entity, id)
92
- request(:post, entity: entity, path: entity_path(entity), payload: payload)
93
- end
94
-
95
- # https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/0085_develop_quickbooks_apps/0004_authentication_and_authorization/oauth_management_api#/Reconnect
96
- def disconnect
97
- path = "#{APP_CONNECTION_URL}/disconnect"
98
- request(:get, path: path)
99
- end
100
-
101
- def reconnect
102
- path = "#{APP_CONNECTION_URL}/reconnect"
103
- request(:get, path: path)
104
- end
105
-
106
- def request(method, path:, entity: nil, payload: nil, params: nil)
107
- raw_response = connection.send(method) do |req|
108
- path = finalize_path(path, method: method, params: params)
109
- case method
110
- when :get, :delete
111
- req.url path
112
- when :post, :put
113
- req.url path
114
- req.body = payload.to_json
115
- end
116
- end
117
- response(raw_response, entity: entity)
118
- end
119
-
120
- def response(resp, entity: nil)
121
- data = JSON.parse(resp.body)
122
- if entity
123
- entity_response(data, entity)
124
- else
125
- data
126
- end
127
- rescue => e
128
- # Catch fetch key errors and just return JSON
129
- data
48
+ def connection(url: @endpoint_url)
49
+ @connection ||= authorized_json_connection(url)
130
50
  end
131
51
 
132
52
  private
133
53
 
134
- def entity_response(data, entity)
135
- if qr = data['QueryResponse']
136
- qr.empty? ? nil : qr.fetch(singular(entity))
137
- elsif ar = data['AttachableResponse']
138
- ar.first.fetch(singular(entity))
139
- else
140
- data.fetch(singular(entity))
141
- end
142
- end
143
-
144
- def oauth_data
145
- {
146
- consumer_key: @consumer_key,
147
- consumer_secret: @consumer_secret,
148
- token: @token,
149
- token_secret: @token_secret
150
- }
151
- end
152
-
153
54
  def get_endpoint
154
55
  prod = self.class.production
155
56
  case @endpoint
@@ -159,5 +60,4 @@ class QboApi
159
60
  prod ? PAYMENTS_API_BASE_URL.sub("sandbox.", '') : PAYMENTS_API_BASE_URL
160
61
  end
161
62
  end
162
-
163
63
  end
@@ -0,0 +1,148 @@
1
+ class QboApi
2
+ module ApiMethods
3
+
4
+ def all(entity, max: 1000, select: nil, inactive: false, params: nil, &block)
5
+ enumerator = create_all_enumerator(entity, max: max, select: select, inactive: inactive, params: params)
6
+
7
+ if block_given?
8
+ enumerator.each(&block)
9
+ else
10
+ enumerator
11
+ end
12
+ end
13
+
14
+ def query(query, params: nil)
15
+ path = "#{realm_id}/query?query=#{CGI.escape(query)}"
16
+ entity = extract_entity_from_query(query, to_sym: true)
17
+ request(:get, entity: entity, path: path, params: params)
18
+ end
19
+
20
+ # @example
21
+ # get(:customer, 5)
22
+ # @see #get_by_query_filter
23
+ def get(entity, id_or_query_filter_args, params: nil)
24
+ if id_or_query_filter_args.is_a?(Array)
25
+ get_by_query_filter(entity, id_or_query_filter_args, params: params)
26
+ else
27
+ path = "#{entity_path(entity)}/#{id_or_query_filter_args}"
28
+ request(:get, entity: entity, path: path, params: params)
29
+ end
30
+ end
31
+
32
+ # @example
33
+ # get_by_query_filter(:customer, ["DisplayName", "Dukes Basketball Camp"])
34
+ # get_by_query_filter(:customer, ["DisplayName", "LIKE", "Dukes%"])
35
+ # get_by_query_filter(:vendor, ["DisplayName", "IN", "(true, false)"])
36
+ # get_by_query_filter(:customer, ["DisplayName", "Amy's Bird Sanctuary"])
37
+ def get_by_query_filter(entity, query_filter_args, params: nil)
38
+ query_str = get_query_str(entity, query_filter_args)
39
+ if resp = query(query_str, params: params)
40
+ resp.size == 1 ? resp[0] : resp
41
+ else
42
+ false
43
+ end
44
+ end
45
+
46
+ def create(entity, payload:, params: nil)
47
+ request(:post, entity: entity, path: entity_path(entity), payload: payload, params: params)
48
+ end
49
+
50
+ def update(entity, id:, payload:, params: nil)
51
+ payload.merge!(set_update(entity, id))
52
+ request(:post, entity: entity, path: entity_path(entity), payload: payload, params: params)
53
+ end
54
+
55
+ def delete(entity, id:)
56
+ err_msg = "Delete is only for transaction entities. Use .deactivate instead"
57
+ raise QboApi::NotImplementedError.new, err_msg unless is_transaction_entity?(entity)
58
+ path = add_params_to_path(path: entity_path(entity), params: { operation: :delete })
59
+ payload = set_update(entity, id)
60
+ request(:post, entity: entity, path: path, payload: payload)
61
+ end
62
+
63
+ def deactivate(entity, id:)
64
+ err_msg = "Deactivate is only for name list entities. Use .delete instead"
65
+ raise QboApi::NotImplementedError.new, err_msg unless is_name_list_entity?(entity)
66
+ payload = set_deactivate(entity, id)
67
+ request(:post, entity: entity, path: entity_path(entity), payload: payload)
68
+ end
69
+
70
+ private
71
+
72
+ def get_query_str(entity, query_filter_args)
73
+ filterable_field = query_filter_args[0]
74
+ operator = query_filter_args.size == 2 ? '=' : query_filter_args[1]
75
+ value = query_filter_args.size == 2 ? query_filter_args[1] : query_filter_args[2]
76
+ "SELECT * FROM #{singular(entity)} WHERE #{filterable_field} #{operator} #{to_quote_or_not(value)}"
77
+ end
78
+
79
+ def to_quote_or_not(str)
80
+ inside_parens_regex = '\(.*\)'
81
+ if str.match(/^(#{inside_parens_regex}|true|false|CURRENT_DATE)$/)
82
+ str
83
+ else
84
+ %{'#{esc(str)}'}
85
+ end
86
+ end
87
+
88
+ def create_all_enumerator(entity, max: 1000, select: nil, inactive: false, params: nil)
89
+ Enumerator.new do |enum_yielder|
90
+ select = build_all_query(entity, select: select, inactive: inactive)
91
+ pos = 0
92
+ begin
93
+ pos = pos == 0 ? pos + 1 : pos + max
94
+ results = query(offset_query_string(select, limit: max, offset: pos), params: params)
95
+ results.each do |entry|
96
+ enum_yielder.yield(entry)
97
+ end if results
98
+ end while (results ? results.size == max : false)
99
+ end
100
+ end
101
+
102
+ # NOTE(BF): QuickBooks offsets start at 1, but our convention is to index at 0.
103
+ # That is, to get an offset of index 0, pass in 1, and so forth.
104
+ def offset_query_string(query_string, limit:, offset:)
105
+ "#{query_string} MAXRESULTS #{limit} STARTPOSITION #{offset}"
106
+ end
107
+
108
+ def join_or_start_where_clause!(select:)
109
+ if select.match(/where/i)
110
+ str = ' AND '
111
+ else
112
+ str = ' WHERE '
113
+ end
114
+ str
115
+ end
116
+
117
+ def build_all_query(entity, select: nil, inactive: false)
118
+ select ||= "SELECT * FROM #{singular(entity)}"
119
+ select += join_or_start_where_clause!(select: select) + 'Active IN ( true, false )' if inactive
120
+ select
121
+ end
122
+
123
+ def build_update(resp)
124
+ { Id: resp['Id'], SyncToken: resp['SyncToken'] }
125
+ end
126
+
127
+ def build_deactivate(entity, resp)
128
+ payload = build_update(resp).merge('sparse': true, 'Active': false)
129
+
130
+ case singular(entity)
131
+ when 'Account'
132
+ payload['Name'] = resp['Name']
133
+ end
134
+ payload
135
+ end
136
+
137
+ def set_update(entity, id)
138
+ resp = get(entity, id)
139
+ build_update(resp)
140
+ end
141
+
142
+ def set_deactivate(entity, id)
143
+ resp = get(entity, id)
144
+ build_deactivate(entity, resp)
145
+ end
146
+
147
+ end
148
+ end
@@ -16,15 +16,8 @@ class QboApi
16
16
  response(raw_response, entity: :attachable)
17
17
  end
18
18
 
19
- private
20
-
21
19
  def attachment_connection
22
- return @attachment_connection if @attachment_connection
23
- multipart_connection = connection.dup
24
- multipart_connection.headers['Content-Type'] = 'multipart/form-data'
25
- multipart_middleware_index = multipart_connection.builder.handlers.index(Faraday::Request::UrlEncoded) || 1
26
- multipart_connection.builder.insert(multipart_middleware_index, Faraday::Request::Multipart)
27
- @attachment_connection = multipart_connection
20
+ @attachment_connection ||= authorized_multipart_connection(@endpoint_url)
28
21
  end
29
22
 
30
23
  end
@@ -0,0 +1,157 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'faraday/detailed_logger'
4
+
5
+ class QboApi
6
+ module Connection
7
+
8
+ def authorized_json_connection(url, headers: nil)
9
+ headers ||= {}
10
+ headers['Accept'] ||= 'application/json;charset=UTF-8' # required "we'll only accept JSON". Can be changed to any `+json` media type.
11
+ headers['Content-Type'] ||= 'application/json' # required when request has a body, else harmless
12
+ build_connection(url, headers: headers) do |conn|
13
+ add_authorization_middleware(conn)
14
+ add_exception_middleware(conn)
15
+ conn.request :url_encoded
16
+ add_connection_adapter(conn)
17
+ end
18
+ end
19
+
20
+ def authorized_multipart_connection(url)
21
+ headers = { 'Content-Type' => 'multipart/form-data' }
22
+ build_connection(url, headers: headers) do |conn|
23
+ add_authorization_middleware(conn)
24
+ add_exception_middleware(conn)
25
+ conn.request :multipart
26
+ add_connection_adapter(conn)
27
+ end
28
+ end
29
+
30
+ # @example
31
+ # connection = build_connection('https://oauth.platform.intuit.com', headers: { 'Accept' => 'application/json' }) do |conn|
32
+ # conn.basic_auth(client_id, client_secret)
33
+ # conn.request :url_encoded # application/x-www-form-urlencoded
34
+ # conn.use FaradayMiddleware::ParseJson, parser_options: { symbolize_names: true }
35
+ # conn.use Faraday::Response::RaiseError
36
+ # end
37
+ # raw_response = connection.post {|req|
38
+ # req.body = { grant_type: :refresh_token, refresh_token: current_refresh_token }
39
+ # req.url '/oauth2/v1/tokens/bearer'
40
+ # }
41
+ def build_connection(url, headers: nil)
42
+ Faraday.new(url: url) { |conn|
43
+ conn.response :detailed_logger, QboApi.logger, LOG_TAG if QboApi.log
44
+ conn.headers.update(headers) if headers
45
+ yield conn if block_given?
46
+ }
47
+ end
48
+
49
+ def request(method, path:, entity: nil, payload: nil, params: nil)
50
+ raw_response = raw_request(method, conn: connection, path: path, params: params, payload: payload)
51
+ response(raw_response, entity: entity)
52
+ end
53
+
54
+ def raw_request(method, conn:, path:, payload: nil, params: nil)
55
+ path = finalize_path(path, method: method, params: params)
56
+ conn.public_send(method) do |req|
57
+ case method
58
+ when :get, :delete
59
+ req.url path
60
+ when :post, :put
61
+ req.url path
62
+ req.body = payload.to_json
63
+ else raise ArgumentError, "Unhandled request method '#{method.inspect}'"
64
+ end
65
+ end
66
+ end
67
+
68
+ def response(resp, entity: nil)
69
+ data = parse_response_body(resp)
70
+ entity ? entity_response(data, entity) : data
71
+ rescue => e
72
+ QboApi.logger.debug { "#{LOG_TAG} response parsing error: entity=#{entity.inspect} body=#{resp.body.inspect} exception=#{e.inspect}" }
73
+ data
74
+ end
75
+
76
+ def parse_response_body(resp)
77
+ body = resp.body
78
+ case resp.headers['Content-Type']
79
+ when /json/ then JSON.parse(body)
80
+ else body
81
+ end
82
+ end
83
+
84
+ # Part of the OAuth1 API
85
+ # https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/0085_develop_quickbooks_apps/0004_authentication_and_authorization/oauth_management_api#/Reconnect
86
+ def disconnect
87
+ path = "#{APP_CONNECTION_URL}/disconnect"
88
+ request(:get, path: path)
89
+ end
90
+
91
+ # Part of the OAuth1 API
92
+ # https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/0085_develop_quickbooks_apps/0004_authentication_and_authorization/oauth_management_api#/Reconnect
93
+ def reconnect
94
+ path = "#{APP_CONNECTION_URL}/reconnect"
95
+ request(:get, path: path)
96
+ end
97
+
98
+ private
99
+
100
+ def entity_response(data, entity)
101
+ entity_name = entity_name(entity)
102
+ if data.key?('QueryResponse')
103
+ entity_body = data['QueryResponse']
104
+ return nil if entity_body.empty?
105
+ entity_body.fetch(entity_name, data)
106
+ elsif data.key?('AttachableResponse')
107
+ entity_body = data['AttachableResponse']
108
+ entity_body &&= entity_body.first
109
+ entity_body.fetch(entity_name, data)
110
+ else
111
+ entity_body = data
112
+ entity_body.fetch(entity_name) do
113
+ QboApi.logger.debug { "#{LOG_TAG} entity name not in response body: entity=#{entity.inspect} entity_name=#{entity_name.inspect} body=#{data.inspect}" }
114
+ data
115
+ end
116
+ end
117
+ end
118
+
119
+ def add_connection_adapter(conn)
120
+ conn.adapter Faraday.default_adapter
121
+ end
122
+
123
+ def add_exception_middleware(conn)
124
+ conn.use FaradayMiddleware::RaiseHttpException
125
+ end
126
+
127
+ def add_authorization_middleware(conn)
128
+ if @token != nil
129
+ # Part of the OAuth1 API
130
+ gem 'simple_oauth'
131
+ require 'simple_oauth'
132
+ conn.request :oauth, oauth_data
133
+ elsif @access_token != nil
134
+ conn.request :oauth2, @access_token, token_type: 'bearer'
135
+ else
136
+ raise QboApi::Error.new error_body: 'Must set either the token or access_token'
137
+ end
138
+ end
139
+
140
+ # Part of the OAuth1 API
141
+ # Use with simple_oauth OAuth1 middleware
142
+ # @see #add_authorization_middleware
143
+ def oauth_data
144
+ {
145
+ consumer_key: @consumer_key,
146
+ consumer_secret: @consumer_secret,
147
+ token: @token,
148
+ token_secret: @token_secret
149
+ }
150
+ end
151
+
152
+ def entity_name(entity)
153
+ singular(entity)
154
+ end
155
+
156
+ end
157
+ end
data/lib/qbo_api/util.rb CHANGED
@@ -54,21 +54,6 @@ class QboApi
54
54
  uri.to_s
55
55
  end
56
56
 
57
- def join_or_start_where_clause!(select:)
58
- if select.match(/where/i)
59
- str = ' AND '
60
- else
61
- str = ' WHERE '
62
- end
63
- str
64
- end
65
-
66
- def build_all_query(entity, select: nil, inactive: false)
67
- select ||= "SELECT * FROM #{singular(entity)}"
68
- select += join_or_start_where_clause!(select: select) + 'Active IN ( true, false )' if inactive
69
- select
70
- end
71
-
72
57
  end
73
58
  end
74
59
 
@@ -1,3 +1,3 @@
1
1
  class QboApi
2
- VERSION = "1.7.1"
2
+ VERSION = "1.8.0"
3
3
  end
data/qbo_api.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'webmock'
25
25
  spec.add_development_dependency 'sinatra'
26
26
  spec.add_development_dependency 'rack-oauth2'
27
+ spec.add_development_dependency 'simple_oauth'
27
28
  spec.add_development_dependency 'omniauth'
28
29
  spec.add_development_dependency 'omniauth-quickbooks'
29
30
  spec.add_development_dependency 'shotgun'
@@ -33,6 +34,5 @@ Gem::Specification.new do |spec|
33
34
  spec.add_runtime_dependency 'faraday'
34
35
  spec.add_runtime_dependency 'faraday_middleware'
35
36
  spec.add_runtime_dependency 'faraday-detailed_logger'
36
- spec.add_runtime_dependency 'simple_oauth'
37
37
  spec.add_runtime_dependency 'nokogiri'
38
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qbo_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Pelczarski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-16 00:00:00.000000000 Z
11
+ date: 2018-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: omniauth
98
+ name: simple_oauth
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: omniauth-quickbooks
112
+ name: omniauth
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: shotgun
126
+ name: omniauth-quickbooks
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: dotenv
140
+ name: shotgun
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: vcr
154
+ name: dotenv
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
@@ -165,7 +165,7 @@ dependencies:
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
- name: awesome_print
168
+ name: vcr
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -179,13 +179,13 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: faraday
182
+ name: awesome_print
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
- type: :runtime
188
+ type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
@@ -193,7 +193,7 @@ dependencies:
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
- name: faraday_middleware
196
+ name: faraday
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - ">="
@@ -207,7 +207,7 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  - !ruby/object:Gem::Dependency
210
- name: faraday-detailed_logger
210
+ name: faraday_middleware
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
@@ -221,7 +221,7 @@ dependencies:
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  - !ruby/object:Gem::Dependency
224
- name: simple_oauth
224
+ name: faraday-detailed_logger
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - ">="
@@ -272,15 +272,13 @@ files:
272
272
  - example/views/oauth2.erb
273
273
  - example/views/oauth2_redirect.erb
274
274
  - lib/qbo_api.rb
275
- - lib/qbo_api/all.rb
275
+ - lib/qbo_api/api_methods.rb
276
276
  - lib/qbo_api/attachment.rb
277
- - lib/qbo_api/builder.rb
278
277
  - lib/qbo_api/configuration.rb
278
+ - lib/qbo_api/connection.rb
279
279
  - lib/qbo_api/entity.rb
280
280
  - lib/qbo_api/error.rb
281
- - lib/qbo_api/finder.rb
282
281
  - lib/qbo_api/raise_http_exception.rb
283
- - lib/qbo_api/setter.rb
284
282
  - lib/qbo_api/supporting.rb
285
283
  - lib/qbo_api/util.rb
286
284
  - lib/qbo_api/version.rb
data/lib/qbo_api/all.rb DELETED
@@ -1,31 +0,0 @@
1
- class QboApi
2
- module All
3
-
4
- def all(entity, max: 1000, select: nil, inactive: false, &block)
5
- enumerator = create_all_enumerator(entity, max: max, select: select, inactive: inactive)
6
-
7
- if block_given?
8
- enumerator.each(&block)
9
- else
10
- enumerator
11
- end
12
- end
13
-
14
- private
15
-
16
- def create_all_enumerator(entity, max: 1000, select: nil, inactive: false)
17
- Enumerator.new do |enum_yielder|
18
- select = build_all_query(entity, select: select, inactive: inactive)
19
- pos = 0
20
- begin
21
- pos = pos == 0 ? pos + 1 : pos + max
22
- results = query("#{select} MAXRESULTS #{max} STARTPOSITION #{pos}")
23
- results.each do |entry|
24
- enum_yielder.yield(entry)
25
- end if results
26
- end while (results ? results.size == max : false)
27
- end
28
- end
29
-
30
- end
31
- end
@@ -1,21 +0,0 @@
1
- class QboApi
2
- module Builder
3
-
4
- private
5
-
6
- def build_update(resp)
7
- { Id: resp['Id'], SyncToken: resp['SyncToken'] }
8
- end
9
-
10
- def build_deactivate(entity, resp)
11
- payload = build_update(resp).merge('sparse': true, 'Active': false)
12
-
13
- case singular(entity)
14
- when 'Account'
15
- payload['Name'] = resp['Name']
16
- end
17
- payload
18
- end
19
-
20
- end
21
- end
@@ -1,47 +0,0 @@
1
- class QboApi
2
- module Finder
3
-
4
- def query(query, params: nil)
5
- path = "#{realm_id}/query?query=#{CGI.escape(query)}"
6
- entity = extract_entity_from_query(query, to_sym: true)
7
- request(:get, entity: entity, path: path, params: params)
8
- end
9
-
10
- def get(entity, type, params: nil)
11
- if type.is_a?(Array)
12
- query_str = get_query_str(entity, type)
13
- if resp = query(query_str, params: params)
14
- resp.size == 1 ? resp[0] : resp
15
- else
16
- false
17
- end
18
- else
19
- path = "#{entity_path(entity)}/#{type}"
20
- request(:get, entity: entity, path: path, params: params)
21
- end
22
- end
23
-
24
- def to_quote_or_not(str)
25
- inside_parens_regex = '\(.*\)'
26
- if str.match(/^(#{inside_parens_regex}|true|false|CURRENT_DATE)$/)
27
- str
28
- else
29
- %{'#{esc(str)}'}
30
- end
31
- end
32
-
33
- private
34
-
35
- def get_query_str(entity, type)
36
- if type.size == 2
37
- operator = '='
38
- value = type[1]
39
- else
40
- operator = type[1]
41
- value = type[2]
42
- end
43
- "SELECT * FROM #{singular(entity)} WHERE #{type[0]} #{operator} #{to_quote_or_not(value)}"
44
- end
45
-
46
- end
47
- end
@@ -1,18 +0,0 @@
1
- class QboApi
2
- module Setter
3
-
4
- private
5
-
6
- def set_update(entity, id)
7
- resp = get(entity, id)
8
- build_update(resp)
9
- end
10
-
11
- def set_deactivate(entity, id)
12
- resp = get(entity, id)
13
- build_deactivate(entity, resp)
14
- end
15
-
16
- end
17
- end
18
-