Skip to content

Commit

Permalink
Prioritize AOD and CAVC cases during Bulk Assignment (#15125)
Browse files Browse the repository at this point in the history
Resolves #14781

### Description
Prioritize associated cases before bulk assigning tasks.

### Acceptance Criteria
- [ ] Code compiles correctly

Cases are prioritized in the following order for Bulk Assign: 
1. CAVC AOD Cases
2. AOD Cases
3. CAVC Cases
4. Regular appeal stream

### Testing Plan
(See #14501, #14510, and #14523 for reference.)
1. Make BVATWARNER an admin so that the bulk "Assign tasks" button appears
   ```ruby
   OrganizationsUser.make_user_admin(User.find_by(css_id: "BVATWARNER"), HearingsManagement.singleton)
   ```
1. Sign in as BVATWARNER and go to `/organizations/hearings-management`
1. Make some cases AOD or CAVC
   * grant AOD Motion per case -- do [this](#14085 (comment)) as AOD_USER (in an incognito window to avoid logging out BVATWARNER)
   * create a CAVC case (is there a better way?):
      ```ruby
      corres=FactoryBot.create(:correspondent, stafkey:"777");
      folder=FactoryBot.create(:folder, ticknum: "000100777");
      vcase= FactoryBot.create(:case, :type_cavc_remand, :assigned, bfkey: "77777", user: User.find_by(css_id: "BVATWARNER"), correspondent: corres, folder: folder);
      appeal=FactoryBot.create(:legacy_appeal, vacols_case: vcase);

      ht=FactoryBot.create(:hearing_task, appeal: appeal, assigned_by: nil);
      ahdt=FactoryBot.create(:assign_hearing_disposition_task, parent: ht, assigned_by: nil);
      FactoryBot.create(:no_show_hearing_task, parent: ahdt, assigned_by: nil);

      UpdateCachedAppealsAttributesJob.perform_now
      ```
   * create AOD CAVC case (by combining the procedures above)
1. As BVATWARNER, refresh the `/organizations/hearings-management` page to see AOD and CAVC cases
1. Perform bulk "Assign tasks" with "No Show Hearing Task" type and ensure priority cases are assigned first (see the "Assigned" tab)
  • Loading branch information
yoomlam authored Sep 2, 2020
1 parent c4f630d commit 93a23f4
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 16 deletions.
4 changes: 4 additions & 0 deletions app/models/appeal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ def veteran_middle_initial
veteran_middle_name&.first
end

def cavc?
false if cavc == "not implemented for AMA"
end

def cavc
"not implemented for AMA"
end
Expand Down
11 changes: 4 additions & 7 deletions app/models/legacy_appeal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,8 @@ class UnknownLocationError < StandardError; end
end

# To match Appeals AOD behavior
def aod?
aod
end

def advanced_on_docket?
aod
end
alias aod? aod
alias advanced_on_docket? aod

cache_attribute :dic do
issues.map(&:dic).include?(true)
Expand Down Expand Up @@ -787,6 +782,8 @@ def cavc
type == "Court Remand"
end

alias cavc? cavc

# Adding anything to this to_hash can trigger a lazy load which slows down
# welcome gate dramatically. Don't add anything to it without also adding it to
# the query in VACOLS::CaseAssignment.
Expand Down
8 changes: 8 additions & 0 deletions app/models/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ def joins_with_cached_appeals_clause
"on #{CachedAppeal.table_name}.appeal_id = #{Task.table_name}.appeal_id "\
"and #{CachedAppeal.table_name}.appeal_type = #{Task.table_name}.appeal_type"
end

def order_by_appeal_priority_clause
Arel.sql(
"CASE WHEN #{CachedAppeal.table_name}.is_aod = TRUE THEN 0 ELSE 1 END, "\
"CASE WHEN #{CachedAppeal.table_name}.case_type = 'Court Remand' THEN 0 ELSE 1 END, "\
"#{Task.table_name}.created_at"
)
end
end

########################################################################################
Expand Down
24 changes: 16 additions & 8 deletions app/workflows/bulk_task_assignment.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# frozen_string_literal: true

# Assign multiple cases, which are selected based on parameters.
# Cases are prioritized in the following order:
# - CAVC AOD Cases
# - AOD Cases
# - CAVC Cases
# - remaining cases
class BulkTaskAssignment
include ActiveModel::Model

Expand Down Expand Up @@ -37,15 +43,17 @@ def process

def tasks_to_be_assigned
@tasks_to_be_assigned ||= begin
tasks = task_type.constantize
.active.where(assigned_to_id: organization.id)
.limit(task_count).order(:created_at)
tasks = task_type.constantize.active
.where(assigned_to_id: organization.id)
.limit(task_count)
.with_cached_appeals.order(Task.order_by_appeal_priority_clause)
if regional_office
tasks = tasks.joins(
"INNER JOIN appeals ON appeals.id = appeal_id AND appeal_type = '#{Appeal.name}'"
).where("closest_regional_office = ?", regional_office) +
tasks.joins("INNER JOIN legacy_appeals ON legacy_appeals.id = appeal_id \
AND appeal_type = '#{LegacyAppeal.name}'").where("closest_regional_office = ?", regional_office)
tasks = tasks.joins("INNER JOIN appeals ON appeals.id = #{Task.table_name}.appeal_id "\
"AND #{Task.table_name}.appeal_type = '#{Appeal.name}'")
.where("closest_regional_office = ?", regional_office) +
tasks.joins("INNER JOIN legacy_appeals ON legacy_appeals.id = #{Task.table_name}.appeal_id "\
"AND #{Task.table_name}.appeal_type = '#{LegacyAppeal.name}'")
.where("closest_regional_office = ?", regional_office)
end
tasks
end
Expand Down
47 changes: 46 additions & 1 deletion spec/workflows/bulk_task_assignment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
created_at: 1.day.ago)
end

# Even it is the oldest task, it should skip it becasue it is on hold
# Even it is the oldest task, it should skip it because it is on hold
let!(:no_show_hearing_task4) do
create(:no_show_hearing_task,
:on_hold,
Expand Down Expand Up @@ -134,6 +134,51 @@
expect(task_with_legacy_appeal.assigned_by).to eq assigned_by
end
end

def create_no_show_hearing_task_for_appeal(appeal, creation_time = 1.day.ago)
create(:no_show_hearing_task, appeal: appeal, assigned_to: organization, created_at: creation_time)
end

context "when there are priority appeals" do
let(:regional_office) { nil }
let(:task_count) { 20 }

let(:aod_appeal) { create(:appeal, :advanced_on_docket_due_to_motion) }
# Since cavc is not currently supported, ignore CAVC AMA appeals for now; use CAVC legacy appeals for now
let(:aod_legacy_appeal) { create(:legacy_appeal, vacols_case: create(:case, :aod)) }
let(:cavc_legacy_appeal) { create(:legacy_appeal, vacols_case: create(:case, :type_cavc_remand)) }
let(:cavc_aod_legacy_appeal) { create(:legacy_appeal, vacols_case: create(:case, :aod, :type_cavc_remand)) }

before do
create_no_show_hearing_task_for_appeal(aod_appeal, 3.days.ago)
create_no_show_hearing_task_for_appeal(aod_legacy_appeal, 2.days.ago)
create_no_show_hearing_task_for_appeal(cavc_legacy_appeal)
create_no_show_hearing_task_for_appeal(cavc_aod_legacy_appeal)

UpdateCachedAppealsAttributesJob.perform_now
end

let(:expected_appeal_ordering) { [cavc_aod_legacy_appeal, aod_appeal, aod_legacy_appeal, cavc_legacy_appeal] }

subject { BulkTaskAssignment.new(params).process }

it "sorts priority appeals first" do
prioritized_assigned_tasks = subject
expect(prioritized_assigned_tasks.first(4).map(&:appeal)).to eq(expected_appeal_ordering)

appeals_of_returned_tasks = prioritized_assigned_tasks.map(&:appeal)
expect(appeals_of_returned_tasks).to include(no_show_hearing_task1.appeal)
expect(appeals_of_returned_tasks).to include(no_show_hearing_task2.appeal)
expect(appeals_of_returned_tasks).to include(no_show_hearing_task3.appeal)
end

context "when task_count param is less than the number of AOD and CAVC appeals" do
let(:task_count) { 2 }
it "sorts priority appeals first" do
expect(subject.map(&:appeal)).to eq(expected_appeal_ordering.first(task_count))
end
end
end
end
end
end

0 comments on commit 93a23f4

Please sign in to comment.