Skip to content

Commit

Permalink
Api 24831 section 5 disabilities validation (#12749)
Browse files Browse the repository at this point in the history
* Incremental commit

* Fix secondary disability logic

* Add validation for diagnostic code & toxic exposure

* Commit working implementation

* Add VCR cassette for BRD disabilties, add & update disability tests

* Add rspec tests for secondary disabilities

* Rubocop fixes

* Disable module length check

* Fix tests broken by merge

* Move name validation to schema, update tests

* Updates to fix rspec tests, accomodate schema change

* Misc cleanup

* Fix pdf mapper tests

* Fix tests after merge w/ master

* Test updates to add VCR cassette

---------

Co-authored-by: Jeremy Weiland <jeremy6d@users.noreply.github.com>
  • Loading branch information
mchristiansonVA and jeremy6d authored May 31, 2023
1 parent cb632a7 commit a9ac9cb
Show file tree
Hide file tree
Showing 7 changed files with 2,119 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def validate_form_526_submission_values!
validate_form_526_claimant_certification!
# ensure mailing address country is valid
validate_form_526_current_mailing_address_country!
# ensure disabilities are valid
validate_form_526_disabilities!
# ensure homeless information is valid
validate_form_526_veteran_homelessness!
# ensure military service pay information is valid
Expand Down Expand Up @@ -49,6 +51,170 @@ def valid_countries
@valid_countries ||= ClaimsApi::BRD.new(request).countries
end

def validate_form_526_disabilities!
validate_form_526_disability_classification_code!
validate_form_526_diagnostic_code!
validate_form_526_toxic_exposure!
validate_form_526_disability_approximate_begin_date!
validate_form_526_disability_secondary_disabilities!
end

def validate_form_526_disability_classification_code!
return if (form_attributes['disabilities'].pluck('classificationCode') - [nil]).blank?

form_attributes['disabilities'].each do |disability|
next if disability['classificationCode'].blank?

if brd_classification_ids.include?(disability['classificationCode'].to_i)
validate_form_526_disability_name!(disability['classificationCode'].to_i, disability['name'])
else
raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.classificationCode' must match the associated id " \
'value returned from the /disabilities endpoint of the Benefits ' \
'Reference Data API.'
)
end
end
end

def validate_form_526_disability_name!(classification_code, disability_name)
if disability_name.blank?
raise ::Common::Exceptions::InvalidFieldValue.new('disabilities.name',
disability['name'])
end
reference_disability = brd_disabilities.find { |x| x[:id] == classification_code }
return if reference_disability[:name] == disability_name

raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.name' must match the name value associated " \
"with 'disabilities.classificationCode' as returned from the " \
'/disabilities endpoint of the Benefits Reference Data API.'
)
end

def brd_classification_ids
return @brd_classification_ids if @brd_classification_ids.present?

brd_disabilities_arry = ClaimsApi::BRD.new(request).disabilities
@brd_classification_ids = brd_disabilities_arry.pluck(:id)
end

def brd_disabilities
return @brd_disabilities if @brd_disabilities.present?

@brd_disabilities = ClaimsApi::BRD.new(request).disabilities
end

def validate_form_526_disability_approximate_begin_date!
disabilities = form_attributes['disabilities']
return if disabilities.blank?

disabilities.each do |disability|
approx_begin_date = disability['approximateDate']
next if approx_begin_date.blank?

next if Date.parse(approx_begin_date) < Time.zone.today

raise ::Common::Exceptions::InvalidFieldValue.new('disability.approximateDate', approx_begin_date)
end
end

def validate_form_526_diagnostic_code!
form_attributes['disabilities'].each do |disability|
next unless disability['disabilityActionType'] == 'NONE' && disability['secondaryDisabilities'].present?

if disability['diagnosticCode'].blank?
raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.diagnosticCode' is required if 'disabilities.disabilityActionType' " \
"is 'NONE' and there are secondary disbilities included with the primary."
)
end
end
end

def validate_form_526_toxic_exposure!
form_attributes['disabilities'].each do |disability|
next unless disability['isRelatedToToxicExposure'] == true

if disability['exposureOrEventOrInjury'].blank?
raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "If disability is related to toxic exposure a value for 'disabilities.exposureOrEventOrInjury' " \
'is required.'
)
end
end
end

def validate_form_526_disability_secondary_disabilities!
form_attributes['disabilities'].each do |disability|
validate_form_526_disability_secondary_disability_disability_action_type!(disability)
next if disability['secondaryDisabilities'].blank?

disability['secondaryDisabilities'].each do |secondary_disability|
if secondary_disability['classificationCode'].present?
validate_form_526_disability_secondary_disability_classification_code!(secondary_disability)
validate_form_526_disability_secondary_disability_classification_code_matches_name!(
secondary_disability
)
end

if secondary_disability['approximateDate'].present?
validate_form_526_disability_secondary_disability_approximate_begin_date!(secondary_disability)
end
end
end
end

def validate_form_526_disability_secondary_disability_disability_action_type!(disability)
return unless disability['disabilityActionType'] == 'NONE' && disability['secondaryDisabilities'].present?

if disability['diagnosticCode'].blank?
raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.diagnosticCode' is required if 'disabilities.disabilityActionType' " \
"is 'NONE' and there are secondary disbilities included with the primary."
)
end
end

def validate_form_526_disability_secondary_disability_classification_code!(secondary_disability)
return if brd_classification_ids.include?(secondary_disability['classificationCode'].to_i)

raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.secondaryDisabilities.classificationCode' must match the associated id " \
'value returned from the /disabilities endpoint of the Benefits ' \
'Reference Data API.'
)
end

def validate_form_526_disability_secondary_disability_classification_code_matches_name!(secondary_disability)
if secondary_disability['name'].blank?
raise ::Common::Exceptions::InvalidFieldValue.new('disabilities.secondaryDisabilities.name',
secondary_disability['name'])
end
reference_disability = brd_disabilities.find { |x| x[:id] == secondary_disability['classificationCode'].to_i }
return if reference_disability[:name] == secondary_disability['name']

raise ::Common::Exceptions::UnprocessableEntity.new(
detail: "'disabilities.secondaryDisabilities.name' must match the name value associated " \
"with 'disabilities.secondaryDisabilities.classificationCode' as returned from the " \
'/disabilities endpoint of the Benefits Reference Data API.'
)
end

def validate_form_526_disability_secondary_disability_approximate_begin_date!(secondary_disability)
return if Date.parse(secondary_disability['approximateDate']) < Time.zone.today

raise ::Common::Exceptions::InvalidFieldValue.new(
'disabilities.secondaryDisabilities.approximateDate',
secondary_disability['approximateDate']
)
rescue ArgumentError
raise ::Common::Exceptions::InvalidFieldValue.new(
'disabilities.secondaryDisabilities.approximateDate',
secondary_disability['approximateDate']
)
end

def validate_form_526_veteran_homelessness!
handle_empty_other_description

Expand Down
4 changes: 3 additions & 1 deletion modules/claims_api/config/schemas/v2/526.json
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,9 @@
"name": {
"description": "What the Disability is called.",
"type": "string",
"example": "PTSD (post traumatic stress disorder)"
"pattern": "([a-zA-Z0-9\"\\/&\\(\\)\\-'.,# ]([a-zA-Z0-9(\\)\\-'.,# ])?)+$",
"example": "PTSD (post traumatic stress disorder)",
"maxLength" : 255
},
"disabilityActionType": {
"description": "The status of the secondary disability.",
Expand Down
4 changes: 4 additions & 0 deletions modules/claims_api/lib/brd/brd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def intake_sites
client.get('intake-sites').body[:items]
end

def disabilities
client.get('disabilities').body[:items]
end

private

def client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,18 @@
{
"disabilityActionType": "REOPEN",
"name": "PTSD (post traumatic stress disorder)",
"classificationCode": "ABCDEFGHIJ",
"classificationCode": "5420",
"serviceRelevance": "ABCDEFG",
"approximateDate": "4592-11-04",
"approximateDate": "2018-03-02",
"ratedDisabilityId": "ABCDEFGHIJKLMNOPQRSTUVWX",
"diagnosticCode": 0,
"diagnosticCode": 9999,
"secondaryDisabilities": [
{
"name": "ABCDEF",
"name": "Cancer - Musculoskeletal - Elbow",
"disabilityActionType": "SECONDARY",
"serviceRelevance": "ABCDEFGHIJKLMNOPQ",
"classificationCode": "ABCDEFGHIJKLMNO",
"approximateDate": "9904-01-03",
"classificationCode": "249470",
"approximateDate": "2018-03-02",
"exposureOrEventOrInjury": "EXPOSURE"
}
],
Expand All @@ -91,19 +91,19 @@
},
{
"disabilityActionType": "REOPEN",
"name": "Trauma",
"classificationCode": "ABCDEFGHIJ",
"name": "Traumatic Brain Injury",
"classificationCode": "9020",
"serviceRelevance": "ABCDEFG",
"approximateDate": "4592-11-04",
"approximateDate": "2018-03-02",
"ratedDisabilityId": "ABCDEFGHIJKLMNOPQRSTUVWX",
"diagnosticCode": 0,
"secondaryDisabilities": [
{
"name": "GHIJKLM",
"name": "Cancer - Musculoskeletal - Elbow",
"disabilityActionType": "SECONDARY",
"serviceRelevance": "ABCDEFGHIJKLMNOPQ",
"classificationCode": "ABCDEFGHIJKLMNO",
"approximateDate": "9904-01-03",
"classificationCode": "249470",
"approximateDate": "2018-03-02",
"exposureOrEventOrInjury": "EXPOSURE"
}
],
Expand Down Expand Up @@ -174,16 +174,7 @@
},
"treatments": [
{
"treatedDisabilityNames": ["PTSD (post traumatic stress disorder)", "Trauma"],
"center": {
"name": "Center One",
"state": "GA",
"city": "Decatur"
},
"startDate": "03-1985"
},
{
"treatedDisabilityNames": ["Trauma"],
"treatedDisabilityNames": ["PTSD (post traumatic stress disorder)"],
"center": {
"name": "Center One",
"state": "GA",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@
expect(has_conditions).to eq(true)
expect(name).to eq('PTSD (post traumatic stress disorder)')
expect(relevance).to eq('ABCDEFG')
expect(date).to eq('4592-11-04')
expect(date).to eq('2018-03-02')
expect(event).to eq('EXPOSURE')
expect(is_related).to eq(true)
expect(attribut_count).to eq(5)
expect(secondary_name).to eq('Trauma')
expect(secondary_name).to eq('Traumatic Brain Injury')
expect(secondary_event).to eq('EXPOSURE')
expect(secondary_relevance).to eq('ABCDEFG')
end
Expand Down Expand Up @@ -269,7 +269,7 @@

expect(start_date).to eq('03-1985')
expect(no_date).to eq(false)
expect(treatment_details).to eq('PTSD (post traumatic stress disorder), Trauma - Center One, Decatur, GA')
expect(treatment_details).to eq('PTSD (post traumatic stress disorder) - Center One, Decatur, GA')
end
end

Expand Down
Loading

0 comments on commit a9ac9cb

Please sign in to comment.