Skip to content

Commit

Permalink
DM-5278 metrics page refactor (#1136)
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipDeFraties authored Dec 3, 2024
1 parent ff5befa commit 6c4859c
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 172 deletions.
120 changes: 64 additions & 56 deletions app/controllers/practices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions app/models/diffusion_history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 1 addition & 3 deletions app/views/practices/form/metrics.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<tr>
<td style="font-size: 32px"><%= @page_views_for_practice_count %></td>
<td style="font-size: 32px"><%= @unique_visitors_for_practice_count %></td>
<td style="font-size: 32px"><%= @bookmarks_by_practice %></td>
<td style="font-size: 32px"><%= @bookmarks_by_practice_count %></td>
<td style="font-size: 32px"><%= @adoptions_by_practice %></td>
</tr>
</table>
Expand Down Expand Up @@ -267,5 +267,3 @@
</div>
</div>
</div>


145 changes: 32 additions & 113 deletions lib/modules/practice_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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|
Expand All @@ -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
Expand Down

0 comments on commit 6c4859c

Please sign in to comment.