feat: Add rollup read path to report builders
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
class V2::Reports::BaseSummaryBuilder
|
||||
include DateRangeHelper
|
||||
include V2::Reports::Concerns::RollupConditions
|
||||
|
||||
def build
|
||||
load_data
|
||||
@@ -10,7 +11,7 @@ class V2::Reports::BaseSummaryBuilder
|
||||
|
||||
def load_data
|
||||
@conversations_count = fetch_conversations_count
|
||||
load_reporting_events_data
|
||||
use_rollup? ? load_rollup_data : load_reporting_events_data
|
||||
end
|
||||
|
||||
def load_reporting_events_data
|
||||
@@ -34,6 +35,44 @@ class V2::Reports::BaseSummaryBuilder
|
||||
@avg_reply_time = results.transform_values(&:avg_reply_time)
|
||||
end
|
||||
|
||||
def load_rollup_data
|
||||
group_by_key.to_s.split('.').last
|
||||
dimension_type = dimension_type_to_rollup
|
||||
|
||||
# Fetch rollup data grouped by dimension_id
|
||||
rollup_rows = ReportingEventRollup.where(
|
||||
account_id: account.id,
|
||||
dimension_type: dimension_type,
|
||||
date: range.first..range.last
|
||||
).group(:dimension_id).select(
|
||||
'dimension_id',
|
||||
'SUM(CASE WHEN metric = \'resolutions_count\' THEN count ELSE 0 END) as resolved_count',
|
||||
'SUM(CASE WHEN metric = \'resolution_time\' THEN count ELSE 0 END) as resolution_count',
|
||||
'SUM(CASE WHEN metric = \'resolution_time\' THEN sum_value ELSE 0 END) as resolution_sum_value',
|
||||
'SUM(CASE WHEN metric = \'first_response\' THEN count ELSE 0 END) as first_response_count',
|
||||
'SUM(CASE WHEN metric = \'first_response\' THEN sum_value ELSE 0 END) as first_response_sum_value',
|
||||
'SUM(CASE WHEN metric = \'reply_time\' THEN count ELSE 0 END) as reply_count',
|
||||
'SUM(CASE WHEN metric = \'reply_time\' THEN sum_value ELSE 0 END) as reply_sum_value'
|
||||
)
|
||||
|
||||
# Convert to the expected format
|
||||
results = {}
|
||||
rollup_rows.each do |row|
|
||||
results[row.dimension_id] = row
|
||||
end
|
||||
|
||||
@resolved_count = results.transform_values { |r| r.resolved_count.to_i }
|
||||
@avg_resolution_time = results.transform_values do |r|
|
||||
r.resolution_count.to_i.zero? ? nil : (r.resolution_sum_value.to_f / r.resolution_count.to_i)
|
||||
end
|
||||
@avg_first_response_time = results.transform_values do |r|
|
||||
r.first_response_count.to_i.zero? ? nil : (r.first_response_sum_value.to_f / r.first_response_count.to_i)
|
||||
end
|
||||
@avg_reply_time = results.transform_values do |r|
|
||||
r.reply_count.to_i.zero? ? nil : (r.reply_sum_value.to_f / r.reply_count.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
def reporting_events
|
||||
@reporting_events ||= account.reporting_events.where(created_at: range)
|
||||
end
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
class V2::Reports::Timeseries::AverageReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
def timeseries
|
||||
use_rollup? ? rollup_timeseries : raw_timeseries
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
use_rollup? ? rollup_aggregate_value : raw_aggregate_value
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def raw_timeseries
|
||||
grouped_average_time = reporting_events.average(average_value_key)
|
||||
grouped_event_count = reporting_events.count
|
||||
grouped_average_time.each_with_object([]) do |element, arr|
|
||||
@@ -12,11 +22,90 @@ class V2::Reports::Timeseries::AverageReportBuilder < V2::Reports::Timeseries::B
|
||||
end
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
def rollup_timeseries
|
||||
dimension_type = dimension_type_to_rollup
|
||||
dimension_id = dimension_id_for_rollup
|
||||
metric = metric_to_rollup_metric(params[:metric])
|
||||
|
||||
rollup_rows = ReportingEventRollup.where(
|
||||
account_id: account.id,
|
||||
metric: metric,
|
||||
dimension_type: dimension_type,
|
||||
dimension_id: dimension_id,
|
||||
date: range.first..range.last
|
||||
)
|
||||
|
||||
group_and_aggregate_rollup(rollup_rows)
|
||||
end
|
||||
|
||||
def raw_aggregate_value
|
||||
object_scope.average(average_value_key)
|
||||
end
|
||||
|
||||
private
|
||||
def rollup_aggregate_value
|
||||
dimension_type = dimension_type_to_rollup
|
||||
dimension_id = dimension_id_for_rollup
|
||||
metric = metric_to_rollup_metric(params[:metric])
|
||||
|
||||
result = ReportingEventRollup.where(
|
||||
account_id: account.id,
|
||||
metric: metric,
|
||||
dimension_type: dimension_type,
|
||||
dimension_id: dimension_id,
|
||||
date: range.first..range.last
|
||||
).pluck(Arel.sql('SUM(count), SUM(sum_value)'))
|
||||
.first
|
||||
|
||||
return nil if result.blank? || result[0].to_i.zero?
|
||||
|
||||
result[1].to_f / result[0].to_i
|
||||
end
|
||||
|
||||
def dimension_id_for_rollup
|
||||
case params[:type].to_s
|
||||
when 'account'
|
||||
account.id
|
||||
when 'agent'
|
||||
params[:id].to_i
|
||||
when 'inbox'
|
||||
params[:id].to_i
|
||||
when 'team'
|
||||
params[:id].to_i
|
||||
end
|
||||
end
|
||||
|
||||
def group_and_aggregate_rollup(rollup_rows)
|
||||
grouped_data = {}
|
||||
|
||||
rollup_rows.each do |row|
|
||||
date_key = case group_by
|
||||
when 'day'
|
||||
row.date
|
||||
when 'week'
|
||||
row.date.beginning_of_week(:monday)
|
||||
when 'month'
|
||||
row.date.beginning_of_month
|
||||
when 'year'
|
||||
row.date.beginning_of_year
|
||||
else
|
||||
row.date
|
||||
end
|
||||
|
||||
grouped_data[date_key] ||= { count: 0, sum_value: 0.0 }
|
||||
grouped_data[date_key][:count] += row.count
|
||||
grouped_data[date_key][:sum_value] += row.sum_value
|
||||
end
|
||||
|
||||
grouped_data.each_with_object([]) do |(date_key, data), arr|
|
||||
next if data[:count].zero?
|
||||
|
||||
arr << {
|
||||
value: data[:sum_value] / data[:count],
|
||||
timestamp: date_key.in_time_zone(timezone).to_i,
|
||||
count: data[:count]
|
||||
}
|
||||
end.sort_by { |h| h[:timestamp] }
|
||||
end
|
||||
|
||||
def event_name
|
||||
metric_to_event_name = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
include TimezoneHelper
|
||||
include DateRangeHelper
|
||||
include V2::Reports::Concerns::RollupConditions
|
||||
DEFAULT_GROUP_BY = 'day'.freeze
|
||||
|
||||
pattr_initialize :account, :params
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
class V2::Reports::Timeseries::CountReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
def timeseries
|
||||
use_rollup? ? rollup_timeseries : raw_timeseries
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
use_rollup? ? rollup_aggregate_value : raw_aggregate_value
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def raw_timeseries
|
||||
grouped_count.each_with_object([]) do |element, arr|
|
||||
event_date, event_count = element
|
||||
|
||||
@@ -11,11 +21,85 @@ class V2::Reports::Timeseries::CountReportBuilder < V2::Reports::Timeseries::Bas
|
||||
end
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
def rollup_timeseries
|
||||
metric = metric_to_rollup_metric(params[:metric])
|
||||
return [] if metric.blank?
|
||||
|
||||
dimension_type = dimension_type_to_rollup
|
||||
dimension_id = dimension_id_for_rollup
|
||||
|
||||
rollup_rows = ReportingEventRollup.where(
|
||||
account_id: account.id,
|
||||
metric: metric,
|
||||
dimension_type: dimension_type,
|
||||
dimension_id: dimension_id,
|
||||
date: range.first..range.last
|
||||
)
|
||||
|
||||
group_and_aggregate_rollup_counts(rollup_rows)
|
||||
end
|
||||
|
||||
def raw_aggregate_value
|
||||
object_scope.count
|
||||
end
|
||||
|
||||
private
|
||||
def rollup_aggregate_value
|
||||
metric = metric_to_rollup_metric(params[:metric])
|
||||
return 0 if metric.blank?
|
||||
|
||||
dimension_type = dimension_type_to_rollup
|
||||
dimension_id = dimension_id_for_rollup
|
||||
|
||||
ReportingEventRollup.where(
|
||||
account_id: account.id,
|
||||
metric: metric,
|
||||
dimension_type: dimension_type,
|
||||
dimension_id: dimension_id,
|
||||
date: range.first..range.last
|
||||
).sum(:count).to_i
|
||||
end
|
||||
|
||||
def dimension_id_for_rollup
|
||||
case params[:type].to_s
|
||||
when 'account'
|
||||
account.id
|
||||
when 'agent'
|
||||
params[:id].to_i
|
||||
when 'inbox'
|
||||
params[:id].to_i
|
||||
when 'team'
|
||||
params[:id].to_i
|
||||
end
|
||||
end
|
||||
|
||||
def group_and_aggregate_rollup_counts(rollup_rows)
|
||||
grouped_data = {}
|
||||
|
||||
rollup_rows.each do |row|
|
||||
date_key = case group_by
|
||||
when 'day'
|
||||
row.date
|
||||
when 'week'
|
||||
row.date.beginning_of_week(:monday)
|
||||
when 'month'
|
||||
row.date.beginning_of_month
|
||||
when 'year'
|
||||
row.date.beginning_of_year
|
||||
else
|
||||
row.date
|
||||
end
|
||||
|
||||
grouped_data[date_key] ||= 0
|
||||
grouped_data[date_key] += row.count
|
||||
end
|
||||
|
||||
grouped_data.each_with_object([]) do |(date_key, count), arr|
|
||||
arr << {
|
||||
value: count,
|
||||
timestamp: date_key.in_time_zone(timezone).to_i
|
||||
}
|
||||
end.sort_by { |h| h[:timestamp] }
|
||||
end
|
||||
|
||||
def metric
|
||||
@metric ||= params[:metric]
|
||||
|
||||
Reference in New Issue
Block a user