diff --git a/app/controllers/practices_controller.rb b/app/controllers/practices_controller.rb index 39370ade7..c61e1daa5 100644 --- a/app/controllers/practices_controller.rb +++ b/app/controllers/practices_controller.rb @@ -261,68 +261,76 @@ def overview def metrics @duration = params[:duration] || "30" + + if @duration != "30" + @duration = get_practice_all_time_duration(@practice.id).to_s + end + @page_views_leader_board_30_days = fetch_page_views_leader_board @page_views_leader_board_all_time = fetch_page_views_leader_board(0) - @page_views_for_practice_count = fetch_page_view_for_practice_count(@practice.id, @duration) - @unique_visitors_for_practice_count = fetch_unique_visitors_by_practice_count(@practice.id, @duration) - @bookmarks_by_practice = fetch_bookmarks_by_practice(@practice.id, @duration) + page_views = fetch_page_views_for_practice_over_duration(@practice.id, @duration) + @page_views_for_practice_count = page_views.size + @unique_visitors_for_practice_count = page_views + .select(:user_id) + .distinct + .count + + @bookmarks_by_practice_count = fetch_bookmarks_by_practice(@practice.id, @duration) + + adoptions_all_time = DiffusionHistory.with_practice_and_facilities(@practice) + @adoptions_total_at = adoptions_all_time.size + + adoptions_past_30_days = adoptions_all_time.in_date_range(30.days.ago.beginning_of_day) + @adoptions_total_30 = adoptions_past_30_days.size + if @duration === '30' - @adoptions_by_practice = fetch_adoption_counts_by_practice_last_30_days(@practice) + @adoptions_by_practice = @adoptions_total_30 else - @adoptions_by_practice = fetch_adoption_counts_by_practice_all_time(@practice) - end - - @adoptions_total_30 = fetch_adoption_counts_by_practice_last_30_days(@practice) - @adoptions_total_at = fetch_adoption_counts_by_practice_all_time(@practice) - - @adoptions_successful_total_30 = fetch_adoptions_total_by_practice_and_status_last_30_days(@practice, 'Completed') - @adoptions_successful_total_at = fetch_adoptions_total_by_practice_and_status_all_time(@practice, 'Completed') - @adoptions_in_progress_total_30 = fetch_adoptions_total_by_practice_and_status_last_30_days(@practice, 'In progress') - @adoptions_in_progress_total_at = fetch_adoptions_total_by_practice_and_status_all_time(@practice, 'In progress') - @adoptions_unsuccessful_total_30 = fetch_adoptions_total_by_practice_and_status_last_30_days(@practice, 'Unsuccessful') - @adoptions_unsuccessful_total_at = fetch_adoptions_total_by_practice_and_status_all_time(@practice, 'Unsuccessful') - - @facility_ids_for_practice_30 = fetch_adoption_facilities_for_practice_last_30_days(@practice) - @rural_facility_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "rurality", "R") - @urban_facility_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "rurality", "U") - @a_high_complexity_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "fy17_parent_station_complexity_level", "1a-High Complexity") - @b_high_complexity_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "fy17_parent_station_complexity_level", "1b-High Complexity") - @c_high_complexity_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "fy17_parent_station_complexity_level", "1c-High Complexity") - @medium_complexity_2_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "fy17_parent_station_complexity_level", "2 -Medium Complexity") - @low_complexity_3_30 = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_30, "fy17_parent_station_complexity_level", "3 -Low Complexity") - - @facility_ids_for_practice_at = fetch_adoption_facilities_for_practice_all_time(@practice) - @rural_facility_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "rurality", "R") - @urban_facility_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "rurality", "U") - @a_high_complexity_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "fy17_parent_station_complexity_level", "1a-High Complexity") - @b_high_complexity_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "fy17_parent_station_complexity_level", "1b-High Complexity") - @c_high_complexity_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "fy17_parent_station_complexity_level", "1c-High Complexity") - @medium_complexity_2_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "fy17_parent_station_complexity_level", "2 -Medium Complexity") - @low_complexity_3_at = get_adoption_facility_details_for_practice(@va_facilities, @facility_ids_for_practice_at, "fy17_parent_station_complexity_level", "3 -Low Complexity") - - # Charts..... - @unique_visitors_for_practice = fetch_unique_visitors_by_practice(@practice.id, @duration) - @page_views_for_practice = fetch_page_views_for_practice(@practice.id, @duration) - - if @duration != "30" - @duration = get_practice_all_time_duration(@practice.id) + @adoptions_by_practice = @adoptions_total_at end + + # Adoptions Metrics + adoption_metrics_30 = calculate_adoption_metrics(adoptions_past_30_days) + adoption_metrics_at = calculate_adoption_metrics(adoptions_all_time) + + @adoptions_successful_total_30 = adoption_metrics_30[:successful] + @adoptions_successful_total_at = adoption_metrics_at[:successful] + + @adoptions_in_progress_total_30 = adoption_metrics_30[:in_progress] + @adoptions_in_progress_total_at = adoption_metrics_at[:in_progress] + + @adoptions_unsuccessful_total_30 = adoption_metrics_30[:unsuccessful] + @adoptions_unsuccessful_total_at = adoption_metrics_at[:unsuccessful] + + + # Facility metrics + facility_station_numbers_for_practice_30 = adoptions_past_30_days.map {|dh| dh.station_number if dh.station_number.present?} + facility_station_numbers_for_practice_at = adoptions_all_time.map {|dh| dh.station_number if dh.station_number.present?} + facility_metrics_30 = calculate_facility_metrics(@va_facilities, facility_station_numbers_for_practice_30) + facility_metrics_at = calculate_facility_metrics(@va_facilities, facility_station_numbers_for_practice_at) + + @rural_facility_30 = facility_metrics_30[:rural] + @urban_facility_30 = facility_metrics_30[:urban] + @a_high_complexity_30 = facility_metrics_30[:high_complexity_1a] + @b_high_complexity_30 = facility_metrics_30[:high_complexity_1b] + @c_high_complexity_30 = facility_metrics_30[:high_complexity_1c] + @medium_complexity_2_30 = facility_metrics_30[:medium_complexity_2] + @low_complexity_3_30 = facility_metrics_30[:low_complexity_3] + + @rural_facility_at = facility_metrics_at[:rural] + @urban_facility_at = facility_metrics_at[:urban] + @a_high_complexity_at = facility_metrics_at[:high_complexity_1a] + @b_high_complexity_at = facility_metrics_at[:high_complexity_1b] + @c_high_complexity_at = facility_metrics_at[:high_complexity_1c] + @medium_complexity_2_at = facility_metrics_at[:medium_complexity_2] + @low_complexity_3_at = facility_metrics_at[:low_complexity_3] + + # Google line chart @month_names = "Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - @cur_duration = @duration.to_i - @dates = ((@cur_duration.days.ago.to_date .. 0.days.ago.to_date).to_a).map(&:to_s) - @views = [] - @visitors = [] - @dates.each do |date| - objCtr = 0 - @page_views_for_practice.each do |obj| - objCtr += 1 if obj[:created_at].to_s == date.to_s - end - @views << objCtr - end - @unique_visitors = [] - @dates.each do |date| - @unique_visitors << fetch_unique_visitors_by_practice_and_date(@practice.id, date) - end + page_view_metrics = calculate_page_view_metrics(page_views, @duration) + @dates = page_view_metrics[:dates] + @views = page_view_metrics[:views] + @unique_visitors = page_view_metrics[:unique_visitors] render 'practices/form/metrics' end diff --git a/app/models/diffusion_history.rb b/app/models/diffusion_history.rb index 0f5f99292..58890cc75 100644 --- a/app/models/diffusion_history.rb +++ b/app/models/diffusion_history.rb @@ -19,6 +19,21 @@ class DiffusionHistory < ApplicationRecord scope :get_va_facilities, -> { includes(:va_facility).pluck("va_facilities.station_number") } scope :get_clinical_resource_hubs, -> { includes(:clinical_resource_hub).pluck("clinical_resource_hubs.official_station_name") } scope :get_with_practice, -> (practice) { joins(:practice).where(practice: practice) } + scope :with_practice_and_facilities, ->(practice) { + get_with_practice(practice) + .joins( + "LEFT OUTER JOIN va_facilities ON va_facilities.id = diffusion_histories.va_facility_id + LEFT OUTER JOIN clinical_resource_hubs ON clinical_resource_hubs.id = diffusion_histories.clinical_resource_hub_id" + ) + .select( + 'diffusion_histories.id, + diffusion_histories.created_at, + va_facilities.station_number AS station_number' + ) + } scope :exclude_va_facilities, -> { where(va_facility_id: nil) } scope :exclude_clinical_resource_hubs, -> { where(clinical_resource_hub_id: nil) } + scope :in_date_range, ->(start_date, end_date = Time.now) { + where(created_at: start_date..end_date) + } end diff --git a/app/views/practices/form/metrics.html.erb b/app/views/practices/form/metrics.html.erb index 7f63de92a..156986f95 100644 --- a/app/views/practices/form/metrics.html.erb +++ b/app/views/practices/form/metrics.html.erb @@ -46,7 +46,7 @@ <%= @page_views_for_practice_count %> <%= @unique_visitors_for_practice_count %> - <%= @bookmarks_by_practice %> + <%= @bookmarks_by_practice_count %> <%= @adoptions_by_practice %> @@ -267,5 +267,3 @@ - - diff --git a/lib/modules/practice_utils.rb b/lib/modules/practice_utils.rb index 939d76de2..ea6adfd74 100644 --- a/lib/modules/practice_utils.rb +++ b/lib/modules/practice_utils.rb @@ -28,73 +28,9 @@ def practice_leader_board(practice, count, created_at = DateTime.now()) {practice_name: practice.name, practice_slug: practice.slug, count: count, created_at: created_at} end - def fetch_page_view_for_practice_count(practice_id, duration = "30") - page_view_leaders = [] - sql = "select name, properties, count(properties) as count from ahoy_events where name = 'Practice show' and time >= $1 group by name, properties" - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, "#{Time.now - duration.to_i.days}"]]) - # records_array = prepare_sql.execute(sql) - #recs = records_array.values - records_array.each do |rec| - if practice_id == JSON.parse(rec["properties"])["practice_id"] - practice = practice_leader_board(Practice.find(practice_id), rec["count"]) - page_view_leaders << practice - end - end - if page_view_leaders.empty? - return 0 - else - page_view_leaders[0][:count] - end - end - - def fetch_page_views_for_practice(practice_id, duration = "30") - page_views = [] - sql = "select name, properties, time from ahoy_events where name = 'Practice show' and properties = $1" - param1 = "{\"practice_id\": #{practice_id}}" - if duration == "30" - sql += " and time >= $2" - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1], [nil, "#{Time.now - duration.to_i.days}"]]) - else - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1]]) - end - records_array.each do |rec| - if practice_id == JSON.parse(rec["properties"])["practice_id"] - practice = practice_leader_board(Practice.find(practice_id), 0, rec["time"].to_date) - page_views << practice - end - end - page_views - end - - def fetch_unique_visitors_by_practice_count(practice_id, duration = "30") - sql = "select distinct user_id from ahoy_events where name = 'Practice show' and properties = $1" - param1 = "{\"practice_id\": #{practice_id}}" - if duration == "30" - sql += " and time >= $2" - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1], [nil, "#{Time.now - duration.to_i.days}"]]) - else - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1]]) - end - records_array.count - end - - def fetch_unique_visitors_by_practice(practice_id, duration = "30") - sql = "select user_id, time from ahoy_events where name = 'Practice show' and properties = $1" - param1 = "{\"practice_id\": #{practice_id}}" - if duration == "30" - sql += " and time >= $2" - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1], [nil, "#{Time.now - duration.to_i.days}"]]) - else - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1]]) - end - records_array - end - - def fetch_unique_visitors_by_practice_and_date(practice_id, date) - sql = "select distinct user_id from ahoy_events where name = 'Practice show' and properties = $1 and date(time) = $2" - param1 = "{\"practice_id\": #{practice_id}}" - records_array = ActiveRecord::Base.connection.exec_query(sql, "SQL", [[nil, param1], [nil, "#{date}"]]) - records_array.count + def fetch_page_views_for_practice_over_duration(practice_id, duration = "30") + start_date = Time.now - duration.to_i.days + Ahoy::Event.practice_views_for_single_practice_by_date_range(practice_id, start_date, Time.now) end def get_practice_all_time_duration(practice_id) @@ -103,7 +39,6 @@ def get_practice_all_time_duration(practice_id) duration end - def fetch_bookmarks_by_practice(practice_id, duration = "30") practice = Practice.find(practice_id) bookmarked = practice.user_practices.where(favorited: true) @@ -114,51 +49,6 @@ def fetch_bookmarks_by_practice(practice_id, duration = "30") end end - def fetch_adoptions_by_practice_last_30_days(practice) - DiffusionHistory.get_with_practice(practice).where(created_at: Time.now.beginning_of_day - 30.days..Time.now) - end - - def fetch_adoptions_by_practice_all_time(practice) - DiffusionHistory.get_with_practice(practice) - end - - def fetch_adoption_counts_by_status(status, adoptions) - case status - when 'Completed' - adoptions.get_by_successful_status.size - when 'In progress' - adoptions.get_by_in_progress_status.size - when 'Unsuccessful' - adoptions.get_by_unsuccessful_status.size - end - end - - def fetch_adoptions_total_by_practice_and_status_last_30_days(practice, status) - adoptions = fetch_adoptions_by_practice_last_30_days(practice) - fetch_adoption_counts_by_status(status, adoptions) - end - - def fetch_adoptions_total_by_practice_and_status_all_time(practice, status) - adoptions = fetch_adoptions_by_practice_all_time(practice) - fetch_adoption_counts_by_status(status, adoptions) - end - - def fetch_adoption_counts_by_practice_last_30_days(practice) - DiffusionHistory.get_with_practice(practice).where(created_at: Time.now.beginning_of_day - 30.days..Time.now).size - end - - def fetch_adoption_counts_by_practice_all_time(practice) - DiffusionHistory.get_with_practice(practice).size - end - - def fetch_adoption_facilities_for_practice_last_30_days(practice) - DiffusionHistory.get_with_practice(practice).where(created_at: Time.now.beginning_of_day - 30.days..Time.now).includes(:va_facility).collect { |dh| dh.va_facility.station_number if dh.va_facility.present? } - end - - def fetch_adoption_facilities_for_practice_all_time(practice) - DiffusionHistory.get_with_practice(practice).includes(:va_facility).collect { |dh| dh.va_facility.station_number if dh.va_facility.present? } - end - def get_adoption_facility_details_for_practice(facility_data, facility_station_numbers_for_practice, key, value) match_counter = 0 facility_data.where(station_number: facility_station_numbers_for_practice).each do |facility| @@ -169,6 +59,35 @@ def get_adoption_facility_details_for_practice(facility_data, facility_station_n match_counter end + def calculate_adoption_metrics(adoptions) + { + successful: adoptions.get_by_successful_status.size, + in_progress: adoptions.get_by_in_progress_status.size, + unsuccessful: adoptions.get_by_unsuccessful_status.size + } + end + + def calculate_facility_metrics(facilities, facility_ids) + { + rural: get_adoption_facility_details_for_practice(facilities, facility_ids, "rurality", "R"), + urban: get_adoption_facility_details_for_practice(facilities, facility_ids, "rurality", "U"), + high_complexity_1a: get_adoption_facility_details_for_practice(facilities, facility_ids, "fy17_parent_station_complexity_level", "1a-High Complexity"), + high_complexity_1b: get_adoption_facility_details_for_practice(facilities, facility_ids, "fy17_parent_station_complexity_level", "1b-High Complexity"), + high_complexity_1c: get_adoption_facility_details_for_practice(facilities, facility_ids, "fy17_parent_station_complexity_level", "1c-High Complexity"), + medium_complexity_2: get_adoption_facility_details_for_practice(facilities, facility_ids, "fy17_parent_station_complexity_level", "2 -Medium Complexity"), + low_complexity_3: get_adoption_facility_details_for_practice(facilities, facility_ids, "fy17_parent_station_complexity_level", "3 -Low Complexity") + } + end + + def calculate_page_view_metrics(page_views, duration) + grouped_page_views = page_views.group_by { |pv| pv.time.to_date } + dates = (duration.to_i.days.ago.to_date..Date.today).map(&:to_s) + views = dates.map { |date| grouped_page_views[Date.parse(date)]&.count || 0 } + unique_visitors = dates.map { |date| grouped_page_views[Date.parse(date)]&.map(&:user_id)&.uniq&.count || 0 } + + { dates: dates, views: views, unique_visitors: unique_visitors } + end + def fetch_page_views_leader_board(duration = "30") page_view_leaders = [] ctr = 0