diff --git a/app/models/report.rb b/app/models/report.rb index 9682f3ac9..0b450213c 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -32,6 +32,7 @@ class Report display: 'Backlog', selected: true, dataDownload: false, + adapter: Report::TicketBacklog, }, { name: 'first_solution', @@ -169,12 +170,60 @@ class Report display: 'Web (in)', selected: true, dataDownload: true, + adapter: Report::TicketGenericTime, + params: { + field: 'created_at', + selector: { + 'create_article_type_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Type.lookup(name: 'web').id, + }, + 'create_article_sender_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Sender.lookup(name: 'Customer').id, + }, + }, + }, }, { name: 'twitter_in', display: 'Twitter (in)', selected: true, dataDownload: true, + adapter: Report::TicketGenericTime, + params: { + field: 'created_at', + selector: { + 'create_article_type_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Type.lookup(name: 'twitter status').id, + }, + 'create_article_sender_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Sender.lookup(name: 'Customer').id, + }, + }, + }, + }, + { + name: 'twitter_out', + display: 'Twitter (out)', + selected: true, + dataDownload: true, + adapter: Report::TicketGenericTime, + params: { + field: 'created_at', + selector: { + 'create_article_type_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Type.lookup(name: 'twitter status').id, + }, + 'create_article_sender_id' => { + 'operator' => 'is', + 'value' => Ticket::Article::Sender.lookup(name: 'Agent').id, + }, + }, + }, }, ] config[:metric][:create_channels][:backend] = backend @@ -235,46 +284,81 @@ class Report display: 'Phone (in)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'phone', + sender: 'Customer', + }, }, { name: 'phone_out', display: 'Phone (out)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'phone', + sender: 'Agent', + }, }, { name: 'email_in', display: 'Email (in)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'email', + sender: 'Customer', + }, }, { name: 'email_out', display: 'Email (out)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'email', + sender: 'Agent', + }, }, { name: 'web_in', display: 'Web (in)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'web', + sender: 'Customer', + }, }, { name: 'twitter_in', display: 'Twitter (in)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'twitter status', + sender: 'Customer', + }, }, { name: 'twitter_out', display: 'Twitter (out)', selected: true, dataDownload: false, + adapter: Report::ArticleByTypeSender, + params: { + type: 'twitter status', + sender: 'Agent', + }, }, ] config[:metric][:communication][:backend] = backend - +=begin config[:metric][:sla] = { name: 'sla', display: 'SLAs', @@ -331,7 +415,7 @@ class Report }, ] config[:metric][:sla][:backend] = backend - +=end config[:metric].each {|metric_key, metric_value| metric_value[:backend].each {|metric_backend| metric_backend[:name] = "#{metric_key}::#{metric_backend[:name]}" diff --git a/lib/report/article_by_type_sender.rb b/lib/report/article_by_type_sender.rb new file mode 100644 index 000000000..5c16fbfda --- /dev/null +++ b/lib/report/article_by_type_sender.rb @@ -0,0 +1,98 @@ +class Report::ArticleByTypeSender < Report::Base + +=begin + + result = Report::ArticleByTypeSender.aggs( + range_start: '2015-01-01T00:00:00Z', + range_end: '2015-12-31T23:59:59Z', + interval: 'month', # quarter, month, week, day, hour, minute, second + selector: selector, # ticket selector to get only a collection of tickets + params: { + type: 'phone', + sender: 'Customer', + } + ) + +returns + + [4,5,1,5,0,51,5,56,7,4] + +=end + + def self.aggs(params) + + interval = params[:interval] + if params[:interval] == 'week' + interval = 'day' + end + + result = [] + if params[:interval] == 'month' + start = Date.parse(params[:range_start]) + stop_interval = 12 + elsif params[:interval] == 'week' + start = Date.parse(params[:range_start]) + stop_interval = 7 + elsif params[:interval] == 'day' + start = Date.parse(params[:range_start]) + stop_interval = 31 + elsif params[:interval] == 'hour' + start = Time.zone.parse(params[:range_start]) + stop_interval = 24 + elsif params[:interval] == 'minute' + start = Time.zone.parse(params[:range_start]) + stop_interval = 60 + end + (1..stop_interval).each {|_counter| + if params[:interval] == 'month' + stop = start.next_month + elsif params[:interval] == 'week' + stop = start.next_day + elsif params[:interval] == 'day' + stop = start.next_day + elsif params[:interval] == 'hour' + stop = start + 1.hour + elsif params[:interval] == 'minute' + stop = start + 1.minute + end + query, bind_params, tables = Ticket.selector2sql(params[:selector]) + sender = Ticket::Article::Sender.lookup( name: params[:params][:sender] ) + type = Ticket::Article::Type.lookup( name: params[:params][:type] ) + count = Ticket::Article.joins('INNER JOIN tickets ON tickets.id = ticket_articles.ticket_id') + .where(query, *bind_params).joins(tables) + .where( + 'ticket_articles.created_at >= ? AND ticket_articles.created_at <= ? AND ticket_articles.type_id = ? AND ticket_articles.sender_id = ?', + start, + stop, + type.id, + sender.id, + ).count + result.push count + start = stop + } + result + end + +=begin + + result = Report::ArticleByTypeSender.items( + range_start: '2015-01-01T00:00:00Z', + range_end: '2015-12-31T23:59:59Z', + selector: selector, # ticket selector to get only a collection of tickets + selector: selector, # ticket selector to get only a collection of tickets + params: { + type: 'phone', + sender: 'Customer', + } + ) + +returns + + {} + +=end + + def self.items(_params) + {} + end +end diff --git a/lib/report/base.rb b/lib/report/base.rb index caac25917..b0b1c51dc 100644 --- a/lib/report/base.rb +++ b/lib/report/base.rb @@ -224,51 +224,6 @@ class Report::Base fail "UNKOWN :type (#{data[:type]})!" end - # :sender - # :type - # :start - # :end - # :condition - def self.article_type_and_sender(data) - query, bind_params, tables = Ticket.selector2sql(data[:condition]) - sender = Ticket::Article::Sender.lookup( name: data[:sender] ) - type = Ticket::Article::Type.lookup( name: data[:type] ) - articles = Ticket::Article.joins('INNER JOIN tickets ON tickets.id = ticket_articles.ticket_id') - .where(query, *bind_params).joins(tables) - .where( - 'ticket_articles.created_at >= ? AND ticket_articles.created_at <= ? AND ticket_articles.type_id = ? AND ticket_articles.sender_id = ?', - data[:start], - data[:end], - type.id, - sender.id, - ).count - { - count: articles, - } - end - - # :type - # :start - # :end - # :condition - def self.create_channel(data) - query, bind_params, tables = Ticket.selector2sql(data[:condition]) - article_type = Ticket::Article::Type.lookup( name: data[:type] ) - tickets = Ticket.select('tickets.id') - .where( 'tickets.created_at >= ? AND tickets.created_at <= ? AND tickets.create_article_type_id = ?', data[:start], data[:end], article_type.id ) - .where(query, *bind_params).joins(tables) - count = 0 - ticket_ids = [] - tickets.each {|ticket| - count += 1 - ticket_ids.push ticket.id - } - { - count: count, - ticket_ids: ticket_ids, - } - end - # :type # :start # :end diff --git a/lib/report/ticket_backlog.rb b/lib/report/ticket_backlog.rb new file mode 100644 index 000000000..eb70ee939 --- /dev/null +++ b/lib/report/ticket_backlog.rb @@ -0,0 +1,55 @@ +class Report::TicketBacklog < Report::Base + +=begin + + result = Report::TicketBacklog.aggs( + range_start: '2015-01-01T00:00:00Z', + range_end: '2015-12-31T23:59:59Z', + interval: 'month', # quarter, month, week, day, hour, minute, second + selector: selector, # ticket selector to get only a collection of tickets + ) + +returns + + [4,5,1,5,0,51,5,56,7,4] + +=end + + def self.aggs(params) + + local_params = params.clone + local_params[:params] = {} + + local_params[:params][:field] = 'created_at' + created = Report::TicketGenericTime.aggs(local_params) + + local_params[:params][:field] = 'close_time' + closed = Report::TicketGenericTime.aggs(local_params) + + result = [] + (0..created.length - 1).each {|position| + count = created[position] - closed[position] + result.push count + } + result + end + +=begin + + result = Report::TicketBacklog.items( + range_start: '2015-01-01T00:00:00Z', + range_end: '2015-12-31T23:59:59Z', + selector: selector, # ticket selector to get only a collection of tickets + ) + +returns + + {} + +=end + + def self.items(_params) + {} + end + +end diff --git a/lib/report/ticket_generic_time.rb b/lib/report/ticket_generic_time.rb index f71f1b40b..c0b8d00ee 100644 --- a/lib/report/ticket_generic_time.rb +++ b/lib/report/ticket_generic_time.rb @@ -1,13 +1,13 @@ class Report::TicketGenericTime =begin - selector = {} + result = Report::TicketGenericTime.aggs( range_start: '2015-01-01T00:00:00Z', range_end: '2015-12-31T23:59:59Z', interval: 'month', # year, quarter, month, week, day, hour, minute, second selector: selector, # ticket selector to get only a collection of tickets - params: { field: 'created_at' }, + params: { field: 'created_at', selector: selector_sub }, ) returns @@ -29,7 +29,12 @@ returns field: params[:params][:field], } - result_es = SearchIndexBackend.selectors(['Ticket'], params[:selector], nil, nil, aggs_interval) + selector = params[:selector].clone + if params[:params] && params[:params][:selector] + selector = selector.merge(params[:params][:selector]) + end + + result_es = SearchIndexBackend.selectors(['Ticket'], selector, nil, nil, aggs_interval) if params[:interval] == 'month' start = Date.parse(params[:range_start]) @@ -50,6 +55,18 @@ returns result = [] (1..stop_interval).each {|_counter| match = false + if !result_es + fail "Invalid es result #{result_es.inspect}" + end + if !result_es['aggregations'] + fail "Invalid es result, no aggregations #{result_es.inspect}" + end + if !result_es['aggregations']['time_buckets'] + fail "Invalid es result, no time_buckets #{result_es.inspect}" + end + if !result_es['aggregations']['time_buckets']['buckets'] + fail "Invalid es result, no buckets #{result_es.inspect}" + end result_es['aggregations']['time_buckets']['buckets'].each {|item| if params[:interval] == 'minute' item['key_as_string'] = item['key_as_string'].sub(/:\d\d.\d\d\dZ$/, '') @@ -118,7 +135,12 @@ returns field: params[:params][:field], } - result = SearchIndexBackend.selectors(['Ticket'], params[:selector], nil, nil, aggs_interval) + selector = params[:selector].clone + if params[:params] && params[:params][:selector] + selector = selector.merge(params[:params][:selector]) + end + + result = SearchIndexBackend.selectors(['Ticket'], selector, nil, nil, aggs_interval) assets = {} result[:ticket_ids].each {|ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/lib/search_index_backend.rb b/lib/search_index_backend.rb index 4d64973a4..70e9878c2 100644 --- a/lib/search_index_backend.rb +++ b/lib/search_index_backend.rb @@ -303,8 +303,7 @@ get count of tickets and tickets which match on selector Rails.logger.info "# #{response.code}" if !response.success? - Rails.logger.error "ERROR: #{response.inspect}" - return [] + fail "ERROR: #{response.inspect}" end Rails.logger.debug response.data.to_json @@ -412,6 +411,17 @@ get count of tickets and tickets which match on selector data[:query][:filtered][:filter][:bool][:must_not] = filter_must_not end + # add sort + if aggs_interval && aggs_interval[:field] && !aggs_interval[:interval] + sort = [] + sort[0] = {} + sort[0][aggs_interval[:field]] = { + order: 'desc' + } + sort[1] = '_score' + data['sort'] = sort + end + data end diff --git a/test/integration/report_test.rb b/test/integration/report_test.rb index eed983516..51e2b4afb 100644 --- a/test/integration/report_test.rb +++ b/test/integration/report_test.rb @@ -734,6 +734,7 @@ class ReportTest < ActiveSupport::TestCase params: { field: 'created_at' }, ) assert(result) + puts "r #{result.inspect}" assert_equal(ticket1.id, result[:ticket_ids][0].to_i) assert_equal(ticket2.id, result[:ticket_ids][1].to_i) assert_equal(ticket3.id, result[:ticket_ids][2].to_i)