FIX: more accurate and flexible random assign automation (#222)
- allows to define the number of days within which a user is considered recently assigned - more correct by now using post custom fields
This commit is contained in:
parent
dc8f43fbb1
commit
7747bb81a0
|
@ -86,7 +86,13 @@ en:
|
||||||
assignees_group:
|
assignees_group:
|
||||||
label: Assignees Group
|
label: Assignees Group
|
||||||
minimum_time_between_assignments:
|
minimum_time_between_assignments:
|
||||||
label: Hours between assignments
|
label: Mininmum hours between assignments
|
||||||
|
min_recently_assigned_days:
|
||||||
|
label: Min recently assigned days
|
||||||
|
description: Defaults to 14 days.
|
||||||
|
max_recently_assigned_days:
|
||||||
|
label: Max recently assigned days
|
||||||
|
description: First attempt to exclude users assigned in the last `n` days. If no user left, fallbacks to `min_recently_assigned_days`. Defaults to 180 days.
|
||||||
assigned_topic:
|
assigned_topic:
|
||||||
label: Assigned Topic ID
|
label: Assigned Topic ID
|
||||||
in_working_hours:
|
in_working_hours:
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class RandomAssignUtils
|
class RandomAssignUtils
|
||||||
|
def self.recently_assigned_users_ids(topic_id, from)
|
||||||
|
posts = Post
|
||||||
|
.joins(:user)
|
||||||
|
.where(topic_id: topic_id, action_code: 'assigned')
|
||||||
|
.where('posts.created_at > ?', from)
|
||||||
|
.order(created_at: :desc)
|
||||||
|
usernames = Post.custom_fields_for_ids(posts, [:action_code_who]).map { |_, v| v['action_code_who'] }.uniq
|
||||||
|
User.where(username: usernames).limit(100).pluck(:id)
|
||||||
|
end
|
||||||
|
|
||||||
def self.user_tzinfo(user_id)
|
def self.user_tzinfo(user_id)
|
||||||
timezone = UserOption.where(user_id: user_id).pluck(:timezone).first || "UTC"
|
timezone = UserOption.where(user_id: user_id).pluck(:timezone).first || "UTC"
|
||||||
|
|
||||||
|
|
23
plugin.rb
23
plugin.rb
|
@ -701,6 +701,8 @@ after_initialize do
|
||||||
field :assignees_group, component: :group
|
field :assignees_group, component: :group
|
||||||
field :assigned_topic, component: :text
|
field :assigned_topic, component: :text
|
||||||
field :minimum_time_between_assignments, component: :text
|
field :minimum_time_between_assignments, component: :text
|
||||||
|
field :max_recently_assigned_days, component: :text
|
||||||
|
field :min_recently_assigned_days, component: :text
|
||||||
field :in_working_hours, component: :boolean
|
field :in_working_hours, component: :boolean
|
||||||
|
|
||||||
version 1
|
version 1
|
||||||
|
@ -719,7 +721,7 @@ after_initialize do
|
||||||
next unless group_id = fields.dig('assignees_group', 'value')
|
next unless group_id = fields.dig('assignees_group', 'value')
|
||||||
next unless group = Group.find_by(id: group_id)
|
next unless group = Group.find_by(id: group_id)
|
||||||
|
|
||||||
min_hours = fields.dig('minimum_time_between_assignments', 'value')
|
min_hours = fields.dig('minimum_time_between_assignments', 'value').presence
|
||||||
if min_hours && TopicCustomField
|
if min_hours && TopicCustomField
|
||||||
.where(name: 'assigned_to_id', topic_id: topic_id)
|
.where(name: 'assigned_to_id', topic_id: topic_id)
|
||||||
.where('created_at < ?', min_hours.to_i.hours.ago)
|
.where('created_at < ?', min_hours.to_i.hours.ago)
|
||||||
|
@ -747,23 +749,14 @@ after_initialize do
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
last_assignees_ids = UserAction
|
last_assignees_ids = RandomAssignUtils.recently_assigned_users_ids(
|
||||||
.joins(:user)
|
topic_id,
|
||||||
.where(action_type: UserAction::ASSIGNED, target_topic_id: topic_id)
|
(fields.dig('max_recently_assigned_days', 'value').presence || 180).to_i.days.ago
|
||||||
.where('user_actions.created_at > ?', 6.months.ago)
|
)
|
||||||
.order(created_at: :desc)
|
|
||||||
.limit(group_users_ids.length)
|
|
||||||
.pluck('users.id')
|
|
||||||
.uniq
|
|
||||||
|
|
||||||
users_ids = group_users_ids - last_assignees_ids
|
users_ids = group_users_ids - last_assignees_ids
|
||||||
if users_ids.blank?
|
if users_ids.blank?
|
||||||
recently_assigned_users_ids = UserAction
|
recently_assigned_users_ids = RandomAssignUtils.recently_assigned_users_ids(topic_id, (fields.dig('min_recently_assigned_days', 'value').presence || 14).to_i.days.ago)
|
||||||
.joins(:user)
|
|
||||||
.where(action_type: UserAction::ASSIGNED, target_topic_id: topic_id)
|
|
||||||
.where('user_actions.created_at < ?', 2.weeks.ago)
|
|
||||||
.pluck('users.id')
|
|
||||||
.uniq
|
|
||||||
users_ids = group_users_ids - recently_assigned_users_ids
|
users_ids = group_users_ids - recently_assigned_users_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
require_relative '../support/assign_allowed_group'
|
||||||
|
require 'random_assign_utils'
|
||||||
|
|
||||||
|
describe RandomAssignUtils do
|
||||||
|
before do
|
||||||
|
SiteSetting.assign_enabled = true
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:post) { Fabricate(:post) }
|
||||||
|
|
||||||
|
describe '.recently_assigned_users_ids' do
|
||||||
|
context 'no one has been assigned' do
|
||||||
|
it 'returns an empty array' do
|
||||||
|
assignees_ids = described_class.recently_assigned_users_ids(post.topic_id, 2.months.ago)
|
||||||
|
expect(assignees_ids).to eq([])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'users have been assigned' do
|
||||||
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
let(:assign_allowed_group) { Group.find_by(name: 'staff') }
|
||||||
|
let(:user_1) { Fabricate(:user, groups: [assign_allowed_group]) }
|
||||||
|
let(:user_2) { Fabricate(:user, groups: [assign_allowed_group]) }
|
||||||
|
let(:user_3) { Fabricate(:user, groups: [assign_allowed_group]) }
|
||||||
|
|
||||||
|
it 'returns the recently assigned user ids' do
|
||||||
|
freeze_time 1.months.ago do
|
||||||
|
Assigner.new(post.topic, admin).assign(user_1)
|
||||||
|
Assigner.new(post.topic, admin).assign(user_2)
|
||||||
|
end
|
||||||
|
|
||||||
|
freeze_time 3.months.ago do
|
||||||
|
Assigner.new(post.topic, admin).assign(user_3)
|
||||||
|
end
|
||||||
|
|
||||||
|
assignees_ids = described_class.recently_assigned_users_ids(post.topic_id, 2.months.ago)
|
||||||
|
|
||||||
|
expect(assignees_ids).to contain_exactly(user_1.id, user_2.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue