@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -95,7 +95,8 @@
|
||||
<div class="social-share-full">
|
||||
<%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %>
|
||||
<% if browser.device.mobile? %>
|
||||
<a href="whatsapp://send?text=<%= investment.title %> <%= budget_investment_url(budget_id: investment.budget_id, id: investment.id) %>" data-action="share/whatsapp/share">
|
||||
<a href="whatsapp://send?text=<%= investment.title %> <%= budget_investment_url(budget_id: investment.budget_id, id: investment.id) %>"
|
||||
data-action="share/whatsapp/share">
|
||||
<span class="icon-whatsapp whatsapp"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
@@ -104,11 +105,23 @@
|
||||
<% else %>
|
||||
<div class="small-12 medium-3 column">
|
||||
<div class="float-right">
|
||||
<span class="label-budget-investment float-left"><%= t("budgets.investments.show.title") %></span>
|
||||
<span class="label-budget-investment float-left">
|
||||
<%= t("budgets.investments.show.title") %>
|
||||
</span>
|
||||
<span class="icon-budget"></span>
|
||||
</div>
|
||||
<br>
|
||||
<% end %>
|
||||
<div id="social-share" class="sidebar-divider"></div>
|
||||
<h2><%= t("budgets.investments.show.share") %></h2>
|
||||
<div class="social-share-full">
|
||||
<%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %>
|
||||
<% if browser.device.mobile? %>
|
||||
<a href="whatsapp://send?text=<%= investment.title %> <%= budget_investment_url(budget_id: investment.budget_id, id: investment.id) %>" data-action="share/whatsapp/share">
|
||||
<span class="icon-whatsapp whatsapp"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
42
app/views/mailer/budget_investment_created.html.erb
Normal file
42
app/views/mailer/budget_investment_created.html.erb
Normal file
@@ -0,0 +1,42 @@
|
||||
<td style="padding-bottom: 20px; padding-left: 10px;">
|
||||
|
||||
<h1 style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;">
|
||||
<%= t("mailers.budget_investment_created.title") %>
|
||||
</h1>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_created.intro_html",
|
||||
author: @investment.author.name).html_safe %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_created.text_html",
|
||||
investment: @investment.title,
|
||||
budget: @investment.budget.name).html_safe %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_created.follow_html",
|
||||
link: link_to(t("mailers.budget_investment_created.follow_link"), budgets_url)).html_safe %>
|
||||
</p>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding-bottom: 12px; text-align: center;">
|
||||
<%= 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 %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_created.sincerely") %>
|
||||
<br>
|
||||
<span style="color: #ccc; font-size: 12px;">
|
||||
<%= t("mailers.budget_investment_created.signatory") %>
|
||||
</span>
|
||||
</p>
|
||||
35
app/views/mailer/budget_investment_unfeasible.html.erb
Normal file
35
app/views/mailer/budget_investment_unfeasible.html.erb
Normal file
@@ -0,0 +1,35 @@
|
||||
<td style="padding-bottom: 20px; padding-left: 10px;">
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_unfeasible.hi") %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_unfeasible.unfeasible_html",
|
||||
title: @investment.title) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; padding-left: 12px; border-left: 2px solid #ccc;">
|
||||
<%= @investment.unfeasibility_explanation %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= 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;")) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_unfeasible.reconsider_html", code: @investment.code) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_unfeasible.sorry") %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.budget_investment_unfeasible.sincerely") %><br>
|
||||
<span style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 12px;font-weight: normal;line-height: 24px; color: #ccc;">
|
||||
<%= t("mailers.budget_investment_unfeasible.signatory") %></span>
|
||||
</p>
|
||||
</td>
|
||||
@@ -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 <strong>participatory budgets</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> 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 <strong>new proposal</strong> 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 <strong>participatory budgets</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> 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}"
|
||||
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 <strong>%{author}</strong>,"
|
||||
text_html: "Thank you for creating your investment <strong>%{investment}</strong> for Participatory Budgets <strong>%{budget}</strong>."
|
||||
follow_html: "We will inform you about how the process progresses, which you can also follow on <strong>%{link}</strong>."
|
||||
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 <strong>new investment</strong> 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 <strong>participatory budgets</strong>. We regret to inform you that your investment <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:"
|
||||
@@ -52,4 +52,24 @@ es:
|
||||
thanks: "Muchas gracias."
|
||||
title: "Bienvenido a %{org}"
|
||||
button: Completar registro
|
||||
subject: "Invitación a %{org_name}"
|
||||
subject: "Invitación a %{org_name}"
|
||||
budget_investment_created:
|
||||
subject: "¡Gracias por crear un proyecto!"
|
||||
title: "¡Gracias por crear un proyecto!"
|
||||
intro_html: "Hola <strong>%{author}</strong>,"
|
||||
text_html: "Muchas gracias por crear tu proyecto <strong>%{investment}</strong> para los Presupuestos Participativos <strong>%{budget}</strong>."
|
||||
follow_html: "Te informaremos de cómo avanza el proceso, que también puedes seguir en la página de <strong>%{link}</strong>."
|
||||
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 <strong>nuevo proyecto de gasto</strong> 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 <strong>Presupuestos Participativos</strong>. Lamentamos informarte de que tu proyecto <strong>'%{title}'</strong> quedará excluido de este proceso participativo por el siguiente motivo:"
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddUnfeasibleEmailSentAtToBudgetInvestments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :budget_investments, :unfeasible_email_sent_at, :datetime
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user