@@ -15,7 +15,17 @@ class Admin::BudgetsController < Admin::BaseController
|
||||
end
|
||||
|
||||
def new
|
||||
@budget = Budget.new
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @budget.update(budget_params)
|
||||
redirect_to admin_budget_path(@budget), notice: t('admin.budgets.update.notice')
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -30,7 +40,9 @@ class Admin::BudgetsController < Admin::BaseController
|
||||
private
|
||||
|
||||
def budget_params
|
||||
params.require(:budget).permit(:name, :description, :phase, :currency_symbol)
|
||||
descriptions = Budget::PHASES.map{|p| "description_#{p}"}.map(&:to_sym)
|
||||
valid_attributes = [:name, :phase, :currency_symbol] + descriptions
|
||||
params.require(:budget).permit(*valid_attributes)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -80,7 +80,7 @@ module Budgets
|
||||
end
|
||||
|
||||
def investment_params
|
||||
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service)
|
||||
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service, :location)
|
||||
end
|
||||
|
||||
def load_ballot
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module BudgetsHelper
|
||||
|
||||
def budget_phases_select_options
|
||||
Budget::VALID_PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] }
|
||||
Budget::PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] }
|
||||
end
|
||||
|
||||
def budget_currency_symbol_select_options
|
||||
|
||||
@@ -46,7 +46,7 @@ module Abilities
|
||||
can [:read, :create, :update, :destroy], Budget::Group
|
||||
can [:read, :create, :update, :destroy], Budget::Heading
|
||||
can [:hide, :update, :toggle_selection], Budget::Investment
|
||||
can :valuate, Budget::Investment, budget: { valuating: true }
|
||||
can :valuate, Budget::Investment, budget: { phase: 'valuating' }
|
||||
can :create, Budget::ValuatorAssignment
|
||||
|
||||
can [:search, :edit, :update, :create, :index, :destroy], Banner
|
||||
|
||||
@@ -5,7 +5,7 @@ module Abilities
|
||||
def initialize(user)
|
||||
valuator = user.valuator
|
||||
can [:read, :update, :valuate], SpendingProposal
|
||||
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids, budget: { valuating: true }
|
||||
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids, budget: { phase: 'valuating' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
class Budget < ActiveRecord::Base
|
||||
|
||||
include Sanitizable
|
||||
include Measurable
|
||||
|
||||
VALID_PHASES = %W{on_hold accepting selecting balloting finished}
|
||||
CURRENCY_SYMBOLS = %W{€ $ £ ¥}
|
||||
PHASES = %w(accepting reviewing selecting valuating balloting reviewing_ballots finished).freeze
|
||||
CURRENCY_SYMBOLS = %w(€ $ £ ¥).freeze
|
||||
|
||||
validates :name, presence: true
|
||||
validates :phase, inclusion: { in: VALID_PHASES }
|
||||
validates :phase, inclusion: { in: PHASES }
|
||||
validates :currency_symbol, presence: true
|
||||
|
||||
has_many :investments, dependent: :destroy
|
||||
@@ -14,35 +14,59 @@ class Budget < ActiveRecord::Base
|
||||
has_many :groups, dependent: :destroy
|
||||
has_many :headings, through: :groups
|
||||
|
||||
scope :on_hold, -> { where(phase: "on_hold") }
|
||||
before_validation :sanitize_descriptions
|
||||
|
||||
scope :on_hold, -> { where(phase: %w(reviewing valuating reviewing_ballots")) }
|
||||
scope :accepting, -> { where(phase: "accepting") }
|
||||
scope :reviewing, -> { where(phase: "reviewing") }
|
||||
scope :selecting, -> { where(phase: "selecting") }
|
||||
scope :valuating, -> { where(phase: "valuating") }
|
||||
scope :balloting, -> { where(phase: "balloting") }
|
||||
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
|
||||
scope :finished, -> { where(phase: "finished") }
|
||||
|
||||
scope :current, -> { where.not(phase: "finished") }
|
||||
scope :valuating, -> { where(valuating: true) }
|
||||
|
||||
def on_hold?
|
||||
phase == "on_hold"
|
||||
def description
|
||||
self.send("description_#{self.phase}").try(:html_safe)
|
||||
end
|
||||
|
||||
def self.description_max_length
|
||||
2000
|
||||
end
|
||||
|
||||
def accepting?
|
||||
phase == "accepting"
|
||||
end
|
||||
|
||||
def reviewing?
|
||||
phase == "reviewing"
|
||||
end
|
||||
|
||||
def selecting?
|
||||
phase == "selecting"
|
||||
end
|
||||
|
||||
def valuating?
|
||||
phase == "valuating"
|
||||
end
|
||||
|
||||
def balloting?
|
||||
phase == "balloting"
|
||||
end
|
||||
|
||||
def reviewing_ballots?
|
||||
phase == "reviewing_ballots"
|
||||
end
|
||||
|
||||
def finished?
|
||||
phase == "finished"
|
||||
end
|
||||
|
||||
def on_hold?
|
||||
reviewing? || valuating? || reviewing_ballots?
|
||||
end
|
||||
|
||||
def current?
|
||||
!finished?
|
||||
end
|
||||
@@ -69,5 +93,15 @@ class Budget < ActiveRecord::Base
|
||||
def formatted_heading_amount_spent(heading)
|
||||
formatted_amount(amount_spent(heading))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sanitize_descriptions
|
||||
s = WYSIWYGSanitizer.new
|
||||
PHASES.each do |phase|
|
||||
sanitized = s.sanitize(self.send("description_#{phase}"))
|
||||
self.send("description_#{phase}=", sanitized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
18
app/views/admin/budgets/_form.html.erb
Normal file
18
app/views/admin/budgets/_form.html.erb
Normal file
@@ -0,0 +1,18 @@
|
||||
<%= form_for [:admin, @budget] do |f| %>
|
||||
|
||||
<%= f.text_field :name, maxlength: Budget.title_max_length %>
|
||||
|
||||
<% Budget::PHASES.each do |phase| %>
|
||||
<%= f.cktext_area "description_#{phase}", maxlength: Budget.description_max_length, ckeditor: { language: I18n.locale } %>
|
||||
<% end %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= f.select :phase, budget_phases_select_options %>
|
||||
</div>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= f.select :currency_symbol, budget_currency_symbol_select_options %>
|
||||
</div>
|
||||
</div>
|
||||
<%= f.submit nil, class: "button success" %>
|
||||
<% end %>
|
||||
7
app/views/admin/budgets/edit.html.erb
Normal file
7
app/views/admin/budgets/edit.html.erb
Normal file
@@ -0,0 +1,7 @@
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<h2><%= t("admin.budgets.edit.title") %></h2>
|
||||
|
||||
<%= render '/admin/budgets/form' %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,28 +2,6 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<h2><%= t("admin.budgets.new.title") %></h2>
|
||||
|
||||
<%= form_for [:admin, @budget] do |f| %>
|
||||
|
||||
<%= f.label :name, t("admin.budgets.new.name") %>
|
||||
<%= f.text_field :name,
|
||||
label: false,
|
||||
maxlength: 30,
|
||||
placeholder: t("admin.budgets.new.name") %>
|
||||
|
||||
<%= f.label :description, t("admin.budgets.new.description") %>
|
||||
<%= f.text_area :description, rows: 3, maxlength: 6000, label: false, placeholder: t("admin.budgets.new.description") %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= f.label :description, t("admin.budgets.new.phase") %>
|
||||
<%= f.select :phase, budget_phases_select_options, {label: false} %>
|
||||
</div>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= f.label :description, t("admin.budgets.new.currency") %>
|
||||
<%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %>
|
||||
</div>
|
||||
</div>
|
||||
<%= f.submit t("admin.budgets.new.create"), class: "button success" %>
|
||||
<% end %>
|
||||
<%= render '/admin/budgets/form' %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<h2><%= @budget.name %></h2>
|
||||
<h2><%= @budget.name %> <small><%= link_to(t('shared.edit'), edit_admin_budget_path(@budget)) %></small></h2>
|
||||
|
||||
<%= simple_format(text_with_links(@budget.description), {}, sanitize: false) %>
|
||||
<%= @budget.description %>
|
||||
|
||||
<p>
|
||||
<strong><%= t('admin.budgets.show.phase') %>:</strong> <%= t("budget.phase.#{@budget.phase}") %> |
|
||||
@@ -13,4 +13,4 @@
|
||||
|
||||
<div id="<%= dom_id @budget %>_groups" class="row">
|
||||
<%= render "groups", groups: @budget.groups %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
<%= f.text_field :external_url, placeholder: t("budget.investments.form.external_url"), label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :location, t("budget.investments.form.location") %>
|
||||
<%= f.text_field :location, placeholder: t("budget.investments.form.location"), label: false %>
|
||||
</div>
|
||||
|
||||
<% unless current_user.manager? %>
|
||||
|
||||
<div class="small-12 column">
|
||||
|
||||
@@ -26,10 +26,15 @@
|
||||
|
||||
<br>
|
||||
<p id="investment_code">
|
||||
<%= t("budget.investments.show.code") %>
|
||||
<strong><%= investment.id %></strong>
|
||||
<%= t("budget.investments.show.code_html", code: investment.id) %>
|
||||
</p>
|
||||
|
||||
<% if investment.location.present? %>
|
||||
<p id="investment_code">
|
||||
<%= t("budget.investments.show.location_html", location: investment.location) %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= safe_html_with_links investment.description.html_safe %>
|
||||
|
||||
<% if investment.external_url.present? %>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<%= link_to @budget, class: "back" do %>
|
||||
<i class="icon-angle-left"></i>
|
||||
<%= t("spending_proposals.index.sidebar.back") %>
|
||||
<% end %>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<% if @budget.accepting? %>
|
||||
<% if current_user && current_user.level_two_or_three_verified? %>
|
||||
<%= link_to t("budget.investments.index.sidebar.create"), new_budget_investment_path, class: "button budget expanded" %>
|
||||
<% else %>
|
||||
<div class="callout warning">
|
||||
<%= t("budget.investments.index.sidebar.verified_only",
|
||||
verify: link_to(t("budget.investments.index.sidebar.verify_account"), verification_path)).html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3 class="sidebar-title"><%= t("spending_proposals.index.sidebar.my_ballot") %></h3>
|
||||
<h2 class="sidebar-title"><%= t("budget.investments.index.sidebar.my_ballot") %></h2>
|
||||
|
||||
<% if @heading && @ballot.investments.by_heading(@heading.id).count > 0 %>
|
||||
<p>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
<h1><%= @budget.name %>
|
||||
<small><%= t("budgets.phases.#{@budget.phase}") %></small>
|
||||
</h1>
|
||||
<p><%= @budget.description %></p>
|
||||
|
||||
<%= @budget.description %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="no-bullet submenu">
|
||||
<ul class="no-bullet submenu">
|
||||
<% @valid_orders.each do |order| %>
|
||||
<li class="inline-block">
|
||||
<%= link_to current_path_with_query_params(order: order, page: 1), class: order == @current_order ? 'active' : '' do %>
|
||||
|
||||
@@ -12,7 +12,7 @@ Devise.setup do |config|
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class
|
||||
# with default "from" parameter.
|
||||
if Rails.env.test?
|
||||
if Rails.env.test? || !ActiveRecord::Base.connection.table_exists?('settings')
|
||||
config.mailer_sender = "noreply@example.org"
|
||||
else
|
||||
config.mailer_sender = "#{Setting['mailer_from_name']} <#{Setting['mailer_from_address']}>"
|
||||
|
||||
@@ -41,6 +41,17 @@ en:
|
||||
one: "Spending proposal"
|
||||
other: "Spending proposals"
|
||||
attributes:
|
||||
budget:
|
||||
name: "Name"
|
||||
description_accepting: "Description during Accepting phase"
|
||||
description_reviewing: "Description during Reviewing phase"
|
||||
description_selecting: "Description during Selecting phase"
|
||||
description_valuating: "Description during Valuating phase"
|
||||
description_balloting: "Description during Balloting phase"
|
||||
description_reviewing_ballots: "Description during Reviewing Ballots phase"
|
||||
description_finished: "Description when the budget is finished"
|
||||
phase: "Phase"
|
||||
currency_symbol: "Currency"
|
||||
budget/investment:
|
||||
administrator_id: "Administrator"
|
||||
description: "Description"
|
||||
|
||||
@@ -41,6 +41,17 @@ es:
|
||||
one: "Propuesta de inversión"
|
||||
other: "Propuestas de inversión"
|
||||
attributes:
|
||||
budget:
|
||||
name: "Nombre"
|
||||
description_accepting: "Descripción durante la fase de aceptación"
|
||||
description_reviewing: "Descripción durante la fase de revisión"
|
||||
description_selecting: "Descripción durante la fase de selección"
|
||||
description_valuating: "Descripción durante la fase de evaluación"
|
||||
description_balloting: "Descripción duratne la fase de votación"
|
||||
description_reviewing_ballots: "Descripción durante la fase de revisión de votos"
|
||||
description_finished: "Descripción cuando el presupuesto ha finalizado"
|
||||
phase: "Fase"
|
||||
currency_symbol: "Divisa"
|
||||
budget/investment:
|
||||
administrator_id: "Administrador"
|
||||
description: "Descripción"
|
||||
@@ -111,4 +122,4 @@ es:
|
||||
attributes:
|
||||
document_number:
|
||||
not_in_census: 'No verificado por Padrón'
|
||||
already_voted: 'Ya ha votado esta propuesta'
|
||||
already_voted: 'Ya ha votado esta propuesta'
|
||||
|
||||
@@ -61,30 +61,29 @@ en:
|
||||
budgets:
|
||||
index:
|
||||
title: Participatory budgets
|
||||
new_link: Create new
|
||||
new_link: Create new budget
|
||||
info_link: Info
|
||||
filters:
|
||||
open: Open
|
||||
finished: Finished
|
||||
create:
|
||||
notice: New participatory budget created successfully!
|
||||
update:
|
||||
notice: Participatory budget updated successfully
|
||||
edit:
|
||||
title: Edit Participatory budget
|
||||
new:
|
||||
title: New participatory budget
|
||||
create: Create budget
|
||||
name: Budget's name
|
||||
description: Description
|
||||
phase: Phase
|
||||
currency: Currency
|
||||
show:
|
||||
phase: Current phase
|
||||
currency: Currency
|
||||
groups: Groups of budget headings
|
||||
form:
|
||||
group: Group's name
|
||||
group: Group name
|
||||
no_groups: No groups created yet. Each user will be able to vote in only one heading per group.
|
||||
add_group: Add new group
|
||||
create_group: Create group
|
||||
heading: Heading's name
|
||||
heading: Heading name
|
||||
add_heading: Add heading
|
||||
amount: Amount
|
||||
save_heading: Save heading
|
||||
|
||||
@@ -61,20 +61,19 @@ es:
|
||||
budgets:
|
||||
index:
|
||||
title: Presupuestos participativos
|
||||
new_link: Crear nuevo
|
||||
new_link: Crear nuevo presupuesto
|
||||
info_link: Info
|
||||
filters:
|
||||
open: Abiertos
|
||||
finished: Terminados
|
||||
create:
|
||||
notice: ¡Nueva campaña de presupuestos participativos creada con éxito!
|
||||
update:
|
||||
notice: Campaña de presupuestos participativos actualizada
|
||||
edit:
|
||||
title: Editar campaña de presupuestos participativos
|
||||
new:
|
||||
title: Nuevo presupuesto ciudadano
|
||||
create: Crear presupuesto
|
||||
name: Nombre del presupuesto
|
||||
description: Descripción
|
||||
phase: Fase
|
||||
currency: Divisa
|
||||
show:
|
||||
phase: Fase actual
|
||||
currency: Divisa
|
||||
|
||||
@@ -24,10 +24,12 @@ en:
|
||||
title: Select a heading
|
||||
budget:
|
||||
phase:
|
||||
on_hold: On hold
|
||||
accepting: Accepting proposals
|
||||
reviewing: Reviewing proposals
|
||||
selecting: Selecting
|
||||
valuating: Valuating
|
||||
balloting: Balloting
|
||||
reviewing_ballots: Reviewing Ballots
|
||||
finished: Finished
|
||||
groups:
|
||||
index:
|
||||
@@ -36,7 +38,7 @@ en:
|
||||
none: Whole City
|
||||
all: All scopes
|
||||
index:
|
||||
name: Budget's name
|
||||
name: Budget name
|
||||
phase: Phase
|
||||
title: Participatory budgets
|
||||
investments:
|
||||
@@ -46,6 +48,7 @@ en:
|
||||
description: Description
|
||||
external_url: Link to additional documentation
|
||||
heading: Choose if a proposed citywide or district
|
||||
location: "Location"
|
||||
submit_buttons:
|
||||
create: Create
|
||||
new: Create
|
||||
@@ -79,6 +82,9 @@ en:
|
||||
votes: Supports remaining
|
||||
votes_district: "You can only vote in the district %{district}"
|
||||
zero: You have not voted any investment project.
|
||||
verified_only: "To create a new budget investment %{verify}."
|
||||
verify_account: "verify your account"
|
||||
create: "Create budget investment"
|
||||
orders:
|
||||
random: random
|
||||
confidence_score: highest rated
|
||||
@@ -96,7 +102,9 @@ en:
|
||||
author_deleted: User deleted
|
||||
price_explanation: Price explanation
|
||||
unfeasibility_explanation: Unfeasibility explanation
|
||||
code: 'Investment project code:'
|
||||
code_html: 'Investment project code: <strong>%{code}</strong>'
|
||||
location_html: 'Location: <strong>%{location}</strong>'
|
||||
location: Location
|
||||
share: Share
|
||||
wrong_price_format: Only integer numbers
|
||||
investment:
|
||||
|
||||
@@ -24,10 +24,12 @@ es:
|
||||
title: Selecciona una partida
|
||||
budget:
|
||||
phase:
|
||||
on_hold: En pausa
|
||||
accepting: Aceptando propuestas
|
||||
reviewing: Revisando propuestas
|
||||
selecting: Fase de selección
|
||||
balloting: Fase de Votación
|
||||
valuating: Fase de evaluación de propuestas
|
||||
balloting: Fase de votación
|
||||
reviewing_ballots: Contando resultados
|
||||
finished: Terminado
|
||||
groups:
|
||||
index:
|
||||
@@ -46,6 +48,7 @@ es:
|
||||
description: Descripción detallada
|
||||
external_url: Enlace a documentación adicional
|
||||
heading: "Elige si es una propuesta para toda la ciudad o para un distrito"
|
||||
location: "Ubicación de la propuesta"
|
||||
submit_buttons:
|
||||
create: Crear
|
||||
new: Crear
|
||||
@@ -79,6 +82,9 @@ es:
|
||||
votes: Apoyos restantes
|
||||
votes_district: "Solo puedes votar en el distrito %{district}"
|
||||
zero: "Todavía no has votado ninguna propuesta de inversión."
|
||||
verified_only: "Para crear una nueva propuesta de inversión %{verify}."
|
||||
verify_account: "verifica tu cuenta"
|
||||
create: "Crear propuesta de inversión"
|
||||
orders:
|
||||
random: Aleatorias
|
||||
confidence_score: Mejor valoradas
|
||||
@@ -96,7 +102,8 @@ es:
|
||||
author_deleted: Usuario eliminado
|
||||
price_explanation: Informe de coste
|
||||
unfeasibility_explanation: Informe de inviabilidad
|
||||
code: 'Código propuesta de gasto:'
|
||||
code_html: 'Código propuesta de gasto: <strong>%{code}</strong>'
|
||||
location_html: 'Ubicación: <strong>%{location}</strong>'
|
||||
share: Compartir
|
||||
wrong_price_format: Solo puede incluir caracteres numéricos
|
||||
investment:
|
||||
|
||||
@@ -441,6 +441,7 @@ en:
|
||||
collective: Collective
|
||||
flag: Flag as inappropriate
|
||||
hide: Hide
|
||||
edit: Editar
|
||||
print:
|
||||
print_button: Print this info
|
||||
search: Search
|
||||
@@ -499,11 +500,9 @@ en:
|
||||
one: " containing the term '%{search_term}'"
|
||||
other: " containing the term '%{search_term}'"
|
||||
sidebar:
|
||||
back: Volver
|
||||
geozones: Scope of operation
|
||||
feasibility: Feasibility
|
||||
unfeasible: Unfeasible
|
||||
my_ballot: My votes
|
||||
start_spending_proposal: Create an investment project
|
||||
new:
|
||||
more_info: How do participatory budgeting works?
|
||||
|
||||
@@ -445,6 +445,7 @@ es:
|
||||
print_button: Imprimir esta información
|
||||
search: Buscar
|
||||
show: Mostrar
|
||||
edit: Editar
|
||||
suggest:
|
||||
debate:
|
||||
found:
|
||||
@@ -499,11 +500,9 @@ es:
|
||||
one: " que contiene '%{search_term}'"
|
||||
other: " que contienen '%{search_term}'"
|
||||
sidebar:
|
||||
back: Volver
|
||||
geozones: Ámbitos de actuación
|
||||
feasibility: Viabilidad
|
||||
unfeasible: No viables
|
||||
my_ballot: Mis votos
|
||||
start_spending_proposal: Crea una propuesta de inversión
|
||||
new:
|
||||
more_info: "¿Cómo funcionan los presupuestos participativos?"
|
||||
|
||||
@@ -327,19 +327,23 @@ end
|
||||
|
||||
puts "Creating Budgets"
|
||||
|
||||
phases = %w{on_hold accepting selecting balloting finished}
|
||||
phases.each_with_index do |phase, i|
|
||||
budget = Budget.create!(name: (Date.today.year - 10 + i).to_s,
|
||||
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>",
|
||||
currency_symbol: "€",
|
||||
phase: phase,
|
||||
valuating: [false, true].sample)
|
||||
Budget::PHASES.each_with_index do |phase, i|
|
||||
descriptions = Hash[Budget::PHASES.map{ |p| ["description_#{p}",
|
||||
"<p>#{Faker::Lorem.paragraphs(2).join('</p><p>')}</p>"] }]
|
||||
budget = Budget.create!(
|
||||
descriptions.merge(
|
||||
name: (Date.current - 10 + i).to_s,
|
||||
currency_symbol: "€",
|
||||
phase: phase
|
||||
)
|
||||
)
|
||||
|
||||
puts budget.name
|
||||
|
||||
(1..[1,2,3].sample).each do |i|
|
||||
(1..([1, 2, 3].sample)).each do
|
||||
group = budget.groups.create!(name: Faker::StarWars.planet)
|
||||
|
||||
geozones = Geozone.reorder("RANDOM()").limit([2,5,6,7].sample)
|
||||
geozones = Geozone.reorder("RANDOM()").limit([2, 5, 6, 7].sample)
|
||||
geozones.each do |geozone|
|
||||
group.headings << group.headings.create!(name: geozone.name,
|
||||
geozone: geozone,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddLocationToBudgetInvestments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :budget_investments, :location, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class RemoveValuatingFromBudgets < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :budgets, :valuating, :bool
|
||||
end
|
||||
end
|
||||
12
db/migrate/20161230174744_change_budget_description.rb
Normal file
12
db/migrate/20161230174744_change_budget_description.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class ChangeBudgetDescription < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :budgets, :description, :text
|
||||
add_column :budgets, :description_accepting, :text
|
||||
add_column :budgets, :description_reviewing, :text
|
||||
add_column :budgets, :description_selecting, :text
|
||||
add_column :budgets, :description_valuating, :text
|
||||
add_column :budgets, :description_balloting, :text
|
||||
add_column :budgets, :description_reviewing_ballots, :text
|
||||
add_column :budgets, :description_finished, :text
|
||||
end
|
||||
end
|
||||
5
db/migrate/20170102080432_adjust_budget_fields.rb
Normal file
5
db/migrate/20170102080432_adjust_budget_fields.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AdjustBudgetFields < ActiveRecord::Migration
|
||||
def change
|
||||
change_column :budgets, :phase, :string, limit: 40, default: 'accepting'
|
||||
end
|
||||
end
|
||||
24
db/schema.rb
24
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20161221172447) do
|
||||
ActiveRecord::Schema.define(version: 20170102080432) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -142,6 +142,7 @@ ActiveRecord::Schema.define(version: 20161221172447) do
|
||||
t.integer "budget_id"
|
||||
t.integer "group_id"
|
||||
t.boolean "selected", default: false
|
||||
t.string "location"
|
||||
end
|
||||
|
||||
add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree
|
||||
@@ -159,13 +160,18 @@ ActiveRecord::Schema.define(version: 20161221172447) do
|
||||
add_index "budget_valuator_assignments", ["investment_id"], name: "index_budget_valuator_assignments_on_investment_id", using: :btree
|
||||
|
||||
create_table "budgets", force: :cascade do |t|
|
||||
t.string "name", limit: 30
|
||||
t.text "description"
|
||||
t.string "currency_symbol", limit: 10
|
||||
t.string "phase", limit: 15, default: "on_hold"
|
||||
t.boolean "valuating", default: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "name", limit: 30
|
||||
t.string "currency_symbol", limit: 10
|
||||
t.string "phase", limit: 40, default: "accepting"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "description_accepting"
|
||||
t.text "description_reviewing"
|
||||
t.text "description_selecting"
|
||||
t.text "description_valuating"
|
||||
t.text "description_balloting"
|
||||
t.text "description_reviewing_ballots"
|
||||
t.text "description_finished"
|
||||
end
|
||||
|
||||
create_table "campaigns", force: :cascade do |t|
|
||||
@@ -572,7 +578,7 @@ ActiveRecord::Schema.define(version: 20161221172447) do
|
||||
t.boolean "email_digest", default: true
|
||||
t.boolean "email_on_direct_message", default: true
|
||||
t.boolean "official_position_badge", default: false
|
||||
t.datetime "password_changed_at", default: '2016-12-21 17:55:08', null: false
|
||||
t.datetime "password_changed_at", default: '2016-11-02 13:51:14', null: false
|
||||
t.boolean "created_from_signature", default: false
|
||||
end
|
||||
|
||||
|
||||
@@ -195,20 +195,39 @@ FactoryGirl.define do
|
||||
factory :budget do
|
||||
sequence(:name) { |n| "Budget #{n}" }
|
||||
currency_symbol "€"
|
||||
phase 'on_hold'
|
||||
phase 'accepting'
|
||||
description_accepting "This budget is accepting"
|
||||
description_reviewing "This budget is reviewing"
|
||||
description_selecting "This budget is selecting"
|
||||
description_valuating "This budget is valuating"
|
||||
description_balloting "This budget is balloting"
|
||||
description_reviewing_ballots "This budget is reviewing ballots"
|
||||
description_finished "This budget is finished"
|
||||
|
||||
trait :accepting do
|
||||
phase 'accepting'
|
||||
end
|
||||
|
||||
trait :reviewing do
|
||||
phase 'reviewing'
|
||||
end
|
||||
|
||||
trait :selecting do
|
||||
phase 'selecting'
|
||||
end
|
||||
|
||||
trait :valuating do
|
||||
phase 'valuating'
|
||||
end
|
||||
|
||||
trait :balloting do
|
||||
phase 'balloting'
|
||||
end
|
||||
|
||||
trait :reviewing_ballots do
|
||||
phase 'reviewing_ballots'
|
||||
end
|
||||
|
||||
trait :finished do
|
||||
phase 'finished'
|
||||
end
|
||||
|
||||
@@ -80,13 +80,13 @@ feature 'Admin budgets' do
|
||||
|
||||
scenario 'Create budget' do
|
||||
visit admin_budgets_path
|
||||
click_link 'Create new'
|
||||
click_link 'Create new budget'
|
||||
|
||||
fill_in 'budget_name', with: 'M30 - Summer campaign'
|
||||
fill_in 'budget_description', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
|
||||
fill_in 'budget_description_accepting', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
|
||||
select 'Accepting proposals', from: 'budget[phase]'
|
||||
|
||||
click_button 'Create budget'
|
||||
click_button 'Create Participatory budget'
|
||||
|
||||
expect(page).to have_content 'New participatory budget created successfully!'
|
||||
expect(page).to have_content 'M30 - Summer campaign'
|
||||
@@ -94,10 +94,10 @@ feature 'Admin budgets' do
|
||||
|
||||
scenario 'Name is mandatory' do
|
||||
visit new_admin_budget_path
|
||||
click_button 'Create budget'
|
||||
click_button 'Create Participatory budget'
|
||||
|
||||
expect(page).to_not have_content 'New participatory budget created successfully!'
|
||||
expect(page).to have_css("label.error", text: "Budget's name")
|
||||
expect(page).to have_css("label.error", text: "Name")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -582,7 +582,7 @@ feature 'Ballots' do
|
||||
end
|
||||
|
||||
scenario "Balloting is disabled when budget isn't in the balotting phase", :js do
|
||||
budget.update(phase: 'on_hold')
|
||||
budget.update(phase: 'accepting')
|
||||
|
||||
bi1 = create(:budget_investment, :selected, heading: california, price: 600)
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ feature 'Votes' do
|
||||
|
||||
scenario 'Disable voting on spending proposals', :js do
|
||||
login_as(@manuela)
|
||||
budget.update(phase: "on_hold")
|
||||
budget.update(phase: "reviewing")
|
||||
investment = create(:budget_investment, budget: budget, heading: heading)
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
@@ -5,7 +5,7 @@ feature 'Valuation budget investments' do
|
||||
background do
|
||||
@valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org'))
|
||||
login_as(@valuator.user)
|
||||
@budget = create(:budget, valuating: true)
|
||||
@budget = create(:budget, :valuating)
|
||||
end
|
||||
|
||||
scenario 'Disabled with a feature flag' do
|
||||
@@ -392,4 +392,4 @@ feature 'Valuation budget investments' do
|
||||
expect(page).to have_content('Only integer numbers', count: 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,7 +65,7 @@ describe "Abilities::Administrator" do
|
||||
it { should be_able_to(:update, Budget::Investment) }
|
||||
it { should be_able_to(:hide, Budget::Investment) }
|
||||
|
||||
it { should be_able_to(:valuate, create(:budget_investment, budget: create(:budget, valuating: true))) }
|
||||
it { should_not be_able_to(:valuate, create(:budget_investment, budget: create(:budget, valuating: false))) }
|
||||
it { should be_able_to(:valuate, create(:budget_investment, budget: create(:budget, phase: 'valuating'))) }
|
||||
it { should_not be_able_to(:valuate, create(:budget_investment, budget: create(:budget, phase: 'finished'))) }
|
||||
|
||||
end
|
||||
|
||||
@@ -7,10 +7,10 @@ describe "Abilities::Valuator" do
|
||||
let(:valuator) { create(:valuator) }
|
||||
let(:non_assigned_investment) { create(:budget_investment) }
|
||||
|
||||
let(:assigned_investment) { create(:budget_investment, budget: create(:budget, valuating: true)) }
|
||||
let(:assigned_investment) { create(:budget_investment, budget: create(:budget, phase: 'valuating')) }
|
||||
before(:each) { assigned_investment.valuators << valuator }
|
||||
|
||||
let(:assigned_investment_not_valuating) { create(:budget_investment, budget: create(:budget, valuating: false)) }
|
||||
let(:assigned_investment_not_valuating) { create(:budget_investment, budget: create(:budget, phase: 'finished')) }
|
||||
before(:each) { assigned_investment_not_valuating.valuators << valuator }
|
||||
|
||||
it { should be_able_to(:read, SpendingProposal) }
|
||||
|
||||
@@ -318,8 +318,8 @@ describe Budget::Investment do
|
||||
expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to eq(:organization)
|
||||
end
|
||||
|
||||
it "rejects votes when voting is not allowed (via admin setting)" do
|
||||
budget.phase = "on_hold"
|
||||
it "rejects votes when voting is not allowed (wrong phase)" do
|
||||
budget.phase = "reviewing"
|
||||
expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Budget do
|
||||
|
||||
describe "description" do
|
||||
it "changes depending on the phase" do
|
||||
budget = create(:budget)
|
||||
|
||||
Budget::PHASES.each do |phase|
|
||||
budget.phase = phase
|
||||
expect(budget.description).to eq(budget.send("description_#{phase}"))
|
||||
expect(budget.description).to be_html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "phase" do
|
||||
let(:budget) { create(:budget) }
|
||||
|
||||
it "is validated" do
|
||||
Budget::VALID_PHASES.each do |phase|
|
||||
Budget::PHASES.each do |phase|
|
||||
budget.phase = phase
|
||||
expect(budget).to be_valid
|
||||
end
|
||||
@@ -15,18 +28,24 @@ describe Budget do
|
||||
end
|
||||
|
||||
it "produces auxiliary methods" do
|
||||
budget.phase = "on_hold"
|
||||
expect(budget).to be_on_hold
|
||||
|
||||
budget.phase = "accepting"
|
||||
expect(budget).to be_accepting
|
||||
|
||||
budget.phase = "reviewing"
|
||||
expect(budget).to be_reviewing
|
||||
|
||||
budget.phase = "selecting"
|
||||
expect(budget).to be_selecting
|
||||
|
||||
budget.phase = "valuating"
|
||||
expect(budget).to be_valuating
|
||||
|
||||
budget.phase = "balloting"
|
||||
expect(budget).to be_balloting
|
||||
|
||||
budget.phase = "reviewing_ballots"
|
||||
expect(budget).to be_reviewing_ballots
|
||||
|
||||
budget.phase = "finished"
|
||||
expect(budget).to be_finished
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user