Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PART 2] Show task assignee name in queue tables #14264

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/models/queue_column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ def task_type_options(tasks)
end

def assignee_options(tasks)
tasks.joins(CachedAppeal.left_join_from_tasks_clause)
.group(:assignee_label).count.each_pair.map do |option, count|
tasks.with_assignees.group("assignees.display_name").count(:all).each_pair.map do |option, count|
label = self.class.format_option_label(option, count)
self.class.filter_option_hash(option, label)
end
Expand Down
11 changes: 6 additions & 5 deletions app/models/serializers/work_queue/task_column_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,15 @@ def self.serialize_attribute?(params, columns)

attribute :assigned_to do |object, params|
columns = [Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name]
assignee = object.assigned_to

if serialize_attribute?(params, columns)
{
css_id: object.assigned_to.try(:css_id),
is_organization: object.assigned_to.is_a?(Organization),
name: object.appeal.assigned_to_location,
type: object.assigned_to.class.name,
id: object.assigned_to.id
css_id: assignee.try(:css_id),
is_organization: assignee.is_a?(Organization),
name: assignee.is_a?(Organization) ? assignee.name : assignee.full_name,
type: assignee.class.name,
id: assignee.id
}
else
{
Expand Down
14 changes: 8 additions & 6 deletions app/models/serializers/work_queue/task_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ class WorkQueue::TaskSerializer
end

attribute :assigned_to do |object|
assignee = object.assigned_to

{
css_id: object.assigned_to.try(:css_id),
is_organization: object.assigned_to.is_a?(Organization),
name: object.appeal.assigned_to_location,
full_name: object.assigned_to.try(:full_name),
type: object.assigned_to.class.name,
id: object.assigned_to.id
css_id: assignee.try(:css_id),
full_name: assignee.try(:full_name),
is_organization: assignee.is_a?(Organization),
name: assignee.is_a?(Organization) ? assignee.name : assignee.full_name,
type: assignee.class.name,
id: assignee.id
}
end

Expand Down
24 changes: 24 additions & 0 deletions app/models/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class << self; undef_method :open; end
)
}

scope :with_assignees, -> { joins(Task.joins_with_assignees_clause) }
ajspotts marked this conversation as resolved.
Show resolved Hide resolved

scope :with_assigners, -> { joins(Task.joins_with_assigners_clause) }
ajspotts marked this conversation as resolved.
Show resolved Hide resolved

scope :with_cached_appeals, -> { joins(Task.joins_with_cached_appeals_clause) }

############################################################################################
Expand Down Expand Up @@ -175,6 +179,26 @@ def create_child_task(parent, current_user, params)
)
end

def assigners_table_clause
"(SELECT id, full_name AS display_name FROM users) AS assigners"
end
ajspotts marked this conversation as resolved.
Show resolved Hide resolved

def joins_with_assigners_clause
"LEFT JOIN #{Task.assigners_table_clause} ON assigners.id = tasks.assigned_by_id"
end

def assignees_table_clause
"(SELECT id, 'Organization' AS type, name AS display_name FROM organizations " \
"UNION " \
"SELECT id, 'User' AS type, full_name AS display_name FROM users)" \
"AS assignees"
end
ajspotts marked this conversation as resolved.
Show resolved Hide resolved

def joins_with_assignees_clause
"INNER JOIN #{Task.assignees_table_clause} ON " \
"assignees.id = tasks.assigned_to_id AND assignees.type = tasks.assigned_to_type"
end

def joins_with_cached_appeals_clause
"left join #{CachedAppeal.table_name} "\
"on #{CachedAppeal.table_name}.appeal_id = #{Task.table_name}.appeal_id "\
Expand Down
6 changes: 4 additions & 2 deletions app/models/task_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def table_column_from_name(column_name)
when Constants.QUEUE_CONFIG.COLUMNS.APPEAL_TYPE.name
"cached_appeal_attributes.case_type"
when Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name
"cached_appeal_attributes.assignee_label"
"assignees.display_name"
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
when Constants.QUEUE_CONFIG.POWER_OF_ATTORNEY_COLUMN_NAME
"cached_appeal_attributes.power_of_attorney_name"
when Constants.QUEUE_CONFIG.SUGGESTED_HEARING_LOCATION_COLUMN_NAME
Expand All @@ -67,7 +67,9 @@ def initialize(args)
end

def filtered_tasks
where_clause.empty? ? tasks : tasks.joins(CachedAppeal.left_join_from_tasks_clause).where(*where_clause)
return tasks if where_clause.empty?

tasks.with_assignees.with_cached_appeals.where(*where_clause)
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
end

# filter_params = ["col=docketNumberColumn&val=legacy|evidence_submission", "col=taskColumn&val=TranslationTask"]
Expand Down
10 changes: 3 additions & 7 deletions app/models/task_sorter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def sorted_tasks

# Always join to the CachedAppeal and users tables because we sometimes need it, joining does not slow down the
# application, and conditional logic to only join sometimes adds unnecessary complexity.
tasks.joins(CachedAppeal.left_join_from_tasks_clause).joins(left_join_from_users_clause).order(order_clause)
tasks.with_assignees.with_assigners.with_cached_appeals.order(order_clause)
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
end

private
Expand Down Expand Up @@ -67,16 +67,12 @@ def default_order_clause
# postgres to use as a reference for sorting as a task's label is not stored in the database.
def task_type_order_clause
task_types_sorted_by_label = Task.descendants.sort_by(&:label).map(&:name)
task_type_sort_position = "type in '#{task_types_sorted_by_label.join(',')}'"
task_type_sort_position = "tasks.type in '#{task_types_sorted_by_label.join(',')}'"
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
"position(#{task_type_sort_position}) #{sort_order}"
end

def assigner_order_clause
"substring(users.full_name,\'([a-zA-Z]+)$\') #{sort_order}"
end

def left_join_from_users_clause
"left join users on users.id = tasks.assigned_by_id"
"substring(assigners.display_name,\'([a-zA-Z]+)$\') #{sort_order}"
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
end

def column_is_valid
Expand Down
4 changes: 2 additions & 2 deletions client/constants/QUEUE_CONFIG.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
"TASK_ASSIGNEE": {
"filterable": true,
"name": "assignedToColumn",
"sorting_table": "cached_appeal_attributes",
"sorting_columns": ["assignee_label"]
"sorting_table": "assignees",
"sorting_columns": ["display_name"]
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
},
"TASK_ASSIGNER": {
"name": "completedToNameColumn"
Expand Down
25 changes: 25 additions & 0 deletions spec/models/queue_column_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,30 @@ def match_encoding(str)
end
end
end

context "for the assignee column" do
let(:column_name) { Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name }
let(:org_1) { create(:organization, name: "Org 1") }
let(:org_2) { create(:organization, name: "Org 2") }
let(:user_1) { create(:user, full_name: "User 1") }
let(:user_2) { create(:user, full_name: "User 2") }
let(:org_1_tasks) { Task.where(id: create_list(:task, 1, assigned_to: org_1).map(&:id)) }
let(:org_2_tasks) { Task.where(id: create_list(:task, 2, assigned_to: org_2).map(&:id)) }
let(:user_1_tasks) { Task.where(id: create_list(:task, 3, assigned_to: user_1).map(&:id)) }
let(:user_2_tasks) { Task.where(id: create_list(:task, 4, assigned_to: user_2).map(&:id)) }
let(:tasks) do
Task.where(id: org_1_tasks.map(&:id) + org_2_tasks.map(&:id) + user_1_tasks.map(&:id) + user_2_tasks.map(&:id))
end

it "returns an array with all present user names" do
[org_1_tasks, org_2_tasks, user_1_tasks, user_2_tasks].each do |task_set|
assignee = task_set.first.assigned_to
name = assignee.is_a?(Organization) ? assignee.name : assignee.full_name
option = QueueColumn.filter_option_hash(name, QueueColumn.format_option_label(name, task_set.count))

expect(subject).to include(option)
end
end
end
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
end
end
28 changes: 11 additions & 17 deletions spec/models/task_filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -378,23 +378,14 @@ def create_cached_appeals_for_tasks(tasks, case_type)

context "when filtering by assignee" do
let(:tasks_per_user) { 3 }
let(:users) { create_list(:user, 3) }
let(:users) do
[create(:user, full_name: "UserA"), create(:user, full_name: "UserB"), create(:user, full_name: "UserZ")]
end
let(:first_user_tasks) { create_list(:ama_task, tasks_per_user, assigned_to: users.first) }
let(:second_user_tasks) { create_list(:ama_task, tasks_per_user, assigned_to: users.second) }
let(:third_user_tasks) { create_list(:ama_task, tasks_per_user, assigned_to: users.third) }
let(:all_tasks) { Task.where(id: (first_user_tasks + second_user_tasks + third_user_tasks).pluck(:id)) }

before do
all_tasks.each do |task|
create(
:cached_appeal,
appeal_type: task.appeal_type,
appeal_id: task.appeal.id,
assignee_label: task.appeal.assigned_to_location
)
end
end

ajspotts marked this conversation as resolved.
Show resolved Hide resolved
context "when filter_params is an empty array" do
let(:filter_params) { [] }

Expand All @@ -411,20 +402,23 @@ def create_cached_appeals_for_tasks(tasks, case_type)
end
end

context "when filter includes the first user's css_id" do
let(:filter_params) { ["col=#{Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name}&val=#{users.first.css_id}"] }
context "when filter includes the first user's name" do
let(:filter_params) do
["col=#{Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name}&val=#{users.first.full_name}"]
end

it "returns only tasks where the closest regional office is Boston" do
expect(subject.map(&:id)).to match_array(first_user_tasks.map(&:id))
end
end

context "when filter includes Boston and Washington" do
context "when filter includes the first and second users' names" do
let(:filter_params) do
["col=#{Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name}&val=#{users.first.css_id}|#{users.second.css_id}"]
["col=#{Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name}&"\
"val=#{users.first.full_name}|#{users.second.full_name}"]
end

it "returns tasks where the closest regional office is Boston or Washington" do
it "returns tasks assigned to the first and second user" do
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
expect(subject.map(&:id)).to match_array((first_user_tasks + second_user_tasks).map(&:id))
end
end
Expand Down
24 changes: 11 additions & 13 deletions spec/models/task_sorter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,22 +233,20 @@

context "when sorting by assigned to column" do
let(:column_name) { Constants.QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name }
let(:tasks) { Task.where(id: create_list(:ama_task, 5).pluck(:id)) }

before do
users = []
5.times do
users.push(create(:user, css_id: Faker::Name.unique.first_name))
end
tasks.each_with_index do |task, index|
user = users[index % 5]
task.update!(assigned_to_id: user.id)
create(:cached_appeal, appeal_id: task.appeal_id, assignee_label: user.css_id)
end
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
let(:org_1) { create(:organization, name: "Org B") }
let(:user_1) { create(:user, full_name: "User Z") }
let(:user_2) { create(:user, full_name: "User A") }
let(:org_1_task) { create(:task, assigned_to: org_1) }
let(:user_1_task) { create(:task, assigned_to: user_1) }
let(:user_2_task) { create(:task, assigned_to: user_2) }
let(:tasks) do
Task.where(id: [org_1_task, user_1_task, user_2_task])
end

it "sorts by assigned to" do
expected_order = tasks.sort_by { |task| task.appeal.assigned_to_location }
expected_order = tasks.sort_by do |task|
task.assigned_to.is_a?(User) ? task.assigned_to.full_name : task.assigned_to.name
end
ajspotts marked this conversation as resolved.
Show resolved Hide resolved
expect(subject.map(&:appeal_id)).to eq(expected_order.map(&:appeal_id))
end
end
Expand Down