updox 0.12.0 → 1.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/CHANGELOG.md +11 -1
- data/README.md +5 -5
- data/lib/updox.rb +3 -0
- data/lib/updox/connection.rb +5 -3
- data/lib/updox/error_message.rb +60 -0
- data/lib/updox/models/appointment.rb +5 -2
- data/lib/updox/models/appointment_status.rb +2 -0
- data/lib/updox/models/calendar.rb +2 -0
- data/lib/updox/models/extensions/exists.rb +17 -0
- data/lib/updox/models/extensions/sync.rb +32 -0
- data/lib/updox/models/location.rb +3 -0
- data/lib/updox/models/model.rb +6 -41
- data/lib/updox/models/patient.rb +3 -1
- data/lib/updox/models/patient_message.rb +15 -0
- data/lib/updox/models/practice.rb +8 -2
- data/lib/updox/models/reminder.rb +1 -1
- data/lib/updox/models/user.rb +9 -1
- data/lib/updox/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f62aa99da193e378457e56e3a055b4d52973c4cae2bb4944f2e300e51287064
|
4
|
+
data.tar.gz: e399c7debeefac7f7608579f056db93cdf3ea24ace47e4173c96adb0d176f87f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3654a26917f7d18de3661921fe72253fbdbc9b7d518f6a9465cde9ee84d5ef65b0ad62e480213618ad676cdf6b74ff6b510bad05e917603c5c2956b69d9c8318
|
7
|
+
data.tar.gz: 82f90067272574222de2a8009b49c0109696a626aea6800c0b415e842a17026b1efa75c8f65cddc5e7493d4616163cee0e4df9e12f44a60514488c7eadc4a611
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [1.0.0] - [UNRELEASED]
|
8
|
+
### Added
|
9
|
+
- Aliases canceled to cancelled
|
10
|
+
- Patient#exists?
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
- `failure_action = :raise` works better
|
14
|
+
- README fix for `failure_action` method
|
15
|
+
|
7
16
|
## [0.12.0] - [2020-02-21]
|
8
17
|
### Added
|
9
18
|
- Configuration to `raise` on non-success response
|
@@ -89,7 +98,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
89
98
|
### Added
|
90
99
|
- Initial Release with ability to ping Updox api
|
91
100
|
|
92
|
-
[0.
|
101
|
+
[1.0.0]: https://github.com/WeInfuse/updox/compare/v0.12.0...HEAD
|
102
|
+
[0.12.0]: https://github.com/WeInfuse/updox/compare/v0.11.0...v0.12.0
|
93
103
|
[0.11.0]: https://github.com/WeInfuse/updox/compare/v0.10.0...v0.11.0
|
94
104
|
[0.10.0]: https://github.com/WeInfuse/updox/compare/v0.9.0...v0.10.0
|
95
105
|
[0.9.0]: https://github.com/WeInfuse/updox/compare/v0.8.0...v0.9.0
|
data/README.md
CHANGED
@@ -146,9 +146,9 @@ response.practices # Has the practices as Updox::Models::Practice model
|
|
146
146
|
response.items # Same as practices, always exists on any model if alias is broken
|
147
147
|
response.item # If there is no array, we populate this object
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
149
|
+
response.successful? # Indicates Updox successful indication
|
150
|
+
response.response_code? # Indicates Updox response code
|
151
|
+
response.response_message? # Indicates Updox response message
|
152
152
|
|
153
153
|
response.response # Raw HTTParty response is here
|
154
154
|
```
|
@@ -159,9 +159,9 @@ response.response # Raw HTTParty response is here
|
|
159
159
|
Updox.configure do |c|
|
160
160
|
c.application_id = ENV['UPDOX_APP_ID']
|
161
161
|
c.application_password = ENV['UPDOX_APP_PASS']
|
162
|
-
c.api_endpoint =
|
162
|
+
c.api_endpoint = Updox::Connection::PROD_ENDPOINT # Defaults to Updox QA endpoint
|
163
163
|
c.parse_responses = false # Defaults to true
|
164
|
-
c.
|
164
|
+
c.failure_action = :raise # Defaults to do nothing and allows lambdas
|
165
165
|
end
|
166
166
|
```
|
167
167
|
|
data/lib/updox.rb
CHANGED
@@ -4,6 +4,8 @@ require 'updox/version'
|
|
4
4
|
require 'updox/updox_exception'
|
5
5
|
require 'updox/connection'
|
6
6
|
require 'updox/models/model'
|
7
|
+
require 'updox/models/extensions/exists'
|
8
|
+
require 'updox/models/extensions/sync'
|
7
9
|
require 'updox/models/auth'
|
8
10
|
require 'updox/models/application'
|
9
11
|
require 'updox/models/appointment'
|
@@ -11,6 +13,7 @@ require 'updox/models/appointment_status'
|
|
11
13
|
require 'updox/models/calendar'
|
12
14
|
require 'updox/models/location'
|
13
15
|
require 'updox/models/patient'
|
16
|
+
require 'updox/models/patient_message'
|
14
17
|
require 'updox/models/practice'
|
15
18
|
require 'updox/models/reminder'
|
16
19
|
require 'updox/models/status'
|
data/lib/updox/connection.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
module Updox
|
2
2
|
class Connection
|
3
|
-
|
4
|
-
|
3
|
+
URI_BUILDER = ->(host) { "https://#{host}/api/io/".freeze }
|
4
|
+
|
5
|
+
QA_ENDPOINT = URI_BUILDER.call('updoxqa.com')
|
6
|
+
PROD_ENDPOINT = URI_BUILDER.call('myupdox.com')
|
5
7
|
|
6
8
|
include HTTParty
|
7
9
|
|
8
|
-
base_uri
|
10
|
+
base_uri QA_ENDPOINT
|
9
11
|
|
10
12
|
headers 'Content-Type' => 'application/json'
|
11
13
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Updox
|
2
|
+
ERROR_CODES = {
|
3
|
+
"2000"=>"OK",
|
4
|
+
"4000"=>"Bad Request",
|
5
|
+
"4010"=>"Unauthorized",
|
6
|
+
"4011"=>"Unauthorized [Practice does not exist or is inactive]",
|
7
|
+
"4012"=>"Unauthorized [User does not exist or is inactive]",
|
8
|
+
"4060"=>"A validation error in the request. For example not including a required field, an invalid e-mail address, too long of a value, etc. A list of the errors is included in the message.",
|
9
|
+
"5000"=>"an unknown error has occurred",
|
10
|
+
"5100"=>"an unknown server error has occurred",
|
11
|
+
"5110"=>"an unknown server error has occurred",
|
12
|
+
"4130"=>"account already exists",
|
13
|
+
"4110"=>"no practice ID",
|
14
|
+
"4160"=>"direct domain is invalid",
|
15
|
+
"4621"=>"direct address error: domain does not match the direct domain for this vendor",
|
16
|
+
"4150"=>"direct domain is already taken",
|
17
|
+
"4163"=>"direct domain is unavailable",
|
18
|
+
"4610"=>"direct address error: direct address is taken",
|
19
|
+
"4161"=>"web address is invalid",
|
20
|
+
"4131"=>"account does not exist",
|
21
|
+
"4140"=>"web address is already taken",
|
22
|
+
"4230"=>"user already exists",
|
23
|
+
"4210"=>"no user ID",
|
24
|
+
"4241"=>"invalid user ID, user IDs starting with '@' are reserved for practice users",
|
25
|
+
"4251"=>"invalid NPI",
|
26
|
+
"4252"=>"invalid taxonomy code",
|
27
|
+
"4630"=>"direct address error: account does not have a direct domain configured",
|
28
|
+
"4232"=>"user password is required",
|
29
|
+
"4240"=>"user does not exist, use practice methods instead",
|
30
|
+
"4231"=>"user does not exist",
|
31
|
+
"4641"=>"direct address error: sending user does not have a direct address configured",
|
32
|
+
"4642"=>"direct address error: identity verification required to send to this address",
|
33
|
+
"4640"=>"direct address error: invalid direct address",
|
34
|
+
"4650"=>"direct error: send failed",
|
35
|
+
"4651"=>"direct error: send failed and/or invalid direct address",
|
36
|
+
"4430"=>"message type does not have any MDNs",
|
37
|
+
"4410"=>"message not found",
|
38
|
+
"4652"=>"direct error: either from or patientDemographics is required",
|
39
|
+
"4071"=>"Recipient not found",
|
40
|
+
"4070"=>"Invalid recipient",
|
41
|
+
"4831"=>"portal account does not exist",
|
42
|
+
"4830"=>"portal account already exists",
|
43
|
+
"4832"=>"patient has opted out of portal communications",
|
44
|
+
"4731"=>"patient account does not exist",
|
45
|
+
"4960"=>"image not found",
|
46
|
+
"4331"=>"contact does not exist",
|
47
|
+
"4931"=>"you sent zero bulk faxes with this bulkFaxId",
|
48
|
+
"4021"=>"Invalid date format",
|
49
|
+
"4930"=>"no fax found for this ID",
|
50
|
+
"4932"=>"fax number does not appear to be available",
|
51
|
+
"4933"=>"invalid fax number",
|
52
|
+
"4330"=>"contact already exists",
|
53
|
+
"6212"=>"at least one id must be specified for the request",
|
54
|
+
"4162"=>"ip is invalid",
|
55
|
+
"4165"=>"port is invalid",
|
56
|
+
"6210"=>"at least one value must be provided",
|
57
|
+
"6213"=>"record does not exist for ID",
|
58
|
+
"9010"=>"the date format must be in the format is yyyy-MM-dd"
|
59
|
+
}
|
60
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Updox
|
2
2
|
module Models
|
3
3
|
class Appointment < Model
|
4
|
+
extend Updox::Models::Extensions::Sync
|
5
|
+
|
4
6
|
SYNC_ENDPOINT = '/AppointmentsSync'.freeze
|
5
7
|
|
6
8
|
SYNC_LIST_TYPE = 'appointments'.freeze
|
@@ -14,8 +16,8 @@ module Updox
|
|
14
16
|
property :typeId, from: :type_id
|
15
17
|
property :summary
|
16
18
|
property :details
|
17
|
-
property :blocked, required: true,
|
18
|
-
property :cancelled, required: true,
|
19
|
+
property :blocked, required: true, default: false
|
20
|
+
property :cancelled, required: true, from: :canceled, default: false
|
19
21
|
property :locationId, from: :location_id
|
20
22
|
property :reminderTokens, from: :reminder_tokens
|
21
23
|
|
@@ -25,6 +27,7 @@ module Updox
|
|
25
27
|
alias_method :type_id, :typeId
|
26
28
|
alias_method :location_id, :locationId
|
27
29
|
alias_method :reminder_tokens, :reminderTokens
|
30
|
+
alias_method :canceled, :cancelled
|
28
31
|
|
29
32
|
def to_h
|
30
33
|
result = super.to_h
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Updox
|
2
|
+
module Models
|
3
|
+
module Extensions
|
4
|
+
module Exists
|
5
|
+
def exists?(item_id, account_id: , cached_query: nil)
|
6
|
+
raise UpdoxException.new('Not implemented on this model.') unless self.respond_to?(:find)
|
7
|
+
opts = { account_id: account_id }
|
8
|
+
opts[:cached_query] = cached_query unless cached_query.nil?
|
9
|
+
|
10
|
+
response = self.find(item_id, **opts)
|
11
|
+
|
12
|
+
false == response.nil?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Updox
|
2
|
+
module Models
|
3
|
+
module Extensions
|
4
|
+
module Sync
|
5
|
+
RECOMMENDED_BATCH_SIZE = 200
|
6
|
+
|
7
|
+
def sync(items, account_id: , batch_size: RECOMMENDED_BATCH_SIZE, endpoint: self.const_get(:SYNC_ENDPOINT))
|
8
|
+
response = nil
|
9
|
+
list_type = self.const_get(:SYNC_LIST_TYPE)
|
10
|
+
|
11
|
+
if 0 >= batch_size
|
12
|
+
response = request(endpoint: endpoint, body: { list_type => items }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
13
|
+
else
|
14
|
+
items.each_slice(batch_size) do |batch|
|
15
|
+
r = request(endpoint: endpoint, body: { list_type => batch }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
16
|
+
|
17
|
+
return r unless r.successful?
|
18
|
+
|
19
|
+
if response
|
20
|
+
response.items += r.items
|
21
|
+
else
|
22
|
+
response = r
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
return response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/updox/models/model.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Updox
|
2
2
|
module Models
|
3
3
|
DATETIME_FORMAT = '%Y-%m-%d %H:%M'.freeze
|
4
|
-
|
5
|
-
|
6
|
-
RECOMMENDED_BATCH_SIZE = 200
|
4
|
+
DATETIME_TZ_FORMAT = '%m/%d/%Y %H:%M:%s %z'.freeze
|
7
5
|
|
8
6
|
class Model < Hashie::Trash
|
9
7
|
include Hashie::Extensions::IgnoreUndeclared
|
@@ -33,39 +31,6 @@ module Updox
|
|
33
31
|
"#{response_code}: #{response_message}"
|
34
32
|
end
|
35
33
|
|
36
|
-
def self.exists?(item_id, account_id: , cached_query: nil)
|
37
|
-
raise UpdoxException.new('Not implemented on this model.') unless self.respond_to?(:find)
|
38
|
-
opts = { account_id: account_id }
|
39
|
-
opts[:cached_query] = cached_query unless cached_query.nil?
|
40
|
-
|
41
|
-
response = self.find(item_id, **opts)
|
42
|
-
|
43
|
-
false == response.nil? && (false == self.const_defined?(:FIND_ENDPOINT) || response.successful?)
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.sync(items, account_id: , batch_size: RECOMMENDED_BATCH_SIZE, endpoint: self.const_get(:SYNC_ENDPOINT))
|
47
|
-
response = nil
|
48
|
-
list_type = self.const_get(:SYNC_LIST_TYPE)
|
49
|
-
|
50
|
-
if 0 >= batch_size
|
51
|
-
response = request(endpoint: endpoint, body: { list_type => items }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
52
|
-
else
|
53
|
-
items.each_slice(batch_size) do |batch|
|
54
|
-
r = request(endpoint: endpoint, body: { list_type => batch }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
55
|
-
|
56
|
-
return r unless r.successful?
|
57
|
-
|
58
|
-
if response
|
59
|
-
response.items += r.items
|
60
|
-
else
|
61
|
-
response = r
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
return response
|
67
|
-
end
|
68
|
-
|
69
34
|
def self.request(**kwargs)
|
70
35
|
from_response(UpdoxClient.connection.request(kwargs))
|
71
36
|
end
|
@@ -88,15 +53,15 @@ module Updox
|
|
88
53
|
model.item = klazz.new(data.dig(klazz.const_get(:ITEM_TYPE)))
|
89
54
|
model.define_singleton_method(klazz.const_get(:ITEM_TYPE)) { self.item }
|
90
55
|
else
|
91
|
-
|
92
|
-
|
56
|
+
status_key = data&.keys&.find {|k| k.to_s.downcase.end_with?('statuses') }
|
57
|
+
status_class = 'Updox::Models::' + status_key[0..-3].capitalize if status_key
|
93
58
|
|
94
|
-
if
|
59
|
+
if status_key.nil? || false == Module.const_defined?(status_class)
|
95
60
|
model.items = [data]
|
96
61
|
else
|
97
|
-
statuses = data.delete(
|
62
|
+
statuses = data.delete(status_key)
|
98
63
|
|
99
|
-
model.items = statuses.map {|status| Object.const_get(
|
64
|
+
model.items = statuses.map {|status| Object.const_get(status_class).new(status) }
|
100
65
|
model.define_singleton_method(:statuses) { self.items }
|
101
66
|
end
|
102
67
|
|
data/lib/updox/models/patient.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Updox
|
2
2
|
module Models
|
3
3
|
class Patient < Model
|
4
|
+
extend Updox::Models::Extensions::Sync
|
5
|
+
|
4
6
|
SYNC_ENDPOINT = '/PatientsSync'.freeze
|
5
7
|
SYNC_LIST_TYPE = 'patients'.freeze
|
6
8
|
|
@@ -33,7 +35,7 @@ module Updox
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def self.exists?(patient_id, account_id: )
|
36
|
-
|
38
|
+
Updox::Models::PatientMessage.exists?(patient_id, account_id: account_id)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Updox
|
2
|
+
module Models
|
3
|
+
class PatientMessage < Model
|
4
|
+
LIST_ENDPOINT = '/PatientMessageCountSince'.freeze
|
5
|
+
|
6
|
+
def self.query(patient_id, account_id: )
|
7
|
+
request(endpoint: LIST_ENDPOINT, body: { patientId: patient_id }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.exists?(patient_id, account_id: )
|
11
|
+
request(endpoint: LIST_ENDPOINT, body: { patientId: patient_id }, auth: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_ACCT).successful?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -40,11 +40,17 @@ module Updox
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.exists?(account_id)
|
43
|
-
self.find(account_id).
|
43
|
+
false == self.find(account_id).nil?
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.find(account_id)
|
47
|
-
request(endpoint: FIND_ENDPOINT, body: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_APP)
|
47
|
+
response = request(endpoint: FIND_ENDPOINT, body: {accountId: account_id}, required_auths: Updox::Models::Auth::AUTH_APP)
|
48
|
+
|
49
|
+
if response.successful?
|
50
|
+
response
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
48
54
|
end
|
49
55
|
|
50
56
|
def self.query
|
@@ -3,7 +3,7 @@ module Updox
|
|
3
3
|
class Reminder < Model
|
4
4
|
property :reminderId
|
5
5
|
property :reminderStatus
|
6
|
-
property :reminderStatusDate, transform_with: ->(v) { DateTime.strptime(v,
|
6
|
+
property :reminderStatusDate, transform_with: ->(v) { DateTime.strptime(v, DATETIME_TZ_FORMAT) unless v.nil? || v.empty? }
|
7
7
|
property :reminderType
|
8
8
|
|
9
9
|
alias_method :reminder_id, :reminderId
|
data/lib/updox/models/user.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Updox
|
2
2
|
module Models
|
3
3
|
class User < Model
|
4
|
+
extend Updox::Models::Extensions::Exists
|
5
|
+
|
4
6
|
SAVE_ENDPOINT = '/UserSave'.freeze
|
5
7
|
QUERY_ENDPOINT = '/UserList'.freeze
|
6
8
|
FIND_ENDPOINT = '/UserGet'.freeze
|
@@ -45,7 +47,13 @@ module Updox
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def self.find(user_id, account_id: )
|
48
|
-
request(endpoint: FIND_ENDPOINT, account_id: account_id, body: { userId: user_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
50
|
+
response = request(endpoint: FIND_ENDPOINT, account_id: account_id, body: { userId: user_id}, required_auths: Updox::Models::Auth::AUTH_ACCT)
|
51
|
+
|
52
|
+
if response.successful?
|
53
|
+
response
|
54
|
+
else
|
55
|
+
nil
|
56
|
+
end
|
49
57
|
end
|
50
58
|
|
51
59
|
def self.query
|
data/lib/updox/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: updox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Crockett
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -142,14 +142,18 @@ files:
|
|
142
142
|
- Rakefile
|
143
143
|
- lib/updox.rb
|
144
144
|
- lib/updox/connection.rb
|
145
|
+
- lib/updox/error_message.rb
|
145
146
|
- lib/updox/models/application.rb
|
146
147
|
- lib/updox/models/appointment.rb
|
147
148
|
- lib/updox/models/appointment_status.rb
|
148
149
|
- lib/updox/models/auth.rb
|
149
150
|
- lib/updox/models/calendar.rb
|
151
|
+
- lib/updox/models/extensions/exists.rb
|
152
|
+
- lib/updox/models/extensions/sync.rb
|
150
153
|
- lib/updox/models/location.rb
|
151
154
|
- lib/updox/models/model.rb
|
152
155
|
- lib/updox/models/patient.rb
|
156
|
+
- lib/updox/models/patient_message.rb
|
153
157
|
- lib/updox/models/practice.rb
|
154
158
|
- lib/updox/models/reminder.rb
|
155
159
|
- lib/updox/models/status.rb
|