diff --git a/app/models/current_rating.rb b/app/models/current_rating.rb new file mode 100644 index 00000000000..07d7a86b485 --- /dev/null +++ b/app/models/current_rating.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# CurrentRating provides a Rating implementation based on data returned by the BGS endpoint +# rating_profile.find_current_rating_profile_by_ptcpnt_id. Unlike its siblings RatingAtIssue +# and PromulgatedRating, this fetches a single rating per call. Thus, fetch_in_range and +# ratings_from_bgs_response are left unimplemented, and a few other methods aren't used. + +class CurrentRating < Rating + class << self + def fetch_by_participant_id(participant_id) + from_bgs_hash(BGSService.new.find_current_rating_profile_by_ptcpnt_id(participant_id)) + rescue BGS::ShareError + nil + end + + def from_bgs_hash(data) + new( + participant_id: data[:ptcpnt_vet_id], + profile_date: data[:prfl_dt], + promulgation_date: data[:prmlgn_dt], + rating_profile: data + ) + end + end +end diff --git a/app/models/rating.rb b/app/models/rating.rb index f7270154a59..2b90da330dd 100644 --- a/app/models/rating.rb +++ b/app/models/rating.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -# A Rating can be a PromulgatedRating or a RatingAtIssue. Please see the subclasses for more information. +# A Rating can be a PromulgatedRating, RatingAtIssue, or CurrentRating. +# Please see the subclasses for more information. class Rating include ActiveModel::Model diff --git a/app/services/external_api/bgs_service.rb b/app/services/external_api/bgs_service.rb index 607dd1c23c8..1d44084ac00 100644 --- a/app/services/external_api/bgs_service.rb +++ b/app/services/external_api/bgs_service.rb @@ -409,6 +409,15 @@ def find_contentions_by_claim_id(claim_id) end end + def find_current_rating_profile_by_ptcpnt_id(participant_id) + DBService.release_db_connections + MetricsService.record("BGS: find current rating profile for veteran by participant_id #{participant_id}", + service: :bgs, + name: "rating_profile.find_current_rating_profile_by_ptcpnt_id") do + client.rating_profile.find_current_rating_profile_by_ptcpnt_id(participant_id, true) + end + end + def pay_grade_list DBService.release_db_connections diff --git a/lib/fakes/bgs_service.rb b/lib/fakes/bgs_service.rb index be8dff42885..c17516b5c11 100644 --- a/lib/fakes/bgs_service.rb +++ b/lib/fakes/bgs_service.rb @@ -135,6 +135,16 @@ def find_contentions_by_claim_id(claim_id) format_contentions(contentions) end + # :reek:FeatureEnvy + def find_current_rating_profile_by_ptcpnt_id(participant_id) + record = get_rating_record(participant_id) + fail BGS::ShareError, "No Record Found" if record.blank? + + # We grab the latest promulgated rating, assuming that under the hood BGS also does. + rating = record[:ratings].max_by { |rt| rt[:prmlgn_dt] } + rating_at_issue_profile_data(rating) + end + def format_contentions(contentions) { contentions: contentions.map { |contention| format_contention(contention) } } end diff --git a/spec/models/current_rating_spec.rb b/spec/models/current_rating_spec.rb new file mode 100644 index 00000000000..ecc19cd2686 --- /dev/null +++ b/spec/models/current_rating_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +describe CurrentRating do + describe "#fetch_by_participant_id" do + let(:bgs) { double("BGSService") } + let(:pid) { "12345" } + before do + allow(BGSService).to receive(:new) { bgs } + end + + subject { CurrentRating.fetch_by_participant_id(pid) } + + context "when participant exists" do + let(:bgs_hash) do + { ptcpnt_vet_id: pid } + end + before do + allow(bgs).to receive(:find_current_rating_profile_by_ptcpnt_id).with(pid).and_return(bgs_hash) + end + + it "returns a current rating object" do + expect(subject.participant_id).to eq(pid) + end + end + + context "when participant doesn't exist" do + let(:error) { BGS::ShareError.new_from_message("message", 500) } + before do + allow(bgs).to receive(:find_current_rating_profile_by_ptcpnt_id).with(pid).and_raise(error) + end + + it { is_expected.to be_nil } + end + end + + describe "#from_bgs_hash" do + let(:yesterday) { DateTime.yesterday } + let(:bgs_hash) do + { + ptcpnt_vet_id: "participant ID", + prfl_dt: yesterday, + prmlgn_dt: yesterday, + rating_issues: [ + { + rba_issue_id: "rating issue ID", + decn_txt: "issue description text" + } + ], + disabilities: [ + { + decn_tn: "Service Connected", + dis_sn: "disability ID" + } + ], + associated_claims: { clm_id: "EP claim ID", bnft_clm_tc: "600PRI" } + } + end + + it "hydrates an object that behaves like a Rating" do + rating = CurrentRating.from_bgs_hash(bgs_hash) + expect(rating.participant_id).to eq("participant ID") + expect(rating.profile_date).to eq(yesterday) + expect(rating.promulgation_date).to eq(yesterday) + expect(rating.issues[0].reference_id).to eq("rating issue ID") + expect(rating.associated_end_products[0].claim_id).to eq("EP claim ID") + end + end +end