feat: Agent & Inbox Report APIs (#1391)
This commit is contained in:
parent
faaed17418
commit
eb2ded6f65
11 changed files with 102 additions and 12 deletions
|
@ -9,6 +9,18 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
||||||
render json: account_summary_metrics
|
render json: account_summary_metrics
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def agents
|
||||||
|
response.headers['Content-Type'] = 'text/csv'
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename=agents_report.csv'
|
||||||
|
render layout: false, template: 'api/v2/accounts/reports/agents.csv.erb', format: 'csv'
|
||||||
|
end
|
||||||
|
|
||||||
|
def inboxes
|
||||||
|
response.headers['Content-Type'] = 'text/csv'
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename=inboxes_report.csv'
|
||||||
|
render layout: false, template: 'api/v2/accounts/reports/inboxes.csv.erb', format: 'csv'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def account_summary_params
|
def account_summary_params
|
||||||
|
|
|
@ -12,8 +12,8 @@ class ReportsAPI extends ApiClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccountSummary(accountId, since, until) {
|
getAccountSummary(since, until) {
|
||||||
return axios.get(`${this.url}/${accountId}/account_summary`, {
|
return axios.get(`${this.url}/account_summary`, {
|
||||||
params: { since, until },
|
params: { since, until },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ const actions = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fetchAccountSummary({ commit }, reportObj) {
|
fetchAccountSummary({ commit }, reportObj) {
|
||||||
Report.getAccountSummary(1, reportObj.from, reportObj.to)
|
Report.getAccountSummary(reportObj.from, reportObj.to)
|
||||||
.then(accountSummary => {
|
.then(accountSummary => {
|
||||||
commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data);
|
commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data);
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
# name :string not null
|
# name :string not null
|
||||||
# settings_flags :integer default(0), not null
|
# settings_flags :integer default(0), not null
|
||||||
# support_email :string(100)
|
# support_email :string(100)
|
||||||
# timezone :string default("UTC")
|
# timezone :string default("UTC")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -66,6 +66,8 @@ class User < ApplicationRecord
|
||||||
accepts_nested_attributes_for :account_users
|
accepts_nested_attributes_for :account_users
|
||||||
|
|
||||||
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify
|
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify
|
||||||
|
alias_attribute :conversations, :assigned_conversations
|
||||||
|
|
||||||
has_many :inbox_members, dependent: :destroy
|
has_many :inbox_members, dependent: :destroy
|
||||||
has_many :inboxes, through: :inbox_members, source: :inbox
|
has_many :inboxes, through: :inbox_members, source: :inbox
|
||||||
has_many :messages, as: :sender
|
has_many :messages, as: :sender
|
||||||
|
|
12
app/views/api/v2/accounts/reports/agents.csv.erb
Normal file
12
app/views/api/v2/accounts/reports/agents.csv.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<% headers = ['Agent name', 'Conversations count', 'Avg first response time (Minutes)', 'Avg resolution time (Minutes)'] %>
|
||||||
|
<%= CSV.generate_line headers %>
|
||||||
|
<% Current.account.users.each do |agent| %>
|
||||||
|
<% agent_report = V2::ReportBuilder.new(Current.account, {
|
||||||
|
type: :agent,
|
||||||
|
id: agent.id,
|
||||||
|
since: params[:since],
|
||||||
|
until: params[:until]
|
||||||
|
}).summary %>
|
||||||
|
<% row = [ agent.name, agent_report[:conversations_count], (agent_report[:avg_first_response_time]/60).to_i, (agent_report[:avg_resolution_time]/60).to_i ] %>
|
||||||
|
<%= CSV.generate_line row %>
|
||||||
|
<% end %>
|
12
app/views/api/v2/accounts/reports/inboxes.csv.erb
Normal file
12
app/views/api/v2/accounts/reports/inboxes.csv.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<% headers = ['Inbox name', 'Conversations count', 'Avg first response time (Minutes)', 'Avg resolution time (Minutes)'] %>
|
||||||
|
<%= CSV.generate_line headers %>
|
||||||
|
<% Current.account.inboxes.each do |inbox| %>
|
||||||
|
<% inbox_report = V2::ReportBuilder.new(Current.account, {
|
||||||
|
type: :inbox,
|
||||||
|
id: inbox.id,
|
||||||
|
since: params[:since],
|
||||||
|
until: params[:until]
|
||||||
|
}).summary %>
|
||||||
|
<% row = [ inbox.name, inbox_report[:conversations_count], (inbox_report[:avg_first_response_time]/60).to_i, (inbox_report[:avg_resolution_time]/60).to_i ] %>
|
||||||
|
<%= CSV.generate_line row %>
|
||||||
|
<% end %>
|
|
@ -145,9 +145,9 @@ Rails.application.routes.draw do
|
||||||
resources :reports, only: [] do
|
resources :reports, only: [] do
|
||||||
collection do
|
collection do
|
||||||
get :account
|
get :account
|
||||||
end
|
|
||||||
member do
|
|
||||||
get :account_summary
|
get :account_summary
|
||||||
|
get :agents
|
||||||
|
get :inboxes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -456,11 +456,9 @@ ActiveRecord::Schema.define(version: 2020_10_27_135006) do
|
||||||
t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
||||||
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
|
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
|
||||||
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
|
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
|
||||||
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
|
|
||||||
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
|
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
|
||||||
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
|
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
|
||||||
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
|
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
|
||||||
t.index ["tagger_type", "tagger_id"], name: "index_taggings_on_tagger_type_and_tagger_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tags", id: :serial, force: :cascade do |t|
|
create_table "tags", id: :serial, force: :cascade do |t|
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService
|
||||||
end
|
end
|
||||||
|
|
||||||
def sender_type(sender)
|
def sender_type(sender)
|
||||||
sender.class == Contact ? 'Contact' : 'Agent'
|
sender.instance_of?(Contact) ? 'Contact' : 'Agent'
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_reference_id
|
def update_reference_id
|
||||||
|
|
|
@ -46,10 +46,10 @@ RSpec.describe 'Reports API', type: :request do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /api/v2/accounts/:account_id/reports/:id/account_summary' do
|
describe 'GET /api/v2/accounts/:account_id/reports/account_summary' do
|
||||||
context 'when it is an unauthenticated user' do
|
context 'when it is an unauthenticated user' do
|
||||||
it 'returns unauthorized' do
|
it 'returns unauthorized' do
|
||||||
get "/api/v2/accounts/#{account.id}/reports/#{account.id}/account_summary"
|
get "/api/v2/accounts/#{account.id}/reports/account_summary"
|
||||||
|
|
||||||
expect(response).to have_http_status(:unauthorized)
|
expect(response).to have_http_status(:unauthorized)
|
||||||
end
|
end
|
||||||
|
@ -65,7 +65,7 @@ RSpec.describe 'Reports API', type: :request do
|
||||||
until: Time.zone.today.to_time.to_i.to_s
|
until: Time.zone.today.to_time.to_i.to_s
|
||||||
}
|
}
|
||||||
|
|
||||||
get "/api/v2/accounts/#{account.id}/reports/#{account.id}/account_summary",
|
get "/api/v2/accounts/#{account.id}/reports/account_summary",
|
||||||
params: params,
|
params: params,
|
||||||
headers: agent.create_new_auth_token,
|
headers: agent.create_new_auth_token,
|
||||||
as: :json
|
as: :json
|
||||||
|
@ -77,4 +77,58 @@ RSpec.describe 'Reports API', type: :request do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'GET /api/v2/accounts/:account_id/reports/agents' do
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
get "/api/v2/accounts/#{account.id}/reports/agents.csv"
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
let(:agent) { create(:user, account: account, role: :agent) }
|
||||||
|
|
||||||
|
params = {
|
||||||
|
since: 30.days.ago.to_i.to_s,
|
||||||
|
until: Time.zone.today.to_time.to_i.to_s
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'returns summary' do
|
||||||
|
get "/api/v2/accounts/#{account.id}/reports/agents.csv",
|
||||||
|
params: params,
|
||||||
|
headers: agent.create_new_auth_token
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /api/v2/accounts/:account_id/reports/inboxes' do
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
get "/api/v2/accounts/#{account.id}/reports/inboxes"
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
let(:agent) { create(:user, account: account, role: :agent) }
|
||||||
|
|
||||||
|
params = {
|
||||||
|
since: 30.days.ago.to_i.to_s,
|
||||||
|
until: Time.zone.today.to_time.to_i.to_s
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'returns summary' do
|
||||||
|
get "/api/v2/accounts/#{account.id}/reports/inboxes",
|
||||||
|
params: params,
|
||||||
|
headers: agent.create_new_auth_token
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue