change_health 2.1.0 → 3.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: 962d95245a21c89b96048449a0111165eee7b3a392f00a2f1cddf8924bf98150
4
- data.tar.gz: 8b0127fb08968b20213728ffdc08afc0ae33a53a5d9c620efa916c8cc82f285f
3
+ metadata.gz: e0ce7d0b0648eeebabb95a1d8cbd2ddd81f778f5cea329f755b8734d754821e9
4
+ data.tar.gz: a81b263ebb9adc652ca914effc3b14ba047b429bb6a9ddff6faa89d73f9895fa
5
5
  SHA512:
6
- metadata.gz: 0e64c195c18b7fb2cbaf028141af3eab9ab2fbecfeb0750c1d706f81c9b12502d747a8a6d765228a9f731aa7c653ba6023a476677419e307089cbc15e320e93f
7
- data.tar.gz: 8c598d163710ae6d9f2a4a048d4f2697beb6f308eba526f3ca449962e920065a3a128f10769d38307fa7efaff3d13df7c4c57e16333dbc593bde48a99e745749
6
+ metadata.gz: d34f0ac2d23fe74bcc4674ff3c223ded869869bc62668578ead46a6dce495bce00cfd3d812d06faef795d8512eb59b93a492d0eeac627710bf73d8eec589ca6b
7
+ data.tar.gz: 24bcddfa9679442ece9d63a2ec3092f456394bb325a863bec29b8bc376d7052d0771b193572dc58610ee5a6c9b8f4cb64b28562fffa9adb039fcf057ca3d3502
data/CHANGELOG.md CHANGED
@@ -4,11 +4,60 @@ 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
- ## [2.1.0] - [2021-10-12]
7
+ ## [3.0.0] - 2021-12-08
8
+ ### Added
9
+ * Report277Claim - specific to claims from 277 reports
10
+ * Report835Claim - specific to claims from 835 reports
11
+ * Report835ServiceAdjustment & Report835ServiceLine - helper classes for readability of claims from 835 reports
12
+
13
+ ### Changed
14
+ * ReportClaim - removed 277 report unique fields
15
+
16
+ #### Namespace
17
+ | Previous | Current |
18
+ |-|-|
19
+ | ChangeHealth::Models::Error | ChangeHealth::Response::Error |
20
+ | ChangeHealth::Response::Claim::ReportInfoClaimStatus | ChangeHealth::Response::Claim::Report277InfoClaimStatus|
21
+
22
+ #### Methods
23
+ | Previous | Current |
24
+ |-|-|
25
+ | Report277Data#payer_org_name | Report277Data#payer_name |
26
+ | ReportClaim#latest_total_charge_amount | ReportClaim#total_charge_amount |
27
+ | ReportClaim#payer_org_name | ReportClaim#payer_name |
28
+ | ReportClaim#service_begin_date | ReportClaim#service_date_begin |
29
+ | ReportClaim#service_end_date | ReportClaim#service_date_end |
30
+ | ReportClaim#subscriber_first_name | ReportClaim#patient_first_name |
31
+ | ReportClaim#subscriber_last_name | ReportClaim#patient_last_name |
32
+ | ReportClaim#transaction_set_creation_date | ReportClaim#report_creation_date |
33
+
34
+
35
+ ## [2.3.0] - 2021-11-18
36
+ ### Added
37
+ * Report277Data & Report835Data - Specific classes for 277 & 835 reports
38
+ * ReportClaim & ReportInfoClaimStatus - only works for json 277 reports
39
+
40
+ ### Fixed
41
+ * Headers can now be nil for requests
42
+
43
+ ## [2.2.1] - 2021-11-15
44
+ ### Added
45
+ Custom Headers for Reports API and Professional Claims API
46
+ * Report
47
+ * Submission
48
+
49
+ ## [2.2.0] - 2021-11-04
50
+ ### Added
51
+ Ability to hit [Claim Responses and Reports](https://developers.changehealthcare.com/eligibilityandclaims/docs/claims-responses-and-reports-getting-started)
52
+ * Report
53
+ * ReportListData
54
+ * ReportData
55
+
56
+ ## [2.1.0] - 2021-10-12
8
57
  ### Changed
9
58
  Model#to_h enhanced to change empty values AKA "" to nil. Reason: If a field is empty, Change Healthcare responds with an error - `Invalid value. Item must not be blank value.`. If the empty field is optional, Change Healthcare will accept the field as nil without error. If the empty field is required, Change Healthcare will return an error if the value is empty or nil.
10
59
 
11
- ## [2.0.0] - [2021-10-08]
60
+ ## [2.0.0] - 2021-10-08
12
61
  ### Added
13
62
  #### Models
14
63
  * ResponseData - for responses from calling change healthcare api used by EligibilityData and SubmissionData
@@ -39,50 +88,50 @@ Added the ability to hit professional claim submission API. For more details, se
39
88
  ### Fixed
40
89
  * Eligibility#add_dependent actually works
41
90
 
42
- ## [1.0.3] - [2021-04-26]
91
+ ## [1.0.3] - 2021-04-26
43
92
  ### Added
44
93
  - Model::Error#represents_down? - adds ability to distinguish error representing down state
45
94
  - Model::Error#retryable? - retryable when down
46
95
  - EligibilityData#recommend_retry? - recommend retry when down
47
96
 
48
- ## [1.0.2] - [2021-04-06]
97
+ ## [1.0.2] - 2021-04-06
49
98
  ### Added
50
99
  - EligibilityData#recommend_retry? - fix a bug in the search statement
51
100
 
52
- ## [1.0.1] - [2021-03-24]
101
+ ## [1.0.1] - 2021-03-24
53
102
  ### Added
54
103
  - EligibilityData#plan_status - adds ability to select instead of find
55
104
  - EligibilityData#inactive? active? - use new plan_status select
56
105
 
57
- ## [1.0.0] - [2021-03-17]
106
+ ## [1.0.0] - 2021-03-17
58
107
  ### Added
59
108
  - Model::Error - help with error codes
60
109
  - EligibilityData#recommend_retry? - if it looks like you can retry the exact same request
61
110
  - EligibilityData#inactive? - looks for plan status 6
62
111
 
63
- ## [0.15.0] - [2020-06-12]
112
+ ## [0.15.0] - 2020-06-12
64
113
  ### Added
65
114
  - Extensions - InNetworkMissing for plans that don't provide in network indicators.
66
115
 
67
116
  ### Fixed
68
117
  - Bug where active codes with no service codes cause exception.
69
118
 
70
- ## [0.14.0] - [2020-05-07]
119
+ ## [0.14.0] - 2020-05-07
71
120
  ### Added
72
121
  - Extensions - mixins for common overrides
73
122
 
74
- ## [0.13.0] - [2020-05-05]
123
+ ## [0.13.0] - 2020-05-05
75
124
  ### Changed
76
125
  - Removed `alias_method` for `where` helpers so you can override a single method
77
126
  - Added type Year to Date type 24
78
127
  - Added type Day type 7
79
128
 
80
- ## [0.12.0] - [2020-04-30]
129
+ ## [0.12.0] - 2020-04-30
81
130
  ### Added
82
131
  - EligibilityData#errors
83
132
  - EligibilityData#errors?
84
133
 
85
- ## [0.11.0] - [2020-04-24]
134
+ ## [0.11.0] - 2020-04-24
86
135
  ### Added
87
136
  - EligibilityData#medicare?
88
137
  - EligibilityData#plan\_id
@@ -97,7 +146,7 @@ Added the ability to hit professional claim submission API. For more details, se
97
146
  - EligibilityData initialize now checks for sub-classes of EligibilityBenefits with trading partner responds to `factory` to choose sub-class
98
147
  - EligibilityBenefits initializes `self.class` type in case it's a subclass
99
148
 
100
- ## [0.10.0] - [2020-04-09]
149
+ ## [0.10.0] - 2020-04-09
101
150
  ### Added
102
151
  - Add Trading Partner API querying capability
103
152
  - Request::TradingPartner
@@ -105,7 +154,7 @@ Added the ability to hit professional claim submission API. For more details, se
105
154
  - Response::TradingPartnersData
106
155
  - Models::TradingPartner
107
156
 
108
- ## [0.9.0] - [2020-04-08]
157
+ ## [0.9.0] - 2020-04-08
109
158
  ### Added
110
159
  - Added EligibilityBenefit#medicare?
111
160
  - Added EligibilityData#medicare?
@@ -114,20 +163,20 @@ Added the ability to hit professional claim submission API. For more details, se
114
163
  - EligibilityBenefit(s)#individual returns true for medicare in benefit and queries that look for 'IND'
115
164
  - EligibilityBenefit(s)#in\_network returns true for medicare in benefit and queries that look for 'Y'
116
165
 
117
- ## [0.8.0] - [2020-04-04]
166
+ ## [0.8.0] - 2020-04-04
118
167
  ### Changed
119
168
  - Attempt to serialize all properties with 'date' in the name to ChangeHealth date format
120
169
 
121
- ## [0.7.0] - [2020-04-03]
170
+ ## [0.7.0] - 2020-04-03
122
171
  ### Changed
123
172
  - Fixed bug in serializing date on subscriber and encounter
124
173
 
125
- ## [0.6.0] - [2020-04-02]
174
+ ## [0.6.0] - 2020-04-02
126
175
  ### Changed
127
176
  - Added Indifferent Access to hashes
128
177
  - Fixed bug with Authentication endpoint
129
178
 
130
- ## [0.5.0] - [2020-03-11]
179
+ ## [0.5.0] - 2020-03-11
131
180
  ### Added
132
181
  - EligibilityBenefit Deductible information
133
182
  - EligibilityBenefit benefits date information
@@ -139,17 +188,17 @@ Added the ability to hit professional claim submission API. For more details, se
139
188
  ### Changed
140
189
  - Broke EligibilityBenefit and EligibilityBenefits into separate files
141
190
 
142
- ## [0.4.0] - [2020-03-10]
191
+ ## [0.4.0] - 2020-03-10
143
192
  ### Added
144
193
  - EligibilityBenefit(s) Employee information
145
194
  - EligibilityData plan date information
146
195
  - EligibilityData eligibility, plan and service date helpers on date info
147
196
 
148
- ## [0.3.0] - [2020-03-09]
197
+ ## [0.3.0] - 2020-03-09
149
198
  ### Added
150
199
  - Production endpoint
151
200
 
152
- ## [0.0.2] - [2020-03-09]
201
+ ## [0.0.2] - 2020-03-09
153
202
  ### Added
154
203
  - EligibilityData
155
204
  - EligibilityBenefit
@@ -167,6 +216,10 @@ Added the ability to hit professional claim submission API. For more details, se
167
216
  - Authentication
168
217
  - Configuration
169
218
 
219
+ [3.0.0]: https://github.com/WeInfuse/change_health/compare/v2.3.0...v3.0.0
220
+ [2.3.0]: https://github.com/WeInfuse/change_health/compare/v2.2.1...v2.3.0
221
+ [2.2.1]: https://github.com/WeInfuse/change_health/compare/v2.2.0...v2.2.1
222
+ [2.2.0]: https://github.com/WeInfuse/change_health/compare/v2.1.0...v2.2.0
170
223
  [2.1.0]: https://github.com/WeInfuse/change_health/compare/v2.0.0...v2.1.0
171
224
  [2.0.0]: https://github.com/WeInfuse/change_health/compare/v1.0.3...v2.0.0
172
225
  [1.0.3]: https://github.com/WeInfuse/change_health/compare/v1.0.2...v1.0.3
data/README.md CHANGED
@@ -1,9 +1,17 @@
1
1
  [![CircleCI](https://circleci.com/gh/WeInfuse/change_health.svg?style=svg)](https://circleci.com/gh/WeInfuse/change_health)
2
2
 
3
- # Change Health
3
+ ```
4
+ ____ _ _ _ _ _ _
5
+ / ___| |__ __ _ _ __ __ _ ___ | | | | ___ __ _| | |_| |__
6
+ | | | '_ \ / _` | '_ \ / _` |/ _ \ | |_| |/ _ \/ _` | | __| '_ \
7
+ | |___| | | | (_| | | | | (_| | __/ | _ | __/ (_| | | |_| | | |
8
+ \____|_| |_|\__,_|_| |_|\__, |\___| |_| |_|\___|\__,_|_|\__|_| |_|
9
+ |___/
10
+ ```
11
+
4
12
  Ruby API wrapper for [Change Health](https://developers.changehealthcare.com/api)
5
13
 
6
- ## Installation
14
+ # Installation
7
15
 
8
16
  Add this line to your application's Gemfile:
9
17
 
@@ -19,13 +27,13 @@ Or install it yourself as:
19
27
 
20
28
  $ gem install change_health
21
29
 
22
- ## Usage
30
+ # Usage
23
31
 
24
- ### Setup
32
+ ## Setup
25
33
 
26
34
  Make sure you're [configured](#configuration)!
27
35
 
28
- ### Eligibility
36
+ ## Eligibility
29
37
  [Change Healthcare Eligibility Guide](https://developers.changehealthcare.com/eligibilityandclaims/docs)
30
38
  ```ruby
31
39
  ChangeHealth::Request::Eligibility.ping # Test your connection
@@ -39,7 +47,7 @@ edata = ChangeHealth::Request::Eligibility.new(tradingPartnerServiceId: '000050'
39
47
  edata.raw # Raw Hash of JSON response
40
48
  ```
41
49
 
42
- #### Benefit(s) objects
50
+ ### Benefit(s) objects
43
51
  Benefits extends Array and provides a query-like interface.
44
52
 
45
53
  Benefit extends Hash and provides helpers for single-benefit.
@@ -58,7 +66,7 @@ edata.benefits.where(name: 'Co-Payment', code: 'B', benefitAmount: '30) # Generi
58
66
  edata.benefits.find_by(name: 'Co-Payment', code: 'B', benefitAmount: '30) # Generic 'find_by' api returns first object found
59
67
  ```
60
68
 
61
- #### Response
69
+ ### Response
62
70
 
63
71
  Response is EligibilityData object
64
72
 
@@ -67,29 +75,29 @@ edata.response
67
75
  #<HTTParty::Response:0x7fa354c1fbe8>
68
76
 
69
77
  edata.response.ok?
70
- true
78
+ # true
71
79
 
72
80
  edata.individual_oop_remaining(service_code: '30')
73
- 1344.88
81
+ # 1344.88
74
82
 
75
83
  edata.raw == edata.response.parsed_response
76
- true
84
+ # true
77
85
  ```
78
86
 
79
- ### Trading Partners
87
+ ## Trading Partners
80
88
  ```ruby
81
89
  # Query trading partners using a wildcard search
82
90
  # Returns Array of ChangeHealth::Models::TradingPartner Objects
83
91
  trading_partners = ChangeHealth::Request::TradingPartner.query("Aetna")
84
92
 
85
93
  trading_partners.first.name
86
- "Aetna"
94
+ # "Aetna"
87
95
 
88
96
  trading_partners.first.service_id
89
- "ABC123"
97
+ # "ABC123"
90
98
  ```
91
99
 
92
- ### Claim Submission
100
+ ## Claim Submission
93
101
  [Change Healthcare Claim Submission Guide](https://developers.changehealthcare.com/eligibilityandclaims/docs/professional-claims-v3-getting-started)
94
102
  ```ruby
95
103
  ChangeHealth::Request::Claim::Submission.ping # Test your connection
@@ -174,6 +182,12 @@ claim_information = ChangeHealth::Models::Claim::ClaimInformation.new(
174
182
  service_lines: [service_line1, service_line2]
175
183
  )
176
184
 
185
+ professional_headers = {
186
+ submitter_id: '111000',
187
+ biller_id: '000111',
188
+ username: '222333hey',
189
+ password: 'builder1'
190
+ }
177
191
 
178
192
  claim_submission = ChangeHealth::Request::Claim::Submission.new(
179
193
  trading_partner_service_id: "9496",
@@ -181,29 +195,127 @@ claim_submission = ChangeHealth::Request::Claim::Submission.new(
181
195
  receiver: receiver,
182
196
  subscriber: subscriber,
183
197
  providers: [provider],
184
- claim_information: claim_information
198
+ claim_information: claim_information,
199
+ headers: professional_headers
185
200
  )
186
201
 
187
202
  claim_submission_data = claim_submission.submission
203
+
204
+ validation = claim_submission.validation
205
+ ```
206
+
207
+ ## Claim Reports
208
+ [Change Healthcare Claim Responses and Reports Guide](https://developers.changehealthcare.com/eligibilityandclaims/docs/claims-responses-and-reports-getting-started)
209
+
210
+ ### Get Reports
211
+ ```ruby
212
+ ChangeHealth::Request::Claim::Report.ping # Test your connection
213
+
214
+ report_headers = {
215
+ username: '111000john',
216
+ password: 'WeInfuse1'
217
+ }
218
+
219
+ report_list = ChangeHealth::Request::Claim::Report.report_list(headers: report_headers)
220
+
221
+ report_list.report_names
222
+ # ["X3000000.XX", "R5000000.XY", "R5000000.XX", "X3000000.AB", "X3000000.AC", "X3000000.ZZ", "R5000000.XZ", "R5000000.YZ", "R5000000.WA", "R5000000.WB", "R5000000.WC"]
223
+
224
+ report0_edi = ChangeHealth::Request::Claim::Report.get_report(report_list.report_names.first, as_json_report: false)
225
+ # Report in edi format
226
+
227
+ report0_json = ChangeHealth::Request::Claim::Report.get_report(report_list.report_names.first, as_json_report: true)
228
+ # Report in json format
229
+
230
+ reports_json = report_list.report_names.map {|report_name| ChangeHealth::Request::Claim::Report.get_report(report_name, headers: report_headers)}
231
+ # all reports in json format
232
+
233
+ reports_edi = report_list.report_names.map {|report_name| ChangeHealth::Request::Claim::Report.get_report(report_name, as_json_report: false, headers: report_headers)}
234
+ # all reports in edi format
235
+ ```
236
+
237
+ ### Inspect Reports
238
+ Currently only works for json 277 reports and json 835 reports. Not for EDI reports
239
+
240
+ From a report, you can get an array of claims
241
+
242
+ #### Report 277
243
+
244
+ ```ruby
245
+ report_277_data = ChangeHealth::Request::Claim::Report.get_report("X3000000.AB", as_json_report: true)
246
+
247
+ report_277_data.payer_name
248
+ # "PREMERA"
249
+
250
+ report_277_data.report_creation_date
251
+ # Tue, 01 Dec 2020
252
+
253
+ claim_277 = report_277_data.claims.first
254
+ claim_277.payer_name
255
+ # "PREMERA"
256
+
257
+ claim_277.patient_first_name
258
+ # "JOHNONE"
259
+
260
+ claim_277.report_creation_date
261
+ # Tue, 01 Dec 2020
262
+
263
+ # Report 277 specific below
264
+ claim_277.latest_status_category_codes
265
+ # ["F1"]
266
+
267
+ claim_277.total_charge_amount
268
+ # "100"
269
+
270
+ claim_277.procedure_codes
271
+ # ["97161"]
272
+ ```
273
+
274
+ #### Report 835
275
+
276
+ ```ruby
277
+ report_835_data = ChangeHealth::Request::Claim::Report.get_report("R5000000.XY", as_json_report: true)
278
+
279
+ report_835_data.payment_method_code
280
+ # "ACH"
281
+
282
+ report_835_data.total_actual_provider_payment_amount
283
+ # "2563.13"
284
+
285
+ claim_835 = report_835_data.claims.first
286
+ claim_835.payer_name
287
+ # "NATIONAL GOVERNMENT SERVICES, INC."
288
+
289
+ claim_835.patient_first_name
290
+ # "JANE"
291
+
292
+ claim_835.report_creation_date
293
+ # Wed, 22 Apr 2020
294
+
295
+ claim_835.procedure_codes
296
+ # ["21210", "21026", "21208", "30580"]
297
+
298
+ claim_835.service_lines.map(&:line_item_charge_amount)
299
+ # ["3600", "1890", "1836", "1680"]
188
300
  ```
189
301
 
190
- ### Configuration
302
+ ## Configuration
191
303
 
192
304
  ```ruby
193
305
  ChangeHealth.configure do |c|
194
306
  c.client_id = ENV['CHANGE_HEALTH_CLIENT_ID']
195
307
  c.client_secret = ENV['CHANGE_HEALTH_SECRET']
196
- c.grant_type = 'bob' # Defaults to client_credentials
197
- c.api_endpoint = 'http://hello.com' # Defaults to Change Health Sandbox endpoint
308
+ c.grant_type = 'client_credentials' # Defaults to client_credentials
309
+ c.api_endpoint = 'https://sandbox.apigw.changehealthcare.com' # Defaults to Change Health Sandbox endpoint
198
310
  end
199
311
  ```
200
312
 
201
- ## Development
313
+ # Development
202
314
 
203
315
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
204
316
 
205
317
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
206
318
 
207
- ## Contributing
319
+ # Contributing
208
320
 
209
321
  Bug reports and pull requests are welcome on GitHub at https://github.com/WeInfuse/change\_health.
@@ -13,11 +13,12 @@ module ChangeHealth
13
13
 
14
14
  format :json
15
15
 
16
- def request(endpoint: , query: nil, body: nil, headers: {}, auth: true, verb: :post)
16
+ def request(endpoint:, query: nil, body: nil, headers: {}, auth: true, verb: :post)
17
17
  body = body.to_json if body.is_a?(Hash)
18
+ headers = {} if headers.nil?
18
19
  headers = auth_header.merge(headers) if auth
19
20
 
20
- self.class.send("#{verb}", endpoint, query: query, body: body, headers: headers)
21
+ self.class.send(verb.to_s, endpoint, query: query, body: body, headers: headers)
21
22
  end
22
23
 
23
24
  private
@@ -25,7 +26,7 @@ module ChangeHealth
25
26
  def auth_header
26
27
  @auth ||= Authentication.new
27
28
 
28
- return @auth.authenticate.access_header
29
+ @auth.authenticate.access_header
29
30
  end
30
31
  end
31
32
  end
@@ -0,0 +1,60 @@
1
+ module ChangeHealth
2
+ module Request
3
+ module Claim
4
+ class Report
5
+ ENDPOINT = '/medicalnetwork/reports/v2'.freeze
6
+ HEALTH_CHECK_ENDPOINT = ENDPOINT + '/healthcheck'.freeze
7
+
8
+ def self.report_list(headers: nil)
9
+ final_headers = ChangeHealth::Request::Claim::Report.report_headers(headers)
10
+ ChangeHealth::Response::Claim::ReportListData.new(response: ChangeHealth::Connection.new.request(endpoint: ENDPOINT, verb: :get, headers: final_headers))
11
+ end
12
+
13
+ def self.get_report(report_name, as_json_report: true, headers: nil)
14
+ return if report_name.nil? || report_name.empty?
15
+ final_headers = ChangeHealth::Request::Claim::Report.report_headers(headers)
16
+
17
+ report_type = ChangeHealth::Response::Claim::ReportData.report_type(report_name)
18
+ return if report_type.nil?
19
+
20
+ individual_report_endpoint = ENDPOINT + '/' + report_name
21
+
22
+ # https://developers.changehealthcare.com/eligibilityandclaims/docs/what-file-types-does-this-api-get-from-the-mailbox
23
+ individual_report_endpoint += '/' + report_type if as_json_report
24
+
25
+ response = ChangeHealth::Connection.new.request(endpoint: individual_report_endpoint, verb: :get, headers: final_headers)
26
+ if ChangeHealth::Response::Claim::ReportData.is_277?(report_name)
27
+ ChangeHealth::Response::Claim::Report277Data
28
+ .new(report_name,
29
+ as_json_report,
30
+ response: response)
31
+ else
32
+ ChangeHealth::Response::Claim::Report835Data
33
+ .new(report_name,
34
+ as_json_report,
35
+ response: response)
36
+ end
37
+ end
38
+
39
+ def self.health_check
40
+ ChangeHealth::Connection.new.request(endpoint: HEALTH_CHECK_ENDPOINT, verb: :get)
41
+ end
42
+
43
+ def self.ping
44
+ self.health_check
45
+ end
46
+
47
+ def self.report_headers(headers)
48
+ if headers
49
+ extra_headers = {}
50
+ extra_headers["X-CHC-Reports-Username"] = headers[:username]
51
+ extra_headers["X-CHC-Reports-Password"] = headers[:password]
52
+ extra_headers
53
+ else
54
+ nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -2,9 +2,11 @@ module ChangeHealth
2
2
  module Request
3
3
  module Claim
4
4
  class Submission < Hashie::Trash
5
+
5
6
  ENDPOINT = '/medicalnetwork/professionalclaims/v3'.freeze
6
7
  HEALTH_CHECK_ENDPOINT = ENDPOINT + '/healthcheck'.freeze
7
8
  SUBMISSION_ENDPOINT = ENDPOINT + '/submission'.freeze
9
+ VALIDATION_ENDPOINT = ENDPOINT + '/validation'.freeze
8
10
 
9
11
  property :claimInformation, from: :claim_information, required: false
10
12
  property :controlNumber, from: :control_number, required: true, default: ChangeHealth::Models::CONTROL_NUMBER
@@ -12,6 +14,7 @@ module ChangeHealth
12
14
  property :receiver, required: false
13
15
  property :submitter, required: false
14
16
  property :subscriber, required: false
17
+ property :headers, required: false
15
18
  # Need one or the other, trading partner id or trading partner service id
16
19
  property :tradingPartnerId, from: :trading_partner_id, required: false
17
20
  property :tradingPartnerServiceId, from: :trading_partner_service_id, required: false
@@ -22,7 +25,11 @@ module ChangeHealth
22
25
  end
23
26
 
24
27
  def submission
25
- ChangeHealth::Response::Claim::SubmissionData.new(response: ChangeHealth::Connection.new.request(endpoint: SUBMISSION_ENDPOINT, body: self.to_h))
28
+ ChangeHealth::Response::Claim::SubmissionData.new(response: ChangeHealth::Connection.new.request(endpoint: SUBMISSION_ENDPOINT, body: self.to_h, headers: professional_headers))
29
+ end
30
+
31
+ def validation
32
+ ChangeHealth::Response::Claim::SubmissionData.new(response: ChangeHealth::Connection.new.request(endpoint: VALIDATION_ENDPOINT, body: self.to_h, headers: professional_headers))
26
33
  end
27
34
 
28
35
  def self.health_check
@@ -32,6 +39,19 @@ module ChangeHealth
32
39
  def self.ping
33
40
  self.health_check
34
41
  end
42
+
43
+ def professional_headers
44
+ if self[:headers]
45
+ extra_headers = {}
46
+ extra_headers["X-CHC-ClaimSubmission-SubmitterId"] = self[:headers][:submitter_id]
47
+ extra_headers["X-CHC-ClaimSubmission-BillerId"] = self[:headers][:biller_id]
48
+ extra_headers["X-CHC-ClaimSubmission-Username"] = self[:headers][:username]
49
+ extra_headers["X-CHC-ClaimSubmission-Pwd"] = self[:headers][:password]
50
+ extra_headers
51
+ else
52
+ nil
53
+ end
54
+ end
35
55
  end
36
56
  end
37
57
  end
@@ -0,0 +1,40 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class Report277Claim < ReportClaim
5
+ property :info_claim_statuses, required: false
6
+ property :procedure_codes, required: false
7
+
8
+ def add_info_claim_status(info_claim_status)
9
+ self[:info_claim_statuses] ||= []
10
+ self[:info_claim_statuses] << info_claim_status
11
+ end
12
+
13
+ def add_procedure_code(procedure_code)
14
+ self[:procedure_codes] ||= []
15
+ self[:procedure_codes] << procedure_code
16
+ end
17
+
18
+ def latest_status_category_codes
19
+ latest_info_claim_status&.status_category_codes
20
+ end
21
+
22
+ def total_charge_amount
23
+ latest_info_claim_status&.total_charge_amount
24
+ end
25
+
26
+ def latest_status_info_effective_date
27
+ latest_info_claim_status&.status_information_effective_date
28
+ end
29
+
30
+ def latest_info_claim_status
31
+ info_claim_statuses&.select do |info|
32
+ !info.status_information_effective_date.nil? &&
33
+ info.status_information_effective_date.is_a?(Date) &&
34
+ info.status_information_effective_date <= Date.today
35
+ end&.max_by(&:status_information_effective_date)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,84 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ # Methods only return meaningful data for json reports
5
+ class Report277Data < ChangeHealth::Response::Claim::ReportData
6
+ def transactions
7
+ @raw['transactions']
8
+ end
9
+
10
+ # Only one payer per report
11
+ def payer_name
12
+ transactions&.first&.dig('payers')&.first&.dig('organizationName')
13
+ end
14
+
15
+ def report_creation_date
16
+ ChangeHealth::Models::PARSE_DATE.call(transactions&.first&.dig('transactionSetCreationDate'))
17
+ end
18
+
19
+ def claims
20
+ report_claims = []
21
+
22
+ transactions&.each do |transaction|
23
+ report_creation_date = ChangeHealth::Models::PARSE_DATE.call(transaction['transactionSetCreationDate'])
24
+ transaction['payers']&.each do |payer|
25
+ payer_identification = payer['payerIdentification']
26
+ payer_name = payer['organizationName']
27
+ payer['claimStatusTransactions']&.each do |claim_status_txn|
28
+ claim_status_txn['claimStatusDetails']&.each do |claim_status_detail|
29
+ service_provider_npi = claim_status_detail.dig('serviceProvider', 'npi')
30
+ claim_status_detail['patientClaimStatusDetails']&.each do |patient_claim_status_detail|
31
+ patient_first_name = patient_claim_status_detail.dig('subscriber', 'firstName')
32
+ patient_last_name = patient_claim_status_detail.dig('subscriber', 'lastName')
33
+ patient_claim_status_detail['claims']&.each do |claim|
34
+ procedure_codes = []
35
+ claim['serviceLines']&.each do |service_line|
36
+ procedure_codes << service_line.dig('service', 'procedureCode')
37
+ end
38
+ claim_status = claim['claimStatus']
39
+ next if claim_status.nil?
40
+
41
+ service_date_begin = ChangeHealth::Models::PARSE_DATE.call(claim_status['claimServiceBeginDate'] || claim_status['claimServiceDate'])
42
+ service_date_end = ChangeHealth::Models::PARSE_DATE.call(claim_status['claimServiceEndDate'] || claim_status['claimServiceDate'])
43
+
44
+ info_claim_statuses = []
45
+ claim_status['informationClaimStatuses']&.each do |info_claim_status|
46
+ status_information_effective_date = ChangeHealth::Models::PARSE_DATE.call(info_claim_status['statusInformationEffectiveDate'])
47
+ total_charge_amount = info_claim_status['totalClaimChargeAmount']
48
+
49
+ status_category_codes = []
50
+ info_claim_status['informationStatuses']&.each do |info_status|
51
+ status_category_codes << info_status['healthCareClaimStatusCategoryCode']
52
+ end
53
+
54
+ info_claim_statuses << Report277InfoClaimStatus.new(
55
+ status_category_codes: status_category_codes,
56
+ total_charge_amount: total_charge_amount,
57
+ status_information_effective_date: status_information_effective_date
58
+ )
59
+ end
60
+ report_claims << Report277Claim.new(
61
+ info_claim_statuses: info_claim_statuses,
62
+ patient_first_name: patient_first_name,
63
+ patient_last_name: patient_last_name,
64
+ payer_identification: payer_identification,
65
+ payer_name: payer_name,
66
+ procedure_codes: procedure_codes,
67
+ report_creation_date: report_creation_date,
68
+ service_date_begin: service_date_begin,
69
+ service_date_end: service_date_end,
70
+ service_provider_npi: service_provider_npi
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ report_claims
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,16 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class Report277InfoClaimStatus < Hashie::Trash
5
+ property :status_category_codes, required: false
6
+ property :total_charge_amount, required: false
7
+ property :status_information_effective_date, required: false
8
+
9
+ def add_status_category_code(status_category_code)
10
+ self[:status_category_codes] ||= []
11
+ self[:status_category_codes] << status_category_code
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class Report835Claim < ReportClaim
5
+ property :payer_claim_control_number, required: false
6
+ property :payment_method_code, required: false
7
+ property :service_lines, required: false
8
+ property :total_actual_provider_payment_amount, required: false
9
+ property :total_charge_amount, required: false
10
+
11
+ def procedure_codes
12
+ service_lines&.map(&:adjudicated_procedure_code)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,116 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ # Methods only return meaningful data for json reports
5
+ class Report835Data < ChangeHealth::Response::Claim::ReportData
6
+ def transactions
7
+ @raw['transactions']
8
+ end
9
+
10
+ # Only one payer per report
11
+ def payer_name
12
+ transactions&.first&.dig('payer')&.dig('name')
13
+ end
14
+
15
+ def payment_method_code
16
+ transactions&.first&.dig('financialInformation', 'paymentMethodCode')
17
+ end
18
+
19
+ def report_creation_date
20
+ ChangeHealth::Models::PARSE_DATE.call(transactions&.first&.dig('productionDate'))
21
+ end
22
+
23
+ def total_actual_provider_payment_amount
24
+ transactions&.first&.dig('financialInformation', 'totalActualProviderPaymentAmount')
25
+ end
26
+
27
+ def claims
28
+ report_claims = []
29
+
30
+ transactions&.each do |transaction|
31
+ payment_method_code = transaction.dig('financialInformation', 'paymentMethodCode')
32
+ payer_name = transaction.dig('payer', 'name')
33
+ payer_identification = transaction.dig('payer', 'payerIdentificationNumber')
34
+ report_creation_date = ChangeHealth::Models::PARSE_DATE.call(transaction['productionDate'])
35
+ total_actual_provider_payment_amount = transaction.dig('financialInformation',
36
+ 'totalActualProviderPaymentAmount')
37
+
38
+ transaction['detailInfo']&.each do |detail_info|
39
+ detail_info['paymentInfo']&.each do |payment_info|
40
+ patient_first_name = payment_info.dig('patientName', 'firstName')
41
+ patient_last_name = payment_info.dig('patientName', 'lastName')
42
+ service_provider_npi = payment_info.dig('renderingProvider', 'npi')
43
+ total_charge_amount = payment_info.dig('claimPaymentInfo', 'totalClaimChargeAmount')
44
+ payer_claim_control_number = payment_info.dig('claimPaymentInfo', 'payerClaimControlNumber')
45
+
46
+ service_date_begin = nil
47
+ service_date_end = nil
48
+ service_lines = []
49
+ payment_info['serviceLines']&.each do |service_line|
50
+ service_line_date = ChangeHealth::Models::PARSE_DATE.call(service_line['serviceDate'])
51
+ if service_date_begin.nil? || service_line_date < service_date_begin
52
+ service_date_begin = service_line_date
53
+ end
54
+ if service_date_end.nil? || service_date_end < service_line_date
55
+ service_date_end = service_line_date
56
+ end
57
+
58
+ adjudicated_procedure_code = service_line.dig('servicePaymentInformation', 'adjudicatedProcedureCode')
59
+ allowed_actual = service_line.dig('serviceSupplementalAmounts', 'allowedActual')
60
+ line_item_charge_amount = service_line.dig('servicePaymentInformation', 'lineItemChargeAmount')
61
+ line_item_provider_payment_amount = service_line.dig('servicePaymentInformation',
62
+ 'lineItemProviderPaymentAmount')
63
+
64
+ service_adjustments = []
65
+ service_line['serviceAdjustments']&.each do |service_adjustment|
66
+ adjustments = {}
67
+ # - 2 b/c group code & value, / 2 b/c come in pairs
68
+ num_adjustments = (service_adjustment.keys.size - 2) / 2
69
+ (1..num_adjustments).each do |index|
70
+ adjustment_reason = service_adjustment["adjustmentReasonCode#{index}"]
71
+ adjustment_amount = service_adjustment["adjustmentAmount#{index}"]
72
+ adjustments[adjustment_reason] = adjustment_amount
73
+ end
74
+
75
+ claim_adjustment_group_code = service_adjustment['claimAdjustmentGroupCode']
76
+
77
+ service_adjustments << Report835ServiceAdjustment.new(
78
+ adjustments: adjustments,
79
+ claim_adjustment_group_code: claim_adjustment_group_code
80
+ )
81
+ end
82
+
83
+ service_lines << Report835ServiceLine.new(
84
+ adjudicated_procedure_code: adjudicated_procedure_code,
85
+ allowed_actual: allowed_actual,
86
+ line_item_charge_amount: line_item_charge_amount,
87
+ line_item_provider_payment_amount: line_item_provider_payment_amount,
88
+ service_adjustments: service_adjustments
89
+ )
90
+ end
91
+
92
+ report_claims << Report835Claim.new(
93
+ patient_first_name: patient_first_name,
94
+ patient_last_name: patient_last_name,
95
+ payer_claim_control_number: payer_claim_control_number,
96
+ payer_identification: payer_identification,
97
+ payer_name: payer_name,
98
+ payment_method_code: payment_method_code,
99
+ report_creation_date: report_creation_date,
100
+ service_date_begin: service_date_begin,
101
+ service_date_end: service_date_end,
102
+ service_lines: service_lines,
103
+ service_provider_npi: service_provider_npi,
104
+ total_actual_provider_payment_amount: total_actual_provider_payment_amount,
105
+ total_charge_amount: total_charge_amount
106
+ )
107
+ end
108
+ end
109
+ end
110
+
111
+ report_claims
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,15 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class Report835ServiceAdjustment < Hashie::Trash
5
+ property :adjustments, required: false
6
+ property :claim_adjustment_group_code, required: false
7
+
8
+ def add_adjustment(adjustment)
9
+ self[:adjustments] ||= []
10
+ self[:adjustments] << adjustment
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class Report835ServiceLine < Hashie::Trash
5
+ property :adjudicated_procedure_code, required: false
6
+ property :allowed_actual, required: false
7
+ property :line_item_charge_amount, required: false
8
+ property :line_item_provider_payment_amount, required: false
9
+ property :service_adjustments, required: false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class ReportClaim < Hashie::Trash
5
+ property :patient_first_name, required: false
6
+ property :patient_last_name, required: false
7
+ property :payer_identification, required: false
8
+ property :payer_name, required: false
9
+ property :report_creation_date, required: false
10
+ property :service_date_begin, required: false
11
+ property :service_date_end, required: false
12
+ property :service_provider_npi, required: false
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class ReportData < ChangeHealth::Response::ResponseData
5
+ attr_reader :report_name, :json
6
+ alias_method :json?, :json
7
+
8
+ def initialize(report_name, json, data: nil, response: nil)
9
+ super(data: data, response: response)
10
+ @report_name = report_name
11
+ @json = json
12
+ end
13
+
14
+ def edi?
15
+ !@json
16
+ end
17
+
18
+ def report_type
19
+ self.class.report_type(@report_name)
20
+ end
21
+
22
+ def self.report_type(report_name)
23
+ return '277' if is_277?(report_name)
24
+ return '835' if is_835?(report_name)
25
+ end
26
+
27
+ def is_277?
28
+ self.class.is_277?(@report_name)
29
+ end
30
+
31
+ def self.is_277?(report_name)
32
+ report_name.start_with?('X3')
33
+ end
34
+
35
+ def is_835?
36
+ self.class.is_835?(@report_name)
37
+ end
38
+
39
+ def self.is_835?(report_name)
40
+ report_name.start_with?('R5')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module ChangeHealth
2
+ module Response
3
+ module Claim
4
+ class ReportListData < ChangeHealth::Response::ResponseData
5
+
6
+ def report_names
7
+ @raw.dig('reports')
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,12 +1,12 @@
1
1
  module ChangeHealth
2
- module Models
2
+ module Response
3
3
  class Error
4
4
  attr_reader :data
5
5
 
6
6
  SIMPLE_RETRY_CODES = %w[
7
- 42
8
- 80
9
- ].freeze
7
+ 42
8
+ 80
9
+ ].freeze
10
10
 
11
11
  NO_RESUBMIT_MESSAGES = [
12
12
  'resubmission not allowed',
@@ -39,7 +39,9 @@ module ChangeHealth
39
39
 
40
40
  def retryable?
41
41
  represents_down? ||
42
- (code? && SIMPLE_RETRY_CODES.include?(code) && followupAction? && NO_RESUBMIT_MESSAGES.none? {|msg| followupAction.downcase.include?(msg) })
42
+ (code? && SIMPLE_RETRY_CODES.include?(code) && followupAction? && NO_RESUBMIT_MESSAGES.none? do |msg|
43
+ followupAction.downcase.include?(msg)
44
+ end)
43
45
  end
44
46
 
45
47
  %w[field description code followupAction location].each do |method_name|
@@ -47,7 +49,7 @@ module ChangeHealth
47
49
  false == send(method_name).nil?
48
50
  end
49
51
 
50
- define_method("#{method_name}") do
52
+ define_method(method_name.to_s) do
51
53
  @data[method_name]
52
54
  end
53
55
  end
@@ -16,13 +16,13 @@ module ChangeHealth
16
16
  end
17
17
 
18
18
  def errors?
19
- self.errors.is_a?(Array) && false == self.errors.empty?
19
+ errors.is_a?(Array) && false == errors.empty?
20
20
  end
21
21
 
22
22
  def errors
23
23
  errors = @raw.dig('errors') || []
24
24
 
25
- errors.flatten.map {|error| ChangeHealth::Models::Error.new(error) }
25
+ errors.flatten.map { |error| ChangeHealth::Response::Error.new(error) }
26
26
  end
27
27
 
28
28
  def recommend_retry?
@@ -34,7 +34,7 @@ module ChangeHealth
34
34
 
35
35
  return false if error_codes.empty?
36
36
 
37
- return error_codes.all?(&:retryable?)
37
+ error_codes.all?(&:retryable?)
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module ChangeHealth
2
- VERSION = '2.1.0'.freeze
2
+ VERSION = '3.0.0'.freeze
3
3
  end
data/lib/change_health.rb CHANGED
@@ -5,7 +5,6 @@ require 'change_health/authentication'
5
5
  require 'change_health/change_health_exception'
6
6
  require 'change_health/connection'
7
7
  require 'change_health/extensions'
8
- require 'change_health/models/error'
9
8
  require 'change_health/models/model'
10
9
  require 'change_health/models/claim/submission/claim_information'
11
10
  require 'change_health/models/claim/submission/provider'
@@ -18,9 +17,21 @@ require 'change_health/models/eligibility/subscriber'
18
17
  require 'change_health/models/trading_partner/trading_partner'
19
18
  require 'change_health/request/eligibility'
20
19
  require 'change_health/request/submission'
20
+ require 'change_health/request/report'
21
21
  require 'change_health/request/trading_partner'
22
+ require 'change_health/response/error'
22
23
  require 'change_health/response/response_data'
23
24
  require 'change_health/response/claim/submission/submission_data'
25
+ require 'change_health/response/claim/report/report_list_data'
26
+ require 'change_health/response/claim/report/report_data'
27
+ require 'change_health/response/claim/report/report_277_data'
28
+ require 'change_health/response/claim/report/report_835_data'
29
+ require 'change_health/response/claim/report/report_claim'
30
+ require 'change_health/response/claim/report/report_277_claim'
31
+ require 'change_health/response/claim/report/report_277_info_claim_status'
32
+ require 'change_health/response/claim/report/report_835_claim'
33
+ require 'change_health/response/claim/report/report_835_service_adjustment'
34
+ require 'change_health/response/claim/report/report_835_service_line'
24
35
  require 'change_health/response/eligibility/eligibility_benefit'
25
36
  require 'change_health/response/eligibility/eligibility_benefits'
26
37
  require 'change_health/response/eligibility/eligibility_data'
@@ -42,11 +53,11 @@ module ChangeHealth
42
53
  end
43
54
 
44
55
  def api_endpoint
45
- return Connection.base_uri
56
+ Connection.base_uri
46
57
  end
47
58
 
48
59
  def to_h
49
- return {
60
+ {
50
61
  client_id: @client_id,
51
62
  client_secret: @client_secret,
52
63
  grant_type: @grant_type,
@@ -60,7 +71,7 @@ module ChangeHealth
60
71
  self.grant_type = h[:grant_type]
61
72
  self.api_endpoint = h[:api_endpoint]
62
73
 
63
- return self
74
+ self
64
75
  end
65
76
  end
66
77
 
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: 2.1.0
4
+ version: 3.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: 2021-10-12 00:00:00.000000000 Z
11
+ date: 2021-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -155,16 +155,27 @@ files:
155
155
  - lib/change_health/models/eligibility/encounter.rb
156
156
  - lib/change_health/models/eligibility/provider.rb
157
157
  - lib/change_health/models/eligibility/subscriber.rb
158
- - lib/change_health/models/error.rb
159
158
  - lib/change_health/models/model.rb
160
159
  - lib/change_health/models/trading_partner/trading_partner.rb
161
160
  - lib/change_health/request/eligibility.rb
161
+ - lib/change_health/request/report.rb
162
162
  - lib/change_health/request/submission.rb
163
163
  - lib/change_health/request/trading_partner.rb
164
+ - lib/change_health/response/claim/report/report_277_claim.rb
165
+ - lib/change_health/response/claim/report/report_277_data.rb
166
+ - lib/change_health/response/claim/report/report_277_info_claim_status.rb
167
+ - lib/change_health/response/claim/report/report_835_claim.rb
168
+ - lib/change_health/response/claim/report/report_835_data.rb
169
+ - lib/change_health/response/claim/report/report_835_service_adjustment.rb
170
+ - lib/change_health/response/claim/report/report_835_service_line.rb
171
+ - lib/change_health/response/claim/report/report_claim.rb
172
+ - lib/change_health/response/claim/report/report_data.rb
173
+ - lib/change_health/response/claim/report/report_list_data.rb
164
174
  - lib/change_health/response/claim/submission/submission_data.rb
165
175
  - lib/change_health/response/eligibility/eligibility_benefit.rb
166
176
  - lib/change_health/response/eligibility/eligibility_benefits.rb
167
177
  - lib/change_health/response/eligibility/eligibility_data.rb
178
+ - lib/change_health/response/error.rb
168
179
  - lib/change_health/response/response_data.rb
169
180
  - lib/change_health/response/trading_partner/trading_partner_data.rb
170
181
  - lib/change_health/response/trading_partner/trading_partners_data.rb