From 2231640580b2d78141bd6b304fbda8fc273e11c5 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 11 Aug 2025 20:17:32 +0530 Subject: [PATCH] feat: add conversation assigned event --- app/helpers/reporting_event_helper.rb | 25 +++++++ app/listeners/reporting_event_listener.rb | 83 +++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/app/helpers/reporting_event_helper.rb b/app/helpers/reporting_event_helper.rb index f0a419cc8..d3494b7b6 100644 --- a/app/helpers/reporting_event_helper.rb +++ b/app/helpers/reporting_event_helper.rb @@ -64,6 +64,31 @@ module ReportingEventHelper { format_time(working_hour.open_hour, working_hour.open_minutes) => format_time(working_hour.close_hour, working_hour.close_minutes) } end + def assignee_changed_to_assigned?(previous_changes) + return false unless previous_changes['assignee_id'] + + previous_assignee, current_assignee = previous_changes['assignee_id'] + previous_assignee.nil? && current_assignee.present? + end + + def assignee_changed_to_unassigned?(previous_changes) + return false unless previous_changes['assignee_id'] + + previous_assignee, current_assignee = previous_changes['assignee_id'] + previous_assignee.present? && current_assignee.nil? + end + + def find_last_unassignment_event(conversation) + last_assignment_event = ReportingEvent.where( + conversation_id: conversation.id, + name: 'conversation_assigned' + ).order(event_end_time: :desc).first + + return last_assignment_event if last_assignment_event&.user_id.nil? + + nil + end + def format_time(hour, minute) hour = hour < 10 ? "0#{hour}" : hour minute = minute < 10 ? "0#{minute}" : minute diff --git a/app/listeners/reporting_event_listener.rb b/app/listeners/reporting_event_listener.rb index 7c1ba01c4..0b5d09d2e 100644 --- a/app/listeners/reporting_event_listener.rb +++ b/app/listeners/reporting_event_listener.rb @@ -107,6 +107,31 @@ class ReportingEventListener < BaseListener reporting_event.save! end + def conversation_assigned(event) + conversation = extract_conversation_and_account(event)[0] + previous_changes = event.data[:changed_attributes] || {} + puts "DEBUG: previous_changes = #{previous_changes.inspect}" + return unless previous_changes['assignee_id'] + + puts "DEBUG: assignee_changed_to_assigned? = #{assignee_changed_to_assigned?(previous_changes)}" + puts "DEBUG: assignee_changed_to_unassigned? = #{assignee_changed_to_unassigned?(previous_changes)}" + + if assignee_changed_to_assigned?(previous_changes) + puts 'DEBUG: Creating assignment event' + assignment_time_data = calculate_assignment_time(conversation, previous_changes) + puts "DEBUG: assignment_time_data = #{assignment_time_data.inspect}" + create_assignment_event(conversation, assignment_time_data) + elsif assignee_changed_to_unassigned?(previous_changes) + puts 'DEBUG: Creating unassignment event' + create_unassignment_event(conversation) + else + # Re-assignment: user to different user + puts 'DEBUG: Creating re-assignment event with value 0' + reassignment_data = { value: 0, business_hours_value: 0, start_time: conversation.updated_at } + create_assignment_event(conversation, reassignment_data) + end + end + def conversation_opened(event) conversation = extract_conversation_and_account(event)[0] @@ -148,6 +173,64 @@ class ReportingEventListener < BaseListener reporting_event.save! end + def calculate_assignment_time(conversation, previous_changes) + previous_assignee = previous_changes['assignee_id'][0] + + if previous_assignee.nil? + calculate_time_to_assignment(conversation) + else + # Re-assignment - value is 0 + { value: 0, business_hours_value: 0, start_time: conversation.updated_at } + end + end + + def calculate_time_to_assignment(conversation) + last_unassignment = find_last_unassignment_event(conversation) + + start_time = if last_unassignment + # Assignment after unassignment + last_unassignment.event_end_time + else + # First assignment + conversation.created_at + end + + time_to_assignment = conversation.updated_at.to_i - start_time.to_i + business_hours_value = business_hours(conversation.inbox, start_time, conversation.updated_at) + + { value: time_to_assignment, business_hours_value: business_hours_value, start_time: start_time } + end + + def create_assignment_event(conversation, time_data) + reporting_event = ReportingEvent.new( + name: 'conversation_assigned', + value: time_data[:value], + value_in_business_hours: time_data[:business_hours_value], + account_id: conversation.account_id, + inbox_id: conversation.inbox_id, + user_id: conversation.assignee_id, + conversation_id: conversation.id, + event_start_time: time_data[:start_time], + event_end_time: conversation.updated_at + ) + reporting_event.save! + end + + def create_unassignment_event(conversation) + reporting_event = ReportingEvent.new( + name: 'conversation_assigned', + value: 0, + value_in_business_hours: 0, + account_id: conversation.account_id, + inbox_id: conversation.inbox_id, + user_id: nil, + conversation_id: conversation.id, + event_start_time: conversation.updated_at, + event_end_time: conversation.updated_at + ) + reporting_event.save! + end + def create_bot_resolved_event(conversation, reporting_event) return unless conversation.inbox.active_bot? # We don't want to create a bot_resolved event if there is user interaction on the conversation