diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index 0b373c0bd..b37351028 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -14,10 +14,15 @@ class Admin::BudgetsController < Admin::BaseController
@budget = Budget.includes(groups: :headings).find(params[:id])
end
- def new
- end
+ def new; end
- def edit
+ def edit; end
+
+ def calculate_winners
+ return unless @budget.balloting_process?
+ @budget.headings.each { |heading| Budget::Result.new(@budget, heading).calculate_winners }
+ redirect_to admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'winners'),
+ notice: I18n.t("admin.budgets.winners.calculated")
end
def update
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 1aba9dd7c..9d779299d 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -44,7 +44,7 @@ module Abilities
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
- can [:index, :read, :new, :create, :update, :destroy], Budget
+ can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget
can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update, :toggle_selection], Budget::Investment
diff --git a/app/models/budget.rb b/app/models/budget.rb
index a5932921c..bc7231f29 100644
--- a/app/models/budget.rb
+++ b/app/models/budget.rb
@@ -67,8 +67,12 @@ class Budget < ActiveRecord::Base
phase == "finished"
end
+ def balloting_process?
+ balloting? || reviewing_ballots?
+ end
+
def balloting_or_later?
- balloting? || reviewing_ballots? || finished?
+ balloting_process? || finished?
end
def on_hold?
diff --git a/app/models/budget/result.rb b/app/models/budget/result.rb
index f29bc72cc..f835bce0c 100644
--- a/app/models/budget/result.rb
+++ b/app/models/budget/result.rb
@@ -12,11 +12,10 @@ class Budget
reset_winners
investments.each do |investment|
@current_investment = investment
- if inside_budget?
- set_winner
- end
+ set_winner if inside_budget?
end
end
+ handle_asynchronously :calculate_winners
def investments
heading.investments.selected.sort_by_ballots
@@ -52,4 +51,4 @@ class Budget
end
end
-end
\ No newline at end of file
+end
diff --git a/app/views/admin/budgets/_form.html.erb b/app/views/admin/budgets/_form.html.erb
index 5d323b45c..58a56d564 100644
--- a/app/views/admin/budgets/_form.html.erb
+++ b/app/views/admin/budgets/_form.html.erb
@@ -16,5 +16,15 @@
<%= f.select :currency_symbol, budget_currency_symbol_select_options %>
- <%= f.submit nil, class: "button success" %>
+
+ <%= f.submit nil, class: "button success" %>
+ <% if @budget.balloting_process? %>
+
+ <%= link_to t("admin.budgets.winners.calculate"),
+ calculate_winners_admin_budget_path(@budget),
+ method: :put,
+ class: "button hollow" %>
+
+ <% end %>
+
<% end %>
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index baca6b270..156decd7d 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -101,6 +101,9 @@ en:
no_heading: This group has no assigned heading.
table_heading: Heading
table_amount: Amount
+ winners:
+ calculate: Calculate Winner Investments
+ calculated: Winners being calculated, it may take a minute.
budget_investments:
index:
heading_filter_all: All headings
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index f47bd19a8..ba66a4052 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -101,6 +101,9 @@ es:
no_heading: Este grupo no tiene ninguna partida asignada.
table_heading: Partida
table_amount: Cantidad
+ winners:
+ calculate: Calcular propuestas ganadoras
+ calculated: Calculando ganadoras, puede tardar un minuto.
budget_investments:
index:
heading_filter_all: Todas las partidas
diff --git a/config/locales/admin.fr.yml b/config/locales/admin.fr.yml
index 8100a95a6..549ddd813 100644
--- a/config/locales/admin.fr.yml
+++ b/config/locales/admin.fr.yml
@@ -101,6 +101,9 @@ fr:
no_heading: Ce groupe n'a pas de rubrique assignée.
table_heading: Rubrique
table_amount: Montant
+ winners:
+ calculate: Calculate Winner Investments
+ calculated: Winners being calculated, it may take a minute.
budget_investments:
index:
heading_filter_all: Toutes les rubriques
diff --git a/config/locales/admin.nl.yml b/config/locales/admin.nl.yml
index 40b21ed32..e401952c9 100755
--- a/config/locales/admin.nl.yml
+++ b/config/locales/admin.nl.yml
@@ -102,6 +102,9 @@ nl:
no_heading: This group has no assigned heading.
table_heading: Heading
table_amount: Amount
+ winners:
+ calculate: Calculate Winner Investments
+ calculated: Winners being calculated, it may take a minute.
budget_investments:
index:
heading_filter_all: All headings
diff --git a/config/routes.rb b/config/routes.rb
index e436244a1..ef476cf28 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -193,6 +193,10 @@ Rails.application.routes.draw do
end
resources :budgets do
+ member do
+ put :calculate_winners
+ end
+
resources :budget_groups do
resources :budget_headings do
end
diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb
index 760817c26..4f78f3edf 100644
--- a/spec/features/admin/budgets_spec.rb
+++ b/spec/features/admin/budgets_spec.rb
@@ -109,6 +109,33 @@ feature 'Admin budgets' do
end
+ context "Calculate Budget's Winner Investments" do
+
+ scenario 'For a Budget in reviewing balloting' do
+ budget = create(:budget, phase: 'reviewing_ballots')
+ group = create(:budget_group, budget: budget)
+ heading = create(:budget_heading, group: group, price: 4)
+ unselected_investment = create(:budget_investment, :unselected, heading: heading, price: 1, ballot_lines_count: 3)
+ winner_investment = create(:budget_investment, :winner, heading: heading, price: 3, ballot_lines_count: 2)
+ selected_investment = create(:budget_investment, :selected, heading: heading, price: 2, ballot_lines_count: 1)
+
+ visit edit_admin_budget_path(budget)
+ click_link 'Calculate Winner Investments'
+ expect(page).to have_content 'Winners being calculated, it may take a minute.'
+ expect(page).to have_content winner_investment.title
+ expect(page).not_to have_content unselected_investment.title
+ expect(page).not_to have_content selected_investment.title
+ end
+
+ scenario 'For a finished Budget' do
+ budget = create(:budget, phase: 'finished')
+
+ visit edit_admin_budget_path(budget)
+ expect(page).not_to have_content 'Calculate Winner Investments'
+ end
+
+ end
+
context 'Manage groups and headings' do
scenario 'Create group', :js do