Update report controller to use the new reports builder

This commit is contained in:
Pranav
2024-05-15 20:37:54 -07:00
parent cbdc5b1ab0
commit 08834b6016
5 changed files with 183 additions and 1 deletions
+32
View File
@@ -0,0 +1,32 @@
class V2::NewReportBuilder
include DateRangeHelper
pattr_initialize :account, :params
AVG_METRICS = %w[avg_first_response_time avg_resolution_time reply_time].freeze
COUNT_METRICS = %w[conversations_count incoming_messages_count outgoing_messages_count resolutions_count bot_resolutions_count
bot_handoffs_count].freeze
DEFAULT_GROUP_BY = 'day'.freeze
AGENT_RESULTS_PER_PAGE = 25
def build
builder_class = case params[:metric]
when *AVG_METRICS
V2::Reports::Timeseries::AverageReportBuilder
when *COUNT_METRICS
V2::Reports::Timeseries::MetricCountReportBuilder
else
log_invalid_metric
return {}
end
builder_class.new(account, params).build
end
private
def log_invalid_metric
Rails.logger.error "ReportBuilder: Invalid metric - #{params[:metric]}"
end
end
@@ -0,0 +1,40 @@
class V2::Reports::Timeseries::AverageReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
def build
grouped_average_time = reporting_events.average(average_value_key)
grouped_event_count = reporting_events.count
grouped_average_time.each_with_object([]) do |element, arr|
event_date, average_time = element
arr << {
value: average_time,
timestamp: event_date.to_time.to_i,
count: grouped_event_count[event_date]
}
end
end
private
def event_name
metric_to_event_name = {
avg_first_response_time: :first_response,
avg_resolution_time: :conversation_resolved,
reply_time: :reply_time
}
metric_to_event_name[params[:metric].to_sym]
end
def reporting_events
object_scope = scope.reporting_events.where(name: event_name)
@grouped_values = object_scope.group_by_period(
group_by,
:created_at,
default_value: 0,
permit: %w[day week month year hour],
time_zone: timezone
)
end
def average_value_key
@average_value_key ||= params[:business_hours].present? ? :value_in_business_hours : :value
end
end
@@ -0,0 +1,49 @@
class V2::Reports::Timeseries::BaseTimeseriesBuilder
include DateRangeHelper
DEFAULT_GROUP_BY = 'day'.freeze
pattr_initialize :account, :params
def scope
case params[:type]
when :account
account
when :inbox
inbox
when :agent
user
when :label
label
when :team
team
end
end
def inbox
@inbox ||= account.inboxes.find(params[:id])
end
def user
@user ||= account.users.find(params[:id])
end
def label
@label ||= account.labels.find(params[:id])
end
def team
@team ||= account.teams.find(params[:id])
end
def group_by
@group_by ||= params[:group_by] || DEFAULT_GROUP_BY
end
def timezone
@timezone ||= ActiveSupport::TimeZone[timezone_offset]&.name
end
def timezone_offset
@timezone_offset ||= params.fetch(:timezone_offset, 0).to_f
end
end
@@ -0,0 +1,61 @@
class V2::Reports::Timeseries::MetricCountReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
def build
grouped_count.each_with_object([]) do |element, arr|
event_date, event_count = element
arr << { value: event_count, timestamp: event_date.to_time.to_i }
end
end
private
def metric
@metric ||= params[:metric]
end
def object_scope
send("scope_for_#{metric}")
end
def scope_for_conversations_count
scope.conversations.where(account_id: account.id, created_at: range)
end
def scope_for_incoming_messages_count
scope.messages.where(account_id: account.id, created_at: range).incoming.unscope(:order)
end
def scope_for_outgoing_messages_count
scope.messages.where(account_id: account.id, created_at: range).outgoing.unscope(:order)
end
def scope_for_resolutions_count
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
name: :conversation_resolved,
conversations: { status: :resolved }, created_at: range
).distinct
end
def scope_for_bot_resolutions_count
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
name: :conversation_bot_resolved,
conversations: { status: :resolved }, created_at: range
).distinct
end
def scope_for_bot_handoffs_count
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
name: :conversation_bot_handoff,
created_at: range
).distinct
end
def grouped_count
@grouped_values = object_scope.group_by_period(
group_by,
:created_at,
default_value: 0,
permit: %w[day week month year hour],
time_zone: timezone
).count
end
end
@@ -5,7 +5,7 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
before_action :check_authorization
def index
builder = V2::ReportBuilder.new(Current.account, report_params)
builder = V2::NewReportBuilder.new(Current.account, report_params)
data = builder.build
render json: data
end