redox 0.1.6 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4cf3d701269f03a48d3cd1fe870e2f124aeb705c643c4cd3826ad5b352317276
4
- data.tar.gz: 562cc78ba951b7a58a3365612e09e38f114d7a7ab8ceb80b6e0e1c73b5592c7a
3
+ metadata.gz: 63503f81ebcb62da585b095cbe53721f14fd4924b6b7f292db34dc28a1fb58a0
4
+ data.tar.gz: d79801d7d642ada1dd96952fb00882c858a06b6b3a165e9aa634624cd8580872
5
5
  SHA512:
6
- metadata.gz: fdd640751e3226609ac29cf6be385b7ae52487df1e46fa925e8e984cdf1e0458066f14e16a464dfa43d1201f9b0efcd988442c4eea26fd770a9b57d10e5cfd48
7
- data.tar.gz: a339571774b1058f4b646d0d2667bee605def7683c2aa47e152f41bfb3cb51872915a91d120a8b7da5e75c89da0ff0b46ef7292931c3da9cd5941b74fd31b73e
6
+ metadata.gz: cc2504239a0515d8d951a7d0d181a260ca7719130fd0fffc40d309cf8938c46ebce2d1c402a1864e019d689836f5988857608d6e19c18326f7d00dcc180985a5
7
+ data.tar.gz: cf26db2a8ee7d9379c01f2af44aa9b25c2b67a6d6b5fc8d09faa5d449dcfb89b6d8ef32e22cebb2f0dda1b68238f0982103a08e4d5d8accbb5635682f73532bd
@@ -4,7 +4,19 @@ 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
- ## [0.1.6] - Unreleased
7
+ ## [1.0.0] - Unreleased
8
+ ### Changed
9
+ - How it works
10
+
11
+ ### Added
12
+ - Connection, RedoxClient, Authorization
13
+ - Global configuration block
14
+ - Gems httparty, hashie
15
+
16
+ ### Removed
17
+ - Identifiers, Demographics
18
+
19
+ ## [0.1.6] - 2019-04-22
8
20
  ### Added
9
21
  - Meta model
10
22
  - Response and Authentication classes
@@ -58,7 +70,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
58
70
  ### Added
59
71
  - Initial Release
60
72
 
61
- [Unreleased]: https://github.com/WeInfuse/redox/compare/v0.1.5...HEAD
73
+ [Unreleased]: https://github.com/WeInfuse/redox/compare/v0.1.6...HEAD
74
+ [0.1.6]: https://github.com/WeInfuse/redox/compare/v0.1.5...v0.1.6
62
75
  [0.1.5]: https://github.com/WeInfuse/redox/compare/v0.1.4...v0.1.5
63
76
  [0.1.4]: https://github.com/WeInfuse/redox/compare/0.1.3...v0.1.4
64
77
  [0.1.3]: https://github.com/WeInfuse/redox/compare/0.1.2...0.1.3
data/README.md CHANGED
@@ -21,34 +21,90 @@ Or install it yourself as:
21
21
 
22
22
  ## Usage
23
23
 
24
+ ### Setup
25
+
26
+ Make sure you're [configured](#configuration)!
27
+
24
28
  ```ruby
25
- source = {
26
- Name: 'Redox Dev Tools',
27
- ID: ENV['REDOX_SRC_ID']
28
- }
29
+ patient = Redox::Models::Patient.new
30
+ patient.demographics.first_name = 'Joe'
31
+ patient.demographics['LastName'] = 'Joerson'
32
+ patient.add_identifier(type: 'TheType', value: 'x13005')
33
+
34
+ meta = Redox::Models::Meta.new
35
+ meta.set_source(name: 'MySource', id: '123-584')
36
+ meta.add_destination(name: 'TheDest', id: '973-238')
37
+ ```
38
+
39
+ ### Create
40
+
41
+ ```ruby
42
+ response = patient.create(meta: meta)
43
+ ```
44
+
45
+ ### Update
46
+
47
+ ```ruby
48
+ response = patient.update(meta: meta)
49
+ ```
50
+
51
+ ### Search
52
+
53
+ ```ruby
54
+ response = Redox::Models::Patient.query(patient, meta: meta)
55
+ ```
56
+
57
+ ### Response
58
+
59
+ The response object is a base `Redox::Models::Model` class.
60
+
61
+ With the HTTParty response object
62
+ ```ruby
63
+ response.response
64
+ #<HTTParty::Response:0x7fa354c1fbe8>
65
+
66
+ response.response.ok?
67
+ true
68
+ ```
29
69
 
30
- destinations = [
31
- {
32
- Name: 'Redox EMR',
33
- ID: ENV['REDOX_DEST_ID']
70
+ And any `Model` objects that were returned
71
+ ```ruby
72
+ response.patient
73
+ {
74
+ "Identifiers"=> [
75
+ {"IDType"=>"MR", "ID"=>"0000000003"},
76
+ {"ID"=>"e3fedf48-c8bf-4728-845f-cb810001b571", "IDType"=>"EHRID"}
77
+ ],
78
+ "Demographics"=> {
79
+ "Race"=>"Black",
80
+ "SSN"=>"303-03-0003",
81
+ "Nickname"=>"Walt"
82
+ ...
34
83
  }
35
- ]
36
-
37
- redox = Redox::Redox.new(
38
- api_key: ENV['REDOX_KEY'],
39
- secret: ENV['REDOX_SECRET'],
40
- source: source,
41
- destinations: destinations,
42
- test: true
43
- )
44
-
45
- redox.add_patient(
46
- Identifiers: [...],
47
- Demographics: {
48
- FirstName: 'Joe'
49
- ...
84
+ "PCP"=> {
85
+ "NPI"=>nil,
50
86
  }
51
- )
87
+ }
88
+
89
+ response.meta
90
+ {
91
+ "EventDateTime"=>"2019-04-26T20:03:00.304866Z",
92
+ "DataModel"=>"PatientAdmin",
93
+ ...
94
+ "Transmission"=>{"ID"=>797225234},
95
+ "Message"=>{"ID"=>1095117817}
96
+ }
97
+ ```
98
+
99
+ ### Configuration
100
+
101
+ ```ruby
102
+ Redox.configure do |c|
103
+ c.api_key = ENV['REDOX_API_KEY']
104
+ c.secret = ENV['REDOX_SECRET']
105
+ c.api_endpoint = 'http://hello.com' # Defaults to Redox endpoint
106
+ c.token_expiry_padding = 120 # Defaults to 60 seconds
107
+ end
52
108
  ```
53
109
 
54
110
  ## Development
@@ -1,160 +1,82 @@
1
- require 'json'
2
- require 'net/http'
3
- require 'uri'
4
- require 'openssl'
1
+ require 'httparty'
2
+ require 'hashie'
5
3
  require 'redox/version'
6
4
  require 'redox/redox_exception'
5
+ require 'redox/connection'
7
6
  require 'redox/authentication'
8
- require 'redox/response'
9
7
  require 'redox/models/model'
10
8
  require 'redox/models/meta'
11
9
  require 'redox/models/patient'
12
- require 'redox/models/demographics'
13
- require 'redox/models/identifiers'
10
+ require 'redox/models/patient/demographics'
11
+ require 'redox/models/patient/identifier'
12
+ require 'redox/models/patient/insurance'
13
+ require 'redox/models/patient/p_c_p'
14
14
 
15
15
  module Redox
16
- # Redox API client
17
- class Redox
18
- DEFAULT_URI = 'https://api.redoxengine.com/'.freeze
16
+ class Configuration
17
+ attr_accessor :api_key, :secret
19
18
 
20
- # Instantiates a new Redox connection object
21
- #
22
- # @param [String] api_key API key for the connection
23
- # @param [String] secret API secret for the connection
24
- # @param [Hash] source source information
25
- # @param [Array<Hash>] destinations list of destinations
26
- # @param [Boolean] test whether to use test mode
27
- # @example
28
- # redox = Redox::Redox.new(
29
- # api_key: ENV['REDOX_KEY'],
30
- # secret: ENV['REDOX_SECRET'],
31
- # source: source,
32
- # destinations: destinations,
33
- # test: true
34
- # )
35
- def initialize(api_key:, secret:, source: nil, destinations: nil, facility_code: nil, test: true, uri: DEFAULT_URI)
36
- @api_key = api_key
37
- @secret = secret
38
- @meta = Models::Meta.new
39
- destinations.each {|dest| @meta.add_destination(dest['Name'], dest['ID']) } if destinations
40
- @meta.source = source if source
41
- @meta.facility_code = facility_code if facility_code
42
- @meta.test = test
43
- @connection = nil
44
- @authentication = nil
45
- @uri = uri
19
+ def initialize
20
+ @api_key = nil
21
+ @secret = nil
46
22
  end
47
23
 
48
- # Send NewPatient message
49
- #
50
- # @param [Hash] patient_params data to send in the Patient JSON object
51
- # @return [Hash] parsed response object
52
- # @example
53
- # Redox::Redox.new(*connection_params).add_patient(
54
- # Identifiers: [],
55
- # Demographics: {
56
- # FirstName: 'Joe'
57
- # }
58
- # )
59
- def add_patient(patient_params, meta = nil)
60
- meta = @meta.merge(Models::Meta.from_h(Models::Patient::ADD[:meta]).merge(meta))
61
- body = meta.to_h.merge(Patient: patient_params)
62
-
63
- return request(
64
- endpoint: Models::Patient::ADD[:endpoint],
65
- body: body.to_json,
66
- model: Models::Patient
67
- )
24
+ def api_endpoint=(endpoint)
25
+ Connection.base_uri(endpoint.freeze)
68
26
  end
69
27
 
70
- # Send PatientUpdate message
71
- #
72
- # @param [Hash] patient_params data to send in the Patient JSON object
73
- # @return [Hash] parsed response object
74
- # @example
75
- # Redox::Redox.new(*connection_params).update_patient(
76
- # Identifiers: [],
77
- # Demographics: {
78
- # FirstName: 'Joe'
79
- # }
80
- # )
81
- def update_patient(patient_params, meta = nil)
82
- meta = @meta.merge(Models::Meta.from_h(Models::Patient::UPDATE[:meta]).merge(meta))
83
- body = meta.to_h.merge(Patient: patient_params)
84
-
85
- return request(
86
- endpoint: Models::Patient::UPDATE[:endpoint],
87
- body: body.to_json,
88
- model: Models::Patient
89
- )
28
+ def api_endpoint
29
+ return Connection.base_uri
90
30
  end
91
31
 
92
- # Send PatientSearch query
93
- #
94
- # @param [Hash] patient_params data to send in the Patient JSON object
95
- # @return [Hash] Redox Patient object
96
- # @example
97
- # Redox::Redox.new(*connection_params).search_patients(
98
- # Identifiers: [],
99
- # Demographics: {
100
- # FirstName: 'Joe'
101
- # }
102
- # )
103
- def search_patients(patient_params, meta = nil)
104
- meta = @meta.merge(Models::Meta.from_h(Models::Patient::SEARCH[:meta]).merge(meta))
105
- body = meta.to_h.merge(Patient: patient_params)
106
-
107
- return request(
108
- endpoint: Models::Patient::SEARCH[:endpoint],
109
- body: body.to_json,
110
- model: Models::Patient
111
- )
32
+ def token_expiry_padding=(time_in_seconds)
33
+ Authentication.token_expiry_padding = time_in_seconds
112
34
  end
113
35
 
114
- private
115
-
116
- attr_reader :api_key, :secret, :meta
117
-
118
- def request(endpoint: , body: , header: {}, model: nil, authorize: true)
119
- header = {
120
- 'Content-Type' => 'application/json'
121
- }.merge(header)
122
-
123
- header = header.merge(authenticate.access_header) if authorize
124
-
125
- request = Net::HTTP::Post.new(endpoint, header)
126
- request.body = body
127
-
128
- return Response.new(connection.request(request), model)
36
+ def token_expiry_padding
37
+ return Authentication.token_expiry_padding
129
38
  end
130
39
 
131
- def authenticate
132
- return @authentication if @authentication
40
+ def to_h
41
+ return {
42
+ api_key: @api_key,
43
+ secret: @secret,
44
+ api_endpoint: api_endpoint,
45
+ token_expiry_padding: token_expiry_padding
46
+ }
47
+ end
133
48
 
134
- redox_response = request(
135
- endpoint: Authentication::ENDPOINT,
136
- body: { apiKey: api_key, secret: secret }.to_json,
137
- model: Authentication,
138
- authorize: false
139
- )
49
+ def from_h(h)
50
+ self.api_key = h[:api_key]
51
+ self.secret = h[:secret]
52
+ self.api_endpoint = h[:api_endpoint]
53
+ self.token_expiry_padding = h[:token_expiry_padding]
140
54
 
141
- if (false == redox_response.success?)
142
- raise RedoxException.from_response(redox_response.http_response, msg: 'Authentication')
143
- end
55
+ return self
56
+ end
57
+ end
144
58
 
145
- @authentication = redox_response.model
59
+ class << self
60
+ def configuration
61
+ @configuration ||= Configuration.new
146
62
  end
147
63
 
148
- def connection
149
- return @connection if @connection
64
+ def configure
65
+ yield(configuration)
66
+ end
67
+ end
150
68
 
151
- uri = URI.parse(@uri)
152
- http = Net::HTTP.new(uri.host, uri.port)
153
- http.use_ssl = true
154
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
155
- http.verify_depth = 5
69
+ # Redox API client
70
+ class RedoxClient
71
+ class << self
72
+ def connection
73
+ Redox.configuration.token_expiry_padding = 60 if Redox.configuration.token_expiry_padding.nil?
74
+ @connection ||= Connection.new
75
+ end
156
76
 
157
- @connection = http
77
+ def release
78
+ @connection = nil
79
+ end
158
80
  end
159
81
  end
160
82
  end
@@ -1,19 +1,77 @@
1
1
  module Redox
2
- class Authentication
3
- ENDPOINT = '/auth/authenticate'.freeze
2
+ class Authentication < Connection
3
+ attr_accessor :response
4
4
 
5
- def initialize(response_body)
6
- @body = response_body
5
+ BASE_ENDPOINT = '/auth'.freeze
6
+
7
+ AUTH_ENDPOINT = "#{BASE_ENDPOINT}/authenticate".freeze
8
+ REFRESH_ENDPOINT = "#{BASE_ENDPOINT}/refreshToken".freeze
9
+
10
+ class << self
11
+ attr_accessor :token_expiry_padding
12
+
13
+ @@token_expiry_padding = 0
14
+ end
15
+
16
+ def initialize
17
+ @response = nil
18
+ end
19
+
20
+ def authenticate
21
+ if (self.expires?)
22
+ if (self.refresh_token)
23
+ request = {
24
+ body: { apiKey: Redox.configuration.api_key, refreshToken: self.refresh_token },
25
+ endpoint: REFRESH_ENDPOINT
26
+ }
27
+ else
28
+ request = {
29
+ body: { apiKey: Redox.configuration.api_key, secret: Redox.configuration.secret },
30
+ endpoint: AUTH_ENDPOINT
31
+ }
32
+ end
33
+
34
+ response = self.request(**request, auth: false)
35
+
36
+ if (false == response.ok?)
37
+ @response = nil
38
+ raise RedoxException.from_response(response, msg: 'Authentication')
39
+ else
40
+ @response = response
41
+ end
42
+ end
43
+
44
+ return self
7
45
  end
8
46
 
9
47
  def access_token
10
- return @body['accessToken']
48
+ return @response['accessToken'] if @response
49
+ end
50
+
51
+ def expiry
52
+ return @response['expires'] if @response
53
+ end
54
+
55
+ def refresh_token
56
+ return @response['refreshToken'] if @response
57
+ end
58
+
59
+ def expires?(seconds_from_now = Authentication.token_expiry_padding)
60
+ if (self.expiry)
61
+ return DateTime.strptime(self.expiry, Models::Meta::FROM_DATETIME_FORMAT).to_time.utc <= (Time.now + seconds_from_now).utc
62
+ else
63
+ return true
64
+ end
11
65
  end
12
66
 
13
67
  def access_header
14
68
  return {
15
- 'Authorization' => "Bearer #{access_token}",
69
+ 'Authorization' => "Bearer #{self.access_token}",
16
70
  }
17
71
  end
72
+
73
+ def expire!
74
+ @response = nil
75
+ end
18
76
  end
19
77
  end
@@ -0,0 +1,28 @@
1
+ module Redox
2
+ class Connection
3
+ DEFAULT_ENDPOINT = '/endpoint'.freeze
4
+
5
+ include HTTParty
6
+
7
+ base_uri 'https://api.redoxengine.com/'.freeze
8
+
9
+ headers 'Content-Type' => 'application/json'
10
+
11
+ format :json
12
+
13
+ def request(endpoint: DEFAULT_ENDPOINT, body: nil, headers: {}, auth: true)
14
+ body = body.to_json if body.is_a?(Hash)
15
+ headers = auth_header.merge(headers) if auth
16
+
17
+ self.class.post(endpoint, body: body, headers: headers)
18
+ end
19
+
20
+ private
21
+
22
+ def auth_header
23
+ @auth ||= Authentication.new
24
+
25
+ return @auth.authenticate.access_header
26
+ end
27
+ end
28
+ end
@@ -1,79 +1,45 @@
1
1
  module Redox
2
2
  module Models
3
3
  class Meta < Model
4
- KEY = 'Meta'.freeze
5
-
6
- DEFAULT = -> () {
7
- return {
8
- KEY => {
9
- 'DataModel' => nil,
10
- 'EventType' => nil,
11
- 'EventDateTime' => Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6NZ"),
12
- 'Test' => true,
13
- 'Source' => {},
14
- 'Destinations' => [],
15
- 'FacilityCode' => nil
16
- }
17
- }
18
- }
19
-
20
- def initialize(data = DEFAULT.call)
21
- super(data)
22
- end
23
-
24
- def add_destination(name, id)
25
- self.inner['Destinations'] << Meta.build_subscription(name, id)
4
+ TO_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%6NZ'.freeze
5
+ FROM_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%Z'.freeze
6
+
7
+ property :DataModel, from: :data_model, required: false
8
+ property :EventType, from: :event_type, required: false
9
+ property :EventDateTime, from: :event_date_time, default: ->() { Time.now.utc.strftime(TO_DATETIME_FORMAT) }
10
+ property :Test, from: :test, default: true
11
+ property :Source, from: :source, required: false
12
+ property :Destinations, from: :destinations, required: false
13
+ property :FacilityCode, from: :facility_code, required: false
14
+
15
+ alias_method :data_model, :DataModel
16
+ alias_method :event_type, :EventType
17
+ alias_method :event_date_time, :EventDateTime
18
+ alias_method :test, :Test
19
+ alias_method :source, :Source
20
+ alias_method :destinations, :Destinations
21
+ alias_method :facility_code, :FacilityCode
22
+
23
+ def add_destination(name: , id: )
24
+ self[:Destinations] ||= []
25
+ self[:Destinations] << Meta.build_subscription(name: name, id: id)
26
26
 
27
27
  return self
28
28
  end
29
29
 
30
- def set_source(name, id)
31
- self.source = Meta.build_subscription(name, id)
32
-
33
- return self
34
- end
35
-
36
- def source=(source)
37
- self.inner['Source'] = source
38
- end
39
-
40
- def facility_code=(facility_code)
41
- self.inner['FacilityCode'] = facility_code.to_s
42
- end
43
-
44
- def test=(test)
45
- self.inner['Test'] = (true == test)
46
- end
47
-
48
- def merge(other)
49
- if (other.is_a?(Hash))
50
- if (other.include?(KEY))
51
- self.inner.merge!(other[KEY])
52
- else
53
- self.inner.merge!(other)
54
- end
55
- elsif (other.is_a?(self.class))
56
- self.inner.merge!(other.inner.select {|k,v| !v.nil?})
57
- end
30
+ def set_source(name: , id: )
31
+ self[:Source] = Meta.build_subscription(name: name, id: id)
58
32
 
59
33
  return self
60
34
  end
61
35
 
62
- def to_h
63
- return JSON.parse(@data.to_json)
64
- end
65
-
66
36
  class << self
67
- def build_subscription(name, id)
37
+ def build_subscription(name: , id:)
68
38
  return {
69
39
  'ID' => id,
70
40
  'Name' => name
71
41
  }
72
42
  end
73
-
74
- def from_h(hash)
75
- return Meta.new.merge(hash)
76
- end
77
43
  end
78
44
  end
79
45
  end
@@ -1,27 +1,53 @@
1
1
  module Redox
2
2
  module Models
3
- class Model
4
- KEY = nil
3
+ class Model < Hashie::Trash
4
+ include Hashie::Extensions::IgnoreUndeclared
5
+ include Hashie::Extensions::IndifferentAccess
5
6
 
6
- def initialize(data)
7
- @data = data.freeze
7
+ property :Meta, from: :meta, required: false
8
+ property :Patient, from: :patient, required: false
9
+ property :response, required: false
10
+
11
+ alias_method :patient, :Patient
12
+ alias_method :meta, :Meta
13
+
14
+ def initialize(data = {})
15
+ if (data.is_a?(Hash) && data.include?(key))
16
+ data = data[key]
17
+ end
18
+
19
+ super(data)
8
20
  end
9
21
 
10
- def valid?
11
- return @data.is_a?(Hash) && @data.include?(self.class::KEY)
22
+ def to_h
23
+ return {"#{key}" => super.to_h}
12
24
  end
13
25
 
14
- def raw
15
- return self.inner(key: nil)
26
+ def to_json
27
+ return self.to_h.to_json
16
28
  end
17
29
 
18
- def inner(key: self.class::KEY)
19
- if key.nil?
20
- return @data
21
- else
22
- return @data[key]
30
+ class << self
31
+ def from_response(response)
32
+ model = Model.new
33
+ model.response = response
34
+
35
+ %w[Meta Patient].each do |k|
36
+ begin
37
+ model.send("#{k}=", Module.const_get("Redox::Models::#{k}").new(response[k])) if response[k]
38
+ rescue
39
+ end
40
+ end
41
+
42
+ return model
23
43
  end
24
44
  end
45
+
46
+ private
47
+
48
+ def key
49
+ return self.class.to_s.split('::').last
50
+ end
25
51
  end
26
52
  end
27
53
  end
@@ -1,40 +1,60 @@
1
1
  module Redox
2
2
  module Models
3
3
  class Patient < Model
4
- attr_reader :demographics, :identifiers
5
-
6
- KEY = 'Patient'.freeze
7
-
8
- SEARCH = {
9
- meta: {
10
- 'DataModel' => 'PatientSearch',
11
- 'EventType' => 'Query'
12
- },
13
- endpoint: '/query'
14
- }
15
-
16
- ADD = {
17
- meta: {
18
- 'DataModel' => 'PatientAdmin',
19
- 'EventType' => 'NewPatient'
20
- },
21
- endpoint: '/endpoint'
22
- }
23
-
24
- UPDATE = {
25
- meta: {
26
- 'DataModel' => 'PatientAdmin',
27
- 'EventType' => 'PatientUpdate'
28
- },
29
- endpoint: '/endpoint'
30
- }
31
-
32
- def initialize(data)
33
- super(data)
34
-
35
- if (self.valid?)
36
- @demographics = Demographics.new(self.inner)
37
- @identifiers = Identifiers.new(self.inner)
4
+ QUERY_ENDPOINT = '/query'.freeze
5
+ QUERY_META = Meta.new(EventType: 'Query', DataModel: 'PatientSearch')
6
+ CREATE_META = Meta.new(EventType: 'NewPatient', DataModel: 'PatientAdmin')
7
+ UPDATE_META = Meta.new(EventType: 'PatientUpdate', DataModel: 'PatientAdmin')
8
+
9
+ property :Identifiers, from: :identifiers, required: false, default: []
10
+ property :Insurances, from: :insurances, required: false, default: []
11
+ property :Demographics, from: :demographics, required: false
12
+ property :PCP, from: :primary_care_provider, required: false
13
+
14
+ alias_method :identifiers, :Identifiers
15
+ alias_method :insurances, :Insurances
16
+
17
+ def demographics
18
+ self[:Demographics] = Demographics.new(self[:Demographics]) unless self[:Demographics].is_a?(Redox::Models::Demographics)
19
+ self[:Demographics] ||= Demographics.new
20
+ end
21
+
22
+ def primary_care_provider
23
+ self[:PCP] ||= PCP.new
24
+ end
25
+
26
+ def add_identifier(type: , value: )
27
+ self[:Identifiers] << Identifier.new({'ID' => value, 'IDType' => type})
28
+
29
+ return self
30
+ end
31
+
32
+ def add_insurance(data = {})
33
+ self[:Insurances] << Insurance.new(data)
34
+
35
+ return self
36
+ end
37
+
38
+ def update(meta: Meta.new)
39
+ meta = UPDATE_META.merge(meta)
40
+ return Model.from_response((RedoxClient.connection.request(body: Patient.body(self, meta))))
41
+ end
42
+
43
+ def create(meta: Meta.new)
44
+ meta = CREATE_META.merge(meta)
45
+ return Model.from_response((RedoxClient.connection.request(body: Patient.body(self, meta))))
46
+ end
47
+
48
+ class << self
49
+ def query(params, meta: Meta.new)
50
+ meta = QUERY_META.merge(meta)
51
+ return Model.from_response((RedoxClient.connection.request(endpoint: QUERY_ENDPOINT, body: Patient.body(params, meta))))
52
+ end
53
+
54
+ def body(params, meta)
55
+ meta = Meta.new.merge(meta)
56
+
57
+ return meta.to_h.merge(params.to_h)
38
58
  end
39
59
  end
40
60
  end
@@ -0,0 +1,34 @@
1
+ module Redox
2
+ module Models
3
+ class Demographics < Model
4
+ property :FirstName, required: false, from: :first_name
5
+ property :MiddleName, required: false, from: :middle_name
6
+ property :LastName, required: false, from: :last_name
7
+ property :DOB, required: false, from: :dob
8
+ property :SSN, required: false, from: :ssn
9
+ property :Sex, required: false, from: :sex
10
+ property :Race, required: false, from: :race
11
+ property :IsHispanic, required: false
12
+ property :MaritalStatus, required: false, from: :martial_status
13
+ property :IsDeceased, required: false
14
+ property :DeathDateTime, required: false
15
+ property :Language, required: false, from: :language
16
+ property :EmailAddresses, required: false, default: []
17
+ property :Citizenship, required: false, default: []
18
+ property :Address, required: false, default: {}
19
+ property :PhoneNumber, required: false, default: {}
20
+
21
+ alias_method :first_name, :FirstName
22
+ alias_method :middle_name, :MiddleName
23
+ alias_method :last_name, :LastName
24
+ alias_method :dob, :DOB
25
+ alias_method :ssn, :SSN
26
+ alias_method :sex, :Sex
27
+ alias_method :race, :Race
28
+ alias_method :martial_status, :MaritalStatus
29
+ alias_method :language, :Language
30
+ alias_method :address, :Address
31
+ alias_method :phone_number, :PhoneNumber
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module Redox
2
+ module Models
3
+ class Identifier < Model
4
+ property :ID, from: :id
5
+ property :IDType, from: :id_type
6
+
7
+ alias_method :id, :ID
8
+ alias_method :id_type, :IDType
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module Redox
2
+ module Models
3
+ class Insurance < Model
4
+ property :Plan, required: false, from: :plan, default: {}
5
+ property :MemberNumber, required: false, from: :member_number
6
+ property :Company, required: false, from: :company, default: {}
7
+ property :GroupNumber, required: false, from: :group_number
8
+ property :GroupName, required: false, from: :group_name
9
+ property :EffectiveDate, required: false, from: :effective_date
10
+ property :ExpirationDate, required: false, from: :expiration_date
11
+ property :PolicyNumber, required: false, from: :policy_number
12
+ property :AgreementType, required: false, from: :agreement_type
13
+ property :CoverageType, required: false, from: :coverage_type
14
+ property :Insured, required: false, from: :insured, default: {}
15
+
16
+ alias_method :plan, :Plan
17
+ alias_method :member_number, :MemberNumber
18
+ alias_method :company, :Company
19
+ alias_method :group_number, :GroupNumber
20
+ alias_method :group_name, :GroupName
21
+ alias_method :effective_date, :EffectiveDate
22
+ alias_method :expiration_date, :ExpirationDate
23
+ alias_method :policy_number, :PolicyNumber
24
+ alias_method :agreement_type, :AgreementType
25
+ alias_method :coverage_type, :CoverageType
26
+ alias_method :insured, :Insured
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ module Redox
2
+ module Models
3
+ class PCP < Model
4
+ property :NPI, from: :npi
5
+ property :FirstName, required: false, from: :first_name
6
+ property :LastName, required: false, from: :last_name
7
+
8
+ alias_method :npi, :NPI
9
+ alias_method :first_name, :FirstName
10
+ alias_method :last_name, :LastName
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Redox
2
- VERSION = '0.1.6'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ['lib']
28
28
 
29
+ spec.add_dependency 'httparty'
30
+ spec.add_dependency 'hashie'
29
31
  spec.add_development_dependency 'bundler'
30
32
  spec.add_development_dependency 'byebug'
31
33
  spec.add_development_dependency 'minitest', '~> 5.0'
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Clark
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-22 00:00:00.000000000 Z
11
+ date: 2019-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hashie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -113,11 +141,14 @@ files:
113
141
  - bin/setup
114
142
  - lib/redox.rb
115
143
  - lib/redox/authentication.rb
116
- - lib/redox/models/demographics.rb
117
- - lib/redox/models/identifiers.rb
144
+ - lib/redox/connection.rb
118
145
  - lib/redox/models/meta.rb
119
146
  - lib/redox/models/model.rb
120
147
  - lib/redox/models/patient.rb
148
+ - lib/redox/models/patient/demographics.rb
149
+ - lib/redox/models/patient/identifier.rb
150
+ - lib/redox/models/patient/insurance.rb
151
+ - lib/redox/models/patient/p_c_p.rb
121
152
  - lib/redox/redox_exception.rb
122
153
  - lib/redox/response.rb
123
154
  - lib/redox/version.rb
@@ -1,7 +0,0 @@
1
- module Redox
2
- module Models
3
- class Demographics < Model
4
- KEY = 'Demographics'.freeze
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Redox
2
- module Models
3
- class Identifiers < Model
4
- KEY = 'Identifiers'.freeze
5
- end
6
- end
7
- end