qbo_api 1.7.1 → 1.8.0

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