diff --git a/app/controllers/spending_proposals_controller.rb b/app/controllers/spending_proposals_controller.rb
index 1abc71549..e5bf2debf 100644
--- a/app/controllers/spending_proposals_controller.rb
+++ b/app/controllers/spending_proposals_controller.rb
@@ -1,7 +1,32 @@
class SpendingProposalsController < ApplicationController
before_action :authenticate_user!, except: [:index]
+ load_and_authorize_resource
+
def index
end
+ def new
+ @spending_proposal = SpendingProposal.new
+ @featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
+ end
+
+ def create
+ @spending_proposal = SpendingProposal.new(spending_proposal_params)
+ @spending_proposal.author = current_user
+
+ if @spending_proposal.save_with_captcha
+ redirect_to spending_proposals_path, notice: t('flash.actions.create.notice', resource_name: t("activerecord.models.spending_proposal", count: 1))
+ else
+ @featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
+ render :new
+ end
+ end
+
+ private
+
+ def spending_proposal_params
+ params.require(:spending_proposal).permit(:title, :description, :external_url, :tag_list, :terms_of_service, :captcha, :captcha_key)
+ end
+
end
\ No newline at end of file
diff --git a/app/models/spending_proposal.rb b/app/models/spending_proposal.rb
index 12fa816df..30f270ab3 100644
--- a/app/models/spending_proposal.rb
+++ b/app/models/spending_proposal.rb
@@ -3,14 +3,16 @@ class SpendingProposal < ActiveRecord::Base
include Sanitizable
include Taggable
+ apply_simple_captcha
+
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
validates :title, presence: true
validates :author, presence: true
validates :description, presence: true
- validates :title, length: { in: 4..Proposal.title_max_length }
- validates :description, length: { maximum: Proposal.description_max_length }
+ validates :title, length: { in: 4..SpendingProposal.title_max_length }
+ validates :description, length: { maximum: SpendingProposal.description_max_length }
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
end
diff --git a/app/views/spending_proposals/_form.html.erb b/app/views/spending_proposals/_form.html.erb
new file mode 100644
index 000000000..8f5bc5bb7
--- /dev/null
+++ b/app/views/spending_proposals/_form.html.erb
@@ -0,0 +1,52 @@
+<%= form_for(@spending_proposal, url: form_url) do |f| %>
+ <%= render 'shared/errors', resource: @spending_proposal %>
+
+
+
+ <%= f.label :title, t("spending_proposals.form.title") %>
+ <%= f.text_field :title, maxlength: SpendingProposal.title_max_length, placeholder: t("spending_proposals.form.title"), label: false %>
+
+
+
+ <%= f.label :description, t("spending_proposals.form.description") %>
+ <%= f.cktext_area :description, maxlength: SpendingProposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
+
+
+
+ <%= f.label :external_url, t("spending_proposals.form.external_url") %>
+ <%= f.text_field :external_url, placeholder: t("spending_proposals.form.external_url"), label: false %>
+
+
+
+ <%= f.label :tag_list, t("spending_proposals.form.tags_label") %>
+
<%= t("spending_proposals.form.tags_instructions") %>
+
+ <% @featured_tags.each do |tag| %>
+ <%= tag.name %>
+ <% end %>
+
+ <%= f.text_field :tag_list, value: @spending_proposal.tag_list.to_s, label: false, placeholder: t("spending_proposals.form.tags_placeholder"), class: 'js-tag-list' %>
+
+
+
+ <% if @spending_proposal.new_record? %>
+ <%= f.label :terms_of_service do %>
+ <%= f.check_box :terms_of_service, label: false %>
+
+ <%= t("form.accept_terms",
+ policy: link_to(t("form.policy"), "/privacy", target: "blank"),
+ conditions: link_to(t("form.conditions"), "/conditions", target: "blank")).html_safe %>
+
+ <% end %>
+ <% end %>
+
+
+
+ <%= f.simple_captcha input_html: { required: false } %>
+
+
+
+ <%= f.submit(class: "button radius", value: t("spending_proposals.form.submit_buttons.#{action_name}")) %>
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/spending_proposals/new.html.erb b/app/views/spending_proposals/new.html.erb
new file mode 100644
index 000000000..c761487ff
--- /dev/null
+++ b/app/views/spending_proposals/new.html.erb
@@ -0,0 +1,27 @@
+
+
+
+ <%= link_to spending_proposals_path, class: "left back" do %>
+
+ <%= t("spending_proposals.new.back_link") %>
+ <% end %>
+
<%= t("spending_proposals.new.start_new") %>
+
+ <%= link_to "/spending_proposals_info", target: "_blank" do %>
+ <%= t("spending_proposals.new.more_info")%>
+ <% end %>
+
+ <%= render "spending_proposals/form", form_url: spending_proposals_url %>
+
+
+
+
+
<%= t("spending_proposals.new.recommendations_title") %>
+
+ - <%= t("spending_proposals.new.recommendation_one") %>
+ - <%= t("spending_proposals.new.recommendation_two") %>
+ - <%= t("spending_proposals.new.recommendation_three") %>
+
+
+
+
\ No newline at end of file
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 4e9cd5931..42c29fed8 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -37,6 +37,9 @@ en:
proposal:
one: "Citizen proposal"
other: "Citizen proposals"
+ spending_proposal:
+ one: "Spending proposal"
+ other: "Spending proposals"
attributes:
comment:
body: "Comment"
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index 998bc4fb6..780595562 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -37,6 +37,9 @@ es:
proposal:
one: "Propuesta ciudadana"
other: "Propuestas ciudadanas"
+ spending_proposal:
+ one: "Propuesta de gasto"
+ other: "Propuestas de gasto"
attributes:
comment:
body: "Comentario"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 40d9d4973..60032de69 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -248,9 +248,27 @@ en:
submit_button: "Save changes"
spending_proposals:
index:
- title: "Citizen budget"
- text: "Here you can send spending proposals to be considered in the frame of the annual citizen budgets."
+ title: "Participatory budgeting"
+ text: "Here you can send spending proposals to be considered in the frame of the annual participatory budgeting."
create_link: "Create spending proposal"
+ new:
+ back_link: Back
+ start_new: "Create spending proposal"
+ more_info: "How do participatory bufgeting works?"
+ recommendations_title: "Recommendations for creating a spending proposal"
+ recommendation_one: "It's mandatory that the proposal makes reference to a budgetable action."
+ recommendation_two: "Any proposal or comment suggesting illegal action will be deleted."
+ recommendation_three: "Try to go into details when describing your spending proposal so the reviewing team undertands your points."
+ form:
+ title: "Spending proposal title"
+ description: "Description"
+ external_url: "Link to additional documentation"
+ tags_label: "Tags"
+ tags_instructions: "Tag this spending proposal. You can choose from our tags or add your own."
+ tags_placeholder: "Enter the tags you would like to use, separated by commas (',')"
+ submit_buttons:
+ new: Create
+ create: Create
comments:
show:
return_to_commentable: "Go back to "
@@ -338,6 +356,7 @@ en:
user: "the secret code does not match the image"
debate: "the secret code does not match the image"
proposal: "the secret code does not match the image"
+ spendingproposal: "the secret code does not match the image"
shared:
author_info:
author_deleted: "User deleted"
diff --git a/config/locales/es.yml b/config/locales/es.yml
index e67f42153..da8511678 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -209,7 +209,7 @@ es:
proposal_responsible_name: "Nombre y apellidos de la persona que hace esta propuesta"
proposal_responsible_name_note: "(individualmente o como representante de un colectivo; no se mostrará públicamente)"
tags_label: "Temas"
- tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre nuestras propuestas o introducir las que desees."
+ tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre nuestras sugerencias o introducir las que desees."
tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')"
show:
back_link: "Volver"
@@ -248,9 +248,27 @@ es:
submit_button: "Guardar cambios"
spending_proposals:
index:
- title: "Presupuestos ciudadanos"
+ title: "Presupuestos participativos"
text: "Desde esta sección podrás sugerir propuestas de gasto que irán asociadas a las partidas de presupuestos ciudadanos. El requisito principal es que sean propuestas presupuestables."
create_link: "Enviar propuesta de gasto"
+ new:
+ back_link: Volver
+ start_new: "Crear una propuesta de gasto"
+ more_info: "¿Cómo funcionan los presupuestos participativos?"
+ recommendations_title: "Recomendaciones para crear una propuesta de gasto"
+ recommendation_one: "Es fundamental que haga referencia a una actuación presupuestable."
+ recommendation_two: "Cualquier propuesta o comentario que implique acciones ilegales será eliminada."
+ recommendation_three: "Intenta detallar lo máximo posible la propuesta para que el equipo de gobierno encargado de estudiarla tenga las menor dudas posibles."
+ form:
+ title: "Título de la propuesta de gasto"
+ description: "Descripción detallada"
+ external_url: "Enlace a documentación adicional"
+ tags_label: "Temas"
+ tags_instructions: "Etiqueta esta propuesta de gasto. Puedes elegir entre nuestras sugerencias o introducir las que desees."
+ tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')"
+ submit_buttons:
+ new: Crear
+ create: Crear
comments:
show:
return_to_commentable: "Volver a "
@@ -338,6 +356,7 @@ es:
user: "el código secreto no coincide con la imagen"
debate: "el código secreto no coincide con la imagen"
proposal: "el código secreto no coincide con la imagen"
+ spendingproposal: "el código secreto no coincide con la imagen"
shared:
author_info:
author_deleted: Usuario eliminado
diff --git a/spec/features/spending_proposals_spec.rb b/spec/features/spending_proposals_spec.rb
index 1a5946b01..bf4a7f585 100644
--- a/spec/features/spending_proposals_spec.rb
+++ b/spec/features/spending_proposals_spec.rb
@@ -8,4 +8,50 @@ feature 'Spending proposals' do
expect(page).to have_link('Create spending proposal', href: new_spending_proposal_path)
end
+ scenario 'Create' do
+ author = create(:user)
+ login_as(author)
+
+ visit new_spending_proposal_path
+ fill_in 'spending_proposal_title', with: 'Build a skyscraper'
+ fill_in 'spending_proposal_description', with: 'I want to live in a high tower over the clouds'
+ fill_in 'spending_proposal_external_url', with: 'http://http://skyscraperpage.com/'
+ fill_in 'spending_proposal_captcha', with: correct_captcha_text
+ check 'spending_proposal_terms_of_service'
+
+ click_button 'Create'
+
+ expect(page).to have_content 'Spending proposal created successfully'
+ end
+
+ scenario 'Captcha is required for proposal creation' do
+ login_as(create(:user))
+
+ visit new_spending_proposal_path
+ fill_in 'spending_proposal_title', with: 'Build a skyscraper'
+ fill_in 'spending_proposal_description', with: 'I want to live in a high tower over the clouds'
+ fill_in 'spending_proposal_external_url', with: 'http://http://skyscraperpage.com/'
+ fill_in 'spending_proposal_captcha', with: 'wrongText'
+ check 'spending_proposal_terms_of_service'
+
+ click_button 'Create'
+
+ expect(page).to_not have_content 'Spending proposal created successfully'
+ expect(page).to have_content '1 error'
+
+ fill_in 'spending_proposal_captcha', with: correct_captcha_text
+ click_button 'Create'
+
+ expect(page).to have_content 'Spending proposal created successfully'
+ end
+
+ scenario 'Errors on create' do
+ author = create(:user)
+ login_as(author)
+
+ visit new_spending_proposal_path
+ click_button 'Create'
+ expect(page).to have_content error_message
+ end
+
end