Skip to content
10 changes: 9 additions & 1 deletion lib/unified_health_data/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,16 @@ def get_immunizations
# Use of this is behind va_online_scheduling_uhd_avs_metadata flipper
def get_all_avs_metadata(start_date:, end_date:) # rubocop:disable Metrics/MethodLength
validate_icn!
start_d = (start_date || default_start_date).to_s
end_d = (end_date || default_end_date).to_s

if start_d > end_d
Rails.logger.error("UHD: start_d not before end_d | start_d: #{start_d}, end_d: #{end_d}")
return [[], []]
end
Comment thread
eselkin marked this conversation as resolved.

with_monitoring do
response = uhd_client.get_all_avs(patient_id: @user.icn, start_date:, end_date:)
response = uhd_client.get_all_avs(patient_id: @user.icn, start_date: start_d, end_date: end_d)
# SCDF returns a bundle: DocumentReference, Encounter, and other types.
body = response.body
if body.nil? || !body.is_a?(Hash) || body['entry'].blank?
Expand Down
27 changes: 18 additions & 9 deletions modules/vaos/app/services/vaos/v2/appointments_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,10 @@ def get_appointment(appointment_id, include = {}, tp_client = 'vagov')
# We always fetch facility and clinic information when getting a single appointment
include[:facilities] = true
include[:clinics] = true
start_dt = appointment[:start]&.to_datetime
should_fetch_avs = include[:avs] && start_dt&.past?

avs_metadata = fetch_all_avs_metadata(appointment[:start]&.to_datetime, [appointment],
include_avs: include[:avs])
avs_metadata = fetch_all_avs_metadata(start_dt, [appointment], include_avs: should_fetch_avs)
prepare_appointment(appointment, include, avs_metadata)

check_appointments_migration_override([appointment])
Expand Down Expand Up @@ -498,22 +499,30 @@ def extract_facility_identifiers(appointments)
# Returns a hash indexed by appointment id (without any prefix like CERNER)
#
# @return [Hash{String => Array<UnifiedHealthData::AfterVisitSummary>}]
def fetch_all_avs_metadata(start_date, appointments = [], include_avs: false)
def fetch_all_avs_metadata(start_date, appointments = [], include_avs: false) # rubocop:disable Metrics/MethodLength
return {} unless include_avs
return {} unless Flipper.enabled?(:va_online_scheduling_uhd_avs_metadata, user) &&
Flipper.enabled?(APPOINTMENTS_FETCH_OH_AVS, user) &&
appointments.any? { |appt| VAOS::AppointmentsHelper.cerner?(appt) }
return {} if user.icn.nil? || !start_date.respond_to?(:to_date)

start_date_str = start_date.to_date.to_s
end_date_str = Time.zone.today.to_s
doc_refs, encounters = unified_health_data_service.get_all_avs_metadata(start_date: start_date_str,
end_date: end_date_str)
start_date = start_date.to_date
end_date = Time.zone.today

return {} if start_date > end_date

doc_refs, encounters = unified_health_data_service.get_all_avs_metadata(start_date:, end_date:)
clinical_notes_adapter.build_avs_metadata_by_appointment(encounters, doc_refs)
rescue => e
err_stack = e.backtrace.reject { |line| line.include?('gems') }.compact.join("\n ")
Rails.logger.error("VAOS: Error retrieving AVS metadata for user #{user.user_account_uuid}:" \
"#{e.class}, #{e.message} \n #{err_stack}")
original_status = e.respond_to?(:original_status) ? e.original_status : nil
Rails.logger.error(
"VAOS: Error retrieving AVS metadata for user #{user.user_account_uuid}:" \
"#{e.class}, #{e.message}" \
" | start_date: #{start_date}, end_date: #{end_date}" \
" | upstream_status: #{original_status}" \
" \n #{err_stack}"
)
{}
end

Expand Down
18 changes: 18 additions & 0 deletions modules/vaos/spec/requests/vaos/v2/appointments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,24 @@ def stub_clinics
end
end

it 'does not fetch avs when OH appointment is in the future even if avs is requested' do
Timecop.freeze(DateTime.parse('2023-09-01T12:00:00Z')) do
VCR.use_cassette('vaos/v2/appointments/get_appointment_200_with_facility_200_with_avs_cerner',
match_requests_on: %i[method path query]) do
allow(Rails.logger).to receive(:info).at_least(:once)
expect_any_instance_of(VAOS::V2::AppointmentsService).to receive(:fetch_all_avs_metadata)
.with(anything, anything, include_avs: false).and_call_original

get '/vaos/v2/appointments/70060?_include=avs', headers: inflection_header
expect(response).to have_http_status(:ok)
data = JSON.parse(response.body)['data']

expect(data['id']).to eq('70060')
expect(data['attributes']['avsPdf']).to be_nil
end
end
end

it 'has access and returns appointment with OH avs' do
avs_show_metadata = {
'523938333130383130' => [
Expand Down
21 changes: 21 additions & 0 deletions spec/lib/unified_health_data/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,27 @@
returned_types = all_returned.map { |entry| entry['resourceType'] }.uniq
expect(returned_types).to contain_exactly('DocumentReference', 'Encounter')
end

it 'returns empty arrays when start_date is after end_date' do
expect_any_instance_of(UnifiedHealthData::Client).not_to receive(:get_all_avs)
result = service.get_all_avs_metadata(start_date: '2025-12-31', end_date: '2025-01-01')
expect(result).to eq([[], []])
end

it 'does not short-circuit when start_date equals end_date' do
result = service.get_all_avs_metadata(start_date: '2025-06-15', end_date: '2025-06-15')
doc_refs, encounters = result
expect(doc_refs.size).to eq(2)
expect(encounters.size).to eq(2)
end

it 'accepts Date objects for start_date and end_date' do
result = service.get_all_avs_metadata(start_date: Date.new(2025, 1, 1), end_date: Date.new(2025, 12, 31))

doc_refs, encounters = result
expect(doc_refs.size).to eq(2)
expect(encounters.size).to eq(2)
end
end

describe '#get_avs_binary_data' do
Expand Down
Loading