diff --git a/app/jobs/send_reference_request_reminder_to_teacher_job.rb b/app/jobs/send_reference_request_reminder_to_teacher_job.rb new file mode 100644 index 0000000000..c0daac6bce --- /dev/null +++ b/app/jobs/send_reference_request_reminder_to_teacher_job.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class SendReferenceRequestReminderToTeacherJob < ApplicationJob + def perform + SendReferenceRequestReminderToTeacher.call + end +end diff --git a/app/mailers/teacher_mailer.rb b/app/mailers/teacher_mailer.rb index 09a93c9e82..83ece2cdee 100644 --- a/app/mailers/teacher_mailer.rb +++ b/app/mailers/teacher_mailer.rb @@ -99,6 +99,18 @@ def references_requested ) end + def references_reminder + @number_of_reminders_sent = teacher.reminder_emails.count + view_mail( + GOVUK_NOTIFY_TEMPLATE_ID, + to: teacher.email, + subject: + I18n.t( + "mailer.teacher.references_reminder.subject.#{@number_of_reminders_sent}", + ), + ) + end + private def teacher diff --git a/app/models/concerns/expirable.rb b/app/models/concerns/expirable.rb index 4676102fc4..5bbc552fcb 100644 --- a/app/models/concerns/expirable.rb +++ b/app/models/concerns/expirable.rb @@ -4,6 +4,7 @@ module Expirable extend ActiveSupport::Concern def expires_at + return true if is_a?(Teacher) return nil if requested_at.nil? || expires_after.nil? requested_at + expires_after diff --git a/app/models/teacher.rb b/app/models/teacher.rb index b996aaf68a..ae4a0ae084 100644 --- a/app/models/teacher.rb +++ b/app/models/teacher.rb @@ -23,6 +23,7 @@ # index_teachers_on_uuid (uuid) UNIQUE # class Teacher < ApplicationRecord + include Remindable include Emailable devise :magic_link_authenticatable, :registerable, :timeoutable, :trackable @@ -45,4 +46,28 @@ def send_magic_link(*) def send_devise_notification(notification, *args) devise_mailer.send(notification, self, *args).deliver_later end + + def should_send_reminder_email? + all_reference_requests = + ReferenceRequest + .joins(:work_history) + .where(work_histories: { application_form_id: application_form.id }) + .where(received_at: nil, expired_at: nil) + @remindable_reference_requests = + all_reference_requests.select do |reference_request| + reference_request.should_send_reminder_email?( + (reference_request.expires_at.to_date - Time.zone.today).to_i, + reminder_emails.count, + ) + end + Rails.logger.debug @remindable_reference_requests + @remindable_reference_requests.any? + end + + def send_reminder_email(_number_of_reminders_sent) + TeacherMailer + .with(teacher: self, reference_requests: @remindable_reference_requests) + .references_reminder + .deliver_later + end end diff --git a/app/services/send_reference_request_reminder_to_teacher.rb b/app/services/send_reference_request_reminder_to_teacher.rb new file mode 100644 index 0000000000..ccea0459aa --- /dev/null +++ b/app/services/send_reference_request_reminder_to_teacher.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +# +class SendReferenceRequestReminderToTeacher + include ServicePattern + + def call + reference_requests = + ReferenceRequest.where(expired_at: nil, received_at: nil) + teachers_to_receive_reminder_email = Set.new + + reference_requests.each do |reference_request| + if reference_request.should_display_teacher_reference_reminder_text? + teacher = reference_request.assessment.application_form.teacher + teachers_to_receive_reminder_email.add(teacher) + end + end + teachers_to_receive_reminder_email.each do |teacher| + TeacherMailer.with(teacher:).references_reminder.deliver_later + end + end +end diff --git a/app/services/send_reminder_email.rb b/app/services/send_reminder_email.rb index d6ed99779b..53b5c251ab 100644 --- a/app/services/send_reminder_email.rb +++ b/app/services/send_reminder_email.rb @@ -19,12 +19,15 @@ def call attr_reader :remindable def send_reminder? - return false unless remindable.expires_at - - remindable.should_send_reminder_email?( - days_until_expired, - number_of_reminders_sent, - ) + if remindable.is_a?(Teacher) + remindable.should_send_reminder_email? + else + return false unless remindable.expires_at + remindable.should_send_reminder_email?( + days_until_expired, + number_of_reminders_sent, + ) + end end def number_of_reminders_sent diff --git a/app/views/teacher_mailer/references_reminder.text.erb b/app/views/teacher_mailer/references_reminder.text.erb new file mode 100644 index 0000000000..dcab18394d --- /dev/null +++ b/app/views/teacher_mailer/references_reminder.text.erb @@ -0,0 +1,18 @@ +Dear <%= application_form_full_name(@application_form) %> + +We’re still waiting for a response from one or more of the references you provided to verify your work history. + +<% if @teacher.reminder_emails.count == 0 %> + We contacted your references on <%= @application_form.work_histories.first.reference_request.requested_at.to_date.to_fs(:long_ordinal_uk) %> but have not received a response from: +<% elsif @teacher.reminder_emails.count == 1 %> + The following references have just 2 weeks to respond to the reference request. +<% end %> + +<% @reference_requests.each do |reference_request| %> + <%= reference_request.contact_name + ". " + reference_request.work_history.school_name %> +<% end %> + + +They need to respond by <%= @reference_requests.first.expires_at.to_date.to_fs(:long_ordinal_uk) %>. If your references do not respond, and, as a result, we cannot verify your work history, we may not be able to award you QTS. You should contact your reference to remind them about the request. + +<%= render "shared/teacher_mailer/footer" %> \ No newline at end of file diff --git a/config/locales/mailer.en.yml b/config/locales/mailer.en.yml index f1e6cd35bd..b5d80c8be9 100644 --- a/config/locales/mailer.en.yml +++ b/config/locales/mailer.en.yml @@ -28,6 +28,10 @@ en: subject: Your qualified teacher status application – we’ve received your %{certificate} references_requested: subject: Your qualified teacher status application – we’ve contacted your references + references_reminder: + subject: + 0: Waiting on references – QTS application + 1: Your references only have two weeks left to respond teaching_authority: application_submitted: subject: "%{name} has made an application for qualified teacher status (QTS) in England" diff --git a/spec/services/send_reference_request_reminder_to_teach_spec.rb b/spec/services/send_reference_request_reminder_to_teach_spec.rb new file mode 100644 index 0000000000..f67b9d39fc --- /dev/null +++ b/spec/services/send_reference_request_reminder_to_teach_spec.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe SendReferenceRequestReminderToTeacher do + describe "#call" do + subject(:call) { described_class.call } + + shared_examples "doesn't send an email" do + it "doesn't send any email" do + expect { call }.to_not have_enqueued_mail + end + end + + shared_examples "sends a reference request reminder to teacher email" do + it "sends an email" do + expect { call }.to have_enqueued_mail( + TeacherMailer, + :references_reminder, + ).with(params: { teacher: }, args: []) + end + end + + shared_examples "first reminder email" do |shared_example| + context "when no previous reminder has been sent" do + include_examples shared_example + end + + context "when a previous reminder has been sent" do + before { reference_request.reminder_emails.create } + include_examples "doesn't send an email" + end + + context "when two previous reminders have been sent" do + before { 2.times { reference_request.reminder_emails.create } } + include_examples "doesn't send an email" + end + end + + shared_examples "second reminder email" do |shared_example| + context "when no previous reminder has been sent" do + include_examples shared_example + end + + context "when one previous reminder has been sent" do + before { reference_request.reminder_emails.create } + include_examples shared_example + end + + context "when two previous reminders have been sent" do + before { 2.times { reference_request.reminder_emails.create } } + include_examples "doesn't send an email" + end + end + + context "with a requested reference request" do + let(:application_form) do + create( + :application_form, + :submitted, + :old_regs, + region:, + teacher_id: teacher.id, + ) + end + let(:assessment) { create(:assessment, application_form:) } + let(:region) { create(:region, :in_country, country_code: "FR") } + let(:work_history) { reference_request.work_history } + let(:teacher) { create(:teacher) } + + let(:reference_request) do + create( + :reference_request, + requested_at: reference_requested_at, + assessment:, + ) + end + + context "with less than four weeks remaining" do + let(:reference_requested_at) { (6.weeks - 27.days).ago } + include_examples "first reminder email", + "sends a reference request reminder to teacher email" + end + + context "with less than two weeks remaining" do + let(:reference_requested_at) { (6.weeks - 13.days).ago } + include_examples "second reminder email", + "sends a reference request reminder to teacher email" + end + end + + context "with a received reference request" do + let(:reference_request) do + create(:reference_request, :received, requested_at: Time.zone.now) + end + include_examples "doesn't send an email" + end + + context "with an expired reference request" do + let(:reference_request) do + create(:reference_request, :expired, requested_at: Time.zone.now) + end + include_examples "doesn't send an email" + end + end +end diff --git a/spec/services/send_reminder_email_spec.rb b/spec/services/send_reminder_email_spec.rb index 532aeae457..7ccf2c401b 100644 --- a/spec/services/send_reminder_email_spec.rb +++ b/spec/services/send_reminder_email_spec.rb @@ -52,6 +52,17 @@ end end + shared_examples "sends a teacher references reminder email" do + include_examples "sends an email" + + it "sends an email" do + expect { subject }.to have_enqueued_mail( + TeacherMailer, + :references_reminder, + ).with(params: { teacher: remindable, reference_requests: [reference_request] }, args: []) + end + end + shared_examples "sends an application not submitted email" do include_examples "sends an email" @@ -293,5 +304,55 @@ end include_examples "doesn't send an email" end + + context "with a teacher with an remindable reference request" do + let!(:remindable) do + create( + :teacher + ) + end + let!(:application_form) do + create(:application_form, :submitted, :old_regs, region:, teacher: remindable) + end + let!(:assessment) { create(:assessment, application_form:) } + let!(:region) { create(:region, :in_country, country_code: "FR") } + let!(:reference_request) do + create( + :reference_request, + requested_at: reference_requested_at, + assessment:, + ) + end + context "with less than four weeks remaining" do + let(:reference_requested_at) { (6.weeks - 27.days).ago } + include_examples "first reminder email", + "sends a teacher references reminder email" + end + + context "with less than two weeks remaining" do + let(:reference_requested_at) { (6.weeks - 13.days).ago } + include_examples "second reminder email", + "sends a teacher references reminder email" + end + + context "with more than four weeks remaining" do + let(:reference_requested_at) { (2.days).ago } + include_examples "doesn't send an email" + end + + context "with a received reference request" do + let(:reference_request) do + create(:reference_request, :received, requested_at: Time.zone.now) + end + include_examples "doesn't send an email" + end + + context "with an expired reference request" do + let(:reference_request) do + create(:reference_request, :expired, requested_at: Time.zone.now) + end + include_examples "doesn't send an email" + end + end end end