Show only available budget stats phases
This way we can show statistics for the supports phase before the vote phase is over.
This commit is contained in:
@@ -190,12 +190,10 @@ table {
|
|||||||
|
|
||||||
tr th {
|
tr th {
|
||||||
border: 1px solid $border;
|
border: 1px solid $border;
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tiny {
|
.phase-subheader {
|
||||||
font-size: rem-calc(11);
|
font-size: rem-calc(11);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ module Abilities
|
|||||||
can [:hide, :update, :toggle_selection], Budget::Investment
|
can [:hide, :update, :toggle_selection], Budget::Investment
|
||||||
can [:valuate, :comment_valuation], Budget::Investment
|
can [:valuate, :comment_valuation], Budget::Investment
|
||||||
can :create, Budget::ValuatorAssignment
|
can :create, Budget::ValuatorAssignment
|
||||||
can :read_stats, Budget, phase: "reviewing_ballots"
|
|
||||||
|
|
||||||
can [:search, :edit, :update, :create, :index, :destroy], Banner
|
can [:search, :edit, :update, :create, :index, :destroy], Banner
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module Abilities
|
|||||||
can [:read], Budget::Group
|
can [:read], Budget::Group
|
||||||
can [:read, :print, :json_data], Budget::Investment
|
can [:read, :print, :json_data], Budget::Investment
|
||||||
can [:read_results, :read_executions], Budget, phase: "finished"
|
can [:read_results, :read_executions], Budget, phase: "finished"
|
||||||
can :read_stats, Budget, phase: "finished"
|
can(:read_stats, Budget) { |budget| budget.valuating_or_later? }
|
||||||
can :new, DirectMessage
|
can :new, DirectMessage
|
||||||
can [:read, :debate, :draft_publication, :allegations, :result_publication,
|
can [:read, :debate, :draft_publication, :allegations, :result_publication,
|
||||||
:proposals, :milestones], Legislation::Process, published: true
|
:proposals, :milestones], Legislation::Process, published: true
|
||||||
|
|||||||
@@ -3,14 +3,42 @@ class Budget::Stats
|
|||||||
alias_method :budget, :resource
|
alias_method :budget, :resource
|
||||||
|
|
||||||
def self.stats_methods
|
def self.stats_methods
|
||||||
super +
|
super + support_phase_methods + vote_phase_methods
|
||||||
%i[total_participants_support_phase total_participants_vote_phase
|
end
|
||||||
total_budget_investments total_votes total_selected_investments
|
|
||||||
total_unfeasible_investments headings]
|
def self.support_phase_methods
|
||||||
|
%i[total_participants_support_phase total_budget_investments
|
||||||
|
total_selected_investments total_unfeasible_investments headings]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.vote_phase_methods
|
||||||
|
%i[total_votes total_participants_vote_phase]
|
||||||
|
end
|
||||||
|
|
||||||
|
def stats_methods
|
||||||
|
base_stats_methods + participation_methods + phase_methods
|
||||||
|
end
|
||||||
|
|
||||||
|
def phases
|
||||||
|
%w[support vote].select { |phase| send("#{phase}_phase_finished?") }
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_phases
|
||||||
|
return phases unless phases.many?
|
||||||
|
|
||||||
|
[*phases, "every"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def support_phase_finished?
|
||||||
|
budget.valuating_or_later?
|
||||||
|
end
|
||||||
|
|
||||||
|
def vote_phase_finished?
|
||||||
|
budget.finished?
|
||||||
end
|
end
|
||||||
|
|
||||||
def participants
|
def participants
|
||||||
User.where(id: (authors + voters + balloters + poll_ballot_voters).uniq.compact)
|
User.where(id: phases.map { |phase| send("participant_ids_#{phase}_phase") }.flatten.uniq)
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_participants
|
def total_participants
|
||||||
@@ -66,6 +94,18 @@ class Budget::Stats
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def phase_methods
|
||||||
|
phases.map { |phase| self.class.send("#{phase}_phase_methods") }.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def participant_ids_support_phase
|
||||||
|
(authors + voters).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def participant_ids_vote_phase
|
||||||
|
(balloters + poll_ballot_voters).uniq
|
||||||
|
end
|
||||||
|
|
||||||
def authors
|
def authors
|
||||||
budget.investments.pluck(:author_id)
|
budget.investments.pluck(:author_id)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -80,11 +80,12 @@
|
|||||||
<div id="stats_by_phase" class="stats-group">
|
<div id="stats_by_phase" class="stats-group">
|
||||||
<h4><%= t("stats.budgets.by_phase") %></h4>
|
<h4><%= t("stats.budgets.by_phase") %></h4>
|
||||||
|
|
||||||
<%= number_with_info_tags(@stats.total_participants_support_phase,
|
<% @stats.phases.each do |phase| %>
|
||||||
t("stats.budgets.participants_support_phase")) %>
|
<%= number_with_info_tags(
|
||||||
<%= number_with_info_tags(@stats.total_participants_vote_phase,
|
@stats.send("total_participants_#{phase}_phase"),
|
||||||
t("stats.budgets.participants_voting_phase")) %>
|
t("stats.budgets.participants_#{phase}_phase")
|
||||||
|
) %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="stats_by_heading" class="stats-group">
|
<div id="stats_by_heading" class="stats-group">
|
||||||
@@ -95,20 +96,19 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="col" rowspan="2"><%= t("stats.budgets.heading") %></th>
|
<th scope="col" rowspan="2"><%= t("stats.budgets.heading") %></th>
|
||||||
<th scope="col" rowspan="2"><%= t("stats.budgets.investments_sent_html") %></th>
|
<th scope="col" rowspan="2"><%= t("stats.budgets.investments_sent_html") %></th>
|
||||||
<th scope="col" colspan="3"><%= t("stats.budgets.participants_support_phase") %></th>
|
|
||||||
<th scope="col" colspan="3"><%= t("stats.budgets.participants_voting_phase") %></th>
|
<% @stats.all_phases.each do |phase| %>
|
||||||
<th scope="col" colspan="3"><%= t("stats.budgets.participants_total") %></th>
|
<th scope="col" colspan="3">
|
||||||
|
<%= t("stats.budgets.participants_#{phase}_phase") %>
|
||||||
|
</th>
|
||||||
|
<% end %>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.total") %></th>
|
<% @stats.all_phases.each do %>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_total_participants_html") %></th>
|
<th scope="col" class="phase-subheader"><%= t("stats.budgets.total") %></th>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_heading_census_html") %></th>
|
<th scope="col" class="phase-subheader"><%= t("stats.budgets.percent_total_participants") %></th>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.total") %></th>
|
<th scope="col" class="phase-subheader"><%= t("stats.budgets.percent_heading_census") %></th>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_total_participants_html") %></th>
|
<% end %>
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_heading_census_html") %></th>
|
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.total") %></th>
|
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_total_participants_html") %></th>
|
|
||||||
<th scope="col" class="tiny"><%= t("stats.budgets.percent_heading_census_html") %></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="headings">
|
<tbody id="headings">
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
<%= @stats.headings[heading.id][:total_investments_count] %>
|
<%= @stats.headings[heading.id][:total_investments_count] %>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<% ["support", "vote", "every"].each do |phase| %>
|
<% @stats.all_phases.each do |phase| %>
|
||||||
<td id="total_participants_<%= phase %>_phase_heading_<%= heading.id %>"
|
<td id="total_participants_<%= phase %>_phase_heading_<%= heading.id %>"
|
||||||
class="border-left text-center">
|
class="border-left text-center">
|
||||||
<%= @stats.headings[heading.id]["total_participants_#{phase}_phase".to_sym] %>
|
<%= @stats.headings[heading.id]["total_participants_#{phase}_phase".to_sym] %>
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ ignore_unused:
|
|||||||
- "admin.site_customization.pages.page.status_*"
|
- "admin.site_customization.pages.page.status_*"
|
||||||
- "admin.legislation.processes.process.*"
|
- "admin.legislation.processes.process.*"
|
||||||
- "legislation.processes.index.*"
|
- "legislation.processes.index.*"
|
||||||
|
- "stats.budgets.participants_*_phase"
|
||||||
- "votes.budget_investments.different_heading_assigned*"
|
- "votes.budget_investments.different_heading_assigned*"
|
||||||
- "*.form.map_skip_checkbox"
|
- "*.form.map_skip_checkbox"
|
||||||
# - "{devise,kaminari,will_paginate}.*"
|
# - "{devise,kaminari,will_paginate}.*"
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ en:
|
|||||||
heading: "Heading"
|
heading: "Heading"
|
||||||
investments_sent_html: "Investment proposals sent"
|
investments_sent_html: "Investment proposals sent"
|
||||||
participants_support_phase: "Participants support phase"
|
participants_support_phase: "Participants support phase"
|
||||||
participants_voting_phase: "Participants voting phase"
|
participants_vote_phase: "Participants voting phase"
|
||||||
participants_total: "Total Participants"
|
participants_every_phase: "Total Participants"
|
||||||
percent_total_participants_html: "% <br>Total<br>Participants"
|
percent_total_participants: "% Total Participants"
|
||||||
percent_heading_census_html: "% <br>Heading<br>Census"
|
percent_heading_census: "% Heading Census"
|
||||||
participatory_disclaimer: "** The numbers of total participants refer to persons that created, supported or voted investment proposals."
|
participatory_disclaimer: "** The numbers of total participants refer to persons that created, supported or voted investment proposals."
|
||||||
heading_disclaimer: "*** Data about headings refer to the heading where each user voted, not necessarily the one that person is registered on."
|
heading_disclaimer: "*** Data about headings refer to the heading where each user voted, not necessarily the one that person is registered on."
|
||||||
polls:
|
polls:
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ es:
|
|||||||
heading: "Distrito"
|
heading: "Distrito"
|
||||||
investments_sent_html: "Propuestas<br>enviadas"
|
investments_sent_html: "Propuestas<br>enviadas"
|
||||||
participants_support_phase: Participantes fase apoyos
|
participants_support_phase: Participantes fase apoyos
|
||||||
participants_voting_phase: Participantes fase votación
|
participants_vote_phase: Participantes fase votación
|
||||||
participants_total: Total de participantes
|
participants_every_phase: Total de participantes
|
||||||
percent_total_participants_html: "% <br>Total<br>Participantes"
|
percent_total_participants: "% Total Participantes"
|
||||||
percent_heading_census_html: "% <br>Censo<br>Distrito"
|
percent_heading_census: "% Censo Distrito"
|
||||||
participatory_disclaimer: "** Las cifras de total de participantes se refieren a personas que han creado, apoyado o votado propuestas."
|
participatory_disclaimer: "** Las cifras de total de participantes se refieren a personas que han creado, apoyado o votado propuestas."
|
||||||
heading_disclaimer: "*** Los datos de distrito se refieren al distrito en el que el usuario ha votado, no necesariamente en el que está empadronado."
|
heading_disclaimer: "*** Los datos de distrito se refieren al distrito en el que el usuario ha votado, no necesariamente en el que está empadronado."
|
||||||
polls:
|
polls:
|
||||||
|
|||||||
@@ -8,25 +8,16 @@ feature "Stats" do
|
|||||||
|
|
||||||
describe "Show" do
|
describe "Show" do
|
||||||
|
|
||||||
it "is not accessible to normal users if phase is not 'finished'" do
|
it "is not accessible if supports phase is not finished" do
|
||||||
budget.update(phase: "reviewing_ballots")
|
budget.update(phase: "selecting")
|
||||||
|
|
||||||
visit budget_stats_path(budget.id)
|
visit budget_stats_path(budget.id)
|
||||||
expect(page).to have_content "You do not have permission to carry out the action "\
|
expect(page).to have_content "You do not have permission to carry out the action "\
|
||||||
"'read_stats' on budget."
|
"'read_stats' on budget."
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is accessible to normal users if phase is 'finished'" do
|
it "is accessible if supports phase is finished" do
|
||||||
budget.update(phase: "finished")
|
budget.update(phase: "valuating")
|
||||||
|
|
||||||
visit budget_stats_path(budget.id)
|
|
||||||
expect(page).to have_content "Stats"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "is accessible to administrators when budget has phase 'reviewing_ballots'" do
|
|
||||||
budget.update(phase: "reviewing_ballots")
|
|
||||||
|
|
||||||
login_as(create(:administrator).user)
|
|
||||||
|
|
||||||
visit budget_stats_path(budget.id)
|
visit budget_stats_path(budget.id)
|
||||||
expect(page).to have_content "Stats"
|
expect(page).to have_content "Stats"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Budget::Stats do
|
describe Budget::Stats do
|
||||||
let(:budget) { create(:budget) }
|
let(:budget) { create(:budget, :finished) }
|
||||||
let(:stats) { Budget::Stats.new(budget) }
|
let(:stats) { Budget::Stats.new(budget) }
|
||||||
let(:investment) { create(:budget_investment, :selected, budget: budget) }
|
let(:investment) { create(:budget_investment, :selected, budget: budget) }
|
||||||
|
|
||||||
@@ -213,4 +213,75 @@ describe Budget::Stats do
|
|||||||
expect(heading_stats[:percentage_district_population_every_phase]).to be 0.243
|
expect(heading_stats[:percentage_district_population_every_phase]).to be 0.243
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#support_phase_finished?" do
|
||||||
|
context "support phase isn't finished" do
|
||||||
|
before { budget.phase = "selecting" }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
expect(stats.support_phase_finished?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "support phase is finished" do
|
||||||
|
before { budget.phase = "valuating" }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
expect(stats.support_phase_finished?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#vote_phase_finished" do
|
||||||
|
context "support phase isn't finished" do
|
||||||
|
before { budget.phase = "reviewing_ballots" }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
expect(stats.vote_phase_finished?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "vote phase is finished" do
|
||||||
|
before { budget.phase = "finished" }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
expect(stats.vote_phase_finished?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#all_phases" do
|
||||||
|
context "no phases are finished" do
|
||||||
|
before do
|
||||||
|
allow(stats).to receive(:support_phase_finished?).and_return(false)
|
||||||
|
allow(stats).to receive(:vote_phase_finished?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns an empty array" do
|
||||||
|
expect(stats.all_phases).to eq []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "one phase is finished" do
|
||||||
|
before do
|
||||||
|
allow(stats).to receive(:support_phase_finished?).and_return(true)
|
||||||
|
allow(stats).to receive(:vote_phase_finished?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the finished phase" do
|
||||||
|
expect(stats.all_phases).to eq ["support"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "all phases are finished" do
|
||||||
|
before do
|
||||||
|
allow(stats).to receive(:support_phase_finished?).and_return(true)
|
||||||
|
allow(stats).to receive(:vote_phase_finished?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the finished phases and a total phase" do
|
||||||
|
expect(stats.all_phases).to eq ["support", "vote", "every"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user