diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 932d760b0..ebf14d94b 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -46,6 +46,7 @@ module Budgets @investment.author = current_user if @investment.save + Mailer.budget_investment_created(@investment).deliver_later redirect_to budget_investment_path(@budget, @investment), notice: t('flash.actions.create.budget_investment') else diff --git a/app/controllers/valuation/budget_investments_controller.rb b/app/controllers/valuation/budget_investments_controller.rb index 03facadb3..666fac74a 100644 --- a/app/controllers/valuation/budget_investments_controller.rb +++ b/app/controllers/valuation/budget_investments_controller.rb @@ -21,6 +21,11 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController def valuate if valid_price_params? && @investment.update(valuation_params) + + if @investment.unfeasible_email_pending? + @investment.send_unfeasible_email + end + redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate') else render action: :edit diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 25c019857..188de029b 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -74,6 +74,23 @@ class Mailer < ApplicationMailer end end + def budget_investment_created(investment) + @investment = investment + + with_user(@investment.author) do + mail(to: @investment.author.email, subject: t('mailers.budget_investment_created.subject')) + end + end + + def budget_investment_unfeasible(investment) + @investment = investment + @author = investment.author + + with_user(@author) do + mail(to: @author.email, subject: t('mailers.budget_investment_unfeasible.subject', code: @investment.code)) + end + end + private def with_user(user, &block) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 395b6890e..100433707 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -136,12 +136,21 @@ class Budget unfeasible? && valuation_finished? end + def unfeasible_email_pending? + unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished? + end + def total_votes cached_votes_up + physical_votes end def code - "B#{budget.id}I#{id}" + "#{created_at.strftime('%Y')}-#{id}" + (administrator.present? ? "-A#{administrator.id}" : "") + end + + def send_unfeasible_email + Mailer.budget_investment_unfeasible(self).deliver_later + update(unfeasible_email_sent_at: Time.current) end def reason_for_not_being_selectable_by(user) diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index af3c6b194..fad11d0f0 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -95,7 +95,8 @@
<%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %> <% if browser.device.mobile? %> - + <% end %> @@ -104,11 +105,23 @@ <% else %>
- <%= t("budgets.investments.show.title") %> + + <%= t("budgets.investments.show.title") %> +
+
+ <% end %> + +

<%= t("budgets.investments.show.share") %>

+ - <% end %> - +
diff --git a/app/views/mailer/budget_investment_created.html.erb b/app/views/mailer/budget_investment_created.html.erb new file mode 100644 index 000000000..59af63dd1 --- /dev/null +++ b/app/views/mailer/budget_investment_created.html.erb @@ -0,0 +1,42 @@ + + +

+ <%= t("mailers.budget_investment_created.title") %> +

+ +

+ <%= t("mailers.budget_investment_created.intro_html", + author: @investment.author.name).html_safe %> +

+ +

+ <%= t("mailers.budget_investment_created.text_html", + investment: @investment.title, + budget: @investment.budget.name).html_safe %> +

+ +

+ <%= t("mailers.budget_investment_created.follow_html", + link: link_to(t("mailers.budget_investment_created.follow_link"), budgets_url)).html_safe %> +

+ + + + + + + +
+ <%= link_to budget_investment_url(@investment.budget, @investment, anchor: "social-share"), style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block;" do %> + <%= image_tag('icon_mailer_share.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px", alt: "") %> + <%= t('mailers.budget_investment_created.share') %> + <% end %> +
+ +

+ <%= t("mailers.budget_investment_created.sincerely") %> +
+ + <%= t("mailers.budget_investment_created.signatory") %> + +

diff --git a/app/views/mailer/budget_investment_unfeasible.html.erb b/app/views/mailer/budget_investment_unfeasible.html.erb new file mode 100644 index 000000000..3bed46cec --- /dev/null +++ b/app/views/mailer/budget_investment_unfeasible.html.erb @@ -0,0 +1,35 @@ + + +

+ <%= t("mailers.budget_investment_unfeasible.hi") %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.unfeasible_html", + title: @investment.title) %> +

+ +

+ <%= @investment.unfeasibility_explanation %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.new_html", + url: link_to(t("mailers.budget_investment_unfeasible.new_href"), + new_budget_investment_url(@investment.budget), style: "color: #2895F1; text-decoration: underline;")) %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.reconsider_html", code: @investment.code) %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.sorry") %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.sincerely") %>
+ + <%= t("mailers.budget_investment_unfeasible.signatory") %> +

+ \ No newline at end of file diff --git a/config/locales/mailers.en.yml b/config/locales/mailers.en.yml index 3fa63f9ec..49143f354 100755 --- a/config/locales/mailers.en.yml +++ b/config/locales/mailers.en.yml @@ -31,6 +31,16 @@ en: sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation." subject: "Your investment project '%{code}' has been marked as unfeasible" unfeasible_html: "From the City Council we want to thank you for your participation in the participatory budgets. We regret to inform you that your proposal '%{title}' will be excluded from this participatory process for the following reason:" + budget_investment_unfeasible: + hi: "Dear user," + new_html: "For all these, we invite you to elaborate a new proposal that ajusts to the conditions of this process. You can do it following this link: %{url}." + new_href: "new investment project" + reconsider_html: "If you believe that the rejected proposal meets the requirements to be an investment proposal, you can communicate this, within 48 hours, responding to the email address examples@consul.es. Including the code %{code} in the subject of the email." + sincerely: "Sincerely" + signatory: "DEPARTMENT OF PUBLIC PARTICIPATION" + sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation." + subject: "Your investment project '%{code}' has been marked as unfeasible" + unfeasible_html: "From the City Council we want to thank you for your participation in the participatory budgets. We regret to inform you that your proposal '%{title}' will be excluded from this participatory process for the following reason:" proposal_notification_digest: info: "Here are the new notifications that have been published by authors of the proposals that you have supported in %{org_name}." title: "Proposal notifications in %{org_name}" @@ -52,4 +62,24 @@ en: thanks: "Thank you very much." title: "Welcome to %{org}" button: Complete registration - subject: "Invitation to %{org_name}" \ No newline at end of file + subject: "Invitation to %{org_name}" + budget_investment_created: + subject: "Thank you for creating an investment!" + title: "Thank you for creating an investment!" + intro_html: "Hi %{author}," + text_html: "Thank you for creating your investment %{investment} for Participatory Budgets %{budget}." + follow_html: "We will inform you about how the process progresses, which you can also follow on %{link}." + follow_link: "Participatory Budgets" + sincerely: "Sincerely," + signatory: "DEPARTMENT OF PUBLIC PARTICIPATION" + share: "Comparte tu proyecto" + budget_investment_unfeasible: + hi: "Dear user," + new_html: "For all these, we invite you to elaborate a new investment that ajusts to the conditions of this process. You can do it following this link: %{url}." + new_href: "new investment project" + reconsider_html: "If you believe that the rejected investment meets the requirements to be an investment project, you can communicate this, within 48 hours, responding to the email address examples@consul.es. Including the code %{code} in the subject of the email." + sincerely: "Sincerely" + signatory: "DEPARTMENT OF PUBLIC PARTICIPATION" + sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation." + subject: "Your investment project '%{code}' has been marked as unfeasible" + unfeasible_html: "From the City Council we want to thank you for your participation in the participatory budgets. We regret to inform you that your investment '%{title}' will be excluded from this participatory process for the following reason:" \ No newline at end of file diff --git a/config/locales/mailers.es.yml b/config/locales/mailers.es.yml index 49e3e0796..82a03d8de 100644 --- a/config/locales/mailers.es.yml +++ b/config/locales/mailers.es.yml @@ -52,4 +52,24 @@ es: thanks: "Muchas gracias." title: "Bienvenido a %{org}" button: Completar registro - subject: "Invitación a %{org_name}" \ No newline at end of file + subject: "Invitación a %{org_name}" + budget_investment_created: + subject: "¡Gracias por crear un proyecto!" + title: "¡Gracias por crear un proyecto!" + intro_html: "Hola %{author}," + text_html: "Muchas gracias por crear tu proyecto %{investment} para los Presupuestos Participativos %{budget}." + follow_html: "Te informaremos de cómo avanza el proceso, que también puedes seguir en la página de %{link}." + follow_link: "Presupuestos participativos" + sincerely: "Atentamente," + signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA" + share: "Comparte tu proyecto" + budget_investment_unfeasible: + hi: "Estimado usuario," + new_html: "Por todo ello, te invitamos a que elabores un nuevo proyecto de gasto que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}." + new_href: "nueva propuesta de inversión" + reconsider_html: "Si consideras que el proyecto rechazado cumple los requisitos para mantenerlo como proyecto de gasto, podrás comunicarlo, en el plazo de 48 horas, al correo example@consul.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu proyecto." + sincerely: "Atentamente" + signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA" + sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación." + subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable" + unfeasible_html: "Desde el Ayuntamiento queremos agradecer tu participación en los Presupuestos Participativos. Lamentamos informarte de que tu proyecto '%{title}' quedará excluido de este proceso participativo por el siguiente motivo:" \ No newline at end of file diff --git a/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb b/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb new file mode 100644 index 000000000..dbd1a203b --- /dev/null +++ b/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb @@ -0,0 +1,5 @@ +class AddUnfeasibleEmailSentAtToBudgetInvestments < ActiveRecord::Migration + def change + add_column :budget_investments, :unfeasible_email_sent_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 6a9498399..fb563c8db 100644 --- a/db/schema.rb +++ b/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: 20170106130838) do +ActiveRecord::Schema.define(version: 20170114154421) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -143,6 +143,7 @@ ActiveRecord::Schema.define(version: 20170106130838) do t.boolean "selected", default: false t.string "location" t.string "organization_name" + t.datetime "unfeasible_email_sent_at" end add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb index fe6c18774..b3e52370d 100644 --- a/spec/features/emails_spec.rb +++ b/spec/features/emails_spec.rb @@ -261,4 +261,65 @@ feature 'Emails' do end + context "Budgets" do + + background do + Setting["feature.budgets"] = true + end + + let(:author) { create(:user, :level_two) } + let(:budget) { create(:budget) } + let(:group) { create(:budget_group, name: "Health", budget: budget) } + let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } + + scenario "Investment created" do + login_as(author) + visit new_budget_investment_path(budget_id: budget.id) + + select 'Health: More hospitals', from: 'budget_investment_heading_id' + fill_in 'budget_investment_title', with: 'Build a hospital' + fill_in 'budget_investment_description', with: 'We have lots of people that require medical attention' + fill_in 'budget_investment_external_url', with: 'http://http://hospitalsforallthepeople.com/' + check 'budget_investment_terms_of_service' + + click_button 'Create Investment' + expect(page).to have_content 'Investment created successfully' + + email = open_last_email + investment = Budget::Investment.last + + expect(email).to have_subject("Thank you for creating an investment!") + expect(email).to deliver_to(investment.author.email) + expect(email).to have_body_text(author.name) + expect(email).to have_body_text(investment.title) + expect(email).to have_body_text(investment.budget.name) + expect(email).to have_body_text(budget_path(budget)) + end + + scenario "Unfeasible investment" do + investment = create(:budget_investment, author: author, budget: budget) + + valuator = create(:valuator) + investment.valuators << valuator + + login_as(valuator.user) + visit edit_valuation_budget_budget_investment_path(budget, investment) + + choose 'budget_investment_feasibility_unfeasible' + fill_in 'budget_investment_unfeasibility_explanation', with: 'This is not legal as stated in Article 34.9' + check 'budget_investment_valuation_finished' + click_button 'Save changes' + + expect(page).to have_content "Dossier updated" + investment.reload + + email = open_last_email + expect(email).to have_subject("Your investment project '#{investment.code}' has been marked as unfeasible") + expect(email).to deliver_to(investment.author.email) + expect(email).to have_body_text(investment.title) + expect(email).to have_body_text(investment.code) + expect(email).to have_body_text(investment.unfeasibility_explanation) + end + + end end diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 0c9d14561..abbc8ad26 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -58,10 +58,29 @@ describe Budget::Investment do end describe "#code" do - it "returns the investment and budget id" do - investment = create(:budget_investment) - expect(investment.code).to include("#{investment.id}") - expect(investment.code).to include("#{investment.budget.id}") + let(:investment) { create(:budget_investment) } + + it "returns the proposal id" do + expect(investment.code).to include("#{investment.id}") + end + + it "returns the administrator id when assigned" do + investment.administrator = create(:administrator) + expect(investment.code).to include("#{investment.id}-A#{investment.administrator.id}") + end + end + + describe "#send_unfeasible_email" do + let(:investment) { create(:budget_investment) } + + it "sets the time when the unfeasible email was sent" do + expect(investment.unfeasible_email_sent_at).to_not be + investment.send_unfeasible_email + expect(investment.unfeasible_email_sent_at).to be + end + + it "send an email" do + expect {investment.send_unfeasible_email}.to change { ActionMailer::Base.deliveries.count }.by(1) end end