change_health 0.0.1 → 0.0.2
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 +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
|