diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index f6463175e..eb938c9b3 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -5,7 +5,7 @@
//= require admin_valuators_forms
var initialize_admin_modules = function() {
-
+ App.AdminValuatorsForms.initialize();
};
$(function(){
diff --git a/app/assets/javascripts/admin_valuators_forms.js.coffee b/app/assets/javascripts/admin_valuators_forms.js.coffee
new file mode 100644
index 000000000..559d82e50
--- /dev/null
+++ b/app/assets/javascripts/admin_valuators_forms.js.coffee
@@ -0,0 +1,17 @@
+App.AdminValuatorsForms =
+
+ initialize: ->
+ $('#spending_proposal_administrator_id').unbind('change').on('change', ->
+ $('#administrator_assignment_form').submit()
+ false
+ )
+
+ $('#assign-valuators-link').unbind('click').on('click', ->
+ $('#valuators-assign-list').toggle("down")
+ false
+ )
+
+ $('.js-assign-valuators-check').unbind('change').on('change', ->
+ $('#valuators_assignment_form').submit()
+ false
+ )
diff --git a/app/assets/javascripts/stat_graphs.js b/app/assets/javascripts/stat_graphs.js
index e21d88ff0..c5bc5b538 100644
--- a/app/assets/javascripts/stat_graphs.js
+++ b/app/assets/javascripts/stat_graphs.js
@@ -8,7 +8,6 @@ var initialize_stats_modules = function() {
};
$(function(){
-
$(document).ready(initialize_stats_modules);
$(document).on('page:load', initialize_stats_modules);
$(document).on('ajax:complete', initialize_stats_modules);
diff --git a/app/controllers/admin/spending_proposals_controller.rb b/app/controllers/admin/spending_proposals_controller.rb
index 3e0be1bf5..b758bd10d 100644
--- a/app/controllers/admin/spending_proposals_controller.rb
+++ b/app/controllers/admin/spending_proposals_controller.rb
@@ -1,25 +1,27 @@
class Admin::SpendingProposalsController < Admin::BaseController
include FeatureFlags
+ feature_flag :spending_proposals
load_and_authorize_resource
- feature_flag :spending_proposals
-
def index
@spending_proposals = @spending_proposals.includes([:geozone], [administrator: :user]).order(created_at: :desc).page(params[:page])
end
def show
+ @admins = Administrator.includes(:user).all
+ @valuators = Valuator.includes(:user).all.order("users.username ASC")
end
- def accept
- @spending_proposal.accept
- redirect_to request.query_parameters.merge(action: :index)
+ def assign_admin
+ @spending_proposal.update(params.require(:spending_proposal).permit(:administrator_id))
+ render nothing: true
end
- def reject
- @spending_proposal.reject
- redirect_to request.query_parameters.merge(action: :index)
+ def assign_valuators
+ params[:spending_proposal] ||= {}
+ params[:spending_proposal][:valuator_ids] ||= []
+ @spending_proposal.update(params.require(:spending_proposal).permit(valuator_ids: []))
end
end
diff --git a/app/views/admin/spending_proposals/_assigned_valuators.html.erb b/app/views/admin/spending_proposals/_assigned_valuators.html.erb
new file mode 100644
index 000000000..09e144dcd
--- /dev/null
+++ b/app/views/admin/spending_proposals/_assigned_valuators.html.erb
@@ -0,0 +1,9 @@
+
+ <% @spending_proposal.valuators.each do |valuator| %>
+ - <%= valuator.name %> (<%= valuator.email %>)
+ <% end %>
+
+ <% if @spending_proposal.valuators.empty? %>
+ - <%= t("admin.spending_proposals.show.undefined") %>
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/admin/spending_proposals/assign_valuators.js.coffee b/app/views/admin/spending_proposals/assign_valuators.js.coffee
new file mode 100644
index 000000000..afe581e59
--- /dev/null
+++ b/app/views/admin/spending_proposals/assign_valuators.js.coffee
@@ -0,0 +1 @@
+$('#assigned_valuators').html("<%= j(render 'assigned_valuators') %>")
\ No newline at end of file
diff --git a/app/views/admin/spending_proposals/show.html.erb b/app/views/admin/spending_proposals/show.html.erb
index 016c5e630..a18a80f9e 100644
--- a/app/views/admin/spending_proposals/show.html.erb
+++ b/app/views/admin/spending_proposals/show.html.erb
@@ -1,25 +1,78 @@
-<%= @spending_proposal.title %>
+<%= t("admin.spending_proposals.show.heading") %> <%= @spending_proposal.id %>
+<%= @spending_proposal.title %>
-<%= safe_html_with_links @spending_proposal.description.html_safe %>
+<%= safe_html_with_links @spending_proposal.description %>
<% if @spending_proposal.external_url.present? %>
<%= text_with_links @spending_proposal.external_url %>
<% end %>
-<%= t("admin.spending_proposals.show.by") %>:
+
<%= t("admin.spending_proposals.show.info") %>
+
+<%= t("admin.spending_proposals.show.by") %>:
<%= link_to @spending_proposal.author.name, admin_user_path(@spending_proposal.author) %>
-<%= t("admin.spending_proposals.show.association_name") %>:
- <%= @spending_proposal.association_name %>
-
-<%= t("admin.spending_proposals.show.geozone") %>:
+
+<% if @spending_proposal.association_name.present? %>
+
<%= t("admin.spending_proposals.show.association_name") %>:
+ <%= @spending_proposal.association_name %>
+
+<% end %>
+
+<%= t("admin.spending_proposals.show.geozone") %>:
<%= geozone_name(@spending_proposal) %>
+
+<%= t("admin.spending_proposals.show.sent") %>:
+ <%= l @spending_proposal.created_at, format: :datetime %>
+<%= t("admin.spending_proposals.show.responsibles") %>
-<%= t("admin.spending_proposals.show.dossier") %>:
+<%= t("admin.spending_proposals.show.assigned_admin") %>:
+ <%= form_for(@spending_proposal, url: assign_admin_admin_spending_proposal_path(@spending_proposal), remote: true, html: {id: 'administrator_assignment_form'}) do |f| %>
+ <%= f.select :administrator_id, @admins.collect { |a| [ "#{a.name} (#{a.email})", a.id ] }, {include_blank: t("admin.spending_proposals.show.undefined"), label: false} %>
+ <% end %>
+
-<%= t("admin.spending_proposals.show.price") %>: <%= @spending_proposal.price %>
-<%= t("admin.spending_proposals.show.feasibility") %>: <%= t("admin.spending_proposals.show.#{@spending_proposal.feasibility}") %>
+<%= t("admin.spending_proposals.show.assigned_valuators") %>:
+
+ <%= render "assigned_valuators" %>
+
+<%= link_to t("admin.spending_proposals.show.assign_valuators"), "", id: "assign-valuators-link" %>
+
+
+ <%= form_for(@spending_proposal, url: assign_valuators_admin_spending_proposal_path(@spending_proposal), remote: true, html: {id: 'valuators_assignment_form'}) do |f| %>
+ <% @valuators.each do |valuator| -%>
+
+ <%= check_box_tag "valuator_ids_#{valuator.id}", valuator.id, @spending_proposal.valuators.include?(valuator),
+ name: 'spending_proposal[valuator_ids][]',
+ class: "js-assign-valuators-check" %>
+ <%= label_tag "valuator_ids_#{valuator.id}", valuator.name %>
+
+ <% end -%>
+ <% end -%>
+
+
+
+<%= t("admin.spending_proposals.show.dossier") %>
+
+<%= t("admin.spending_proposals.show.price") %> (<%= t("admin.spending_proposals.show.currency") %>):
+ <%= @spending_proposal.price.present? ? @spending_proposal.price : t("admin.spending_proposals.show.undefined") %>
+
+<%= simple_format(safe_html_with_links(@spending_proposal.price_explanation.html_safe), {}, sanitize: false) if @spending_proposal.price_explanation.present? %>
+
+<%= t("admin.spending_proposals.show.feasibility") %>:
+ <%= t("admin.spending_proposals.show.#{@spending_proposal.feasibility}") %>
+
+<%= simple_format(safe_html_with_links(@spending_proposal.feasible_explanation.html_safe), {}, sanitize: false) if @spending_proposal.feasible_explanation.present? %>
+
+<% if @spending_proposal.valuation_finished %>
+ <%= t("admin.spending_proposals.show.valuation_finished") %>
+<% end %>
+
+<% if @spending_proposal.internal_comments.present? %>
+
<%= t("admin.spending_proposals.show.internal_comments") %>
+ <%= simple_format(safe_html_with_links(@spending_proposal.internal_comments.html_safe), {}, sanitize: false) %>
+<% end %>
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 6f90446d7..7d3aef540 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -145,15 +145,26 @@ en:
unresolved: Unresolved
title: Spending proposals for participatory budgeting
show:
+ heading: Investment project
+ info: Author info
association_name: Asociación
by: Sent by
+ sent: Sent at
geozone: Scope
dossier: Dossier
price: Price
+ currency: "€"
feasibility: Feasibility
feasible: Feasible
not_feasible: Not feasible
undefined: Undefined
+ valuation_finished: Valuation finished
+ internal_comments: Internal comments
+ responsibles: Responsibles
+ assigned_admin: Assigned admin
+ assigned_valuators: Assigned valuators
+ assign_valuators: Assign valuators
+ assign: Assign
stats:
show:
stats_title: Stats
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 5a1ecafab..8d2815423 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -57,7 +57,7 @@ es:
officials: Cargos públicos
organizations: Organizaciones
settings: Configuración global
- spending_proposals: Propuestas de gasto
+ spending_proposals: Propuestas de inversión
stats: Estadísticas
moderators:
index:
@@ -145,15 +145,26 @@ es:
unresolved: Sin resolver
title: Propuestas de gasto para presupuestos participativos
show:
+ heading: Propuesta de inversión
+ info: Datos de envío
association_name: Asociación
by: Enviada por
+ sent: Fecha de creación
geozone: Ámbito
dossier: Informe
price: Coste
+ currency: "€"
feasibility: Viabilidad
feasible: Viable
not_feasible: No viable
undefined: Sin definir
+ valuation_finished: Informe finalizado
+ internal_comments: Commentarios internos
+ responsibles: Responsables
+ assigned_admin: Administrador asignado
+ assigned_valuators: Evaluadores asignados
+ assign_valuators: Asignar evaluadores
+ assign: Asignar
stats:
show:
stats_title: Estadísticas
diff --git a/config/routes.rb b/config/routes.rb
index 7a8a99881..302ce602c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -131,10 +131,10 @@ Rails.application.routes.draw do
end
end
- resources :spending_proposals, only: [:index, :show], path: 'investment_projects' do
+ resources :spending_proposals, only: [:index, :show] do
member do
- put :accept
- put :reject
+ patch :assign_admin
+ patch :assign_valuators
end
end
diff --git a/spec/features/admin/spending_proposals_spec.rb b/spec/features/admin/spending_proposals_spec.rb
index de1906a76..a3a844d94 100644
--- a/spec/features/admin/spending_proposals_spec.rb
+++ b/spec/features/admin/spending_proposals_spec.rb
@@ -20,12 +20,17 @@ feature 'Admin spending proposals' do
end
scenario 'Show' do
+ administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
+ valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org'))
spending_proposal = create(:spending_proposal,
geozone: create(:geozone),
association_name: 'People of the neighbourhood',
price: 1234.56,
feasible: false,
- feasible_explanation: "It's impossible")
+ feasible_explanation: 'It is impossible',
+ administrator: administrator)
+ spending_proposal.valuators << valuator
+
visit admin_spending_proposals_path
click_link spending_proposal.title
@@ -35,9 +40,71 @@ feature 'Admin spending proposals' do
expect(page).to have_content(spending_proposal.author.name)
expect(page).to have_content(spending_proposal.association_name)
expect(page).to have_content(spending_proposal.geozone.name)
- expect(page).to have_content("1234.56")
- expect(page).to have_content("Not feasible")
- expect(page).to have_content("It's impossible")
+ expect(page).to have_content('1234.56')
+ expect(page).to have_content('Not feasible')
+ expect(page).to have_content('It is impossible')
+ expect(page).to have_select('spending_proposal[administrator_id]', selected: 'Ana (ana@admins.org)')
+
+ within('#assigned_valuators') do
+ expect(page).to have_content('Rachel (rachel@valuators.org)')
+ end
+ end
+
+ scenario 'Administrator assigment', :js do
+ spending_proposal = create(:spending_proposal)
+
+ administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
+
+ visit admin_spending_proposal_path(spending_proposal)
+
+ expect(page).to have_select('spending_proposal[administrator_id]', selected: 'Undefined')
+ select 'Ana (ana@admins.org)', from: 'spending_proposal[administrator_id]'
+
+ visit admin_spending_proposal_path(spending_proposal)
+
+ expect(page).to have_select('spending_proposal[administrator_id]', selected: 'Ana (ana@admins.org)')
+ end
+
+ scenario 'Valuators assigments', :js do
+ spending_proposal = create(:spending_proposal)
+
+ valuator1 = create(:valuator, user: create(:user, username: 'Valentina', email: 'v1@valuators.org'))
+ valuator2 = create(:valuator, user: create(:user, username: 'Valerian', email: 'v2@valuators.org'))
+ valuator3 = create(:valuator, user: create(:user, username: 'Val', email: 'v3@valuators.org'))
+
+ visit admin_spending_proposal_path(spending_proposal)
+
+ within('#assigned_valuators') do
+ expect(page).to have_content('Undefined')
+ expect(page).to_not have_content('Valentina (v1@valuators.org)')
+ expect(page).to_not have_content('Valerian (v2@valuators.org)')
+ expect(page).to_not have_content('Val (v3@valuators.org)')
+ end
+
+ visit admin_spending_proposal_path(spending_proposal)
+
+ click_link "Assign valuators"
+
+ within('#valuators-assign-list') do
+ check "valuator_ids_#{valuator1.id}"
+ check "valuator_ids_#{valuator3.id}"
+ end
+
+ within('#assigned_valuators') do
+ expect(page).to have_content('Valentina (v1@valuators.org)')
+ expect(page).to have_content('Val (v3@valuators.org)')
+ expect(page).to_not have_content('Undefined')
+ expect(page).to_not have_content('Valerian (v2@valuators.org)')
+ end
+
+ visit admin_spending_proposal_path(spending_proposal)
+
+ within('#assigned_valuators') do
+ expect(page).to have_content('Valentina (v1@valuators.org)')
+ expect(page).to have_content('Val (v3@valuators.org)')
+ expect(page).to_not have_content('Undefined')
+ expect(page).to_not have_content('Valerian (v2@valuators.org)')
+ end
end
end