redox 0.1.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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