chore: Use Round Robin service for team assignment (#4237)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
class RoundRobin::AssignmentService
|
||||
pattr_initialize [:conversation]
|
||||
pattr_initialize [:conversation, { allowed_member_ids: [] }]
|
||||
|
||||
def find_assignee
|
||||
round_robin_manage_service.available_agent(priority_list: online_agents)
|
||||
end
|
||||
|
||||
def perform
|
||||
# online agents will get priority
|
||||
new_assignee = round_robin_manage_service.available_agent(priority_list: online_agents)
|
||||
new_assignee = find_assignee
|
||||
conversation.update(assignee: new_assignee) if new_assignee
|
||||
end
|
||||
|
||||
@@ -15,7 +19,7 @@ class RoundRobin::AssignmentService
|
||||
end
|
||||
|
||||
def round_robin_manage_service
|
||||
@round_robin_manage_service ||= RoundRobin::ManageService.new(inbox: conversation.inbox)
|
||||
@round_robin_manage_service ||= RoundRobin::ManageService.new(inbox: conversation.inbox, allowed_member_ids: allowed_member_ids)
|
||||
end
|
||||
|
||||
def round_robin_key
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# If allowed_member_ids are supplied round robin service will only fetch a member from member id
|
||||
# This is used in case of team assignment
|
||||
class RoundRobin::ManageService
|
||||
pattr_initialize [:inbox!]
|
||||
pattr_initialize [:inbox!, { allowed_member_ids: [] }]
|
||||
|
||||
# called on inbox delete
|
||||
def clear_queue
|
||||
@@ -18,9 +20,9 @@ class RoundRobin::ManageService
|
||||
|
||||
def available_agent(priority_list: [])
|
||||
reset_queue unless validate_queue?
|
||||
user_id = get_agent_via_priority_list(priority_list)
|
||||
user_id = get_member_via_priority_list(priority_list)
|
||||
# incase priority list was empty or inbox members weren't present
|
||||
user_id ||= ::Redis::Alfred.rpoplpush(round_robin_key, round_robin_key)
|
||||
user_id ||= fetch_user_id
|
||||
inbox.inbox_members.find_by(user_id: user_id)&.user if user_id.present?
|
||||
end
|
||||
|
||||
@@ -31,17 +33,36 @@ class RoundRobin::ManageService
|
||||
|
||||
private
|
||||
|
||||
def get_agent_via_priority_list(priority_list)
|
||||
def fetch_user_id
|
||||
if allowed_member_ids_in_str.present?
|
||||
user_id = queue.intersection(allowed_member_ids_in_str).pop
|
||||
pop_push_to_queue(user_id)
|
||||
user_id
|
||||
else
|
||||
::Redis::Alfred.rpoplpush(round_robin_key, round_robin_key)
|
||||
end
|
||||
end
|
||||
|
||||
# priority list is usually the members who are online passed from assignmebt service
|
||||
def get_member_via_priority_list(priority_list)
|
||||
return if priority_list.blank?
|
||||
|
||||
# when allowed member ids is passed we will be looking to get members from that list alone
|
||||
priority_list = priority_list.intersection(allowed_member_ids_in_str) if allowed_member_ids_in_str.present?
|
||||
return if priority_list.blank?
|
||||
|
||||
user_id = queue.intersection(priority_list.map(&:to_s)).pop
|
||||
if user_id.present?
|
||||
remove_agent_from_queue(user_id)
|
||||
add_agent_to_queue(user_id)
|
||||
end
|
||||
pop_push_to_queue(user_id)
|
||||
user_id
|
||||
end
|
||||
|
||||
def pop_push_to_queue(user_id)
|
||||
return if user_id.blank?
|
||||
|
||||
remove_agent_from_queue(user_id)
|
||||
add_agent_to_queue(user_id)
|
||||
end
|
||||
|
||||
def validate_queue?
|
||||
return true if inbox.inbox_members.map(&:user_id).sort == queue.map(&:to_i).sort
|
||||
end
|
||||
@@ -53,4 +74,9 @@ class RoundRobin::ManageService
|
||||
def round_robin_key
|
||||
format(::Redis::Alfred::ROUND_ROBIN_AGENTS, inbox_id: inbox.id)
|
||||
end
|
||||
|
||||
def allowed_member_ids_in_str
|
||||
# NOTE: the values which are returned from redis for priority list are string
|
||||
@allowed_member_ids_in_str ||= allowed_member_ids.map(&:to_s)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user