Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
class Sla::EvaluateAppliedSlaService
|
||||
pattr_initialize [:applied_sla!]
|
||||
|
||||
def perform
|
||||
check_sla_thresholds
|
||||
|
||||
# We will calculate again in the next iteration
|
||||
return unless applied_sla.conversation.resolved?
|
||||
|
||||
# after conversation is resolved, we will check if the SLA was hit or missed
|
||||
handle_hit_sla(applied_sla)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_sla_thresholds
|
||||
[:first_response_time_threshold, :next_response_time_threshold, :resolution_time_threshold].each do |threshold|
|
||||
next if applied_sla.sla_policy.send(threshold).blank?
|
||||
|
||||
send("check_#{threshold}", applied_sla, applied_sla.conversation, applied_sla.sla_policy)
|
||||
end
|
||||
end
|
||||
|
||||
def still_within_threshold?(threshold)
|
||||
Time.zone.now.to_i < threshold
|
||||
end
|
||||
|
||||
def check_first_response_time_threshold(applied_sla, conversation, sla_policy)
|
||||
threshold = conversation.created_at.to_i + sla_policy.first_response_time_threshold.to_i
|
||||
return if first_reply_was_within_threshold?(conversation, threshold)
|
||||
return if still_within_threshold?(threshold)
|
||||
|
||||
handle_missed_sla(applied_sla, 'frt')
|
||||
end
|
||||
|
||||
def first_reply_was_within_threshold?(conversation, threshold)
|
||||
conversation.first_reply_created_at.present? && conversation.first_reply_created_at.to_i <= threshold
|
||||
end
|
||||
|
||||
def check_next_response_time_threshold(applied_sla, conversation, sla_policy)
|
||||
# still waiting for first reply, so covered under first response time threshold
|
||||
return if conversation.first_reply_created_at.blank?
|
||||
# Waiting on customer response, no need to check next response time threshold
|
||||
return if conversation.waiting_since.blank?
|
||||
|
||||
threshold = conversation.waiting_since.to_i + sla_policy.next_response_time_threshold.to_i
|
||||
return if still_within_threshold?(threshold)
|
||||
|
||||
handle_missed_sla(applied_sla, 'nrt')
|
||||
end
|
||||
|
||||
def get_last_message_id(conversation)
|
||||
# TODO: refactor the method to fetch last message without reply
|
||||
conversation.messages.where(message_type: :incoming).last&.id
|
||||
end
|
||||
|
||||
def already_missed?(applied_sla, type, meta = {})
|
||||
SlaEvent.exists?(applied_sla: applied_sla, event_type: type, meta: meta)
|
||||
end
|
||||
|
||||
def check_resolution_time_threshold(applied_sla, conversation, sla_policy)
|
||||
return if conversation.resolved?
|
||||
|
||||
threshold = conversation.created_at.to_i + sla_policy.resolution_time_threshold.to_i
|
||||
return if still_within_threshold?(threshold)
|
||||
|
||||
handle_missed_sla(applied_sla, 'rt')
|
||||
end
|
||||
|
||||
def handle_missed_sla(applied_sla, type, meta = {})
|
||||
meta = { message_id: get_last_message_id(applied_sla.conversation) } if type == 'nrt'
|
||||
return if already_missed?(applied_sla, type, meta)
|
||||
|
||||
create_sla_event(applied_sla, type, meta)
|
||||
Rails.logger.warn "SLA #{type} missed for conversation #{applied_sla.conversation.id} " \
|
||||
"in account #{applied_sla.account_id} " \
|
||||
"for sla_policy #{applied_sla.sla_policy.id}"
|
||||
|
||||
applied_sla.update!(sla_status: 'active_with_misses') if applied_sla.sla_status != 'active_with_misses'
|
||||
end
|
||||
|
||||
def handle_hit_sla(applied_sla)
|
||||
if applied_sla.active?
|
||||
applied_sla.update!(sla_status: 'hit')
|
||||
Rails.logger.info "SLA hit for conversation #{applied_sla.conversation.id} " \
|
||||
"in account #{applied_sla.account_id} " \
|
||||
"for sla_policy #{applied_sla.sla_policy.id}"
|
||||
else
|
||||
applied_sla.update!(sla_status: 'missed')
|
||||
Rails.logger.info "SLA missed for conversation #{applied_sla.conversation.id} " \
|
||||
"in account #{applied_sla.account_id} " \
|
||||
"for sla_policy #{applied_sla.sla_policy.id}"
|
||||
end
|
||||
end
|
||||
|
||||
def create_sla_event(applied_sla, event_type, meta = {})
|
||||
SlaEvent.create!(
|
||||
applied_sla: applied_sla,
|
||||
conversation: applied_sla.conversation,
|
||||
event_type: event_type,
|
||||
meta: meta,
|
||||
account: applied_sla.account,
|
||||
inbox: applied_sla.conversation.inbox,
|
||||
sla_policy: applied_sla.sla_policy
|
||||
)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user