-
Notifications
You must be signed in to change notification settings - Fork 94
VFMP - Added the ability for CST providers to upload supporting docs to existing cases #27798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7eff8a4
Added endpoint to submit docs to existing case in PEGA
ksantiagoBAH bf3e931
Fixed linting
ksantiagoBAH c5b7e59
Remove accidental Gemfile.lock change
ksantiagoBAH 6e79563
Added feature flag and updated specs
ksantiagoBAH 36e2423
Addressed reek issues
ksantiagoBAH d1f2276
Removed dead code
ksantiagoBAH cbfe4a3
Merge remote-tracking branch 'origin' into vfmp-champva-fileuploader
ksantiagoBAH 93db897
Updated metadata after front end changes fixed rubocop issues
ksantiagoBAH ea0abb1
fixed rubocop issues
ksantiagoBAH File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| require 'lighthouse/benefits_documents/update_documents_status_service' | ||
|
|
||
| module V0 | ||
| # rubocop:disable Metrics/ClassLength | ||
| class BenefitsClaimsController < ApplicationController | ||
| include InboundRequestLogging | ||
| include V0::Concerns::MultiProviderSupport | ||
|
|
@@ -28,19 +29,63 @@ class BenefitsClaimsController < ApplicationController | |
|
|
||
| FEATURE_USE_TITLE_GENERATOR_WEB = 'cst_use_claim_title_generator_web' | ||
| FEATURE_MULTI_CLAIM_PROVIDER = 'cst_multi_claim_provider' | ||
| DEFAULT_UPLOAD_DESTINATION_KEY = 'benefits_claims' | ||
| IVC_CHAMPVA_UPLOAD_DESTINATION_KEY = 'ivc_champva_supporting_documents' | ||
| IVC_CHAMPVA_FINALIZE_DESTINATION_KEY = 'ivc_champva_docs_only_resubmission' | ||
|
|
||
| UPLOAD_DESTINATION_KEY_BY_PROVIDER = { | ||
| 'lighthouse' => DEFAULT_UPLOAD_DESTINATION_KEY, | ||
| 'ivc_champva' => IVC_CHAMPVA_UPLOAD_DESTINATION_KEY | ||
| }.freeze | ||
|
|
||
| IVC_CHAMPVA_FORM_ID_BY_CLAIM_TYPE = { | ||
| 'CHAMPVA application' => '10-10D-EXTENDED', | ||
| 'Other Health Insurance' => '10-7959C', | ||
| 'Foreign Medical Program registration' => '10-7959F-1', | ||
| 'Foreign Medical Program claim' => '10-7959F-2', | ||
| 'CHAMPVA claim' => '10-7959A' | ||
| }.freeze | ||
|
|
||
| IVC_CHAMPVA_10_10D_EXTENDED_DOCUMENT_TYPE_OPTIONS = [ | ||
| 'Court ordered adoption papers', | ||
| 'Birth certificate', | ||
| 'Certificate of civil union', | ||
| 'Divorce decree', | ||
| 'Marriage certificate', | ||
| 'Front of Medicare Parts A or B card', | ||
| 'Back of Medicare Parts A or B card', | ||
| 'Front of Medicare Part C card', | ||
| 'Back of Medicare Part C card', | ||
| 'Front of Medicare Part D card', | ||
| 'Back of Medicare Part D card', | ||
| 'Front of health insurance card', | ||
| 'Back of health insurance card', | ||
| 'Other document', | ||
| 'School enrollment certification form', | ||
| 'Enrollment letter', | ||
| 'Letter from the SSA' | ||
| ].map { |option| { 'value' => option, 'label' => option } }.freeze | ||
|
|
||
| IVC_CHAMPVA_DOCUMENT_TYPE_OPTIONS_BY_FORM_ID = { | ||
| '10-10D-EXTENDED' => IVC_CHAMPVA_10_10D_EXTENDED_DOCUMENT_TYPE_OPTIONS | ||
| }.freeze | ||
|
|
||
| IVC_CHAMPVA_ACCEPTED_FILE_TYPES = %w[pdf jpg jpeg png].freeze | ||
|
|
||
| def index | ||
| claims = if Flipper.enabled?(FEATURE_MULTI_CLAIM_PROVIDER, @current_user) | ||
| get_claims_from_providers | ||
| else | ||
| service.get_claims | ||
| end | ||
| champva_enhanced_flow_enabled = Flipper.enabled?(:form1010d_enhanced_flow_enabled, @current_user) | ||
|
|
||
| check_for_birls_id | ||
| check_for_file_number | ||
|
|
||
| claims['data'].each do |claim| | ||
| update_claim_type_language(claim) | ||
| add_upload_metadata(claim, champva_enhanced_flow_enabled:) | ||
| end | ||
|
|
||
| claim_ids = claims['data'].map { |claim| claim['id'] } | ||
|
|
@@ -63,7 +108,9 @@ def show | |
| # Legacy single-provider path: Apply Lighthouse-specific transforms here | ||
| get_legacy_claim(params[:id]) | ||
| end | ||
| champva_enhanced_flow_enabled = Flipper.enabled?(:form1010d_enhanced_flow_enabled, @current_user) | ||
| update_claim_type_language(claim['data']) | ||
| add_upload_metadata(claim['data'], champva_enhanced_flow_enabled:) | ||
|
|
||
| # Document uploads to EVSS require a birls_id; This restriction should | ||
| # be removed when we move to Lighthouse Benefits Documents for document uploads | ||
|
|
@@ -180,6 +227,37 @@ def update_claim_type_language(claim) | |
| end | ||
| end | ||
|
|
||
| def add_upload_metadata(claim, champva_enhanced_flow_enabled: false) | ||
| metadata = build_upload_metadata_for_claim(claim, champva_enhanced_flow_enabled:) | ||
| return if metadata.blank? | ||
|
|
||
| claim['attributes'] ||= {} | ||
| claim['attributes']['uploadMetadata'] = metadata | ||
| end | ||
|
|
||
| def build_upload_metadata_for_claim(claim, champva_enhanced_flow_enabled: false) | ||
| claim_attributes = claim['attributes'] || {} | ||
| provider = claim_attributes['provider'].presence | ||
| destination_key = UPLOAD_DESTINATION_KEY_BY_PROVIDER.fetch(provider, DEFAULT_UPLOAD_DESTINATION_KEY) | ||
|
|
||
| metadata = { 'uploadDestinationKey' => destination_key } | ||
|
|
||
| if destination_key == IVC_CHAMPVA_UPLOAD_DESTINATION_KEY | ||
| form_id = IVC_CHAMPVA_FORM_ID_BY_CLAIM_TYPE[claim_attributes['claimType']] | ||
| metadata['formId'] = form_id if form_id.present? | ||
| metadata['acceptedFileTypes'] = IVC_CHAMPVA_ACCEPTED_FILE_TYPES | ||
| if form_id == '10-10D-EXTENDED' && champva_enhanced_flow_enabled | ||
| metadata['finalizeDestinationKey'] = IVC_CHAMPVA_FINALIZE_DESTINATION_KEY | ||
| metadata['submissionType'] = 'existing' | ||
| end | ||
|
|
||
| document_type_options = IVC_CHAMPVA_DOCUMENT_TYPE_OPTIONS_BY_FORM_ID[form_id] | ||
| metadata['documentTypeOptions'] = document_type_options if document_type_options.present? | ||
| end | ||
|
|
||
| metadata | ||
| end | ||
|
|
||
| def add_evidence_submissions(claim, evidence_submissions) | ||
| non_duplicate_submissions = filter_duplicate_evidence_submissions(evidence_submissions, claim) | ||
| tracked_items = claim['attributes']['trackedItems'] | ||
|
|
@@ -328,7 +406,10 @@ def report_evidence_submission_metrics(endpoint, evidence_submissions) | |
| end | ||
|
|
||
| def fetch_evidence_submissions(claim_ids, endpoint) | ||
| EvidenceSubmission.where(claim_id: claim_ids) | ||
| query_ids = resolve_evidence_submission_claim_ids(claim_ids) | ||
| return EvidenceSubmission.none if query_ids.empty? | ||
|
|
||
| EvidenceSubmission.where(claim_id: query_ids) | ||
| rescue => e | ||
| ::Rails.logger.error( | ||
| "BenefitsClaimsController##{endpoint} Error fetching evidence submissions", | ||
|
|
@@ -342,6 +423,17 @@ def fetch_evidence_submissions(claim_ids, endpoint) | |
| EvidenceSubmission.none | ||
| end | ||
|
|
||
| def resolve_evidence_submission_claim_ids(claim_ids) | ||
| identifiers = Array(claim_ids).compact.map(&:to_s) | ||
| return [] if identifiers.empty? | ||
|
|
||
| numeric_ids = identifiers.grep(/\A\d+\z/).map(&:to_i) | ||
| uuid_ids = identifiers.grep_v(/\A\d+\z/) | ||
| numeric_ids += IvcChampvaForm.where(form_uuid: uuid_ids).pluck(:id) if uuid_ids.any? | ||
|
|
||
| numeric_ids.uniq | ||
| end | ||
|
|
||
| def update_evidence_submissions_for_claim(claim_id, evidence_submissions) | ||
| # Get pending evidence submissions as an ActiveRecord relation | ||
| # PENDING = successfully sent to Lighthouse with request_id, awaiting final status | ||
|
|
@@ -441,30 +533,60 @@ def handle_error(claim_id, response, lighthouse_document_request_ids, error_sour | |
| def add_evidence_submissions_to_claims(claims, all_evidence_submissions, endpoint) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ksantiagoBAH it looks like you can tighten up this method a little bit to avoid disabling this rubocop. See what I did here:
|
||
| return if claims.empty? | ||
|
|
||
| # Group evidence submissions by claim_id for efficient lookup | ||
| evidence_submissions_by_claim = all_evidence_submissions.group_by(&:claim_id) | ||
| evidence_submissions_by_claim_id = all_evidence_submissions.group_by(&:claim_id) | ||
| ivc_form_ids_by_uuid = {} | ||
|
|
||
| # Add evidence submissions to each claim | ||
| claims.each do |claim| | ||
| claim_id = claim['id'].to_i | ||
| evidence_submissions = evidence_submissions_by_claim[claim_id] || [] | ||
| assign_evidence_submissions_to_claims( | ||
| claims, | ||
| evidence_submissions_by_claim_id, | ||
| ivc_form_ids_by_uuid | ||
| ) | ||
| rescue ArgumentError | ||
| ensure_claims_have_evidence_submissions(claims) | ||
| rescue => e | ||
| log_add_evidence_submissions_error(claims, endpoint, e) | ||
| end | ||
|
|
||
| def assign_evidence_submissions_to_claims(claims, evidence_submissions_by_claim_id, ivc_form_ids_by_uuid) | ||
| claims.each do |claim| | ||
| evidence_submissions = evidence_submissions_for_claim( | ||
| claim, | ||
| evidence_submissions_by_claim_id, | ||
| ivc_form_ids_by_uuid | ||
| ) | ||
| claim['attributes']['evidenceSubmissions'] = | ||
| add_evidence_submissions(claim, evidence_submissions) | ||
| end | ||
| rescue => e | ||
| # Log error but don't fail the request - graceful degradation | ||
| # Frontend already handles missing evidenceSubmissions attribute | ||
| end | ||
|
|
||
| def ensure_claims_have_evidence_submissions(claims) | ||
| claims.each do |claim| | ||
| claim['attributes']['evidenceSubmissions'] ||= [] | ||
| end | ||
| end | ||
|
|
||
| def log_add_evidence_submissions_error(claims, endpoint, error) | ||
| claim_ids = claims.map { |claim| claim['id'] } | ||
| ::Rails.logger.error( | ||
| "BenefitsClaimsController##{endpoint} Error adding evidence submissions", | ||
| { | ||
| claim_ids:, | ||
| error_class: e.class.name | ||
| } | ||
| { claim_ids:, error_class: error.class.name } | ||
| ) | ||
| end | ||
|
|
||
| def evidence_submissions_for_claim(claim, evidence_submissions_by_claim_id, ivc_form_ids_by_uuid) | ||
| provider = claim.dig('attributes', 'provider') | ||
| claim_id = claim['id'].to_s | ||
| return non_champva_evidence_submissions(claim_id, evidence_submissions_by_claim_id) if provider != 'ivc_champva' | ||
|
|
||
| ivc_form_ids_by_uuid[claim_id] ||= IvcChampvaForm.where(form_uuid: claim_id).pluck(:id) | ||
| ivc_form_ids_by_uuid[claim_id].flat_map { |form_id| evidence_submissions_by_claim_id[form_id] || [] } | ||
| end | ||
|
|
||
| def non_champva_evidence_submissions(claim_id, evidence_submissions_by_claim_id) | ||
| numeric_claim_id = Integer(claim_id, 10) | ||
| evidence_submissions_by_claim_id[numeric_claim_id] || [] | ||
| end | ||
|
|
||
| def recently_polled_request_ids?(claim_id, request_ids) | ||
| cache_record = EvidenceSubmissionPollStore.find(claim_id.to_s) | ||
| return false if cache_record.nil? | ||
|
|
@@ -500,4 +622,5 @@ def cache_polled_request_ids(claim_id, request_ids) | |
| ) | ||
| end | ||
| end | ||
| # rubocop:enable Metrics/ClassLength | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has your team considered a plan to refactor this class so it's not so long?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm going to refactor these real quick
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored the method level ones, but I will bring this to the team as some tech debt for us to refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!