diff --git a/app/models/report.rb b/app/models/report.rb index 617bde3544d..856bcbd093d 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -138,7 +138,12 @@ class Report data = User.real.count_by_inactivity(report.start_date, report.end_date) data.each do |data_point| - report.data << { x: data_point["date_trunc"], y: data_point["count"] } + report.data << { x: data_point["date"], y: data_point["count"] } + end + + unless report.data.blank? + report.prev30Days = report.data.first[:y] + report.total = report.data.last[:y] end end diff --git a/app/models/user.rb b/app/models/user.rb index d612353083d..9989bff0cf9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -830,40 +830,48 @@ class User < ActiveRecord::Base end def self.count_by_inactivity(start_date, end_date) - sql = < 0 AND - NOT EXISTS( - SELECT 1 - FROM user_custom_fields ucf - WHERE - ucf.user_id = u.id AND - ucf.name = 'master_id' AND - ucf.value :: int > 0 - ) AND - NOT EXISTS( - SELECT 1 - FROM user_visits v - WHERE v.visited_at BETWEEN (d.generated_date - INTERVAL '89 days') :: DATE AND d.generated_date - AND v.user_id = u.id - ) AND - NOT EXISTS( - SELECT 1 - FROM incoming_emails e - WHERE e.user_id = u.id AND - e.post_id IS NOT NULL AND - e.created_at :: DATE BETWEEN (d.generated_date - INTERVAL '89 days') :: DATE AND d.generated_date - ) - GROUP BY date_trunc('day', d.generated_date) :: DATE - ORDER BY date_trunc('day', d.generated_date) :: DATE -SQL + aggregation_unit = aggregation_unit_for_period(start_date, end_date) - exec_sql(sql).to_a + sql = <<~SQL + SELECT + date_trunc('#{aggregation_unit}', generated_date) :: DATE AS "date", + max("count") AS "count" + FROM ( + SELECT + d.generated_date, + COUNT(1) AS "count" + FROM (SELECT generate_series(:start_date, :end_date, '1 day' :: INTERVAL) :: DATE AS generated_date) d + JOIN users u ON (u.created_at :: DATE <= d.generated_date) + WHERE u.active AND + u.id > 0 AND + NOT EXISTS( + SELECT 1 + FROM user_custom_fields ucf + WHERE + ucf.user_id = u.id AND + ucf.name = 'master_id' AND + ucf.value :: int > 0 + ) AND + NOT EXISTS( + SELECT 1 + FROM user_visits v + WHERE v.visited_at BETWEEN (d.generated_date - INTERVAL '89 days') :: DATE AND d.generated_date + AND v.user_id = u.id + ) AND + NOT EXISTS( + SELECT 1 + FROM incoming_emails e + WHERE e.user_id = u.id AND + e.post_id IS NOT NULL AND + e.created_at :: DATE BETWEEN (d.generated_date - INTERVAL '89 days') :: DATE AND d.generated_date + ) + GROUP BY d.generated_date + ) AS x + GROUP BY date_trunc('#{aggregation_unit}', generated_date) :: DATE + ORDER BY date_trunc('#{aggregation_unit}', generated_date) :: DATE + SQL + + exec_sql(sql, start_date: start_date, end_date: end_date).to_a end def self.count_by_signup_date(start_date = nil, end_date = nil, group_id = nil) diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index de386463f57..6b573dbb0b3 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -455,6 +455,8 @@ describe Report do report = Report.find('inactive_users') expect(report.data.first[:y]).to eq(3) expect(report.data.last[:y]).to eq(5) + expect(report.prev30Days).to eq(3) + expect(report.total).to eq(5) @arpit.user_visits.create(visited_at: 80.days.ago) report = Report.find('inactive_users')