feat: Add inbox-label matrix report endpoint (#13394)
This PR added new API endpoint GET /api/v2/accounts/:account_id/reports/inbox_label_matrix that returns conversation counts grouped by inbox and label in a matrix format. Supports optional filtering by date range, inbox_ids, and label_ids. --------- Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
65
app/builders/v2/reports/inbox_label_matrix_builder.rb
Normal file
65
app/builders/v2/reports/inbox_label_matrix_builder.rb
Normal file
@@ -0,0 +1,65 @@
|
||||
class V2::Reports::InboxLabelMatrixBuilder
|
||||
include DateRangeHelper
|
||||
|
||||
attr_reader :account, :params
|
||||
|
||||
def initialize(account:, params:)
|
||||
@account = account
|
||||
@params = params
|
||||
end
|
||||
|
||||
def build
|
||||
{
|
||||
inboxes: filtered_inboxes.map { |inbox| { id: inbox.id, name: inbox.name } },
|
||||
labels: filtered_labels.map { |label| { id: label.id, title: label.title } },
|
||||
matrix: build_matrix
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filtered_inboxes
|
||||
@filtered_inboxes ||= begin
|
||||
inboxes = account.inboxes
|
||||
inboxes = inboxes.where(id: params[:inbox_ids]) if params[:inbox_ids].present?
|
||||
inboxes.order(:name).to_a
|
||||
end
|
||||
end
|
||||
|
||||
def filtered_labels
|
||||
@filtered_labels ||= begin
|
||||
labels = account.labels
|
||||
labels = labels.where(id: params[:label_ids]) if params[:label_ids].present?
|
||||
labels.order(:title).to_a
|
||||
end
|
||||
end
|
||||
|
||||
def conversation_filter
|
||||
filter = { account_id: account.id }
|
||||
filter[:created_at] = range if range.present?
|
||||
filter[:inbox_id] = params[:inbox_ids] if params[:inbox_ids].present?
|
||||
filter
|
||||
end
|
||||
|
||||
def fetch_grouped_counts
|
||||
label_names = filtered_labels.map(&:title)
|
||||
return {} if label_names.empty?
|
||||
|
||||
ActsAsTaggableOn::Tagging
|
||||
.joins('INNER JOIN conversations ON taggings.taggable_id = conversations.id')
|
||||
.joins('INNER JOIN tags ON taggings.tag_id = tags.id')
|
||||
.where(taggable_type: 'Conversation', context: 'labels', conversations: conversation_filter)
|
||||
.where(tags: { name: label_names })
|
||||
.group('conversations.inbox_id', 'tags.name')
|
||||
.count
|
||||
end
|
||||
|
||||
def build_matrix
|
||||
counts = fetch_grouped_counts
|
||||
filtered_inboxes.map do |inbox|
|
||||
filtered_labels.map do |label|
|
||||
counts[[inbox.id, label.title]] || 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user