Partial to render the polls stats and model methods to get the information from DB

This commit is contained in:
iagirre
2017-10-17 15:04:29 +02:00
parent 78cc09cc5a
commit 6a292daf42
10 changed files with 343 additions and 189 deletions

View File

@@ -1,20 +0,0 @@
class Polls::StatsController < ApplicationController
before_action :load_poll
load_and_authorize_resource :poll
def show
authorize! :read_stats, @poll
@stats = load_stats
end
private
def load_stats
Poll::Stats.new(@poll).generate
end
def load_poll
@poll = Poll.find_by(id: params[:id])
end
end

View File

@@ -25,6 +25,8 @@ class PollsController < ApplicationController
@commentable = @poll @commentable = @poll
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order) @comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
@stats = Poll::Stats.new(@poll).generate
end end
end end

View File

@@ -6,26 +6,115 @@ class Poll
end end
def generate def generate
stats = %w[total_participants total_participants_web total_participants_booth] stats = %w[total_participants total_participants_web total_web_valid total_web_white total_web_null
total_participants_booth total_booth_valid total_booth_white total_booth_null
total_valid_votes total_white_votes total_null_votes valid_percentage_web valid_percentage_booth
total_valid_percentage white_percentage_web white_percentage_booth total_white_percentage
null_percentage_web null_percentage_booth total_null_percentage total_participants_web_percentage
total_participants_booth_percentage]
stats.map { |stat_name| [stat_name.to_sym, send(stat_name)] }.to_h stats.map { |stat_name| [stat_name.to_sym, send(stat_name)] }.to_h
end end
private private
def total_participants def total_participants
stats_cache('total_participants') { voters.uniq.count } total_participants_web + total_participants_booth
end end
def total_participants_web def total_participants_web
stats_cache('total_participants_web') { voters.where(origin: 'web').count } total_web_valid + total_web_white + total_web_null
end
def total_participants_web_percentage
total_participants_web * 100 / total_participants
end end
def total_participants_booth def total_participants_booth
stats_cache('total_participants_booth') { voters.where(origin: 'booth').count } voters.where(origin: 'booth').count
end
def total_participants_booth_percentage
(total_participants) == 0 ? 0 : total_participants_booth * 100 / total_participants.to_f
end
def total_web_valid
voters.where(origin: 'web').count
end
def valid_percentage_web
(total_valid_votes) == 0 ? 0 : total_web_valid * 100 / total_valid_votes.to_f
end
def total_web_white
0
end
def white_percentage_web
0
end
def total_web_null
0
end
def null_percentage_web
0
end
def total_booth_valid
recounts.sum(:total_amount)
end
def valid_percentage_booth
(total_valid_votes) == 0 ? 0 : total_booth_valid * 100 / total_valid_votes.to_f
end
def total_booth_white
recounts.sum(:white_amount)
end
def white_percentage_booth
(total_white_votes) == 0 ? 0 : total_booth_white * 100 / total_white_votes.to_f
end
def total_booth_null
recounts.sum(:null_amount)
end
def null_percentage_booth
(total_null_votes == 0) ? 0 : total_booth_null * 100 / total_null_votes.to_f
end
def total_valid_votes
total_web_valid + total_booth_valid
end
def total_valid_percentage
(total_participants) == 0 ? 0 : total_valid_votes * 100 / total_participants.to_f
end
def total_white_votes
total_web_white + total_booth_white
end
def total_white_percentage
(total_participants) == 0 ? 0 : total_white_votes * 100 / total_participants.to_f
end
def total_null_votes
total_web_null + total_booth_null
end
def total_null_percentage
(total_participants) == 0 ? 0 : total_null_votes * 100 / total_participants.to_f
end end
def voters def voters
stats_cache('voters') { @poll.voters } @poll.voters
end
def recounts
@poll.recounts
end end
def stats_cache(key, &block) def stats_cache(key, &block)

View File

@@ -0,0 +1,20 @@
<div class="row">
<div class="small-12 column">
<ul class="tabs" data-tabs id="polls-tabs">
<li class="tabs-title is-active">
<%= link_to "#tab-stats" do %>
<h3>
<%= "Estadísticas" %> <!-- t("polls.show.comments_tab") -->
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-information" do %>
<h3>
<%= "Información" %>
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,111 @@
<div class="row margin">
<div class="small-12 medium-9 column">
<%= render "callout" %>
<% if @poll.voted_in_booth?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_booth") %>
</div>
<% else %>
<% if current_user && !@poll.votable_by?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_web") %>
</div>
<% end %>
<% end %>
<% @questions.each do |question| %>
<%= render 'polls/questions/question', question: question, token: @token %>
<% end %>
<% if poll_voter_token(@poll, current_user).empty? %>
<div class="callout token-message js-token-message" style="display: none">
<%= t('poll_questions.show.voted_token') %>
</div>
<% end %>
<%= link_to t("polls.show.participate_in_other_polls"), polls_path, class: "button hollow" %>
</div>
</div>
<div class="expanded poll-more-info">
<div class="row margin">
<div class="small-12 medium-9 column">
<h3><%= t("polls.show.more_info_title") %></h3>
<%= safe_html_with_links simple_format(@poll.description) %>
</div>
<% if false %>
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("polls.show.documents") %></h2>
</aside>
<% end %>
</div>
</div>
<div class="expanded poll-more-info-answers">
<div class="row padding">
<% @poll_questions_answers.each do |answer| %>
<div class="small-12 medium-6 column end" id="answer_<%= answer.id %>"
data-toggler="medium-6 answer-divider">
<% if answer.description.present? %>
<h3><%= answer.title %></h3>
<% end %>
<% if answer.images.any? %>
<%= render "gallery", answer: answer %>
<% end %>
<% if answer.description.present? %>
<div class="margin-top">
<div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short">
<%= safe_html_with_links simple_format(answer.description) %>
</div>
<div class="margin">
<a id="read_more_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide">
<%= t("polls.show.read_more", answer: answer.title) %>
</a>
<a id="read_less_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide"
class="hide">
<%= t("polls.show.read_less", answer: answer.title) %>
</a>
</div>
</div>
<% end %>
<% if answer.documents.present? %>
<div class="document-link">
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t("polls.show.documents") %></strong>
</p>
<% answer.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
target: "_blank",
rel: "nofollow" %><br>
<% end %>
</div>
<% end %>
</div>
<% end %>
</div>
</div>
<div class="tabs-content" data-tabs-content="proposals-tabs" role="tablist">
<%= render "filter_subnav" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render "comments" %>
</div>
</div>

View File

@@ -29,117 +29,15 @@
</div> </div>
</div> </div>
<%= link_to "Estadísticas", custom_poll_stats_path(@poll.id) %> <div class="tabs-content" data-tabs-content="polls-tabs" role="tablist">
<%= render "results_subnavigation" %>
<div class="row margin"> <div id="tab-stats" class="tabs-panel is-active">
<div class="small-12 medium-9 column"> <%= render "polls/stats/show" %>
<%= render "callout" %>
<% if @poll.voted_in_booth?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_booth") %>
</div> </div>
<% else %> <div id="tab-information" class="tabs-panel">
<%= render "show" %>
<% if current_user && !@poll.votable_by?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_web") %>
</div> </div>
<% end %>
<% end %>
<% @questions.each do |question| %>
<%= render 'polls/questions/question', question: question, token: @token %>
<% end %>
<% if poll_voter_token(@poll, current_user).empty? %>
<div class="callout token-message js-token-message" style="display: none">
<%= t('poll_questions.show.voted_token') %>
</div>
<% end %>
<%= link_to t("polls.show.participate_in_other_polls"), polls_path, class: "button hollow" %>
</div>
</div>
<div class="expanded poll-more-info">
<div class="row margin">
<div class="small-12 medium-9 column">
<h3><%= t("polls.show.more_info_title") %></h3>
<%= safe_html_with_links simple_format(@poll.description) %>
</div>
<% if false %>
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("polls.show.documents") %></h2>
</aside>
<% end %>
</div>
</div>
<div class="expanded poll-more-info-answers">
<div class="row padding">
<% @poll_questions_answers.each do |answer| %>
<div class="small-12 medium-6 column end" id="answer_<%= answer.id %>"
data-toggler="medium-6 answer-divider">
<% if answer.description.present? %>
<h3><%= answer.title %></h3>
<% end %>
<% if answer.images.any? %>
<%= render "gallery", answer: answer %>
<% end %>
<% if answer.description.present? %>
<div class="margin-top">
<div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short">
<%= safe_html_with_links simple_format(answer.description) %>
</div>
<div class="margin">
<a id="read_more_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide">
<%= t("polls.show.read_more", answer: answer.title) %>
</a>
<a id="read_less_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide"
class="hide">
<%= t("polls.show.read_less", answer: answer.title) %>
</a>
</div>
</div>
<% end %>
<% if answer.documents.present? %>
<div class="document-link">
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t("polls.show.documents") %></strong>
</p>
<% answer.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
target: "_blank",
rel: "nofollow" %><br>
<% end %>
</div>
<% end %>
</div>
<% end %>
</div>
</div> </div>
</div> </div>
<div class="tabs-content" data-tabs-content="proposals-tabs" role="tablist">
<%= render "filter_subnav" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render "comments" %>
</div>
</div>

View File

@@ -0,0 +1,85 @@
<div class="row">
<div class="small-12 medium-3 column sidebar">
<p><%= t("polls.show.stats.title") %></p>
<ul class="menu vertical margin-top">
<li><a href="#total"><%= t("polls.show.stats.total_participation") %></a></li>
</ul>
</div>
<div class="small-12 medium-9 column">
<h3 id="total"><%= t("polls.show.stats.total_participation") %></h3>
<p class="stat-number margin-top">
<%= t("polls.show.stats.total_votes") %><br>
<span><%= @stats[:total_participants] %></span>
</p>
<table class="polls-total-stats">
<thead>
<tr>
<th scope="col"><%= t("polls.show.stats.votes") %></th>
<th scope="col"><%= t("polls.show.stats.web") %></th>
<th scope="col"><%= t("polls.show.stats.booth") %></th>
<th scope="col"><%= t("polls.show.stats.total") %></th>
</tr>
</thead>
<tbody>
<tr>
<th><%= t("polls.show.stats.valid") %></th>
<td><%= @stats[:total_web_valid] %> <small><em>
(<%= number_to_percentage(@stats[:valid_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_valid] %> <small><em>
(<%= number_to_percentage(@stats[:valid_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_valid_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_valid_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.white") %></th>
<td><%= @stats[:total_web_white] %> <small><em>
(<%= number_to_percentage(@stats[:white_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_white] %> <small><em>
(<%= number_to_percentage(@stats[:white_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_white_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_white_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.null_votes") %></th>
<td><%= @stats[:total_web_null] %> <small><em>
(<%= number_to_percentage(@stats[:null_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_null] %> <small><em>
(<%= number_to_percentage(@stats[:null_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_null_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_null_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.total") %></th>
<td><%= @stats[:total_participants_web] %> <small><em>
(<%= number_to_percentage(@stats[:total_participants_web_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_participants_booth] %> <small><em>
(<%= number_to_percentage(@stats[:total_participants_booth_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_participants_web] + @stats[:total_participants_booth] %></td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -1,53 +0,0 @@
<% cache [@stats] do %>
<% provide :title do %>
<%= t("polls.stats.page_title", poll: @poll.name) %>
<% end %>
<% provide :social_media_meta_tags do %>
<%= render "shared/social_media_meta_tags",
social_url: poll_url(@poll),
social_title: @poll.name,
social_description: @poll.description %>
<% end %>
<div class="budgets-stats">
<div class="expanded no-margin-top padding header">
<div class="row">
<div class="small-12 column text-center">
<%= back_link_to polls_path %>
<h1 class="title"><%= t("polls.stats.title") %><br><%= @poll.name %></h1>
</div>
</div>
</div>
<!-- Aquí se empiezan a mostrar los datos -->
<div class="row">
<div class="small-12 medium-6 column">
<div class="callout">
<span class="uppercase"><%= t("polls.stats.total_participants") %></span>
<p id="total_participants" class="big-number-stat budget">
<%= @stats[:total_participants] %>
</p>
<table>
<thead>
<tr>
<td>Web</td>
<td>Booth</td>
</tr>
</thead>
<tbody>
<tr>
<td><%= @stats[:total_participants_web] %></td>
<td><%= @stats[:total_participants_booth] %></td>
</tr>
</tbody>
</table>
<span class="uppercase"><%= t("polls.stats.total_votes") %></span>
<p class="big-number-stat budget">
<%= @stats[:total_votes] %>
</p>
</div>
</div>
</div>
</div>
<% end %>

View File

@@ -497,6 +497,17 @@ en:
read_more: "Read more about %{answer}" read_more: "Read more about %{answer}"
read_less: "Read less about %{answer}" read_less: "Read less about %{answer}"
participate_in_other_polls: Participate in other polls participate_in_other_polls: Participate in other polls
stats:
title: "Participation data"
total_participation: "Total participation"
total_votes: "Total amount of given votes"
votes: "VOTES"
web: "WEB"
booth: "BOOTH"
total: "TOTAL"
valid: "Valid"
white: "White votes"
null_votes: "Invalid"
poll_questions: poll_questions:
create_question: "Create question" create_question: "Create question"
default_valid_answers: "Yes, No" default_valid_answers: "Yes, No"

View File

@@ -497,6 +497,17 @@ es:
read_more: "Leer más sobre %{answer}" read_more: "Leer más sobre %{answer}"
read_less: "Leer menos sobre %{answer}" read_less: "Leer menos sobre %{answer}"
participate_in_other_polls: Participar en otras votaciones participate_in_other_polls: Participar en otras votaciones
stats:
title: "Datos de participación"
total_participation: "Participación total"
total_votes: "Nº total de votos emitidos"
votes: "VOTOS"
web: "WEB"
booth: "URNAS"
total: "TOTAL"
valid: "Válidos"
white: "En blanco"
null_votes: "Nulos"
poll_questions: poll_questions:
create_question: "Crear pregunta para votación" create_question: "Crear pregunta para votación"
default_valid_answers: "Sí, No" default_valid_answers: "Sí, No"