diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb index 5dabd3f82..1bacf1139 100644 --- a/app/helpers/stats_helper.rb +++ b/app/helpers/stats_helper.rb @@ -30,9 +30,4 @@ module StatsHelper opt[:data][:graph] = admin_api_stats_path(budget_investments: true) content_tag :div, "", opt end - - def calculate_percentage(fraction, total) - percent = fraction / total.to_f - percent.nan? ? 0.0 : (percent * 100).round(3) - end end diff --git a/app/models/budget/stats.rb b/app/models/budget/stats.rb index cbcde4703..24ba6fafc 100644 --- a/app/models/budget/stats.rb +++ b/app/models/budget/stats.rb @@ -3,11 +3,11 @@ class Budget::Stats alias_method :budget, :resource def self.stats_methods - %i[total_participants total_participants_support_phase total_participants_vote_phase - total_budget_investments total_votes total_selected_investments - total_unfeasible_investments total_male_participants total_female_participants - total_supports total_unknown_gender_or_age age_groups male_percentage - female_percentage headings total_participants_web total_participants_booths] + super + + %i[total_participants_support_phase total_participants_vote_phase + total_budget_investments total_votes total_selected_investments + total_unfeasible_investments total_supports headings + total_participants_web total_participants_booths] end private @@ -48,54 +48,10 @@ class Budget::Stats budget.investments.unfeasible.count end - def total_male_participants - participants.where(gender: "male").count - end - - def total_female_participants - participants.where(gender: "female").count - end - def total_supports supports(budget).count end - def total_unknown_gender_or_age - participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count - end - - def age_groups - groups = Hash.new(0) - ["16 - 19", - "20 - 24", - "25 - 29", - "30 - 34", - "35 - 39", - "40 - 44", - "45 - 49", - "50 - 54", - "55 - 59", - "60 - 64", - "65 - 69", - "70 - 140"].each do |group| - start, finish = group.split(" - ") - group_name = (group == "70 - 140" ? "+ 70" : group) - groups[group_name] = User.where(id: participants) - .where("date_of_birth > ? AND date_of_birth < ?", - finish.to_i.years.ago.beginning_of_year, - start.to_i.years.ago.end_of_year).count - end - groups - end - - def male_percentage - total_male_participants / total_participants_with_gender.to_f * 100 - end - - def female_percentage - total_female_participants / total_participants_with_gender.to_f * 100 - end - def participants User.where(id: (authors + voters + balloters + poll_ballot_voters).uniq.compact) end @@ -116,10 +72,6 @@ class Budget::Stats budget&.poll ? budget.poll.voters.pluck(:user_id) : [] end - def total_participants_with_gender - participants.where.not(gender: nil).distinct.count - end - def balloters_by_heading(heading_id) stats_cache("balloters_by_heading_#{heading_id}") do budget.ballots.joins(:lines).where(budget_ballot_lines: {heading_id: heading_id}).pluck(:user_id) @@ -188,11 +140,6 @@ class Budget::Stats calculate_percentage(participants, population) end - def calculate_percentage(fraction, total) - percent = fraction / total.to_f - percent.nan? ? 0.0 : (percent * 100).round(3) - end - def supports(supportable) ActsAsVotable::Vote.where(votable_type: "Budget::Investment", votable_id: supportable.investments.pluck(:id)) end diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 0a8032e3d..6548df8c6 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -11,9 +11,71 @@ module Statisticable def generate self.class.stats_methods.map { |stat_name| [stat_name, send(stat_name)] }.to_h end + + private + + def total_participants_with_gender + participants.where.not(gender: nil).distinct.count + end + + def total_male_participants + participants.where(gender: "male").count + end + + def total_female_participants + participants.where(gender: "female").count + end + + def total_unknown_gender_or_age + participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count + end + + def male_percentage + calculate_percentage(total_male_participants, total_participants_with_gender) + end + + def female_percentage + calculate_percentage(total_female_participants, total_participants_with_gender) + end + + def age_groups + groups = Hash.new(0) + ["16 - 19", + "20 - 24", + "25 - 29", + "30 - 34", + "35 - 39", + "40 - 44", + "45 - 49", + "50 - 54", + "55 - 59", + "60 - 64", + "65 - 69", + "70 - 140"].each do |group| + start, finish = group.split(" - ") + group_name = (group == "70 - 140" ? "+ 70" : group) + groups[group_name] = User.where(id: participants) + .where("date_of_birth > ? AND date_of_birth < ?", + finish.to_i.years.ago.beginning_of_year, + start.to_i.years.ago.end_of_year).count + end + groups + end + + def calculate_percentage(fraction, total) + return 0.0 if total.zero? + + (fraction * 100.0 / total).round(3) + end end class_methods do + def stats_methods + %i[total_participants total_male_participants + total_female_participants total_unknown_gender_or_age + male_percentage female_percentage age_groups] + end + def stats_cache(*method_names) method_names.each do |method_name| alias_method :"raw_#{method_name}", method_name diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb index 2b40f2daf..ebba64b35 100644 --- a/app/models/poll/stats.rb +++ b/app/models/poll/stats.rb @@ -1,6 +1,5 @@ class Poll::Stats include Statisticable - include StatsHelper alias_method :poll, :resource def self.stats_methods diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index a89277ac4..d472ebc3d 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -86,7 +86,7 @@ <%= @stats[:total_participants_booth] %> (<%= @stats[:total_participants_booth_percentage].round(2) %>%) -