diff --git a/modules/travel_pay/app/services/travel_pay/claims_client.rb b/modules/travel_pay/app/services/travel_pay/claims_client.rb index e509fb6f78f..bc2fe24c3c2 100644 --- a/modules/travel_pay/app/services/travel_pay/claims_client.rb +++ b/modules/travel_pay/app/services/travel_pay/claims_client.rb @@ -24,6 +24,37 @@ def get_claims(veis_token, btsss_token) end end + ## + # HTTP GET call to the BTSSS 'claims/search-by-appointment-date' endpoint + # API responds with travel pay claims including status for the specified date-range + # + # @params { + # startDate: string ('2024-01-01T12:45:34Z') (Required) + # endDate: string ('2024-01-01T12:45:34Z') (Required) + # pageNumber: int + # pageSize: int + # sortField: string + # sortDirection: string + # } + # @return [TravelPay::Claim] + # + def get_claims_by_date(veis_token, btsss_token, params = {}) + btsss_url = Settings.travel_pay.base_url + correlation_id = SecureRandom.uuid + Rails.logger.debug(message: 'Correlation ID', correlation_id:) + + url_params = params.transform_keys { |k| k.to_s.camelize(:lower) } + + connection(server_url: btsss_url) + # URL subject to change once v1.2 is available (proposed endpoint: '/search') + .get("/api/v1.1/claims/search-by-appointment-date?#{url_params.to_query}") do |req| + req.headers['Authorization'] = "Bearer #{veis_token}" + req.headers['BTSSS-Access-Token'] = btsss_token + req.headers['X-Correlation-ID'] = correlation_id + req.headers.merge!(claim_headers) + end + end + ## # HTTP POST call to the BTSSS 'claims' endpoint # API responds with a new travel pay claim ID diff --git a/modules/travel_pay/app/services/travel_pay/claims_service.rb b/modules/travel_pay/app/services/travel_pay/claims_service.rb index e60912c4b72..2380fe95887 100644 --- a/modules/travel_pay/app/services/travel_pay/claims_service.rb +++ b/modules/travel_pay/app/services/travel_pay/claims_service.rb @@ -21,6 +21,31 @@ def get_claims(params = {}) } end + def get_claims_by_date_range(params = {}) + if params['start_date'] && params['end_date'] + DateTime.parse(params['start_date'].to_s) && DateTime.parse(params['end_date'].to_s) + else + raise ArgumentError, + message: "Both start and end dates are required, got #{params['start_date']}-#{params['end_date']}." + end + + @auth_manager.authorize => { veis_token:, btsss_token: } + faraday_response = client.get_claims_by_date(veis_token, btsss_token, params) + raw_claims = faraday_response.body['data'].deep_dup + + { + data: raw_claims.map do |sc| + sc['claimStatus'] = sc['claimStatus'].underscore.titleize + sc + end + } + rescue Date::Error => e + Rails.logger.debug(message: + "#{e}. Invalid date(s) provided (given: #{params['start_date']} & #{params['end_date']}).") + raise ArgumentError, + message: "#{e}. Invalid date(s) provided (given: #{params['start_date']} & #{params['end_date']})." + end + def get_claim_by_id(claim_id) # ensure claim ID is the right format, allowing any version uuid_all_version_format = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[89ABCD][0-9A-F]{3}-[0-9A-F]{12}$/i diff --git a/modules/travel_pay/spec/services/claims_client_spec.rb b/modules/travel_pay/spec/services/claims_client_spec.rb index 72e5bb208ec..563ddf18fda 100644 --- a/modules/travel_pay/spec/services/claims_client_spec.rb +++ b/modules/travel_pay/spec/services/claims_client_spec.rb @@ -85,6 +85,47 @@ expect(actual_claim_ids).to eq(expected_ids) end + it 'returns response from claims/search endpoint' do + @stubs.get('/api/v1.1/claims/search-by-appointment-date') do + [ + 200, + {}, + { + 'data' => [ + { + 'id' => 'uuid1', + 'claimNumber' => 'TC0000000000001', + 'claimStatus' => 'InProgress', + 'appointmentDateTime' => '2024-01-01T16:45:34.465Z', + 'facilityName' => 'Cheyenne VA Medical Center', + 'createdOn' => '2024-03-22T21:22:34.465Z', + 'modifiedOn' => '2024-01-01T16:44:34.465Z' + }, + { + 'id' => 'uuid3', + 'claimNumber' => 'TC0000000000002', + 'claimStatus' => 'Incomplete', + 'appointmentDateTime' => '2024-02-01T16:45:34.465Z', + 'facilityName' => 'Cheyenne VA Medical Center', + 'createdOn' => '2024-01-22T21:22:34.465Z', + 'modifiedOn' => '2024-02-01T00:00:00.0Z' + } + ] + } + ] + end + + expected = %w[uuid1 uuid3] + + client = TravelPay::ClaimsClient.new + claims_response = client.get_claims_by_date('veis_token', 'btsss_token', + { 'start_date' => '2024-01-01T16:45:34.465Z', + 'end_date' => '2024-02-01T16:45:34.465Z' }) + actual_ids = claims_response.body['data'].pluck('id') + + expect(actual_ids).to eq(expected) + end + # POST create_claim it 'returns a claim ID from the claims endpoint' do claim_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6' diff --git a/modules/travel_pay/spec/services/claims_service_spec.rb b/modules/travel_pay/spec/services/claims_service_spec.rb index f84d4882055..e3ae40d5ccb 100644 --- a/modules/travel_pay/spec/services/claims_service_spec.rb +++ b/modules/travel_pay/spec/services/claims_service_spec.rb @@ -130,6 +130,86 @@ end end + context 'get_claims_by_date_range' do + let(:user) { build(:user) } + let(:claims_by_date_data) do + { + 'data' => [ + { + 'id' => 'uuid1', + 'claimNumber' => 'TC0000000000001', + 'claimStatus' => 'InProgress', + 'appointmentDateTime' => '2024-01-01T16:45:34.465Z', + 'facilityName' => 'Cheyenne VA Medical Center', + 'createdOn' => '2024-03-22T21:22:34.465Z', + 'modifiedOn' => '2024-01-01T16:44:34.465Z' + }, + { + 'id' => 'uuid2', + 'claimNumber' => 'TC0000000000002', + 'claimStatus' => 'InProgress', + 'appointmentDateTime' => '2024-03-01T16:45:34.465Z', + 'facilityName' => 'Cheyenne VA Medical Center', + 'createdOn' => '2024-02-22T21:22:34.465Z', + 'modifiedOn' => '2024-03-01T00:00:00.0Z' + }, + { + 'id' => 'uuid3', + 'claimNumber' => 'TC0000000000002', + 'claimStatus' => 'Incomplete', + 'appointmentDateTime' => '2024-02-01T16:45:34.465Z', + 'facilityName' => 'Cheyenne VA Medical Center', + 'createdOn' => '2024-01-22T21:22:34.465Z', + 'modifiedOn' => '2024-02-01T00:00:00.0Z' + } + ] + } + end + let(:claims_by_date_response) do + Faraday::Response.new( + body: claims_by_date_data + ) + end + + let(:tokens) { { veis_token: 'veis_token', btsss_token: 'btsss_token' } } + + before do + allow_any_instance_of(TravelPay::ClaimsClient) + .to receive(:get_claims_by_date) + .with(tokens[:veis_token], tokens[:btsss_token], { + 'start_date' => '2024-01-01T16:45:34Z', + 'end_date' => '2024-03-01T16:45:34Z' + }) + .and_return(claims_by_date_response) + + auth_manager = object_double(TravelPay::AuthManager.new(123, user), authorize: tokens) + @service = TravelPay::ClaimsService.new(auth_manager) + end + + it 'returns claims that are in the specified date range' do + claims_by_date = @service.get_claims_by_date_range({ + 'start_date' => '2024-01-01T16:45:34Z', + 'end_date' => '2024-03-01T16:45:34Z' + }) + + expect(claims_by_date[:data].count).to equal(3) + end + + it 'throws an Argument exception if both start and end dates are not provided' do + expect { @service.get_claims_by_date_range({ 'start_date' => '2024-01-01T16:45:34.465Z' }) } + .to raise_error(ArgumentError, /Both start and end/i) + end + + it 'throws an exception if dates are invalid' do + expect do + @service.get_claims_by_date_range( + { 'start_date' => '2024-01-01T16:45:34.465Z', 'end_date' => 'banana' } + ) + end + .to raise_error(ArgumentError, /Invalid date/i) + end + end + context 'create_new_claim' do let(:user) { build(:user) } let(:new_claim_data) do