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