pokitdok-ruby 0.7.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +34 -20
- data/README.md +25 -1
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/OAuthApplicationClient.rb +149 -0
- data/lib/pokitdok.rb +157 -194
- data/pokitdok-ruby.gemspec +8 -27
- data/spec/fixtures/acme_inc_supplemental_identifiers.834 +35 -0
- data/spec/fixtures/chiropractic_example.837 +33 -0
- data/spec/fixtures/identity_match.json +29 -0
- data/spec/pokitdok_spec.rb +578 -261
- data/spec/spec_helper.rb +1 -1
- metadata +6 -36
- data/spec/vcr_setup.rb +0 -11
- data/vcr_cassettes/activities.yml +0 -66
- data/vcr_cassettes/auth.yml +0 -41
- data/vcr_cassettes/authorizations.yml +0 -57
- data/vcr_cassettes/cash_prices.yml +0 -45
- data/vcr_cassettes/claims.yml +0 -72
- data/vcr_cassettes/claims_status.yml +0 -67
- data/vcr_cassettes/eligibility.yml +0 -144
- data/vcr_cassettes/enrollment.yml +0 -83
- data/vcr_cassettes/files.yml +0 -112
- data/vcr_cassettes/insurance_prices.yml +0 -48
- data/vcr_cassettes/payers.yml +0 -505
- data/vcr_cassettes/plans.yml +0 -134
- data/vcr_cassettes/plans_no_args.yml +0 -133
- data/vcr_cassettes/providers.yml +0 -113
- data/vcr_cassettes/referrals.yml +0 -56
- data/vcr_cassettes/scheduling.yml +0 -182
- data/vcr_cassettes/scheduling_scoped.yml +0 -223
- data/vcr_cassettes/trading_partners_get.yml +0 -43
- data/vcr_cassettes/trading_partners_index.yml +0 -390
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39fe6e6cd01f6b839d325c3f36a8c431f4bb28e1
|
4
|
+
data.tar.gz: 8eb46680810f6453958ae8d914861aa30e4150d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c87e045eecc7c3e9b663da64bc18cc546cb17c77e09c0cdaff5076ca764f9fe87f6fd92b268d98f089985d412befd793db2fe81906740201e7e0f73ff2671a84
|
7
|
+
data.tar.gz: 81923ed48261191bb967eaead0278e6f5308f56b7bc2f93d29f816af28b9836c24071843ae928edc6c07a1c7b9cd0bba832d76bff067db9bc6046843bb4e2189
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
addressable (2.
|
4
|
+
addressable (2.4.0)
|
5
5
|
ansi (1.5.0)
|
6
6
|
ast (2.0.0)
|
7
7
|
astrolabe (1.3.0)
|
@@ -26,15 +26,14 @@ GEM
|
|
26
26
|
faraday (0.9.2)
|
27
27
|
multipart-post (>= 1.2, < 3)
|
28
28
|
ffi (1.9.8)
|
29
|
+
ffi (1.9.8-java)
|
29
30
|
formatador (0.2.5)
|
30
|
-
git (1.
|
31
|
-
github_api (0.
|
32
|
-
addressable (~> 2.
|
31
|
+
git (1.3.0)
|
32
|
+
github_api (0.14.1)
|
33
|
+
addressable (~> 2.4.0)
|
33
34
|
descendants_tracker (~> 0.0.4)
|
34
35
|
faraday (~> 0.8, < 0.10)
|
35
|
-
hashie (>= 3.
|
36
|
-
multi_json (>= 1.7.5, < 2.0)
|
37
|
-
nokogiri (~> 1.6.3)
|
36
|
+
hashie (>= 3.4)
|
38
37
|
oauth2
|
39
38
|
guard (2.12.5)
|
40
39
|
formatador (>= 0.2.4)
|
@@ -52,12 +51,13 @@ GEM
|
|
52
51
|
guard-rubocop (1.2.0)
|
53
52
|
guard (~> 2.0)
|
54
53
|
rubocop (~> 0.20)
|
55
|
-
hashie (3.4.
|
56
|
-
highline (1.7.
|
54
|
+
hashie (3.4.4)
|
55
|
+
highline (1.7.8)
|
57
56
|
hitimes (1.2.2)
|
57
|
+
hitimes (1.2.2-java)
|
58
58
|
http-cookie (1.0.2)
|
59
59
|
domain_name (~> 0.5)
|
60
|
-
jeweler (2.
|
60
|
+
jeweler (2.1.1)
|
61
61
|
builder
|
62
62
|
bundler (>= 1.0)
|
63
63
|
git (>= 1.2.5)
|
@@ -66,7 +66,9 @@ GEM
|
|
66
66
|
nokogiri (>= 1.5.10)
|
67
67
|
rake
|
68
68
|
rdoc
|
69
|
-
|
69
|
+
semver
|
70
|
+
json (1.8.3)
|
71
|
+
json (1.8.3-java)
|
70
72
|
jwt (1.5.1)
|
71
73
|
listen (2.10.0)
|
72
74
|
celluloid (~> 0.16.0)
|
@@ -76,7 +78,7 @@ GEM
|
|
76
78
|
metaclass (0.0.4)
|
77
79
|
method_source (0.8.2)
|
78
80
|
mime-types (2.5)
|
79
|
-
|
81
|
+
mini_portile2 (2.1.0)
|
80
82
|
minitest (5.6.1)
|
81
83
|
minitest-reporters (1.0.16)
|
82
84
|
ansi
|
@@ -85,13 +87,15 @@ GEM
|
|
85
87
|
ruby-progressbar
|
86
88
|
mocha (1.1.0)
|
87
89
|
metaclass (~> 0.0.1)
|
88
|
-
multi_json (1.12.
|
90
|
+
multi_json (1.12.1)
|
89
91
|
multi_xml (0.5.5)
|
90
92
|
multipart-post (2.0.0)
|
91
93
|
nenv (0.2.0)
|
92
94
|
netrc (0.10.3)
|
93
|
-
nokogiri (1.6.
|
94
|
-
|
95
|
+
nokogiri (1.6.8)
|
96
|
+
mini_portile2 (~> 2.1.0)
|
97
|
+
pkg-config (~> 1.1.7)
|
98
|
+
nokogiri (1.6.8-java)
|
95
99
|
notiffany (0.0.6)
|
96
100
|
nenv (~> 0.1)
|
97
101
|
shellany (~> 0.0)
|
@@ -103,18 +107,24 @@ GEM
|
|
103
107
|
rack (>= 1.2, < 3)
|
104
108
|
parser (2.2.2.3)
|
105
109
|
ast (>= 1.1, < 3.0)
|
110
|
+
pkg-config (1.1.7)
|
106
111
|
powerpack (0.1.1)
|
107
112
|
pry (0.10.1)
|
108
113
|
coderay (~> 1.1.0)
|
109
114
|
method_source (~> 0.8.1)
|
110
115
|
slop (~> 3.4)
|
116
|
+
pry (0.10.1-java)
|
117
|
+
coderay (~> 1.1.0)
|
118
|
+
method_source (~> 0.8.1)
|
119
|
+
slop (~> 3.4)
|
120
|
+
spoon (~> 0.0)
|
111
121
|
rack (1.6.4)
|
112
122
|
rainbow (2.0.0)
|
113
|
-
rake (
|
123
|
+
rake (11.2.2)
|
114
124
|
rb-fsevent (0.9.5)
|
115
125
|
rb-inotify (0.9.5)
|
116
126
|
ffi (>= 0.5.0)
|
117
|
-
rdoc (4.2.
|
127
|
+
rdoc (4.2.2)
|
118
128
|
json (~> 1.4)
|
119
129
|
rest-client (1.8.0)
|
120
130
|
http-cookie (>= 1.0.2, < 2.0)
|
@@ -128,6 +138,7 @@ GEM
|
|
128
138
|
ruby-progressbar (~> 1.4)
|
129
139
|
ruby-progressbar (1.7.5)
|
130
140
|
safe_yaml (1.0.4)
|
141
|
+
semver (1.0.1)
|
131
142
|
shellany (0.0.1)
|
132
143
|
simplecov (0.10.0)
|
133
144
|
docile (~> 1.1.0)
|
@@ -135,24 +146,28 @@ GEM
|
|
135
146
|
simplecov-html (~> 0.10.0)
|
136
147
|
simplecov-html (0.10.0)
|
137
148
|
slop (3.6.0)
|
149
|
+
spoon (0.0.4)
|
150
|
+
ffi
|
138
151
|
term-ansicolor (1.3.0)
|
139
152
|
tins (~> 1.0)
|
140
153
|
terminal-notifier (1.6.3)
|
141
154
|
terminal-notifier-guard (1.6.4)
|
142
155
|
thor (0.19.1)
|
143
156
|
thread_safe (0.3.5)
|
157
|
+
thread_safe (0.3.5-java)
|
144
158
|
timers (4.0.1)
|
145
159
|
hitimes
|
146
160
|
tins (1.5.1)
|
147
161
|
unf (0.1.4)
|
148
162
|
unf_ext
|
163
|
+
unf (0.1.4-java)
|
149
164
|
unf_ext (0.0.7.1)
|
150
|
-
vcr (2.9.3)
|
151
165
|
webmock (1.21.0)
|
152
166
|
addressable (>= 2.3.6)
|
153
167
|
crack (>= 0.3.2)
|
154
168
|
|
155
169
|
PLATFORMS
|
170
|
+
java
|
156
171
|
ruby
|
157
172
|
|
158
173
|
DEPENDENCIES
|
@@ -173,8 +188,7 @@ DEPENDENCIES
|
|
173
188
|
simplecov (~> 0.8)
|
174
189
|
terminal-notifier
|
175
190
|
terminal-notifier-guard (~> 1.5)
|
176
|
-
vcr (~> 2.9)
|
177
191
|
webmock (~> 1.17)
|
178
192
|
|
179
193
|
BUNDLED WITH
|
180
|
-
1.12.
|
194
|
+
1.12.5
|
data/README.md
CHANGED
@@ -135,14 +135,38 @@ you can pass a third parameter to PokitDok::Pokitdok.new, like this:
|
|
135
135
|
This library aims to support and is tested against these Ruby versions,
|
136
136
|
using travis-ci:
|
137
137
|
|
138
|
+
* 2.2.3
|
138
139
|
* 2.1.1
|
139
140
|
* 2.0.0
|
140
141
|
* 1.9.3
|
141
142
|
* JRuby in 1.9 mode
|
142
|
-
* Rubinius 2.2.7
|
143
143
|
|
144
144
|
You may have luck with other interpreters - let us know how it goes.
|
145
145
|
|
146
|
+
## Development/Debugging
|
147
|
+
|
148
|
+
##### Prerequisite: Make sure to have the RubyMine plugin installed with IntelliJ.
|
149
|
+
|
150
|
+
#### Steps to getting setup in the IntelliJ IDE:
|
151
|
+
1. Fork and/or clone the `pokitdok-ruby` github repository onto your local machine.
|
152
|
+
2. Open IntelliJ IDE.
|
153
|
+
3. Select `File > New > Project From Existing Sources` and select the directory of the cloned `pokitdok-ruby` project.
|
154
|
+
4. In the pop-up GUI select `Create project from existing sources` and continue selecting next/finish with the default settings.
|
155
|
+
5. Next you want to make sure ruby has selected the correct ruby SDK. It is recommended to use rvm for ruby version management.
|
156
|
+
* Select `File > Project Structure`. Then under the Project -> SDK settings select the ruby version you wish to use with the project (i.e.- `RVM: ruby-1.9.3-p551 [global]`).
|
157
|
+
6. You will probably be prompted to install the project dependencies with bundler which you should do.
|
158
|
+
7. Now to debug tests you need to create a `run configuration`.
|
159
|
+
* Select `Run > Edit Configurations`.
|
160
|
+
* We use `rake` to run our project tasks. So select the `+` button and add a new `Rake` configuration.
|
161
|
+
* A few properties you need to set:
|
162
|
+
* Task Name: `spec`
|
163
|
+
* Ruby SDK -> Use other SDK and 'rake' gem: `Whichever ruby version you chose in step 5`
|
164
|
+
* Bundler Tab: Check the box labeled `Run the script in the context of the bundle (bundle exec)`
|
165
|
+
8. You can now run/debug the project tests in the IntelliJ IDE.
|
166
|
+
* NOTE: Currently the tests will not finish executing though all are completed. This is a known issue with RubyMine.
|
167
|
+
|
168
|
+
NOTE: If you would just like to run the test framework outside of the IDE make sure to have all the dependencies installed via bundle in the project directory then run the following command: `bundle exec rake spec`.
|
169
|
+
|
146
170
|
## License
|
147
171
|
Copyright (c) 2014 PokitDok Inc. See [LICENSE][] for details.
|
148
172
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
# OAuth 2.0 Client implementation for Ruby.
|
4
|
+
class OAuthApplicationClient
|
5
|
+
attr_accessor :token, :user_agent
|
6
|
+
|
7
|
+
# Connect to the PokitDok API with the specified Client ID and Client
|
8
|
+
# Authentication logic located within this class.
|
9
|
+
#
|
10
|
+
# +client_id+ your client ID, provided by PokitDok
|
11
|
+
# +client_secret+ your client secret, provided by PokitDok
|
12
|
+
# +token_url+ token url to be appended for authentication. Defaults to '/oauth2/token'
|
13
|
+
# +redirect_uri+ the Redirect URI set for the PokitDok Platform Application.
|
14
|
+
# This value is managed at https://platform.pokitdok.com in the App Settings
|
15
|
+
# +scope+ a list of scope names that should be used when requesting authorization
|
16
|
+
# +code+ code value received from an authorization code grant
|
17
|
+
# +token+ The current API access token for your PokitDok Platform Application. If not provided a new token is generated.
|
18
|
+
# +user_agent+ user agent to be used as a header in HTTP requests
|
19
|
+
def initialize(client_id, client_secret, token_url, redirect_uri, scope, code, token, user_agent)
|
20
|
+
@client_id = client_id
|
21
|
+
@client_secret = client_secret
|
22
|
+
@token_url = token_url
|
23
|
+
@redirect_uri = redirect_uri
|
24
|
+
@scope = scope
|
25
|
+
@code = code
|
26
|
+
@user_agent = user_agent
|
27
|
+
@token = token
|
28
|
+
|
29
|
+
@api_client = OAuth2::Client.new(@client_id, @client_secret, site: @api_url, token_url: @token_url, raise_errors: false)
|
30
|
+
if @token.nil?
|
31
|
+
fetch_access_token(@code)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Perform a GET request given the http request path and optional params
|
36
|
+
#
|
37
|
+
# +path+ request path
|
38
|
+
# +params+ an optional hash of parameters that will be sent in the request
|
39
|
+
def get_request(path, params, &block)
|
40
|
+
if isAccessTokenExpired?
|
41
|
+
fetch_access_token()
|
42
|
+
end
|
43
|
+
@token.get(path, params: params, headers: headers, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Perform a PUT request given the http request path and optional params
|
47
|
+
#
|
48
|
+
# +path+ request path
|
49
|
+
# +params+ an optional hash of parameters that will be sent in the request
|
50
|
+
def put_request(path, params = {}, &block)
|
51
|
+
if isAccessTokenExpired?
|
52
|
+
fetch_access_token()
|
53
|
+
end
|
54
|
+
headers.merge({ headers: { :'Content-Type' => 'application/json'}})
|
55
|
+
@token.put(path, body: params.to_json, headers: headers({:'Content-Type' => 'application/json'}), &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Perform a POST request given the http request path and optional params
|
59
|
+
#
|
60
|
+
# +path+ request path
|
61
|
+
# +params+ an optional hash of parameters that will be sent in the request
|
62
|
+
def post_request(path, params = {}, &block)
|
63
|
+
if isAccessTokenExpired?
|
64
|
+
fetch_access_token()
|
65
|
+
end
|
66
|
+
headers.merge({ headers: { :'Content-Type' => 'application/json'}})
|
67
|
+
@token.post(path, body: params.to_json, headers: headers({:'Content-Type' => 'application/json'}), &block)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Perform a POST request given the http request path, a file and optional params
|
71
|
+
#
|
72
|
+
# +path+ request path
|
73
|
+
# +file+ the file to be sent with the request
|
74
|
+
# +params+ an optional hash of parameters that will be sent in the request
|
75
|
+
def post_file(endpoint, file=nil, params={})
|
76
|
+
if isAccessTokenExpired?
|
77
|
+
fetch_access_token()
|
78
|
+
end
|
79
|
+
url = URI.parse(@api_url + endpoint)
|
80
|
+
|
81
|
+
File.open(file) do |f|
|
82
|
+
additional_params = params.merge({'file' => UploadIO.new(f, 'application/EDI-X12', file)})
|
83
|
+
req = Net::HTTP::Post::Multipart.new(url.path, additional_params)
|
84
|
+
|
85
|
+
req['Authorization'] = "Bearer #{self.token.token}"
|
86
|
+
req['User-Agent'] = @user_agent
|
87
|
+
|
88
|
+
@response = Net::HTTP.start(url.host, url.port) do |http|
|
89
|
+
http.request(req)
|
90
|
+
end
|
91
|
+
JSON.parse(@response.body)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Perform a DELETE request given the http request path and optional params
|
96
|
+
#
|
97
|
+
# +path+ request path
|
98
|
+
# +params+ an optional hash of parameters that will be sent in the request
|
99
|
+
def delete_request(path, params = {}, &block)
|
100
|
+
if isAccessTokenExpired?
|
101
|
+
fetch_access_token()
|
102
|
+
end
|
103
|
+
@token.delete(path, body: params.to_json, headers: headers({:'Content-Type' => 'application/json'}), &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Construct OAuth2 Authorization Grant URL
|
107
|
+
def authorization_url()
|
108
|
+
if @redirect_uri.nil? || @scope.nil?
|
109
|
+
raise 'A redirect_uri and scope must be specified when the client is instantiated in order to get a working authorization URL'
|
110
|
+
end
|
111
|
+
@api_client.auth_code.authorize_url(redirect_uri: @redirect_uri, scope: @scope)
|
112
|
+
end
|
113
|
+
|
114
|
+
### PRIVATE METHODS ###
|
115
|
+
|
116
|
+
# Retrieves an OAuth2 access token. If `code` is not specified, the client_credentials
|
117
|
+
# grant type will be used based on the client_id and client_secret. If `code` is not None,
|
118
|
+
# an authorization_code grant type will be used.
|
119
|
+
#
|
120
|
+
# +code+ optional authorization code used for scope purposes
|
121
|
+
def fetch_access_token(code = nil)
|
122
|
+
if code
|
123
|
+
# Currently non functioning as our OAuth2 authorization_code grant type is not implemented on the server
|
124
|
+
params = {
|
125
|
+
headers: { 'Authorization' => 'Basic' },
|
126
|
+
scope: @scope,
|
127
|
+
redirect_uri: @redirect_uri
|
128
|
+
}
|
129
|
+
@token = @api_client.auth_code.get_token(code, params)
|
130
|
+
else
|
131
|
+
@token = @api_client.client_credentials.get_token(headers: { 'Authorization' => 'Basic' })
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns a standard set of headers to be passed along with all requests
|
136
|
+
def headers(additional_headers = {})
|
137
|
+
{ 'User-Agent' => @user_agent }.merge(additional_headers)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Check if the access token is expired
|
141
|
+
def isAccessTokenExpired?
|
142
|
+
if !@token.is_a?(OAuth2::AccessToken)
|
143
|
+
return true
|
144
|
+
end
|
145
|
+
@token.expired?
|
146
|
+
end
|
147
|
+
|
148
|
+
private :headers, :isAccessTokenExpired?, :fetch_access_token
|
149
|
+
end
|
data/lib/pokitdok.rb
CHANGED
@@ -11,15 +11,13 @@ require 'rubygems'
|
|
11
11
|
require 'bundler/setup'
|
12
12
|
require 'base64'
|
13
13
|
require 'json'
|
14
|
-
require '
|
14
|
+
require 'OAuthApplicationClient'
|
15
15
|
require 'net/http/post/multipart'
|
16
16
|
|
17
17
|
module PokitDok
|
18
18
|
# PokitDok API client implementation for Ruby.
|
19
|
-
class PokitDok
|
20
|
-
|
21
|
-
|
22
|
-
attr_reader :client # :nodoc:
|
19
|
+
class PokitDok < OAuthApplicationClient
|
20
|
+
attr_reader :api_client # :nodoc:
|
23
21
|
attr_reader :api_url
|
24
22
|
attr_reader :version
|
25
23
|
|
@@ -27,36 +25,19 @@ module PokitDok
|
|
27
25
|
# Secret.
|
28
26
|
#
|
29
27
|
# +client_id+ your client ID, provided by PokitDok
|
30
|
-
#
|
31
28
|
# +client_secret+ your client secret, provided by PokitDok
|
29
|
+
# +version+ The API version that should be used for requests. Defaults to the latest version.
|
30
|
+
# +base+ The base URL to use for API requests. Defaults to https://platform.pokitdok.com
|
32
31
|
#
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
# TODO: Make it simpler to pass in params out of order (also so you don't have to do init(..., nil, nil, nil, param))
|
33
|
+
#
|
34
|
+
def initialize(client_id, client_secret, version='v4', base='https://platform.pokitdok.com',
|
35
|
+
redirect_uri=nil, scope= nil, code=nil, token= nil)
|
36
36
|
@version = version
|
37
|
+
@api_url = "#{base}/api/#{version}"
|
38
|
+
@user_agent = "pokitdok-ruby 0.8 #{RUBY_DESCRIPTION}"
|
37
39
|
|
38
|
-
|
39
|
-
@client = OAuth2::Client.new(@client_id, @client_secret,
|
40
|
-
site: @api_url, token_url: '/oauth2/token')
|
41
|
-
|
42
|
-
|
43
|
-
@scopes = {}
|
44
|
-
@scopes['default'] = { scope: refresh_token }
|
45
|
-
scope 'default'
|
46
|
-
end
|
47
|
-
|
48
|
-
# Accessor for the PokitDok Platform URL, overridable for testing.
|
49
|
-
def url_base
|
50
|
-
POKITDOK_URL_BASE
|
51
|
-
end
|
52
|
-
|
53
|
-
# Adds an authorization code for a given OAuth2 scope.
|
54
|
-
#
|
55
|
-
# +name+ the scope name
|
56
|
-
# +code+ the authorization code
|
57
|
-
#
|
58
|
-
def scope_code(name, code)
|
59
|
-
@scopes[name] = { code: code }
|
40
|
+
super(client_id, client_secret, '/oauth2/token', redirect_uri, scope, code, token, user_agent)
|
60
41
|
end
|
61
42
|
|
62
43
|
# Invokes the appointments endpoint, to query for open appointment slots
|
@@ -66,7 +47,6 @@ module PokitDok
|
|
66
47
|
# +params+ an optional Hash of parameters
|
67
48
|
#
|
68
49
|
def activities(params = {})
|
69
|
-
scope 'default'
|
70
50
|
get('activities/', params)
|
71
51
|
end
|
72
52
|
|
@@ -75,7 +55,6 @@ module PokitDok
|
|
75
55
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
76
56
|
#
|
77
57
|
def authorizations(params = {})
|
78
|
-
scope 'default'
|
79
58
|
post('authorizations/', params)
|
80
59
|
end
|
81
60
|
|
@@ -84,7 +63,6 @@ module PokitDok
|
|
84
63
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
85
64
|
#
|
86
65
|
def cash_prices(params = {})
|
87
|
-
scope 'default'
|
88
66
|
get('prices/cash', params)
|
89
67
|
end
|
90
68
|
|
@@ -93,7 +71,6 @@ module PokitDok
|
|
93
71
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
94
72
|
#
|
95
73
|
def claims(params = {})
|
96
|
-
scope 'default'
|
97
74
|
post('claims/', params)
|
98
75
|
end
|
99
76
|
|
@@ -102,16 +79,39 @@ module PokitDok
|
|
102
79
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
103
80
|
#
|
104
81
|
def claims_status(params = {})
|
105
|
-
scope 'default'
|
106
82
|
post('claims/status', params)
|
107
83
|
end
|
108
84
|
|
85
|
+
# Invokes the ICD convert endpoint.
|
86
|
+
#
|
87
|
+
# +params+ an optional hash of parameters
|
88
|
+
#
|
89
|
+
def icd_convert(params = {})
|
90
|
+
get("icd/convert/#{params[:code]}")
|
91
|
+
end
|
92
|
+
|
93
|
+
# Invokes the mpc endpoint.
|
94
|
+
#
|
95
|
+
# +params+ an optional hash of parameters
|
96
|
+
#
|
97
|
+
def mpc(params = {})
|
98
|
+
get('mpc/', params)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Uploads an .837 file to the claims convert endpoint.
|
102
|
+
# Uses the multipart-post gem, since oauth2 doesn't support multipart.
|
103
|
+
#
|
104
|
+
# +x12_claims_file+ the path to the file to transmit
|
105
|
+
#
|
106
|
+
def claims_convert(x12_claims_file)
|
107
|
+
request('/claims/convert', 'POST', x12_claims_file)
|
108
|
+
end
|
109
|
+
|
109
110
|
# Invokes the eligibility endpoint.
|
110
111
|
#
|
111
112
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
112
113
|
#
|
113
114
|
def eligibility(params = {})
|
114
|
-
scope 'default'
|
115
115
|
post('eligibility/', params)
|
116
116
|
end
|
117
117
|
|
@@ -120,10 +120,36 @@ module PokitDok
|
|
120
120
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
121
121
|
#
|
122
122
|
def enrollment(params = {})
|
123
|
-
scope 'default'
|
124
123
|
post('enrollment/', params)
|
125
124
|
end
|
126
125
|
|
126
|
+
# Uploads an .834 file to the enrollment snapshot endpoint.
|
127
|
+
# Uses the multipart-post gem, since oauth2 doesn't support multipart.
|
128
|
+
#
|
129
|
+
# +trading_partner_id+ the trading partner to transmit to
|
130
|
+
# +x12_file+ the path to the file to transmit
|
131
|
+
#
|
132
|
+
def enrollment_snapshot(trading_partner_id, x12_file)
|
133
|
+
request("/enrollment/snapshot/#{trading_partner_id}", "POST", x12_file)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Invokes the enrollment snapshots endpoint.
|
137
|
+
#
|
138
|
+
# +params+ an optional Hash of parameters
|
139
|
+
#
|
140
|
+
def enrollment_snapshots(params = {})
|
141
|
+
snapshot_id = params.delete :snapshot_id
|
142
|
+
get("enrollment/snapshot" + (snapshot_id ? "/#{snapshot_id}" : ''), params)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Invokes the enrollment snapshots data endpoint.
|
146
|
+
#
|
147
|
+
# +params+ an optional Hash of parameters
|
148
|
+
#
|
149
|
+
def enrollment_snapshot_data(params = {})
|
150
|
+
get("enrollment/snapshot/#{params[:snapshot_id]}/data")
|
151
|
+
end
|
152
|
+
|
127
153
|
# Uploads an EDI file to the files endpoint.
|
128
154
|
# Uses the multipart-post gem, since oauth2 doesn't support multipart.
|
129
155
|
#
|
@@ -131,22 +157,7 @@ module PokitDok
|
|
131
157
|
# +filename+ the path to the file to transmit
|
132
158
|
#
|
133
159
|
def files(trading_partner_id, filename)
|
134
|
-
|
135
|
-
url = URI.parse(@api_url + '/files/')
|
136
|
-
|
137
|
-
File.open(filename) do |f|
|
138
|
-
req = Net::HTTP::Post::Multipart.new url.path,
|
139
|
-
'file' => UploadIO.new(f, 'application/EDI-X12', filename),
|
140
|
-
'trading_partner_id' => trading_partner_id
|
141
|
-
req['Authorization'] = "Bearer #{default_scope.token}"
|
142
|
-
req['User-Agent'] = user_agent
|
143
|
-
|
144
|
-
@response = Net::HTTP.start(url.host, url.port) do |http|
|
145
|
-
http.request(req)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
JSON.parse(@response.body)
|
160
|
+
request('/files/', 'POST', filename, { trading_partner_id: trading_partner_id})
|
150
161
|
end
|
151
162
|
|
152
163
|
# Invokes the insurance prices endpoint.
|
@@ -154,7 +165,6 @@ module PokitDok
|
|
154
165
|
# +params+ an optional hash of parameters
|
155
166
|
#
|
156
167
|
def insurance_prices(params = {})
|
157
|
-
scope 'default'
|
158
168
|
get('prices/insurance', params)
|
159
169
|
end
|
160
170
|
|
@@ -163,7 +173,6 @@ module PokitDok
|
|
163
173
|
# +params+ an optional hash of parameters
|
164
174
|
#
|
165
175
|
def payers(params = {})
|
166
|
-
scope 'default'
|
167
176
|
get('payers/', params)
|
168
177
|
end
|
169
178
|
|
@@ -172,7 +181,6 @@ module PokitDok
|
|
172
181
|
# +params+ an optional Hash of parameters
|
173
182
|
#
|
174
183
|
def plans(params = {})
|
175
|
-
scope 'default'
|
176
184
|
get('plans/', params)
|
177
185
|
end
|
178
186
|
|
@@ -181,10 +189,7 @@ module PokitDok
|
|
181
189
|
# +params+ an optional Hash of parameters
|
182
190
|
#
|
183
191
|
def providers(params = {})
|
184
|
-
|
185
|
-
request.params = params
|
186
|
-
end
|
187
|
-
JSON.parse(response.body)
|
192
|
+
get('providers/', params)
|
188
193
|
end
|
189
194
|
|
190
195
|
# Invokes the referrals endpoint.
|
@@ -192,7 +197,6 @@ module PokitDok
|
|
192
197
|
# +params+ an optional Hash of parameters
|
193
198
|
#
|
194
199
|
def referrals(params = {})
|
195
|
-
scope 'default'
|
196
200
|
post('referrals/', params)
|
197
201
|
end
|
198
202
|
|
@@ -202,12 +206,7 @@ module PokitDok
|
|
202
206
|
#
|
203
207
|
def trading_partners(params = {})
|
204
208
|
trading_partner_id = params.delete :trading_partner_id
|
205
|
-
|
206
|
-
response =
|
207
|
-
default_scope.get("tradingpartners/#{trading_partner_id}") do |request|
|
208
|
-
request.params = params
|
209
|
-
end
|
210
|
-
JSON.parse(response.body)
|
209
|
+
get("tradingpartners/#{trading_partner_id}")
|
211
210
|
end
|
212
211
|
|
213
212
|
# Scheduling endpoints
|
@@ -219,23 +218,18 @@ module PokitDok
|
|
219
218
|
# +params+ an optional Hash of parameters
|
220
219
|
#
|
221
220
|
def appointment(params = {})
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
get_one('schedule/appointmenttypes/', @appointment_id, params)
|
221
|
+
appointment_id = params.delete :appointment_id
|
222
|
+
get("schedule/appointmenttypes/#{appointment_id}", params)
|
226
223
|
end
|
227
224
|
|
228
225
|
# Invokes the activities endpoint.
|
229
226
|
#
|
230
227
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
231
|
-
# get the user's authorization via our OAuth2 provider
|
232
|
-
# authorization code you received into
|
233
|
-
# scope_code('user_schedule', '(the authorization code)')
|
228
|
+
# get the user's authorization via our OAuth2 provider
|
234
229
|
#
|
235
230
|
# +params+ an optional Hash of parameters
|
236
231
|
#
|
237
232
|
def appointments(params = {})
|
238
|
-
scope 'user_schedule'
|
239
233
|
get('schedule/appointments/', params)
|
240
234
|
end
|
241
235
|
|
@@ -246,13 +240,7 @@ module PokitDok
|
|
246
240
|
#
|
247
241
|
def appointment_type(params = {})
|
248
242
|
appointment_type = params.delete :uuid
|
249
|
-
|
250
|
-
response =
|
251
|
-
default_scope.get("schedule/appointmenttypes/#{appointment_type}") do |request|
|
252
|
-
request.params = params
|
253
|
-
end
|
254
|
-
|
255
|
-
JSON.parse(response.body)
|
243
|
+
get("schedule/appointmenttypes/#{appointment_type}")
|
256
244
|
end
|
257
245
|
|
258
246
|
# Invokes the appointment_types endpoint.
|
@@ -260,51 +248,39 @@ module PokitDok
|
|
260
248
|
# +params+ an optional hash of parameters
|
261
249
|
#
|
262
250
|
def appointment_types(params = {})
|
263
|
-
scope 'default'
|
264
251
|
get('schedule/appointmenttypes/', params)
|
265
252
|
end
|
266
253
|
|
267
254
|
# Books an appointment.
|
268
255
|
#
|
269
256
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
270
|
-
# get the user's authorization via our OAuth2 provider
|
271
|
-
# authorization code you received into
|
272
|
-
# scope_code('user_schedule', '(the authorization code)')
|
257
|
+
# get the user's authorization via our OAuth2 provider
|
273
258
|
#
|
274
259
|
# +params+ an optional hash of parameters that will be sent in the POST body
|
275
260
|
#
|
276
261
|
def book_appointment(appointment_uuid, params = {})
|
277
|
-
|
278
|
-
|
279
|
-
put_one("schedule/appointments", appointment_uuid, params)
|
262
|
+
put("schedule/appointments/#{appointment_uuid}", params)
|
280
263
|
end
|
281
264
|
|
282
265
|
# Cancels the specified appointment.
|
283
266
|
#
|
284
267
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
285
|
-
# get the user's authorization via our OAuth2 provider
|
286
|
-
# authorization code you received into
|
287
|
-
# scope_code('user_schedule', '(the authorization code)')
|
268
|
+
# get the user's authorization via our OAuth2 provider
|
288
269
|
#
|
289
270
|
# +params+ an optional Hash of parameters
|
290
271
|
#
|
291
272
|
def cancel_appointment(appointment_uuid, params={})
|
292
|
-
|
293
|
-
|
294
|
-
delete_one("schedule/appointments", appointment_uuid, params)
|
273
|
+
delete("schedule/appointments/#{appointment_uuid}", params)
|
295
274
|
end
|
296
275
|
|
297
276
|
# Invokes the schedule/appointments endpoint.
|
298
277
|
#
|
299
278
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
300
|
-
# get the user's authorization via our OAuth2 provider
|
301
|
-
# authorization code you received into
|
302
|
-
# scope_code('user_schedule', '(the authorization code)')
|
279
|
+
# get the user's authorization via our OAuth2 provider
|
303
280
|
#
|
304
281
|
# +params+ an optional hash of parameters
|
305
282
|
#
|
306
283
|
def open_appointment_slots(params = {})
|
307
|
-
scope 'user_schedule'
|
308
284
|
get('schedule/appointments', params)
|
309
285
|
end
|
310
286
|
|
@@ -313,7 +289,6 @@ module PokitDok
|
|
313
289
|
# +params an optional Hash of parameters
|
314
290
|
#
|
315
291
|
def schedulers(params = {})
|
316
|
-
scope 'default'
|
317
292
|
get('schedule/schedulers/', params)
|
318
293
|
end
|
319
294
|
|
@@ -324,25 +299,18 @@ module PokitDok
|
|
324
299
|
#
|
325
300
|
def scheduler(params = {})
|
326
301
|
scheduler_id = params.delete :uuid
|
327
|
-
|
328
|
-
response =
|
329
|
-
default_scope.get("schedule/schedulers/#{scheduler_id}") do |request|
|
330
|
-
request.params = params
|
331
|
-
end
|
332
|
-
JSON.parse(response.body)
|
302
|
+
get("schedule/schedulers/#{scheduler_id}")
|
333
303
|
end
|
334
304
|
|
335
305
|
# Invokes the slots endpoint.
|
336
306
|
#
|
337
307
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
338
|
-
# get the user's authorization via our OAuth2 provider
|
339
|
-
# authorization code you received into
|
340
|
-
# scope_code('user_schedule', '(the authorization code)')
|
308
|
+
# get the user's authorization via our OAuth2 provider
|
341
309
|
#
|
342
310
|
# +params+ an optional Hash of parameters
|
343
311
|
#
|
344
|
-
def
|
345
|
-
|
312
|
+
def schedule_slots(params = {})
|
313
|
+
post('/schedule/slots/', params)
|
346
314
|
end
|
347
315
|
|
348
316
|
# Invokes the pharmacy plans endpoint.
|
@@ -350,10 +318,7 @@ module PokitDok
|
|
350
318
|
# +params+ an optional Hash of parameters
|
351
319
|
#
|
352
320
|
def pharmacy_plans(params = {})
|
353
|
-
|
354
|
-
request.params = params
|
355
|
-
end
|
356
|
-
JSON.parse(response.body)
|
321
|
+
get('pharmacy/plans', params)
|
357
322
|
end
|
358
323
|
|
359
324
|
# Invokes the pharmacy formulary endpoint.
|
@@ -361,10 +326,7 @@ module PokitDok
|
|
361
326
|
# +params+ an optional Hash of parameters
|
362
327
|
#
|
363
328
|
def pharmacy_formulary(params = {})
|
364
|
-
|
365
|
-
request.params = params
|
366
|
-
end
|
367
|
-
JSON.parse(response.body)
|
329
|
+
get('pharmacy/formulary', params)
|
368
330
|
end
|
369
331
|
|
370
332
|
# Invokes the pharmacy network cost endpoint.
|
@@ -374,76 +336,110 @@ module PokitDok
|
|
374
336
|
def pharmacy_network(params = {})
|
375
337
|
npi = params.delete :npi
|
376
338
|
endpoint = npi ? "pharmacy/network/#{npi}" : "pharmacy/network"
|
377
|
-
|
378
|
-
request.params = params
|
379
|
-
end
|
380
|
-
JSON.parse(response.body)
|
339
|
+
get(endpoint, params)
|
381
340
|
end
|
382
341
|
|
383
342
|
# Updates the specified appointment.
|
384
343
|
#
|
385
344
|
# This endpoint uses the user_schedule OAuth2 scope. You'll need to
|
386
|
-
# get the user's authorization via our OAuth2 provider
|
387
|
-
# authorization code you received into
|
388
|
-
# scope_code('user_schedule', '(the authorization code)')
|
345
|
+
# get the user's authorization via our OAuth2 provider
|
389
346
|
#
|
390
347
|
# +params+ an optional Hash of parameters
|
391
348
|
#
|
392
349
|
def update_appointment(appointment_uuid, params={})
|
393
|
-
|
350
|
+
put("schedule/appointments/#{appointment_uuid}", params)
|
351
|
+
end
|
394
352
|
|
395
|
-
|
396
|
-
|
353
|
+
# Invokes the identity endpoint for creation
|
354
|
+
#
|
355
|
+
# +params+ a hash of parameters that will be sent in the POST body
|
356
|
+
#
|
357
|
+
def create_identity(params = {})
|
358
|
+
post('identity/', params)
|
359
|
+
end
|
397
360
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
361
|
+
# Invokes the identity endpoint for updating
|
362
|
+
#
|
363
|
+
# +identity_uuid+ unique id of the identity to be updated
|
364
|
+
# +params+ a hash of parameters that will be sent in the PUT body
|
365
|
+
#
|
366
|
+
def update_identity(identity_uuid, params = {})
|
367
|
+
put("identity/#{identity_uuid}", params)
|
368
|
+
end
|
403
369
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
370
|
+
# Invokes the identity endpoint for querying
|
371
|
+
#
|
372
|
+
# +params+ an optional hash of parameters that will be sent in the GET body
|
373
|
+
#
|
374
|
+
def identity(params = {})
|
375
|
+
identity_uuid = params.delete :identity_uuid
|
376
|
+
get("identity" + (identity_uuid ? "/#{identity_uuid}" : ''), params)
|
377
|
+
end
|
408
378
|
|
409
|
-
|
410
|
-
|
379
|
+
# Invokes the identity history endpoint
|
380
|
+
#
|
381
|
+
# +identity_uuid+ unique id of the identity to be updated
|
382
|
+
# +historical_version+ historical version of the identity being requested
|
383
|
+
#
|
384
|
+
def identity_history(identity_uuid, historical_version=nil)
|
385
|
+
get("identity/#{identity_uuid}/history" + (historical_version ? "/#{historical_version}" : ''))
|
386
|
+
end
|
411
387
|
|
412
|
-
|
413
|
-
|
388
|
+
# Invokes the identity endpoint for querying
|
389
|
+
#
|
390
|
+
# +params+ hash of parameters that will be sent in the POST body
|
391
|
+
#
|
392
|
+
def identity_match(params = {})
|
393
|
+
post("identity/match", params)
|
394
|
+
end
|
414
395
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
396
|
+
# Invokes the the general request method for submitting API request.
|
397
|
+
#
|
398
|
+
# +endpoint+ the API request path
|
399
|
+
# +method+ the http request method that should be used
|
400
|
+
# +file+ file when the API accepts file uploads as input
|
401
|
+
# +params+ an optional Hash of parameters
|
402
|
+
#
|
403
|
+
# NOTE: There might be a better way of achieving the seperation of get/get_request
|
404
|
+
# but currently using the "send" method will go down the ancestor chain until the correct
|
405
|
+
# method is found. In this case the 'httpMethod'_request
|
406
|
+
def request(endpoint, method='get', file=nil, params={})
|
407
|
+
method = method.downcase
|
408
|
+
if file
|
409
|
+
self.send('post_file', endpoint, file, params)
|
410
|
+
else
|
411
|
+
# Work around to delete the leading slash on the request endpoint
|
412
|
+
# Currently the module we're using appends a slash to the base url
|
413
|
+
# so an additional url will break the request.
|
414
|
+
# Refer to ...faraday/connection.rb L#404
|
415
|
+
if endpoint[0] == '/'
|
416
|
+
endpoint[0] = ''
|
419
417
|
end
|
418
|
+
self.send("#{method}_request", endpoint, params)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
private
|
423
|
+
def get(endpoint, params = {})
|
424
|
+
response = request(endpoint, 'GET', nil, params)
|
420
425
|
|
421
426
|
JSON.parse(response.body)
|
422
427
|
end
|
423
428
|
|
424
429
|
def post(endpoint, params = {})
|
425
|
-
response =
|
426
|
-
body: params.to_json) do |request|
|
427
|
-
request.headers['Content-Type'] = 'application/json'
|
428
|
-
end
|
430
|
+
response = request(endpoint, 'POST', nil, params)
|
429
431
|
|
430
432
|
JSON.parse(response.body)
|
431
433
|
end
|
432
434
|
|
433
|
-
def
|
434
|
-
response =
|
435
|
-
body: params.to_json) do |request|
|
436
|
-
request.headers['Content-Type'] = 'application/json'
|
437
|
-
end
|
435
|
+
def put(endpoint, params = {})
|
436
|
+
response = request(endpoint, 'PUT', nil, params)
|
438
437
|
|
439
438
|
JSON.parse(response.body)
|
440
439
|
end
|
441
440
|
|
442
|
-
def
|
443
|
-
response =
|
444
|
-
body: params.to_json) do |request|
|
445
|
-
request.headers['Content-Type'] = 'application/json'
|
446
|
-
end
|
441
|
+
def delete(endpoint, params = {})
|
442
|
+
response = request(endpoint, 'DELETE', nil, params)
|
447
443
|
|
448
444
|
if response.body.empty?
|
449
445
|
response.status == 204
|
@@ -451,38 +447,5 @@ module PokitDok
|
|
451
447
|
JSON.parse(response.body)
|
452
448
|
end
|
453
449
|
end
|
454
|
-
|
455
|
-
# Refreshes the client token associated with this PokitDok connection
|
456
|
-
#
|
457
|
-
# FIXME: automatic refresh on expiration
|
458
|
-
#
|
459
|
-
def refresh_token(code=nil)
|
460
|
-
body = {}
|
461
|
-
body[:code] = code unless code.nil?
|
462
|
-
|
463
|
-
@client.client_credentials.get_token(
|
464
|
-
headers: { 'Authorization' => 'Basic' })
|
465
|
-
end
|
466
|
-
|
467
|
-
def scope(name)
|
468
|
-
raise ArgumentError, "You need to provide an authorization code for " \
|
469
|
-
"the scope #{name} with the scope_code method" if @scopes[name].nil?
|
470
|
-
|
471
|
-
@current_scope = name
|
472
|
-
|
473
|
-
if @scopes[name][:scope].nil?
|
474
|
-
@scopes[name][:scope] = refresh_token(@scopes[name][:code])
|
475
|
-
end
|
476
|
-
|
477
|
-
@scopes[name][:scope]
|
478
|
-
end
|
479
|
-
|
480
|
-
def current_scope
|
481
|
-
@scopes[@current_scope][:scope]
|
482
|
-
end
|
483
|
-
|
484
|
-
def default_scope
|
485
|
-
@scopes['default'][:scope]
|
486
|
-
end
|
487
450
|
end
|
488
451
|
end
|