diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index bf812e990..4677488f1 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -48,8 +48,17 @@ class LocationsController < ApplicationController end def deactivate - if @location.location_deactivation_periods.create!(deactivation_date: params[:deactivation_date]) && reset_location_and_scheme_for_logs! + if @location.location_deactivation_periods.create!(deactivation_date: params[:deactivation_date]) + logs = reset_location_and_scheme_for_logs! + flash[:notice] = deactivate_success_notice + logs.group_by(&:created_by).transform_values(&:count).compact.each do |user, count| + LocationOrSchemeDeactivationMailer.send_deactivation_mail(user, + count, + url_for(controller: "lettings_logs", action: "update_logs"), + @location.scheme.service_name, + @location.postcode).deliver_later + end end redirect_to scheme_location_path(@scheme, @location) end @@ -219,7 +228,9 @@ private end def reset_location_and_scheme_for_logs! - @location.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil, unresolved: true) + logs = @location.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time) + logs.update!(location: nil, scheme: nil, unresolved: true) + logs end def toggle_date(key) diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index 477c5d143..bfa7073d6 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -49,8 +49,16 @@ class SchemesController < ApplicationController end def deactivate - if @scheme.scheme_deactivation_periods.create!(deactivation_date: params[:deactivation_date]) && reset_location_and_scheme_for_logs! + if @scheme.scheme_deactivation_periods.create!(deactivation_date: params[:deactivation_date]) + logs = reset_location_and_scheme_for_logs! + flash[:notice] = deactivate_success_notice + logs.group_by(&:created_by).transform_values(&:count).compact.each do |user, count| + LocationOrSchemeDeactivationMailer.send_deactivation_mail(user, + count, + url_for(controller: "lettings_logs", action: "update_logs"), + @scheme.service_name).deliver_later + end end redirect_to scheme_details_path(@scheme) end @@ -349,6 +357,8 @@ private end def reset_location_and_scheme_for_logs! - @scheme.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil, unresolved: true) + logs = @scheme.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time) + logs.update!(location: nil, scheme: nil, unresolved: true) + logs end end diff --git a/app/mailers/location_or_scheme_deactivation_mailer.rb b/app/mailers/location_or_scheme_deactivation_mailer.rb new file mode 100644 index 000000000..b6e8f704f --- /dev/null +++ b/app/mailers/location_or_scheme_deactivation_mailer.rb @@ -0,0 +1,26 @@ +class LocationOrSchemeDeactivationMailer < NotifyMailer + DEACTIVATION_TEMPLATE_ID = "8d07a8c3-a4e3-4102-8be7-4ee79e4183fd".freeze + + def send_deactivation_mail(user, log_count, update_logs_url, scheme_name, postcode = nil) + send_email( + user.email, + DEACTIVATION_TEMPLATE_ID, + { + log_count:, + log_or_logs: log_count == 1 ? "log" : "logs", + update_logs_url:, + location_or_scheme_description: description(scheme_name, postcode), + }, + ) + end + +private + + def description(scheme_name, postcode) + if postcode + "the #{postcode} location from the #{scheme_name} scheme" + else + "the #{scheme_name} scheme" + end + end +end diff --git a/app/mailers/notify_mailer.rb b/app/mailers/notify_mailer.rb index 506df5818..21a6e0270 100644 --- a/app/mailers/notify_mailer.rb +++ b/app/mailers/notify_mailer.rb @@ -1,4 +1,4 @@ -class NotifyMailer +class NotifyMailer < ApplicationMailer require "notifications/client" def notify_client diff --git a/spec/mailers/location_or_scheme_deactivation_mailer_spec.rb b/spec/mailers/location_or_scheme_deactivation_mailer_spec.rb new file mode 100644 index 000000000..49c515be8 --- /dev/null +++ b/spec/mailers/location_or_scheme_deactivation_mailer_spec.rb @@ -0,0 +1,73 @@ +require "rails_helper" + +RSpec.describe LocationOrSchemeDeactivationMailer do + let(:notify_client) { instance_double(Notifications::Client) } + + before do + allow(Notifications::Client).to receive(:new).and_return(notify_client) + allow(notify_client).to receive(:send_email).and_return(true) + end + + describe "#send_deactivation_mail" do + let(:user) { FactoryBot.create(:user, email: "user@example.com") } + + it "sends a deactivation E-mail via notify" do + update_logs_url = :update_logs_url + + expect(notify_client).to receive(:send_email).with(hash_including({ + email_address: user.email, + template_id: described_class::DEACTIVATION_TEMPLATE_ID, + personalisation: hash_including({ update_logs_url: }), + })) + + described_class.new.send_deactivation_mail(user, 3, update_logs_url, "Test Scheme Name", "test postcode") + end + + it "singularises 'logs' correctly" do + expect(notify_client).to receive(:send_email).with(hash_including({ + personalisation: hash_including({ + log_count: 1, + log_or_logs: "log", + }), + })) + + described_class.new.send_deactivation_mail(user, 1, :update_logs_url, :scheme_name) + end + + it "pluralises 'logs' correctly" do + expect(notify_client).to receive(:send_email).with(hash_including({ + personalisation: hash_including({ + log_count: 2, + log_or_logs: "logs", + }), + })) + + described_class.new.send_deactivation_mail(user, 2, :update_logs_url, :scheme_name) + end + + it "describes a scheme" do + scheme_name = "Test Scheme" + + expect(notify_client).to receive(:send_email).with(hash_including({ + personalisation: hash_including({ + location_or_scheme_description: "the #{scheme_name} scheme", + }), + })) + + described_class.new.send_deactivation_mail(user, 3, :update_logs_url, scheme_name) + end + + it "describes a location within a scheme" do + scheme_name = "Test Scheme" + postcode = "test postcode" + + expect(notify_client).to receive(:send_email).with(hash_including({ + personalisation: hash_including({ + location_or_scheme_description: "the #{postcode} location from the #{scheme_name} scheme", + }), + })) + + described_class.new.send_deactivation_mail(user, 3, :update_logs_url, scheme_name, postcode) + end + end +end diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index f17ef604a..e870fe4ff 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -1336,27 +1336,37 @@ RSpec.describe LocationsController, type: :request do context "when confirming deactivation" do let(:params) { { deactivation_date:, confirm: true, deactivation_date_type: "other" } } + let(:mailer) { instance_double(LocationOrSchemeDeactivationMailer) } + + let(:user_a) { FactoryBot.create(:user, email: "user_a@example.com") } + let(:user_b) { FactoryBot.create(:user, email: "user_b@example.com") } before do + FactoryBot.create_list(:lettings_log, 1, :sh, location:, scheme:, startdate:, created_by: user_a) + FactoryBot.create_list(:lettings_log, 3, :sh, location:, scheme:, startdate:, created_by: user_b) + Timecop.freeze(Time.utc(2022, 10, 10)) sign_in user - patch "/schemes/#{scheme.id}/locations/#{location.id}/deactivate", params: end after do Timecop.unfreeze end - it "updates existing location with valid deactivation date and renders location page" do - follow_redirect! - expect(response).to have_http_status(:ok) - expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") - location.reload - expect(location.location_deactivation_periods.count).to eq(1) - expect(location.location_deactivation_periods.first.deactivation_date).to eq(deactivation_date) - end - context "and a log startdate is after location deactivation date" do + before do + patch "/schemes/#{scheme.id}/locations/#{location.id}/deactivate", params: + end + + it "updates existing location with valid deactivation date and renders location page" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + location.reload + expect(location.location_deactivation_periods.count).to eq(1) + expect(location.location_deactivation_periods.first.deactivation_date).to eq(deactivation_date) + end + it "clears the location and scheme answers" do expect(lettings_log.location).to eq(location) expect(lettings_log.scheme).to eq(scheme) @@ -1372,6 +1382,14 @@ RSpec.describe LocationsController, type: :request do end end + context "and the users need to be notified" do + it "sends E-mails to the creators of affected logs with counts" do + expect { + patch "/schemes/#{scheme.id}/locations/#{location.id}/deactivate", params: + }.to enqueue_job(ActionMailer::MailDeliveryJob).at_least(2).times + end + end + context "and a log startdate is before location deactivation date" do let(:startdate) { Time.utc(2022, 10, 9) } diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index 0a75e4fcd..3624313eb 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -1792,7 +1792,7 @@ RSpec.describe SchemesController, type: :request do let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation, created_at: Time.zone.today) } let!(:location) { FactoryBot.create(:location, scheme:) } let(:deactivation_date) { Time.utc(2022, 10, 10) } - let!(:lettings_log) { FactoryBot.create(:lettings_log, :sh, location:, scheme:, startdate:, owning_organisation: user.organisation) } + let!(:lettings_log) { FactoryBot.create(:lettings_log, :sh, location:, scheme:, startdate:, owning_organisation: user.organisation, created_by: user) } let(:startdate) { Time.utc(2022, 10, 11) } let(:setup_schemes) { nil } @@ -1863,28 +1863,32 @@ RSpec.describe SchemesController, type: :request do context "when confirming deactivation" do let(:params) { { deactivation_date:, confirm: true, deactivation_date_type: "other" } } + let(:mailer) { instance_double(LocationOrSchemeDeactivationMailer) } before do Timecop.freeze(Time.utc(2022, 10, 10)) sign_in user - patch "/schemes/#{scheme.id}/deactivate", params: end after do Timecop.unfreeze end - it "updates existing scheme with valid deactivation date and renders scheme page" do - follow_redirect! - follow_redirect! - expect(response).to have_http_status(:ok) - expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") - scheme.reload - expect(scheme.scheme_deactivation_periods.count).to eq(1) - expect(scheme.scheme_deactivation_periods.first.deactivation_date).to eq(deactivation_date) - end - context "and a log startdate is after scheme deactivation date" do + before do + patch "/schemes/#{scheme.id}/deactivate", params: + end + + it "updates existing scheme with valid deactivation date and renders scheme page" do + follow_redirect! + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + scheme.reload + expect(scheme.scheme_deactivation_periods.count).to eq(1) + expect(scheme.scheme_deactivation_periods.first.deactivation_date).to eq(deactivation_date) + end + it "clears the scheme and scheme answers" do expect(lettings_log.scheme).to eq(scheme) expect(lettings_log.scheme).to eq(scheme) @@ -1917,6 +1921,14 @@ RSpec.describe SchemesController, type: :request do expect(lettings_log.unresolved).to eq(nil) end end + + context "and the users need to be notified" do + it "sends E-mails to the creators of affected logs with counts" do + expect { + patch "/schemes/#{scheme.id}/deactivate", params: + }.to enqueue_job(ActionMailer::MailDeliveryJob) + end + end end context "when the date is not selected" do