qbo_api 1.9.0 → 2.0.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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -4
- data/README.md +34 -71
- data/example/base.rb +1 -0
- data/example/oauth2.rb +15 -2
- data/example/public/connect-to-qbo.svg +1 -0
- data/example/views/oauth2.erb +4 -14
- data/lib/qbo_api.rb +2 -2
- data/lib/qbo_api/api_methods.rb +2 -12
- data/lib/qbo_api/attachment.rb +4 -6
- data/lib/qbo_api/configuration.rb +0 -1
- data/lib/qbo_api/connection.rb +3 -31
- data/lib/qbo_api/entity.rb +0 -2
- data/lib/qbo_api/error.rb +5 -1
- data/lib/qbo_api/raise_http_exception.rb +4 -3
- data/lib/qbo_api/supporting.rb +0 -2
- data/lib/qbo_api/util.rb +0 -1
- data/lib/qbo_api/version.rb +1 -1
- data/qbo_api.gemspec +3 -3
- metadata +15 -18
- data/.env.example_app.oauth1 +0 -2
- data/example/oauth.rb +0 -62
- data/lib/qbo_api/connection/oauth1.rb +0 -60
- data/lib/qbo_api/connection/oauth2.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d72b41eaf72084c4445833378025cd45c902ad44e5df4c3d3f43e6eb69646c58
|
4
|
+
data.tar.gz: 7b304ea6e41fc62e6d14f5b3bd68ff001cc8ebc1754cad02238ca86ffeba0813
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6362288c9c1e0d29b8a5f181d9f0b1ede2c2fb09804410a4e1deba35e65517c675c14a1649c2a1c4638ec0bf52ca5f0317244b1881f9654ef4b53aa842d22a4
|
7
|
+
data.tar.gz: 3ff300fae0442f99747d5d4a6cf2f36c97ad036a5fed351ae0447a8e915a5be265aeeedfe13a34e3dd832adf65543fd3f157d1e0d5c738eaa6f3ca4ac683e028
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.4.9
|
5
4
|
- 2.5.7
|
6
|
-
- 2.6.
|
7
|
-
- 2.7.
|
5
|
+
- 2.6.6
|
6
|
+
- 2.7.1
|
8
7
|
|
9
8
|
before_install:
|
10
9
|
- gem install bundler
|
@@ -15,7 +14,6 @@ before_script:
|
|
15
14
|
script:
|
16
15
|
- bundle exec rspec spec/
|
17
16
|
|
18
|
-
|
19
17
|
notifications:
|
20
18
|
email:
|
21
19
|
- christian@minimul.com
|
data/README.md
CHANGED
@@ -1,23 +1,11 @@
|
|
1
1
|
# QboApi
|
2
2
|
|
3
3
|
Ruby client for the QuickBooks Online API version 3.
|
4
|
-
- Built on top of the excellent Faraday gem.
|
5
4
|
- JSON only support.
|
6
5
|
- Please don't ask about XML support. [Intuit has stated](https://github.com/ruckus/quickbooks-ruby/issues/257#issuecomment-126834454) that JSON is the primary data format for the QuickBooks API (v3 and beyond). This gem will specialize in JSON only. The [`quickbooks-ruby`](https://github.com/ruckus/quickbooks-ruby) gem has fantastic support for those who favor XML.
|
7
6
|
- Features specs built directly against a QuickBooks Online Sandbox via the VCR gem.
|
8
7
|
- Robust error handling.
|
9
8
|
|
10
|
-
## Tutorials and Screencasts
|
11
|
-
- <a href="https://minimul.com/migrating-a-quickbooks-online-app-from-oauth1-to-oauth2-using-the-qbo_api-gem.html" target="_blank">Migrating a QuickBooks Online App from OAuth1 to OAuth2 using the qbo_api gem - Step 1</a>.
|
12
|
-
- <a href="https://minimul.com/migrating-a-quickbooks-online-app-from-oauth1-to-oauth2-using-the-qbo_api-gem-part-2.html" target="_blank">Migrating a QuickBooks Online App from OAuth1 to OAuth2 using the qbo_api gem - Step 2</a>.
|
13
|
-
- <a href="https://minimul.com/migrating-a-quickbooks-online-app-from-oauth1-to-oauth2-using-the-qbo_api-gem-part-3.html" target="_blank">Migrating a QuickBooks Online App from OAuth1 to OAuth2 using the qbo_api gem - Step 3</a>.
|
14
|
-
- <a href="http://minimul.com/introducing-a-new-ruby-quickbooks-online-client.html" target="_blank">Why qbo_api is a better choice </a> than the <a href="https://github.com/ruckus/quickbooks-ruby" target="_blank">quickbooks-ruby</a> gem.
|
15
|
-
- <a href="http://minimul.com/getting-started-with-the-modern-ruby-quickbooks-online-client-qbo_api-part-1.html" target="_blank">Part 1</a>: Learn how to spin up the <a href="https://github.com/minimul/qbo_api#spin-up-an-example">example app</a>.
|
16
|
-
- <a href="http://minimul.com/the-modern-ruby-quickbooks-client-part-2.html" target="_blank">Part 2</a>: <a href="https://github.com/minimul/qbo_api#running-the-specs">Running the specs</a> to aid you in understanding a QuickBooks API transaction.
|
17
|
-
- <a href="http://minimul.com/the-modern-ruby-quickbooks-client-contributing.html" target="_blank">Part 3</a>: <a href="https://github.com/minimul/qbo_api#creating-new-specs-or-modifying-existing-spec-that-have-been-recorded-using-the-vcr-gem">Contributing to the gem</a>.
|
18
|
-
### Important Note: The videos are out of date.
|
19
|
-
If you signed up for a Intuit developer account after July 17th, 2017 then you will have to
|
20
|
-
follow <a href='#OAuth2-example'>OAuth2: Spin up an example</a>
|
21
9
|
## The Book
|
22
10
|
|
23
11
|
<a href="https://leanpub.com/minimul-qbo-guide-vol-1" target="_blank">
|
@@ -25,7 +13,7 @@ follow <a href='#OAuth2-example'>OAuth2: Spin up an example</a>
|
|
25
13
|
</a>
|
26
14
|
|
27
15
|
|
28
|
-
## Ruby >= 2.
|
16
|
+
## Ruby >= 2.5 required
|
29
17
|
|
30
18
|
## Installation
|
31
19
|
|
@@ -46,41 +34,22 @@ Or install it yourself as:
|
|
46
34
|
## Usage
|
47
35
|
|
48
36
|
### Initialize
|
49
|
-
#### OAuth
|
50
|
-
```ruby
|
51
|
-
q = account.qbo_account # or wherever you are storing the OAuth creds
|
52
|
-
qbo_api = QboApi.new(token: q.token,
|
53
|
-
token_secret: q.secret,
|
54
|
-
realm_id: q.companyid,
|
55
|
-
consumer_key: '*****',
|
56
|
-
consumer_secret: '********')
|
57
|
-
```
|
58
|
-
#### OAuth2
|
59
37
|
```ruby
|
60
38
|
qbo_api = QboApi.new(access_token: 'REWR342532asdfae!$4asdfa', realm_id: 32095430444)
|
39
|
+
- qbo_api.get :customer, 1
|
61
40
|
```
|
62
41
|
|
63
|
-
### Super fast way to use QboApi
|
42
|
+
### Super fast way to use QboApi as long as Ruby >= 2.5 is installed
|
64
43
|
```
|
65
44
|
- cd ~/<local dir>
|
66
45
|
- git clone git@github.com:minimul/qbo_api.git && cd qbo_api
|
67
46
|
- bundle
|
68
47
|
- bin/console
|
69
48
|
- QboApi.production = true
|
70
|
-
-
|
71
|
-
-
|
72
|
-
token_secret:"g8wcyQEtwxxxxxxm",
|
73
|
-
realm_id: "12314xxxxxx7",
|
74
|
-
consumer_key: "qyprdwzcxxxxxxbIWsIMIy9PYI",
|
75
|
-
consumer_secret: "CyDN4wpxxxxxxxPMv7hDhmh4")
|
76
|
-
- # OAuth 2
|
77
|
-
- qboapi = QboApi.new(access_token: "qyprd2uvCOdRq8xzoSSiiiiii", realm_id: "12314xxxxxx7")
|
78
|
-
- qboapi.get :customer, 1
|
49
|
+
- qbo_api = QboApi.new(access_token: "qyprd2uvCOdRq8xzoSSiiiiii", realm_id: "12314xxxxxx7")
|
50
|
+
- qbo_api.get :customer, 1
|
79
51
|
```
|
80
52
|
|
81
|
-
### TLS v1.2
|
82
|
-
Intuit will be [requiring](https://developer.intuit.com/hub/blog/2017/08/03/upgrading-your-apps-to-support-tls-1-2) API client connections to be negotiated over TLS1.2 by December 31st, 2017. Using the default HTTP client (Net::HTTP) with Faraday this is the case with QboApi, however, if you are using another HTTP client you may need to directly set the TLS version negotiation manually.
|
83
|
-
|
84
53
|
### DateTime serialization
|
85
54
|
Some QBO entities have attributes of type DateTime (e.g., Time Activities with StartTime and EndTime). All DateTimes passed to the QBO API must be serialized in ISO 8601 format.
|
86
55
|
If ActiveSupport is loaded, you can achieve proper serialization with the following configuration:
|
@@ -267,7 +236,7 @@ Be aware that any errors will not raise a `QboApi::Error`, but will be returned
|
|
267
236
|
}
|
268
237
|
]
|
269
238
|
}
|
270
|
-
response =
|
239
|
+
response = qbo_api.batch(payload)
|
271
240
|
expect(response['BatchItemResponse'].size).to eq 2
|
272
241
|
expect(batch_response.detect{ |b| b["bId"] == "bid1" }["Vendor"]["DisplayName"]).to eq "Smith Family Store"
|
273
242
|
```
|
@@ -276,7 +245,7 @@ Be aware that any errors will not raise a `QboApi::Error`, but will be returned
|
|
276
245
|
|
277
246
|
```ruby
|
278
247
|
params = { start_date: '2015-01-01', end_date: '2015-07-31', customer: 1, summarize_column_by: 'Customers' }
|
279
|
-
response =
|
248
|
+
response = qbo_api.reports(name: 'ProfitAndLoss', params: params)
|
280
249
|
p response["Header"]["ReportName"]) #=> 'ProfitAndLoss'
|
281
250
|
```
|
282
251
|
|
@@ -346,9 +315,8 @@ See [docs](https://developer.intuit.com/docs/0100_quickbooks_online/0100_essenti
|
|
346
315
|
p qbo_api.is_transaction_entity?(:customer) # => false
|
347
316
|
p qbo_api.is_name_list_entity?(:vendors) # => true
|
348
317
|
```
|
349
|
-
## <a name='OAuth2-example'>
|
350
|
-
|
351
|
-
- <a href="http://minimul.com/access-the-quickbooks-online-api-with-oauth2.html" target="_blank">Check out this article on spinning up the OAuth2 example</a>.
|
318
|
+
## <a name='OAuth2-example'>Spin up an example</a>
|
319
|
+
- <a href="http://minimul.com/access-the-quickbooks-online-api-with-oauth2.html" target="_blank">Check out this article on spinning up the example</a>.
|
352
320
|
- `git clone git://github.com/minimul/qbo_api && cd qbo_api`
|
353
321
|
- `bundle`
|
354
322
|
- Create a `.env` file
|
@@ -363,7 +331,7 @@ See [docs](https://developer.intuit.com/docs/0100_quickbooks_online/0100_essenti
|
|
363
331
|
- Create a new Company ([from the manage sandboxes page](https://developer.intuit.com/v2/ui#/sandbox))
|
364
332
|
Don't use it for anything else besides testing this app.
|
365
333
|
-. Copy the 'Company ID' to your .env as QBO_API_COMPANY_ID
|
366
|
-
- Start up the example
|
334
|
+
- Start up the example app
|
367
335
|
- `ruby example/oauth2.rb`
|
368
336
|
- Go to `http://localhost:9393/oauth2`
|
369
337
|
- Use the `Connect to QuickBooks` button to connect to your QuickBooks sandbox, which you receive when signing up at [https://developer.intuit.com](https://developer.intuit.com).
|
@@ -373,35 +341,13 @@ See [docs](https://developer.intuit.com/docs/0100_quickbooks_online/0100_essenti
|
|
373
341
|
- Checkout [`example/oauth2.rb`](https://github.com/minimul/qbo_api/blob/master/example/oauth2.rb)
|
374
342
|
to see what is going on under the hood.
|
375
343
|
|
376
|
-
## OAuth1: Spin up an example
|
377
|
-
### OLD LEGACY - SEE OAUTH2 EXAMPLE ABOVE
|
378
|
-
- <a href="http://minimul.com/getting-started-with-the-modern-ruby-quickbooks-online-client-qbo_api-part-1.html" target="_blank">Check out this tutorial and screencast on spinning up an example</a>.
|
379
|
-
- `git clone git://github.com/minimul/qbo_api && cd qbo_api`
|
380
|
-
- `bundle`
|
381
|
-
- Create a `.env` file
|
382
|
-
- `cp .env.example_app.oauth1 .env`
|
383
|
-
- If needed create an account at [https://developer.intuit.com](https://developer.intuit.com)
|
384
|
-
- Click `Get started coding`
|
385
|
-
- Create an app with both the `Accounting` & `Payments` selected.
|
386
|
-
- Go to the `Development` tab and copy and paste the consumer key and secret into the `.env` file
|
387
|
-
as QBO_API_CONSUMER_KEY and QBO_API_CONSUMER_SECRET respectively.
|
388
|
-
- Start up the example app
|
389
|
-
- `ruby example/oauth.rb`
|
390
|
-
- Go to `http://localhost:9393`
|
391
|
-
- Use the `Connect to QuickBooks` button to connect to your QuickBooks sandbox, which you receive when signing up at [https://developer.intuit.com](https://developer.intuit.com).
|
392
|
-
- After successfully connecting to your sandbox run:
|
393
|
-
- `http://localhost:9393/customer/5`
|
394
|
-
- You should see "Dukes Basketball Camp" displayed
|
395
|
-
- Checkout [`example/oauth.rb`](https://github.com/minimul/qbo_api/blob/master/example/oauth.rb)
|
396
|
-
to see what is going on under the hood.
|
397
|
-
|
398
344
|
## Webhooks
|
399
345
|
- <a href="http://minimul.com/getting-started-with-quickbooks-online-webhooks.html" target="_blank">Check out this tutorial and screencast on handling a webhook request</a>. Also checkout [`example/app.rb`](https://github.com/minimul/qbo_api/blob/master/example/app.rb) for the request handling code.
|
400
346
|
|
401
347
|
See https://www.twilio.com/blog/2015/09/6-awesome-reasons-to-use-ngrok-when-testing-webhooks.html
|
402
348
|
for how to install ngrok and what it is.
|
403
349
|
|
404
|
-
- With
|
350
|
+
- With the example app running, run:
|
405
351
|
`ngrok http 9393 -subdomain=somereasonablyuniquenamehere`
|
406
352
|
|
407
353
|
- Go to the [`Development` tab](https://developer.intuit.com/v2/ui#/app/dashboard)
|
@@ -411,7 +357,7 @@ for how to install ngrok and what it is.
|
|
411
357
|
- After saving the webhook, click 'show token'.
|
412
358
|
Add the token to your .env as QBO_API_VERIFIER_TOKEN
|
413
359
|
|
414
|
-
- In another tab, create a customer via the
|
360
|
+
- In another tab, create a customer via the API:
|
415
361
|
`bundle exec ruby -rqbo_api -rdotenv -e 'Dotenv.load; p QboApi.new(access_token: ENV.fetch("QBO_API_OAUTH2_ACCESS_TOKEN"), realm_id: ENV.fetch("QBO_API_COMPANY_ID")).create(:customer, payload: { DisplayName: "TestCustomer" })'`
|
416
362
|
(You'll also need to have added the QBO_API_COMPANY_ID and QBO_API_OAUTH2_ACCESS_TOKEN to your .env)
|
417
363
|
|
@@ -424,6 +370,28 @@ for how to install ngrok and what it is.
|
|
424
370
|
"POST /webhooks HTTP/1.1" 200 - 0.0013
|
425
371
|
```
|
426
372
|
|
373
|
+
### Just For Hackers
|
374
|
+
|
375
|
+
- Using the build_connection method
|
376
|
+
```
|
377
|
+
connection = build_connection('https://oauth.platform.intuit.com', headers: { 'Accept' => 'application/json' }) do |conn|
|
378
|
+
conn.basic_auth(client_id, client_secret)
|
379
|
+
conn.request :url_encoded # application/x-www-form-urlencoded
|
380
|
+
conn.use FaradayMiddleware::ParseJson, parser_options: { symbolize_names: true }
|
381
|
+
conn.use Faraday::Response::RaiseError
|
382
|
+
end
|
383
|
+
|
384
|
+
raw_response = connection.post do |req|
|
385
|
+
req.body = { grant_type: :refresh_token, refresh_token: current_refresh_token }
|
386
|
+
req.url '/oauth2/v1/tokens/bearer'
|
387
|
+
end
|
388
|
+
```
|
389
|
+
- Once your .env file is completely filled out you can use the console to play around in your sandbox
|
390
|
+
```
|
391
|
+
bin/console test
|
392
|
+
>> @qbo_api.get :customer, 1
|
393
|
+
```
|
394
|
+
|
427
395
|
## Contributing
|
428
396
|
|
429
397
|
Bug reports and pull requests are welcome on GitHub at https://github.com/minimul/qbo_api.
|
@@ -441,11 +409,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/minimu
|
|
441
409
|
- All specs that require interaction with the API must be recorded against your personal QuickBooks sandbox. More coming on how to create or modifying existing specs against your sandbox.
|
442
410
|
- <a href="http://minimul.com/the-modern-ruby-quickbooks-client-contributing.html" target="_blank">Check out this tutorial and screencast on contributing to qbo_api</a>.
|
443
411
|
|
444
|
-
#### Protip: Once your .env file is completely filled out you can use the console to play around in your sandbox
|
445
|
-
```
|
446
|
-
bin/console test
|
447
|
-
>> @qbo_api.get :customer, 1
|
448
|
-
```
|
449
412
|
|
450
413
|
## License
|
451
414
|
|
data/example/base.rb
CHANGED
data/example/oauth2.rb
CHANGED
@@ -24,16 +24,29 @@ class OAuth2App < Sinatra::Base
|
|
24
24
|
Rack::OAuth2::Client.new(
|
25
25
|
identifier: CLIENT_ID,
|
26
26
|
secret: CLIENT_SECRET,
|
27
|
-
redirect_uri:
|
27
|
+
redirect_uri: redirect_url,
|
28
28
|
authorization_endpoint: "https://appcenter.intuit.com/connect/oauth2",
|
29
29
|
token_endpoint: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
|
30
30
|
)
|
31
31
|
end
|
32
|
+
|
33
|
+
def authorize_url(state:)
|
34
|
+
oauth2_client.authorization_uri(
|
35
|
+
client_id: CLIENT_ID,
|
36
|
+
scope: "com.intuit.quickbooks.accounting",
|
37
|
+
redirect_uri: redirect_url,
|
38
|
+
response_type: "code",
|
39
|
+
state: state
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def redirect_url
|
44
|
+
"http://localhost:#{PORT}/oauth2-redirect"
|
45
|
+
end
|
32
46
|
end
|
33
47
|
|
34
48
|
get '/oauth2' do
|
35
49
|
session[:state] = SecureRandom.uuid
|
36
|
-
@client = oauth2_client
|
37
50
|
erb :oauth2
|
38
51
|
end
|
39
52
|
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="isolation:isolate" viewBox="0 0 775.39 132"><defs><clipPath id="a"><path d="M0 0h775.39v132H0z"/></clipPath></defs><g clip-path="url(#a)"><path d="M775.395 124c0 4.4-3.6 8-8 8H8c-4.4 0-8-3.6-8-8V8c0-4.4 3.6-8 8-8h759.395c4.4 0 8 3.6 8 8v116z" fill="#328538"/><path d="M775.395 124c0 4.4-3.6 8-8 8H8c-4.4 0-8-3.6-8-8V8c0-4.4 3.6-8 8-8h759.395c4.4 0 8 3.6 8 8v116z" fill="none" vector-effect="non-scaling-stroke" stroke-width="4" stroke="#328538" stroke-miterlimit="10"/><path d="M178.168 56.127c-1.033-1.4-2.38-2.424-4.039-3.07-1.66-.645-3.284-.968-4.869-.968-2.028 0-3.872.368-5.532 1.106a13.005 13.005 0 0 0-4.287 3.042c-1.198 1.292-2.121 2.804-2.766 4.538-.646 1.733-.968 3.614-.968 5.642 0 2.14.313 4.093.941 5.864.627 1.771 1.521 3.291 2.683 4.563a12.012 12.012 0 0 0 4.176 2.96c1.622.703 3.448 1.052 5.477 1.052 2.103 0 3.964-.415 5.588-1.244 1.623-.831 2.932-1.928 3.928-3.292l5.587 3.926a17.878 17.878 0 0 1-6.362 5.063c-2.509 1.198-5.441 1.799-8.796 1.799-3.062 0-5.873-.508-8.437-1.523-2.564-1.014-4.767-2.433-6.611-4.258-1.844-1.826-3.282-4.002-4.314-6.53-1.034-2.524-1.55-5.318-1.55-8.38 0-3.134.544-5.965 1.632-8.492 1.088-2.527 2.582-4.674 4.482-6.445 1.898-1.77 4.14-3.135 6.721-4.094 2.581-.958 5.384-1.437 8.408-1.437 1.255 0 2.564.119 3.928.359 1.365.24 2.675.608 3.928 1.105a19.141 19.141 0 0 1 3.541 1.855 11.42 11.42 0 0 1 2.82 2.654l-5.309 4.205m13.056 16.597c0 1.032.156 2.065.471 3.097a8.468 8.468 0 0 0 1.41 2.767 7.381 7.381 0 0 0 2.378 1.991c.96.517 2.102.774 3.43.774 1.328 0 2.471-.257 3.43-.774a7.42 7.42 0 0 0 2.38-1.991 8.566 8.566 0 0 0 1.41-2.767 10.66 10.66 0 0 0 .47-3.097c0-1.033-.158-2.056-.47-3.071a8.637 8.637 0 0 0-1.41-2.738 7.1 7.1 0 0 0-2.38-1.963c-.959-.5-2.102-.748-3.43-.748-1.328 0-2.47.248-3.43.748a7.063 7.063 0 0 0-2.378 1.963 8.536 8.536 0 0 0-1.41 2.738 10.303 10.303 0 0 0-.471 3.071zm-6.749 0c0-2.103.377-4.011 1.134-5.726.755-1.714 1.779-3.181 3.07-4.398 1.29-1.217 2.821-2.157 4.592-2.821 1.77-.664 3.65-.996 5.642-.996 1.992 0 3.872.332 5.643.996 1.771.664 3.3 1.604 4.592 2.821 1.291 1.217 2.313 2.684 3.071 4.398.754 1.715 1.133 3.623 1.133 5.726 0 2.103-.379 4.02-1.133 5.753-.758 1.733-1.78 3.218-3.071 4.454-1.292 1.236-2.821 2.203-4.592 2.903-1.771.7-3.651 1.052-5.643 1.052s-3.872-.352-5.642-1.052c-1.771-.7-3.302-1.667-4.592-2.903-1.291-1.236-2.315-2.721-3.07-4.454-.757-1.733-1.134-3.65-1.134-5.753m33.91-13.167h6.307v4.26h.111c.589-1.328 1.612-2.498 3.069-3.513 1.457-1.015 3.181-1.521 5.173-1.521 1.734 0 3.218.303 4.454.912 1.234.609 2.249 1.412 3.042 2.408a9.715 9.715 0 0 1 1.742 3.429 14.43 14.43 0 0 1 .554 3.983v16.597h-6.638V71.396c0-.775-.056-1.586-.167-2.435a6.59 6.59 0 0 0-.719-2.294 4.775 4.775 0 0 0-1.521-1.688c-.647-.443-1.504-.664-2.572-.664-1.071 0-1.992.212-2.767.637a5.872 5.872 0 0 0-1.908 1.631 7.188 7.188 0 0 0-1.134 2.296 9.124 9.124 0 0 0-.387 2.628v14.605h-6.639V59.557m30.814 0h6.306v4.26h.111c.588-1.328 1.612-2.498 3.069-3.513 1.458-1.015 3.182-1.521 5.174-1.521 1.732 0 3.217.303 4.452.912 1.236.609 2.25 1.412 3.044 2.408a9.713 9.713 0 0 1 1.741 3.429c.369 1.292.553 2.619.553 3.983v16.597h-6.638V71.396c0-.775-.055-1.586-.166-2.435a6.569 6.569 0 0 0-.718-2.294 4.788 4.788 0 0 0-1.522-1.688c-.646-.443-1.504-.664-2.572-.664-1.07 0-1.992.212-2.766.637a5.851 5.851 0 0 0-1.908 1.631 7.169 7.169 0 0 0-1.135 2.296 9.124 9.124 0 0 0-.387 2.628v14.605h-6.638V59.557m49.51 10.622c0-.848-.12-1.66-.358-2.435a5.614 5.614 0 0 0-1.135-2.047c-.516-.588-1.171-1.06-1.964-1.411-.793-.349-1.724-.525-2.793-.525-1.992 0-3.679.6-5.063 1.799-1.383 1.198-2.148 2.737-2.295 4.619h13.608zm6.639 2.988v.885c0 .294-.019.589-.055.884h-20.192c.072.96.322 1.836.747 2.628a6.69 6.69 0 0 0 1.687 2.048 8.437 8.437 0 0 0 2.378 1.355 7.86 7.86 0 0 0 2.767.497c1.659 0 3.06-.304 4.204-.912a7.856 7.856 0 0 0 2.821-2.518l4.426 3.541c-2.619 3.541-6.418 5.311-11.396 5.311-2.066 0-3.964-.323-5.698-.969-1.734-.644-3.236-1.557-4.509-2.738-1.272-1.179-2.268-2.627-2.987-4.342-.72-1.716-1.078-3.661-1.078-5.837 0-2.139.358-4.084 1.078-5.836.719-1.752 1.706-3.245 2.96-4.481 1.254-1.235 2.738-2.194 4.452-2.878 1.716-.681 3.57-1.022 5.56-1.022 1.844 0 3.55.303 5.118.912a11.122 11.122 0 0 1 4.066 2.71c1.143 1.2 2.038 2.693 2.683 4.483.645 1.788.968 3.881.968 6.279m23.179-6.252c-.518-.738-1.291-1.355-2.324-1.852-1.032-.5-2.084-.748-3.152-.748-1.218 0-2.288.248-3.21.748a6.992 6.992 0 0 0-2.296 1.962 8.446 8.446 0 0 0-1.354 2.739 10.907 10.907 0 0 0-.443 3.07c0 1.033.156 2.057.471 3.07a8.538 8.538 0 0 0 1.409 2.739 7.183 7.183 0 0 0 2.352 1.964c.94.498 2.037.746 3.292.746a8.386 8.386 0 0 0 3.097-.608c1.032-.405 1.862-.996 2.49-1.77l4.149 4.204c-1.107 1.181-2.517 2.094-4.232 2.738-1.715.646-3.568.969-5.56.969-1.956 0-3.808-.314-5.56-.941-1.752-.626-3.283-1.549-4.592-2.766-1.309-1.218-2.341-2.691-3.097-4.426-.756-1.733-1.134-3.707-1.134-5.919 0-2.138.378-4.074 1.134-5.809.756-1.733 1.778-3.208 3.07-4.425a13.728 13.728 0 0 1 4.508-2.821c1.715-.664 3.55-.996 5.506-.996 1.954 0 3.844.369 5.67 1.106 1.826.738 3.272 1.752 4.342 3.043l-4.536 3.983m6.417-2.047v-5.311h4.647v-7.689h6.528v7.689h6.638v5.311h-6.638v12.336c0 1.181.212 2.157.636 2.932.424.774 1.373 1.161 2.849 1.161.443 0 .921-.045 1.439-.137a5.718 5.718 0 0 0 1.382-.415l.222 5.2c-.591.222-1.291.395-2.103.526-.811.129-1.585.194-2.323.194-1.77 0-3.209-.25-4.314-.748-1.107-.497-1.984-1.18-2.628-2.047-.646-.865-1.088-1.862-1.328-2.986a17.355 17.355 0 0 1-.36-3.624V64.868h-4.647m29.872 0v-5.311h4.648v-7.689h6.527v7.689h6.638v5.311h-6.638v12.336c0 1.181.212 2.157.637 2.932.423.774 1.373 1.161 2.849 1.161.443 0 .92-.045 1.438-.137a5.704 5.704 0 0 0 1.382-.415l.222 5.2c-.591.222-1.291.395-2.102.526-.812.129-1.586.194-2.324.194-1.77 0-3.208-.25-4.314-.748-1.107-.497-1.983-1.18-2.628-2.047-.646-.865-1.088-1.862-1.328-2.986a17.356 17.356 0 0 1-.359-3.624V64.868h-4.648m26.444 7.856c0 1.032.156 2.065.469 3.097a8.512 8.512 0 0 0 1.412 2.767 7.381 7.381 0 0 0 2.378 1.991c.958.517 2.102.774 3.43.774 1.328 0 2.471-.257 3.43-.774a7.392 7.392 0 0 0 2.378-1.991 8.531 8.531 0 0 0 1.412-2.767 10.66 10.66 0 0 0 .47-3.097c0-1.033-.158-2.056-.47-3.071a8.601 8.601 0 0 0-1.412-2.738 7.072 7.072 0 0 0-2.378-1.963c-.959-.5-2.102-.748-3.43-.748-1.328 0-2.472.248-3.43.748a7.063 7.063 0 0 0-2.378 1.963 8.58 8.58 0 0 0-1.412 2.738 10.365 10.365 0 0 0-.469 3.071zm-6.749 0c0-2.103.377-4.011 1.133-5.726.756-1.714 1.779-3.181 3.071-4.398 1.29-1.217 2.821-2.157 4.592-2.821 1.77-.664 3.65-.996 5.642-.996 1.992 0 3.872.332 5.643.996 1.771.664 3.3 1.604 4.592 2.821 1.291 1.217 2.313 2.684 3.071 4.398.754 1.715 1.133 3.623 1.133 5.726 0 2.103-.379 4.02-1.133 5.753-.758 1.733-1.78 3.218-3.071 4.454-1.292 1.236-2.821 2.203-4.592 2.903-1.771.7-3.651 1.052-5.643 1.052s-3.872-.352-5.642-1.052c-1.771-.7-3.302-1.667-4.592-2.903-1.292-1.236-2.315-2.721-3.071-4.454-.756-1.733-1.133-3.65-1.133-5.753" fill="#FFF"/><path d="M449.899 52.2c-1.882 0-3.643.351-5.283 1.051-1.641.701-3.053 1.658-4.233 2.876-1.18 1.217-2.111 2.674-2.794 4.371-.682 1.697-1.024 3.541-1.024 5.531 0 2.103.323 4.011.968 5.727.646 1.715 1.551 3.18 2.712 4.397 1.162 1.217 2.554 2.167 4.176 2.85 1.623.682 3.412 1.022 5.367 1.022 1.917 0 3.696-.34 5.339-1.022 1.64-.683 3.05-1.633 4.232-2.85 1.178-1.217 2.101-2.682 2.765-4.397.664-1.716.996-3.624.996-5.727 0-1.99-.313-3.834-.94-5.531-.628-1.697-1.521-3.154-2.683-4.371-1.162-1.218-2.554-2.175-4.177-2.876-1.623-.7-3.429-1.051-5.421-1.051zm23.51 33.912h-23.621c-3.136 0-5.984-.452-8.548-1.356-2.563-.904-4.757-2.213-6.583-3.928-1.825-1.715-3.236-3.818-4.232-6.307-.996-2.489-1.493-5.318-1.493-8.492 0-2.986.525-5.707 1.576-8.16 1.052-2.452 2.517-4.564 4.399-6.333 1.88-1.771 4.101-3.144 6.665-4.123 2.564-.976 5.339-1.464 8.327-1.464 2.986 0 5.753.488 8.298 1.464 2.544.979 4.748 2.352 6.611 4.123 1.861 1.769 3.309 3.881 4.341 6.333 1.034 2.453 1.551 5.174 1.551 8.16 0 1.771-.204 3.393-.609 4.868-.407 1.476-.932 2.813-1.578 4.011a15.475 15.475 0 0 1-2.212 3.155 16.224 16.224 0 0 1-2.573 2.294v.111h9.681v5.644m27.439 0h-6.307v-4.261h-.11c-.591 1.328-1.614 2.498-3.07 3.513-1.457 1.015-3.181 1.522-5.173 1.522-1.733 0-3.217-.305-4.453-.913-1.236-.609-2.25-1.41-3.042-2.408a9.677 9.677 0 0 1-1.744-3.429 14.461 14.461 0 0 1-.553-3.983V59.557h6.639v14.716c0 .773.056 1.586.166 2.434.111.849.351 1.613.719 2.296a4.767 4.767 0 0 0 1.521 1.686c.646.443 1.503.664 2.572.664 1.034 0 1.946-.212 2.74-.636.792-.424 1.438-.968 1.936-1.632a7.23 7.23 0 0 0 1.134-2.296 9.19 9.19 0 0 0 .386-2.626V59.557h6.639v26.555m6.693-26.555h6.639v26.555h-6.639V59.557zm-.941-9.017c0-1.069.397-2 1.189-2.795.794-.792 1.799-1.188 3.016-1.188 1.218 0 2.24.379 3.07 1.134.83.757 1.245 1.705 1.245 2.849 0 1.143-.415 2.093-1.245 2.849-.83.756-1.852 1.133-3.07 1.133-1.217 0-2.222-.395-3.016-1.188-.792-.793-1.189-1.724-1.189-2.794zm32.419 16.375c-.518-.738-1.291-1.355-2.324-1.852-1.032-.5-2.084-.748-3.154-.748-1.217 0-2.286.248-3.208.748a6.962 6.962 0 0 0-2.296 1.962 8.47 8.47 0 0 0-1.356 2.739 10.978 10.978 0 0 0-.442 3.07c0 1.033.157 2.057.47 3.07a8.583 8.583 0 0 0 1.411 2.739 7.183 7.183 0 0 0 2.352 1.964c.94.498 2.036.746 3.291.746a8.395 8.395 0 0 0 3.098-.608c1.032-.405 1.862-.996 2.49-1.77l4.149 4.204c-1.107 1.181-2.517 2.094-4.232 2.738-1.716.646-3.568.969-5.56.969-1.956 0-3.809-.314-5.56-.941-1.752-.626-3.283-1.549-4.592-2.766-1.309-1.218-2.343-2.691-3.097-4.426-.758-1.733-1.135-3.707-1.135-5.919 0-2.138.377-4.074 1.135-5.809.754-1.733 1.778-3.208 3.07-4.425a13.718 13.718 0 0 1 4.508-2.821c1.715-.664 3.55-.996 5.504-.996 1.955 0 3.846.369 5.671 1.106 1.825.738 3.272 1.752 4.343 3.043l-4.536 3.983m7.578-22.627h6.639v26.444h.165l10.07-11.175h8.518l-11.506 12.006 12.225 14.549h-8.795l-10.512-13.609h-.165v13.609h-6.639V44.288zm35.847 35.958h6.252c.885 0 1.843-.063 2.876-.193a9.396 9.396 0 0 0 2.849-.802 5.593 5.593 0 0 0 2.158-1.77c.572-.774.857-1.808.857-3.097 0-2.065-.701-3.504-2.101-4.316-1.403-.811-3.523-1.217-6.363-1.217h-6.528v11.395zm0-17.37h6.196c2.324 0 4.093-.46 5.311-1.383 1.217-.921 1.826-2.23 1.826-3.928 0-1.77-.628-3.022-1.881-3.761-1.255-.739-3.209-1.107-5.864-1.107h-5.588v10.179zm-6.969-15.932h15.268c1.474 0 2.932.175 4.37.525 1.439.351 2.719.923 3.844 1.715 1.126.793 2.038 1.817 2.739 3.071.7 1.253 1.052 2.765 1.052 4.536 0 2.213-.628 4.038-1.881 5.477-1.255 1.439-2.896 2.471-4.924 3.097v.111c2.47.332 4.5 1.292 6.085 2.877 1.585 1.587 2.379 3.707 2.379 6.363 0 2.139-.424 3.936-1.272 5.393-.85 1.456-1.964 2.627-3.348 3.512-1.383.886-2.968 1.522-4.756 1.91a25.792 25.792 0 0 1-5.45.581h-14.106V46.944m39.277 25.78c0 1.032.156 2.065.469 3.097a8.49 8.49 0 0 0 1.411 2.767 7.395 7.395 0 0 0 2.379 1.991c.958.517 2.102.774 3.43.774 1.327 0 2.47-.257 3.43-.774a7.413 7.413 0 0 0 2.378-1.991 8.51 8.51 0 0 0 1.411-2.767c.313-1.032.471-2.065.471-3.097 0-1.033-.158-2.056-.471-3.071a8.578 8.578 0 0 0-1.411-2.738 7.092 7.092 0 0 0-2.378-1.963c-.96-.5-2.103-.748-3.43-.748-1.328 0-2.472.248-3.43.748a7.076 7.076 0 0 0-2.379 1.963 8.558 8.558 0 0 0-1.411 2.738 10.365 10.365 0 0 0-.469 3.071zm-6.749 0c0-2.103.377-4.011 1.133-5.726.756-1.714 1.779-3.181 3.071-4.398 1.29-1.217 2.821-2.157 4.59-2.821 1.771-.664 3.652-.996 5.644-.996 1.991 0 3.872.332 5.643.996 1.769.664 3.3 1.604 4.591 2.821 1.29 1.217 2.314 2.684 3.07 4.398.756 1.715 1.135 3.623 1.135 5.726 0 2.103-.379 4.02-1.135 5.753-.756 1.733-1.78 3.218-3.07 4.454-1.291 1.236-2.822 2.203-4.591 2.903-1.771.7-3.652 1.052-5.643 1.052-1.992 0-3.873-.352-5.644-1.052-1.769-.7-3.3-1.667-4.59-2.903-1.292-1.236-2.315-2.721-3.071-4.454-.756-1.733-1.133-3.65-1.133-5.753m39.11 0c0 1.032.156 2.065.471 3.097a8.47 8.47 0 0 0 1.411 2.767 7.367 7.367 0 0 0 2.377 1.991c.96.517 2.103.774 3.431.774 1.328 0 2.47-.257 3.429-.774a7.41 7.41 0 0 0 2.38-1.991 8.588 8.588 0 0 0 1.411-2.767c.312-1.032.469-2.065.469-3.097 0-1.033-.157-2.056-.469-3.071a8.66 8.66 0 0 0-1.411-2.738 7.09 7.09 0 0 0-2.38-1.963c-.959-.5-2.101-.748-3.429-.748-1.328 0-2.471.248-3.431.748a7.05 7.05 0 0 0-2.377 1.963 8.538 8.538 0 0 0-1.411 2.738 10.303 10.303 0 0 0-.471 3.071zm-6.749 0c0-2.103.377-4.011 1.135-5.726.754-1.714 1.778-3.181 3.069-4.398 1.291-1.217 2.821-2.157 4.592-2.821 1.771-.664 3.651-.996 5.643-.996s3.872.332 5.642.996c1.771.664 3.3 1.604 4.592 2.821 1.291 1.217 2.314 2.684 3.071 4.398.755 1.715 1.133 3.623 1.133 5.726 0 2.103-.378 4.02-1.133 5.753-.757 1.733-1.78 3.218-3.071 4.454-1.292 1.236-2.821 2.203-4.592 2.903-1.77.7-3.65 1.052-5.642 1.052-1.992 0-3.872-.352-5.643-1.052-1.771-.7-3.301-1.667-4.592-2.903-1.291-1.236-2.315-2.721-3.069-4.454-.758-1.733-1.135-3.65-1.135-5.753m34.021-28.436h6.638v26.444h.166l10.068-11.175h8.52l-11.506 12.006 12.226 14.549H691.7l-10.511-13.609h-.166v13.609h-6.638V44.288z" fill="#F4F5F5"/><path d="M717.149 66.639c-.589-.775-1.402-1.448-2.433-2.02a6.867 6.867 0 0 0-3.376-.858c-1.069 0-2.047.222-2.932.664-.885.443-1.328 1.182-1.328 2.214 0 1.033.489 1.759 1.467 2.185.976.424 2.405.856 4.288 1.298.996.222 2 .518 3.014.886 1.014.369 1.936.857 2.767 1.467a7.23 7.23 0 0 1 2.019 2.268c.516.903.773 2.001.773 3.291 0 1.623-.303 2.997-.912 4.122a7.773 7.773 0 0 1-2.433 2.739c-1.015.7-2.196 1.208-3.542 1.52a18.318 18.318 0 0 1-4.177.471c-2.064 0-4.075-.379-6.029-1.134-1.956-.756-3.579-1.835-4.868-3.237l4.37-4.094c.738.96 1.695 1.752 2.876 2.379 1.18.628 2.49.94 3.928.94.479 0 .968-.055 1.466-.165.498-.111.96-.286 1.384-.526.424-.24.764-.561 1.024-.968.256-.406.386-.904.386-1.493 0-1.107-.508-1.9-1.521-2.379-1.016-.48-2.536-.96-4.564-1.438a21.777 21.777 0 0 1-2.904-.859 9.374 9.374 0 0 1-2.517-1.383 6.382 6.382 0 0 1-1.771-2.129c-.443-.848-.664-1.899-.664-3.154 0-1.474.304-2.746.912-3.817a7.867 7.867 0 0 1 2.408-2.628c.995-.682 2.12-1.188 3.373-1.52a15.082 15.082 0 0 1 3.874-.498c1.917 0 3.789.332 5.614.996 1.827.664 3.274 1.677 4.343 3.042l-4.315 3.818" fill="#F4F5F5"/><path d="M95.897 66.634c0-9.662-7.862-17.524-17.525-17.524h-1.604v6.157h1.604c6.269 0 11.368 5.1 11.368 11.367 0 6.27-5.099 11.37-11.368 11.37h-5.507v-37.37h-6.157V84.16h11.664c9.663 0 17.525-7.862 17.525-17.526zM62.793 49.11H51.13c-9.663 0-17.525 7.862-17.525 17.524 0 9.664 7.862 17.526 17.525 17.526h1.604v-6.156H51.13c-6.269 0-11.369-5.1-11.369-11.37 0-6.267 5.1-11.367 11.369-11.367h5.506v37.367h6.157V49.11zm45.991 17.557c0 24.301-19.7 44-44 44-24.301 0-44-19.699-44-44 0-24.3 19.699-44 44-44 24.3 0 44 19.7 44 44z" fill="#FFF"/></g></svg>
|
data/example/views/oauth2.erb
CHANGED
@@ -3,20 +3,10 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="UTF-8">
|
5
5
|
<title>QBO Connect via OAuth2</title>
|
6
|
-
|
7
|
-
<script type="text/javascript" src="<%= QboApi::APP_CENTER_BASE %>/Content/IA/intuit.ipp.anywhere-1.3.1.js"></script>
|
8
|
-
<script>
|
9
|
-
intuit.ipp.anywhere.setup({
|
10
|
-
grantUrl: "<%= @client.authorization_uri(scope: 'com.intuit.quickbooks.accounting', state: session[:state]) %>",
|
11
|
-
datasources: {
|
12
|
-
quickbooks : true,
|
13
|
-
payments : true
|
14
|
-
}
|
15
|
-
});
|
16
|
-
</script>
|
17
6
|
</head>
|
18
|
-
<body>
|
19
|
-
|
20
|
-
|
7
|
+
<body style="padding:15px;">
|
8
|
+
<a href="<%= authorize_url(state: session[:state]) %>">
|
9
|
+
<img src="connect-to-qbo.svg" alt="Connect to QuickBooks Online Button" width="400">
|
10
|
+
</a>
|
21
11
|
</body>
|
22
12
|
</html>
|
data/lib/qbo_api.rb
CHANGED
@@ -22,15 +22,15 @@ class QboApi
|
|
22
22
|
include Attachment
|
23
23
|
include ApiMethods
|
24
24
|
|
25
|
-
attr_accessor :realm_id
|
25
|
+
attr_accessor :access_token, :realm_id
|
26
26
|
attr_accessor :endpoint
|
27
27
|
|
28
28
|
V3_ENDPOINT_BASE_URL = 'https://sandbox-quickbooks.api.intuit.com/v3/company/'
|
29
29
|
PAYMENTS_API_BASE_URL = 'https://sandbox.api.intuit.com/quickbooks/v4/payments'
|
30
30
|
LOG_TAG = "[QuickBooks]"
|
31
31
|
|
32
|
-
# @param attributes [Hash<Symbol,String>]
|
33
32
|
def initialize(attributes = {})
|
33
|
+
raise ArgumentError, "missing keyword: access_token" unless attributes.key?(:access_token)
|
34
34
|
raise ArgumentError, "missing keyword: realm_id" unless attributes.key?(:realm_id)
|
35
35
|
attributes = default_attributes.merge!(attributes)
|
36
36
|
attributes.each do |attribute, value|
|
data/lib/qbo_api/api_methods.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
class QboApi
|
2
2
|
module ApiMethods
|
3
|
-
|
4
3
|
def all(entity, max: 1000, select: nil, inactive: false, params: nil, &block)
|
5
|
-
enumerator = create_all_enumerator(entity, max: max, select: select,
|
6
|
-
|
4
|
+
enumerator = create_all_enumerator(entity, max: max, select: select,
|
5
|
+
inactive: inactive, params: params)
|
7
6
|
if block_given?
|
8
7
|
enumerator.each(&block)
|
9
8
|
else
|
@@ -17,9 +16,6 @@ class QboApi
|
|
17
16
|
request(:get, entity: entity, path: path, params: params)
|
18
17
|
end
|
19
18
|
|
20
|
-
# @example
|
21
|
-
# get(:customer, 5)
|
22
|
-
# @see #get_by_query_filter
|
23
19
|
def get(entity, id_or_query_filter_args, params: nil)
|
24
20
|
if id_or_query_filter_args.is_a?(Array)
|
25
21
|
get_by_query_filter(entity, id_or_query_filter_args, params: params)
|
@@ -29,11 +25,6 @@ class QboApi
|
|
29
25
|
end
|
30
26
|
end
|
31
27
|
|
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
28
|
def get_by_query_filter(entity, query_filter_args, params: nil)
|
38
29
|
query_str = get_query_str(entity, query_filter_args)
|
39
30
|
if resp = query(query_str, params: params)
|
@@ -143,6 +134,5 @@ class QboApi
|
|
143
134
|
resp = get(entity, id)
|
144
135
|
build_deactivate(entity, resp)
|
145
136
|
end
|
146
|
-
|
147
137
|
end
|
148
138
|
end
|
data/lib/qbo_api/attachment.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
class QboApi
|
2
2
|
module Attachment
|
3
|
-
|
4
3
|
def read_attachment(id:)
|
5
4
|
raw_response = connection.get do |request|
|
6
5
|
request.url "#{realm_id}/attachable/#{id}"
|
@@ -14,10 +13,10 @@ class QboApi
|
|
14
13
|
raw_response = attachment_connection.post do |request|
|
15
14
|
request.url "#{realm_id}/upload"
|
16
15
|
request.body = {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
'file_metadata_01':
|
17
|
+
Faraday::UploadIO.new(StringIO.new(payload.to_json), 'application/json', 'attachment.json'),
|
18
|
+
'file_content_01':
|
19
|
+
Faraday::UploadIO.new(attachment, content_type, file_name)
|
21
20
|
}
|
22
21
|
end
|
23
22
|
response(raw_response, entity: :attachable)
|
@@ -36,7 +35,6 @@ class QboApi
|
|
36
35
|
def attachment_connection
|
37
36
|
@attachment_connection ||= authorized_multipart_connection(endpoint_url)
|
38
37
|
end
|
39
|
-
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
data/lib/qbo_api/connection.rb
CHANGED
@@ -4,16 +4,10 @@ require 'faraday/detailed_logger'
|
|
4
4
|
|
5
5
|
class QboApi
|
6
6
|
module Connection
|
7
|
-
AUTHORIZATION_MIDDLEWARES = []
|
8
|
-
|
9
|
-
def Connection.add_authorization_middleware(strategy_name)
|
10
|
-
Connection::AUTHORIZATION_MIDDLEWARES << strategy_name
|
11
|
-
end
|
12
|
-
|
13
7
|
def authorized_json_connection(url, headers: nil)
|
14
8
|
headers ||= {}
|
15
|
-
headers['Accept'] ||= 'application/json'
|
16
|
-
headers['Content-Type'] ||= 'application/json;charset=UTF-8'
|
9
|
+
headers['Accept'] ||= 'application/json'
|
10
|
+
headers['Content-Type'] ||= 'application/json;charset=UTF-8'
|
17
11
|
build_connection(url, headers: headers) do |conn|
|
18
12
|
add_authorization_middleware(conn)
|
19
13
|
add_exception_middleware(conn)
|
@@ -35,17 +29,6 @@ class QboApi
|
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
38
|
-
# @example
|
39
|
-
# connection = build_connection('https://oauth.platform.intuit.com', headers: { 'Accept' => 'application/json' }) do |conn|
|
40
|
-
# conn.basic_auth(client_id, client_secret)
|
41
|
-
# conn.request :url_encoded # application/x-www-form-urlencoded
|
42
|
-
# conn.use FaradayMiddleware::ParseJson, parser_options: { symbolize_names: true }
|
43
|
-
# conn.use Faraday::Response::RaiseError
|
44
|
-
# end
|
45
|
-
# raw_response = connection.post {|req|
|
46
|
-
# req.body = { grant_type: :refresh_token, refresh_token: current_refresh_token }
|
47
|
-
# req.url '/oauth2/v1/tokens/bearer'
|
48
|
-
# }
|
49
32
|
def build_connection(url, headers: nil)
|
50
33
|
Faraday.new(url: url) { |conn|
|
51
34
|
conn.response :detailed_logger, QboApi.logger, LOG_TAG if QboApi.log
|
@@ -119,22 +102,11 @@ class QboApi
|
|
119
102
|
end
|
120
103
|
|
121
104
|
def add_authorization_middleware(conn)
|
122
|
-
|
123
|
-
raise QboApi::Error.new error_body: 'Add a configured authorization_middleware'
|
124
|
-
end) do |strategy_name|
|
125
|
-
next unless public_send("use_#{strategy_name}_middleware?")
|
126
|
-
public_send("add_#{strategy_name}_authorization_middleware", conn)
|
127
|
-
true
|
128
|
-
end
|
105
|
+
conn.request :oauth2, access_token, token_type: 'bearer'
|
129
106
|
end
|
130
107
|
|
131
108
|
def entity_name(entity)
|
132
109
|
singular(entity)
|
133
110
|
end
|
134
|
-
|
135
|
-
require_relative 'connection/oauth1'
|
136
|
-
include OAuth1
|
137
|
-
require_relative 'connection/oauth2'
|
138
|
-
include OAuth2
|
139
111
|
end
|
140
112
|
end
|
data/lib/qbo_api/entity.rb
CHANGED
data/lib/qbo_api/error.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
#200 OK The request succeeded. However, the response body may contain a <Fault> element, indicating an error.
|
3
2
|
#400 Bad request Generally, the request cannot be fulfilled due to bad syntax. In some cases, this response code is returned for a request with bad authorization data.
|
4
3
|
#401 Unauthorized Authentication or authorization has failed.
|
@@ -8,10 +7,12 @@
|
|
8
7
|
#500 Internal Server Error An error occurred on the server while processing the request. Resubmit request once; if it persists, contact developer support.
|
9
8
|
#502 Bad Gateway The server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.
|
10
9
|
#503 Service Unavailable The service is temporarily unavailable.
|
10
|
+
#504 Gateway Timeout
|
11
11
|
# Custom error class for rescuing from all QuickBooks Online errors
|
12
12
|
class QboApi
|
13
13
|
class Error < StandardError
|
14
14
|
attr_reader :fault
|
15
|
+
|
15
16
|
def initialize(errors = nil)
|
16
17
|
if errors
|
17
18
|
@fault = errors
|
@@ -46,4 +47,7 @@ class QboApi
|
|
46
47
|
|
47
48
|
# Raised when QuickBooks Online returns the HTTP status code 503
|
48
49
|
class ServiceUnavailable < Error; end
|
50
|
+
|
51
|
+
# Raised when QuickBooks Online returns the HTTP status code 504
|
52
|
+
class GatewayTimeout < Error; end
|
49
53
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'nokogiri'
|
3
|
-
|
4
3
|
# @private
|
5
4
|
module FaradayMiddleware
|
6
5
|
# @private
|
@@ -25,6 +24,8 @@ module FaradayMiddleware
|
|
25
24
|
raise QboApi::BadGateway.new({ error_body: response.reason_phrase })
|
26
25
|
when 503
|
27
26
|
raise QboApi::ServiceUnavailable.new(error_message(response))
|
27
|
+
when 504
|
28
|
+
raise QboApi::GatewayTimeout.new(error_message(response))
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
@@ -40,7 +41,8 @@ module FaradayMiddleware
|
|
40
41
|
method: response.method,
|
41
42
|
url: response.url,
|
42
43
|
status: response.status,
|
43
|
-
error_body: error_body(response.body)
|
44
|
+
error_body: error_body(response.body),
|
45
|
+
intuit_tid: response[:response_headers]['intuit_tid']
|
44
46
|
}
|
45
47
|
end
|
46
48
|
|
@@ -78,6 +80,5 @@ module FaradayMiddleware
|
|
78
80
|
}
|
79
81
|
end
|
80
82
|
end
|
81
|
-
|
82
83
|
end
|
83
84
|
end
|
data/lib/qbo_api/supporting.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
class QboApi
|
2
2
|
module Supporting
|
3
|
-
|
4
3
|
def cdc(entities:, changed_since:)
|
5
4
|
path = "#{realm_id}/cdc"
|
6
5
|
path = add_params_to_path(path: path, params: { entities: entities, changedSince: cdc_time(changed_since) })
|
@@ -17,6 +16,5 @@ class QboApi
|
|
17
16
|
path = add_params_to_path(path: path, params: params) if params
|
18
17
|
request(:get, path: path)
|
19
18
|
end
|
20
|
-
|
21
19
|
end
|
22
20
|
end
|
data/lib/qbo_api/util.rb
CHANGED
data/lib/qbo_api/version.rb
CHANGED
data/qbo_api.gemspec
CHANGED
@@ -18,14 +18,14 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler"
|
22
|
-
spec.add_development_dependency "rake"
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
spec.add_development_dependency 'webmock'
|
25
25
|
spec.add_development_dependency 'simple_oauth'
|
26
26
|
spec.add_development_dependency 'dotenv'
|
27
27
|
spec.add_development_dependency 'vcr'
|
28
|
-
spec.add_development_dependency '
|
28
|
+
spec.add_development_dependency 'amazing_print'
|
29
29
|
spec.add_runtime_dependency 'faraday'
|
30
30
|
spec.add_runtime_dependency 'faraday_middleware'
|
31
31
|
spec.add_runtime_dependency 'faraday-detailed_logger'
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Pelczarski
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: amazing_print
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -178,14 +178,13 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
-
description:
|
181
|
+
description:
|
182
182
|
email:
|
183
183
|
- christian@minimul.com
|
184
184
|
executables: []
|
185
185
|
extensions: []
|
186
186
|
extra_rdoc_files: []
|
187
187
|
files:
|
188
|
-
- ".env.example_app.oauth1"
|
189
188
|
- ".env.example_app.oauth2"
|
190
189
|
- ".env.test"
|
191
190
|
- ".gitignore"
|
@@ -197,8 +196,8 @@ files:
|
|
197
196
|
- bin/console
|
198
197
|
- bin/setup
|
199
198
|
- example/base.rb
|
200
|
-
- example/oauth.rb
|
201
199
|
- example/oauth2.rb
|
200
|
+
- example/public/connect-to-qbo.svg
|
202
201
|
- example/views/customer.erb
|
203
202
|
- example/views/index.erb
|
204
203
|
- example/views/oauth2.erb
|
@@ -208,8 +207,6 @@ files:
|
|
208
207
|
- lib/qbo_api/attachment.rb
|
209
208
|
- lib/qbo_api/configuration.rb
|
210
209
|
- lib/qbo_api/connection.rb
|
211
|
-
- lib/qbo_api/connection/oauth1.rb
|
212
|
-
- lib/qbo_api/connection/oauth2.rb
|
213
210
|
- lib/qbo_api/entity.rb
|
214
211
|
- lib/qbo_api/error.rb
|
215
212
|
- lib/qbo_api/raise_http_exception.rb
|
@@ -221,7 +218,7 @@ homepage: https://github.com/minimul/qbo_api
|
|
221
218
|
licenses:
|
222
219
|
- MIT
|
223
220
|
metadata: {}
|
224
|
-
post_install_message:
|
221
|
+
post_install_message:
|
225
222
|
rdoc_options: []
|
226
223
|
require_paths:
|
227
224
|
- lib
|
@@ -236,8 +233,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
233
|
- !ruby/object:Gem::Version
|
237
234
|
version: '0'
|
238
235
|
requirements: []
|
239
|
-
rubygems_version: 3.
|
240
|
-
signing_key:
|
236
|
+
rubygems_version: 3.1.2
|
237
|
+
signing_key:
|
241
238
|
specification_version: 4
|
242
239
|
summary: Ruby JSON-only client for QuickBooks Online API v3. Built on top of the Faraday
|
243
240
|
gem.
|
data/.env.example_app.oauth1
DELETED
data/example/oauth.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'bundler/inline'
|
2
|
-
|
3
|
-
require File.expand_path(File.join('..', 'base'), __FILE__)
|
4
|
-
|
5
|
-
install_gems = true
|
6
|
-
gemfile(install_gems) do
|
7
|
-
source 'https://rubygems.org'
|
8
|
-
|
9
|
-
instance_eval(&BASE_GEMS)
|
10
|
-
|
11
|
-
gem 'omniauth'
|
12
|
-
gem 'omniauth-quickbooks'
|
13
|
-
end
|
14
|
-
|
15
|
-
instance_eval(&BASE_SETUP)
|
16
|
-
|
17
|
-
class OAuthApp < Sinatra::Base
|
18
|
-
instance_eval(&BASE_APP_CONFIG)
|
19
|
-
|
20
|
-
CONSUMER_KEY = ENV['QBO_API_CONSUMER_KEY']
|
21
|
-
CONSUMER_SECRET = ENV['QBO_API_CONSUMER_SECRET']
|
22
|
-
|
23
|
-
use Rack::Session::Cookie, secret: '34233adasf/qewrq453agqr9(lasfa)'
|
24
|
-
use OmniAuth::Builder do
|
25
|
-
provider :quickbooks, CONSUMER_KEY, CONSUMER_SECRET
|
26
|
-
end
|
27
|
-
|
28
|
-
get '/' do
|
29
|
-
@app_center = QboApi::APP_CENTER_BASE
|
30
|
-
@auth_data = oauth_data
|
31
|
-
@port = PORT
|
32
|
-
erb :index
|
33
|
-
end
|
34
|
-
|
35
|
-
get '/customer/:id' do
|
36
|
-
if session[:token]
|
37
|
-
api = QboApi.new(oauth_data)
|
38
|
-
@resp = api.get :customer, params[:id]
|
39
|
-
end
|
40
|
-
erb :customer
|
41
|
-
end
|
42
|
-
|
43
|
-
get '/auth/quickbooks/callback' do
|
44
|
-
auth = env["omniauth.auth"][:credentials]
|
45
|
-
session[:token] = auth[:token]
|
46
|
-
session[:secret] = auth[:secret]
|
47
|
-
session[:realm_id] = params['realmId']
|
48
|
-
'<!DOCTYPE html><html lang="en"><head></head><body><script>window.opener.location.reload(); window.close();</script></body></html>'
|
49
|
-
end
|
50
|
-
|
51
|
-
def oauth_data
|
52
|
-
{
|
53
|
-
consumer_key: CONSUMER_KEY,
|
54
|
-
consumer_secret: CONSUMER_SECRET,
|
55
|
-
token: session[:token],
|
56
|
-
token_secret: session[:secret],
|
57
|
-
realm_id: session[:realm_id]
|
58
|
-
}
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
OAuthApp.run!
|
@@ -1,60 +0,0 @@
|
|
1
|
-
class QboApi
|
2
|
-
APP_CENTER_BASE = 'https://appcenter.intuit.com'
|
3
|
-
APP_CENTER_URL = APP_CENTER_BASE + '/Connect/Begin?oauth_token='
|
4
|
-
APP_CONNECTION_URL = APP_CENTER_BASE + '/api/v1/connection'
|
5
|
-
|
6
|
-
attr_accessor :token, :token_secret
|
7
|
-
attr_accessor :consumer_key, :consumer_secret
|
8
|
-
|
9
|
-
module Connection::OAuth1
|
10
|
-
|
11
|
-
def self.included(*)
|
12
|
-
QboApi::Connection.add_authorization_middleware :oauth1
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def default_attributes
|
17
|
-
super.merge!(
|
18
|
-
token: nil, token_secret: nil,
|
19
|
-
consumer_key: defined?(CONSUMER_KEY) ? CONSUMER_KEY : nil,
|
20
|
-
consumer_secret: defined?(CONSUMER_SECRET) ? CONSUMER_SECRET : nil,
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
def add_oauth1_authorization_middleware(conn)
|
25
|
-
gem 'simple_oauth'
|
26
|
-
require 'simple_oauth'
|
27
|
-
conn.request :oauth, oauth_data
|
28
|
-
end
|
29
|
-
|
30
|
-
def use_oauth1_middleware?
|
31
|
-
token != nil
|
32
|
-
end
|
33
|
-
|
34
|
-
# https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/0085_develop_quickbooks_apps/0004_authentication_and_authorization/oauth_management_api#/Reconnect
|
35
|
-
def disconnect
|
36
|
-
path = "#{APP_CONNECTION_URL}/disconnect"
|
37
|
-
request(:get, path: path)
|
38
|
-
end
|
39
|
-
|
40
|
-
# https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/0085_develop_quickbooks_apps/0004_authentication_and_authorization/oauth_management_api#/Reconnect
|
41
|
-
def reconnect
|
42
|
-
path = "#{APP_CONNECTION_URL}/reconnect"
|
43
|
-
request(:get, path: path)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# Use with simple_oauth OAuth1 middleware
|
49
|
-
# @see #add_authorization_middleware
|
50
|
-
def oauth_data
|
51
|
-
{
|
52
|
-
consumer_key: @consumer_key,
|
53
|
-
consumer_secret: @consumer_secret,
|
54
|
-
token: @token,
|
55
|
-
token_secret: @token_secret
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
class QboApi
|
2
|
-
attr_accessor :access_token
|
3
|
-
|
4
|
-
module Connection::OAuth2
|
5
|
-
|
6
|
-
def self.included(*)
|
7
|
-
QboApi::Connection.add_authorization_middleware :oauth2
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def default_attributes
|
12
|
-
super.merge!(
|
13
|
-
access_token: nil
|
14
|
-
)
|
15
|
-
end
|
16
|
-
def add_oauth2_authorization_middleware(conn)
|
17
|
-
conn.request :oauth2, access_token, token_type: 'bearer'
|
18
|
-
end
|
19
|
-
|
20
|
-
def use_oauth2_middleware?
|
21
|
-
access_token != nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|