2019-08-14 09:48:44 +00:00
|
|
|
class Conversation < ApplicationRecord
|
|
|
|
include Events::Types
|
|
|
|
|
|
|
|
validates :account_id, presence: true
|
|
|
|
validates :inbox_id, presence: true
|
|
|
|
|
2019-10-08 19:45:04 +00:00
|
|
|
enum status: [:open, :resolved]
|
2019-08-14 09:48:44 +00:00
|
|
|
|
|
|
|
scope :latest, -> { order(created_at: :desc) }
|
|
|
|
scope :unassigned, -> { where(assignee_id: nil) }
|
2019-10-08 19:45:04 +00:00
|
|
|
scope :assigned_to, ->(agent) { where(assignee_id: agent.id) }
|
2019-08-14 09:48:44 +00:00
|
|
|
|
|
|
|
belongs_to :account
|
|
|
|
belongs_to :inbox
|
|
|
|
belongs_to :assignee, class_name: 'User', optional: true
|
2019-08-31 06:22:09 +00:00
|
|
|
belongs_to :sender, class_name: 'Contact'
|
2019-08-14 09:48:44 +00:00
|
|
|
|
|
|
|
has_many :messages, dependent: :destroy, autosave: true
|
|
|
|
|
|
|
|
before_create :set_display_id, unless: :display_id?
|
|
|
|
|
|
|
|
after_update :notify_status_change,
|
|
|
|
:create_activity,
|
|
|
|
:send_email_notification_to_assignee
|
|
|
|
|
2019-08-19 08:19:57 +00:00
|
|
|
after_create :send_events, :run_round_robin
|
2019-08-14 09:48:44 +00:00
|
|
|
|
|
|
|
acts_as_taggable_on :labels
|
|
|
|
|
2019-10-08 19:45:04 +00:00
|
|
|
def update_assignee(agent = nil)
|
2019-08-14 09:48:44 +00:00
|
|
|
self.assignee = agent
|
2019-10-08 19:45:04 +00:00
|
|
|
save!
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
2019-10-08 19:45:04 +00:00
|
|
|
def update_labels(labels = nil)
|
2019-08-14 09:48:44 +00:00
|
|
|
self.label_list = labels
|
2019-10-08 19:45:04 +00:00
|
|
|
save!
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def toggle_status
|
2019-10-08 19:45:04 +00:00
|
|
|
self.status = open? ? :resolved : :open
|
|
|
|
save! ? true : false
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def lock!
|
|
|
|
self.locked = true
|
2019-10-08 19:45:04 +00:00
|
|
|
save!
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def unlock!
|
|
|
|
self.locked = false
|
2019-10-08 19:45:04 +00:00
|
|
|
save!
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def unread_messages
|
|
|
|
# +1 is a hack to avoid https://makandracards.com/makandra/1057-why-two-ruby-time-objects-are-not-equal-although-they-appear-to-be
|
|
|
|
# ente budhiparamaya neekam kandit entu tonunu?
|
2019-10-08 19:45:04 +00:00
|
|
|
messages.where('EXTRACT(EPOCH FROM created_at) > (?)', agent_last_seen_at.to_i + 1)
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def unread_incoming_messages
|
2019-10-08 19:45:04 +00:00
|
|
|
messages.incoming.where('EXTRACT(EPOCH FROM created_at) > (?)', agent_last_seen_at.to_i + 1)
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def push_event_data
|
|
|
|
{
|
2019-10-08 19:45:04 +00:00
|
|
|
meta: { sender: sender.push_event_data, assignee: assignee }, id: display_id,
|
|
|
|
messages: [messages.chat.last&.push_event_data], inbox_id: inbox_id, status: status_before_type_cast.to_i,
|
|
|
|
timestamp: created_at.to_i, user_last_seen_at: user_last_seen_at.to_i, agent_last_seen_at: agent_last_seen_at.to_i,
|
2019-08-14 09:48:44 +00:00
|
|
|
unread_count: unread_incoming_messages.count
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def lock_event_data
|
|
|
|
{
|
|
|
|
id: display_id,
|
|
|
|
locked: locked?
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def dispatch_events
|
|
|
|
$dispatcher.dispatch(CONVERSATION_RESOLVED, Time.zone.now, conversation: self)
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_events
|
|
|
|
$dispatcher.dispatch(CONVERSATION_CREATED, Time.zone.now, conversation: self)
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_email_notification_to_assignee
|
2019-10-08 19:45:04 +00:00
|
|
|
AssignmentMailer.conversation_assigned(self, assignee).deliver if assignee_id_changed? && assignee_id.present? && !self_assign?(assignee_id)
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self_assign?(assignee_id)
|
|
|
|
return false unless Current.user
|
2019-10-08 19:45:04 +00:00
|
|
|
|
2019-08-14 09:48:44 +00:00
|
|
|
Current.user.id == assignee_id
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_display_id
|
|
|
|
self.display_id = loop do
|
2019-10-08 19:45:04 +00:00
|
|
|
disp_id = account.conversations.maximum('display_id').to_i + 1
|
2019-08-14 09:48:44 +00:00
|
|
|
break disp_id unless account.conversations.exists?(display_id: disp_id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_activity
|
2019-10-02 13:03:07 +00:00
|
|
|
return unless Current.user
|
2019-08-14 09:48:44 +00:00
|
|
|
|
2019-10-08 19:45:04 +00:00
|
|
|
user_name = Current.user&.name
|
|
|
|
|
|
|
|
create_status_change_message(user_name) if status_changed?
|
|
|
|
create_assignee_change(username) if assignee_id_changed?
|
2019-10-02 13:03:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def status_changed_message
|
|
|
|
return "Conversation was marked resolved by #{Current.user.try(:name)}" if resolved?
|
|
|
|
|
|
|
|
"Conversation was reopened by #{Current.user.try(:name)}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def assignee_changed_message
|
|
|
|
return "Assigned to #{assignee.name} by #{Current.user.try(:name)}" if assignee_id
|
|
|
|
|
|
|
|
"Conversation unassigned by #{Current.user.try(:name)}"
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
|
2019-10-08 19:45:04 +00:00
|
|
|
def activity_message_params(content)
|
2019-08-14 09:48:44 +00:00
|
|
|
{
|
|
|
|
account_id: account_id,
|
|
|
|
inbox_id: inbox_id,
|
|
|
|
message_type: :activity,
|
|
|
|
content: content
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def notify_status_change
|
2019-10-05 09:12:50 +00:00
|
|
|
resolve_conversation if status_changed?
|
|
|
|
dispatcher_dispatch(CONVERSATION_READ) if user_last_seen_at_changed?
|
|
|
|
dispatcher_dispatch(CONVERSATION_LOCK_TOGGLE) if locked_changed?
|
|
|
|
dispatcher_dispatch(ASSIGNEE_CHANGED) if assignee_id_changed?
|
|
|
|
end
|
|
|
|
|
|
|
|
def resolve_conversation
|
|
|
|
if resolved? && assignee.present?
|
|
|
|
dispatcher_dispatch(CONVERSATION_RESOLVED)
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-10-05 09:12:50 +00:00
|
|
|
def dispatcher_dispatch(event_name)
|
|
|
|
$dispatcher.dispatch(event_name, Time.zone.now, conversation: self)
|
|
|
|
end
|
2019-08-14 09:48:44 +00:00
|
|
|
|
|
|
|
def run_round_robin
|
2019-10-08 19:45:04 +00:00
|
|
|
return unless true # conversation.account.has_feature?(round_robin)
|
|
|
|
return unless true # conversation.account.round_robin_enabled?
|
|
|
|
return if assignee
|
|
|
|
|
|
|
|
new_assignee = inbox.next_available_agent
|
|
|
|
update_assignee(new_assignee) if new_assignee
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_status_change_message(user_name)
|
|
|
|
content = if resolved?
|
|
|
|
"Conversation was marked resolved by #{user_name}"
|
|
|
|
else
|
|
|
|
"Conversation was reopened by #{user_name}"
|
|
|
|
end
|
|
|
|
|
|
|
|
messages.create(activity_message_params(content))
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_assignee_change(username)
|
|
|
|
content = if assignee_id
|
|
|
|
"Assigned to #{assignee.name} by #{username}"
|
|
|
|
else
|
|
|
|
"Conversation unassigned by #{username}"
|
|
|
|
end
|
|
|
|
|
|
|
|
messages.create(activity_message_params(content))
|
|
|
|
end
|
|
|
|
|
|
|
|
def resolved_and_assignee?
|
|
|
|
resolved? && assignee.present?
|
2019-08-14 09:48:44 +00:00
|
|
|
end
|
|
|
|
end
|