From 4161b239e75861f55dd966b7334c58ce750d17e5 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Mon, 9 Nov 2020 15:30:28 -0500 Subject: [PATCH 1/7] Check an attorney case review in addition to the presence of a valid decision document --- app/models/legacy_appeal.rb | 20 +++++++++ app/models/queues/legacy_work_queue.rb | 2 +- spec/models/legacy_appeal_spec.rb | 60 ++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index 4addc7cd0db..b37bf894c5c 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -975,6 +975,26 @@ def latest_appeal_event TaskEvent.new(version: versions.last) if versions.any? end + # Hacky logic to determine if an acting judge should see judge actions or attorney actions on a case assigne to them + # See https://github.com/department-of-veterans-affairs/caseflow/issues/14886 for details + def assigned_to_acting_judge_as_judge?(acting_judge) + recent_review = attorney_case_review + + if recent_review.present? + # If the acting judge was the attorney on this review, this case is very likely assigned to them to redraft the + # decision. + return false if recent_review.attorney_id == acting_judge.id + + # if the acting judge was the judge on this review, this case is very likely assigned to them to sign the decision + return true if recent_review.reviewing_judge_id == acting_judge.id + end + + # In case an attorney case review does not exist in caseflow or if this acting judge was neither the judge or + # attorney listed in the review, check to see if a decision has already been written for the appeal. If so, assume + # this appeal is assigned to the acting judge as a judge task + vacols_case_review.valid_document_id? + end + private def soc_eligible_for_opt_in?(receipt_date:, covid_flag: false) diff --git a/app/models/queues/legacy_work_queue.rb b/app/models/queues/legacy_work_queue.rb index 266114b4273..e4eb7481793 100644 --- a/app/models/queues/legacy_work_queue.rb +++ b/app/models/queues/legacy_work_queue.rb @@ -31,7 +31,7 @@ def tasks_from_vacols_tasks(vacols_tasks, user = nil) # If the user is a judge they are only assigned JudgeLegacyTasks # If the user is an acting judge, assume any case that already has a decision doc is assigned to them as a judge if user&.vacols_roles&.first&.downcase == "judge" || - (user&.acting_judge_in_vacols? && appeal.vacols_case_review.valid_document_id?) + (user&.acting_judge_in_vacols? && appeal.assigned_to_acting_judge_as_judge?(user)) task_class = JudgeLegacyTask end diff --git a/spec/models/legacy_appeal_spec.rb b/spec/models/legacy_appeal_spec.rb index 8d96c8ce87c..0da56dab3cd 100644 --- a/spec/models/legacy_appeal_spec.rb +++ b/spec/models/legacy_appeal_spec.rb @@ -2993,4 +2993,64 @@ it_behaves_like "latest informal hearing presentation task" end + + describe "#assigned_to_acting_judge_as_judge?" do + shared_examples "assumes the case assigned to the user to draft the decision" do + it { is_expected.to be false } + end + + shared_examples "assumes the case assigned to the user to sign the decision" do + it { is_expected.to be true } + end + + let(:acting_judge) { create(:user, :with_vacols_acting_judge_record) } + let!(:appeal) { create(:legacy_appeal, vacols_case: create(:case, :assigned, user: acting_judge)) } + + subject { appeal.assigned_to_acting_judge_as_judge?(acting_judge) } + + context "when the attorney review process has happened outside of caseflow" do + context "a decision has not been written for the case" do + it_behaves_like "assumes the case assigned to the user to draft the decision" + end + + context "a decision has been written for the case" do + before { VACOLS::Decass.where(defolder: appeal.vacols_id).update_all(dedocid: "02255-00000002") } + + it_behaves_like "assumes the case assigned to the user to sign the decision" + end + end + + context "when the attorney review process has happened within caseflow" do + let(:created_at) { VACOLS::Decass.where(defolder: appeal.vacols_id).first.deadtim } + let!(:case_review) { create(:attorney_case_review, task_id: "#{appeal.vacols_id}-#{created_at}") } + + context "when the user does not match the judge or attorney on the case review" do + it_behaves_like "assumes the case assigned to the user to draft the decision" + + it "falls back to check the presence of a decision document" do + expect_any_instance_of(VACOLS::CaseAssignment).to receive(:valid_document_id?).once + subject + end + end + + context "when the user matches the attorney on the case review" do + before do + case_review.update!(attorney: acting_judge) + expect_any_instance_of(VACOLS::CaseAssignment).not_to receive(:valid_document_id?) + end + + + it_behaves_like "assumes the case assigned to the user to draft the decision" + end + + context "when the user matches the judge on the case review" do + before do + case_review.update!(reviewing_judge: acting_judge) + expect_any_instance_of(VACOLS::CaseAssignment).not_to receive(:valid_document_id?) + end + + it_behaves_like "assumes the case assigned to the user to sign the decision" + end + end + end end From 1ab27680ee418f9f638546fce4a5d16f15d17e77 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Mon, 9 Nov 2020 17:08:28 -0500 Subject: [PATCH 2/7] Memoize vacols call --- app/models/legacy_appeal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index b37bf894c5c..ae662b4c1f6 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -935,7 +935,7 @@ def attorney_case_review end def vacols_case_review - VACOLS::CaseAssignment.latest_task_for_appeal(vacols_id) + @vacols_case_review ||= VACOLS::CaseAssignment.latest_task_for_appeal(vacols_id) end def death_dismissal! From c8861a8861aff094cce3a185c36c70ea674ddafe Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Mon, 9 Nov 2020 17:53:00 -0500 Subject: [PATCH 3/7] Code climate --- app/models/legacy_appeal.rb | 14 ++++++-------- spec/models/legacy_appeal_spec.rb | 1 - 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index ae662b4c1f6..da9e8911dee 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -928,12 +928,12 @@ def paper_case? end def attorney_case_review - # # Created at date will be nil if there is no decass record created for this appeal yet - return unless vacols_case_review&.created_at + task_id = "#{vacols_id}-#{VacolsHelper.day_only_str(vacols_case_review&.created_at)}" - AttorneyCaseReview.find_by(task_id: "#{vacols_id}-#{VacolsHelper.day_only_str(vacols_case_review.created_at)}") + @attorney_case_review ||= AttorneyCaseReview.find_by(task_id: task_id) end + def vacols_case_review @vacols_case_review ||= VACOLS::CaseAssignment.latest_task_for_appeal(vacols_id) end @@ -978,15 +978,13 @@ def latest_appeal_event # Hacky logic to determine if an acting judge should see judge actions or attorney actions on a case assigne to them # See https://github.com/department-of-veterans-affairs/caseflow/issues/14886 for details def assigned_to_acting_judge_as_judge?(acting_judge) - recent_review = attorney_case_review - - if recent_review.present? + if attorney_case_review.present? # If the acting judge was the attorney on this review, this case is very likely assigned to them to redraft the # decision. - return false if recent_review.attorney_id == acting_judge.id + return false if attorney_case_review.attorney_id == acting_judge.id # if the acting judge was the judge on this review, this case is very likely assigned to them to sign the decision - return true if recent_review.reviewing_judge_id == acting_judge.id + return true if attorney_case_review.reviewing_judge_id == acting_judge.id end # In case an attorney case review does not exist in caseflow or if this acting judge was neither the judge or diff --git a/spec/models/legacy_appeal_spec.rb b/spec/models/legacy_appeal_spec.rb index 0da56dab3cd..27344e45b68 100644 --- a/spec/models/legacy_appeal_spec.rb +++ b/spec/models/legacy_appeal_spec.rb @@ -3039,7 +3039,6 @@ expect_any_instance_of(VACOLS::CaseAssignment).not_to receive(:valid_document_id?) end - it_behaves_like "assumes the case assigned to the user to draft the decision" end From a95f84945273e744919579b9d0fba04d1b196f40 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Mon, 9 Nov 2020 18:00:49 -0500 Subject: [PATCH 4/7] Code climate --- app/models/legacy_appeal.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index da9e8911dee..63565b9ed51 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -933,7 +933,6 @@ def attorney_case_review @attorney_case_review ||= AttorneyCaseReview.find_by(task_id: task_id) end - def vacols_case_review @vacols_case_review ||= VACOLS::CaseAssignment.latest_task_for_appeal(vacols_id) end From 5b1dccb0f416c8067d627e39078aa779c8d097d8 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Mon, 9 Nov 2020 18:22:32 -0500 Subject: [PATCH 5/7] Add back nil check --- app/models/legacy_appeal.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index 63565b9ed51..af51633f62f 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -928,7 +928,9 @@ def paper_case? end def attorney_case_review - task_id = "#{vacols_id}-#{VacolsHelper.day_only_str(vacols_case_review&.created_at)}" + return unless vacols_case_review&.created_at + + task_id = "#{vacols_id}-#{VacolsHelper.day_only_str(vacols_case_review.created_at)}" @attorney_case_review ||= AttorneyCaseReview.find_by(task_id: task_id) end From 93766ed85c9bdde426b8455d2a52a03358a4b844 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Thu, 12 Nov 2020 12:31:37 -0500 Subject: [PATCH 6/7] Code review suggestions --- app/models/legacy_appeal.rb | 1 + spec/models/legacy_appeal_spec.rb | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index af51633f62f..c658b26f343 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -928,6 +928,7 @@ def paper_case? end def attorney_case_review + # Created at date will be nil if there is no decass record created for this appeal yet return unless vacols_case_review&.created_at task_id = "#{vacols_id}-#{VacolsHelper.day_only_str(vacols_case_review.created_at)}" diff --git a/spec/models/legacy_appeal_spec.rb b/spec/models/legacy_appeal_spec.rb index 27344e45b68..00c25ccd784 100644 --- a/spec/models/legacy_appeal_spec.rb +++ b/spec/models/legacy_appeal_spec.rb @@ -2995,11 +2995,11 @@ end describe "#assigned_to_acting_judge_as_judge?" do - shared_examples "assumes the case assigned to the user to draft the decision" do + shared_examples "assumes user is the decision drafter" do it { is_expected.to be false } end - shared_examples "assumes the case assigned to the user to sign the decision" do + shared_examples "assumes user is the decision signer" do it { is_expected.to be true } end @@ -3009,14 +3009,14 @@ subject { appeal.assigned_to_acting_judge_as_judge?(acting_judge) } context "when the attorney review process has happened outside of caseflow" do - context "a decision has not been written for the case" do - it_behaves_like "assumes the case assigned to the user to draft the decision" + context "when a decision has not been written for the case" do + it_behaves_like "assumes user is the decision drafter" end - context "a decision has been written for the case" do + context "when a decision has been written for the case" do before { VACOLS::Decass.where(defolder: appeal.vacols_id).update_all(dedocid: "02255-00000002") } - it_behaves_like "assumes the case assigned to the user to sign the decision" + it_behaves_like "assumes user is the decision signer" end end @@ -3025,7 +3025,7 @@ let!(:case_review) { create(:attorney_case_review, task_id: "#{appeal.vacols_id}-#{created_at}") } context "when the user does not match the judge or attorney on the case review" do - it_behaves_like "assumes the case assigned to the user to draft the decision" + it_behaves_like "assumes user is the decision drafter" it "falls back to check the presence of a decision document" do expect_any_instance_of(VACOLS::CaseAssignment).to receive(:valid_document_id?).once @@ -3039,7 +3039,7 @@ expect_any_instance_of(VACOLS::CaseAssignment).not_to receive(:valid_document_id?) end - it_behaves_like "assumes the case assigned to the user to draft the decision" + it_behaves_like "assumes user is the decision drafter" end context "when the user matches the judge on the case review" do @@ -3048,7 +3048,7 @@ expect_any_instance_of(VACOLS::CaseAssignment).not_to receive(:valid_document_id?) end - it_behaves_like "assumes the case assigned to the user to sign the decision" + it_behaves_like "assumes user is the decision signer" end end end From 2637e2319ac530cfd2209d058e981bf702ac5ebe Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Thu, 12 Nov 2020 12:57:25 -0500 Subject: [PATCH 7/7] Code review suggestions but actually save first --- app/models/legacy_appeal.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/models/legacy_appeal.rb b/app/models/legacy_appeal.rb index c658b26f343..0a2c785e388 100644 --- a/app/models/legacy_appeal.rb +++ b/app/models/legacy_appeal.rb @@ -977,21 +977,19 @@ def latest_appeal_event TaskEvent.new(version: versions.last) if versions.any? end - # Hacky logic to determine if an acting judge should see judge actions or attorney actions on a case assigne to them + # Hacky logic to determine if an acting judge should see judge actions or attorney actions on a case assigned to them # See https://github.com/department-of-veterans-affairs/caseflow/issues/14886 for details def assigned_to_acting_judge_as_judge?(acting_judge) + # First try to determine role on the case by inspecting the attorney_case_review, if there is one present. if attorney_case_review.present? - # If the acting judge was the attorney on this review, this case is very likely assigned to them to redraft the - # decision. return false if attorney_case_review.attorney_id == acting_judge.id - # if the acting judge was the judge on this review, this case is very likely assigned to them to sign the decision return true if attorney_case_review.reviewing_judge_id == acting_judge.id end # In case an attorney case review does not exist in caseflow or if this acting judge was neither the judge or # attorney listed in the review, check to see if a decision has already been written for the appeal. If so, assume - # this appeal is assigned to the acting judge as a judge task + # this appeal is assigned to the acting judge as a judge task as a best guess vacols_case_review.valid_document_id? end