diff --git a/app/controllers/usage_controller.rb b/app/controllers/usage_controller.rb index 15d0cd3..46e7a38 100644 --- a/app/controllers/usage_controller.rb +++ b/app/controllers/usage_controller.rb @@ -15,6 +15,7 @@ total_users(args: min_max_dates(args: args)) #TODO: pull this in from branding.yml @separators = [",", "|", "#"] + @funder = current_user.org.funder? end # POST /usage_plans_by_template diff --git a/app/helpers/usage_helper.rb b/app/helpers/usage_helper.rb index b38edc6..806c609 100644 --- a/app/helpers/usage_helper.rb +++ b/app/helpers/usage_helper.rb @@ -15,7 +15,7 @@ # appropriately by passing along the labels for the Y axis and the datasets # for the X axis # rubocop:disable Metrics/AbcSize, Metrics/MethodLength - def prep_data_for_template_plans_chart(data:) + def prep_data_for_template_plans_chart(data:, subset: "by_template") last_month = Date.today.last_month.end_of_month.strftime('%b-%y') return { labels: [last_month], datasets: [] }.to_json if data.blank? || data.empty? @@ -29,7 +29,7 @@ # Loop through the data and organize the datasets by template instead of date data.each do |rec| date = prep_date_for_charts(date: rec["date"]) - rec["by_template"].each do |template| + rec[subset].each do |template| # We need a placeholder for each month/year - template combo. The # default is to assume that there are zero plans for that month/year + template dflt = { diff --git a/app/javascript/views/usage/index.js b/app/javascript/views/usage/index.js index d596af6..b9488ec 100644 --- a/app/javascript/views/usage/index.js +++ b/app/javascript/views/usage/index.js @@ -37,25 +37,39 @@ // TODO: Most of these event listeners would not be necessary if JQuery and // all other JS libraries were available to the js.erb files. Reevaluate // this JS once we move to Rails 5 and properly configure webpacker - let drawnChart = null; - const monthlyPlanTemplatesChart = document.getElementById('monthly_template_plans'); + let drawnChartByTemplate = null; + const monthlyPlanTemplatesChart = document.getElementById('monthly_plans_by_template'); // Add event listeners that draw and destroy the chart monthlyPlanTemplatesChart.addEventListener('renderChart', (e) => { - drawnChart = drawHorizontalBar($('#monthly_template_plans'), e.detail); + drawnChartByTemplate = drawHorizontalBar($('#monthly_plans_by_template'), e.detail); // Assigning the chart to a window variable here so that we can fire // the events from the js.erb - window.templatePlansChart = document.getElementById('monthly_template_plans'); + window.templatePlansChart = document.getElementById('monthly_plans_by_template'); }); monthlyPlanTemplatesChart.addEventListener('destroyChart', () => { - if (drawnChart) { - drawnChart.destroy(); + if (drawnChartByTemplate) { + drawnChartByTemplate.destroy(); } }); + let drawnChartUsingTemplate = null; + const monthlyPlanUsingTemplatesChart = document.getElementById('monthly_plans_using_template'); + // Add event listeners that draw the chart + monthlyPlanUsingTemplatesChart.addEventListener('renderChart', (e) => { + drawnChartUsingTemplate = drawHorizontalBar($('#monthly_plans_using_template'), e.detail); + }); + // Create the initial Plans per template chart const templatePlansData = JSON.parse($('#plans_by_template').val()); if (isObject(templatePlansData)) { - const draw = new CustomEvent('renderChart', { detail: templatePlansData }); - document.getElementById('monthly_template_plans').dispatchEvent(draw); + const drawPer = new CustomEvent('renderChart', { detail: templatePlansData }); + document.getElementById('monthly_plans_by_template').dispatchEvent(drawPer); + } + + // Create the initial Plans using template chart + const usingTemplatePlansData = JSON.parse($('#plans_using_template').val()); + if (isObject(usingTemplatePlansData)) { + const drawUsing = new CustomEvent('renderChart', { detail: usingTemplatePlansData }); + document.getElementById('monthly_plans_using_template').dispatchEvent(drawUsing); } }); diff --git a/app/models/stat_created_plan.rb b/app/models/stat_created_plan.rb index 4d4bdf8..75b645d 100644 --- a/app/models/stat_created_plan.rb +++ b/app/models/stat_created_plan.rb @@ -21,14 +21,21 @@ serialize :details, JSON def by_template - return [] unless details.present? + parse_details.fetch("by_template", []) + end - json = details.is_a?(String) ? JSON.parse(details) : details - json.fetch("by_template", []) + def using_template + parse_details.fetch("using_template", []) end def to_json(options = nil) - super(methods: :by_template) + super(methods: [:by_template, :using_template]) + end + + def parse_details + return JSON.parse({}) unless details.present? + + json = details.is_a?(String) ? JSON.parse(details) : details end class << self diff --git a/app/models/stat_created_plan/create_or_update.rb b/app/models/stat_created_plan/create_or_update.rb index 8802105..341307a 100644 --- a/app/models/stat_created_plan/create_or_update.rb +++ b/app/models/stat_created_plan/create_or_update.rb @@ -9,11 +9,12 @@ def do(start_date:, end_date:, org:) count = count_plans(start_date: start_date, end_date: end_date, org: org) by_template = by_template(start_date: start_date, end_date: end_date, org: org) + using_template = using_template(start_date: start_date, end_date: end_date, org: org) attrs = { date: end_date.to_date, org_id: org.id, count: count, - details: { by_template: by_template } + details: { by_template: by_template, using_template: using_template } } stat_created_plan = StatCreatedPlan.find_by( date: attrs[:date], @@ -37,6 +38,11 @@ Plan.where(plans: { created_at: start_date..end_date }) end + def own_template_plans(org) + template_ids = Template.where(org_id: org.id ).pluck(:id) + Plan.where(plans: { template_id: template_ids }) + end + def count_plans(start_date:, end_date:, org:) Role.joins(:plan, :user) .administrator @@ -67,6 +73,27 @@ end end + def using_template(start_date:, end_date:, org:) + roleable_plan_ids = Role.joins([:plan, :user]) \ + .administrator \ + .merge(plans(start_date: start_date, end_date: end_date)) \ + .merge(own_template_plans(org)) \ + .pluck(:plan_id) \ + .uniq + + template_counts = Plan.joins(:template).where(id: roleable_plan_ids) \ + .group("templates.family_id").count + most_recent_versions = Template.where(family_id: template_counts.keys) \ + .group(:family_id).maximum("version") + most_recent_versions = most_recent_versions.map { |k, v| "#{k}=#{v}" } + template_names = Template.where("CONCAT(family_id, '=', version) IN (?)", + most_recent_versions).pluck(:family_id, :title) + template_names.map do |t| + { name: t[1], count: template_counts[t[0]] } + end + + end + end end diff --git a/app/views/usage/_plans_by_template_chart.html.erb b/app/views/usage/_plans_by_template_chart.html.erb index eaf5651..c70df06 100644 --- a/app/views/usage/_plans_by_template_chart.html.erb +++ b/app/views/usage/_plans_by_template_chart.html.erb @@ -1,6 +1,6 @@ -<%# locals: data %> - - +<%# locals: data, ?subset%> +<% subset ||= "by_template" %> + + id="plans_<%= subset %>" + value="<%= prep_data_for_template_plans_chart(data: data, subset: subset) %>" /> diff --git a/app/views/usage/_total_usage.html.erb b/app/views/usage/_total_usage.html.erb index 690fdc8..2a2abfb 100644 --- a/app/views/usage/_total_usage.html.erb +++ b/app/views/usage/_total_usage.html.erb @@ -1,12 +1,5 @@ <%# locals: user_count, plan_count, separators %> -