diff --git a/app/controllers/valuation/spending_proposals_controller.rb b/app/controllers/valuation/spending_proposals_controller.rb index f8c63c974..364671d09 100644 --- a/app/controllers/valuation/spending_proposals_controller.rb +++ b/app/controllers/valuation/spending_proposals_controller.rb @@ -18,6 +18,11 @@ class Valuation::SpendingProposalsController < Valuation::BaseController def valuate if valid_price_params? && @spending_proposal.update(valuation_params) + + if @spending_proposal.unfeasible_email_pending? + @spending_proposal.send_unfeasible_email + end + redirect_to valuation_spending_proposal_path(@spending_proposal), notice: t('valuation.spending_proposals.notice.valuate') else render action: :edit diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 356f2ea45..fcc2a62b1 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -33,6 +33,15 @@ class Mailer < ApplicationMailer end end + def unfeasible_spending_proposal(spending_proposal) + @spending_proposal = spending_proposal + @author = spending_proposal.author + + with_user(@author) do + mail(to: @author.email, subject: t('mailers.unfeasible_spending_proposal.subject', code: @spending_proposal.code)) + end + end + private def with_user(user, &block) diff --git a/app/models/spending_proposal.rb b/app/models/spending_proposal.rb index 237da73f7..a084a800e 100644 --- a/app/models/spending_proposal.rb +++ b/app/models/spending_proposal.rb @@ -68,4 +68,25 @@ class SpendingProposal < ActiveRecord::Base end end + def unfeasible_email_pending? + unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished? + end + + def unfeasible? + feasible == false + end + + def valuation_finished? + valuation_finished + end + + def code + "#{id}" + (administrator.present? ? "-A#{administrator.id}" : "") + end + + def send_unfeasible_email + Mailer.unfeasible_spending_proposal(self).deliver_later + update(unfeasible_email_sent_at: Time.now) + end + end diff --git a/app/views/mailer/unfeasible_spending_proposal.html.erb b/app/views/mailer/unfeasible_spending_proposal.html.erb new file mode 100644 index 000000000..fa4e3cf96 --- /dev/null +++ b/app/views/mailer/unfeasible_spending_proposal.html.erb @@ -0,0 +1,35 @@ + + +

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

+ +

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

+ +

+ <%= @spending_proposal.feasible_explanation %> +

+ +

+ <%= t("mailers.unfeasible_spending_proposal.new_html", + url: link_to(t("mailers.unfeasible_spending_proposal.new_href"), + new_spending_proposal_url, style: "color: #2895F1; text-decoration: underline;")) %> +

+ +

+ <%= t("mailers.unfeasible_spending_proposal.reconsider_html") %> +

+ +

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

+ +

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

+ \ No newline at end of file diff --git a/config/locales/mailers.en.yml b/config/locales/mailers.en.yml index 8e337b42e..9e18435dd 100755 --- a/config/locales/mailers.en.yml +++ b/config/locales/mailers.en.yml @@ -20,3 +20,13 @@ en: new_reply_by_html: There is a new response from %{commenter} to your comment on subject: Someone has responded to your comment title: New response to your comment + unfeasible_spending_proposal: + 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 preparticipativos@madrid.es. Please include all relevant information to reconsider the proposal as valid." + 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 Madrid City Council we want to thank you for your participation in the participatory budgets of the city of Madrid. We regret to inform you that your proposal '%{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 fb0e7b2fb..2e11604a3 100644 --- a/config/locales/mailers.es.yml +++ b/config/locales/mailers.es.yml @@ -20,3 +20,13 @@ es: new_reply_by_html: Hay una nueva respuesta de %{commenter} a tu comentario en subject: Alguien ha respondido a tu comentario title: Nueva respuesta a tu comentario + unfeasible_spending_proposal: + hi: "Estimado usuario," + new_html: "Por todo ello, te invitamos a que elabores una nueva propuesta 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 la propuesta rechazada cumple los requisitos para mantenerla como propuesta de inversión, podrás comunicarlo, en el plazo de 48 horas, al correo preparticipativos@madrid.es. Por favor incluye toda la información relevante para reconsiderar la propuesta como válida." + 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 de Madrid queremos agradecer tu participación en los Presupuestos Participativos de la ciudad de Madrid. Lamentamos informarte de que tu propuesta '%{title}' quedará excluida de este proceso participativo por el siguiente motivo:" diff --git a/db/migrate/20160328152843_add_unfeasible_email_sent_at_to_spending_proposals.rb b/db/migrate/20160328152843_add_unfeasible_email_sent_at_to_spending_proposals.rb new file mode 100644 index 000000000..bbe1dc6ec --- /dev/null +++ b/db/migrate/20160328152843_add_unfeasible_email_sent_at_to_spending_proposals.rb @@ -0,0 +1,5 @@ +class AddUnfeasibleEmailSentAtToSpendingProposals < ActiveRecord::Migration + def change + add_column :spending_proposals, :unfeasible_email_sent_at, :datetime, default: nil + end +end diff --git a/db/schema.rb b/db/schema.rb index a406d3f4c..c6c5faa19 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: 20160315092854) do +ActiveRecord::Schema.define(version: 20160328152843) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -311,6 +311,7 @@ ActiveRecord::Schema.define(version: 20160315092854) do t.integer "valuation_assignments_count", default: 0 t.integer "price_first_year", limit: 8 t.string "time_scope" + t.datetime "unfeasible_email_sent_at" end add_index "spending_proposals", ["author_id"], name: "index_spending_proposals_on_author_id", using: :btree diff --git a/lib/tasks/spending_proposals.rake b/lib/tasks/spending_proposals.rake new file mode 100644 index 000000000..b49f2acf5 --- /dev/null +++ b/lib/tasks/spending_proposals.rake @@ -0,0 +1,13 @@ +namespace :spending_proposals do + desc "Sends an email to the authors of unfeasible spending proposals" + task send_unfeasible_emails: :environment do + SpendingProposal.find_each do |spending_propsal| + if spending_propsal.unfeasible_email_pending? + spending_propsal.send_unfeasible_email + puts "email sent for proposal #{spending_propsal.title}" + else + puts "this proposal is feasible: #{spending_propsal.title}" + end + end + end +end \ No newline at end of file diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb index fd3b219e6..c6d675a73 100644 --- a/spec/features/emails_spec.rb +++ b/spec/features/emails_spec.rb @@ -122,4 +122,29 @@ feature 'Emails' do expect(email).to have_body_text(user_confirmation_path) end + scenario "Email on unfeasible spending proposal" do + spending_proposal = create(:spending_proposal) + administrator = create(:administrator) + valuator = create(:valuator) + spending_proposal.update(administrator: administrator) + spending_proposal.valuators << valuator + + login_as(valuator.user) + visit edit_valuation_spending_proposal_path(spending_proposal) + + choose 'spending_proposal_feasible_false' + fill_in 'spending_proposal_feasible_explanation', with: 'This is not legal as stated in Article 34.9' + check 'spending_proposal_valuation_finished' + click_button 'Save changes' + + expect(page).to have_content "Dossier updated" + spending_proposal.reload + + email = open_last_email + expect(email).to have_subject("Your investment project '#{spending_proposal.id}-A#{spending_proposal.administrator.id}' has been marked as unfeasible") + expect(email).to deliver_to(spending_proposal.author.email) + expect(email).to have_body_text(spending_proposal.title) + expect(email).to have_body_text(spending_proposal.feasible_explanation) + end + end diff --git a/spec/models/spending_proposal_spec.rb b/spec/models/spending_proposal_spec.rb index 2a10851b6..4d320a8d7 100644 --- a/spec/models/spending_proposal_spec.rb +++ b/spec/models/spending_proposal_spec.rb @@ -59,6 +59,69 @@ describe SpendingProposal do expect(spending_proposal.feasibility).to eq "undefined" end end + + describe "#unfeasible?" do + it "returns true when not feasible" do + spending_proposal.feasible = false + expect(spending_proposal.unfeasible?).to eq true + end + + it "returns false when feasible" do + spending_proposal.feasible = true + expect(spending_proposal.unfeasible?).to eq false + end + end + + describe "#unfeasible_email_pending?" do + let(:spending_proposal) { create(:spending_proposal) } + + it "returns true when marked as unfeasibable and valuation_finished" do + spending_proposal.update(feasible: false, valuation_finished: true) + expect(spending_proposal.unfeasible_email_pending?).to eq true + end + + it "returns false when marked as feasible" do + spending_proposal.update(feasible: true) + expect(spending_proposal.unfeasible_email_pending?).to eq false + end + + it "returns false when marked as feasable and valuation_finished" do + spending_proposal.update(feasible: true, valuation_finished: true) + expect(spending_proposal.unfeasible_email_pending?).to eq false + end + + it "returns false when unfeasible email already sent" do + spending_proposal.update(unfeasible_email_sent_at: 1.day.ago) + expect(spending_proposal.unfeasible_email_pending?).to eq false + end + end + + describe "#send_unfeasible_email" do + let(:spending_proposal) { create(:spending_proposal) } + + it "sets the time when the unfeasible email was sent" do + expect(spending_proposal.unfeasible_email_sent_at).to_not be + spending_proposal.send_unfeasible_email + expect(spending_proposal.unfeasible_email_sent_at).to be + end + + it "send an email" do + expect {spending_proposal.send_unfeasible_email}.to change { ActionMailer::Base.deliveries.count }.by(1) + end + end + + describe "#code" do + let(:spending_proposal) { create(:spending_proposal) } + + it "returns the proposal id" do + expect(spending_proposal.code).to eq("#{spending_proposal.id}") + end + + it "returns the administrator id when assigned" do + spending_proposal.administrator = create(:administrator) + expect(spending_proposal.code).to eq("#{spending_proposal.id}-A#{spending_proposal.administrator.id}") + end + end end describe "by_admin" do