diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 3360dc047..5aa952bb4 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -37,7 +37,7 @@ module Statisticable end def participants_by_geozone - Geozone.all.order("name").map do |geozone| + geozones.map do |geozone| count = participants.where(geozone: geozone).count [ @@ -103,6 +103,10 @@ module Statisticable participants.between_ages(from, to) end + def geozones + Geozone.all.order("name") + end + def calculate_percentage(fraction, total) return 0.0 if total.zero? diff --git a/app/models/poll/stats.rb b/app/models/poll/stats.rb index b9938df64..c171d1900 100644 --- a/app/models/poll/stats.rb +++ b/app/models/poll/stats.rb @@ -19,7 +19,8 @@ class Poll::Stats total_female_web total_female_booth total_female_mail male_web_percentage male_booth_percentage male_mail_percentage female_web_percentage female_booth_percentage female_mail_percentage - web_participants_by_age booth_participants_by_age mail_participants_by_age] + web_participants_by_age booth_participants_by_age mail_participants_by_age + web_participants_by_geozone booth_participants_by_geozone mail_participants_by_geozone] end @@ -47,6 +48,19 @@ class Poll::Stats relative_to: :participants_between_ages) end + define_method :"#{channel}_participants_by_geozone" do + geozones.map do |geozone| + count = send(:"#{channel}_participants").where(geozone: geozone).count + [ + geozone.name, + { + count: count, + percentage: calculate_percentage(count, participants.where(geozone: geozone).count) + } + ] + end.to_h + end + %i[male female].each do |gender| define_method :"total_#{gender}_#{channel}" do send(:"#{channel}_participants").public_send(gender).count diff --git a/app/views/polls/stats.html.erb b/app/views/polls/stats.html.erb index f30dc7175..370ace908 100644 --- a/app/views/polls/stats.html.erb +++ b/app/views/polls/stats.html.erb @@ -15,11 +15,14 @@ <%= link_to t("stats.polls.by_channel"), "#stats_by_channel" %>
  • - <%= link_to t("stats.polls.by_gender_and_channel"), "#stats_by_gender_and_channel"%> + <%= link_to t("stats.polls.by_gender_and_channel"), "#stats_by_gender_and_channel" %>
  • <%= link_to t("stats.polls.by_age_and_channel"), "#stats_by_age_and_channel" %>
  • +
  • + <%= link_to t("stats.polls.by_geozone_and_channel"), "#stats_by_geozone_and_channel "%> +
  • <%= link_to t("stats.polls.vote_by_channel"), "#vote_stats_by_channel" %>
  • @@ -107,6 +110,39 @@ +
    +

    <%= t("stats.polls.by_geozone_and_channel") %>

    + + + + + + <% Poll::Stats::CHANNELS.each do |channel| %> + + <% end %> + + + + <% @stats[:web_participants_by_geozone].keys.each do |name| %> + + + + <% Poll::Stats::CHANNELS.each do |channel| %> + <% group = @stats[:"#{channel}_participants_by_geozone"][name] %> + + <% end %> + + <% end %> + +
    <%= t("stats.geozone") %><%= t("stats.polls.#{channel}") %>
    <%= name %> +
    + + +
    + <%= "#{group[:count]} (#{number_to_stats_percentage(group[:percentage])})" %> +
    +
    +

    <%= t("stats.polls.vote_by_channel") %>

    diff --git a/config/locales/en/stats.yml b/config/locales/en/stats.yml index db3ce9f0e..577bf03b8 100644 --- a/config/locales/en/stats.yml +++ b/config/locales/en/stats.yml @@ -20,6 +20,7 @@ en: by_channel: "Participants by channel" by_gender_and_channel: "Participants by gender and channel" by_age_and_channel: "Participants by age and channel" + by_geozone_and_channel: "Participants by district and channel" vote_by_channel: "Vote type by channel" web: "Web" booth: "Booths" diff --git a/config/locales/es/stats.yml b/config/locales/es/stats.yml index 39cca0d47..d2d2a3e14 100644 --- a/config/locales/es/stats.yml +++ b/config/locales/es/stats.yml @@ -20,6 +20,7 @@ es: by_channel: "Participación por medio" by_gender_and_channel: "Participación por género y medio" by_age_and_channel: "Participación por edad y medio" + by_geozone_and_channel: "Participación por distrito y medio" vote_by_channel: "Votos emitidos por medio" web: "Web" booth: "Urnas" diff --git a/spec/models/poll/stats_spec.rb b/spec/models/poll/stats_spec.rb index 898ee4091..3b064ccf4 100644 --- a/spec/models/poll/stats_spec.rb +++ b/spec/models/poll/stats_spec.rb @@ -260,6 +260,48 @@ describe Poll::Stats do expect(stats.booth_participants_by_age["50 - 54"][:percentage]).to eq(25.0) end end + + describe "participants by geozone and channel" do + before do + atlantis = create(:geozone, name: "Atlantis") + lemuria = create(:geozone, name: "Lemuria") + + 4.times do + create :poll_voter, :from_booth, poll: poll, + user: create(:user, :level_two, geozone: atlantis) + end + + 3.times do + create :poll_voter, :from_booth, poll: poll, + user: create(:user, :level_two, geozone: lemuria) + end + + 2.times do + create :poll_voter, :from_web, poll: poll, + user: create(:user, :level_two, geozone: atlantis) + end + + 1.times do + create :poll_voter, :from_web, poll: poll, + user: create(:user, :level_two, geozone: lemuria) + end + end + + it "calculates the count of users by channel and geozone" do + expect(stats.booth_participants_by_geozone["Atlantis"][:count]).to eq(4) + expect(stats.booth_participants_by_geozone["Lemuria"][:count]).to eq(3) + expect(stats.web_participants_by_geozone["Atlantis"][:count]).to eq(2) + expect(stats.web_participants_by_geozone["Lemuria"][:count]).to eq(1) + end + + it "calculates percentage relative to the participants for that geozone" do + expect(stats.booth_participants_by_geozone["Atlantis"][:percentage]).to eq(66.667) + expect(stats.web_participants_by_geozone["Atlantis"][:percentage]).to eq(33.333) + + expect(stats.booth_participants_by_geozone["Lemuria"][:percentage]).to eq(75.0) + expect(stats.web_participants_by_geozone["Lemuria"][:percentage]).to eq(25.0) + end + end end describe "#generate" do