change_health 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +25 -5
- data/lib/change_health.rb +2 -0
- data/lib/change_health/models/eligibility.rb +1 -1
- data/lib/change_health/models/eligibility_benefit.rb +137 -0
- data/lib/change_health/models/eligibility_data.rb +41 -0
- data/lib/change_health/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 052e20dfdfabf7bdf956f2572dba054ef7116e2d3e51e5f24871ec6d61cea229
|
4
|
+
data.tar.gz: 0e57faf6e83afb05685f43d1b1712e67768b700ad88278a555aa7f793b7c5bc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc74abedea032c14c1a1ea314822a5b10262c816b8e437a87a885450079d5bfcc165faad3fdc4ce5761fc12fbb2449d31498085a874ad4bae0abc77140e57b13
|
7
|
+
data.tar.gz: 31b9d040d7d2d7e68b4161714a913c698b045b7cb7e51e111377c418756bd0b7d2b1f5db76fe59c1b0afd69be15021ff566eee45d968b18c20009cceb2319203
|
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
|
+
## [0.2.0] - [UNRELEASED]
|
8
|
+
### Added
|
9
|
+
- EligibilityData
|
10
|
+
- EligibilityBenefit
|
11
|
+
- EligibilityBenefits
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
- Eligibility.query returns EligibilityData object
|
15
|
+
|
7
16
|
## [0.1.0] - 2020-03-04
|
8
17
|
### Added
|
9
18
|
- Provider
|
@@ -13,4 +22,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
13
22
|
- Authentication
|
14
23
|
- Configuration
|
15
24
|
|
25
|
+
[0.2.0]: https://github.com/WeInfuse/change_health/compare/v0.1.0...HEAD
|
16
26
|
[0.1.0]: https://github.com/WeInfuse/change_health/compare/v0.1.0
|
data/README.md
CHANGED
@@ -32,20 +32,40 @@ encounter = ChangeHealth::Models::Encounter.new(date_of_service: Date.current,
|
|
32
32
|
provider = ChangeHealth::Models::Provider.new(npi: '0123456789', last_name: 'Bobson', first_name: 'Bob')
|
33
33
|
subscriber = ChangeHealth::Models::Subscriber.new(member_id: '0000000000', first_name: 'johnOne', last_name: 'doeOne', date_of_birth: '18800102')
|
34
34
|
|
35
|
-
ChangeHealth::Models::Eligibility.new(tradingPartnerServiceId: '000050', provider: provider, subscriber: subscriber, encounter: encounter).query
|
35
|
+
edata = ChangeHealth::Models::Eligibility.new(tradingPartnerServiceId: '000050', provider: provider, subscriber: subscriber, encounter: encounter).query
|
36
|
+
```
|
37
|
+
|
38
|
+
### Benefit(s) objects
|
39
|
+
```
|
40
|
+
edata.benefits # Returns Benefits querying object (extends Array)
|
41
|
+
|
42
|
+
edata.benefits.individual # Only benefits matching the 'IND' identifier
|
43
|
+
|
44
|
+
edata.benefits.individual.in_network # 'IND' and in-plan-network = 'Y'
|
45
|
+
|
46
|
+
edata.benefits.individual(name: 'Co-Payment') # Manually finding "name" == "Co-Payment" in JSON
|
47
|
+
edata.benefits.individual(customParam: 'hi') # Filter on any params in the API combined with 'IND' type
|
48
|
+
|
49
|
+
edata.benefits.where(name: 'Co-Payment', code: 'B', benefitAmount: '30) # Generic 'where' api returns a Benefits querying object for chaining
|
50
|
+
edata.benefits.find_by(name: 'Co-Payment', code: 'B', benefitAmount: '30) # Generic 'find_by' api returns first object found
|
36
51
|
```
|
37
52
|
|
38
53
|
### Response
|
39
54
|
|
40
|
-
Response is
|
55
|
+
Response is EligibilityData object
|
41
56
|
|
42
57
|
```ruby
|
43
|
-
response
|
58
|
+
edata.response
|
44
59
|
#<HTTParty::Response:0x7fa354c1fbe8>
|
45
60
|
|
46
|
-
response.ok?
|
61
|
+
edata.response.ok?
|
62
|
+
true
|
63
|
+
|
64
|
+
edata.individual_oop_remaining(service_code: '30')
|
65
|
+
1344.88
|
66
|
+
|
67
|
+
edata.raw == edata.response.parsed_response
|
47
68
|
true
|
48
|
-
```
|
49
69
|
```
|
50
70
|
|
51
71
|
### Configuration
|
data/lib/change_health.rb
CHANGED
@@ -5,6 +5,8 @@ require 'change_health/change_health_exception'
|
|
5
5
|
require 'change_health/connection'
|
6
6
|
require 'change_health/authentication'
|
7
7
|
require 'change_health/models/eligibility'
|
8
|
+
require 'change_health/models/eligibility_data'
|
9
|
+
require 'change_health/models/eligibility_benefit'
|
8
10
|
require 'change_health/models/encounter'
|
9
11
|
require 'change_health/models/provider'
|
10
12
|
require 'change_health/models/subscriber'
|
@@ -25,7 +25,7 @@ module ChangeHealth
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def query
|
28
|
-
ChangeHealth::Connection.new.request(endpoint: ENDPOINT, body: self.to_h)
|
28
|
+
ChangeHealth::Models::EligibilityData.new(response: ChangeHealth::Connection.new.request(endpoint: ENDPOINT, body: self.to_h))
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.health_check
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module ChangeHealth
|
2
|
+
module Models
|
3
|
+
class EligibilityBenefits < Array
|
4
|
+
def initialize(benefits)
|
5
|
+
super(benefits.map {|benefit| ChangeHealth::Models::EligibilityBenefit.new(benefit) })
|
6
|
+
end
|
7
|
+
|
8
|
+
def where(**kwargs)
|
9
|
+
EligibilityBenefits.new(self.select {|benefit| kwargs.all? {|k,v| benefit_matches?(benefit, k, v) } })
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_by(**kwargs)
|
13
|
+
self.find {|benefit| kwargs.all? {|k,v| benefit[k].is_a?(Array) ? benefit[k].include?(v) : v == benefit[k] } }
|
14
|
+
end
|
15
|
+
|
16
|
+
def individual
|
17
|
+
self.where(coverageLevelCode: ChangeHealth::Models::EligibilityBenefit::INDIVIDUAL)
|
18
|
+
end
|
19
|
+
|
20
|
+
def in_network
|
21
|
+
self.where(inPlanNetworkIndicatorCode: 'Y')
|
22
|
+
end
|
23
|
+
|
24
|
+
%w(visit year remaining).each do |method|
|
25
|
+
define_method("#{method}s") do
|
26
|
+
self.where(timeQualifierCode: Object.const_get("ChangeHealth::Models::EligibilityBenefit::#{method.upcase}"))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
%w(out_of_pocket copayment coinsurance).each do |method|
|
31
|
+
define_method("#{method}s") do
|
32
|
+
self.where(code: Object.const_get("ChangeHealth::Models::EligibilityBenefit::#{method.upcase}"))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def individual_coinsurance_visit(**kwargs)
|
37
|
+
self.individual.coinsurances.visits.where(kwargs).first
|
38
|
+
end
|
39
|
+
|
40
|
+
def individual_copayment_visit(**kwargs)
|
41
|
+
self.individual.copayments.visits.where(kwargs).first
|
42
|
+
end
|
43
|
+
|
44
|
+
def individual_out_of_pocket_remaining(**kwargs)
|
45
|
+
self.individual.out_of_pockets.remainings.where(kwargs).first
|
46
|
+
end
|
47
|
+
|
48
|
+
def individual_out_of_pocket_total(**kwargs)
|
49
|
+
self.individual.out_of_pockets.years.where(kwargs).first
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :oops, :out_of_pockets
|
53
|
+
alias_method :copays, :copayments
|
54
|
+
alias_method :individual_copay_visit, :individual_copayment_visit
|
55
|
+
alias_method :individual_oop_remaining, :individual_out_of_pocket_remaining
|
56
|
+
alias_method :individual_oop_total, :individual_out_of_pocket_total
|
57
|
+
|
58
|
+
private
|
59
|
+
def benefit_matches?(benefit, k, v)
|
60
|
+
if benefit[k].is_a?(Array)
|
61
|
+
if v.is_a?(Array)
|
62
|
+
return v.any? {|possible_v| benefit[k].include?(possible_v) }
|
63
|
+
else
|
64
|
+
return benefit[k].include?(v)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
if v.is_a?(Array)
|
68
|
+
return v.include?(benefit[k])
|
69
|
+
else
|
70
|
+
return v == benefit[k]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class EligibilityBenefit < Hash
|
77
|
+
include Hashie::Extensions::MergeInitializer
|
78
|
+
include Hashie::Extensions::IndifferentAccess
|
79
|
+
|
80
|
+
OUT_OF_POCKET = 'G'
|
81
|
+
COPAYMENT = 'B'
|
82
|
+
COINSURANCE = 'A'
|
83
|
+
NON_COVERED = 'I'
|
84
|
+
|
85
|
+
INDIVIDUAL = 'IND'
|
86
|
+
CHILD = 'CHD'
|
87
|
+
|
88
|
+
VISIT = '27'
|
89
|
+
YEAR = '23'
|
90
|
+
REMAINING = '29'
|
91
|
+
|
92
|
+
%w(individual child).each do |coverage_level|
|
93
|
+
define_method("#{coverage_level}?") do
|
94
|
+
Object.const_get("ChangeHealth::Models::EligibilityBenefit::#{coverage_level.upcase}") == self['coverageLevelCode']
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
%w(visit year remaining).each do |time_qualifier|
|
99
|
+
define_method("#{time_qualifier}?") do
|
100
|
+
Object.const_get("ChangeHealth::Models::EligibilityBenefit::#{time_qualifier.upcase}") == self['timeQualifier']
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
%w(out_of_pocket copayment coinsurance non_covered).each do |type|
|
105
|
+
define_method("#{type}?") do
|
106
|
+
Object.const_get("ChangeHealth::Models::EligibilityBenefit::#{type.upcase}") == self['code']
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
%w(benefitAmount benefitPercent).each do |amount_method|
|
111
|
+
define_method("#{amount_method}") do
|
112
|
+
format_amount(amount_method)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def in_plan_network?
|
117
|
+
return 'Y' == self[:inPlanNetworkIndicatorCode]
|
118
|
+
end
|
119
|
+
alias_method :in_plan?, :in_plan_network?
|
120
|
+
alias_method :in_network?, :in_plan_network?
|
121
|
+
|
122
|
+
def amount
|
123
|
+
self.coinsurance? ? self.benefitPercent : self.benefitAmount
|
124
|
+
end
|
125
|
+
|
126
|
+
def services
|
127
|
+
self['serviceTypeCodes']&.each_with_index&.map {|stc, i| [stc, self['serviceTypes']&.at(i)]} || []
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
def format_amount(key)
|
132
|
+
amt = self[key]
|
133
|
+
amt = amt.to_f unless amt.nil?
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ChangeHealth
|
2
|
+
module Models
|
3
|
+
class EligibilityData
|
4
|
+
attr_reader :response, :raw
|
5
|
+
|
6
|
+
def initialize(data: nil, response: nil)
|
7
|
+
@response = response
|
8
|
+
@raw = data
|
9
|
+
|
10
|
+
begin
|
11
|
+
@raw ||= response&.parsed_response
|
12
|
+
rescue JSON::ParserError
|
13
|
+
end
|
14
|
+
|
15
|
+
@raw ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def active?(service_code: '30')
|
19
|
+
return '1' == plan_status(service_code: service_code).dig('statusCode')
|
20
|
+
end
|
21
|
+
|
22
|
+
%w(planStatus benefitsInformation controlNumber).each do |v|
|
23
|
+
define_method(v) do
|
24
|
+
@raw.dig(v)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def plan_status(service_code: )
|
29
|
+
self.planStatus&.find {|plan| plan.dig('serviceTypeCodes').include?(service_code) } || {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def benefits
|
33
|
+
ChangeHealth::Models::EligibilityBenefits.new(self.benefitsInformation || [])
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :control_number, :controlNumber
|
37
|
+
alias_method :benefits_information, :benefitsInformation
|
38
|
+
alias_method :plan_statuses, :planStatus
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: change_health
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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-03-
|
11
|
+
date: 2020-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -147,6 +147,8 @@ files:
|
|
147
147
|
- lib/change_health/change_health_exception.rb
|
148
148
|
- lib/change_health/connection.rb
|
149
149
|
- lib/change_health/models/eligibility.rb
|
150
|
+
- lib/change_health/models/eligibility_benefit.rb
|
151
|
+
- lib/change_health/models/eligibility_data.rb
|
150
152
|
- lib/change_health/models/encounter.rb
|
151
153
|
- lib/change_health/models/provider.rb
|
152
154
|
- lib/change_health/models/subscriber.rb
|