diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/entry_date_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/entry_date_form.rb new file mode 100644 index 0000000000..90bf5e222d --- /dev/null +++ b/app/forms/journeys/get_a_teacher_relocation_payment/entry_date_form.rb @@ -0,0 +1,38 @@ +module Journeys + module GetATeacherRelocationPayment + class EntryDateForm < Form + include ActiveRecord::AttributeAssignment + + attribute :date_of_entry, :date + + validates :date_of_entry, presence: { + message: i18n_error_message(:presence) + } + + validates :date_of_entry, + comparison: { + less_than: ->(_) { Date.tomorrow }, + message: i18n_error_message(:date_not_in_future) + }, if: :date_of_entry + + def initialize(journey_session:, journey:, params:) + super + + # Handle setting date from multi part params see + # ActiveRecord::AttributeAssignment + _assign_attributes(permitted_params) + rescue ActiveRecord::MultiparameterAssignmentErrors + # Invalid date was entered + self.date_of_entry = nil + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(date_of_entry: date_of_entry) + + journey_session.save! + end + end + end +end diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/start_date_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/start_date_form.rb index 65fbd82971..517ea0d99e 100644 --- a/app/forms/journeys/get_a_teacher_relocation_payment/start_date_form.rb +++ b/app/forms/journeys/get_a_teacher_relocation_payment/start_date_form.rb @@ -24,10 +24,20 @@ def initialize(journey_session:, journey:, params:) def save return false unless valid? + if start_date_changed? + journey_session.answers.assign_attributes(date_of_entry: nil) + end + journey_session.answers.assign_attributes(start_date: start_date) journey_session.save! end + + private + + def start_date_changed? + journey_session.answers.start_date != start_date + end end end end diff --git a/app/models/journeys/get_a_teacher_relocation_payment.rb b/app/models/journeys/get_a_teacher_relocation_payment.rb index e81608b897..16d87fb549 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -14,7 +14,8 @@ module GetATeacherRelocationPayment "contract-details" => ContractDetailsForm, "start-date" => StartDateForm, "subject" => SubjectForm, - "visa" => VisaForm + "visa" => VisaForm, + "entry-date" => EntryDateForm } } end diff --git a/app/models/journeys/get_a_teacher_relocation_payment/answers_presenter.rb b/app/models/journeys/get_a_teacher_relocation_payment/answers_presenter.rb index c01009f512..d660e21cdf 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment/answers_presenter.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment/answers_presenter.rb @@ -11,6 +11,7 @@ def eligibility_answers a << start_date_details a << subject_details a << visa_details + a << entry_date end.compact end @@ -63,6 +64,14 @@ def visa_details "visa" ] end + + def entry_date + [ + t("get_a_teacher_relocation_payment.forms.entry_date.question"), + answers.date_of_entry.strftime("%d-%m-%Y"), + "entry-date" + ] + end end end end diff --git a/app/models/journeys/get_a_teacher_relocation_payment/session_answers.rb b/app/models/journeys/get_a_teacher_relocation_payment/session_answers.rb index 7c61ee2a61..8af21f834f 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment/session_answers.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment/session_answers.rb @@ -7,6 +7,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :start_date, :date attribute :subject, :string attribute :visa_type, :string + attribute :date_of_entry, :date end end end diff --git a/app/models/journeys/get_a_teacher_relocation_payment/slug_sequence.rb b/app/models/journeys/get_a_teacher_relocation_payment/slug_sequence.rb index c89b0728b0..1419a891f6 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment/slug_sequence.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment/slug_sequence.rb @@ -8,6 +8,7 @@ class SlugSequence "start-date", "subject", "visa", + "entry-date", "check-your-answers-part-one" ] diff --git a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb index e64f6009ba..300a3eda53 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -35,10 +35,18 @@ def ineligible_reason "taught subject not accepted" in visa_type: "Other" "visa not accepted" + in date_of_entry: Date, start_date: Date unless date_of_entry_eligible? + "cannot enter the UK more than 3 months before your contract start date" else nil end end + + def date_of_entry_eligible? + return false unless answers.date_of_entry && answers.start_date + + answers.date_of_entry >= answers.start_date - 3.months + end end end end diff --git a/app/views/get_a_teacher_relocation_payment/claims/entry_date.html.erb b/app/views/get_a_teacher_relocation_payment/claims/entry_date.html.erb new file mode 100644 index 0000000000..53ed14387d --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/entry_date.html.erb @@ -0,0 +1,30 @@ +<% content_for( + :page_title, + page_title( + t("get_a_teacher_relocation_payment.forms.entry_date.question"), + journey: current_journey_routing_name, + show_error: @form.errors.any? + ) +) %> +
+
+ <%= form_for( + @form, + url: claim_path(current_journey_routing_name), + builder: GOVUKDesignSystemFormBuilder::FormBuilder + ) do |f| %> + <% if f.object.errors.any? %> + <%= render("shared/error_summary", instance: f.object) %> + <% end %> + + <%= f.govuk_date_field( + :date_of_entry, + legend: { + text: t("get_a_teacher_relocation_payment.forms.entry_date.question") + }, + ) %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/analytics.yml b/config/analytics.yml index aa032ab828..2f7af2317e 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -198,6 +198,7 @@ shared: - start_date - subject - visa_type + - date_of_entry :schools: - id - urn diff --git a/config/locales/en.yml b/config/locales/en.yml index 2d60548386..105dba80bb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -735,6 +735,12 @@ en: question: "Select the visa you used to move to England" errors: inclusion: "Choose your visa type" + entry_date: + question: "Enter the date you moved to England to start your teaching job" + errors: + presence: "Enter your entry date" + date_not_in_future: "Date of entry cannot be in the future" + check_your_answers: part_one: diff --git a/db/migrate/20240621200501_add_date_of_entry_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240621200501_add_date_of_entry_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..93b8284bf9 --- /dev/null +++ b/db/migrate/20240621200501_add_date_of_entry_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,5 @@ +class AddDateOfEntryToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_column :international_relocation_payments_eligibilities, :date_of_entry, :date + end +end diff --git a/db/schema.rb b/db/schema.rb index aa8134c998..2e7e7a70dd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_21_153517) do +ActiveRecord::Schema[7.0].define(version: 2024_06_21_200501) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -194,6 +194,7 @@ t.date "start_date" t.string "subject" t.string "visa_type" + t.date "date_of_entry" end create_table "journey_configurations", primary_key: "routing_name", id: :string, force: :cascade do |t| diff --git a/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb b/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb index 8021d2f1ac..d526c3a141 100644 --- a/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb +++ b/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb @@ -35,6 +35,11 @@ visa_type { "British National (Overseas) visa" } end + trait :with_entry_date do + with_start_date + date_of_entry { start_date - 1.week } + end + trait :with_email_details do email_address { generate(:email_address) } email_verified { true } @@ -59,6 +64,7 @@ with_one_year_contract with_start_date with_visa + with_entry_date end end end diff --git a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb index 9a4b2a1808..7f3c9d0235 100644 --- a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb @@ -112,6 +112,24 @@ then_i_see_the_ineligible_page end end + + context "ineligible - entry date" do + it "shows the ineligible page" do + when_i_start_the_form + and_i_complete_application_route_question_with( + option: "I am employed as a teacher in a school in England" + ) + and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") + and_i_complete_the_contract_details_step_with(option: "Yes") + and_i_complete_the_contract_start_date_step_with( + date: contract_start_date + ) + and_i_complete_the_subject_step_with(option: "Physics") + and_i_complete_the_visa_screen_with(option: "British National (Overseas) visa") + and_i_complete_the_entry_date_page_with(date: contract_start_date - 4.months) + then_i_see_the_ineligible_page + end + end end def then_i_see_the_ineligible_page diff --git a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb index dc570b8757..e7b13e3b6f 100644 --- a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb @@ -11,6 +11,10 @@ Date.tomorrow end + let(:entry_date) do + contract_start_date - 1.week + end + before do journey_configuration end @@ -28,6 +32,7 @@ ) and_i_complete_the_subject_step_with(option: "Physics") and_i_complete_the_visa_screen_with(option: "British National (Overseas) visa") + and_i_complete_the_entry_date_page_with(date: entry_date) then_the_check_your_answers_part_one_page_shows_my_answers and_i_dont_change_my_answers and_the_personal_details_section_has_been_temporarily_stubbed @@ -62,5 +67,9 @@ def then_the_check_your_answers_part_one_page_shows_my_answers expect(page).to have_text( "Select the visa you used to move to England British National (Overseas) visa" ) + + expect(page).to have_text( + "Enter the date you moved to England to start your teaching job #{entry_date.strftime("%d-%m-%Y")}" + ) end end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/entry_date_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/entry_date_form_spec.rb new file mode 100644 index 0000000000..b3c178ad76 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/entry_date_form_spec.rb @@ -0,0 +1,102 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::EntryDateForm, type: :model do + let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } + + let(:params) do + ActionController::Parameters.new( + claim: multi_part_date_parms(option) + ) + end + + let(:option) { nil } + + def multi_part_date_parms(date) + return {} unless date.present? + + { + "date_of_entry(1i)" => date.year.to_s, + "date_of_entry(2i)" => date.month.to_s, + "date_of_entry(3i)" => date.day.to_s + } + end + + let(:form) do + described_class.new( + journey_session: journey_session, + journey: Journeys::GetATeacherRelocationPayment, + params: params + ) + end + + describe "validations" do + subject { form } + + context "with an invalid date" do + it { is_expected.not_to be_valid } + end + + context "with a date in the future" do + it do + is_expected.not_to( + allow_value(Date.tomorrow) + .for(:date_of_entry) + .with_message("Date of entry cannot be in the future") + ) + end + end + + context "with a date in the present" do + it { is_expected.to allow_value(Date.today).for(:date_of_entry) } + end + + context "with a date in the past" do + it { is_expected.to allow_value(Date.yesterday).for(:date_of_entry) } + end + end + + describe "#date_of_entry" do + subject { form.date_of_entry } + + before do + journey_session.answers.assign_attributes(date_of_entry: Date.tomorrow) + end + + context "when date is not present in the params" do + let(:option) { nil } + + it { is_expected.to eq(journey_session.answers.date_of_entry) } + end + + context "when date is persent in the params" do + let(:option) { Date.yesterday } + + it { is_expected.to eq(option) } + end + + context "when date is invalid" do + let(:params) do + ActionController::Parameters.new( + claim: { + "date_of_entry(1i)" => "01", + "date_of_entry(2i)" => "00", + "date_of_entry(3i)" => "2024" + } + ) + end + + it { is_expected.to be_nil } + end + end + + describe "#save" do + let(:option) { Date.yesterday } + + it "updates the journey session" do + expect { expect(form.save).to be(true) }.to( + change { journey_session.reload.answers.date_of_entry } + .to(option) + ) + end + end +end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/start_date_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/start_date_form_spec.rb index 25fbd8db12..b5419c2725 100644 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/start_date_form_spec.rb +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/start_date_form_spec.rb @@ -98,5 +98,34 @@ def multi_part_date_parms(date) .to(option) ) end + + describe "resetting depenent answers" do + before do + journey_session.answers.assign_attributes(date_of_entry: 1.year.ago) + journey_session.save! + end + + context "when the start date is changed" do + it "resets the dependent answers" do + expect { form.save }.to( + change { journey_session.reload.answers.date_of_entry } + .to(nil) + ) + end + end + + context "when the start date is not changed" do + before do + journey_session.answers.assign_attributes(start_date: option) + journey_session.save! + end + + it "does not reset the dependent answers" do + expect { form.save }.to( + not_change { journey_session.reload.answers.date_of_entry } + ) + end + end + end end end diff --git a/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb b/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb index 602e1cb623..e4ac7233a8 100644 --- a/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb +++ b/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb @@ -18,7 +18,8 @@ :with_one_year_contract, :with_start_date, :with_subject, - :with_visa + :with_visa, + :with_entry_date ) end @@ -53,6 +54,11 @@ "Select the visa you used to move to England", "British National (Overseas) visa", "visa" + ], + [ + "Enter the date you moved to England to start your teaching job", + answers.date_of_entry.strftime("%d-%m-%Y"), + "entry-date" ] ) end diff --git a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb index 7fda3efbd9..4dc03d9612 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -83,6 +83,16 @@ def and_i_complete_the_visa_screen_with(option:) click_button("Continue") end + def and_i_complete_the_entry_date_page_with(date:) + assert_on_entry_date_page! + + fill_in("Day", with: date.day) + fill_in("Month", with: date.month) + fill_in("Year", with: date.year) + + click_button("Continue") + end + def and_i_dont_change_my_answers click_button("Continue") end @@ -123,6 +133,12 @@ def assert_on_visa_page! expect(page).to have_text("Select the visa you used to move to England") end + def assert_on_entry_date_page! + expect(page).to have_text( + "Enter the date you moved to England to start your teaching job" + ) + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content(